scotch-6.0.4.dfsg/0000755002563400244210000000000012410344724017072 5ustar trophimeutilisateurs du domainescotch-6.0.4.dfsg/man/0000755002563400244210000000000011762163747017662 5ustar trophimeutilisateurs du domainescotch-6.0.4.dfsg/man/man1/0000755002563400244210000000000011762163747020516 5ustar trophimeutilisateurs du domainescotch-6.0.4.dfsg/man/man1/gmk_hy.10000644002563400244210000000362111631447171022047 0ustar trophimeutilisateurs du domaine." Text automatically generated by txt2man .TH gmk_hy 1 "August 03, 2010" "" "Scotch user's manual" .SH NAME \fBgmk_hy, gmk_m2, gmk_m3, gmk_ub2 \fP- create source graphs \fB .SH SYNOPSIS .nf .fam C \fBgmk_hy\fP [\fIoptions\fP] \fIdim\fP [\fIofile\fP] .PP \fBgmk_m2\fP [\fIoptions\fP] [\fB-g\fP\fIcfile\fP] \fIdimX\fP \fIdimY\fP [\fIofile\fP] .PP \fBgmk_m3\fP [\fIoptions\fP] [\fB-g\fP\fIcfile\fP] \fIdimX\fP \fIdimY\fP \fIdimZ\fP [\fIofile\fP] .PP \fBgmk_ub2\fP [\fIoptions\fP] \fIdim\fP .fam T .fi .SH DESCRIPTION The \fBgmk_\fP* programs create source graph files for some common, regular topologies. .PP \fBgmk_hy\fP creates a hypercube of dimension \fIdim\fP. .PP \fBgmk_m2\fP creates a 2D regular grid of dimensions \fIdimX\fP and \fIdimY\fP. .PP \fBgmk_m3\fP creates a 3D regular grid of dimensions \fIdimX\fP, \fIdimY\fP and \fIdimZ\fP. .PP \fBgmk_ub2\fP creates an unoriented de Bruijn graph of dimension \fIdim\fP. .SH OPTIONS .TP .B \fB-b\fP base For \fBgmk_m2\fP and \fBgmk_m3\fP only. Output graphs with base value set to base. Default value is 0. .TP .B \fB-e\fP For \fBgmk_m2\fP only. Build a 8-neighbor grid rather than a 4-neighbor grid. .TP .B \fB-g\fP\fIcfile\fP For \fBgmk_m2\fP and \fBgmk_m3\fP only. Output graph vertex coordinates (that is, geometry data to be used by \fBgout\fP(1)) in file \fIcfile\fP. .TP .B \fB-h\fP Display some help. .TP .B \fB-t\fP For \fBgmk_m2\fP and \fBgmk_m3\fP only. Create torus graphs, that is, graphs such that there exist loop edges between vertices of rank 0 and (\fIdim\fP-1) in every dimension. .TP .B \fB-V\fP Display program version and copyright. .SH EXAMPLE Create a 5x7 grid along with its geometry: .PP .nf .fam C $ gmk_m2 5 7 -g/tmp/m5x7.xyz /tmp/m5x7.grf .fam T .fi .SH SEE ALSO \fBgmk_msh\fP(1), \fBgtst\fP(1), \fBgmap\fP(1), \fBgord\fP(1), \fBgout\fP(1), \fBamk_grf\fP(1). .PP Scotch user's manual. .SH AUTHOR Francois Pellegrini scotch-6.0.4.dfsg/man/man1/gotst.10000644002563400244210000000367311631447171021740 0ustar trophimeutilisateurs du domaine." Text automatically generated by txt2man .TH gotst 1 "August 03, 2010" "" "Scotch user's manual" .SH NAME \fBgomtst \fP- compute statistics on sparse matrix orderings \fB .SH SYNOPSIS .nf .fam C \fBgotst\fP [\fIoptions\fP] [\fIgfile\fP] [\fIofile\fP] [\fIlfile\fP] .fam T .fi .SH DESCRIPTION The \fBgotst\fP program computes, in a sequential way, statistics on a sparse matrix ordering, such as fill-in, operation count, and separator tree parameters: minimum, maximum, average height and variance of its leaves. .PP Source graph file \fIgfile\fP can only be a centralized graph file. File \fIofile\fP represents the ordering of the symmetric sparse matrix the pattern of which is represented by \fIgfile\fP. The resulting statistics are stored in file \fIlfile\fP. When file names are not specified, data is read from standard input and written to standard output. Standard streams can also be explicitly represented by a dash '-'. .PP When the proper libraries have been included at compile time, gtst can directly handle compressed graphs, both as input and output. A stream is treated as compressed whenever its name is postfixed with a compressed file extension, such as in 'brol.grf.bz2' or '-.gz'. The compression formats which can be supported are the bzip2 format ('.bz2'), the gzip format ('.gz'), and the lzma format ('.lzma', on input only). .PP Since \fBgotst\fP performs sequentially the symbolic factorization of matrix \fIgfile\fP in order to compute fill-in and operation count numbers, this program can take a long time or even run out of memory, when applied to very large graphs. .SH OPTIONS .TP .B \fB-h\fP Display some help. .TP .B \fB-V\fP Display program version and copyright. .SH EXAMPLE Display statistics on ordering brol.ord of graph brol.grf: .PP .nf .fam C $ gotst brol.grf brol.ord .fam T .fi .SH SEE ALSO \fBgord\fP(1), \fBgtst\fP(1), \fBdgord\fP(1). .PP Scotch user's manual. .SH AUTHOR Francois Pellegrini scotch-6.0.4.dfsg/man/man1/gmtst.10000644002563400244210000000461411631447171021732 0ustar trophimeutilisateurs du domaine." Text automatically generated by txt2man .TH gmtst 1 "August 03, 2010" "" "Scotch user's manual" .SH NAME \fBgmtst \fP- compute statistics on mappings \fB .SH SYNOPSIS .nf .fam C \fBgmtst\fP [\fIoptions\fP] [\fIgfile\fP] [\fItfile\fP] [\fImfile\fP] [\fIlfile\fP] .fam T .fi .SH DESCRIPTION The \fBgmtst\fP program computes, in a sequential way, statistics on a static mapping, such as load imbalance ratio, edge dilation distribution, etc. It yields the same results as the ones produced by the \fB-vm\fP option of the \fBgmap\fP(1) program. .PP Source graph file \fIgfile\fP can only be a centralized graph file. File \fItfile\fP represents the target architecture onto which \fIgfile\fP was mapped. If mapping file \fImfile\fP was produced by \fBgpart\fP(1), the target architecture file to provide \fBgmtst\fP should describe a complete graph with the same number of vertices as the requested number of parts, for instance by means of the '\fBcmplt\fP \fInum\fP' algorithmically-described architecture. The resulting statistics are stored in file \fIlfile\fP. When file names are not specified, data is read from standard input and written to standard output. Standard streams can also be explicitly represented by a dash '-'. .PP When the proper libraries have been included at compile time, gtst can directly handle compressed graphs, both as input and output. A stream is treated as compressed whenever its name is postfixed with a compressed file extension, such as in 'brol.grf.bz2' or '-.gz'. The compression formats which can be supported are the bzip2 format ('.bz2'), the gzip format ('.gz'), and the lzma format ('.lzma', on input only). .SH OPTIONS .TP .B \fB-h\fP Display some help. .TP .B \fB-V\fP Display program version and copyright. .SH EXAMPLES Display statistics on mapping brol.map of graph brol.grf onto target architecture brol.tgt: .PP .nf .fam C $ gmtst brol.grf brol.tgt brol.map .fam T .fi Display statistics on partitioning brol.map of graph brol.grf into \fInum\fP parts. Note the use of the complete graph algorithmically-described architecture and of the shell pipe command to provide the complete target architecture description on the standard input of the \fBgmtst\fP command: .PP .nf .fam C $ echo "cmplt num" | gmtst brol.grf - brol.map .fam T .fi .SH SEE ALSO \fBgmap\fP(1), \fBgout\fP(1), \fBgtst\fP(1). .PP Scotch user's manual. .SH AUTHOR Francois Pellegrini scotch-6.0.4.dfsg/man/man1/mmk_m2.10000644002563400244210000000300711631447171021751 0ustar trophimeutilisateurs du domaine." Text automatically generated by txt2man .TH mmk_m2 1 "August 03, 2010" "" "Scotch user's manual" .SH NAME \fBmmk_m2, mmk_m3 \fP- create source meshes \fB .SH SYNOPSIS .nf .fam C \fBmmk_m2\fP [\fIoptions\fP] [\fB-g\fP\fIcfile\fP] \fIdimX\fP \fIdimY\fP [\fIofile\fP] .PP \fBmmk_m3\fP [\fIoptions\fP] [\fB-g\fP\fIcfile\fP] \fIdimX\fP \fIdimY\fP \fIdimZ\fP [\fIofile\fP] .fam T .fi .SH DESCRIPTION The \fBmmk_\fP* programs create source mesh files for some common, regular topologies. .PP \fBmmk_m2\fP creates a 2D regular mesh of \fIdimX\fP times \fIdimY\fP elements and (\fIdimX\fP+1) times (\fIdimY\fP+1) nodes, such that element (i,j) is connected to nodes (i,j), (i,j+1), (i+1,j) and (i+1,j+1). .PP \fBmmk_m3\fP creates a 3D regular mesh of \fIdimX\fP times \fIdimY\fP times \fIdimZ\fP elements and (\fIdimX\fP+1) times (\fIdimY\fP+1) times (\fIdimZ\fP+1) nodes, such that element (i,j,k) is connected to nodes (i,j,k), (i,j,k+1), (i,j+1,k), (i,j+1,k+1), (i+1,j,k), (i+1,j,k+1), (i+1,j+1,k) and (i+1,j+1,k+1). .SH OPTIONS .TP .B \fB-g\fP\fIcfile\fP Output graph vertex coordinates (that is, geometry data to be used by \fBgout\fP(1)) in file \fIcfile\fP. .TP .B \fB-h\fP Display some help. .TP .B \fB-V\fP Display program version and copyright. .SH EXAMPLE Create a mesh of 5x7 elements, along with its geometry: .PP .nf .fam C $ mmk_m2 5 7 -g/tmp/m5x7.xyz /tmp/m5x7.msh .fam T .fi .SH SEE ALSO \fBmord\fP(1), \fBmtst\fP(1), \fBgmk_msh\fP(1). .PP Scotch user's manual. .SH AUTHOR Francois Pellegrini scotch-6.0.4.dfsg/man/man1/dgord.10000644002563400244210000000716011631447171021672 0ustar trophimeutilisateurs du domaine." Text automatically generated by txt2man .TH dgord 1 "August 03, 2010" "" "PT-Scotch user's manual" .SH NAME \fBdgord \fP- compute sparse matrix orderings of graphs in parallel \fB .SH SYNOPSIS .nf .fam C \fBdgord\fP [\fIoptions\fP] [\fIgfile\fP] [\fIofile\fP] [\fIlfile\fP] .fam T .fi .SH DESCRIPTION The \fBdgord\fP program computes, in a parallel way, an ordering of a Scotch source graph representing the pattern of some symmetric sparse matrix. .PP Source graph file \fIgfile\fP is either a centralized graph file, or a set of files representing fragments of a distributed graph. The resulting ordering is stored in file \fIofile\fP. Eventual logging information (such as the one produced by option \fB-v\fP) is sent to file \fIlfile\fP. When file names are not specified, data is read from standard input and written to standard output. Standard streams can also be explicitely represented by a dash '-'. .PP When the proper libraries have been included at compile time, \fBdgord\fP can directly handle compressed graphs, both as input and output. A stream is treated as compressed whenever its name is postfixed with a compressed file extension, such as in 'brol.grf.bz2' or '-.gz'. The compression formats which can be supported are the bzip2 format ('.bz2'), the gzip format ('.gz'), and the lzma format ('.lzma', on input only). .PP \fBdgord\fP bases on implementations of the MPI interface to spread work across the processing elements. It is therefore not likely to be run directly, but instead through some launcher command such as \fBmpirun\fP. .SH OPTIONS .TP .B \fB-c\fPopt Choose default ordering strategy according to one or several \fIoptions\fP among: .RS .TP .B b enforce load balance as much as possible. .TP .B q privilege quality over speed (default). .TP .B s privilege speed over quality. .TP .B t enforce safety. .TP .B x enforce scalability. .RE .TP .B \fB-h\fP Display some help. .TP .B \fB-m\fP\fImfile\fP Save column block mapping data to file \fImfile\fP. Mapping data specifies, for each vertex, the index of the column block to which this vertex belongs. .TP .B \fB-o\fP\fIstrat\fP Use parallel graph ordering strategy \fIstrat\fP (see PT-Scotch user's manual for more information). .TP .B \fB-r\fP\fIpnum\fP Set root process for centralized files (default is 0). .TP .B \fB-t\fP\fItfile\fP Save partitioning tree data to file \fItfile\fP. Partitioning tree data specifies, for each vertex, the index of the first vertex of the parent block of the block to which the vertex belongs. Altogether with the mapping data provided in file \fImfile\fP, it allows one to rebuild the separator tree of the nested dissection process. .TP .B \fB-V\fP Display program version and copyright. .TP .B \fB-v\fP\fIverb\fP Set verbose mode to \fIverb\fP. It is a set of one of more characters which can be: .RS .TP .B s strategy information. .TP .B t timing information. .SH EXAMPLES Run \fBdgord\fP on 5 processing elements to reorder matrix graph brol.grf and save the resulting ordering to file brol.ord, using the default sequential graph ordering strategy: .PP .nf .fam C $ mpirun -np 5 dgord brol.grf brol.ord .fam T .fi Run \fBdgord\fP on 5 processing elements to reorder the distributed matrix stored on graph fragment files brol5-0.dgr to brol5-4.dgr, and save the resulting ordering to file brol.ord (see \fBdgscat\fP(1) for an explanation of the '%p' and '%r' sequences in names of distributed graph fragments). .PP .nf .fam C $ mpirun -np 5 dgord brol%p-%r.dgr brol.ord .fam T .fi .SH SEE ALSO \fBdgtst\fP(1), \fBdgscat\fP(1), \fBgmk_hy\fP(1), \fBgord\fP(1). .PP PT-Scotch user's manual. .SH AUTHOR Francois Pellegrini scotch-6.0.4.dfsg/man/man1/mmk_m3.10000644002563400244210000000002211631447171021744 0ustar trophimeutilisateurs du domaine.so man1/mmk_m2.1 scotch-6.0.4.dfsg/man/man1/gpart.10000644002563400244210000000002011631447171021674 0ustar trophimeutilisateurs du domaine.so man1/gmap.1 scotch-6.0.4.dfsg/man/man1/dgpart.10000644002563400244210000000002111631447171022041 0ustar trophimeutilisateurs du domaine.so man1/dgmap.1 scotch-6.0.4.dfsg/man/man1/gmk_msh.10000644002563400244210000000205211631447171022213 0ustar trophimeutilisateurs du domaine." Text automatically generated by txt2man .TH gmk_msh 1 "August 03, 2010" "" "Scotch user's manual" .SH NAME \fBgmk_msh \fP- create source graph from source mesh \fB .SH SYNOPSIS .nf .fam C \fBgmk_msh\fP [\fIoptions\fP] [\fImfile\fP] [\fIgfile\fP] .fam T .fi .SH DESCRIPTION The \fBgmk_msh\fP program creates a source graph from a source mesh. The vertices of the graph are the nodes of the mesh, and all mesh elements are turned into cliques, that is, there exists an edge between two vertices in the graph if there exists at least an element in the mesh which comprises the two associated nodes. .SH OPTIONS .TP .B \fB-h\fP Display some help. .TP .B \fB-V\fP Display program version and copyright. .SH EXAMPLE Create a source graph brol.grf from a source mesh brol.msh: .PP .nf .fam C $ gmk_msh brol.msh brol.grf .fam T .fi .SH SEE ALSO dgmap (1), \fBdgord\fP(1), \fBgmap\fP(1), \fBgord\fP(1), \fBgtst\fP(1), \fBmmk_m2\fP(1), \fBmord\fP(1), \fBmcv\fP(1), \fBmtst\fP(1). .PP Scotch user's manual. .SH AUTHOR Francois Pellegrini scotch-6.0.4.dfsg/man/man1/amk_m2.10000644002563400244210000000002311631447171021730 0ustar trophimeutilisateurs du domaine.so man1/amk_ccc.1 scotch-6.0.4.dfsg/man/man1/gtst.10000644002563400244210000000327411631447171021556 0ustar trophimeutilisateurs du domaine." Text automatically generated by txt2man .TH gtst 1 "August 03, 2010" "" "Scotch user's manual" .SH NAME \fBgtst \fP- test the consistency of source graphs \fB .SH SYNOPSIS .nf .fam C \fBgtst\fP [\fIoptions\fP] [\fIgfile\fP] [\fIlfile\fP] .fam T .fi .SH DESCRIPTION The \fBgtst\fP program checks, in a sequential way, the consistency of a Scotch source graph and, in case of success, outputs some statistics regarding edge weights, vertex weights, and vertex degrees. .PP It produces the very same results as the \fBdgtst\fP(1) program of the PT-Scotch parallel distribution, but unlike this latter it cannot handle distributed graphs. .PP Source graph file \fIgfile\fP can only be a centralized graph file. The resulting statistics are stored in file \fIlfile\fP. When file names are not specified, data is read from standard input and written to standard output. Standard streams can also be explicitly represented by a dash '-'. .PP When the proper libraries have been included at compile time, \fBgtst\fP can directly handle compressed graphs, both as input and output. A stream is treated as compressed whenever its name is postfixed with a compressed file extension, such as in 'brol.grf.bz2' or '-.gz'. The compression formats which can be supported are the bzip2 format ('.bz2'), the gzip format ('.gz'), and the lzma format ('.lzma', on input only). .SH OPTIONS .TP .B \fB-h\fP Display some help. .TP .B \fB-V\fP Display program version and copyright. .SH EXAMPLE Test the consistency of graph brol.grf: .PP .nf .fam C $ gtst brol.grf .fam T .fi .SH SEE ALSO \fBdgtst\fP(1), \fBgmap\fP(1), \fBgord\fP(1), \fBgout\fP(1). .PP Scotch user's manual. .SH AUTHOR Francois Pellegrini scotch-6.0.4.dfsg/man/man1/dgmap.10000644002563400244210000000762111631447171021665 0ustar trophimeutilisateurs du domaine." Text automatically generated by txt2man .TH dgmap 1 "August 03, 2010" "" "PT-Scotch user's manual" .SH NAME \fBdgmap, dgpart \fP- compute static mappings and partitions in parallel \fB .SH SYNOPSIS .nf .fam C \fBdgmap\fP [\fIoptions\fP] [\fIgfile\fP] [\fItfile\fP] [\fImfile\fP] [\fIlfile\fP] .PP \fBdgpart\fP [\fIoptions\fP] [\fInparts\fP] [\fIgfile\fP] [\fImfile\fP] [\fIlfile\fP] .fam T .fi .SH DESCRIPTION The \fBdgmap\fP program computes, in a parallel way, a static mapping of a source graph onto a target graph. .PP The \fBdgpart\fP program is a shortcut of \fBdgmap\fP for computing partitions of a source graph. .PP Source graph file \fIgfile\fP is either a centralized graph file, or a set of files representing fragments of a distributed graph. For \fBdgmap\fP, the target architecture file \fItfile\fP describes either algorithmically-coded topologies such as meshes and hypercubes, or decomposition-defined architectures created by means of the \fBamk_grf\fP(1) program. See \fBgmap\fP(1) for a description of target architectures. The resulting mapping is stored in file \fImfile\fP. Eventual logging information (such as the one produced by option \fB-v\fP) is sent to file \fIlfile\fP. When file names are not specified, data is read from standard input and written to standard output. Standard streams can also be explicitely represented by a dash '-'. .PP When the proper libraries have been included at compile time, \fBdgmap\fP and \fBdgpart\fP can directly handle compressed graphs, both as input and output. A stream is treated as compressed whenever its name is postfixed with a compressed file extension, such as in 'brol.grf.bz2' or '-.gz'. The compression formats which can be supported are the bzip2 format ('.bz2'), the gzip format ('.gz'), and the lzma format ('.lzma', on input only). .PP \fBdgmap\fP and \fBdgpart\fP base on implementations of the MPI interface to spread work across the processing elements. They are therefore not likely to be run directly, but instead through some launcher command such as \fBmpirun\fP. .SH OPTIONS .TP .B \fB-c\fPopt Choose default mapping strategy according to one or several \fIoptions\fP among: .RS .TP .B b enforce load balance as much as possible. .TP .B q privilege quality over speed (default). .TP .B s privilege speed over quality. .TP .B t enforce safety. .TP .B x enforce scalability. .RE .TP .B \fB-h\fP Display some help. .TP .B \fB-m\fP\fIstrat\fP Use parallel mapping strategy \fIstrat\fP (see PT-Scotch user's manual for more information). .TP .B \fB-r\fP\fIpnum\fP Set root process for centralized files (default is 0). .TP .B \fB-V\fP Display program version and copyright. .TP .B \fB-v\fP\fIverb\fP Set verbose mode to \fIverb\fP. It is a set of one of more characters which can be: .RS .TP .B m mapping information. .TP .B s strategy information. .TP .B t timing information. .SH NOTE At the time being (version 5.1.0), \fBdgmap\fP cannot compute full static mappings as \fBgmap\fP(1) does, but only partitions (that is, mappings onto unweighted or weighted complete graphs). Target architectures other than the 'cmplt' and 'wcmplt' ones will lead to an error message. .SH EXAMPLES Run \fBdgpart\fP on 5 processing elements to compute a partition into 7 parts of graph brol.grf and save the resulting ordering to file brol.map. .PP .nf .fam C $ mpirun -np 5 dgpart 7 brol.grf brol.map .fam T .fi Run \fBdgpart\fP on 5 processing elements to partition into 7 parts the distributed graph stored on graph fragment files brol5-0.dgr to brol5-4.dgr, and save the resulting mapping to file brol.map (see \fBdgscat\fP(1) for an explanation of the '%p' and '%r' sequences in names of distributed graph fragments). .PP .nf .fam C $ mpirun -np 5 dgpart 7 brol%p-%r.dgr brol.map .fam T .fi .SH SEE ALSO \fBdgtst\fP(1), \fBdgscat\fP(1), \fBamk_grf\fP(1), \fBacpl\fP(1), \fBgmap\fP(1), \fBgmtst\fP(1). .PP PT-Scotch user's manual. .SH AUTHOR Francois Pellegrini scotch-6.0.4.dfsg/man/man1/mtst.10000644002563400244210000000302611631447171021557 0ustar trophimeutilisateurs du domaine." Text automatically generated by txt2man .TH mtst 1 "August 03, 2010" "" "Scotch user's manual" .SH NAME \fBmtst \fP- test the consistency of source meshes \fB .SH SYNOPSIS .nf .fam C \fBmtst\fP [\fIoptions\fP] [\fImfile\fP] [\fIlfile\fP] .fam T .fi .SH DESCRIPTION The \fBmtst\fP program checks, in a sequential way, the consistency of a Scotch source mesh and, in case of success, outputs some statistics regarding edge weights, node and element vertex weights, and node and element vertex degrees. .PP Source mesh file \fImfile\fP can only be a centralized mesh file. The resulting statistics are stored in file \fIlfile\fP. When file names are not specified, data is read from standard input and written to standard output. Standard streams can also be explicitly represented by a dash '-'. .PP When the proper libraries have been included at compile time, \fBmtst\fP can directly handle compressed meshes, both as input and output. A stream is treated as compressed whenever its name is postfixed with a compressed file extension, such as in 'brol.msh.bz2' or '-.gz'. The compression formats which can be supported are the bzip2 format ('.bz2'), the gzip format ('.gz'), and the lzma format ('.lzma', on input only). .SH OPTIONS .TP .B \fB-h\fP Display some help. .TP .B \fB-V\fP Display program version and copyright. .SH EXAMPLE Test the consistency of mesh brol.msh: .PP .nf .fam C $ mtst brol.msh .fam T .fi .SH SEE ALSO \fBmord\fP(1), \fBgrf_msh\fP(1). .PP Scotch user's manual. .SH AUTHOR Francois Pellegrini scotch-6.0.4.dfsg/man/man1/dgtst.10000644002563400244210000000473711631447171021727 0ustar trophimeutilisateurs du domaine." Text automatically generated by txt2man .TH dgtst 1 "August 03, 2010" "" "PT-Scotch user's manual" .SH NAME \fBdgtst \fP- test the consistency of source graphs in parallel \fB .SH SYNOPSIS .nf .fam C \fBdgtst\fP [\fIoptions\fP] [\fIgfile\fP] [\fIlfile\fP] .fam T .fi .SH DESCRIPTION The \fBdgtst\fP program checks, in a parallel way, the consistency of a Scotch source graph and, in case of success, outputs some statistics regarding edge weights, vertex weights, and vertex degrees. .PP It produces the very same results as the \fBgtst\fP(1) program of the Scotch sequential distribution, but unlike this latter it can handle distributed graphs. .PP Source graph file \fIgfile\fP is either a centralized graph file, or a set of files representing fragments of a distributed graph. The resulting statistics are stored in file \fIlfile\fP. When file names are not specified, data is read from standard input and written to standard output. Standard streams can also be explicitly represented by a dash '-'. .PP When the proper libraries have been included at compile time, \fBdgtst\fP can directly handle compressed graphs, both as input and output. A stream is treated as compressed whenever its name is postfixed with a compressed file extension, such as in 'brol.grf.bz2' or '-.gz'. The compression formats which can be supported are the bzip2 format ('.bz2'), the gzip format ('.gz'), and the lzma format ('.lzma', on input only). .PP \fBdgtst\fP bases on implementations of the MPI interface to spread work across the processing elements. It is therefore not likely to be run directly, but instead through some launcher command such as \fBmpirun\fP. .SH OPTIONS .TP .B \fB-h\fP Display some help. .TP .B \fB-r\fP\fIpnum\fP Set root process for centralized files (default is 0). .TP .B \fB-V\fP Display program version and copyright. .SH EXAMPLE Run \fBdgtst\fP on 5 processing elements to test the consistency of graph brol.grf .PP .nf .fam C $ mpirun -np 5 dgtst brol.grf .fam T .fi Run dgord on 5 processing elements to test the consistency of a distributed graph stored on graph fragment files brol5-0.dgr to brol5-4.dgr, and save the resulting ordering to file brol.ord (see \fBdgscat\fP(1) for an explanation of the '%p' and '%r' sequences in names of distributed graph fragments). .PP .nf .fam C $ mpirun -np 5 dgtst brol%p-%r.dgr brol.ord .fam T .fi .SH SEE ALSO \fBdgscat\fP(1), \fBgtst\fP(1), \fBdgord\fP(1). .PP PT-Scotch user's manual. .SH AUTHOR Francois Pellegrini scotch-6.0.4.dfsg/man/man1/amk_fft2.10000644002563400244210000000002311631447171022253 0ustar trophimeutilisateurs du domaine.so man1/amk_ccc.1 scotch-6.0.4.dfsg/man/man1/dgscat.10000644002563400244210000001036611631447171022042 0ustar trophimeutilisateurs du domaine." Text automatically generated by txt2man .TH dgscat 1 "August 03, 2010" "" "PT-Scotch user's manual" .SH NAME \fBdgscat \fP- build distributed source graph file fragments from a centralized source graph file \fB .SH SYNOPSIS .nf .fam C \fBdgscat\fP [\fIoptions\fP] [\fIigfile\fP] [\fIogfile\fP] .fam T .fi .SH DESCRIPTION The \fBdgscat\fP program reads a centralized source graph \fIigfile\fP and writes it back on the form of a set of files \fIogfile\fP representing fragments of a distributed source graph. .PP When file names are not specified, data is read from standard input and written to standard output. Standard streams can also be explicitly represented by a dash '-'. .PP When the proper libraries have been included at compile time, dgord can directly handle compressed graphs, both as input and output. A stream is treated as compressed whenever its name is postfixed with a compressed file extension, such as in 'brol.grf.bz2' or '-.gz'. The compression formats which can be supported are the bzip2 format ('.bz2'), the gzip format ('.gz'), and the lzma format ('.lzma', on input only). .PP dgord bases on implementations of the MPI interface to spread work across the processing elements. It is therefore not likely to be run directly, but instead through some launcher command such as \fBmpirun\fP. .SH DISTRIBUTED FILE NAMES In order to tell whether programs should read from, or write to, a single file located on only one processor, or to multiple instances of the same file on all of the processors, or else to distinct files on each of the processors, a special grammar has been designed, which is based on the '%' escape character. Four such escape sequences are defined, which are interpreted independently on every processor, prior to file opening. By default, when a filename is provided, it is assumed that the file is to be opened on only one of the processors, called the root processor, which is usually process 0 of the communicator within which the program is run. The index of the root processor can be changed by means of the \fB-r\fP option. Using any of the first three escape sequences below will instruct programs to open in parallel a file of name equal to the interpreted filename, on every processor on which they are run. .TP .B %p Replaced by the number of processes in the global communicator in which the program is run. Leads to parallel opening. .TP .B %r Replaced on each process running the program by the rank of this process in the global communicator. Leads to parallel opening. .TP .B %- Discarded, but leads to parallel opening. This sequence is mainly used to instruct programs to open on every processor a file of identical name. The opened files can be, according whether the given path leads to a shared directory or to directories that are local to each processor, either to the opening of multiple instances of the same file, or to the opening of distinct files which may each have a different content, respectively (but in this latter case it is much recommended to identify files by means of the '%r' sequence). .TP .B %% Replaced by a single '%' character. File names using this escape sequence are not considered for parallel opening, unless one or several of the three other escape sequences are also present. .RE .PP For instance, filename 'brol' will lead to the opening of file 'brol' on the root processor only, filename '%\fB-brol\fP' (or even 'br%\fB-ol\fP') will lead to the parallel opening of files called 'brol' on every processor, and filename 'brol%p-%r' will lead to the opening of files 'brol2-0' and 'brol2-1', respectively, on each of the two processors on which the program were to run. .SH OPTIONS .TP .B \fB-c\fP Check the consistency of the input source graph after loading it into memory. .TP .B \fB-h\fP Display some help. .TP .B \fB-r\fP\fIpnum\fP Set root process for centralized files (default is 0). .TP .B \fB-V\fP Display program version and copyright. .SH EXAMPLE Run \fBdgscat\fP on 5 processing elements to scatter centralized graph file brol.grf into 5 gzipped file fragments brol5-0.dgr.gz to brol5-4.dgr.gz. .PP .nf .fam C $ mpirun -np 5 dgscat brol.grf brol%p-%r.dgr.gz .fam T .fi .SH SEE ALSO \fBdgtst\fP(1), \fBdgord\fP(1), \fBgmk_hy\fP(1). .PP PT-Scotch user's manual. .SH AUTHOR Francois Pellegrini scotch-6.0.4.dfsg/man/man1/gmk_ub2.10000644002563400244210000000002211631447171022107 0ustar trophimeutilisateurs du domaine.so man1/gmk_hy.1 scotch-6.0.4.dfsg/man/man1/gord.10000644002563400244210000000541711631447171021531 0ustar trophimeutilisateurs du domaine." Text automatically generated by txt2man .TH gord 1 "August 03, 2010" "" "Scotch user's manual" .SH NAME \fBgord \fP- compute sparse matrix orderings of graphs \fB .SH SYNOPSIS .nf .fam C \fBgord\fP [\fIoptions\fP] [\fIgfile\fP] [\fIofile\fP] [\fIlfile\fP] .fam T .fi .SH DESCRIPTION The \fBgord\fP program computes, in a sequential way, an ordering of a Scotch source graph representing the pattern of some symmetric sparse matrix. .PP Source graph file \fIgfile\fP can only be a centralized graph file. The resulting ordering is stored in file \fIofile\fP. Eventual logging information (such as the one produced by option \fB-v\fP) is sent to file \fIlfile\fP. When file names are not specified, data is read from standard input and written to standard output. Standard streams can also be explicitely represented by a dash '-'. .PP When the proper libraries have been included at compile time, \fBgord\fP can directly handle compressed graphs, both as input and output. A stream is treated as compressed whenever its name is postfixed with a compressed file extension, such as in 'brol.grf.bz2' or '-.gz'. The compression formats which can be supported are the bzip2 format ('.bz2'), the gzip format ('.gz'), and the lzma format ('.lzma', on input only). .SH OPTIONS .TP .B \fB-c\fPopt Choose default ordering strategy according to one or several \fIoptions\fP among: .RS .TP .B b enforce load balance as much as possible. .TP .B q privilege quality over speed (default). .TP .B s privilege speed over quality. .TP .B t enforce safety. .RE .TP .B \fB-h\fP Display some help. .TP .B \fB-m\fP\fImfile\fP Save column block mapping data to file \fImfile\fP. Mapping data specifies, for each vertex, the index of the column block to which this vertex belongs. .TP .B \fB-o\fP\fIstrat\fP Use sequential graph ordering strategy \fIstrat\fP (see Scotch user's manual for more information). .TP .B \fB-t\fP\fItfile\fP Save partitioning tree data to file \fItfile\fP. Partitioning tree data specifies, for each vertex, the index of the first vertex of the parent block of the block to which the vertex belongs. Altogether with the mapping data provided in file \fImfile\fP, it allows one to rebuild the separator tree of the nested dissection process. .TP .B \fB-V\fP Display program version and copyright. .TP .B \fB-v\fP\fIverb\fP Set verbose mode to \fIverb\fP. It is a set of one of more characters which can be: .RS .TP .B s strategy information. .TP .B t timing information. .SH EXAMPLE Reorder matrix graph brol.grf and save the resulting ordering to file brol.ord using the default sequential graph ordering strategy: .PP .nf .fam C $ gord brol.grf brol.ord .fam T .fi .SH SEE ALSO \fBdgord\fP(1), \fBgmk_hy\fP(1), \fBgtst\fP(1). .PP Scotch user's manual. .SH AUTHOR Francois Pellegrini scotch-6.0.4.dfsg/man/man1/mord.10000644002563400244210000000574511631447171021543 0ustar trophimeutilisateurs du domaine." Text automatically generated by txt2man .TH mord 1 "August 03, 2010" "" "Scotch user's manual" .SH NAME \fBmord \fP- compute sparse matrix orderings of meshes \fB .SH SYNOPSIS .nf .fam C \fBmord\fP [\fIoptions\fP] [\fImfile\fP] [\fIofile\fP] [\fIlfile\fP] .fam T .fi .SH DESCRIPTION The \fBmord\fP program computes, in a sequential way, an ordering of a Scotch source mesh representing the pattern of some symmetric sparse matrix. Only nodes of the mesh are effectively ordered. Elements provide connectivity information, such that every node is considered to be linked to all of the nodes which share at least an element with it. .PP Source mesh file \fImfile\fP can only be a centralized mesh file. The resulting ordering is stored in file \fIofile\fP. Eventual logging information (such as the one produced by option \fB-v\fP) is sent to file \fIlfile\fP. When file names are not specified, data is read from standard input and written to standard output. Standard streams can also be explicitely represented by a dash '-'. .PP When the proper libraries have been included at compile time, gord can directly handle compressed meshes, both as input and output. A stream is treated as compressed whenever its name is postfixed with a compressed file extension, such as in 'brol.msh.bz2' or '-.gz'. The compression formats which can be supported are the bzip2 format ('.bz2'), the gzip format ('.gz'), and the lzma format ('.lzma', on input only). .SH OPTIONS .TP .B \fB-c\fPopt Choose default ordering strategy according to one or several \fIoptions\fP among: .RS .TP .B b enforce load balance as much as possible. .TP .B q privilege quality over speed (default). .TP .B s privilege speed over quality. .TP .B t enforce safety. .RE .TP .B \fB-h\fP Display some help. .TP .B \fB-m\fP\fImfile\fP Save column block mapping data to file \fImfile\fP. Mapping data specifies, for each node vertex, the index of the column block to which this node vertex belongs. .TP .B \fB-o\fP\fIstrat\fP Use sequential mesh ordering strategy \fIstrat\fP (see Scotch user's manual for more information). .TP .B \fB-t\fP\fItfile\fP Save partitioning tree data to file \fItfile\fP. Partitioning tree data specifies, for each node vertex, the index of the first node vertex of the parent block of the block to which the node vertex belongs. Altogether with the mapping data provided in file \fImfile\fP, it allows one to rebuild the separator tree of the nested dissection process. .TP .B \fB-V\fP Display program version and copyright. .TP .B \fB-v\fP\fIverb\fP Set verbose mode to \fIverb\fP. It is a set of one of more characters which can be: .RS .TP .B s strategy information. .TP .B t timing information. .SH EXAMPLE Reorder matrix mesh brol.msh and save the resulting ordering to file brol.ord using the default sequential mesh ordering strategy: .PP .nf .fam C $ mord brol.msh brol.ord .fam T .fi .SH SEE ALSO \fBgmk_msh\fP(1), \fBgotst\fP(1), \fBmtst\fP(1). .PP Scotch user's manual. .SH AUTHOR Francois Pellegrini scotch-6.0.4.dfsg/man/man1/amk_hy.10000644002563400244210000000002311631447171022032 0ustar trophimeutilisateurs du domaine.so man1/amk_ccc.1 scotch-6.0.4.dfsg/man/man1/amk_p2.10000644002563400244210000000002311631447171021733 0ustar trophimeutilisateurs du domaine.so man1/amk_ccc.1 scotch-6.0.4.dfsg/man/man1/atst.10000644002563400244210000000330211631447171021540 0ustar trophimeutilisateurs du domaine." Text automatically generated by txt2man .TH atst 1 "August 03, 2010" "" "Scotch user's manual" .SH NAME \fBatst \fP- test the consistency of target architectures \fB .SH SYNOPSIS .nf .fam C \fBatst\fP [\fIoptions\fP] [\fIafile\fP] [\fIlfile\fP] .fam T .fi .SH DESCRIPTION The \fBatst\fP program checks the consistency of a Scotch decomposition-defined target architecture and, in case of success, outputs some statistics regarding the number of target vertices and the length of paths linking them. Target architectures define the topology of the target graphs used by static mapping programs \fBgmap\fP(1) and \fBdgmap\fP(1). .PP The resulting statistics are stored in file \fIlfile\fP. When file names are not specified, data is read from standard input and written to standard output. Standard streams can also be explicitly represented by a dash '-'. .PP When the proper libraries have been included at compile time, \fBatst\fP can directly handle compressed files, both as input and output. A stream is treated as compressed whenever its name is postfixed with a compressed file extension, such as in 'brol.tgt.bz2' or '-.gz'. The compression formats which can be supported are the bzip2 format ('.bz2'), the gzip format ('.gz'), and the lzma format ('.lzma', on input only). .SH OPTIONS .TP .B \fB-h\fP Display some help. .TP .B \fB-V\fP Display program version and copyright. .SH EXAMPLE Test the consistency of architecture arch.tgt: .PP .nf .fam C $ atst arch.tgt .fam T .fi .SH SEE ALSO \fBamk_grf\fP(1), \fBamk_ccc\fP(1), \fBamk_fft2\fP(1), \fBamk_hy\fP(1), \fBamk_m2\fP(1), \fBamk_p2\fP(1), \fBgmap\fP(1), \fBdgmap\fP(1). .PP Scotch user's manual. .SH AUTHOR Francois Pellegrini scotch-6.0.4.dfsg/man/man1/gmk_m3.10000644002563400244210000000002211631447171021736 0ustar trophimeutilisateurs du domaine.so man1/gmk_hy.1 scotch-6.0.4.dfsg/man/man1/gmap.10000644002563400244210000001225411631447171021517 0ustar trophimeutilisateurs du domaine." Text automatically generated by txt2man .TH gmap 1 "August 03, 2010" "" "Scotch user's manual" .SH NAME \fBgmap, gpart \fP- compute static mappings and partitions sequentially \fB .SH SYNOPSIS .nf .fam C \fBgmap\fP [\fIoptions\fP] [\fIgfile\fP] [\fItfile\fP] [\fImfile\fP] [\fIlfile\fP] .PP \fBgpart\fP [\fIoptions\fP] [\fInparts\fP] [\fIgfile\fP] [\fImfile\fP] [\fIlfile\fP] .fam T .fi .SH DESCRIPTION The \fBgmap\fP program computes, in a sequential way, a static mapping of a source graph onto a target graph. .PP The \fBgpart\fP program is a shortcut of \fBgmap\fP for computing unweighted partitions of a source graph. .PP Source graph file \fIgfile\fP can only be a centralized graph file. For \fBgmap\fP, the target architecture file \fItfile\fP describes either algorithmically-coded topologies such as meshes and hypercubes, or decomposition-defined architectures created by means of the \fBamk_grf\fP(1) program. The resulting mapping is stored in file \fImfile\fP. Eventual logging information (such as the one produced by option \fB-v\fP) is sent to file \fIlfile\fP. When file names are not specified, data is read from standard input and written to standard output. Standard streams can also be explicitely represented by a dash '-'. .PP When the proper libraries have been included at compile time, \fBgmap\fP and \fBgpart\fP can directly handle compressed graphs, both as input and output. A stream is treated as compressed whenever its name is postfixed with a compressed file extension, such as in 'brol.grf.bz2' or '-.gz'. The compression formats which can be supported are the bzip2 format ('.bz2'), the gzip format ('.gz'), and the lzma format ('.lzma', on input only). .SH OPTIONS .TP .B \fB-c\fPopt Choose default mapping strategy according to one or several \fIoptions\fP among: .RS .TP .B b enforce load balance as much as possible. .TP .B q privilege quality over speed (default). .TP .B s privilege speed over quality. .TP .B t enforce safety. .RE .TP .B \fB-h\fP Display some help. .TP .B \fB-m\fPstrat Use sequential mapping strategy strat (see Scotch user's manual for more information). .TP .B \fB-V\fP Display program version and copyright. .TP .B \fB-v\fPverb Set verbose mode to verb. It is a set of one of more characters which can be: .RS .TP .B m mapping information. .TP .B s strategy information. .TP .B t timing information. .SH TARGET ARCHITECTURES Target architectures represent graphs onto which source graphs are mapped. In order to speed-up the obtainment of target architecture topological properties during the computation of mappings, some classical topologies are algorithmically coded into the mapper itself. These topologies are consequently simply defined by their code name, followed by their dimensional parameters: .TP .B cmplt \fIdim\fP unweighted complete graph of size \fIdim\fP. .TP .B cmpltw \fIdim\fP \fIw0\fP \fIw1\fP \.\.\. \fIwdim-1\fP weighted complete graph of size size and of respective loads \fIw0\fP, \fIw1\fP, \.\.\., \fIwdim-1\fP. .TP .B hcub \fIdim\fP hypercube of dimension \fIdim\fP. .TP .B leaf \fIhgt\fP \fIn0\fP \fIw0\fP \.\.\. \fInhgt-1\fP \fIwhgt-1\fP tree-leaf graph of height \fIhgt\fP with (\fIn0\fP times \fIn1\fP times \.\.\. \fInhgt-1\fP) vertices, with inter-cluster link weights of \fIw0\fP, \fIw1\fP, \.\.\. \fIwhgt-1\fP. .TP .B mesh2D \fIdimX\fP \fIdimY\fP 2D mesh of \fIdimX\fP times \fIdimY\fP nodes. .TP .B mesh3D \fIdimX\fP \fIdimY\fP \fIdimZ\fP 23 mesh of \fIdimX\fP times \fIdimY\fP times \fIdimZ\fP nodes. .TP .B torus2D \fIdimX\fP \fIdimY\fP 2D torus of \fIdimX\fP times \fIdimY\fP nodes. .TP .B torus3D \fIdimX\fP \fIdimY\fP \fIdimZ\fP 3D torus of \fIdimX\fP times \fIdimY\fP times \fIdimZ\fP nodes. .PP Other target topologies can be created from their source graph description by using the \fBamk_grf\fP(1) command. In this case, the target description will begin with the code name \fBdeco\fP. .SH MAPPINGS Mappings are represented by as many lines as there are vertices in the source graph. Each of these lines is made of two figures: the number of the vertex (or its label if source graph vertices are labeled) and the index of the target vertex to which it has been assigned. Target vertex indices range from 0 to the number of vertices in the target architecture (that is, the number of parts) minus one. .PP This block of lines is always preceded by the number of such lines. In most cases, since full mappings are requested, the number of lines is equal to the number of vertices in the source graph. .SH EXAMPLES Run \fBgpart\fP to compute a partition into 7 parts of graph 'brol.grf' and save the resulting ordering to file 'brol.map'. .PP .nf .fam C $ gpart 7 brol.grf brol.map .fam T .fi Run \fBgmap\fP to compute a partition, into 3 parts of respective weights 1, 2 and 4, of graph 'brol.grf' and save the resulting mapping to file 'brol.map'. The dash '-' standard file name is used so that the target architecture description is read from the standard input, through the pipe, as provided by the 'echo' shell command. .PP .nf .fam C $ echo "cmpltw 3 1 2 4" | gmap brol.grf - brol.map .fam T .fi .SH SEE ALSO \fBamk_grf\fP(1), \fBacpl\fP(1), \fBgmtst\fP(1), \fBdgmap\fP(1). .PP Scotch user's manual. .SH AUTHOR Francois Pellegrini scotch-6.0.4.dfsg/man/man1/amk_ccc.10000644002563400244210000000660611631447171022157 0ustar trophimeutilisateurs du domaine." Text automatically generated by txt2man .TH amk_ccc 1 "August 03, 2010" "" "Scotch user's manual" .SH NAME \fBamk_ccc, amk_fft2, amk_hy, amk_m2, amk_p2 \fP- create target architectures \fB .SH SYNOPSIS .nf .fam C \fBamk_ccc\fP [\fIoptions\fP] \fIdim\fP [\fItfile\fP] .PP \fBamk_fft2\fP [\fIoptions\fP] \fIdim\fP [\fItfile\fP] .PP \fBamk_hy\fP [\fIoptions\fP] \fIdim\fP [\fItfile\fP] .PP \fBamk_m2\fP [\fIoptions\fP] \fIdimX\fP [\fIdimY\fP] [\fItfile\fP] .PP \fBamk_p2\fP [\fIoptions\fP] [\fIwght0\fP] [\fIwght1\fP] [\fItfile\fP] .fam T .fi .SH DESCRIPTION The amk_* programs create target architecture files for some common, regular topologies. .PP \fBamk_ccc\fP creates a decomposition-defined cube-connected-cycle topology of dimension \fIdim\fP. The decomposition is performed first by bisection along the dimensions of the hypercube, then along the remaining cycle graphs. .PP \fBamk_fft2\fP creates a decomposition-defined fast-Fourier-transform topology of dimension \fIdim\fP. The decomposition is performed by recursive bisection of the vertices, by descending dimension (that is, bit number in the labeling of the vertices). .PP \fBamk_hy\fP creates a decomposition-defined hypercube topology of dimension \fIdim\fP. The decomposition is performed by recursive bisection of the vertices, by descending dimension (that is, bit number in the labeling of the vertices). Save for experimentation purposes, this program is deprecated, as the algorithmically-defined 'hcub' target architecture is a more convenient and efficient way to represent hypercube architectures. .PP \fBamk_m2\fP creates a decomposition-defined 2D regular grid topology of dimensions \fIdimX\fP and \fIdimY\fP. The decomposition is performed by recursive splitting along the dimensions, either by cutting the longest one, or by one-way dissection, depending on the '\fB-m\fP' option flag. Save for experimentation purposes, this program is deprecated, as the algorithmically-defined 'mesh2D' and 'mesh3D' target architectures are a more convenient and efficient way to represent 2D and 3D grid architectures. .PP \fBamk_p2\fP creates a weighted path graph topology comprising only two vertices of weights \fIwght0\fP and \fIwght1\fP. This is just a helper program, which builds a 'wcmplt' algorithmically-defined complete graph with two vertices. It may be used to compute weighted bisections of a graph. .SH OPTIONS .TP .B \fB-m\fP\fImeth\fP For \fBamk_m2\fP only. Perform either recursive dissection or one-way dissection, according to the given method flag: .RS .TP .B n perform nested dissection (default). .TP .B o perform one-way dissection (cut across Y, then X). .RE .TP .B \fB-h\fP Display some help. .TP .B \fB-V\fP Display program version and copyright. .SH EXAMPLE Create a cube-connected-cycle target architecture of dimension 4, and save it to file 'ccc4.tgt'. .PP .nf .fam C $ amk_ccc 4 ccc4.tgt .fam T .fi Run gmap to compute a bisection, into two parts of respective weights 3 and 5, of graph 'brol.grf' and save the resulting mapping to file 'brol.map'. The dash '-' standard file name is used so that the target architecture description is read from the standard input, through the pipe. .PP .nf .fam C $ amk_p2 3 5 | gmap brol.grf - brol.map .fam T .fi .SH SEE ALSO \fBgmk_msh\fP(1), \fBgtst\fP(1), \fBgmap\fP(1), \fBgord\fP(1), \fBgout\fP(1), \fBamk_grf\fP(1). .PP Scotch user's manual. .SH AUTHOR Francois Pellegrini scotch-6.0.4.dfsg/man/man1/gout.10000644002563400244210000001150011631447171021542 0ustar trophimeutilisateurs du domaine." Text automatically generated by txt2man .TH gout 1 "August 03, 2010" "" "Scotch user's manual" .SH NAME \fBgout \fP- output graphics from matrices and graphs \fB .SH SYNOPSIS .nf .fam C \fBgout\fP [\fIoptions\fP] [\fIgfile\fP] [\fIxfile\fP] [\fImfile\fP] [\fIvfile\fP] .fam T .fi .SH DESCRIPTION The \fBgout\fP program creates graphics files of various types, representing the Scotch graph and mapping data which is passed to it. .PP Source graph file \fIgfile\fP can only be a centralized graph file. File \fIxfile\fP stores its associated geometry, whenever necessary. File \fImfile\fP represents label information attached to each of the graph vertices, for instance the index of the part to which each vertex belongs in the case of a mapping file. File \fIvfile\fP is the output graphics file, the type of which may differ according to the input parameters. When file names are not specified, data is read from standard input and written to standard output. Standard streams can also be explicitly represented by a dash '-'. .PP When the proper libraries have been included at compile time, gtst can directly handle compressed graphs, both as input and output. A stream is treated as compressed whenever its name is postfixed with a compressed file extension, such as in 'brol.grf.bz2' or '-.gz'. The compression formats which can be supported are the bzip2 format ('.bz2'), the gzip format ('.gz'), and the lzma format ('.lzma', on input only). .SH OPTIONS .TP .B \fB-h\fP Display some help. .TP .B \fB-g\fP\fIgeop\fP Geometry parameters, which can be an arbitrary combination of any of the following code letters: .RS .TP .B n Do not read geometry data, when it is not available or not required, such as when using the \fB-om\fP option. .TP .B p Permute Y and Z geometry dimensions. .TP .B r Rotate geometry by 90 degrees in the (X,Y) plane. .RE .TP .B \fB-h\fP Display some help. .TP .B \fB-mn\fP Do not read mapping data, when it is not available or not required. .TP .B \fB-o\fP\fIoutp\fP Select the output file type and allows to provide additional parameters between braces and separated by commas: .RS .TP .B i OpenInventor 3D mesh file, to be viewed by means of programs such as \fBivview\fP. Additional parameters for this output file type are: .RS .TP .B c Color output. .TP .B g Gray level output. .TP .B r Remove cut edges. .TP .B v View cut edges. .RE .TP .B m PostScript matrix pattern file. Additional parameters for this output file type are: .RS .TP .B e EPSF-type output. .TP .B f Full-page output. .RE .TP .B p PostScript 2D mesh file. This output module was intended for 2D meshes; as a fallback, the Z coordinate is projected according to isometric perspective rules, but drawings of full 3D objects are most likely to be unreadable. Additional parameters for this output file type are: .RS .TP .B c Color output. .TP .B g Gray level output. .TP .B e EPSF-type output. .TP .B f Full-page output. .TP .B s Short clipping (disks excluded). .TP .B l Large clipping (disks included). .TP .B a Avoid displaying disks. .TP .B d Display disks. .TP .B r Remove cut edges. .TP .B v View cut edges. .TP .B X=\fIrat\fP Maximum x clipping ratio (in [0.0;1.0]). .TP .B x=\fIrat\fP Minimum x clipping ratio. .TP .B Y=\fIrat\fP Maximum y clipping ratio. .TP .B y=\fIrat\fP Minimum y clipping ratio. .RE .TP .B t Tulip 3D mesh file. Additional parameters for this output file type are: .RS .TP .B b Black and white output. .TP .B c Color output. .TP .B a Avoid displaying disks. .TP .B d Display disks. .TP .B r Remove cut edges. .TP .B v View cut edges. .RE .RE .TP .B \fB-V\fP Display program version and copyright. .SH EXAMPLES Build an OpenInventor file of the mapping of graph brol.grf contained in file brol.map. Vertices with no mapping information attached to them will be rendered in white, while distinct colors will be used to represent the different parts. Cut edges will be removed: .PP .nf .fam C $ gout '-oi{r}' brol.grf brol.xyz brol.map brol.iv $ ivview brol.iv .fam T .fi Build an OpenInventor file of graph brol.grf without any vertex information associated to it. Mapping data are not required and will not be read, but a file name has to be provided, hence the '-': .PP .nf .fam C $ gout -oi -mn brol.grf brol.xyz - brol.iv .fam T .fi Output the pattern of matrix brol.grf on the form of a PostScript flat drawing. Geometry and mapping data are not required and will not be read, but file names have to be provided, hence the two '-'s: .PP .nf .fam C $ gout -om -gn -mn brol.grf - - brol.ps .fam T .fi Output a PostScript 2D drawing of a rectangular portion graph brol.grf, with disks representing mapping data: .PP .nf .fam C $ gout '-op{c,e,d,x=0.3,X=0.6,y=0.2,Y=0.5}' brol.grf brol.xyz brol.map brol.ps .fam T .fi .SH SEE ALSO \fBgmap\fP(1), \fBgout\fP(1), \fBgtst\fP(1). .PP Scotch user's manual. .SH AUTHOR Francois Pellegrini scotch-6.0.4.dfsg/man/man1/gcv.10000644002563400244210000000476011631447171021355 0ustar trophimeutilisateurs du domaine." Text automatically generated by txt2man .TH gcv 1 "August 03, 2010" "" "Scotch user's manual" .SH NAME \fBgcv \fP- graph file converter \fB .SH SYNOPSIS .nf .fam C \fBgcv\fP [\fIoptions\fP] [\fIigfile\fP] [\fIogfile\fP] [\fIoxfile\fP] .fam T .fi .SH DESCRIPTION The \fBgcv\fP program converts Scotch graph files from and to other external file formats. .PP File \fIigfile\fP is converted into graph file \fIogfile\fP, with optional geometry data being put in geometry file \fIoxfile\fP, if it is available. .PP When file names are not specified, data is read from standard input and written to standard output. Standard streams can also be explicitly represented by a dash '-'. .PP When the proper libraries have been included at compile time, dgtst can directly handle compressed graphs, both as input and output. A stream is treated as compressed whenever its name is postfixed with a compressed file extension, such as in 'brol.grf.bz2' or '-.gz'. The compression formats which can be supported are the bzip2 format ('.bz2'), the gzip format ('.gz'), and the lzma format ('.lzma', on input only). .SH OPTIONS .TP .B \fB-h\fP Display some help. .TP .B \fB-i\fP\fIifmt\fP Set format of input graph file, which can be: .RS .TP .B b\fInum\fP Boeing-Harwell format. This is a matrix format. Only square matrices are supported. Square matrices with unsymmetric pattern are symmetrized. In case the file contains several matrices, the \fInum\fP parameter allow the user to provide the index of the matrix to convert, starting from 0. When the \fInum\fP parameter is not set, it is assumed to be 0. .TP .B c Chaco format. This is an adjacency graph format, also used by MeTiS. .TP .B m Matrix Market format. This is a matrix format describing individual edges. Matrix pattern is symmetrized, such that rectangular matrices are eventually squared. .TP .B s Scotch graph format. This is an adjacency graph format. .RE .TP .B \fB-o\fP\fIofmt\fP Set format of output graph file, which can be: .RS .TP .B c Chaco format. .TP .B m Matrix Market symmetric pattern format. .TP .B s Scotch format. This is the default. .RE .TP .B \fB-V\fP Display program version and copyright. .SH EXAMPLE Convert a Matrix Market graph into a Scotch graph. Matrix Market files do not comprise geometry data, so no geometry file is needed on output: .PP .nf .fam C $ gcv -im brol.mm brol.grf .fam T .fi .SH SEE ALSO \fBgtst\fP(1), \fBgmap\fP(1), \fBgord\fP(1), \fBgout\fP(1). .PP Scotch user's manual. .SH AUTHOR Francois Pellegrini scotch-6.0.4.dfsg/man/man1/gmk_m2.10000644002563400244210000000002211631447171021735 0ustar trophimeutilisateurs du domaine.so man1/gmk_hy.1 scotch-6.0.4.dfsg/bin/0000755002563400244210000000000012407352724017647 5ustar trophimeutilisateurs du domainescotch-6.0.4.dfsg/doc/0000755002563400244210000000000012777635157017662 5ustar trophimeutilisateurs du domainescotch-6.0.4.dfsg/doc/CeCILL-C_V1-en.txt0000644002563400244210000005254711631447171022542 0ustar trophimeutilisateurs du domaine CeCILL-C FREE SOFTWARE LICENSE AGREEMENT Notice This Agreement is a Free Software license agreement that is the result of discussions between its authors in order to ensure compliance with the two main principles guiding its drafting: * firstly, compliance with the principles governing the distribution of Free Software: access to source code, broad rights granted to users, * secondly, the election of a governing law, French law, with which it is conformant, both as regards the law of torts and intellectual property law, and the protection that it offers to both authors and holders of the economic rights over software. The authors of the CeCILL-C (for Ce[a] C[nrs] I[nria] L[ogiciel] L[ibre]) license are: Commissariat l'Energie Atomique - CEA, a public scientific, technical and industrial research establishment, having its principal place of business at 25 rue Leblanc, immeuble Le Ponant D, 75015 Paris, France. Centre National de la Recherche Scientifique - CNRS, a public scientific and technological establishment, having its principal place of business at 3 rue Michel-Ange, 75794 Paris cedex 16, France. Institut National de Recherche en Informatique et en Automatique - INRIA, a public scientific and technological establishment, having its principal place of business at Domaine de Voluceau, Rocquencourt, BP 105, 78153 Le Chesnay cedex, France. Preamble The purpose of this Free Software license agreement is to grant users the right to modify and re-use the software governed by this license. The exercising of this right is conditional upon the obligation to make available to the community the modifications made to the source code of the software so as to contribute to its evolution. In consideration of access to the source code and the rights to copy, modify and redistribute granted by the license, users are provided only with a limited warranty and the software's author, the holder of the economic rights, and the successive licensors only have limited liability. In this respect, the risks associated with loading, using, modifying and/or developing or reproducing the software by the user are brought to the user's attention, given its Free Software status, which may make it complicated to use, with the result that its use is reserved for developers and experienced professionals having in-depth computer knowledge. Users are therefore encouraged to load and test the suitability of the software as regards their requirements in conditions enabling the security of their systems and/or data to be ensured and, more generally, to use and operate it in the same conditions of security. This Agreement may be freely reproduced and published, provided it is not altered, and that no provisions are either added or removed herefrom. This Agreement may apply to any or all software for which the holder of the economic rights decides to submit the use thereof to its provisions. Article 1 - DEFINITIONS For the purpose of this Agreement, when the following expressions commence with a capital letter, they shall have the following meaning: Agreement: means this license agreement, and its possible subsequent versions and annexes. Software: means the software in its Object Code and/or Source Code form and, where applicable, its documentation, "as is" when the Licensee accepts the Agreement. Initial Software: means the Software in its Source Code and possibly its Object Code form and, where applicable, its documentation, "as is" when it is first distributed under the terms and conditions of the Agreement. Modified Software: means the Software modified by at least one Integrated Contribution. Source Code: means all the Software's instructions and program lines to which access is required so as to modify the Software. Object Code: means the binary files originating from the compilation of the Source Code. Holder: means the holder(s) of the economic rights over the Initial Software. Licensee: means the Software user(s) having accepted the Agreement. Contributor: means a Licensee having made at least one Integrated Contribution. Licensor: means the Holder, or any other individual or legal entity, who distributes the Software under the Agreement. Integrated Contribution: means any or all modifications, corrections, translations, adaptations and/or new functions integrated into the Source Code by any or all Contributors. Related Module: means a set of sources files including their documentation that, without modification to the Source Code, enables supplementary functions or services in addition to those offered by the Software. Derivative Software: means any combination of the Software, modified or not, and of a Related Module. Parties: mean both the Licensee and the Licensor. These expressions may be used both in singular and plural form. Article 2 - PURPOSE The purpose of the Agreement is the grant by the Licensor to the Licensee of a non-exclusive, transferable and worldwide license for the Software as set forth in Article 5 hereinafter for the whole term of the protection granted by the rights over said Software. Article 3 - ACCEPTANCE 3.1 The Licensee shall be deemed as having accepted the terms and conditions of this Agreement upon the occurrence of the first of the following events: * (i) loading the Software by any or all means, notably, by downloading from a remote server, or by loading from a physical medium; * (ii) the first time the Licensee exercises any of the rights granted hereunder. 3.2 One copy of the Agreement, containing a notice relating to the characteristics of the Software, to the limited warranty, and to the fact that its use is restricted to experienced users has been provided to the Licensee prior to its acceptance as set forth in Article 3.1 hereinabove, and the Licensee hereby acknowledges that it has read and understood it. Article 4 - EFFECTIVE DATE AND TERM 4.1 EFFECTIVE DATE The Agreement shall become effective on the date when it is accepted by the Licensee as set forth in Article 3.1. 4.2 TERM The Agreement shall remain in force for the entire legal term of protection of the economic rights over the Software. Article 5 - SCOPE OF RIGHTS GRANTED The Licensor hereby grants to the Licensee, who accepts, the following rights over the Software for any or all use, and for the term of the Agreement, on the basis of the terms and conditions set forth hereinafter. Besides, if the Licensor owns or comes to own one or more patents protecting all or part of the functions of the Software or of its components, the Licensor undertakes not to enforce the rights granted by these patents against successive Licensees using, exploiting or modifying the Software. If these patents are transferred, the Licensor undertakes to have the transferees subscribe to the obligations set forth in this paragraph. 5.1 RIGHT OF USE The Licensee is authorized to use the Software, without any limitation as to its fields of application, with it being hereinafter specified that this comprises: 1. permanent or temporary reproduction of all or part of the Software by any or all means and in any or all form. 2. loading, displaying, running, or storing the Software on any or all medium. 3. entitlement to observe, study or test its operation so as to determine the ideas and principles behind any or all constituent elements of said Software. This shall apply when the Licensee carries out any or all loading, displaying, running, transmission or storage operation as regards the Software, that it is entitled to carry out hereunder. 5.2 RIGHT OF MODIFICATION The right of modification includes the right to translate, adapt, arrange, or make any or all modifications to the Software, and the right to reproduce the resulting software. It includes, in particular, the right to create a Derivative Software. The Licensee is authorized to make any or all modification to the Software provided that it includes an explicit notice that it is the author of said modification and indicates the date of the creation thereof. 5.3 RIGHT OF DISTRIBUTION In particular, the right of distribution includes the right to publish, transmit and communicate the Software to the general public on any or all medium, and by any or all means, and the right to market, either in consideration of a fee, or free of charge, one or more copies of the Software by any means. The Licensee is further authorized to distribute copies of the modified or unmodified Software to third parties according to the terms and conditions set forth hereinafter. 5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION The Licensee is authorized to distribute true copies of the Software in Source Code or Object Code form, provided that said distribution complies with all the provisions of the Agreement and is accompanied by: 1. a copy of the Agreement, 2. a notice relating to the limitation of both the Licensor's warranty and liability as set forth in Articles 8 and 9, and that, in the event that only the Object Code of the Software is redistributed, the Licensee allows effective access to the full Source Code of the Software at a minimum during the entire period of its distribution of the Software, it being understood that the additional cost of acquiring the Source Code shall not exceed the cost of transferring the data. 5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE When the Licensee makes an Integrated Contribution to the Software, the terms and conditions for the distribution of the resulting Modified Software become subject to all the provisions of this Agreement. The Licensee is authorized to distribute the Modified Software, in source code or object code form, provided that said distribution complies with all the provisions of the Agreement and is accompanied by: 1. a copy of the Agreement, 2. a notice relating to the limitation of both the Licensor's warranty and liability as set forth in Articles 8 and 9, and that, in the event that only the object code of the Modified Software is redistributed, the Licensee allows effective access to the full source code of the Modified Software at a minimum during the entire period of its distribution of the Modified Software, it being understood that the additional cost of acquiring the source code shall not exceed the cost of transferring the data. 5.3.3 DISTRIBUTION OF DERIVATIVE SOFTWARE When the Licensee creates Derivative Software, this Derivative Software may be distributed under a license agreement other than this Agreement, subject to compliance with the requirement to include a notice concerning the rights over the Software as defined in Article 6.4. In the event the creation of the Derivative Software required modification of the Source Code, the Licensee undertakes that: 1. the resulting Modified Software will be governed by this Agreement, 2. the Integrated Contributions in the resulting Modified Software will be clearly identified and documented, 3. the Licensee will allow effective access to the source code of the Modified Software, at a minimum during the entire period of distribution of the Derivative Software, such that such modifications may be carried over in a subsequent version of the Software; it being understood that the additional cost of purchasing the source code of the Modified Software shall not exceed the cost of transferring the data. 5.3.4 COMPATIBILITY WITH THE CeCILL LICENSE When a Modified Software contains an Integrated Contribution subject to the CeCILL license agreement, or when a Derivative Software contains a Related Module subject to the CeCILL license agreement, the provisions set forth in the third item of Article 6.4 are optional. Article 6 - INTELLECTUAL PROPERTY 6.1 OVER THE INITIAL SOFTWARE The Holder owns the economic rights over the Initial Software. Any or all use of the Initial Software is subject to compliance with the terms and conditions under which the Holder has elected to distribute its work and no one shall be entitled to modify the terms and conditions for the distribution of said Initial Software. The Holder undertakes that the Initial Software will remain ruled at least by this Agreement, for the duration set forth in Article 4.2. 6.2 OVER THE INTEGRATED CONTRIBUTIONS The Licensee who develops an Integrated Contribution is the owner of the intellectual property rights over this Contribution as defined by applicable law. 6.3 OVER THE RELATED MODULES The Licensee who develops a Related Module is the owner of the intellectual property rights over this Related Module as defined by applicable law and is free to choose the type of agreement that shall govern its distribution under the conditions defined in Article 5.3.3. 6.4 NOTICE OF RIGHTS The Licensee expressly undertakes: 1. not to remove, or modify, in any manner, the intellectual property notices attached to the Software; 2. to reproduce said notices, in an identical manner, in the copies of the Software modified or not; 3. to ensure that use of the Software, its intellectual property notices and the fact that it is governed by the Agreement is indicated in a text that is easily accessible, specifically from the interface of any Derivative Software. The Licensee undertakes not to directly or indirectly infringe the intellectual property rights of the Holder and/or Contributors on the Software and to take, where applicable, vis--vis its staff, any and all measures required to ensure respect of said intellectual property rights of the Holder and/or Contributors. Article 7 - RELATED SERVICES 7.1 Under no circumstances shall the Agreement oblige the Licensor to provide technical assistance or maintenance services for the Software. However, the Licensor is entitled to offer this type of services. The terms and conditions of such technical assistance, and/or such maintenance, shall be set forth in a separate instrument. Only the Licensor offering said maintenance and/or technical assistance services shall incur liability therefor. 7.2 Similarly, any Licensor is entitled to offer to its licensees, under its sole responsibility, a warranty, that shall only be binding upon itself, for the redistribution of the Software and/or the Modified Software, under terms and conditions that it is free to decide. Said warranty, and the financial terms and conditions of its application, shall be subject of a separate instrument executed between the Licensor and the Licensee. Article 8 - LIABILITY 8.1 Subject to the provisions of Article 8.2, the Licensee shall be entitled to claim compensation for any direct loss it may have suffered from the Software as a result of a fault on the part of the relevant Licensor, subject to providing evidence thereof. 8.2 The Licensor's liability is limited to the commitments made under this Agreement and shall not be incurred as a result of in particular: (i) loss due the Licensee's total or partial failure to fulfill its obligations, (ii) direct or consequential loss that is suffered by the Licensee due to the use or performance of the Software, and (iii) more generally, any consequential loss. In particular the Parties expressly agree that any or all pecuniary or business loss (i.e. loss of data, loss of profits, operating loss, loss of customers or orders, opportunity cost, any disturbance to business activities) or any or all legal proceedings instituted against the Licensee by a third party, shall constitute consequential loss and shall not provide entitlement to any or all compensation from the Licensor. Article 9 - WARRANTY 9.1 The Licensee acknowledges that the scientific and technical state-of-the-art when the Software was distributed did not enable all possible uses to be tested and verified, nor for the presence of possible defects to be detected. In this respect, the Licensee's attention has been drawn to the risks associated with loading, using, modifying and/or developing and reproducing the Software which are reserved for experienced users. The Licensee shall be responsible for verifying, by any or all means, the suitability of the product for its requirements, its good working order, and for ensuring that it shall not cause damage to either persons or properties. 9.2 The Licensor hereby represents, in good faith, that it is entitled to grant all the rights over the Software (including in particular the rights set forth in Article 5). 9.3 The Licensee acknowledges that the Software is supplied "as is" by the Licensor without any other express or tacit warranty, other than that provided for in Article 9.2 and, in particular, without any warranty as to its commercial value, its secured, safe, innovative or relevant nature. Specifically, the Licensor does not warrant that the Software is free from any error, that it will operate without interruption, that it will be compatible with the Licensee's own equipment and software configuration, nor that it will meet the Licensee's requirements. 9.4 The Licensor does not either expressly or tacitly warrant that the Software does not infringe any third party intellectual property right relating to a patent, software or any other property right. Therefore, the Licensor disclaims any and all liability towards the Licensee arising out of any or all proceedings for infringement that may be instituted in respect of the use, modification and redistribution of the Software. Nevertheless, should such proceedings be instituted against the Licensee, the Licensor shall provide it with technical and legal assistance for its defense. Such technical and legal assistance shall be decided on a case-by-case basis between the relevant Licensor and the Licensee pursuant to a memorandum of understanding. The Licensor disclaims any and all liability as regards the Licensee's use of the name of the Software. No warranty is given as regards the existence of prior rights over the name of the Software or as regards the existence of a trademark. Article 10 - TERMINATION 10.1 In the event of a breach by the Licensee of its obligations hereunder, the Licensor may automatically terminate this Agreement thirty (30) days after notice has been sent to the Licensee and has remained ineffective. 10.2 A Licensee whose Agreement is terminated shall no longer be authorized to use, modify or distribute the Software. However, any licenses that it may have granted prior to termination of the Agreement shall remain valid subject to their having been granted in compliance with the terms and conditions hereof. Article 11 - MISCELLANEOUS 11.1 EXCUSABLE EVENTS Neither Party shall be liable for any or all delay, or failure to perform the Agreement, that may be attributable to an event of force majeure, an act of God or an outside cause, such as defective functioning or interruptions of the electricity or telecommunications networks, network paralysis following a virus attack, intervention by government authorities, natural disasters, water damage, earthquakes, fire, explosions, strikes and labor unrest, war, etc. 11.2 Any failure by either Party, on one or more occasions, to invoke one or more of the provisions hereof, shall under no circumstances be interpreted as being a waiver by the interested Party of its right to invoke said provision(s) subsequently. 11.3 The Agreement cancels and replaces any or all previous agreements, whether written or oral, between the Parties and having the same purpose, and constitutes the entirety of the agreement between said Parties concerning said purpose. No supplement or modification to the terms and conditions hereof shall be effective as between the Parties unless it is made in writing and signed by their duly authorized representatives. 11.4 In the event that one or more of the provisions hereof were to conflict with a current or future applicable act or legislative text, said act or legislative text shall prevail, and the Parties shall make the necessary amendments so as to comply with said act or legislative text. All other provisions shall remain effective. Similarly, invalidity of a provision of the Agreement, for any reason whatsoever, shall not cause the Agreement as a whole to be invalid. 11.5 LANGUAGE The Agreement is drafted in both French and English and both versions are deemed authentic. Article 12 - NEW VERSIONS OF THE AGREEMENT 12.1 Any person is authorized to duplicate and distribute copies of this Agreement. 12.2 So as to ensure coherence, the wording of this Agreement is protected and may only be modified by the authors of the License, who reserve the right to periodically publish updates or new versions of the Agreement, each with a separate number. These subsequent versions may address new issues encountered by Free Software. 12.3 Any Software distributed under a given version of the Agreement may only be subsequently distributed under the same version of the Agreement or a subsequent version. Article 13 - GOVERNING LAW AND JURISDICTION 13.1 The Agreement is governed by French law. The Parties agree to endeavor to seek an amicable solution to any disagreements or disputes that may arise during the performance of the Agreement. 13.2 Failing an amicable solution within two (2) months as from their occurrence, and unless emergency proceedings are necessary, the disagreements or disputes shall be referred to the Paris Courts having jurisdiction, by the more diligent Party. Version 1.0 dated 2006-09-05. scotch-6.0.4.dfsg/doc/CeCILL-C_V1-fr.txt0000644002563400244210000005314611631447171022543 0ustar trophimeutilisateurs du domaine CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL-C Avertissement Ce contrat est une licence de logiciel libre issue d'une concertation entre ses auteurs afin que le respect de deux grands principes prside sa rdaction: * d'une part, le respect des principes de diffusion des logiciels libres: accs au code source, droits tendus confrs aux utilisateurs, * d'autre part, la dsignation d'un droit applicable, le droit franais, auquel elle est conforme, tant au regard du droit de la responsabilit civile que du droit de la proprit intellectuelle et de la protection qu'il offre aux auteurs et titulaires des droits patrimoniaux sur un logiciel. Les auteurs de la licence CeCILL-C (pour Ce[a] C[nrs] I[nria] L[ogiciel] L[ibre]) sont: Commissariat l'Energie Atomique - CEA, tablissement public de recherche caractre scientifique, technique et industriel, dont le sige est situ 25 rue Leblanc, immeuble Le Ponant D, 75015 Paris. Centre National de la Recherche Scientifique - CNRS, tablissement public caractre scientifique et technologique, dont le sige est situ 3 rue Michel-Ange, 75794 Paris cedex 16. Institut National de Recherche en Informatique et en Automatique - INRIA, tablissement public caractre scientifique et technologique, dont le sige est situ Domaine de Voluceau, Rocquencourt, BP 105, 78153 Le Chesnay cedex. Prambule Ce contrat est une licence de logiciel libre dont l'objectif est de confrer aux utilisateurs la libert de modifier et de rutiliser le logiciel rgi par cette licence. L'exercice de cette libert est assorti d'une obligation de remettre la disposition de la communaut les modifications apportes au code source du logiciel afin de contribuer son volution. L'accessibilit au code source et les droits de copie, de modification et de redistribution qui dcoulent de ce contrat ont pour contrepartie de n'offrir aux utilisateurs qu'une garantie limite et de ne faire peser sur l'auteur du logiciel, le titulaire des droits patrimoniaux et les concdants successifs qu'une responsabilit restreinte. A cet gard l'attention de l'utilisateur est attire sur les risques associs au chargement, l'utilisation, la modification et/ou au dveloppement et la reproduction du logiciel par l'utilisateur tant donn sa spcificit de logiciel libre, qui peut le rendre complexe manipuler et qui le rserve donc des dveloppeurs ou des professionnels avertis possdant des connaissances informatiques approfondies. Les utilisateurs sont donc invits charger et tester l'adquation du logiciel leurs besoins dans des conditions permettant d'assurer la scurit de leurs systmes et/ou de leurs donnes et, plus gnralement, l'utiliser et l'exploiter dans les mmes conditions de scurit. Ce contrat peut tre reproduit et diffus librement, sous rserve de le conserver en l'tat, sans ajout ni suppression de clauses. Ce contrat est susceptible de s'appliquer tout logiciel dont le titulaire des droits patrimoniaux dcide de soumettre l'exploitation aux dispositions qu'il contient. Article 1 - DEFINITIONS Dans ce contrat, les termes suivants, lorsqu'ils seront crits avec une lettre capitale, auront la signification suivante: Contrat: dsigne le prsent contrat de licence, ses ventuelles versions postrieures et annexes. Logiciel: dsigne le logiciel sous sa forme de Code Objet et/ou de Code Source et le cas chant sa documentation, dans leur tat au moment de l'acceptation du Contrat par le Licenci. Logiciel Initial: dsigne le Logiciel sous sa forme de Code Source et ventuellement de Code Objet et le cas chant sa documentation, dans leur tat au moment de leur premire diffusion sous les termes du Contrat. Logiciel Modifi: dsigne le Logiciel modifi par au moins une Contribution Intgre. Code Source: dsigne l'ensemble des instructions et des lignes de programme du Logiciel et auquel l'accs est ncessaire en vue de modifier le Logiciel. Code Objet: dsigne les fichiers binaires issus de la compilation du Code Source. Titulaire: dsigne le ou les dtenteurs des droits patrimoniaux d'auteur sur le Logiciel Initial. Licenci: dsigne le ou les utilisateurs du Logiciel ayant accept le Contrat. Contributeur: dsigne le Licenci auteur d'au moins une Contribution Intgre. Concdant: dsigne le Titulaire ou toute personne physique ou morale distribuant le Logiciel sous le Contrat. Contribution Intgre: dsigne l'ensemble des modifications, corrections, traductions, adaptations et/ou nouvelles fonctionnalits intgres dans le Code Source par tout Contributeur. Module Li: dsigne un ensemble de fichiers sources y compris leur documentation qui, sans modification du Code Source, permet de raliser des fonctionnalits ou services supplmentaires ceux fournis par le Logiciel. Logiciel Driv: dsigne toute combinaison du Logiciel, modifi ou non, et d'un Module Li. Parties: dsigne collectivement le Licenci et le Concdant. Ces termes s'entendent au singulier comme au pluriel. Article 2 - OBJET Le Contrat a pour objet la concession par le Concdant au Licenci d'une licence non exclusive, cessible et mondiale du Logiciel telle que dfinie ci-aprs l'article 5 pour toute la dure de protection des droits portant sur ce Logiciel. Article 3 - ACCEPTATION 3.1 L'acceptation par le Licenci des termes du Contrat est rpute acquise du fait du premier des faits suivants: * (i) le chargement du Logiciel par tout moyen notamment par tlchargement partir d'un serveur distant ou par chargement partir d'un support physique; * (ii) le premier exercice par le Licenci de l'un quelconque des droits concds par le Contrat. 3.2 Un exemplaire du Contrat, contenant notamment un avertissement relatif aux spcificits du Logiciel, la restriction de garantie et la limitation un usage par des utilisateurs expriments a t mis disposition du Licenci pralablement son acceptation telle que dfinie l'article 3.1 ci dessus et le Licenci reconnat en avoir pris connaissance. Article 4 - ENTREE EN VIGUEUR ET DUREE 4.1 ENTREE EN VIGUEUR Le Contrat entre en vigueur la date de son acceptation par le Licenci telle que dfinie en 3.1. 4.2 DUREE Le Contrat produira ses effets pendant toute la dure lgale de protection des droits patrimoniaux portant sur le Logiciel. Article 5 - ETENDUE DES DROITS CONCEDES Le Concdant concde au Licenci, qui accepte, les droits suivants sur le Logiciel pour toutes destinations et pour la dure du Contrat dans les conditions ci-aprs dtailles. Par ailleurs, si le Concdant dtient ou venait dtenir un ou plusieurs brevets d'invention protgeant tout ou partie des fonctionnalits du Logiciel ou de ses composants, il s'engage ne pas opposer les ventuels droits confrs par ces brevets aux Licencis successifs qui utiliseraient, exploiteraient ou modifieraient le Logiciel. En cas de cession de ces brevets, le Concdant s'engage faire reprendre les obligations du prsent alina aux cessionnaires. 5.1 DROIT D'UTILISATION Le Licenci est autoris utiliser le Logiciel, sans restriction quant aux domaines d'application, tant ci-aprs prcis que cela comporte: 1. la reproduction permanente ou provisoire du Logiciel en tout ou partie par tout moyen et sous toute forme. 2. le chargement, l'affichage, l'excution, ou le stockage du Logiciel sur tout support. 3. la possibilit d'en observer, d'en tudier, ou d'en tester le fonctionnement afin de dterminer les ides et principes qui sont la base de n'importe quel lment de ce Logiciel; et ceci, lorsque le Licenci effectue toute opration de chargement, d'affichage, d'excution, de transmission ou de stockage du Logiciel qu'il est en droit d'effectuer en vertu du Contrat. 5.2 DROIT DE MODIFICATION Le droit de modification comporte le droit de traduire, d'adapter, d'arranger ou d'apporter toute autre modification au Logiciel et le droit de reproduire le logiciel en rsultant. Il comprend en particulier le droit de crer un Logiciel Driv. Le Licenci est autoris apporter toute modification au Logiciel sous rserve de mentionner, de faon explicite, son nom en tant qu'auteur de cette modification et la date de cration de celle-ci. 5.3 DROIT DE DISTRIBUTION Le droit de distribution comporte notamment le droit de diffuser, de transmettre et de communiquer le Logiciel au public sur tout support et par tout moyen ainsi que le droit de mettre sur le march titre onreux ou gratuit, un ou des exemplaires du Logiciel par tout procd. Le Licenci est autoris distribuer des copies du Logiciel, modifi ou non, des tiers dans les conditions ci-aprs dtailles. 5.3.1 DISTRIBUTION DU LOGICIEL SANS MODIFICATION Le Licenci est autoris distribuer des copies conformes du Logiciel, sous forme de Code Source ou de Code Objet, condition que cette distribution respecte les dispositions du Contrat dans leur totalit et soit accompagne: 1. d'un exemplaire du Contrat, 2. d'un avertissement relatif la restriction de garantie et de responsabilit du Concdant telle que prvue aux articles 8 et 9, et que, dans le cas o seul le Code Objet du Logiciel est redistribu, le Licenci permette un accs effectif au Code Source complet du Logiciel pendant au moins toute la dure de sa distribution du Logiciel, tant entendu que le cot additionnel d'acquisition du Code Source ne devra pas excder le simple cot de transfert des donnes. 5.3.2 DISTRIBUTION DU LOGICIEL MODIFIE Lorsque le Licenci apporte une Contribution Intgre au Logiciel, les conditions de distribution du Logiciel Modifi en rsultant sont alors soumises l'intgralit des dispositions du Contrat. Le Licenci est autoris distribuer le Logiciel Modifi sous forme de code source ou de code objet, condition que cette distribution respecte les dispositions du Contrat dans leur totalit et soit accompagne: 1. d'un exemplaire du Contrat, 2. d'un avertissement relatif la restriction de garantie et de responsabilit du Concdant telle que prvue aux articles 8 et 9, et que, dans le cas o seul le code objet du Logiciel Modifi est redistribu, le Licenci permette un accs effectif son code source complet pendant au moins toute la dure de sa distribution du Logiciel Modifi, tant entendu que le cot additionnel d'acquisition du code source ne devra pas excder le simple cot de transfert des donnes. 5.3.3 DISTRIBUTION DU LOGICIEL DERIVE Lorsque le Licenci cre un Logiciel Driv, ce Logiciel Driv peut tre distribu sous un contrat de licence autre que le prsent Contrat condition de respecter les obligations de mention des droits sur le Logiciel telles que dfinies l'article 6.4. Dans le cas o la cration du Logiciel Driv a ncessit une modification du Code Source le licenci s'engage ce que: 1. le Logiciel Modifi correspondant cette modification soit rgi par le prsent Contrat, 2. les Contributions Intgres dont le Logiciel Modifi rsulte soient clairement identifies et documentes, 3. le Licenci permette un accs effectif au code source du Logiciel Modifi, pendant au moins toute la dure de la distribution du Logiciel Driv, de telle sorte que ces modifications puissent tre reprises dans une version ultrieure du Logiciel, tant entendu que le cot additionnel d'acquisition du code source du Logiciel Modifi ne devra pas excder le simple cot du transfert des donnes. 5.3.4 COMPATIBILITE AVEC LA LICENCE CeCILL Lorsqu'un Logiciel Modifi contient une Contribution Intgre soumise au contrat de licence CeCILL, ou lorsqu'un Logiciel Driv contient un Module Li soumis au contrat de licence CeCILL, les stipulations prvues au troisime item de l'article 6.4 sont facultatives. Article 6 - PROPRIETE INTELLECTUELLE 6.1 SUR LE LOGICIEL INITIAL Le Titulaire est dtenteur des droits patrimoniaux sur le Logiciel Initial. Toute utilisation du Logiciel Initial est soumise au respect des conditions dans lesquelles le Titulaire a choisi de diffuser son oeuvre et nul autre n'a la facult de modifier les conditions de diffusion de ce Logiciel Initial. Le Titulaire s'engage ce que le Logiciel Initial reste au moins rgi par le Contrat et ce, pour la dure vise l'article 4.2. 6.2 SUR LES CONTRIBUTIONS INTEGREES Le Licenci qui a dvelopp une Contribution Intgre est titulaire sur celle-ci des droits de proprit intellectuelle dans les conditions dfinies par la lgislation applicable. 6.3 SUR LES MODULES LIES Le Licenci qui a dvelopp un Module Li est titulaire sur celui-ci des droits de proprit intellectuelle dans les conditions dfinies par la lgislation applicable et reste libre du choix du contrat rgissant sa diffusion dans les conditions dfinies l'article 5.3.3. 6.4 MENTIONS DES DROITS Le Licenci s'engage expressment: 1. ne pas supprimer ou modifier de quelque manire que ce soit les mentions de proprit intellectuelle apposes sur le Logiciel; 2. reproduire l'identique lesdites mentions de proprit intellectuelle sur les copies du Logiciel modifi ou non; 3. faire en sorte que l'utilisation du Logiciel, ses mentions de proprit intellectuelle et le fait qu'il est rgi par le Contrat soient indiqus dans un texte facilement accessible notamment depuis l'interface de tout Logiciel Driv. Le Licenci s'engage ne pas porter atteinte, directement ou indirectement, aux droits de proprit intellectuelle du Titulaire et/ou des Contributeurs sur le Logiciel et prendre, le cas chant, l'gard de son personnel toutes les mesures ncessaires pour assurer le respect des dits droits de proprit intellectuelle du Titulaire et/ou des Contributeurs. Article 7 - SERVICES ASSOCIES 7.1 Le Contrat n'oblige en aucun cas le Concdant la ralisation de prestations d'assistance technique ou de maintenance du Logiciel. Cependant le Concdant reste libre de proposer ce type de services. Les termes et conditions d'une telle assistance technique et/ou d'une telle maintenance seront alors dtermins dans un acte spar. Ces actes de maintenance et/ou assistance technique n'engageront que la seule responsabilit du Concdant qui les propose. 7.2 De mme, tout Concdant est libre de proposer, sous sa seule responsabilit, ses licencis une garantie, qui n'engagera que lui, lors de la redistribution du Logiciel et/ou du Logiciel Modifi et ce, dans les conditions qu'il souhaite. Cette garantie et les modalits financires de son application feront l'objet d'un acte spar entre le Concdant et le Licenci. Article 8 - RESPONSABILITE 8.1 Sous rserve des dispositions de l'article 8.2, le Licenci a la facult, sous rserve de prouver la faute du Concdant concern, de solliciter la rparation du prjudice direct qu'il subirait du fait du Logiciel et dont il apportera la preuve. 8.2 La responsabilit du Concdant est limite aux engagements pris en application du Contrat et ne saurait tre engage en raison notamment: (i) des dommages dus l'inexcution, totale ou partielle, de ses obligations par le Licenci, (ii) des dommages directs ou indirects dcoulant de l'utilisation ou des performances du Logiciel subis par le Licenci et (iii) plus gnralement d'un quelconque dommage indirect. En particulier, les Parties conviennent expressment que tout prjudice financier ou commercial (par exemple perte de donnes, perte de bnfices, perte d'exploitation, perte de clientle ou de commandes, manque gagner, trouble commercial quelconque) ou toute action dirige contre le Licenci par un tiers, constitue un dommage indirect et n'ouvre pas droit rparation par le Concdant. Article 9 - GARANTIE 9.1 Le Licenci reconnat que l'tat actuel des connaissances scientifiques et techniques au moment de la mise en circulation du Logiciel ne permet pas d'en tester et d'en vrifier toutes les utilisations ni de dtecter l'existence d'ventuels dfauts. L'attention du Licenci a t attire sur ce point sur les risques associs au chargement, l'utilisation, la modification et/ou au dveloppement et la reproduction du Logiciel qui sont rservs des utilisateurs avertis. Il relve de la responsabilit du Licenci de contrler, par tous moyens, l'adquation du produit ses besoins, son bon fonctionnement et de s'assurer qu'il ne causera pas de dommages aux personnes et aux biens. 9.2 Le Concdant dclare de bonne foi tre en droit de concder l'ensemble des droits attachs au Logiciel (comprenant notamment les droits viss l'article 5). 9.3 Le Licenci reconnat que le Logiciel est fourni "en l'tat" par le Concdant sans autre garantie, expresse ou tacite, que celle prvue l'article 9.2 et notamment sans aucune garantie sur sa valeur commerciale, son caractre scuris, innovant ou pertinent. En particulier, le Concdant ne garantit pas que le Logiciel est exempt d'erreur, qu'il fonctionnera sans interruption, qu'il sera compatible avec l'quipement du Licenci et sa configuration logicielle ni qu'il remplira les besoins du Licenci. 9.4 Le Concdant ne garantit pas, de manire expresse ou tacite, que le Logiciel ne porte pas atteinte un quelconque droit de proprit intellectuelle d'un tiers portant sur un brevet, un logiciel ou sur tout autre droit de proprit. Ainsi, le Concdant exclut toute garantie au profit du Licenci contre les actions en contrefaon qui pourraient tre diligentes au titre de l'utilisation, de la modification, et de la redistribution du Logiciel. Nanmoins, si de telles actions sont exerces contre le Licenci, le Concdant lui apportera son aide technique et juridique pour sa dfense. Cette aide technique et juridique est dtermine au cas par cas entre le Concdant concern et le Licenci dans le cadre d'un protocole d'accord. Le Concdant dgage toute responsabilit quant l'utilisation de la dnomination du Logiciel par le Licenci. Aucune garantie n'est apporte quant l'existence de droits antrieurs sur le nom du Logiciel et sur l'existence d'une marque. Article 10 - RESILIATION 10.1 En cas de manquement par le Licenci aux obligations mises sa charge par le Contrat, le Concdant pourra rsilier de plein droit le Contrat trente (30) jours aprs notification adresse au Licenci et reste sans effet. 10.2 Le Licenci dont le Contrat est rsili n'est plus autoris utiliser, modifier ou distribuer le Logiciel. Cependant, toutes les licences qu'il aura concdes antrieurement la rsiliation du Contrat resteront valides sous rserve qu'elles aient t effectues en conformit avec le Contrat. Article 11 - DISPOSITIONS DIVERSES 11.1 CAUSE EXTERIEURE Aucune des Parties ne sera responsable d'un retard ou d'une dfaillance d'excution du Contrat qui serait d un cas de force majeure, un cas fortuit ou une cause extrieure, telle que, notamment, le mauvais fonctionnement ou les interruptions du rseau lectrique ou de tlcommunication, la paralysie du rseau lie une attaque informatique, l'intervention des autorits gouvernementales, les catastrophes naturelles, les dgts des eaux, les tremblements de terre, le feu, les explosions, les grves et les conflits sociaux, l'tat de guerre... 11.2 Le fait, par l'une ou l'autre des Parties, d'omettre en une ou plusieurs occasions de se prvaloir d'une ou plusieurs dispositions du Contrat, ne pourra en aucun cas impliquer renonciation par la Partie intresse s'en prvaloir ultrieurement. 11.3 Le Contrat annule et remplace toute convention antrieure, crite ou orale, entre les Parties sur le mme objet et constitue l'accord entier entre les Parties sur cet objet. Aucune addition ou modification aux termes du Contrat n'aura d'effet l'gard des Parties moins d'tre faite par crit et signe par leurs reprsentants dment habilits. 11.4 Dans l'hypothse o une ou plusieurs des dispositions du Contrat s'avrerait contraire une loi ou un texte applicable, existants ou futurs, cette loi ou ce texte prvaudrait, et les Parties feraient les amendements ncessaires pour se conformer cette loi ou ce texte. Toutes les autres dispositions resteront en vigueur. De mme, la nullit, pour quelque raison que ce soit, d'une des dispositions du Contrat ne saurait entraner la nullit de l'ensemble du Contrat. 11.5 LANGUE Le Contrat est rdig en langue franaise et en langue anglaise, ces deux versions faisant galement foi. Article 12 - NOUVELLES VERSIONS DU CONTRAT 12.1 Toute personne est autorise copier et distribuer des copies de ce Contrat. 12.2 Afin d'en prserver la cohrence, le texte du Contrat est protg et ne peut tre modifi que par les auteurs de la licence, lesquels se rservent le droit de publier priodiquement des mises jour ou de nouvelles versions du Contrat, qui possderont chacune un numro distinct. Ces versions ultrieures seront susceptibles de prendre en compte de nouvelles problmatiques rencontres par les logiciels libres. 12.3 Tout Logiciel diffus sous une version donne du Contrat ne pourra faire l'objet d'une diffusion ultrieure que sous la mme version du Contrat ou une version postrieure. Article 13 - LOI APPLICABLE ET COMPETENCE TERRITORIALE 13.1 Le Contrat est rgi par la loi franaise. Les Parties conviennent de tenter de rgler l'amiable les diffrends ou litiges qui viendraient se produire par suite ou l'occasion du Contrat. 13.2 A dfaut d'accord amiable dans un dlai de deux (2) mois compter de leur survenance et sauf situation relevant d'une procdure d'urgence, les diffrends ou litiges seront ports par la Partie la plus diligente devant les Tribunaux comptents de Paris. Version 1.0 du 2006-09-05. scotch-6.0.4.dfsg/doc/scotch_example.f0000644002563400244210000001114311631447171023010 0ustar trophimeutilisateurs du domaine************************************************************ ** ** ** NAME : scotch_example.f ** ** ** ** AUTHOR : Francois PELLEGRINI ** ** ** ** FUNCTION : FORTRAN testbed for the LibSCOTCH ** ** library routines. ** ** ** ** DATES : # Version 3.4 : from : 04 feb 2000 ** ** to 07 feb 2000 ** ** # Version 4.0 : from : 13 mar 2005 ** ** to 13 mar 2005 ** ** ** *234567***************************************************** PROGRAM SCOTCH_TEST IMPLICIT NONE INCLUDE "scotchf.h" DOUBLEPRECISION SCOTCHGRAPH (SCOTCH_GRAPHDIM) INTEGER VERTNBR DATA VERTNBR / 3 / INTEGER EDGENBR DATA EDGENBR / 4 / INTEGER VERTTAB (4) DATA VERTTAB / 1, 2, 4, 5 / INTEGER EDGETAB (4) DATA EDGETAB / 2, 1, 3, 2 / INTEGER INDXTAB (1) INTEGER IDXVERTNBR INTEGER IDXVERTTABIDX, IDXVENDTABIDX INTEGER IDXVELOTABIDX, IDXVLBLTABIDX INTEGER IDXEDGENBR INTEGER IDXEDGETABIDX, IDXEDLOTABIDX INTEGER IDXBASEVAL, IDXFLAGVAL INTEGER IERR PRINT *, 'Starting' CALL SCOTCHFGRAPHINIT (SCOTCHGRAPH (1), IERR) IF (IERR .NE. 0) THEN PRINT *, 'ERROR : MAIN : Cannot initialize graph' STOP ENDIF CALL SCOTCHFGRAPHBUILD (SCOTCHGRAPH (1), 1, VERTNBR, * VERTTAB (1), VERTTAB (2), * VERTTAB (1), VERTTAB (1), * EDGENBR, * EDGETAB (1), EDGETAB (1), IERR) IF (IERR .NE. 0) THEN PRINT *, 'ERROR : MAIN : Cannot build graph' STOP ENDIF CALL SCOTCHFGRAPHCHECK (SCOTCHGRAPH (1), IERR) IF (IERR .NE. 0) THEN PRINT *, 'ERROR : MAIN : Invalid check' STOP ENDIF PRINT *, 'Outputing original graph' CALL SCOTCHFGRAPHSAVE (SCOTCHGRAPH (1), 1, IERR) IF (IERR .NE. 0) THEN PRINT *, 'ERROR : MAIN : Invalid graph output' STOP ENDIF CALL SCOTCHFGRAPHDATA (SCOTCHGRAPH (1), INDXTAB (1), * IDXBASEVAL, IDXVERTNBR, * IDXVERTTABIDX, IDXVENDTABIDX, * IDXVELOTABIDX, IDXVLBLTABIDX, * IDXEDGENBR, * IDXEDGETABIDX, IDXEDLOTABIDX, * IDXFLAGVAL, IERR); IF (IERR .NE. 0) THEN PRINT *, 'ERROR : MAIN : Cannot get graph data' STOP ENDIF PRINT *, 'Number of vertices : ', IDXVERTNBR PRINT *, 'Index of verttab : ', IDXVERTTABIDX PRINT *, 'Index of vendtab : ', IDXVENDTABIDX PRINT *, 'Index of velotab : ', IDXVELOTABIDX PRINT *, 'Index of vlbltab : ', IDXVLBLTABIDX PRINT *, 'Number of edges : ', IDXEDGENBR PRINT *, 'Index of edgetab : ', IDXEDGETABIDX PRINT *, 'Index of edlotab : ', IDXEDLOTABIDX PRINT *, 'Updating vertex and edge arrays' INDXTAB (IDXVERTTABIDX + 1) = 3 INDXTAB (IDXEDGETABIDX) = 2 INDXTAB (IDXEDGETABIDX + 1) = 3 INDXTAB (IDXEDGETABIDX + 2) = 1 INDXTAB (IDXEDGETABIDX + 3) = 1 PRINT *, 'Outputting updated graph' CALL SCOTCHFGRAPHCHECK (SCOTCHGRAPH (1), IERR) IF (IERR .NE. 0) THEN PRINT *, 'ERROR : MAIN : Invalid check' STOP ENDIF CALL SCOTCHFGRAPHSAVE (SCOTCHGRAPH (1), 1, IERR) IF (IERR .NE. 0) THEN PRINT *, 'ERROR : MAIN : Invalid graph output' STOP ENDIF CALL SCOTCHFGRAPHEXIT (SCOTCHGRAPH (1), IERR) IF (IERR .NE. 0) THEN PRINT *, 'ERROR : MAIN : Cannot destroy graph' STOP ENDIF PRINT *, 'Test complete' RETURN END scotch-6.0.4.dfsg/INSTALL.txt0000644002563400244210000006376212500612501020746 0ustar trophimeutilisateurs du domaineScotch 6.0 installation instructions ==================================== 1) Mandatory tools ================== In order for you to compile Scotch and/or PT-Scotch, you must have GNU Make installed on your system, as well as an implementation of the MPI message-passing library in the case of PT-Scotch. Lex and Yacc are optional. There is a possibility to install Scotch without having Lex or Yacc, but it may require the tuning of sample Flex and Bison (i.e., the GNU equivalents of Lex and Yacc) outputs created on a Linux system, which may need some tricky work to compile on other systems, because of different C library implementations. To check if GNU Make is installed and is found first, please type: %prompt% make --version It should read: % GNU Make x.xx % Copyright (C) 20xx Free Software Foundation, Inc. etc, etc. Alternatively, if GNU Make is installed but its directory does not appear first in the PATH variable that is searched for executables, you can try to locate it using the which command: %prompt% which make If several occurences of make are found, one might be GNU Make, so try to figure out which of them. To see if lex and yacc are present, type %prompt% which lex %prompt% which yacc (or "bison", the GNU flavor of yacc) If some of these are missing, please: - check your path variable (just in case they are located in some unusual place, such as /usr/local/bin, /opt/bin, /opt/local/bin/, /opt/gnu/bin, etc). Tools such as "which", "locate" or "find" may help you find them; - ask your system administrator (highly recommended); - install a copy of GNU Make of your own (less recommended, please ask your system administrator first). GNU Make is available from the FSF website, at: http://www.gnu.org/software/make/ and http://ftp.gnu.org/pub/gnu/make/ . A GNU version of lex and yacc is also available from the very same FSF website, at: http://www.gnu.org/software/flex/ http://ftp.gnu.org/non-gnu/flex/ http://www.gnu.org/software/bison/ http://ftp.gnu.org/pub/gnu/bison/ ; - use the "last resort" files placed in a directory judiciously called "last_resort", located in subdirectory "src/libscotch". These files are: . parser_ll.c . parser_ly.h . parser_yy.c . They should be copied in the directory where object files are created, and "touch"ed so that their modification date is more recent than those of the corresponding "parser_ll.l" and "parser_yy.y" files. Then cross your fingers and hope it compiles properly on your system. Else, you will have to dig in their code to have them compile properly... The Makefile of the libScotch library has been designed so as to copy the last_resort/* files automatically when the lex or yacc tools are not found. In this case, depending on your platform, you may also have to set the "-DSCOTCH_RENAME_PARSER" flag in order for all symbols to be properly redefined (see Section 2.2). 2) Configuration ================ 2.1) Creating the "Makefile.inc" file ------------------------------------- Go to the "src/" directory. Look in the "Make.inc/" subdirectory for a configuration file which matches your system configuration. If there is none, build a proper one in the "Make.inc/" subdirectory, basing on the structure of existing ones. In particular, the Makefile.inc file contains three variables which specify which C compiler to use. Their semantic is as follows: the compiler command in variable CCS is used to compile the sequential (hence the "S" in "CCS") Scotch distribution. The compiler command in CCP is used to compile the parallel ("P") PT-Scotch distribution. The compiler command in CCD is used to compile the version of the "dummysizes" ("D") executable used for compiling PT-Scotch, as explained below. Create a symbolic link from the configuration file to the current "src/" working directory, renaming it as "Makefile.inc": %prompt% ln -s Make.inc/Makefile.inc.xxxx_xxx_xxx Makefile.inc If symbolic links are not available on your system, make a plain copy of the file to a file named "Makefile.inc" in the current "src/" working directory: %prompt% cp Make.inc/Makefile.inc.xxxx_xxx_xxx Makefile.inc Some additional scripts, designed to ease the installation of Scotch on specific platforms, are also present in subdirectories of the Make.inc directory. This is for instance the case for the mingw32 platform. 2.2) Parser symbol conflicts ---------------------------- Since Scotch uses a parser to analyze its strategy strings, it may happen that the symbols of this parser conflict with those of another parser used in a third-party library. All "Makefile.inc.*" platform configuration files which base on flex / bison are already tailored so as to prevent such conflicts. If you use other parsing tools, you may have to provide other options. Another solution is to use the pre-processed parser files of the "src/libscotch/last_resort" subdirectory (corresponding operation instructions are given in Section 1). 2.3) Integer size issues ------------------------ By default, all integers used in Scotch and PT-Scotch are of the "int" C type, corresponding to the "INTEGER" type in Fortran. To coerce the size of the Scotch integer type to 32 or 64 bits, add the "-DINTSIZE32" or "-DINTSIZE64" flags, respectively, to the C compiler flags in the Makefile.inc configuration file. If you do so, make sure to use integer types of equivalent size to declare variables passed to Scotch routines from caller C and Fortran procedures. Also, when running on 32_64-bit architectures (that is, integer types are 32-bit wide, while address types are 64-bit wide), some integer array indices returned by the Fortran interface have to be of a size equivalent to those of memory addresses, that is, 64 bits. The size of these variables is determined by the "-DIDXSIZE32" and "-DIDXSIZE64" flags, respectively. When none of them is provided, the size of the indices is assumed to be equivalent to that of the Scotch integer type. For instance, on a 32-bit architecture, you can use 64-bit integers in Scotch by just setting the "-DINTSIZE64" flag, because addresses will remain on 32 bits. On a 32_64 architecture, you can use either 32-bit or 64-bit integers in Scotch, by setting the "-DINTSIZE32" or "-DINTSIZE64" flags accordingly, but in all cases you must set the "-DIDXSIZE64" flag in order for some of the routines of the Fortran interface to operate properly, because the array indices returned by these routines have to be stored as 64-bit quantities. Of course, on 64-bit architectures, another possibility is to tune your C and Fortran compilers to make them interpret all "int" and "INTEGER" types as 64 bit values. This solution is the simplest one, as there is no need to use any of the aforementioned flags, nor to hard-code type lengths in user's code. Yet, it prevents mixing 32 and 64-bit features, and may create problems when linking PT-Scotch if a corresponding MPI library is not available. Be careful not to mismatch the 32-bit and 64-bit versions of the "scotch.h" and "ptscotch.h" include files that are generated at compile time. When several versions of Scotch are simultaneously present on a system, Make sure to place the corresponding include and library files in separate directories. Most Scotch data structures will have different sizes, depending on integer or pointer sizes. Consequently, compiling a 64-bit executable with the 32-bit version of "scotch.h" may lead to unpredictable behavior because of memory overflow. 2.4) Compression libraries -------------------------- The binaries of the Scotch distribution can handle compressed graphs in input or output. Three compressed graph formats are currently supported: bzip2, gzip and lzma. In order for them to be actually activated, the proper libraries must be available on your system. On a Linux platform, they are called "zlib" for the gzip format, "libbz2" for the bzip2 format, and "liblzma" for the lzma format. Note that it is the "development" version (also called "devel", for short, within package names) of each of these libraries which is required for the compilation to succeed. According to the libraries installed on your system, you may set flags "-DCOMMON_FILE_COMPRESS_BZ2", "-DCOMMON_FILE_COMPRESS_GZ" and/or "-DCOMMON_FILE_COMPRESS_LZMA" in the CFLAGS variable of your Makefile.inc configuration file, to have these formats and their respective extensions ".bz2", ".gz" and ".lzma", recognized and handled by Scotch. Compression and decompression are handled either by extra threads or by fork'ed child processes if threads are not available. On systems which do not provide a functional fork() system call, compressed files cannot be handled when the "-DCOMMON_PTHREAD" flag is not set (see below). 2.5) Multi-threading -------------------- Scotch can also take advantage of Posix threads when they are available. They are used in several places: - to compress and uncompress file data. This can be done either by launching a service thread, or else by creating a separate process by means of a Posix fork() system call. This choice is controlled by the "-DCOMMON_PTHREAD" flag: if it is set, threads will be used, else fork() calls will be performed. For systems which do not support the fork() system call, such as the MinGW32 platform, one can set the "-DCOMMON_STUB_FORK" flag, which creates a stub fork() routine which always returns an error. Therefore, without both fork() and threads, one must set the "-DCOMMON_STUB_FORK" flag without setting "-DCOMMON_PTHREAD", so that compilation will successfully complete; however, in this case, compressed graphs shall not be handled in practice. - to create distributed graphs in parallel. Since this task involves concurrent MPI communications, the MPI library must support the MPI_THREAD_MULTIPLE level. The use of threads within Scotch itself is controlled by the "-DSCOTCH_PTHREAD" flag, which is completely independent from the "-DCOMMON_PTHREAD" flag. Any of them can be set without setting the other. Note that if you compile Scotch with the "-DSCOTCH_PTHREAD" flag, you will have to initialize your communication subsystem by using the MPI_Init_thread() MPI call, not MPI_Init(), and the provided thread support level value returned by the routine must be checked carefully. If you have doubts on the stability of your MPI implementation, it is better not to set "-DSCOTCH_PTHREAD". For instance, on Linux platforms, concurrency problems have been experienced with MPICH2 versions prior to 1.0.7 using TCP; consequently, if the MPI implementation on your platform is based on an older MPICH2 version, do not set the "-DSCOTCH_PTHREAD" flag. Note that since the Scotch and PT-Scotch libraries are distinct, you can still compile Scotch with threads enabled, and compile PT-Scotch with threads disabled. However, since PT-Scotch calls Scotch routines when operating on a single process, threaded routines will be used on each process, without interfering with MPI. - to run in a multi-threaded way several key algorithms of the Scotch (no longer really) sequential library, such as graph coarsening and k-way diffusion. More algorithms will be re-coded in a threaded way in future versions. To date, thread management is performed in a very rudimentary way. The available number of threads can only be set at compile-time, and the assignment of threads to cores is performed in increasing order, starting from 0, which may not always prove to be the most efficient mapping in terms of memory affinity. We plan to add a mechanism for dynamic thread allocation in the near future, based upon the hwloc library. The compilation flags used to manage threads are the following: "-DCOMMON_PTHREAD" enables threads for algorithms not related to graph management, partitioning and/or ordering, e.g. compressed file handling. "-DCOMMON_PTHREAD_BARRIER" creates a replacement for missing pthread_barrier_t implementations, which unfortunately happens on some systems. "-DSCOTCH_PTHREAD" is necessary to enable multi-threaded algorithms in Scotch and/or PT-Scotch. "-DSCOTCH_PTHREAD_AFFINITY_LINUX" enables Linux extensions for handling thread affinity. As said above, this may not prove efficient in all cases. More options will be provided in the near future. "-DSCOTCH_PTHREAD_NUMBER=x" sets the overall number of threads to be used by multi-threaded algorithms. This number may not necessary be a power of two. Since some algorithms have had to be reformulated to accomodate for multi-threading, some algorithms will most probably be much more efficient than sequential processing only for a number of threads strictly greater than 2. Setting "-DSCOTCH_PTHREAD_NUMBER=1" allows one to run sequential algorithms instead of multi-threaded ones, while benefitting from multi-threading for file compression and distributed graph handling. When compiling under mingw32 on Windows systems, it is possible to benefit from multi-threading by including the "semaphore.h" and "pthread.h" files, included in the "src/misc" subdirectory, at compile time. These files have been kindly provided by Samuel Thibault, under a BSD 2-Clause License. These files will not work for Cygwin. This is not a problem, as Cygwin provides its own implementation of Posix threads. 2.6) Monitoring memory allocation --------------------------------- Some memory allocation information can be aggregated if PT-Scotch is compiled with the -DCOMMON_MEMORY_TRACE flag. When this flag is set, the "-va" option will make dgmap, dgord and dgpart output the minimum, maximum and average peak amount of memory used over all processes. Several API routines will also be made available to report the current and maximum amount of memory used by Scotch within the process they are called: SCOTCH_memCur() and SCOTCH_memMax(), respectively. A rudimentary memory checking mechanism is available for platforms that do not have efficient memory checking and debugging tools such as Valgrind or gdb. It can be activated through the "-DCOMMON_MEMORY_CHECK=x" flag. This is almost only for internal debugging purposes. The value of the "-DCOMMON_MEMORY_CHECK" is 1 if memory checking should be enabled by default, and 0 else. This mechanism is absolutely NOT thread-safe at the time being. 2.7) Randomness --------------- Many algorithms in Scotch and PT-Scotch are based on the random selection of vertices (e.g. seed vertices for graph growing algorithms, vertices to be mated for coarsening algorithms, etc.). This selection is performed by using integer pseudo-random generators to produce seemingly uncorrelated vertex indices. The advantage of pseudo-randomness over pure randomness is that the same pseudo-random seed will always yield the same sequence of pseudo-random numbers. Consequently, while using a different random seed for each run is likely to explore better the solution space, using a fixed random seed eases the debugging of programs, because algorithms behave identically across multiple runs (save for asynchronousness issues, see next section). By default, Scotch is compiled with the "-DCOMMON_RANDOM_FIXED_SEED" flag set, so that multiple executions of the same sequential programs will always yield the same results. Prior to version 6.0, Scotch relied on the operating system pseudo-random generator. While this posed no problem for most sequential programs, parallel runs of PT-Scotch were not reproducible on some systems, because the MPI implementation also used this pseudo-random generator for its own purposes. In order to avoid this problem, Scotch now uses its own pseudo-random generator. Users that want to go on using the operating system pseudo-random generator (e.g. for regression testing with respect to version 5.x) can still do so, by compiling with the "-DCOMMON_RANDOM_SYSTEM" flag set. In this case, the "-DCOMMON_RANDOM_RAND" flag allows one to use the srand() routine instead of the default srandom() routine. 2.8) Deterministic behavior --------------------------- When Scotch is compiled with the "-DCOMMON_RANDOM_FIXED_SEED" flag set, multiple executions of the same sequential programs will always yield the same results. Yet, non-deterministic multi-threaded and/or parallel algorithms may still introduce some variability in the produced results, due to operating system artifacts. To ease the tracking down of bugs, it is possible to coerce Scotch to exhibit a deterministic behavior by setting the "-DSCOTCH_DETERMINISTIC" flag. This option makes sure that two consecutive runs of Scotch on the same graph and same number of processes and/or threads will always yield the same result. However, it does not mean that two executions of Scotch on different numbers of processes and/or threads will always yield the same result. Indeed, changing the number of processes impacts graph data distribution and consequently the order in which vertices are processed. Consequently, coarsening algorithms are likely to produce different coarse graphs, leading to different partitions. This option is likely to have adverse impact on performance, since all non-deterministic multi-threaded algorithms will be disabled. In the case of Scotch, the multi-threaded matching algorithm for coarsening will be replaced by its sequential counterpart, whatever the available number of threads is. In the case of PT-Scotch, point-to-point messages will be received in a fixed order rather than being processed on a first-come, first-serve basis. Setting this flag automatically results in setting the "-DCOMMON_RANDOM_FIXED_SEED" flag. Users are also strongly advised to compile without setting the "-DCOMMON_RANDOM_SYSTEM" flag, in order to avoid any interference with third-party libraries that might use the operating system pseudo-random generator. 2.9) Point-to-point or collective communications ------------------------------------------------ Since distributed graph vertices can have any initial distribution across processes, communication rounds are likely to involve all of the processes in an almost all-to-all scheme. In order to speed-up running time, most of these communications are performed by means of asynchronous sends and receives, which allows computations to overlap with communications. However, for large numbers of processes, this can lead to the saturation of the communication network of the target parallel machine. To avoid this, communication consuming routines also have a collective communication based version. The use of this version is enabled by default, as it greatly improves scalability for large numbers of processes. To disable it, set the "-DSCOTCH_PTOP" flag at compile time. 2.10) MeTiS compatibility library --------------------------------- In order to ease the adoption of Scotch/PT-Scotch by people who already developed code based on the MeTiS/ParMeTiS interface, a MeTiS V3 compatibility library is included in the Scotch package. It provides stubs for the graph partitioning and ordering routines of MeTiS/ParMeTiS, but not for the service routines that are comprised in this package. Consequently, for people willing to use both libraries, that is, experiment with the graph partitioning features of Scotch while using the service routines of the genuine MeTiS package, special measures have to be taken. A first solution can be to coerce the linker to pick partitioning routines from the libscotch, and service routines from the libmetis. This can be done by placing the library names in this order as arguments to the linker command. Yet, some linkers may still report an error, as some symbols are multiply defined. Alternately, the names of the compatibility routines can be changed so as to avoid conflicts. When the "-DSCOTCH_METIS_PREFIX" flag is set at compile time, all Scotch versions of the MeTiS routines are prefixed with "SCOTCH_". Of course, this will require an equivalent change in the user's application code. An advantage of the Scotch/PT-Scotch stubs over the genuine MeTiS/ParMeTiS V3 routines is that they can be available in a 64-bit version. In this case, all int's that were passed to MeTiS/ParMeTiS routines must be replaced by 64-bit integer values (even the option configuration values). However, in this case, one will not be able to link against the service routines of the genuine MeTiS/ParMeTiS V3 library, as the latter is only available as a 32-bit implementation. 3) Compilation ============== Once you have performed the configuration of the "Makefile.inc" file, compile the Scotch distribution by typing "make scotch", or just "make", in the current "src/" working directory. To compile the PT-Scotch distribution, type "make ptscotch" in the same "src/" directory. This can be done in any order. Typing "make scotch ptscotch" to compile both is equivalent to typing "make ptscotch" alone, since PT-Scotch requires Scotch. The most common problem you may encounter when trying to compile PT-Scotch on a new platform relates to the "dummysizes" and "ptdummysizes" executables. The purpose of these programs is to determine, on the target platform, the sizes of the opaque data structures of Scotch and PT-Scotch, respectively. They have to be compiled and run before any library function can be compiled. The sequential case poses no specific problems, as "dummysizes" is always compiled with the same command as the one used to compile the sequential Scotch package (hence, "CCD=$(CCS)" when executing "make scotch"). In the parallel case, "ptdummysizes" has to take into account the sizes of some MPI data structures, such as MPI_Comm, and the most common way to have access to this information is to use some flavor of MPI-aware compilers such as "mpicc" which automatically refer to "mpi.h". Therefore, "CCD=mpicc" will work for most systems and MPI implementations. Yet, on some platforms, programs compiled for parallel execution cannot be run interactively. Moreover, "ptdummysizes" itself does not contain any MPI calls, as it just wants to know the sizes of the data structures, and the communication susbystem of the platform may not want to run it. In any of these cases, compilation will break. It is possible to solve this problem by specifying, in the CCD variable of "Makefile.inc", how to compile "ptdummysizes" sequentially but with knowledge of the location of the "mpi.h" include file, for instance with the following line: "CCD = my_sequential_cc -I/path/to/my/mpi/implementation/include/dir/". If no error occurs, all of the relevant header, library and executable files will be created and copied to the "../include/", "../lib/" and "../bin/" directories, relatively to your current "src/" working directory. Headers, libraries and binaries of Scotch and PT-Scotch can coexist in these directories without any interference. Then, typing "make install" will perform a GNU-like installation, with header, library, binary and man files copied to the "include", "lib", "bin" and "man" subdirectories of the path specified in the "prefix" variable, which is set by default to "/usr/local". For instance, typing "make prefix=/home/myself/usr/ install" will install the Scotch/PT-Scotch files in a subtree of directory "/home/myself/usr/". 4) Checking =========== A set of test programs is available in the "src/check" directory. They serve as non-regression checks for both sequential and parallel features of Scotch and PT-Scotch. They can be launched by typing "make check" and/or "make ptcheck" in the "src/" directory. In the case of "ptcheck", programs can be run in debug mode, by compiling with the "-DSCOTCH_CHECK_NOAUTO" flag set. In this case, process numbers are printed, so that users can attach a debugger to a given (set of) process(es), and user action is required for launching the parallel programs, by typing ENTER whenever necessary. One might look at these programs for examples of how to use the Scotch and PT-Scotch libraries. However, some of these programs test internal features, and interact with the library through non-standard and non-documented procedures. It is therefore recommended NOT to imitate these calling practices and rather to follow the guidelines provided in the Scotch and PT-Scotch user manuals. 5) Use ====== Users willing to use the features of the sequential (but possibly threaded) libScotch library have to include "scotch.h" and to link against the "libscotch" library, plus an error handling package such as "libscotcherr" or "libscotcherrexit". Users willing to use the features of the distributed-memory parallel libPTScotch library have to include "ptscotch.h" (which itself includes "scotch.h") and to link against both the "libptscotch" and "libscotch" libraries (in this order whenever order is significant), plus an error handling package such as "libptscotcherr" or "libptscotcherrexit". In the case of complex programs, which may run as sequential programs but may also call parallel routines, it is necessary to link only once against a Scotch error handling routine, and this routine cannot call MPI routines. Hence, the "libscotcherr" or "libscotcherrexit" libraries must be used. This will not impact the behavior of the parallel routines, but process numbers will not be displayed in case of an error. 6) Documentation and use ======================== The Scotch and PT-Scotch user's manuals are available in the "doc/" directory. They describe how to use the libscotch and libptscotch libraries, as well as the standalone programs of the Scotch and PT-Scotch distributions. 7) Note to packagers ==================== Since version 6.0, the Scotch and PT-Scotch packages can be made independent. The libScotch will not be tied by any dependency against any MPI package, while the libPTScotch has to depend on the one with which it has been compiled, in addition to the libScotch package that it uses. In versions 5.x, the libPTScotch also contained a modified copy of the libScotch. It is no longer the case, which will result in lower disk footprint. Regarding the use of threads, since Scotch is at the time being not dynamically configurable, one has to decide whether to compile it with threads enabled or not and, additionally, with which number of threads it will run. Based on the current processor market, I recommend to compile with -DSCOTCH_PTHREAD_NUMBER=2 (and, of course, -DSCOTCH_PTHREAD_AFFINITY_LINUX whenever possible). The penalty for single-thread CPUs will not be too high, while hyper-threaded and many-core CPUs will benefit from the extra thread. scotch-6.0.4.dfsg/include/0000755002563400244210000000000012407352724020522 5ustar trophimeutilisateurs du domainescotch-6.0.4.dfsg/lib/0000755002563400244210000000000012407352724017645 5ustar trophimeutilisateurs du domainescotch-6.0.4.dfsg/LICENSE_en.txt0000644002563400244210000000051011653315743021402 0ustar trophimeutilisateurs du domaineThis copy of the Scotch 6.0 distribution is licensed to you under the terms of the CeCILL-C free/libre software license. A copy of this license is available in subdirectory "doc", in file named "CeCILL-C_V1-en.txt". Please read its terms carefully. Only if you accept them can you use this copy of the Scotch 6.0 distribution. scotch-6.0.4.dfsg/README.txt0000644002563400244210000000044211653315767020605 0ustar trophimeutilisateurs du domaineThe terms under which this copy of the Scotch 6.0 distribution is provided to you are described in file "LICENSE_en.txt", located in the same directory as this file. If you accept them, please refer to file "INSTALL.txt", also located in this directory, for the installation instructions. scotch-6.0.4.dfsg/tgt/0000755002563400244210000000000011762163747017705 5ustar trophimeutilisateurs du domainescotch-6.0.4.dfsg/tgt/k2.tgt0000644002563400244210000000001011631447171020717 0ustar trophimeutilisateurs du domainecmplt 2 scotch-6.0.4.dfsg/tgt/p32.tgt0000644002563400244210000000001411631447171021013 0ustar trophimeutilisateurs du domainemesh2D 32 1 scotch-6.0.4.dfsg/tgt/h5.tgt0000644002563400244210000000000711631447171020725 0ustar trophimeutilisateurs du domainehcub 5 scotch-6.0.4.dfsg/tgt/m27x29.tgt0000644002563400244210000000001511631447171021360 0ustar trophimeutilisateurs du domainemesh2D 27 29 scotch-6.0.4.dfsg/tgt/m24x24.tgt0000644002563400244210000000001511631447171021350 0ustar trophimeutilisateurs du domainemesh2D 24 24 scotch-6.0.4.dfsg/tgt/m29x31.tgt0000644002563400244210000000001511631447171021353 0ustar trophimeutilisateurs du domainemesh2D 29 31 scotch-6.0.4.dfsg/tgt/p256.tgt0000644002563400244210000000001511631447171021104 0ustar trophimeutilisateurs du domainemesh2D 256 1 scotch-6.0.4.dfsg/tgt/h9.tgt0000644002563400244210000000000711631447171020731 0ustar trophimeutilisateurs du domainehcub 9 scotch-6.0.4.dfsg/tgt/m16x16.tgt0000644002563400244210000000001511631447171021352 0ustar trophimeutilisateurs du domainemesh2D 16 16 scotch-6.0.4.dfsg/tgt/k256.tgt0000644002563400244210000000001211631447171021074 0ustar trophimeutilisateurs du domainecmplt 256 scotch-6.0.4.dfsg/tgt/m17x19.tgt0000644002563400244210000000001511631447171021356 0ustar trophimeutilisateurs du domainemesh2D 17 19 scotch-6.0.4.dfsg/tgt/m2x2.tgt0000644002563400244210000000001311631447171021176 0ustar trophimeutilisateurs du domainemesh2D 2 2 scotch-6.0.4.dfsg/tgt/h7.tgt0000644002563400244210000000000711631447171020727 0ustar trophimeutilisateurs du domainehcub 7 scotch-6.0.4.dfsg/tgt/k24.tgt0000644002563400244210000000001111631447171021004 0ustar trophimeutilisateurs du domainecmplt 24 scotch-6.0.4.dfsg/tgt/h2.tgt0000644002563400244210000000000711631447171020722 0ustar trophimeutilisateurs du domainehcub 2 scotch-6.0.4.dfsg/tgt/h3.tgt0000644002563400244210000000000711631447171020723 0ustar trophimeutilisateurs du domainehcub 3 scotch-6.0.4.dfsg/tgt/k4.tgt0000644002563400244210000000001011631447171020721 0ustar trophimeutilisateurs du domainecmplt 4 scotch-6.0.4.dfsg/tgt/SP2_16.txt0000644002563400244210000000000711631447171021344 0ustar trophimeutilisateurs du domaineleaf 4 scotch-6.0.4.dfsg/tgt/m5x5.tgt0000644002563400244210000000001311631447171021204 0ustar trophimeutilisateurs du domainemesh2D 5 5 scotch-6.0.4.dfsg/tgt/vhcub.tgt0000644002563400244210000000001011631447171021512 0ustar trophimeutilisateurs du domainevarhcub scotch-6.0.4.dfsg/tgt/t2x4x8.tgt0000644002563400244210000000001611631447171021472 0ustar trophimeutilisateurs du domainetorus3D 2 4 8 scotch-6.0.4.dfsg/tgt/p16.tgt0000644002563400244210000000001411631447171021015 0ustar trophimeutilisateurs du domainemesh2D 16 1 scotch-6.0.4.dfsg/tgt/m8x16.tgt0000644002563400244210000000001411631447171021272 0ustar trophimeutilisateurs du domainemesh2D 8 16 scotch-6.0.4.dfsg/tgt/k7.tgt0000644002563400244210000000001011631447171020724 0ustar trophimeutilisateurs du domainecmplt 7 scotch-6.0.4.dfsg/tgt/m10x10.tgt0000644002563400244210000000001511631447171021336 0ustar trophimeutilisateurs du domainemesh2D 10 10 scotch-6.0.4.dfsg/tgt/k128.tgt0000644002563400244210000000001211631447171021072 0ustar trophimeutilisateurs du domainecmplt 128 scotch-6.0.4.dfsg/tgt/m9x11.tgt0000644002563400244210000000001411631447171021266 0ustar trophimeutilisateurs du domainemesh2D 9 11 scotch-6.0.4.dfsg/tgt/m64x64.tgt0000644002563400244210000000001511631447171021360 0ustar trophimeutilisateurs du domainemesh2D 64 64 scotch-6.0.4.dfsg/tgt/m16x32.tgt0000644002563400244210000000001511631447171021350 0ustar trophimeutilisateurs du domainemesh2D 16 32 scotch-6.0.4.dfsg/tgt/m5x7.tgt0000644002563400244210000000001311631447171021206 0ustar trophimeutilisateurs du domainemesh2D 5 7 scotch-6.0.4.dfsg/tgt/p64.tgt0000644002563400244210000000001411631447171021020 0ustar trophimeutilisateurs du domainemesh2D 64 1 scotch-6.0.4.dfsg/tgt/k512.tgt0000644002563400244210000000001211631447171021067 0ustar trophimeutilisateurs du domainecmplt 512 scotch-6.0.4.dfsg/tgt/p512.tgt0000644002563400244210000000001511631447171021077 0ustar trophimeutilisateurs du domainemesh2D 512 1 scotch-6.0.4.dfsg/tgt/p128.tgt0000644002563400244210000000001511631447171021102 0ustar trophimeutilisateurs du domainemesh2D 128 1 scotch-6.0.4.dfsg/tgt/k32.tgt0000644002563400244210000000001111631447171021003 0ustar trophimeutilisateurs du domainecmplt 32 scotch-6.0.4.dfsg/tgt/p8.tgt0000644002563400244210000000001311631447171020735 0ustar trophimeutilisateurs du domainemesh2D 8 1 scotch-6.0.4.dfsg/tgt/p2.tgt0000644002563400244210000000001311631447171020727 0ustar trophimeutilisateurs du domainemesh2D 2 1 scotch-6.0.4.dfsg/tgt/h1.tgt0000644002563400244210000000000711631447171020721 0ustar trophimeutilisateurs du domainehcub 1 scotch-6.0.4.dfsg/tgt/k6.tgt0000644002563400244210000000001011631447171020723 0ustar trophimeutilisateurs du domainecmplt 6 scotch-6.0.4.dfsg/tgt/t4x4x4.tgt0000644002563400244210000000001611631447171021470 0ustar trophimeutilisateurs du domainetorus3D 4 4 4 scotch-6.0.4.dfsg/tgt/k16.tgt0000644002563400244210000000001111631447171021005 0ustar trophimeutilisateurs du domainecmplt 16 scotch-6.0.4.dfsg/tgt/m8x8.tgt0000644002563400244210000000001311631447171021212 0ustar trophimeutilisateurs du domainemesh2D 8 8 scotch-6.0.4.dfsg/tgt/m19x31.tgt0000644002563400244210000000001511631447171021352 0ustar trophimeutilisateurs du domainemesh2D 19 31 scotch-6.0.4.dfsg/tgt/vcmplt.tgt0000644002563400244210000000001111631447171021711 0ustar trophimeutilisateurs du domainevarcmplt scotch-6.0.4.dfsg/tgt/k1.tgt0000644002563400244210000000001011631447171020716 0ustar trophimeutilisateurs du domainecmplt 1 scotch-6.0.4.dfsg/tgt/m25x27.tgt0000644002563400244210000000001511631447171021354 0ustar trophimeutilisateurs du domainemesh2D 25 27 scotch-6.0.4.dfsg/tgt/T3D_64.tgt0000644002563400244210000000001611631447171021314 0ustar trophimeutilisateurs du domainetorus3D 4 4 4 scotch-6.0.4.dfsg/tgt/m9x7.tgt0000644002563400244210000000001311631447171021212 0ustar trophimeutilisateurs du domainemesh2D 9 7 scotch-6.0.4.dfsg/tgt/k8.tgt0000644002563400244210000000001011631447171020725 0ustar trophimeutilisateurs du domainecmplt 8 scotch-6.0.4.dfsg/tgt/h4.tgt0000644002563400244210000000000711631447171020724 0ustar trophimeutilisateurs du domainehcub 4 scotch-6.0.4.dfsg/tgt/m2x4x8.tgt0000644002563400244210000000001511631447171021462 0ustar trophimeutilisateurs du domainemesh3D 2 4 8 scotch-6.0.4.dfsg/tgt/void.tgt0000644002563400244210000000001011631447171021344 0ustar trophimeutilisateurs du domainecmplt 1 scotch-6.0.4.dfsg/tgt/m4x8.tgt0000644002563400244210000000001311631447171021206 0ustar trophimeutilisateurs du domainemesh2D 4 8 scotch-6.0.4.dfsg/tgt/p4.tgt0000644002563400244210000000001311631447171020731 0ustar trophimeutilisateurs du domainemesh2D 4 1 scotch-6.0.4.dfsg/tgt/k12.tgt0000644002563400244210000000001111631447171021001 0ustar trophimeutilisateurs du domainecmplt 12 scotch-6.0.4.dfsg/tgt/m19x21.tgt0000644002563400244210000000001511631447171021351 0ustar trophimeutilisateurs du domainemesh2D 19 21 scotch-6.0.4.dfsg/tgt/m10x20.tgt0000644002563400244210000000001511631447171021337 0ustar trophimeutilisateurs du domainemesh2D 10 20 scotch-6.0.4.dfsg/tgt/h6.tgt0000644002563400244210000000000711631447171020726 0ustar trophimeutilisateurs du domainehcub 6 scotch-6.0.4.dfsg/tgt/m32x32.tgt0000644002563400244210000000001511631447171021346 0ustar trophimeutilisateurs du domainemesh2D 32 32 scotch-6.0.4.dfsg/tgt/m3x3.tgt0000644002563400244210000000001311631447171021200 0ustar trophimeutilisateurs du domainemesh2D 3 3 scotch-6.0.4.dfsg/tgt/h8.tgt0000644002563400244210000000000711631447171020730 0ustar trophimeutilisateurs du domainehcub 8 scotch-6.0.4.dfsg/tgt/m21x23.tgt0000644002563400244210000000001511631447171021344 0ustar trophimeutilisateurs du domainemesh2D 21 23 scotch-6.0.4.dfsg/tgt/k96.tgt0000644002563400244210000000001111631447171021015 0ustar trophimeutilisateurs du domainecmplt 96 scotch-6.0.4.dfsg/tgt/m23x25.tgt0000644002563400244210000000001511631447171021350 0ustar trophimeutilisateurs du domainemesh2D 23 25 scotch-6.0.4.dfsg/tgt/m4x4.tgt0000644002563400244210000000001311631447171021202 0ustar trophimeutilisateurs du domainemesh2D 4 4 scotch-6.0.4.dfsg/tgt/k48.tgt0000644002563400244210000000001111631447171021012 0ustar trophimeutilisateurs du domainecmplt 48 scotch-6.0.4.dfsg/tgt/k64.tgt0000644002563400244210000000001111631447171021010 0ustar trophimeutilisateurs du domainecmplt 64 scotch-6.0.4.dfsg/tgt/m11x13.tgt0000644002563400244210000000001511631447171021342 0ustar trophimeutilisateurs du domainemesh2D 11 13 scotch-6.0.4.dfsg/tgt/h10.tgt0000644002563400244210000000001011631447171020773 0ustar trophimeutilisateurs du domainehcub 10 scotch-6.0.4.dfsg/src/0000755002563400244210000000000012410326131017651 5ustar trophimeutilisateurs du domainescotch-6.0.4.dfsg/src/misc/0000755002563400244210000000000012315370011020604 5ustar trophimeutilisateurs du domainescotch-6.0.4.dfsg/src/misc/scotch_5.1.12_openmpi.spec0000644002563400244210000001507012045412600025302 0ustar trophimeutilisateurs du domaine# RPM spec file for Scotch, tested on RHEL 5 & 6. # Licence: CeCILL-C # Build PT-Scotch stuff with openmpi. Probably there should be an mpich # version too, but we don't use mpich. # The mpiwrappers-openmpi-devel required on RHEL5 is in the EPEL repo. %bcond_with openmpi # fixme: Is there a better way? %define rhel5 %(fgrep -q ' 5.' /etc/redhat-release 2>/dev/null && echo 1) Name: scotch # The original tar file was called 5.1.12b, but unpacks into 5.1.12, so it # was re-named. Version: 5.1.12 Release: 1%{?dist} Summary: programs and libraries for graph, mesh and hypergraph partitioning Group: Applications/Engineering License: CeCILL-C URL: https://gforge.inria.fr/projects/scotch Source0: https://gforge.inria.fr/frs/download.php/28925/scotch_%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: gcc, make, binutils, bison, flex %if %{with openmpi} %if 0%rhel5 BuildRequires: mpiwrappers-openmpi-devel %else BuildRequires: openmpi-devel %endif %endif # Cribbed from the Debian package %description Scotch is a software package for graph and mesh/hypergraph partitioning, graph clustering, and sparse matrix ordering. Its purpose is to apply graph theory, with a divide and conquer approach, to scientific computing problems such as graph and mesh partitioning, static mapping, and sparse matrix ordering, in application domains ranging from structural mechanics to operating systems or bio-chemistry. The SCOTCH distribution is a set of programs and libraries which implement the static mapping and sparse matrix reordering algorithms developed within the SCOTCH project. SCOTCH has many interesting features: o Its capabilities can be used through a set of stand-alone programs as well as through the libSCOTCH library, which offers both C and Fortran interfaces. o It provides algorithms to partition graph structures, as well as mesh structures defined as node-element bipartite graphs and which can also represent hypergraphs. o It can map any weighted source graph onto any weighted target graph. The source and target graphs may have any topology, and their vertices and edges may be weighted. Moreover, both source and target graphs may be disconnected. This feature allows for the mapping of programs onto disconnected subparts of a parallel architecture made up of heterogeneous processors and communication links. o It computes amalgamated block orderings of sparse matrices, for efficient solving using BLAS routines. o Its running time is linear in the number of edges of the source graph, and logarithmic in the number of vertices of the target graph for mapping computations. o It can handle indifferently graph and mesh data structures created within C or Fortran programs, with array indices starting from 0 or 1. o It offers extended support for adaptive graphs and meshes through the handling of disjoint edge arrays. o It is dynamically parametrizable thanks to strategy strings that are interpreted at run-time. o It uses system memory efficiently, to process large graphs and meshes without incurring out-of-memory faults; o It can be easily interfaced to other programs. The programs comprising the SCOTCH project have been designed to run in command-line mode without any interactive prompting, so that they can be called easily from other programs by means of system() or popen() calls, or piped together on a single command line. Moreover, vertex labeling capabilities allow for easy renumbering of vertices. o It provides many tools to build, check, and display graphs, meshes and matrix patterns. %package libs Summary: Shared library files for scotch. Group: Applications/Engineering %description libs Scotch is a software package for graph and mesh/hypergraph partitioning, graph clustering, and sparse matrix ordering. This package contains its library files. %package devel Summary: Development files for the scotch library. Group: Applications/Engineering Requires: %{name}-libs = %{version}-%{release} %description devel Scotch is a software package for graph and mesh/hypergraph partitioning, graph clustering, and sparse matrix ordering. This package contains development files. %if %{with openmpi} %package pt Summary: PT-Scotch (parallel programs). Group: Applications/Engineering %description pt Scotch is a software package for graph and mesh/hypergraph partitioning, graph clustering, and sparse matrix ordering. This package contains the MPI-based programs. %package ptlibs Summary: Shared library files for ptscotch. Group: Applications/Engineering %description ptlibs Scotch is a software package for graph and mesh/hypergraph partitioning, graph clustering, and sparse matrix ordering. This package contains the MPI-based libraries. %endif %prep %setup -q -n %{name}_%{version} cat >src/Makefile.inc < - 5.1.12b-1 - Initial packaging scotch-6.0.4.dfsg/src/misc/pthread.h0000644002563400244210000002621512262301373022420 0ustar trophimeutilisateurs du domaine/* * Copyright (c) 2004-2012 Samuel Thibault * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY Samuel Thibault ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* This is a minimal pthread implementation based on windows functions. * It is *not* intended to be complete - just complete enough to get * simple applications running. */ #ifndef _WIN_PTHREAD_PTHREAD_H #define _WIN_PTHREAD_PTHREAD_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #include #include #include #ifdef __CYGWIN32__ #include #define unixErrno() cygwin_internal(CW_GET_ERRNO_FROM_WINERROR, (GetLastError()) #else #define unixErrno() win_toErrno(GetLastError()) #endif #define setSystemErrno() errno = unixErrno() #define winPthreadAssertWindows(expr) do { if (!(expr)) { setSystemErrno(); return errno; } } while (0) #define winPthreadAssertPthread(expr) do { int ret = (expr); if (ret) return ret; } while (0) #define winPthreadAssert(expr) do { if (!(expr)) return EIO; } while (0) /*********** * threads * ***********/ typedef DWORD pthread_attr_t; typedef HANDLE pthread_t; static inline pthread_t pthread_self(void) { return GetCurrentThread(); } static inline int pthread_equal(pthread_t t1, pthread_t t2) { return t1 == t2; } static inline int pthread_attr_init (pthread_attr_t *attr) { *attr = 0; return 0; } #define PTHREAD_CREATE_DETACHED 1 static inline int pthread_attr_setdetachstate (pthread_attr_t *attr, int yes) { (void)attr; (void)yes; /* not supported, ignore */ return 0; } static inline int pthread_attr_setstacksize (pthread_attr_t *attr, size_t stacksize) { (void)attr; (void)stacksize; /* not supported, ignore */ return 0; } static inline int pthread_attr_destroy (pthread_attr_t *attr) { (void)attr; return 0; } /* "real" cleanup handling not yet implemented */ typedef struct { void (*routine) (void *); void *arg; } __pthread_cleanup_handler; void pthread_cleanup_push (void (*routine) (void *), void *arg); #define pthread_cleanup_push(routine, arg) do { \ __pthread_cleanup_handler __cleanup_handler = {routine, arg}; void pthread_cleanup_pop (int execute); #define pthread_cleanup_pop(execute) \ if (execute) __cleanup_handler.routine(__cleanup_handler.arg); \ } while (0); static inline int pthread_create ( pthread_t *thread, const pthread_attr_t *attr, void * (*fun) (void *), void *arg ) { if (attr && *attr) return EINVAL; winPthreadAssertWindows(*thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) fun, arg, 0, NULL)); return 0; } static inline int pthread_setcancelstate (int state, int *oldstate) { (void)state; (void)oldstate; /* not yet implemented :( */ return 0; } static inline int pthread_cancel (pthread_t thread) { /* This is quite harsh :( */ winPthreadAssertWindows(TerminateThread(thread, 0)); return 0; } static inline void pthread_exit (void *res) { ExitThread((DWORD) (DWORD_PTR) res); } static inline int pthread_join (pthread_t thread, void **res) { again: switch (WaitForSingleObject(thread, INFINITE)) { default: case WAIT_FAILED: return unixErrno(); case WAIT_ABANDONED: case WAIT_OBJECT_0: break; case WAIT_TIMEOUT: goto again; } if (res) { DWORD _res; if (GetExitCodeThread(thread, &_res)) *res = (void *)(DWORD_PTR)_res; } return 0; } /*********** * mutexes * ***********/ #define PTHREAD_MUTEX_INITIALIZER NULL typedef HANDLE pthread_mutex_t; #define PTHREAD_MUTEX_RECURSIVE 1 #define PTHREAD_MUTEX_ERRORCHECK 2 typedef int pthread_mutexattr_t; static inline int pthread_mutexattr_init(pthread_mutexattr_t *attr) { *attr = PTHREAD_MUTEX_RECURSIVE; return 0; } static inline int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type) { if (type != PTHREAD_MUTEX_RECURSIVE && type != PTHREAD_MUTEX_ERRORCHECK) return EINVAL; *attr = type; return 0; } static inline int pthread_mutex_init (pthread_mutex_t *mutex, pthread_mutexattr_t *attr) { if (attr && *attr!=PTHREAD_MUTEX_RECURSIVE) return EINVAL; winPthreadAssertWindows(*mutex = CreateMutex(NULL, FALSE, NULL)); return 0; } static inline int pthread_mutex_unlock (pthread_mutex_t *mutex) { winPthreadAssertWindows(ReleaseMutex(*mutex)); return 0; } static inline int pthread_mutex_lock (pthread_mutex_t *mutex); static inline int __pthread_mutex_alloc_concurrently (pthread_mutex_t *mutex) { HANDLE mutex_init_mutex; /* Get access to one global named mutex to serialize mutex initialization */ winPthreadAssertWindows((mutex_init_mutex = CreateMutex(NULL, FALSE, "StarPU mutex init"))); winPthreadAssertPthread(pthread_mutex_lock(&mutex_init_mutex)); /* Now we are the one that can initialize it */ if (!*mutex) winPthreadAssertPthread(pthread_mutex_init(mutex,NULL)); winPthreadAssertPthread(pthread_mutex_unlock(&mutex_init_mutex)); winPthreadAssertWindows(CloseHandle(mutex_init_mutex)); return 0; } static inline int pthread_mutex_lock (pthread_mutex_t *mutex) { if (!*mutex) __pthread_mutex_alloc_concurrently (mutex); again: switch (WaitForSingleObject(*mutex, INFINITE)) { default: case WAIT_FAILED: return unixErrno();; case WAIT_ABANDONED: case WAIT_OBJECT_0: return 0; case WAIT_TIMEOUT: goto again; } } static inline int pthread_mutex_trylock (pthread_mutex_t *mutex) { if (!*mutex) __pthread_mutex_alloc_concurrently (mutex); switch (WaitForSingleObject(*mutex, 0)) { default: case WAIT_FAILED: return unixErrno(); case WAIT_ABANDONED: case WAIT_OBJECT_0: return 0; case WAIT_TIMEOUT: return EBUSY; } } static inline int pthread_mutex_destroy (pthread_mutex_t *mutex) { winPthreadAssertWindows(CloseHandle(*mutex)); *mutex = INVALID_HANDLE_VALUE; return 0; } /******************************************** * rwlock * * VERY LAZY, don't even look at it please! * * Should be fine unoptimized for now. * * TODO: FIXME, using conds for instance? * ********************************************/ #define PTHREAD_RWLOCK_INITIALIZER NULL typedef pthread_mutex_t pthread_rwlock_t; #define pthread_rwlock_init(lock, attr) pthread_mutex_init(lock, NULL) #define pthread_rwlock_wrlock(lock) pthread_mutex_lock(lock) #define pthread_rwlock_rdlock(lock) pthread_mutex_lock(lock) #define pthread_rwlock_unlock(lock) pthread_mutex_unlock(lock) #define pthread_rwlock_destroy(lock) pthread_mutex_destroy(lock) /************** * conditions * **************/ typedef struct { HANDLE sem; volatile unsigned nbwait; } pthread_cond_t; #define PTHREAD_COND_INITIALIZER { NULL, 0} #ifndef _TIMESPEC_DEFINED struct timespec { time_t tv_sec; /* Seconds */ long tv_nsec; /* Nanoseconds */ }; #endif typedef unsigned pthread_condattr_t; static inline int pthread_cond_init (pthread_cond_t *cond, const pthread_condattr_t *attr) { if (attr) return EINVAL; winPthreadAssertWindows(cond->sem = CreateSemaphore(NULL, 0, MAXLONG, NULL)); cond->nbwait = 0; return 0; } static inline int pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *time) { if (!cond->sem) winPthreadAssertPthread(pthread_cond_init(cond,NULL)); cond->nbwait++; winPthreadAssertPthread(pthread_mutex_unlock(mutex)); again: switch (WaitForSingleObject(cond->sem, time->tv_sec*1000+time->tv_nsec/1000)) { default: case WAIT_FAILED: { int error = unixErrno(); winPthreadAssertPthread(pthread_mutex_lock(mutex)); return error; } case WAIT_TIMEOUT: goto again; case WAIT_ABANDONED: case WAIT_OBJECT_0: break; } winPthreadAssertPthread(pthread_mutex_lock(mutex)); cond->nbwait--; return 0; } static inline int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) { if (!cond->sem) winPthreadAssertPthread(pthread_cond_init(cond,NULL)); cond->nbwait++; winPthreadAssertPthread(pthread_mutex_unlock(mutex)); again: switch (WaitForSingleObject(cond->sem, INFINITE)) { case WAIT_FAILED: { int error; error = unixErrno(); winPthreadAssertPthread(pthread_mutex_lock(mutex)); return error; } case WAIT_TIMEOUT: goto again; case WAIT_ABANDONED: case WAIT_OBJECT_0: break; } winPthreadAssertPthread(pthread_mutex_lock(mutex)); cond->nbwait--; return 0; } static inline int pthread_cond_signal (pthread_cond_t *cond) { if (!cond->sem) winPthreadAssertPthread(pthread_cond_init(cond,NULL)); if (cond->nbwait) ReleaseSemaphore(cond->sem, 1, NULL); return 0; } static inline int pthread_cond_broadcast (pthread_cond_t *cond) { if (!cond->sem) winPthreadAssertPthread(pthread_cond_init(cond,NULL)); ReleaseSemaphore(cond->sem, cond->nbwait, NULL); return 0; } static inline int pthread_cond_destroy (pthread_cond_t *cond) { if (cond->sem) { winPthreadAssertWindows(CloseHandle(cond->sem)); cond->sem = NULL; } return 0; } /******* * TLS * *******/ typedef DWORD pthread_key_t; #define PTHREAD_ONCE_INIT {PTHREAD_MUTEX_INITIALIZER, 0} typedef struct { pthread_mutex_t mutex; unsigned done; } pthread_once_t; static inline int pthread_once (pthread_once_t *once, void (*oncefun)(void)) { winPthreadAssertPthread(pthread_mutex_lock(&once->mutex)); if (!once->done) { oncefun(); once->done = 1; } winPthreadAssertPthread(pthread_mutex_unlock(&once->mutex)); return 0; } static inline int pthread_key_create (pthread_key_t *key, void (*freefun)(void *)) { (void)freefun; DWORD res; winPthreadAssertWindows((res = TlsAlloc()) != 0xFFFFFFFF); *key = res; return 0; } static inline int pthread_key_delete (pthread_key_t key) { winPthreadAssertWindows(TlsFree(key)); return 0; } static inline void *pthread_getspecific (pthread_key_t key) { return TlsGetValue(key); } static inline int pthread_setspecific (pthread_key_t key, const void *data) { winPthreadAssertWindows(TlsSetValue(key, (LPVOID) data)); return 0; } #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* _WIN_PTHREAD_PTHREAD_H */ scotch-6.0.4.dfsg/src/misc/semaphore.h0000644002563400244210000000511112262301400022733 0ustar trophimeutilisateurs du domaine/* * Copyright (c) 2004-2012 Samuel Thibault * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY Samuel Thibault ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* This is a minimal pthread implementation based on windows functions. * It is *not* intended to be complete - just complete enough to get * simple applications running. */ #ifndef _WIN_PTHREAD_SEMAPHORE_H #define _WIN_PTHREAD_SEMAPHORE_H #include "pthread.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /************** * semaphores * **************/ typedef HANDLE sem_t; static inline int sem_init(sem_t *sem, int pshared, unsigned int value) { (void)pshared; winPthreadAssertWindows(*sem = CreateSemaphore(NULL, value, MAXLONG, NULL)); return 0; } static inline int do_sem_wait(sem_t *sem, DWORD timeout) { switch (WaitForSingleObject(*sem, timeout)) { default: case WAIT_FAILED: setSystemErrno(); return -1; case WAIT_TIMEOUT: errno = EAGAIN; return -1; case WAIT_ABANDONED: case WAIT_OBJECT_0: return 0; } } #define sem_wait(sem) do_sem_wait(sem, INFINITE) #define sem_trywait(sem) do_sem_wait(sem, 0) static inline int sem_post(sem_t *sem) { winPthreadAssertWindows(ReleaseSemaphore(*sem, 1, NULL)); return 0; } static inline int sem_destroy(sem_t *sem) { winPthreadAssertWindows(CloseHandle(*sem)); return 0; } #endif /* _WIN_PTHREAD_SEMAPHORE_H */ scotch-6.0.4.dfsg/src/Make.inc/0000755002563400244210000000000012406326601021305 5ustar trophimeutilisateurs du domainescotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.i686_pc_linux20000644002563400244210000000064112370152120026165 0ustar trophimeutilisateurs du domaineEXE = LIB = .a OBJ = .o MAKE = make AR = ar ARFLAGS = -ruv CAT = cat CCS = gcc CCP = mpicc CCD = gcc CFLAGS = -O3 -DCOMMON_FILE_COMPRESS_GZ -DCOMMON_PTHREAD -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_RENAME -DSCOTCH_PTHREAD -Drestrict=__restrict CLIBFLAGS = LDFLAGS = -lz -lm -pthread CP = cp LEX = flex -Pscotchyy -olex.yy.c LN = ln MKDIR = mkdir MV = mv RANLIB = ranlib YACC = bison -pscotchyy -y -b y scotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.i686_pc_linux2.prof0000644002563400244210000000064512370152151027142 0ustar trophimeutilisateurs du domaineEXE = LIB = .a OBJ = .o MAKE = make AR = ar ARFLAGS = -ruv CAT = cat CCS = gcc CCP = mpicc CCD = gcc CFLAGS = -pg -O3 -Drestrict=__restrict -DCOMMON_FILE_COMPRESS_GZ -DCOMMON_PTHREAD -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_PTHREAD -DSCOTCH_RENAME CLIBFLAGS = LDFLAGS = -lz -lm -pthread CP = cp LEX = flex -Pscotchyy -olex.yy.c LN = ln MKDIR = mkdir MV = mv RANLIB = ranlib YACC = bison -pscotchyy -y -b y scotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.i686_pc_linux2.c990000644002563400244210000000067712370152130026602 0ustar trophimeutilisateurs du domaineEXE = LIB = .a OBJ = .o MAKE = make AR = ar ARFLAGS = -ruv CAT = cat CCS = gcc CCP = mpicc CCD = gcc CFLAGS = -std=c99 -O3 -DCOMMON_FILE_COMPRESS_GZ -DCOMMON_PTHREAD -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_RENAME -DSCOTCH_RENAME_PARSER -DSCOTCH_PTHREAD CLIBFLAGS = LDFLAGS = -lz -lm -pthread CP = cp LEX = flex -Pscotchyy -D_XOPEN_SOURCE=600 -olex.yy.c LN = ln MKDIR = mkdir MV = mv RANLIB = ranlib YACC = bison -pscotchyy -y -b y scotch-6.0.4.dfsg/src/Make.inc/mingw32/0000755002563400244210000000000011762163747022611 5ustar trophimeutilisateurs du domainescotch-6.0.4.dfsg/src/Make.inc/mingw32/gendll_1.sh0000755002563400244210000000133511631447171024626 0ustar trophimeutilisateurs du domaine#! /bin/sh # (C) 2008 Yves Secretan (yves.secretan@ete.inrs.ca) # This software is governed by the CeCILL-C license under French law # and abiding by the rules of distribution of free software. You can # use, modify and/or redistribute the software under the terms of the # CeCILL-C license as circulated by CEA, CNRS and INRIA at the following # URL: "http://www.cecill.info". # # To be executed in a MSYS window. # # This file creates the Exports definition file from the PT-Scotch DLL. # It must be adapted to reflect your environment, in particular library # path and library name. echo EXPORTS > ../../../lib/libptscotch.def nm ../../../lib/libptscotch.a | grep ' T _SCOTCH_' | sed 's/.* T _//' >> ../../../lib/libptscotch.def scotch-6.0.4.dfsg/src/Make.inc/mingw32/README.txt0000644002563400244210000000116311631447171024277 0ustar trophimeutilisateurs du domaineThese three script files can be used to create a Windows DLL from the PT-Scotch library on a MinGW32 system. They are intended to be called directly from the src/Make.inc/mingw32 directory and produce results in the lib directory. The first two ones must be called from a Unix-like shell window. The last one must be called from a MSDOS-like command window. These scripts are intended only as examples. They must be adapted to reflect your environment, in particular library path and library name. They have been provided by Yves Secretan (yves.secretan@ete.inrs.ca) and are licensed under the CeCILL-C libre/free license. scotch-6.0.4.dfsg/src/Make.inc/mingw32/gendll_2.bat0000755002563400244210000000137711631447171024771 0ustar trophimeutilisateurs du domaineREM (C) 2008 Yves Secretan (yves.secretan@ete.inrs.ca) REM This software is governed by the CeCILL-C license under French law REM and abiding by the rules of distribution of free software. You can REM use, modify and/or redistribute the software under the terms of the REM CeCILL-C license as circulated by CEA, CNRS and INRIA at the following REM URL: "http://www.cecill.info". REM REM To be executed in a DOS window. REM REM This file will create the PT-Scotch DLL. It must be adapted to reflect REM your environment, in particular library path and library name. REM set VC_PATH="C:\Program Files\Microsoft Visual Studio .NET\VC7\BIN" %VC_PATH%\vcvars32.bat && %VC_PATH%\lib.exe /def:..\..\..\lib\libptscotch.def /out:..\..\..\lib\libptscotch.dll scotch-6.0.4.dfsg/src/Make.inc/mingw32/gendll_0.sh0000755002563400244210000000157011631447171024626 0ustar trophimeutilisateurs du domaine#! /bin/sh # (C) 2008 Yves Secretan (yves.secretan@ete.inrs.ca) # This software is governed by the CeCILL-C license under French law # and abiding by the rules of distribution of free software. You can # use, modify and/or redistribute the software under the terms of the # CeCILL-C license as circulated by CEA, CNRS and INRIA at the following # URL: "http://www.cecill.info". # # To be executed in a MSYS window. # # This file will link the PT-Scotch DLL. It must be adapted to reflect # your environment, in particular library path and library name. export OBJS="../../libscotch/lib*.o" export LDFLAGS="--shared -Wl,--allow-multiple-definition" export PGMFILES="/l" export LDPATH="-L../../../lib -L$PGMFILES/MPICH2/lib -L$PGMFILES/pthread-win32/lib" export LDLIBS="-lptscotch -lptscotcherr -lmpi -lpthreadGC2" gcc --output ../../../lib/libptscotch.dll $LDFLAGS $LDPATH $OBJS $LDLIBS scotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.power3_ibm_aix50000644002563400244210000000071211631447171026515 0ustar trophimeutilisateurs du domaineEXE = LIB = .a OBJ = .o MAKE = gmake AR = ar ARFLAGS = -X64 -ruv CAT = cat CCS = xlc_r CCP = mpcc_r CCD = xlc_r -I/usr/lpp/ppe.poe/include CFLAGS = -ma -q64 -qarch=auto -O3 -qstrict -qtune=pwr3 -qlanglvl=extc99 -s -DCOMMON_PTHREAD -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_PTHREAD -DSCOTCH_RENAME -D_ALL_SOURCE CLIBFLAGS = LDFLAGS = -bmaxdata:0x80000000 -lpthread -lm CP = cp LEX = lex LN = ln MKDIR = mkdir MV = mv RANLIB = ranlib YACC = yacc scotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.x86-64_pc_linux2.icc.debug0000644002563400244210000000077712406326554030217 0ustar trophimeutilisateurs du domaineEXE = LIB = .a OBJ = .o MAKE = make AR = ar ARFLAGS = -ruv CAT = cat CCS = icc CCP = mpicc CCD = icc CFLAGS = -g -O0 -fp-model strict -traceback -check-uninit -fp-stack-check -DCOMMON_FILE_COMPRESS_GZ -DCOMMON_PTHREAD -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_DEBUG_ALL -DSCOTCH_DETERMINISTIC -DSCOTCH_RENAME -restrict -DIDXSIZE64 CLIBFLAGS = LDFLAGS = -g -lz -lm -lrt -pthread CP = cp LEX = flex -Pscotchyy -olex.yy.c LN = ln MKDIR = mkdir MV = mv RANLIB = ranlib YACC = bison -pscotchyy -y -b y scotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.ppc450_ibm_bgp0000644002563400244210000000077711631447171026226 0ustar trophimeutilisateurs du domaineEXE = LIB = .a OBJ = .o MAKE = gmake AR = ar ARFLAGS = -ruv CAT = cat CCS = /bgsys/drivers/ppcfloor/comm/bin/mpixlc_r CCP = /bgsys/drivers/ppcfloor/comm/bin/mpixlc_r CCD = xlc_r -I/bgsys/drivers/ppcfloor/comm/include CFLAGS = -O3 -qstrict -qlanglvl=extc99 -qarch=450d -qtune=450 -s -DCOMMON_PTHREAD -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_RENAME -DSCOTCH_DETERMINISTIC -D_ALL_SOURCE CLIBFLAGS = LDFLAGS = -lpthread -lm CP = cp LEX = lex LN = ln MKDIR = mkdir MV = mv RANLIB = ranlib YACC = yacc scotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.i686_mac_darwin80000644002563400244210000000062011631447171026467 0ustar trophimeutilisateurs du domaineEXE = LIB = .a OBJ = .o MAKE = make AR = ar ARFLAGS = -ruv CAT = cat CCS = gcc CCP = mpicc CCD = mpicc CFLAGS = -O3 -Drestrict=__restrict -DCOMMON_PTHREAD -DCOMMON_RANDOM_FIXED_SEED -DCOMMON_TIMING_OLD -DSCOTCH_PTHREAD -DSCOTCH_RENAME CLIBFLAGS = LDFLAGS = -lm CP = cp LEX = flex -Pscotchyy -olex.yy.c LN = ln MKDIR = mkdir MV = mv RANLIB = ranlib YACC = bison -pscotchyy -y -b y scotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.i686_sun_solaris50000644002563400244210000000064312370152407026722 0ustar trophimeutilisateurs du domaineEXE = LIB = .a OBJ = .o MAKE = make AR = ar ARFLAGS = -ruv CAT = cat CCS = cc CCP = mpicc CCD = mpicc CFLAGS = -m64 -O3 -DCOMMON_FILE_COMPRESS_GZ -DCOMMON_PTHREAD -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_PTHREAD -DSCOTCH_RENAME -Du_int32_t=uint32_t -Du_int64_t=uint64_t CLIBFLAGS = LDFLAGS = -lz -lm -lrt CP = cp LEX = flex -Pscotchyy -olex.yy.c LN = ln MKDIR = mkdir MV = mv RANLIB = ranlib YACC = yacc scotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.i686_pc_linux2.nothreads0000644002563400244210000000057712370152141030166 0ustar trophimeutilisateurs du domaineEXE = LIB = .a OBJ = .o MAKE = make AR = ar ARFLAGS = -ruv CAT = cat CCS = gcc CCP = mpicc CCD = gcc CFLAGS = -O3 -Drestrict=__restrict -DCOMMON_FILE_COMPRESS_GZ -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_RENAME CLIBFLAGS = LDFLAGS = -lz -lm -pthread CP = cp LEX = flex -Pscotchyy -olex.yy.c LN = ln MKDIR = mkdir MV = mv RANLIB = ranlib YACC = bison -pscotchyy -y -b y scotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.i686_pc_linux2.shlib0000644002563400244210000000066512370152161027300 0ustar trophimeutilisateurs du domaineEXE = LIB = .so OBJ = .o MAKE = make AR = gcc ARFLAGS = -shared -o CAT = cat CCS = gcc CCP = mpicc CCD = gcc CFLAGS = -O3 -DCOMMON_FILE_COMPRESS_GZ -DCOMMON_PTHREAD -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_RENAME -DSCOTCH_PTHREAD -Drestrict=__restrict CLIBFLAGS = -shared -fPIC LDFLAGS = -lz -lm -pthread CP = cp LEX = flex -Pscotchyy -olex.yy.c LN = ln MKDIR = mkdir MV = mv RANLIB = echo YACC = bison -pscotchyy -y -b y scotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.i686_pc_linux2.debug0000644002563400244210000000070012275403357027265 0ustar trophimeutilisateurs du domaineEXE = LIB = .a OBJ = .o MAKE = make AR = ar ARFLAGS = -ruv CAT = cat CCS = gcc CCP = mpicc CCD = gcc CFLAGS = -g -O0 -Drestrict=__restrict -DCOMMON_FILE_COMPRESS_GZ -DCOMMON_PTHREAD -DSCOTCH_DEBUG_ALL -DSCOTCH_DETERMINISTIC -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_RENAME CLIBFLAGS = LDFLAGS = -g -lz -lm -pthread CP = cp LEX = flex -Pscotchyy -olex.yy.c LN = ln MKDIR = mkdir MV = mv RANLIB = ranlib YACC = bison -pscotchyy -y -b y scotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.i686_mac_darwin10.icc0000644002563400244210000000067112261747670027312 0ustar trophimeutilisateurs du domaineEXE = LIB = .a OBJ = .o MAKE = make AR = ar ARFLAGS = -ruv CAT = cat CCS = icc CCP = mpicc CCD = icc CFLAGS = -O3 -restrict -DCOMMON_FILE_COMPRESS_GZ -DCOMMON_PTHREAD -DCOMMON_PTHREAD_BARRIER -DCOMMON_RANDOM_FIXED_SEED -DCOMMON_TIMING_OLD -DSCOTCH_PTHREAD -DSCOTCH_RENAME CLIBFLAGS = LDFLAGS = -lz -lm CP = cp LEX = flex -Pscotchyy -olex.yy.c LN = ln MKDIR = mkdir MV = mv RANLIB = ranlib YACC = bison -pscotchyy -y -b y scotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.i686_pc_linux2.shlib.debug0000644002563400244210000000072412370152167030367 0ustar trophimeutilisateurs du domaineEXE = LIB = .so OBJ = .o MAKE = make AR = gcc ARFLAGS = -shared -o CAT = cat CCS = gcc CCP = mpicc CCD = gcc CFLAGS = -g -O0 -Drestrict=__restrict -DCOMMON_FILE_COMPRESS_GZ -DCOMMON_PTHREAD -DSCOTCH_DEBUG_ALL -DSCOTCH_DETERMINISTIC -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_RENAME CLIBFLAGS = -shared -fPIC LDFLAGS = -g -lz -lm -pthread CP = cp LEX = flex -Pscotchyy -olex.yy.c LN = ln MKDIR = mkdir MV = mv RANLIB = echo YACC = bison -pscotchyy -y -b y scotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.i686_pc_mingw320000644002563400244210000000370311730652527026253 0ustar trophimeutilisateurs du domaine# This make include file is intended for building under MinGW32. As is, # it relies on : # - pthread-win32 (http://sourceware.org/pthreads-win32/), # - zlib (http://www.zlib.net/) # - mpich2 (http://www.mcs.anl.gov/research/projects/mpich2/). # It must be adapted to reflect your environment, in particular # installation root directories, include path and library name. # Since all files are linked with the MPI libraries, this file is # for compiling PT-Scotch only. To compile Scotch, remove the # -DSCOTCH_PTSCOTCH flag, as well as all references to MPI in the # CFLAGS and CLIBFLAGS = LDFLAGS variables. EXE = LIB = .a OBJ = .o MAKE = make AR = ar ARFLAGS = -ruv CAT = cat CCS = gcc CCP = gcc CCD = gcc #--- Compiler/loader flags CFLAGS_CPL = -O0 -g3 CFLAGS_INC = CFLAGS_DEF = -DCOMMON_RANDOM_FIXED_SEED -DCOMMON_STUB_FORK -DSCOTCH_PTSCOTCH -DSCOTCH_RENAME -D'pipe(pfds)=_pipe(pfds,1024,0x8000)' CLIBFLAGS = LDFLAGS = PGMFILES=$(PROGRAMFILES) #--- MPI MPI_ROOTDIR = $(PGMFILES)/MPICH2 CFLAGS_INC += -I$(MPI_ROOTDIR)/include #--- Comment/Uncomment for threaded MPI CLIBFLAGS = LDFLAGS += -L$(MPI_ROOTDIR)/lib -lm -lmpi #CLIBFLAGS = LDFLAGS += -L$(MPI_ROOTDIR)/lib -lm -lmpich2mt #--- Pthread : Uncomment for pthread support #PTHREAD_ROOTDIR = $(PGMFILES)/pthread-win32 #CFLAGS_INC += -I$(PTHREAD_ROOTDIR)/include #CLIBFLAGS = LDFLAGS += -L$(PTHREAD_ROOTDIR)/lib -lpthreadGC2 #--- zlib: Uncomment for compressed files #ZLIB_ROOTDIR = $(PGMFILES)/zlib-1.2.3 #CFLAGS_INC += -I$(ZLIB_ROOTDIR)/include #CLIBFLAGS = LDFLAGS += -L$(ZLIB_ROOTDIR)/lib -lzdll #--- COMMON_PTHREAD: Uncomment for compressed files #CFLAGS_DEF += -DCOMMON_PTHREAD -DCOMMON_FILE_COMPRESS_GZ #--- SCOTCH_PTHREAD: Uncomment for threaded MPI #CFLAGS_DEF += -DSCOTCH_PTHREAD CFLAGS = $(CFLAGS_CPL) $(CFLAGS_INC) $(CFLAGS_DEF) CP = cp LEX = flex -Pscotchyy -olex.yy.c LN = cp MKDIR = mkdir MV = mv RANLIB = ranlib YACC = bison -pscotchyy -y -b y scotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.alpha_dec_osf10000644002563400244210000000053111631447171026350 0ustar trophimeutilisateurs du domaineEXE = LIB = .a OBJ = .o MAKE = gmake AR = ar ARFLAGS = ruv CAT = cat CCS = cc CCP = mpicc CCD = mpicc CFLAGS = -v -O3 -omp -ansi_alias -ansi_args -DCOMMON_PTHREAD -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_PTHREAD -DSCOTCH_RENAME CLIBFLAGS = LDFLAGS = -lm CP = cp LEX = lex LN = ln MKDIR = mkdir MV = mv RANLIB = ranlib YACC = yacc scotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.x86-64_cray-xt4_linux20000644002563400244210000000060511631447171027432 0ustar trophimeutilisateurs du domaineEXE = LIB = .a OBJ = .o MAKE = gmake AR = ar ARFLAGS = -ruv CAT = cat CCS = cc CCP = cc CCD = cc CFLAGS = -O3 -c99 -fast -fastsse -DCOMMON_PTHREAD -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_PTHREAD -DSCOTCH_RENAME -DIDXSIZE64 CLIBFLAGS = LDFLAGS = -lm -lrt CP = cp LEX = flex -Pscotchyy -olex.yy.c LN = ln MKDIR = mkdir MV = mv RANLIB = ranlib YACC = bison -pscotchyy -y -b y scotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.pa11_hp_ux100000644002563400244210000000054411631447171025632 0ustar trophimeutilisateurs du domaineEXE = LIB = .a OBJ = .o MAKE = gmake AR = ar ARFLAGS = ruv CAT = cat CCS = cc CCP = mpicc CCD = mpicc CFLAGS = -Aa -z +DA1.1 +w1 +O4 +Onoinitcheck +Onolimit -DCOMMON_PTHREAD -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_PTHREAD -DSCOTCH_RENAME CLIBFLAGS = LDFLAGS = -lm CP = cp LEX = lex LN = ln MKDIR = mkdir MV = mv RANLIB = ranlib YACC = yacc scotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.i686_mac_darwin100000644002563400244210000000071712401121645026536 0ustar trophimeutilisateurs du domaineEXE = LIB = .a OBJ = .o MAKE = make AR = ar ARFLAGS = -ruv CAT = cat CCS = gcc CCP = mpicc CCD = gcc CFLAGS = -O3 -Drestrict=__restrict -DCOMMON_FILE_COMPRESS_GZ -DCOMMON_PTHREAD -DCOMMON_PTHREAD_BARRIER -DCOMMON_RANDOM_FIXED_SEED -DCOMMON_TIMING_OLD -DSCOTCH_PTHREAD -DSCOTCH_RENAME CLIBFLAGS = LDFLAGS = -lz -lm -lpthread CP = cp LEX = flex -Pscotchyy -olex.yy.c LN = ln MKDIR = mkdir MV = mv RANLIB = ranlib YACC = bison -pscotchyy -y -b y scotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.i686_pc_linux30000644002563400244210000000070212370152177026200 0ustar trophimeutilisateurs du domaineEXE = LIB = .a OBJ = .o MAKE = make AR = ar ARFLAGS = -ruv CAT = cat CCS = gcc CCP = mpicc CCD = gcc CFLAGS = -O3 -Drestrict=__restrict -DCOMMON_FILE_COMPRESS_GZ -DCOMMON_PTHREAD -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_RENAME -DSCOTCH_RENAME_PARSER -DSCOTCH_PTHREAD CLIBFLAGS = LDFLAGS = -lz -lpthread -lm -pthread CP = cp LEX = flex -Pscotchyy -olex.yy.c LN = ln MKDIR = mkdir MV = mv RANLIB = ranlib YACC = bison -pscotchyy -y -b y scotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.x86-64_pc_linux2.icc0000644002563400244210000000064612406326525027123 0ustar trophimeutilisateurs du domaineEXE = LIB = .a OBJ = .o MAKE = make AR = ar ARFLAGS = -ruv CAT = cat CCS = icc CCP = mpicc CCD = icc CFLAGS = -O3 -DCOMMON_FILE_COMPRESS_GZ -DCOMMON_PTHREAD -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_RENAME -DSCOTCH_PTHREAD -restrict -DIDXSIZE64 CLIBFLAGS = LDFLAGS = -lz -lm -lrt -pthread CP = cp LEX = flex -Pscotchyy -olex.yy.c LN = ln MKDIR = mkdir MV = mv RANLIB = ranlib YACC = bison -pscotchyy -y -b y scotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.x86-64_pc_freebsd0000644002563400244210000000071411631447171026553 0ustar trophimeutilisateurs du domaineEXE = LIB = .a OBJ = .o MAKE = gmake AR = ar ARFLAGS = -ruv CAT = cat CCS = cc CCP = mpicc CCD = cc CFLAGS += -std -fPIC -DCOMMON_FILE_COMPRESS_GZ -DCOMMON_PTHREAD -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_RENAME -DSCOTCH_RENAME_PARSER -DSCOTCH_PTHREAD -Drestrict=__restrict -DIDXSIZE64 CLIBFLAGS = LDFLAGS += -lz -lm -lthread CP = cp LEX = flex -Pscotchyy -olex.yy.c LN = ln MKDIR = mkdir MV = mv RANLIB = ranlib YACC = bison -pscotchyy -y -b y scotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.i686_pc_freebsd0000644002563400244210000000065411631447171026376 0ustar trophimeutilisateurs du domaineEXE = LIB = .a OBJ = .o MAKE = gmake AR = ar ARFLAGS = -ruv CAT = cat CCS = cc CCP = mpicc CCD = mpicc CFLAGS += -std=c99 -DCOMMON_FILE_COMPRESS_GZ -DCOMMON_PTHREAD -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_PTHREAD -DSCOTCH_RENAME -DSCOTCH_RENAME_PARSER CLIBFLAGS = LDFLAGS += -lz -lm -lpthread CP = cp LEX = flex -Pscotchyy -olex.yy.c LN = ln MKDIR = mkdir MV = mv RANLIB = ranlib YACC = bison -pscotchyy -y -b y scotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.x86-64_pc_linux2.shlib0000644002563400244210000000070612406326601027456 0ustar trophimeutilisateurs du domaineEXE = LIB = .so OBJ = .o MAKE = make AR = gcc ARFLAGS = -shared -o CAT = cat CCS = gcc CCP = mpicc CCD = gcc CFLAGS = -O3 -DCOMMON_FILE_COMPRESS_GZ -DCOMMON_PTHREAD -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_RENAME -DSCOTCH_PTHREAD -Drestrict=__restrict -DIDXSIZE64 CLIBFLAGS = -shared -fPIC LDFLAGS = -lz -lm -lrt -pthread CP = cp LEX = flex -Pscotchyy -olex.yy.c LN = ln MKDIR = mkdir MV = mv RANLIB = echo YACC = bison -pscotchyy -y -b y scotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.power6_ibm_aix50000644002563400244210000000066511631447171026527 0ustar trophimeutilisateurs du domaineEXE = LIB = .a OBJ = .o MAKE = gmake AR = ar ARFLAGS = -X64 -ruv CAT = cat CCS = xlc_r CCP = mpcc_r CCD = xlc_r -I/usr/lpp/ppe.poe/include CFLAGS = -ma -q64 -qarch=auto -O3 -qstrict -qtune=pwr6 -qlanglvl=extc99 -s -DCOMMON_PTHREAD -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_PTHREAD -DSCOTCH_RENAME -D_ALL_SOURCE CLIBFLAGS = LDFLAGS = -lpthread -lm CP = cp LEX = lex LN = ln MKDIR = mkdir MV = mv RANLIB = ranlib YACC = yacc scotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.ppca2_ibm_bgq0000644002563400244210000000103412056246613026204 0ustar trophimeutilisateurs du domaineEXE = LIB = .a OBJ = .o MAKE = gmake AR = ar ARFLAGS = -ruv CAT = cat CCS = /bgsys/drivers/ppcfloor/comm/xl/bin/mpixlc_r CCP = /bgsys/drivers/ppcfloor/comm/xl/bin/mpixlc_r CCD = xlc_r -I/bgsys/drivers/ppcfloor/comm/xl/include CFLAGS = -O3 -qstrict -qlanglvl=extc99 -s -DCOMMON_PTHREAD -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_RENAME -DSCOTCH_DETERMINISTIC -D_ALL_SOURCE CLIBFLAGS = LDFLAGS = -lpthread -lm CP = cp LEX = flex -Pscotchyy -olex.yy.c LN = ln MKDIR = mkdir MV = mv RANLIB = ranlib YACC = bison -pscotchyy -y -b y scotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.x86-64_pc_linux20000644002563400244210000000066212406326456026367 0ustar trophimeutilisateurs du domaineEXE = LIB = .a OBJ = .o MAKE = make AR = ar ARFLAGS = -ruv CAT = cat CCS = gcc CCP = mpicc CCD = gcc CFLAGS = -O3 -DCOMMON_FILE_COMPRESS_GZ -DCOMMON_PTHREAD -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_RENAME -DSCOTCH_PTHREAD -Drestrict=__restrict -DIDXSIZE64 CLIBFLAGS = LDFLAGS = -lz -lm -lrt -pthread CP = cp LEX = flex -Pscotchyy -olex.yy.c LN = ln MKDIR = mkdir MV = mv RANLIB = ranlib YACC = bison -pscotchyy -y -b y scotch-6.0.4.dfsg/src/Make.inc/Makefile.inc.mips_sgi_irix60000644002563400244210000000052111631447171026452 0ustar trophimeutilisateurs du domaineEXE = LIB = .a OBJ = .o MAKE = gmake AR = ar ARFLAGS = ruv CAT = cat CCS = xlc CCP = mpicc CCD = mpicc CFLAGS = -n32 -xansi -fullwarn -O2 -DCOMMON_PTHREAD -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_PTHREAD -DSCOTCH_RENAME CLIBFLAGS = LDFLAGS = -lm CP = cp LEX = lex LN = ln MKDIR = mkdir MV = mv RANLIB = ranlib YACC = yacc scotch-6.0.4.dfsg/src/esmumps/0000755002563400244210000000000012401131206021337 5ustar trophimeutilisateurs du domainescotch-6.0.4.dfsg/src/esmumps/symbol_fax_graph.c0000644002563400244210000001324012056411536025044 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2009 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : symbol_fax_graph.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a parallel direct block solver. **/ /** This is the block symbolic factoriza- **/ /** tion routine for graphs. **/ /** **/ /** DATES : # Version 0.0 : from : 22 jul 1998 **/ /** to 29 sep 1998 **/ /** # Version 0.2 : from : 08 may 2000 **/ /** to 09 may 2000 **/ /** # Version 1.0 : from : 01 jun 2002 **/ /** to 03 jun 2002 **/ /** # Version 1.1 : from : 26 jun 2002 **/ /** to 26 jun 2002 **/ /** # Version 2.0 : from : 21 mar 2003 **/ /** to 21 mar 2003 **/ /** # Version 3.0 : from : 02 mar 2004 **/ /** to 02 mar 2004 **/ /** # Version 5.1 : from : 22 jan 2009 **/ /** to 22 jan 2009 **/ /** **/ /** NOTES : # symbolFaxGraph() could have called **/ /** symbolFax() in the regular way, as **/ /** do all of the grid-like factorization **/ /** routines. However, for efficiency **/ /** reasons, we have decided to inline **/ /** symbolFax(), to avoid a function call **/ /** for every arc. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define SYMBOL_FAX #define SYMBOL_FAX_GRAPH #include "common.h" #ifdef SCOTCH_PTSCOTCH #include "ptscotch.h" #else /* SCOTCH_PTSCOTCH */ #include "scotch.h" #endif /* SCOTCH_PTSCOTCH */ #include "graph.h" #include "symbol.h" #include "order.h" #include "fax.h" #include "symbol_fax.h" /***********************************/ /* */ /* Symbolic factorization routine. */ /* */ /***********************************/ /*+ This routine computes the block symbolic *** factorization of the given matrix graph *** according to the given vertex ordering. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int symbolFaxGraph ( SymbolMatrix * const symbptr, /*+ Symbolic block matrix [based] +*/ const Graph * const grafptr, /*+ Matrix adjacency structure [based] +*/ const Order * const ordeptr) /*+ Matrix ordering +*/ { INT baseval; INT vertnbr; INT * verttab; const INT * restrict verttax; INT edgenbr; INT edgenum; INT * edgetab; const INT * restrict edgetax; SCOTCH_graphData (grafptr, &baseval, &vertnbr, &verttab, NULL, NULL, NULL, &edgenbr, &edgetab, NULL); verttax = verttab - baseval; edgetax = edgetab - baseval; #define SYMBOL_FAX_ITERATOR(ngbdptr, vertnum, vertend) \ for (edgenum = verttax[vertnum]; \ edgenum < verttax[vertnum + 1]; \ edgenum ++) { \ vertend = edgetax[edgenum]; #define SYMBOL_FAX_VERTEX_DEGREE(ngbdptr, vertnum) \ (verttax[(vertnum) + 1] - verttax[(vertnum)]) { #define SYMBOL_FAX_INCLUDED #include "symbol_fax.c" } } scotch-6.0.4.dfsg/src/esmumps/esmumps_strats.c0000644002563400244210000001432112056406465024617 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : esmumps_strats.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains defalut strategy **/ /** building routines for calling Scotch **/ /** from MUMPS. **/ /** **/ /** DATES : # Version 1.0 : from : 08 dec 2003 **/ /** to 08 dec 2003 **/ /** # Version 1.1 : from : 21 jun 2007 **/ /** to 21 jun 2007 **/ /** # Version 5.0 : from : 08 feb 2008 **/ /** to 08 feb 2008 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define ESMUMPS #include "common.h" #include "esmumps.h" /**************************************/ /* */ /* This routine creates a strategy */ /* string from the given parameters. */ /* */ /**************************************/ /* Meaning of the parameters : ** - procnbr : number of processors. ** - leafsiz : limit size in vertices of the leaf subgraphs. ** - leorval : type of halo ordering : 0 : HAMD; 1 : HAMF. ** - cminval : minimum number of column blocks. ** - cmaxval : maximum number of column blocks. ** - fratval : maximum fill ratio. ** - verbval : verbose flag if > 0. ** - stream : verbose stream. ** - straptr : pointer to character string of sufficient size ** to hold the resulting Scotch strategy. */ int esmumps_strat1 ( const INT procnbr, const INT leafsiz, const int leorval, const INT cminval, const INT cmaxval, const double fratval, const int verbval, FILE * const stream, char * const straptr) { INT levlval; /* Nested dissection level */ INT procmax; char hamxval; /* Type of halo ordering routine */ for (levlval = 1, procmax = 1; procmax < procnbr; procmax <<= 1, levlval ++) ; /* Compute log2 of procnbr, + 1 */ hamxval = (leorval == 0) ? 'h' : 'f'; /* HAMD if 0, HAMF if 1 */ if (verbval != 0) { fprintf (stream, "Scotch strategy:\n- %ld levels of ND are necessary for %ld processors\n", (long) levlval, (long) procnbr); fprintf (stream, "- If compressed (0.7) graph, then perform %ld levels of ND, then switch to HAM(%c)\n", (long) levlval, (char) hamxval); fprintf (stream, "- If uncompressed graph, then perform at least %ld levels of ND, and proceed\n until graph size less than %ld vertices, then switch to HAM(%c)\n", (long) levlval, (long) leafsiz, (char) hamxval); fprintf (stream, "- At the end of HAM(%c), amalgamate if number of columns not greater than %ld,\n and if either column size is smaller than %ld or fill ratio less than %lf\n", (char) hamxval, (long) cmaxval, (long) cminval, (double) fratval); fprintf (stream, "- During uncoarsening, band graphs of width 3 are used for refinement\n"); fprintf (stream, "- Separators are not split and are ordered in natural order\n"); } sprintf (straptr, "c{rat=0.7,cpr=n{sep=/((levl<%ld)|(vert>%ld))?m{type=h,rat=0.7,vert=100,low=h{pass=10},asc=b{width=3,bnd=f{bal=0.2},org=h{pass=10}f{bal=0.2}}}|m{type=h,rat=0.7,vert=100,low=h{pass=10},asc=b{width=3,bnd=f{bal=0.2},org=h{pass=10}f{bal=0.2}}};,ole=%c{cmin=%ld,cmax=%ld,frat=%lf},ose=s},unc=n{sep=/(levl<%ld)?(m{type=h,rat=0.7,vert=100,low=h{pass=10},asc=b{width=3,bnd=f{bal=0.2},org=h{pass=10}f{bal=0.2}}})|m{type=h,rat=0.7,vert=100,low=h{pass=10},asc=b{width=3,bnd=f{bal=0.2},org=h{pass=10}f{bal=0.2}}};,ole=%c{cmin=%ld,cmax=%ld,frat=%lf},ose=s}}", (long) levlval, (long) leafsiz, (char) hamxval, (long) cminval, (long) cmaxval, (double) fratval, (long) levlval, (char) hamxval, (long) cminval, (long) cmaxval, (double) fratval); return (0); } scotch-6.0.4.dfsg/src/esmumps/main_esmumps.c0000644002563400244210000001335112056412165024217 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2009,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : main_mumps.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This is the test module for the MUMPS **/ /** interface routine. **/ /** **/ /** DATES : # Version 0.0 : from : 17 may 2001 **/ /** to 17 may 2001 **/ /** # Version 1.0 : from : 17 jun 2005 **/ /** to 17 jun 2005 **/ /** # Version 5.1 : from : 22 jan 2009 **/ /** to 22 jan 2009 **/ /** # Version 6.0 : from : 01 dec 2012 **/ /** to 01 dec 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #include "common.h" #ifdef SCOTCH_PTSCOTCH #include "ptscotch.h" #else /* SCOTCH_PTSCOTCH */ #include "scotch.h" #endif /* SCOTCH_PTSCOTCH */ #include "graph.h" #include "esmumps.h" void ESMUMPSF (const INT * const, const INT * const, INT * const, const INT * const, INT * const, INT * const, INT * const, INT * const, INT * const, INT * const); /******************************/ /* */ /* This is the main function. */ /* */ /******************************/ int main (argc, argv) int argc; char * argv[]; { Graph grafdat; /* Graph to load */ INT vertnbr; INT * verttab; INT edgenbr; INT * edgetab; INT * lentab; INT * nvtab; INT * elentab; INT * lasttab; INT pfree; INT ncmpa; INT vertnum; FILE * stream; if (argc != 2) { errorPrint ("main_esmumps: usage: main_esmumps graph_file"); return (1); } graphInit (&grafdat); if ((stream = fopen (argv[1], "r")) == NULL) { errorPrint ("main_esmumps: cannot open graph file"); graphExit (&grafdat); return (1); } if (graphLoad (&grafdat, stream, 1, 3) != 0) { /* Base graph with base value 1, no loads */ errorPrint ("main_esmumps: cannot open graph file"); graphExit (&grafdat); return (1); } fclose (stream); graphData (&grafdat, NULL, &vertnbr, &verttab, NULL, NULL, NULL, &edgenbr, &edgetab, NULL); if ((lentab = (INT *) memAlloc (vertnbr * sizeof (INT))) == NULL) { errorPrint ("main_esmumps: out of memory (1)"); graphExit (&grafdat); return (1); } for (vertnum = 0; vertnum < vertnbr; vertnum ++) { if (verttab[vertnum] == verttab[vertnum + 1]) { lentab[vertnum] = 0; verttab[vertnum] = 0; /* Graph structure no longer valid in Emilio */ } else lentab[vertnum] = verttab[vertnum + 1] - verttab[vertnum]; } if (((nvtab = (INT *) memAlloc (vertnbr * sizeof (INT))) == NULL) || ((elentab = (INT *) memAlloc (vertnbr * sizeof (INT))) == NULL) || ((lasttab = (INT *) memAlloc (vertnbr * sizeof (INT))) == NULL)) { errorPrint ("main_esmumps: out of memory (2)"); if (nvtab != NULL) { if (elentab != NULL) memFree (elentab); memFree (nvtab); } graphExit (&grafdat); return (1); } pfree = edgenbr + 1; ESMUMPSF (&vertnbr, &edgenbr, verttab, &pfree, lentab, edgetab, nvtab, elentab, lasttab, &ncmpa); memFree (lasttab); memFree (elentab); memFree (nvtab); memFree (lentab); graphExit (&grafdat); if (ncmpa < 0) { errorPrint ("main_esmumps: error in ESMUMPSF (%d)", ncmpa); return (1); } exit (0); } scotch-6.0.4.dfsg/src/esmumps/module.h0000644002563400244210000000737612056406465023034 0ustar trophimeutilisateurs du domaine/* Copyright 2009 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : module.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This is the global configuration file **/ /** for the ESMUMPS library module. **/ /** **/ /** DATES : # Version 5.1 : from : 22 jan 2009 **/ /** to 22 jan 2009 **/ /** **/ /************************************************************/ #define MODULE_H /* ** Function renaming. */ #if ((! defined SCOTCH_COMMON_EXTERNAL) || (defined SCOTCH_COMMON_RENAME)) #define clockGet _SCOTCHclockGet #define fileNameDistExpand _SCOTCHfileNameDistExpand #define usagePrint _SCOTCHusagePrint #define errorPrint SCOTCH_errorPrint #define errorPrintW SCOTCH_errorPrintW #define errorProg SCOTCH_errorProg #define intLoad _SCOTCHintLoad #define intSave _SCOTCHintSave #define intAscn _SCOTCHintAscn #define intPerm _SCOTCHintPerm #define intRandReset _SCOTCHintRandReset #define intRandInit _SCOTCHintRandInit /* #define intRandVal _SCOTCHintRandVal Already a macro */ #define intSearchDicho _SCOTCHintSearchDicho #define intSort1asc1 _SCOTCHintSort1asc1 #define intSort2asc1 _SCOTCHintSort2asc1 #define intSort2asc2 _SCOTCHintSort2asc2 #define intSort3asc1 _SCOTCHintSort3asc1 #define memAllocGroup _SCOTCHmemAllocGroup #define memReallocGroup _SCOTCHmemReallocGroup #define memOffset _SCOTCHmemOffset #endif /* ((! defined SCOTCH_COMMON_EXTERNAL) || (defined SCOTCH_COMMON_RENAME)) */ scotch-6.0.4.dfsg/src/esmumps/esmumps.c0000644002563400244210000002043512056406465023222 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2009 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : esmumps.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains a MUMPS interface **/ /** for the ordering routines of the **/ /** libSCOTCH + Emilio libfax libraries. **/ /** **/ /** DATES : # Version 0.0 : from : 16 may 2001 **/ /** to 04 jun 2001 **/ /** # Version 0.1 : from : 13 feb 2002 **/ /** to 13 feb 2002 **/ /** # Version 1.0 : from : 06 dec 2004 **/ /** to 06 dec 2004 **/ /** # Version 5.1 : from : 22 jan 2009 **/ /** to 22 jan 2009 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define ESMUMPS #include "common.h" #ifdef SCOTCH_PTSCOTCH #include "ptscotch.h" #else /* SCOTCH_PTSCOTCH */ #include "scotch.h" #endif /* SCOTCH_PTSCOTCH */ #include "graph.h" #include "dof.h" #include "symbol.h" #include "order.h" #include "fax.h" #include "esmumps.h" /**************************************/ /* */ /* This routine acts as an interface */ /* between ordering software such as */ /* MUMPS and Scotch+Emilio. */ /* */ /**************************************/ /* Meaning of the parameters : ** - n : order of the system (that is, number of columns). ** - iwlen : not used. Here for compatibility. ** - pe : on input, position in array iw of the extra-diagonal ** terms for the considered column. ** on output, -pe(i) is the father of node i in the elimination ** tree if i is a principal variable, or it is the index of ** the principal variable if i is a secondary variable. ** - pfree : number of extra-diagonal terms for the considered ** node (that is, the number of arcs dans le graph for this ** vertex). ** - len : array holding the number of extra-diagonal terms for ** each column. ** - iw : array of extra-diagonal terms (preserved). ** - nv : on output, nv(i) = 0 if variable i is a secondary ** variable, else nv(i) is the number of columns that are ** merged into principal variable i. ** - elen : on output, direct permutation (for MUMPS; the ** meaning of the "direct" and "inverse" permutations is ** just the opposite for Scotch) : ** k=elen(i) <==> column i is the k-th pivot. ** - last : on output, inverse permutation (for MUMPS) : ** i=last(k) <==> column i est le k-th pivot */ int esmumps ( const INT n, const INT iwlen, /* Not used, just here for consistency */ INT * restrict const petab, const INT pfree, INT * restrict const lentab, INT * restrict const iwtab, INT * restrict const nvtab, INT * restrict const elentab, /* Permutations computed for debugging only */ INT * restrict const lasttab) /* Permutations computed for debugging only */ { INT baseval; /* Base value */ INT * restrict vendtab; /* Vertex end array */ Graph grafdat; /* Graph */ Order ordedat; /* Graph ordering */ SymbolMatrix symbdat; /* Block factored matrix */ Dof deofdat; /* Matrix DOF structure */ INT vertnum; INT cblknum; INT colnum; if ((vendtab = memAlloc (n * sizeof (INT))) == NULL) { errorPrint ("esmumps: out of memory"); return (1); } for (vertnum = 0; vertnum < n; vertnum ++) vendtab[vertnum] = petab[vertnum] + lentab[vertnum]; baseval = 1; /* Assume Fortran-based indexing */ graphInit (&grafdat); graphBuildGraph2 (&grafdat, baseval, n, pfree - 1, petab, vendtab, NULL, NULL, iwtab, NULL); dofInit (&deofdat); dofConstant (&deofdat, 1, n, 1); /* One DOF per node, Fortran-based indexing */ orderInit (&ordedat); orderGraph (&ordedat, &grafdat); /* Compute ordering with Scotch */ #ifdef ESMUMPS_DEBUG /* Permutations are output for debugging only */ memCpy (elentab, ordedat.permtab, n * sizeof (INT)); /* Copy permutations */ memCpy (lasttab, ordedat.peritab, n * sizeof (INT)); #endif /* ESMUMPS_DEBUG */ symbolInit (&symbdat); symbolFaxGraph (&symbdat, &grafdat, &ordedat); /* Compute block symbolic factorizaion */ for (cblknum = 0; cblknum < symbdat.cblknbr; cblknum ++) { /* For all column blocks */ INT degnbr; /* True degree of column block */ INT bloknum; for (bloknum = symbdat.cblktab[cblknum].bloknum, degnbr = 0; bloknum < symbdat.cblktab[cblknum + 1].bloknum; bloknum ++) degnbr += symbdat.bloktab[bloknum - baseval].lrownum - symbdat.bloktab[bloknum - baseval].frownum + 1; nvtab[ordedat.peritab[symbdat.cblktab[cblknum].fcolnum - baseval] - baseval] = degnbr; /* Set true block degree */ for (colnum = symbdat.cblktab[cblknum].fcolnum + 1; /* For all secondary variables */ colnum <= symbdat.cblktab[cblknum].lcolnum; colnum ++) { nvtab[ordedat.peritab[colnum - baseval] - baseval] = 0; /* Set nv = 0 and pe = - principal variable */ petab[ordedat.peritab[colnum - baseval] - baseval] = - ordedat.peritab[symbdat.cblktab[cblknum].fcolnum - baseval]; } if (symbdat.cblktab[cblknum].bloknum == /* If column block has no extra-diagonals */ symbdat.cblktab[cblknum + 1].bloknum - 1) /* Then mark block as root of subtree */ petab[ordedat.peritab[symbdat.cblktab[cblknum].fcolnum - baseval] - baseval] = 0; else petab[ordedat.peritab[symbdat.cblktab[cblknum].fcolnum - baseval] - baseval] = - ordedat.peritab[symbdat.cblktab[symbdat.bloktab[symbdat.cblktab[cblknum].bloknum + 1 - baseval].cblknum - baseval].fcolnum - baseval]; } symbolExit (&symbdat); orderExit (&ordedat); dofExit (&deofdat); graphExit (&grafdat); memFree (vendtab); return (0); } scotch-6.0.4.dfsg/src/esmumps/esmumps_f.c0000644002563400244210000000704012056406465023524 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : esmumps_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains Fortran MUMPS **/ /** stubs for the ordering routines of the **/ /** libSCOTCH + Emilio libfax libraries. **/ /** **/ /** DATES : # Version 0.0 : from : 16 may 2001 **/ /** to 17 may 2001 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #include "common.h" #include "esmumps.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the MUMPS ordering routine. */ /* */ /**************************************/ FORTRAN ( \ ESMUMPSF, esmumpsf, ( \ const INT * const n, \ const INT * const iwlen, \ INT * const petab, \ const INT * const pfree, \ INT * const lentab, \ INT * const iwtab, \ INT * const nvtab, \ INT * const elentab, \ INT * const lasttab, \ INT * const ncmpa), \ (n, iwlen, petab, pfree, lentab, iwtab, nvtab, elentab, lasttab, ncmpa)) { *ncmpa = esmumps (*n, *iwlen, petab, *pfree, lentab, iwtab, nvtab, elentab, lasttab); } scotch-6.0.4.dfsg/src/esmumps/dof.h0000644002563400244210000001203012056406465022276 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dof.h **/ /** **/ /** AUTHORS : David GOUDIN **/ /** Pascal HENON **/ /** Francois PELLEGRINI **/ /** Pierre RAMET **/ /** **/ /** FUNCTION : Part of a parallel direct block solver. **/ /** These lines are the data declarations **/ /** for the DOF handling structure. **/ /** **/ /** DATES : # Version 0.0 : from : 07 oct 1998 **/ /** to 16 oct 1998 **/ /** # Version 1.0 : from : 06 jun 2002 **/ /** to 06 jun 2002 **/ /** # Version 3.0 : from : 28 feb 2004 **/ /** to 29 feb 2004 **/ /** **/ /************************************************************/ #define DOF_H #define DOF_CONSTANT /* Constant DOFs for ESMUMPS */ /* ** The type and structure definitions. */ /*+ The DOF structure. This structure is always associated to a Graph structure, which holds the base value. +*/ typedef struct Dof_ { INT baseval; /*+ Base value for indexing +*/ INT nodenbr; /*+ Number of nodes in DOF array +*/ INT noddval; /*+ DOF value for every node (if noddtab == NULL, 0 else) +*/ INT * restrict noddtab; /*+ Array of node->first DOF indexes (if noddval == 0) [+1,based] +*/ } Dof; /* ** The function prototypes. */ #ifndef DOF #define static #endif int dofInit (Dof * const deofptr); void dofExit (Dof * const deofptr); int dofLoad (Dof * const deofptr, FILE * const stream); int dofSave (const Dof * const deofptr, FILE * const stream); void dofConstant (Dof * const deofptr, const INT baseval, const INT nodenbr, const INT noddval); #ifdef GRAPH_H int dofGraph (Dof * const deofptr, const Graph * grafptr, const INT, const INT * const peritab); #endif /* GRAPH_H */ #undef static /* ** The macro definitions. */ #ifdef DOF_CONSTANT #define noddVal(deofptr,nodenum) ((deofptr)->baseval + (deofptr)->noddval * ((nodenum) - (deofptr)->baseval)) #define noddDlt(deofptr,nodenum) ((deofptr)->noddval) #else /* DOF_CONSTANT */ #define noddVal(deofptr,nodenum) (((deofptr)->noddtab != NULL) ? (deofptr)->noddtab[(deofptr)->baseval + (nodenum)] : ((deofptr)->baseval + (deofptr)->noddval * ((nodenum) - (deofptr)->baseval))) #define noddDlt(deofptr,nodenum) (((deofptr)->noddtab != NULL) ? ((deofptr)->noddtab[(deofptr)->baseval + (nodenum) + 1] - (deofptr)->noddtab[(deofptr)->baseval + (nodenum)]) : (deofptr)->noddval) #endif /* DOF_CONSTANT */ scotch-6.0.4.dfsg/src/esmumps/esmumps.h0000644002563400244210000000606512056406465023232 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : esmumps.h **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the symbolic factorization routine. **/ /** **/ /** DATES : # Version 0.0 : from : 22 jul 1998 **/ /** to 24 sep 1998 **/ /** # Version 0.1 : from : 04 apr 1999 **/ /** to 01 may 1999 **/ /** **/ /************************************************************/ #define ESMUMPS_H /* ** The function prototypes. */ #ifndef ESMUMPS #define static #endif int esmumps (const INT n, const INT iwlen, INT * const pe, const INT pfree, INT * const len, INT * const iw, INT * const nv, INT * const elen, INT * const last); int esmumps_strat1 (const INT procnbr, const INT leafsiz, const int leorval, const INT cminval, const INT cmaxval, const double fratval, const int verbval, FILE * const stream, char * const straptr); #undef static scotch-6.0.4.dfsg/src/esmumps/order.h0000644002563400244210000001350212056406465022646 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : order.h **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a parallel direct block solver. **/ /** These lines are the data declarations **/ /** for the graph ordering routine. **/ /** **/ /** DATES : # Version 0.0 : from : 22 aug 1998 **/ /** to 01 may 1999 **/ /** # Version 2.0 : from : 25 oct 2003 **/ /** to 02 jul 2010 **/ /** **/ /************************************************************/ #define ORDER_H /* ** The type and structure definitions. */ /*+ Ordering structure. vnodbas holds the base value for node indexings. vnodbas is equal to baseval for graphs, and to vnodbas for meshes. The same holds for rangtab, with rangtab[0] = vnodbas. +*/ typedef struct Order_ { INT cblknbr; /*+ Number of column blocks +*/ INT * rangtab; /*+ Column block range array [based,+1] +*/ INT * permtab; /*+ Permutation array [based] +*/ INT * peritab; /*+ Inverse permutation array [based] +*/ } Order; /* ** The function prototypes. */ #ifndef ORDER #define static #endif int orderInit (Order * const ordeptr); void orderExit (Order * const ordeptr); int orderLoad (Order * const ordeptr, FILE * const stream); int orderSave (const Order * const ordeptr, FILE * const stream); void orderBase (Order * restrict const ordeptr, const INT baseval); int orderCheck (const Order * const ordeptr); int orderGrid2 (Order * const ordeptr, const INT xnbr, const INT ynbr, const INT baseval, const INT xlim, const INT ylim); int orderGrid2C (Order * const ordeptr, const INT xnbr, const INT ynbr, const INT baseval, const INT xlim, const INT ylim); int orderGrid3 (Order * const ordeptr, const INT xnbr, const INT ynbr, const INT znbr, const INT baseval, const INT xlim, const INT ylim, const INT zlim); int orderGrid3C (Order * const ordeptr, const INT xnbr, const INT ynbr, const INT znbr, const INT baseval, const INT xlim, const INT ylim, const INT zlim); #ifdef GRAPH_H int orderGraph (Order * restrict const ordeptr, Graph * restrict const grafptr); int orderGraphList (Order * restrict const ordeptr, Graph * restrict const grafptr, const INT listnbr, const INT * restrict const listtab); int orderGraphStrat (Order * restrict const ordeptr, Graph * restrict const grafptr, const char * restrict const); int orderGraphListStrat (Order * restrict const ordeptr, Graph * restrict const grafptr, const INT listnbr, const INT * restrict const listtab, const char * const); #endif /* GRAPH_H */ #ifdef MESH_H int orderMesh (Order * restrict const ordeptr, Mesh * restrict const meshptr); int orderMeshList (Order * restrict const ordeptr, Mesh * restrict const meshptr, const INT listnbr, const INT * restrict const listtab); int orderMeshStrat (Order * restrict const ordeptr, Mesh * restrict const meshptr, const char * const); int orderMeshListStrat (Order * restrict const ordeptr, Mesh * restrict const meshptr, const INT listnbr, const INT * restrict const listtab, const char * const); #endif /* MESH_H */ #undef static scotch-6.0.4.dfsg/src/esmumps/Makefile0000644002563400244210000001103312500671566023017 0ustar trophimeutilisateurs du domaine## Copyright 2004,2007-2010,2012,2015 IPB, Universite de Bordeaux, INRIA & CNRS ## ## This file is part of the Scotch software package for static mapping, ## graph partitioning and sparse matrix ordering. ## ## This software is governed by the CeCILL-C license under French law ## and abiding by the rules of distribution of free software. You can ## use, modify and/or redistribute the software under the terms of the ## CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ## URL: "http://www.cecill.info". ## ## As a counterpart to the access to the source code and rights to copy, ## modify and redistribute granted by the license, users are provided ## only with a limited warranty and the software's author, the holder of ## the economic rights, and the successive licensors have only limited ## liability. ## ## In this respect, the user's attention is drawn to the risks associated ## with loading, using, modifying and/or developing or reproducing the ## software by the user in light of its specific status of free software, ## that may mean that it is complicated to manipulate, and that also ## therefore means that it is reserved for developers and experienced ## professionals having in-depth computer knowledge. Users are therefore ## encouraged to load and test the software's suitability as regards ## their requirements in conditions enabling the security of their ## systems and/or data to be ensured and, more generally, to use and ## operate it in the same conditions as regards security. ## ## The fact that you are presently reading this means that you have had ## knowledge of the CeCILL-C license and that you accept its terms. ## bindir = ../../bin includedir = ../../include libdir = ../../lib ## ## General inference rules. ## include ../Makefile.inc %$(OBJ) : %.c $(CC) $(CFLAGS) $(CLIBFLAGS) -I$(includedir) -c $(<) -o $(@) %$(EXE) : %.c $(CC) $(CFLAGS) -I$(includedir) $(<) -o $(@) -L$(libdir) $(LDFLAGS) -L. -l$(ESMUMPSLIB) -l$(SCOTCHLIB) -lscotch -l$(SCOTCHLIB)errexit -lm ## ## Project rules. ## .PHONY : ptscotch scotch ptinstall install clean realclean scotch : clean $(MAKE) CC="$(CCS)" CCD="$(CCS)" SCOTCHLIB=scotch ESMUMPSLIB=esmumps \ libesmumps$(LIB) \ main_esmumps$(EXE) ptscotch : clean $(MAKE) CFLAGS="$(CFLAGS) -DSCOTCH_PTSCOTCH" CC="$(CCP)" SCOTCHLIB=ptscotch ESMUMPSLIB=ptesmumps \ libesmumps$(LIB) \ main_esmumps$(EXE) install : -$(CP) esmumps.h $(includedir) -$(CP) libesmumps$(LIB) $(libdir) ptinstall : -$(CP) esmumps.h $(includedir) -$(CP) libptesmumps$(LIB) $(libdir) clean : -$(RM) *~ common.h *$(OBJ) lib*$(LIB) main_esmumps$(EXE) realclean : clean ## ## Todo list. ## common.h : ../libscotch/common.h \ module.h $(CAT) module.h ../libscotch/common.h > $(@) graph_graph$(OBJ) : graph_graph.c \ common.h \ $(includedir)/$(SCOTCHLIB).h \ graph.h order$(OBJ) : order.c \ order.h \ common.h \ graph.h order_scotch_graph$(OBJ) : order_scotch_graph.c \ order.h \ common.h \ graph.h \ $(includedir)/$(SCOTCHLIB).h dof$(OBJ) : dof.c \ dof.h \ common.h \ graph.h \ $(includedir)/$(SCOTCHLIB).h symbol$(OBJ) : symbol.c \ symbol.h \ common.h symbol_fax$(OBJ) : symbol_fax.c \ common.h \ graph.h \ symbol.h \ order.h \ fax.h symbol_fax_graph$(OBJ) : symbol_fax_graph.c \ symbol_fax.c \ common.h \ graph.h \ symbol.h \ order.h \ fax.h \ $(includedir)/$(SCOTCHLIB).h esmumps$(OBJ) : esmumps.c \ common.h \ graph.h \ symbol.h \ order.h \ fax.h \ esmumps.h \ $(includedir)/$(SCOTCHLIB).h esmumps_f$(OBJ) : esmumps_f.c \ common.h \ esmumps.h esmumps_strats$(OBJ) : esmumps_strats.c \ common.h \ esmumps.h libesmumps$(LIB) : graph_graph$(OBJ) \ order$(OBJ) \ order_scotch_graph$(OBJ) \ dof$(OBJ) \ symbol$(OBJ) \ symbol_fax_graph$(OBJ) \ esmumps$(OBJ) \ esmumps_f$(OBJ) \ esmumps_strats$(OBJ) $(AR) $(ARFLAGS) lib$(ESMUMPSLIB)$(LIB) $(?) -$(RANLIB) lib$(ESMUMPSLIB)$(LIB) main_esmumps$(EXE) : main_esmumps.c \ common.h \ graph.h \ order.h \ symbol.h \ esmumps.h \ lib$(ESMUMPSLIB)$(LIB) \ $(libdir)/lib$(SCOTCHLIB)$(LIB) \ $(libdir)/lib$(SCOTCHLIB)errexit$(LIB) scotch-6.0.4.dfsg/src/esmumps/graph_graph.c0000644002563400244210000001422512056406465024013 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2009 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : graph_graph.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a parallel direct block solver. **/ /** These module holds the array graph **/ /** building routine. **/ /** **/ /** DATES : # Version 1.3 : from : 14 oct 2003 **/ /** to 22 jan 2004 **/ /** # Version 2.0 : from : 28 feb 2004 **/ /** to 06 dec 2004 **/ /** # Version 5.1 : from : 22 jan 2009 **/ /** to 22 jan 2009 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GRAPH #include "common.h" #ifdef SCOTCH_PTSCOTCH #include "ptscotch.h" #else /* SCOTCH_PTSCOTCH */ #include "scotch.h" #endif /* SCOTCH_PTSCOTCH */ #include "graph.h" /********************************/ /* */ /* The graph handling routines. */ /* */ /********************************/ /* This routine builds a graph ** structure from the given ** arrays. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int graphBuildGraph ( Graph * const grafptr, /*+ Graph to build +*/ const INT baseval, /*+ Base value +*/ const INT vertnbr, /*+ Number of vertices +*/ const INT edgenbr, /*+ Number of arcs +*/ INT * restrict verttab, /*+ Vertex array +*/ INT * restrict velotab, /*+ Array of vertex weights (DOFs) if not NULL +*/ INT * restrict edgetab) /*+ Edge array +*/ { if (sizeof (INT) != sizeof (SCOTCH_Num)) { /* Check integer consistency */ errorPrint ("graphBuildGraph: inconsistent integer types"); return (1); } SCOTCH_graphBuild (grafptr, baseval, vertnbr, verttab, NULL, velotab, NULL, edgenbr, edgetab, NULL); #ifdef GRAPH_DEBUG if (graphCheck (grafptr) != 0) { /* Check graph consistency */ errorPrint ("graphBuildGraph: inconsistent graph data"); return (1); } #endif /* GRAPH_DEBUG */ return (0); } /* This routine builds a graph ** structure from the given ** arrays, with full libScotch ** features. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int graphBuildGraph2 ( Graph * const grafptr, /*+ Graph to build +*/ const INT baseval, /*+ Base value +*/ const INT vertnbr, /*+ Number of vertices +*/ const INT edgenbr, /*+ Number of arcs +*/ INT * restrict verttab, /*+ Vertex array +*/ INT * restrict vendtab, /*+ Vertex end array +*/ INT * restrict velotab, /*+ Array of vertex weights (DOFs) if not NULL +*/ INT * restrict vlbltab, /*+ Array of vertex labels if not NULL +*/ INT * restrict edgetab, /*+ Edge array +*/ INT * restrict edlotab) /*+ Edge load array +*/ { if (sizeof (INT) != sizeof (SCOTCH_Num)) { /* Check integer consistency */ errorPrint ("graphBuildGraph2: inconsistent integer types"); return (1); } SCOTCH_graphBuild (grafptr, baseval, vertnbr, verttab, vendtab, velotab, vlbltab, edgenbr, edgetab, edlotab); #ifdef GRAPH_DEBUG if (graphCheck (grafptr) != 0) { /* Check graph consistency */ errorPrint ("graphBuildGraph2: inconsistent graph data"); return (1); } #endif /* GRAPH_DEBUG */ return (0); } scotch-6.0.4.dfsg/src/esmumps/symbol.h0000644002563400244210000002230312056406465023037 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : symbol.h **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** David GOUDIN (v0.0) **/ /** Pascal HENON (v0.0) **/ /** Pierre RAMET (v0.0) **/ /** **/ /** FUNCTION : Part of a parallel direct block solver. **/ /** These lines are the data declarations **/ /** for the symbolic matrix. **/ /** **/ /** DATES : # Version 0.0 : from : 22 jul 1998 **/ /** to 07 oct 1998 **/ /** # Version 0.1 : from : 21 mar 2002 **/ /** to 21 mar 2002 **/ /** # Version 1.0 : from : 03 jun 2002 **/ /** to 26 jun 2002 **/ /** # Version 1.3 : from : 10 apr 2003 **/ /** to 10 jun 2003 **/ /** # Version 3.0 : from : 28 feb 2004 **/ /** to 03 mar 2005 **/ /** # Version 5.1 : from : 05 nov 2010 **/ /** to 05 nov 2010 **/ /** **/ /************************************************************/ #define SYMBOL_H #define SYMBOL_VERSION 1 /* ** The type and structure definitions. */ /*+ The column block structure. +*/ typedef struct SymbolCblk_ { INT fcolnum; /*+ First column index +*/ INT lcolnum; /*+ Last column index (inclusive) +*/ INT bloknum; /*+ First block in column (diagonal) +*/ } SymbolCblk; /*+ The column block structure. +*/ typedef struct SymbolBlok_ { INT frownum; /*+ First row index +*/ INT lrownum; /*+ Last row index (inclusive) +*/ INT cblknum; /*+ Facing column block +*/ INT levfval; /*+ Level-of-fill value +*/ } SymbolBlok; /*+ The symbolic block matrix. +*/ typedef struct SymbolMatrix_ { INT baseval; /*+ Base value for numberings +*/ INT cblknbr; /*+ Number of column blocks +*/ INT bloknbr; /*+ Number of blocks +*/ SymbolCblk * cblktab; /*+ Array of column blocks [+1,based] +*/ SymbolBlok * bloktab; /*+ Array of blocks [based] +*/ INT nodenbr; /*+ Number of nodes in matrix +*/ } SymbolMatrix; /*+ The type of cost computations. +*/ typedef enum SymbolCostType_ { SYMBOLCOSTLDLT /*+ Crout (i.e. LDLt) cost function +*/ } SymbolCostType; /* Structure for keeping track of selected blocks in the matrix pattern. The values of the tables are the remaining values for the yet unselected blocks. */ typedef struct SymbolKeepBlok_ { INT levfval; /*+ Values for incomplete factorisation +*/ INT nupdval; INT ctrival; INT ctroval; INT hghtval; } SymbolKeepBlok; typedef struct SymbolKeep_ { INT levfmax; /*+ Maximum values for incomplete fax +*/ INT nupdmax; INT ctrimax; INT ctromax; INT hghtmax; byte * keeptab; /*+ Flag array for kept blocks +*/ SymbolKeepBlok * kblktab; /*+ Block parameter array +*/ double * levftab; /*+ Area arrays for selected blocks +*/ double * nupdtab; double * ctritab; double * ctrotab; double * hghttab; } SymbolKeep; /* ** The function prototypes. */ #ifndef SYMBOL #define static #endif int symbolInit (SymbolMatrix * const symbptr); void symbolExit (SymbolMatrix * const symbptr); void symbolRealloc (SymbolMatrix * const symbptr); int symbolLoad (SymbolMatrix * const symbptr, FILE * const stream); int symbolSave (const SymbolMatrix * const symbptr, FILE * const stream); int symbolCheck (const SymbolMatrix * const symbptr); int symbolDraw (const SymbolMatrix * const symbptr, FILE * const stream); int symbolDrawFunc (const SymbolMatrix * const symbptr, int (*) (const SymbolMatrix * const, const SymbolBlok * const, void * const, float * const), int (*) (const SymbolMatrix * const, const SymbolBlok * const, void * const, float * const), void * const, FILE * const stream); void symbolDrawColor (const INT labl, float * const coloptr); #ifdef DOF_H int symbolCost (const SymbolMatrix * const symbptr, const Dof * const deofptr, const SymbolCostType typeval, double * const nnzptr, double * const opcptr); int symbolCosti (const SymbolMatrix * const symbptr, const Dof * const deofptr, const SymbolCostType typeval, const INT levfval, double * const nnzptr, double * const opcptr); int symbolLevf (const SymbolMatrix * const symbptr, INT * const levfmax, INT ** const levftab); int symbolTree (const SymbolMatrix * const symbptr, const Dof * const deofptr, INT * const leafnbr, INT * const heigmin, INT * const heigmax, double * const heigavg, double * const heigdlt); int symbolNonzeros (const SymbolMatrix * const symbptr, FILE * const stream); #endif /* DOF_H */ int symbolKeepInit (SymbolKeep * restrict const keepptr, const SymbolMatrix * const symbptr); void symbolKeepExit (SymbolKeep * restrict const keepptr); void symbolKeepAdd (SymbolKeep * restrict const keepptr, const SymbolMatrix * const symbptr, int (* funcptr) (const SymbolKeepBlok * const, void * const), void * dataptr); void symbolKeepDel (SymbolKeep * restrict const keepptr, const SymbolMatrix * const symbptr, int (* funcptr) (const SymbolKeepBlok * const, void * const), void * dataptr); int symbolKeepCompute (SymbolKeep * restrict const keepptr, const SymbolMatrix * const symbptr); int symbolKeepHisto (SymbolKeep * const keepptr, const SymbolMatrix * const, int (* funcptr) (const SymbolKeepBlok * const, void * const), void * dataptr); int symbolKeepPurge (SymbolKeep * restrict const keepptr, SymbolMatrix * restrict const symbptr); int symbolKeepView (const SymbolKeep * const keepptr, const double nnzlmax, const char * const nameptr); #undef static scotch-6.0.4.dfsg/src/esmumps/order.c0000644002563400244210000000651312056406465022645 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : order.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a parallel direct block solver. **/ /** This module computes orderings. **/ /** **/ /** DATES : # Version 0.0 : from : 20 aug 1998 **/ /** to 24 sep 1998 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define ORDER #include "common.h" #include "order.h" /***********************************/ /* */ /* The ordering handling routines. */ /* */ /***********************************/ /* This routine initializes the given ** ordering structure. ** It returns: ** - 0 : in all cases. */ int orderInit ( Order * const ordeptr) { memSet (ordeptr, 0, sizeof (Order)); return (0); } /* This routine frees the contents ** of the given ordering. ** It returns: ** - VOID : in all cases. */ void orderExit ( Order * const ordeptr) { if (ordeptr->rangtab != NULL) memFree (ordeptr->rangtab); if (ordeptr->permtab != NULL) memFree (ordeptr->permtab); if (ordeptr->peritab != NULL) memFree (ordeptr->peritab); #ifdef ORDER_DEBUG memSet (ordeptr, ~0, sizeof (Order)); #endif /* ORDER_DEBUG */ } scotch-6.0.4.dfsg/src/esmumps/symbol_fax.h0000644002563400244210000000741512056406465023704 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : symbol_fax.h **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** Jean ROMAN (v0.0) **/ /** **/ /** FUNCTION : Part of a parallel direct block solver. **/ /** These lines are the data declarations **/ /** for the symbolic factorization routine. **/ /** **/ /** DATES : # Version 0.0 : from : 22 jul 1998 **/ /** to 24 sep 1998 **/ /** # Version 0.1 : from : 04 apr 1999 **/ /** to 01 may 1999 **/ /** # Version 1.0 : from : 01 jun 2002 **/ /** to 05 jun 2002 **/ /** # Version 1.1 : from : 26 jun 2002 **/ /** to 26 jun 2002 **/ /** # Version 3.0 : from : 03 mar 2004 **/ /** to 03 mar 2004 **/ /** **/ /************************************************************/ #define SYMBOL_FAX_H /* ** The defines. */ /* Prime number for hashing vertex numbers. */ #define SYMBOL_FAX_HASHPRIME 17 /*+ Prime number for hashing +*/ /* ** The type and structure definitions. */ /*+ The chained column block structure. These blocks are chained in a single linked list for block merge with blocks of left columns. +*/ typedef struct SymbolFaxTlok_ { INT frownum; /*+ First row index +*/ INT lrownum; /*+ Last row index (inclusive) +*/ INT cblknum; /*+ Facing column block +*/ INT nextnum; /*+ Index of next block +*/ } SymbolFaxTlok; scotch-6.0.4.dfsg/src/esmumps/symbol.c0000644002563400244210000001144212056406465023034 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : symbol.c **/ /** **/ /** AUTHORS : David GOUDIN **/ /** Pascal HENON **/ /** Francois PELLEGRINI **/ /** Pierre RAMET **/ /** **/ /** FUNCTION : Part of a parallel direct block solver. **/ /** These lines are the general purpose **/ /** routines for the symbolic matrix. **/ /** **/ /** DATES : # Version 0.0 : from : 22 jul 1998 **/ /** to 07 oct 1998 **/ /** # Version 0.1 : from : 03 dec 1998 **/ /** to 03 dec 1998 **/ /** # Version 3.0 : from : 29 feb 2004 **/ /** to 29 feb 2004 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define SYMBOL #include "common.h" #include "symbol.h" /******************************************/ /* */ /* The symbolic matrix handling routines. */ /* */ /******************************************/ /*+ This routine initializes the given *** symbolic block matrix structure. *** It returns: *** - 0 : in all cases. +*/ int symbolInit ( SymbolMatrix * const symbptr) { memSet (symbptr, 0, sizeof (SymbolMatrix)); return (0); } /*+ This routine frees the contents *** of the given symbolic block matrix. *** It returns: *** - VOID : in all cases. +*/ void symbolExit ( SymbolMatrix * const symbptr) { if (symbptr->cblktab != NULL) memFree (symbptr->cblktab); if (symbptr->bloktab != NULL) memFree (symbptr->bloktab); #ifdef SYMBOL_DEBUG symbolInit (symbptr); #endif /* SYMBOL_DEBUG */ } /*+ This routine reallocates the arrays *** of the given symbolic block matrix. *** It returns: *** - VOID : in all cases. +*/ void symbolRealloc ( SymbolMatrix * const symbptr) { SymbolCblk * cblktab; SymbolBlok * bloktab; if ((cblktab = (SymbolCblk *) memAlloc ((symbptr->cblknbr + 1) * sizeof (SymbolCblk))) == NULL) return; /* Cannot move smallest array */ memCpy (cblktab, symbptr->cblktab, (symbptr->cblknbr + 1) * sizeof (SymbolCblk)); memFree (symbptr->cblktab); /* Move column block array */ symbptr->cblktab = cblktab; if ((bloktab = (SymbolBlok *) memAlloc (symbptr->bloknbr * sizeof (SymbolBlok))) == NULL) return; /* Cannot move array */ memCpy (bloktab, symbptr->bloktab, symbptr->bloknbr * sizeof (SymbolBlok)); memFree (symbptr->bloktab); /* Move column block array */ symbptr->bloktab = bloktab; } scotch-6.0.4.dfsg/src/esmumps/symbol_fax.c0000644002563400244210000006176712056406465023711 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : symbol_fax.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** Jean ROMAN (v0.0) **/ /** **/ /** FUNCTION : Part of a parallel direct block solver. **/ /** This is the generic block symbolic **/ /** factorization routine. **/ /** **/ /** DATES : # Version 0.0 : from : 22 jul 1998 **/ /** to 29 sep 1998 **/ /** # Version 0.1 : from : 04 apr 1999 **/ /** to 21 apr 1999 **/ /** # Version 0.2 : from : 08 may 2000 **/ /** to 09 may 2000 **/ /** # Version 1.0 : from : 13 mar 2002 **/ /** to 08 jun 2002 **/ /** # Version 1.2 : from : 23 aug 2002 **/ /** to 23 aug 2002 **/ /** # Version 2.0 : from : 21 mar 2003 **/ /** to 21 mar 2003 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #ifndef SYMBOL_FAX_INCLUDED /* If included from other file */ #define SYMBOL_FAX #include "common.h" #include "symbol.h" #include "order.h" #include "fax.h" #include "symbol_fax.h" #endif /* SYMBOL_FAX_INCLUDED */ /***********************************/ /* */ /* Symbolic factorization routine. */ /* */ /***********************************/ /*+ This routine computes the block symbolic *** factorization of the given matrix *** according to the given vertex ordering. *** It returns: *** - 0 : on success. *** - !0 : on error. *** Algorithm: *** The algorithm is implemented in a *** cache-friendly manner, by using a single *** dynamic array which grows along with the *** number of computed blocks. The array is *** decomposed in the following manner: *** - In a first phase, a hash table and a *** sort area are reserved at the end of *** the space of already computed blocks. *** The sort area is created far enough from *** the end of the array of already computed *** blocks such that if there are no contributing *** blocks all new blocks can be created without *** colliding with the sort area. *** - Then, in a second phase, if the current *** column block does have contributing column *** blocks, an area for simply-linked temporary *** blocks is reserved at least after the sort area, *** leaving enough space to create all of the *** corresponding potential new blocks *** just after all the blocks of the previous *** column block (right picture). *** ___________ *** |ccccccccccc| <- bloktab (bloktax) *** |ccccccccccc| *** |ccccccccccc| :ccccccccccc: *** |ccccccccccc| >- Computed blocks ----------< |ccccccccccc| *** |ccccccccccc| |ccccccccccc| *** |-----------| |:::::::::::| *** |hhhhhhhhhhh| <- hashtab = bloknum --------> |bcbcbcbcbcb| *** |hhhhhhhhhhh| | |cbcbcbcbcbc| *** |hhhhhhhhhhh| | |bcbcbcbcbcb| *** |hhhhhhhhhhh| | |cbcbcbcbcbc| *** |-----------| | |bcbcbcbcbcb| *** | | | |-----------| *** |-----------| <- sorttab...... ------------> | | *** |sssssssssss| | | *** |sssssssssss| | | *** |-----------| <- ............................| | *** | | tloktab -> |-----------| *** | | |ttttttttttt| *** | | |ttttttttttt| *** : : |-----------| *** :___________: :___________: *** <- bloktab + blokmax +*/ #ifndef SYMBOL_FAX_INCLUDED #define SYMBOL_FAX_ITERATOR(ngbdptr, vertnum, vertend) \ for (vertend = ngbfrst ((ngbdptr), (vertnum)); \ vertend >= baseval; \ vertend = ngbnext (ngbdptr)) { #define SYMBOL_FAX_VERTEX_DEGREE(ngbdptr, vertnum) \ (ngbdegr ((ngbdptr), (vertnum))) int symbolFax ( SymbolMatrix * const symbptr, /*+ Symbolic block matrix [based] +*/ const INT vertnbr, /*+ Number of vertices +*/ const INT edgenbr, /*+ Number of edges +*/ const INT baseval, /*+ Base value +*/ void * const ngbdptr, /*+ Neighbor bookkeeping area +*/ INT ngbfrst (void * const, const INT), /*+ First neighbor function +*/ INT ngbnext (void * const), /*+ Next neighbor function +*/ INT ngbdegr (void * const, const INT), /*+ Vertex degree function (upper bound) +*/ const Order * const ordeptr) /*+ Matrix ordering +*/ #endif /* SYMBOL_FAX_INCLUDED */ { INT vertnum; /* Vertex number of current column */ INT vertend; /* Current end vertex number */ const INT * restrict permtax; /* Based access to direct permutation array */ const INT * restrict peritax; /* Based access to inverse permutation array */ const INT * restrict rangtax; /* Based access to column block range array */ INT * restrict ctrbtax; /* Based access to array of contribution chains */ SymbolCblk * restrict cblktax; /* Based access to column block array */ INT cblknum; /* Based number of current column block */ INT cblkctr; /* Based number of current contributing column block */ SymbolBlok * restrict bloktax; /* Based access to block array */ INT bloknum; /* Based number of current first free block slot */ INT blokmax; /* Maximum number of blocks in array */ SymbolFaxTlok * restrict tloktab; /* Beginning of array of temporary blocks */ INT ctrbsum; /* Number of contributing blocks for column block */ INT * restrict sorttab; /* Beginning of sort area */ INT sortnbr; /* Number of vertices in sort area and hash table */ INT * restrict hashtab; /* Hash vertex table */ INT hashmsk; /* Mask for access to hash table */ INT colend; /* Column number of vertex neighbor */ permtax = ordeptr->permtab - baseval; /* Compute array bases */ peritax = ordeptr->peritab - baseval; rangtax = ordeptr->rangtab - baseval; blokmax = ordeptr->cblknbr * (2 + edgenbr / vertnbr) + 2; /* Estimate size of initial block array */ { /* Allocate arrays for factoring */ INT * ctrbtab; /* Array for contribution chaining */ SymbolCblk * cblktab; /* Column block array */ SymbolBlok * bloktab; /* Block array */ if (((ctrbtab = (INT *) memAlloc (ordeptr->cblknbr * sizeof (INT))) == NULL) || ((cblktab = (SymbolCblk *) memAlloc ((ordeptr->cblknbr + 1) * sizeof (SymbolCblk))) == NULL) || ((bloktab = (SymbolBlok *) memAlloc (blokmax * sizeof (SymbolBlok))) == NULL)) { errorPrint ("symbolFax: out of memory (1)"); if (ctrbtab != NULL) { if (cblktab != NULL) memFree (cblktab); memFree (ctrbtab); } return (1); } cblktax = cblktab - baseval; /* Set based accesses */ bloktax = bloktab - baseval; ctrbtax = ctrbtab - baseval; memset (ctrbtab, ~0, ordeptr->cblknbr * sizeof (INT)); /* Initialize column block contributions link array */ } bloknum = baseval; for (cblknum = baseval; cblknum < baseval + ordeptr->cblknbr; cblknum ++) { /* For all column blocks */ INT colnum; /* Number of current column [based] */ INT colmax; /* Maximum column index for current column block */ { /* Compute offsets and check for array size */ INT degrsum; INT hashsiz; INT hashmax; INT ctrbtmp; INT sortoft; /* Offset of sort array */ INT tlokoft; /* Offset of temporary block array */ INT tlndoft; /* Offset of end of temporary block array */ INT tlokmax; colnum = rangtax[cblknum]; colmax = rangtax[cblknum + 1]; /* Get maximum column value */ cblktax[cblknum].fcolnum = colnum; /* Set column block data */ cblktax[cblknum].lcolnum = colmax - 1; cblktax[cblknum].bloknum = bloknum; degrsum = 0; for ( ; colnum < colmax; colnum ++) /* For all columns */ degrsum += SYMBOL_FAX_VERTEX_DEGREE (ngbdptr, peritax[colnum]); /* Add column degrees */ for (hashmax = 256; hashmax < degrsum; hashmax *= 2) ; /* Get upper bound on hash table size */ hashsiz = hashmax << 2; /* Fill hash table at 1/4 of capacity */ hashmsk = hashsiz - 1; for (ctrbsum = 0, ctrbtmp = ctrbtax[cblknum]; /* Follow chain of contributing column blocks */ ctrbtmp != ~0; ctrbtmp = ctrbtax[ctrbtmp]) ctrbsum += cblktax[ctrbtmp + 1].bloknum - cblktax[ctrbtmp].bloknum - 2; /* Sum contributing column blocks */ tlokmax = degrsum + ctrbsum; sortoft = tlokmax * sizeof (SymbolBlok); if ((hashsiz * sizeof (INT)) > sortoft) /* Compute offset of sort area */ sortoft = (hashsiz * sizeof (INT)); tlokoft = sortoft + degrsum * sizeof (INT); /* Compute offset of temporary block area */ tlndoft = tlokoft + tlokmax * sizeof (SymbolFaxTlok); /* Compute end of area */ if (((byte *) (bloktax + bloknum) + tlndoft) > /* If not enough room */ ((byte *) (bloktax + blokmax))) { SymbolBlok * bloktmp; /* Temporary pointer for array resizing */ do blokmax = blokmax + (blokmax >> 2) + 4; /* Increase block array size by 25% as long as it does not fit */ while (((byte *) (bloktax + bloknum) + tlndoft) > ((byte *) (bloktax + blokmax))); if ((bloktmp = (SymbolBlok *) memRealloc (bloktax + baseval, (blokmax * sizeof (SymbolBlok)))) == NULL) { errorPrint ("symbolFax: out of memory (2)"); memFree (bloktax + baseval); memFree (cblktax + baseval); memFree (ctrbtax + baseval); return (1); } bloktax = bloktmp - baseval; } hashtab = (INT *) (bloktax + bloknum); sorttab = (INT *) ((byte *) hashtab + sortoft); tloktab = (SymbolFaxTlok *) ((byte *) hashtab + tlokoft); memset (hashtab, ~0, hashsiz * sizeof (INT)); /* Initialize hash table */ } sortnbr = 0; /* No vertices yet */ for (colnum = rangtax[cblknum]; colnum < colmax; colnum ++) { /* For all columns */ INT hashnum; vertnum = peritax[colnum]; /* Get associated vertex */ SYMBOL_FAX_ITERATOR (ngbdptr, vertnum, vertend) /* For all adjacent edges */ colend = permtax[vertend]; /* Get end column number */ if (colend < colmax) /* If end vertex number in left columns */ continue; /* Skip to next neighbor */ for (hashnum = (colend * SYMBOL_FAX_HASHPRIME) & hashmsk; ; /* Search end column in hash table */ hashnum = (hashnum + 1) & hashmsk) { INT * hashptr; hashptr = hashtab + hashnum; /* Point to hash slot */ if (*hashptr == colend) /* If end column in hash table */ break; /* Skip to next end column */ if (*hashptr == ~0) { /* If slot is empty */ *hashptr = colend; /* Set column in hash table */ sorttab[sortnbr ++] = colend; /* Add end column to sort array */ break; } } } /* End of loop on neighbors */ } /* End of loop on columns */ intSort1asc1 (sorttab, sortnbr); /* Sort neighbor array */ cblkctr = cblknum; if (ctrbtax[cblknum] == ~0) { /* If column is not to be updated */ INT sortnum; bloktax[bloknum].frownum = cblktax[cblknum].fcolnum; /* Build diagonal block */ bloktax[bloknum].lrownum = cblktax[cblknum].lcolnum; bloktax[bloknum].cblknum = cblknum; bloktax[bloknum].levfval = 0; bloknum ++; for (sortnum = 0; sortnum < sortnbr; ) { /* For all entries in sorted array */ INT colend; /* Column number of current entry */ colend = sorttab[sortnum]; if (colend >= rangtax[cblkctr + 1]) { /* If column block number to be found */ INT cblktmm; /* Median value */ INT cblktmx; /* Maximum value */ for (cblkctr ++, /* Find new column block by dichotomy */ cblktmx = ordeptr->cblknbr + baseval; cblktmx - cblkctr > 1; ) { cblktmm = (cblktmx + cblkctr) >> 1; if (rangtax[cblktmm] <= colend) cblkctr = cblktmm; else cblktmx = cblktmm; } } bloktax[bloknum].frownum = colend; /* Set beginning of new block */ while ((++ sortnum < sortnbr) && /* Scan extent of block */ (sorttab[sortnum] - 1 == sorttab[sortnum - 1]) && (sorttab[sortnum] < rangtax[cblkctr + 1])) ; bloktax[bloknum].lrownum = sorttab[sortnum - 1]; /* Set end of block */ bloktax[bloknum].cblknum = cblkctr; bloktax[bloknum].levfval = 0; bloknum ++; /* One more block */ } } else { /* Column will be updated */ INT sortnum; /* Current index in sort array */ INT tloknum; /* Current index on temporary block */ INT tlokfre; /* Index of first free block */ tloktab->frownum = cblktax[cblknum].fcolnum; /* Build diagonal chained block */ tloktab->lrownum = cblktax[cblknum].lcolnum; tloktab->cblknum = cblknum; tloktab->nextnum = 1; tloknum = 1; for (sortnum = 0; sortnum < sortnbr; ) { /* For all entries in sorted array */ INT colend; /* Column number of current entry */ colend = sorttab[sortnum]; if (colend >= rangtax[cblkctr + 1]) { /* If column block number to be found */ INT cblktmm; /* Median value */ INT cblktmx; /* Maximum value */ for (cblkctr ++, /* Find new column block by dichotomy */ cblktmx = ordeptr->cblknbr + baseval; cblktmx - cblkctr > 1; ) { cblktmm = (cblktmx + cblkctr) >> 1; if (rangtax[cblktmm] <= colend) cblkctr = cblktmm; else cblktmx = cblktmm; } } tloktab[tloknum].frownum = colend; /* Set beginning of new block */ while ((++ sortnum < sortnbr) && /* Scan extent of block */ (sorttab[sortnum] - 1 == sorttab[sortnum - 1]) && (sorttab[sortnum] < rangtax[cblkctr + 1])) ; tloktab[tloknum].lrownum = sorttab[sortnum - 1]; /* Set end of block */ tloktab[tloknum].cblknum = cblkctr; tloktab[tloknum].nextnum = tloknum + 1; /* Chain block */ tloknum = tloknum + 1; } tloktab[tloknum].frownum = /* Build trailing block */ tloktab[tloknum].lrownum = vertnbr + baseval; tloktab[tloknum].cblknum = ordeptr->cblknbr + baseval; tloktab[tloknum].nextnum = 0; /* Set end of chain (never chain to diagonal block) */ tlokfre = ++ tloknum; /* Build free chain for possible contributing blocks */ for ( ; tloknum < tlokfre + ctrbsum; tloknum = tloknum + 1) tloktab[tloknum].nextnum = tloknum + 1; tloktab[tloknum].nextnum = ~0; /* Set end of free chain */ for (cblkctr = ctrbtax[cblknum]; cblkctr != ~0; cblkctr = ctrbtax[cblkctr]) { /* Follow chain */ INT blokctr; /* Current index of contributing column block */ INT tloklst; /* Index of previous temporary block */ tloklst = 0; /* Previous is diagonal block */ tloknum = 0; /* Current is diagonal block */ for (blokctr = cblktax[cblkctr].bloknum + 2; /* For all blocks in contributing column block */ blokctr < cblktax[cblkctr + 1].bloknum; blokctr ++) { while ((tloktab[tloknum].cblknum < bloktax[blokctr].cblknum) || /* Skip unmatched chained blocks */ (tloktab[tloknum].lrownum < bloktax[blokctr].frownum - 1)) { tloklst = tloknum; tloknum = tloktab[tloknum].nextnum; } if ((bloktax[blokctr].cblknum < tloktab[tloknum].cblknum) || /* If contributing block has no mate */ (bloktax[blokctr].lrownum < tloktab[tloknum].frownum - 1)) { INT tloktmp; #ifdef FAX_DEBUG if (tlokfre == ~0) { errorPrint ("symbolFax: internal error (1)"); memFree (bloktax + baseval); memFree (cblktax + baseval); memFree (ctrbtax + baseval); return (1); } #endif /* FAX_DEBUG */ tloktmp = tloktab[tloklst].nextnum = tlokfre; /* Chain new block */ tloktab[tlokfre].frownum = bloktax[blokctr].frownum; /* Copy block data */ tloktab[tlokfre].lrownum = bloktax[blokctr].lrownum; tloktab[tlokfre].cblknum = bloktax[blokctr].cblknum; tlokfre = tloktab[tlokfre].nextnum; tloktab[tloktmp].nextnum = tloknum; /* Complete chainimg */ tloknum = tloktab[tloklst].nextnum; /* Resume from new block */ continue; /* Process next block */ } if ((bloktax[blokctr].lrownum >= tloktab[tloknum].frownum - 1) && /* Update chained block lower bound */ (bloktax[blokctr].frownum < tloktab[tloknum].frownum)) tloktab[tloknum].frownum = bloktax[blokctr].frownum; if ((bloktax[blokctr].frownum <= tloktab[tloknum].lrownum + 1) && /* Update chained block upper bound */ (bloktax[blokctr].lrownum > tloktab[tloknum].lrownum)) { INT tloktmp; tloktab[tloknum].lrownum = bloktax[blokctr].lrownum; for (tloktmp = tloktab[tloknum].nextnum; /* Aggregate following chained blocks */ (tloktab[tloktmp].cblknum == tloktab[tloknum].cblknum) && (tloktab[tloktmp].frownum <= tloktab[tloknum].lrownum + 1); tloktmp = tloktab[tloknum].nextnum) { if (tloktab[tloktmp].lrownum > tloktab[tloknum].lrownum) /* Merge aggregated block */ tloktab[tloknum].lrownum = tloktab[tloktmp].lrownum; tloktab[tloknum].nextnum = tloktab[tloktmp].nextnum; /* Unlink aggregated block */ tloktab[tloktmp].nextnum = tlokfre; tlokfre = tloktmp; } } } } for (tloknum = 0; /* For all chained blocks */ tloktab[tloknum].nextnum != 0; /* Until trailer block is reached */ tloknum = tloktab[tloknum].nextnum, bloknum ++) { /* Copy block data to block array */ bloktax[bloknum].frownum = tloktab[tloknum].frownum; bloktax[bloknum].lrownum = tloktab[tloknum].lrownum; bloktax[bloknum].cblknum = tloktab[tloknum].cblknum; bloktax[bloknum].levfval = 0; } } if ((bloknum - cblktax[cblknum].bloknum) > 2) { /* If more than one extra-diagonal blocks exist */ ctrbtax[cblknum] = ctrbtax[bloktax[cblktax[cblknum].bloknum + 1].cblknum]; /* Link contributing column blocks */ ctrbtax[bloktax[cblktax[cblknum].bloknum + 1].cblknum] = cblknum; } } cblktax[cblknum].fcolnum = /* Set last column block data */ cblktax[cblknum].lcolnum = vertnbr + baseval; cblktax[cblknum].bloknum = bloknum; memFree (ctrbtax + baseval); /* Free contribution link array */ symbptr->baseval = baseval; /* Fill in matrix fields */ symbptr->cblknbr = ordeptr->cblknbr; symbptr->bloknbr = bloknum - baseval; symbptr->cblktab = cblktax + baseval; symbptr->bloktab = memRealloc (bloktax + baseval, (bloknum - baseval) * sizeof (SymbolBlok)); /* Set array to its exact size */ symbptr->nodenbr = vertnbr; #ifdef FAX_DEBUG if (symbolCheck (symbptr) != 0) { errorPrint ("symbolFax: internal error (2)"); symbolExit (symbptr); return (1); } #endif /* FAX_DEBUG */ return (0); } scotch-6.0.4.dfsg/src/esmumps/graph.h0000644002563400244210000001000112056406465022623 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : graph.h **/ /** **/ /** AUTHORS : David GOUDIN **/ /** Pascal HENON **/ /** Francois PELLEGRINI **/ /** Pierre RAMET **/ /** **/ /** FUNCTION : Part of a parallel direct block solver. **/ /** These lines are the data declarations **/ /** for the graph structure. **/ /** **/ /** DATES : # Version 0.0 : from : 27 jul 1998 **/ /** to 24 jan 2004 **/ /** # Version 2.0 : from : 28 feb 2004 **/ /** to 23 apr 2004 **/ /** **/ /************************************************************/ #define GRAPH_H /* ** The defines. */ #define Graph SCOTCH_Graph #define graphInit SCOTCH_graphInit #define graphExit SCOTCH_graphExit #define graphLoad SCOTCH_graphLoad #define graphSave SCOTCH_graphSave #define graphBase SCOTCH_graphBase #define graphData SCOTCH_graphData #define graphCheck SCOTCH_graphCheck /* ** The function prototypes. */ #ifndef GRAPH #define static #endif int graphBuild (Graph * const grafptr, const INT baseval, const INT vertnbr, const INT edgenbr, void * const ngbdptr, INT nghbfrstfunc (void * const, const INT), INT nghbnextfunc (void * const)); int graphBuildGraph (Graph * const grafptr, const INT baseval, const INT vertnbr, const INT edgenbr, INT * restrict verttab, INT * restrict velotab, INT * restrict edgetab); int graphBuildGraph2 (Graph * const grafptr, const INT baseval, const INT vertnbr, const INT edgenbr, INT * restrict verttab, INT * restrict vendtab, INT * restrict velotab, INT * restrict vlbltab, INT * restrict edgetab, INT * restrict edlotab); #undef static scotch-6.0.4.dfsg/src/esmumps/order_scotch_graph.c0000644002563400244210000002061112056411513025352 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : order_scotch_graph.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a parallel direct block solver. **/ /** This is the interface module with the **/ /** libSCOTCH matrix ordering library. **/ /** **/ /** DATES : # Version 0.0 : from : 20 aug 1998 **/ /** to 18 may 1999 **/ /** # Version 1.0 : from : 18 mar 2003 **/ /** to 21 jan 2004 **/ /** # Version 2.0 : from : 28 feb 2004 **/ /** to 04 jan 2005 **/ /** # Version 2.1 : from : 21 jun 2007 **/ /** to 21 jun 2007 **/ /** # Version 5.0 : from : 08 feb 2008 **/ /** to 01 jun 2008 **/ /** # Version 5.1 : from : 22 jan 2009 **/ /** to 02 jul 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define ORDER_GRAPH #include "common.h" #ifdef SCOTCH_PTSCOTCH #include "ptscotch.h" #else /* SCOTCH_PTSCOTCH */ #include "scotch.h" #endif /* SCOTCH_PTSCOTCH */ #include "graph.h" #include "order.h" /****************************/ /* */ /* Graph ordering routines. */ /* */ /****************************/ /*+ This routine orders the given *** graph using the Emilio default *** ordering strategy. *** It returns: *** - 0 : if ordering succeeded. *** - !0 : on error. +*/ int orderGraph ( Order * restrict const ordeptr, /*+ Ordering to compute +*/ Graph * restrict const grafptr) /*+ Graph matrix to order +*/ { INT vertnbr; SCOTCH_graphSize (grafptr, &vertnbr, NULL); return (orderGraphList (ordeptr, grafptr, vertnbr, NULL)); } /*+ This routine orders the subgraph of *** the given graph induced by the given *** vertex list, using the Emilio default *** ordering strategy. *** It returns: *** - 0 : if ordering succeeded. *** - !0 : on error. +*/ int orderGraphList ( Order * restrict const ordeptr, /*+ Ordering to compute +*/ Graph * restrict const grafptr, /*+ Graph matrix to order +*/ const INT listnbr, /*+ Number of vertices in list +*/ const INT * restrict const listtab) /*+ Vertex list array +*/ { return (orderGraphListStrat (ordeptr, grafptr, listnbr, listtab, "c{rat=0.7,cpr=n{sep=/(vert>120)?m{type=h,rat=0.7,vert=100,low=h{pass=10},asc=b{width=3,bnd=f{bal=0.2},org=(|h{pass=10})f{bal=0.2}}}|m{type=h,rat=0.7,vert=100,low=h{pass=10},asc=b{width=3,bnd=f{bal=0.2},org=(|h{pass=10})f{bal=0.2}}};,ole=f{cmin=0,cmax=100000,frat=0.0},ose=g},unc=n{sep=/(vert>120)?m{type=h,rat=0.7,vert=100,low=h{pass=10},asc=b{width=3,bnd=f{bal=0.2},org=(|h{pass=10})f{bal=0.2}}}|m{type=h,rat=0.7,vert=100,low=h{pass=10},asc=b{width=3,bnd=f{bal=0.2},org=(|h{pass=10})f{bal=0.2}}};,ole=f{cmin=15,cmax=100000,frat=0.0},ose=g}}")); } /*+ This routine orders the given *** graph using the given ordering *** strategy. *** It returns: *** - 0 : if ordering succeeded. *** - !0 : on error. +*/ int orderGraphStrat ( Order * restrict const ordeptr, /*+ Ordering to compute +*/ Graph * restrict const grafptr, /*+ Graph matrix to order +*/ const char * restrict const stratptr) /*+ Ordering strategy +*/ { INT vertnbr; SCOTCH_graphSize (grafptr, &vertnbr, NULL); return (orderGraphListStrat (ordeptr, grafptr, vertnbr, NULL, stratptr)); } /*+ This routine orders the subgraph of *** the given graph induced by the given *** vertex list, using the given ordering *** strategy. *** It returns: *** - 0 : if ordering succeeded. *** - !0 : on error. +*/ int orderGraphListStrat ( Order * restrict const ordeptr, /*+ Ordering to compute +*/ Graph * restrict const grafptr, /*+ Graph matrix to order +*/ const INT listnbr, /*+ Number of vertices in list +*/ const INT * restrict const listtab, /*+ Vertex list array +*/ const char * restrict const stratptr) /*+ Ordering strategy +*/ { SCOTCH_Strat scotstrat; /* Scotch ordering strategy */ INT baseval; INT vertnbr; INT edgenbr; int o; if (sizeof (INT) != sizeof (SCOTCH_Num)) { /* Check integer consistency */ errorPrint ("orderGraphListStrat: inconsistent integer types"); return (1); } SCOTCH_graphData (grafptr, &baseval, &vertnbr, NULL, NULL, NULL, NULL, &edgenbr, NULL, NULL); if (((ordeptr->permtab = (INT *) memAlloc ( vertnbr * sizeof (INT))) == NULL) || ((ordeptr->peritab = (INT *) memAlloc ( vertnbr * sizeof (INT))) == NULL) || ((ordeptr->rangtab = (INT *) memAlloc ((vertnbr + 1) * sizeof (INT))) == NULL)) { errorPrint ("orderGraphListStrat: out of memory"); orderExit (ordeptr); orderInit (ordeptr); return (1); } SCOTCH_stratInit (&scotstrat); /* Initialize default ordering strategy */ o = SCOTCH_stratGraphOrder (&scotstrat, stratptr); if (o == 0) o = SCOTCH_graphOrderList (grafptr, /* Compute graph ordering */ (SCOTCH_Num) listnbr, (SCOTCH_Num *) listtab, &scotstrat, (SCOTCH_Num *) ordeptr->permtab, (SCOTCH_Num *) ordeptr->peritab, (SCOTCH_Num *) &ordeptr->cblknbr, (SCOTCH_Num *) ordeptr->rangtab, NULL); SCOTCH_stratExit (&scotstrat); if (o != 0) { /* If something failed in Scotch */ orderExit (ordeptr); /* Free ordering arrays */ orderInit (ordeptr); return (1); } #ifdef ORDER_DEBUG if ((ordeptr->rangtab[0] != baseval) || (ordeptr->rangtab[ordeptr->cblknbr] != baseval + vertnbr) || (orderCheck (ordeptr) != 0)) { errorPrint ("orderGraphListStrat: invalid ordering"); } #endif /* ORDER_DEBUG */ ordeptr->rangtab = (INT *) memRealloc (ordeptr->rangtab, (ordeptr->cblknbr + 1) * sizeof (INT)); return (0); } scotch-6.0.4.dfsg/src/esmumps/fax.h0000644002563400244210000001463112056406465022315 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : fax.h **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** Jean ROMAN (v0.0) **/ /** **/ /** FUNCTION : Part of a parallel direct block solver. **/ /** These lines are the data declarations **/ /** for the symbolic factorization routine. **/ /** **/ /** DATES : # Version 0.0 : from : 22 jul 1998 **/ /** to 24 sep 1998 **/ /** # Version 0.1 : from : 04 apr 1999 **/ /** to 01 may 1999 **/ /** # Version 1.0 : from : 01 jun 2002 **/ /** to 25 jun 2002 **/ /** # Version 1.1 : from : 26 jun 2002 **/ /** to 25 sep 2002 **/ /** # Version 1.3 : from : 17 jun 2003 **/ /** to 17 jul 2003 **/ /** # Version 2.0 : from : 21 mar 2003 **/ /** to 29 oct 2003 **/ /** # Version 2.0 : from : 03 mar 2004 **/ /** to 03 mar 2004 **/ /** # Version 3.0 : from : 23 nov 2004 **/ /** to 03 mar 2005 **/ /** **/ /************************************************************/ #define FAX_H /* ** The function prototypes. */ #ifndef FAX #define static #endif int symbolCompact (SymbolMatrix * const symbptr); int symbolFax (SymbolMatrix * const symbptr, const INT vertnbr, const INT edgenbr, const INT baseval, void * const ngbdptr, INT ngbfrst (void * const, const INT), INT ngbnext (void * const), INT ngbdegr (void * const, const INT), const Order * const ordeptr); #ifdef GRAPH_H int symbolFaxGraph (SymbolMatrix * const symbptr, const Graph * const grafptr, const Order * const ordeptr); #endif /* GRAPH_H */ int symbolFaxGrid2C (SymbolMatrix * const symbptr, const INT xnbr, const INT ynbr, const INT baseval, const Order * const ordeptr); int symbolFaxGrid2D (SymbolMatrix * const symbptr, const INT xnbr, const INT ynbr, const INT baseval, const Order * const ordeptr); int symbolFaxGrid2E (SymbolMatrix * const symbptr, const INT xnbr, const INT ynbr, const INT baseval, const Order * const ordeptr); int symbolFaxGrid3C (SymbolMatrix * const symbptr, const INT xnbr, const INT ynbr, const INT znbr, const INT baseval, const Order * const ordeptr); int symbolFaxGrid3D (SymbolMatrix * const symbptr, const INT xnbr, const INT ynbr, const INT znbr, const INT baseval, const Order * const ordeptr); int symbolFaxGrid3E (SymbolMatrix * const symbptr, const INT xnbr, const INT ynbr, const INT znbr, const INT baseval, const Order * const ordeptr); #ifdef MESH_H int symbolFaxMesh (SymbolMatrix * const symbptr, const Mesh * const meshptr, const Order * const ordeptr); #endif /* MESH_H */ int symbolFaxi (SymbolMatrix * const symbptr, const INT vertnbr, const INT edgenbr, const INT baseval, void * const ngbdptr, INT ngbfrst (void * const, const INT), INT ngbnext (void * const), INT ngbdegr (void * const, const INT), const Order * const ordeptr, const INT levfmax); #ifdef GRAPH_H int symbolFaxiGraph (SymbolMatrix * const symbptr, const Graph * const grafptr, const Order * const ordeptr, const INT levfmax); #endif /* GRAPH_H */ int symbolFaxiGrid2D (SymbolMatrix * const symbptr, const INT xnbr, const INT ynbr, const INT baseval, const Order * const ordeptr, const INT levfmax); int symbolFaxiGrid2E (SymbolMatrix * const symbptr, const INT xnbr, const INT ynbr, const INT baseval, const Order * const ordeptr, const INT levfmax); int symbolFaxiGrid3D (SymbolMatrix * const symbptr, const INT xnbr, const INT ynbr, const INT znbr, const INT baseval, const Order * const ordeptr, const INT levfmax); int symbolFaxiGrid3E (SymbolMatrix * const symbptr, const INT xnbr, const INT ynbr, const INT znbr, const INT baseval, const Order * const ordeptr, const INT levfmax); #undef static scotch-6.0.4.dfsg/src/esmumps/dof.c0000644002563400244210000001571712056406465022310 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2009 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dof.c **/ /** **/ /** AUTHORS : David GOUDIN **/ /** Pascal HENON **/ /** Francois PELLEGRINI **/ /** Pierre RAMET **/ /** **/ /** FUNCTION : Part of a parallel direct block solver. **/ /** These lines are the general purpose **/ /** routines for the DOF structure. **/ /** **/ /** DATES : # Version 0.0 : from : 07 oct 1998 **/ /** to 14 oct 1998 **/ /** # Version 3.0 : from : 28 feb 2004 **/ /** to 03 feb 2006 **/ /** # Version 5.1 : from : 22 jan 2009 **/ /** to 22 jan 2009 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DOF #include "common.h" #ifdef SCOTCH_PTSCOTCH #include "ptscotch.h" #else /* SCOTCH_PTSCOTCH */ #include "scotch.h" #endif /* SCOTCH_PTSCOTCH */ #include "graph.h" #include "dof.h" /******************************/ /* */ /* The DOF handling routines. */ /* */ /******************************/ /*+ This routine initializes *** the given DOF structure. *** It returns: *** - 0 : in all cases. +*/ int dofInit ( Dof * const deofptr) { deofptr->baseval = 0; deofptr->nodenbr = 0; deofptr->noddval = 1; /* Set constant, non zero, number of DOFs */ deofptr->noddtab = NULL; return (0); } /*+ This routine frees the contents *** of the given DOF structure. *** It returns: *** - VOID : in all cases. +*/ void dofExit ( Dof * const deofptr) { if (deofptr->noddtab != NULL) memFree (deofptr->noddtab); #ifdef DOF_DEBUG dofInit (deofptr); #endif /* DOF_DEBUG */ } /*+ This routine sets the number of DOFs *** per node to a constant value. *** It returns: *** - VOID : in all cases. +*/ void dofConstant ( Dof * const deofptr, const INT baseval, const INT nodenbr, const INT noddval) { deofptr->baseval = baseval; deofptr->nodenbr = nodenbr; if (deofptr->noddtab != NULL) { /* If DOF array already allocated */ memFree (deofptr->noddtab); /* It is no longer of use */ deofptr->noddtab = NULL; } deofptr->noddval = noddval; } /*+ This routine builds the DOF index *** array from the graph vertex array. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int dofGraph ( Dof * const deofptr, /*+ DOF index array to build [based] +*/ const Graph * const grafptr, /*+ Matrix adjacency structure [based] +*/ const INT deofval, /*+ DOFs per node if no graph vertex load array +*/ const INT * const peritab) /*+ Inverse vertex->node permutation array +*/ { INT baseval; INT vertnbr; INT * velotab; INT edgenbr; SCOTCH_graphData (grafptr, &baseval, &vertnbr, NULL, NULL, &velotab, NULL, &edgenbr, NULL, NULL); deofptr->baseval = baseval; deofptr->nodenbr = vertnbr; if (velotab == NULL) { /* If no vertex weight (i.e. DOF) array */ deofptr->noddtab = NULL; /* No DOF array */ deofptr->noddval = deofval; /* Get node DOF value */ } else { /* Vertex load array present */ #ifdef DOF_CONSTANT deofptr->noddtab = NULL; /* No DOF array */ deofptr->noddval = deofval; #else /* DOF_CONSTANT */ const INT * restrict velotax; /* Based access to grafptr->velotab */ INT nodenum; /* Number of current node */ INT * noddtnd; /* Pointer to end of DOF index array */ INT * noddptr; /* Pointer to current DOF index */ const INT * periptr; deofptr->noddval = 0; /* DOF values are not constant */ if ((deofptr->noddtab = (INT *) memAlloc ((vertnbr + 1) * sizeof (INT))) == NULL) { errorPrint ("dofGraph: out of memory"); return (1); } for (noddptr = deofptr->noddtab, noddtnd = noddptr + vertnbr, periptr = peritab, nodenum = baseval, velotax = velotab - baseval; noddptr < noddtnd; noddptr ++, periptr ++) { *noddptr = nodenum; /* Set index to DOF array */ nodenum += velotax[*periptr]; /* Add number of DOFs for vertex */ } *noddptr = nodenum; /* Set end of DOF array */ #endif /* DOF_CONSTANT */ } return (0); } scotch-6.0.4.dfsg/src/libscotch/0000755002563400244210000000000012500613573021634 5ustar trophimeutilisateurs du domainescotch-6.0.4.dfsg/src/libscotch/library_order.h0000644002563400244210000000656511631447171024663 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_order.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the library ordering **/ /** structure. **/ /** **/ /** DATES : # Version 3.3 : from : 08 oct 1998 **/ /** to : 08 oct 1998 **/ /** # Version 4.0 : from : 11 dec 2001 **/ /** to 25 dec 2004 **/ /** # Version 5.1 : from : 04 nov 2010 **/ /** to 04 nov 2010 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ Ordering. +*/ typedef struct LibOrder_ { Order o; /*+ Ordering data +*/ Gnum * permtab; /*+ Direct permutation array +*/ Gnum * peritab; /*+ Inverse permutation array +*/ Gnum * cblkptr; /*+ Pointer to number of column blocks +*/ Gnum * rangtab; /*+ Column block range array +*/ Gnum * treetab; /*+ Separator tree array +*/ } LibOrder; scotch-6.0.4.dfsg/src/libscotch/hdgraph.c0000644002563400244210000000700711631447170023423 0ustar trophimeutilisateurs du domaine/* Copyright 2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hdgraph.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the distributed graph general **/ /** purpose routines. **/ /** **/ /** DATES : # Version 5.0 : from : 21 apr 2006 **/ /** to : 21 apr 2006 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HDGRAPH #include "module.h" #include "common.h" #include "dgraph.h" #include "hdgraph.h" /******************************/ /* */ /* These routines handle halo */ /* distributed source graphs. */ /* */ /******************************/ /* This routine destroys a distributed halo graph ** structure. It is not a collective routine, as no ** communication is needed to perform the freeing of ** memory structures. ** It returns: ** - 0 : on success. ** - !0 : on error. */ void hdgraphExit ( Hdgraph * restrict const grafptr) { if ((grafptr->vhndloctax != grafptr->s.vertloctax + 1) && /* If graph has a halo, with a separate end vertex array */ ((grafptr->s.flagval & HDGRAPHFREEVHND) != 0)) memFree (grafptr->vhndloctax); dgraphExit (&grafptr->s); /* Free distributed graph data (flagval may be corrupted afterwards) */ #ifdef SCOTCH_DEBUG_HDGRAPH1 memSet (grafptr, 0, sizeof (Hdgraph)); #endif /* SCOTCH_DEBUG_HDGRAPH1 */ } scotch-6.0.4.dfsg/src/libscotch/kgraph_map_ml.c0000644002563400244210000004553712474554132024624 0ustar trophimeutilisateurs du domaine/* Copyright 2010,2011,2012,2014,2015 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph_map_ml.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module maps an active graph **/ /** to a specific architecture graph **/ /** using a multi-level scheme. **/ /** **/ /** DATES : # Version 5.1 : from : 13 jul 2010 **/ /** to 14 jul 2010 **/ /** DATES : # Version 6.0 : from : 03 mar 2011 **/ /** to 27 feb 2015 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define KGRAPH_MAP_ML #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "arch.h" #include "mapping.h" #include "graph_coarsen.h" #include "kgraph.h" #include "kgraph_map_ml.h" #include "kgraph_map_st.h" /*********************************************/ /* */ /* The coarsening and uncoarsening routines. */ /* */ /*********************************************/ /* This routine builds a coarser graph from the ** graph that is given on input. The coarser ** graphs differ at this stage from classical ** active graphs as their internal gains are not ** yet computed. ** It returns: ** - 0 : if the coarse graph has been built. ** - 1 : if threshold reached or on error. */ static int kgraphMapMlCoarsen ( Kgraph * restrict const finegrafptr, /*+ Finer graph +*/ Kgraph * restrict const coargrafptr, /*+ Coarser graph to build +*/ GraphCoarsenMulti * restrict * const coarmultptr, /*+ Pointer to un-based multinode table to build +*/ const KgraphMapMlParam * const paraptr) /*+ Method parameters +*/ { GraphCoarsenMulti * restrict coarmulttab; Gnum coarvertnum; /* Number of current multinode vertex */ Gnum coarflagval; const Anum * restrict const finepfixtax = finegrafptr->pfixtax; #ifdef SCOTCH_DEBUG_KGRAPH2 if ((finegrafptr->comploadavg == NULL) || (finegrafptr->comploaddlt == NULL)) { errorPrint ("kgraphMapMlCoarsen: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ *coarmultptr = NULL; /* Allocate coarmulttab along with coarse graph */ if (graphCoarsen (&finegrafptr->s, &coargrafptr->s, coarmultptr, paraptr->coarnbr, paraptr->coarval, finegrafptr->r.m.parttax, finegrafptr->pfixtax, finegrafptr->vfixnbr, &coargrafptr->vfixnbr) != 0) return (1); /* Return if coarsening failed */ finegrafptr->s.flagval &= ~KGRAPHFREECOMP; /* Now it's the coarse graph job to handle the load array */ coargrafptr->s.flagval = (coargrafptr->s.flagval & ~KGRAPHFREEFRON) | KGRAPHFREECOMP; /* Share frontier array */ coargrafptr->comploadavg = finegrafptr->comploadavg; /* By default, use fine target load arrays as coarse load arrays */ coargrafptr->comploaddlt = finegrafptr->comploaddlt; coargrafptr->frontab = finegrafptr->frontab; /* Share frontier array of finer graph as coarse frontier array */ coargrafptr->a = finegrafptr->a; coargrafptr->m.parttax = NULL; /* Do not allocate partition data yet */ coargrafptr->m.domntab = finegrafptr->m.domntab; /* Get domain private array if any */ coargrafptr->m.archptr = &coargrafptr->a; coargrafptr->m.grafptr = &coargrafptr->s; coargrafptr->m.flagval = finegrafptr->m.flagval & MAPPINGFREEDOMN; /* Get fine private domain array, if any */ finegrafptr->m.flagval &= ~MAPPINGFREEDOMN; /* Now it's the coarse graph job to handle the domain array, if any */ coargrafptr->m.domnorg = finegrafptr->m.domnorg; coargrafptr->m.domnnbr = 0; /* Number of domains not known yet */ coargrafptr->m.domnmax = finegrafptr->m.domnmax; /* Propagate relevant estimation */ coarmulttab = *coarmultptr; if (finegrafptr->r.m.parttax != NULL) { const Gnum * restrict fineparotax; const Gnum * restrict finevmlotax; Gnum * coarparotab; Gnum * coarvmlotab; Gnum coarvertnbr; coarvertnbr = coargrafptr->s.vertnbr; if ((coarparotab = (Anum *) memAlloc (coarvertnbr * sizeof (Anum))) == NULL) { errorPrint ("kgraphMapMlCoarsen: out of memory (1)"); return (1); } if ((coarvmlotab = (Gnum *) memAlloc (coarvertnbr * sizeof (Gnum))) == NULL) { errorPrint ("kgraphMapMlCoarsen: out of memory (2)"); memFree (coarparotab); return (1); } fineparotax = finegrafptr->r.m.parttax; finevmlotax = finegrafptr->r.vmlotax; for (coarvertnum = 0; coarvertnum < coarvertnbr; coarvertnum ++) { Gnum finevertnum0; Gnum finevertnum1; finevertnum0 = coarmulttab[coarvertnum].vertnum[0]; finevertnum1 = coarmulttab[coarvertnum].vertnum[1]; coarparotab[coarvertnum] = fineparotax[finevertnum0]; coarvmlotab[coarvertnum] = (finevmlotax != NULL) ? ((finevertnum0 == finevertnum1) ? 0 : finevmlotax[finevertnum1]) + finevmlotax[finevertnum0] : ((finevertnum0 == finevertnum1) ? 1 : 2); #ifdef SCOTCH_DEBUG_KGRAPH2 if ((fineparotax[finevertnum1] != fineparotax[finevertnum0]) && /* If vertices were not in the same part */ ((finegrafptr->pfixtax == NULL) || ((finepfixtax[finevertnum1] == -1) && /* And both are not fixed */ (finepfixtax[finevertnum0] == -1)))) { errorPrint ("kgraphMapMlCoarsen: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ } coargrafptr->r.m.flagval = MAPPINGFREEPART; coargrafptr->r.m.grafptr = &coargrafptr->s; coargrafptr->r.m.archptr = finegrafptr->r.m.archptr; coargrafptr->r.m.parttax = coarparotab - coargrafptr->s.baseval; /* Set coarse arrays */ coargrafptr->r.m.domntab = finegrafptr->r.m.domntab; /* Clone old domain array */ coargrafptr->r.m.domnnbr = finegrafptr->r.m.domnnbr; coargrafptr->r.m.domnmax = finegrafptr->r.m.domnmax; coargrafptr->r.vmlotax = coarvmlotab - coargrafptr->s.baseval; coargrafptr->s.flagval |= KGRAPHFREEVMLO; } else { /* No old mapping */ coargrafptr->r.m.flagval = MAPPINGNONE; coargrafptr->r.m.parttax = NULL; coargrafptr->r.vmlotax = NULL; } if (finepfixtax != NULL) { /* If we have fixed vertices */ Gnum coarvertnbr; Anum * restrict coarpfixtab; Gnum coarvfixnbr; coarvertnbr = coargrafptr->s.vertnbr; if ((coarpfixtab = (Anum *) memAlloc (coarvertnbr * sizeof (Anum))) == NULL) { errorPrint ("kgraphMapMlCoarsen: out of memory (3)"); return (1); } coarvfixnbr = coarvertnbr; /* Assume all vertices are fixed */ for (coarvertnum = 0; coarvertnum < coarvertnbr; coarvertnum ++) { Anum coarpfixval; coarpfixval = finepfixtax[coarmulttab[coarvertnum].vertnum[0]]; coarvfixnbr += coarpfixval >> (sizeof (Anum) * 8 - 1); /* Accumulate -1's, that is, non-fixed vertices */ coarpfixtab[coarvertnum] = coarpfixval; #ifdef SCOTCH_DEBUG_KGRAPH2 if (finepfixtax[coarmulttab[coarvertnum].vertnum[1]] != coarpfixval) { errorPrint ("kgraphMapMlCoarsen: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ } coargrafptr->s.flagval |= KGRAPHFREEPFIX; coargrafptr->pfixtax = coarpfixtab - coargrafptr->s.baseval; coargrafptr->vfixnbr = coarvfixnbr; } else { coargrafptr->pfixtax = NULL; coargrafptr->vfixnbr = 0; } coargrafptr->comploadrat = finegrafptr->comploadrat; coargrafptr->r.cmloval = finegrafptr->r.cmloval; coargrafptr->r.crloval = finegrafptr->r.crloval; coargrafptr->kbalval = finegrafptr->kbalval; coargrafptr->levlnum = finegrafptr->levlnum + 1; return (0); } /* This routine propagates the partitioning of the ** coarser graph back to the finer graph, according ** to the multinode table of collapsed vertices. ** After the partitioning is propagated, it finishes ** to compute the parameters of the finer graph that ** were not computed at the coarsening stage. ** It returns: ** - 0 : if coarse graph data has been propagated to fine graph. ** - !0 : on error. */ static int kgraphMapMlUncoarsen ( Kgraph * restrict const finegrafptr, /*+ Finer graph +*/ Kgraph * restrict const coargrafptr, /*+ Coarser graph +*/ const GraphCoarsenMulti * const coarmulttab) /*+ Pointer to multinode array +*/ { const Anum * restrict coarparttax; /* Only known when coagrafptr is not NULL */ Gnum coarvertnnd; Gnum coarvertnum; Gnum * restrict coarfrontab; /* Coarse and fine frontiers arrays are merged */ Gnum coarfronnbr; Gnum coarfronnum; Gnum finefronnum; Anum * restrict fineparttax; /* May not have been allocated yet */ const GraphCoarsenMulti * const coarmulttax = coarmulttab - finegrafptr->s.baseval; const Gnum * restrict const fineverttax = finegrafptr->s.verttax; /* Fast accesses */ const Gnum * restrict const finevendtax = finegrafptr->s.vendtax; const Gnum * restrict const fineedgetax = finegrafptr->s.edgetax; if (coargrafptr == NULL) { /* If no coarse graph provided */ if (mapAlloc (&finegrafptr->m) != 0) { /* Allocate partition array if needed */ errorPrint ("kdgraphMapMlUncoarsen: cannot allocate mapping (1)"); return (1); } kgraphFrst (finegrafptr); /* Assign all vertices to first subdomain */ return (0); } #ifdef SCOTCH_DEBUG_KGRAPH2 if (((finegrafptr->m.flagval & MAPPINGFREEDOMN) != 0) && /* Fine graph should not have a private domain array because of coarsening */ (finegrafptr->m.domntab != NULL)) { errorPrint ("kdgraphMapMlUncoarsen: internal error"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ finegrafptr->m.domnnbr = coargrafptr->m.domnnbr; /* Propagate coarse domain array */ finegrafptr->m.domnmax = coargrafptr->m.domnmax; finegrafptr->m.domntab = coargrafptr->m.domntab; finegrafptr->m.flagval |= MAPPINGFREEDOMN; coargrafptr->m.domntab = NULL; /* No need to free coarse graph domain array as it has been transferred */ if (mapAlloc (&finegrafptr->m) != 0) { /* Allocate partition array if needed */ errorPrint ("kdgraphMapMlUncoarsen: cannot allocate mapping (2)"); return (1); } finegrafptr->s.flagval |= KGRAPHFREECOMP; finegrafptr->comploadavg = coargrafptr->comploadavg; /* Propagate part load data in case it was changed at the coarser levels */ finegrafptr->comploaddlt = coargrafptr->comploaddlt; coargrafptr->comploadavg = NULL; /* No need to free coarse graph load array as it has been transferred */ fineparttax = finegrafptr->m.parttax; /* Fine part array is now allocated */ coarparttax = coargrafptr->m.parttax; coarfrontab = coargrafptr->frontab; for (coarvertnum = coargrafptr->s.baseval, coarvertnnd = coargrafptr->s.vertnnd; coarvertnum < coarvertnnd; coarvertnum ++) { Gnum finevertnum0; /* First multinode vertex */ Gnum finevertnum1; /* Second multinode vertex */ Anum partval; finevertnum0 = coarmulttax[coarvertnum].vertnum[0]; finevertnum1 = coarmulttax[coarvertnum].vertnum[1]; partval = coarparttax[coarvertnum]; fineparttax[finevertnum0] = partval; if (finevertnum0 != finevertnum1) fineparttax[finevertnum1] = partval; } finegrafptr->commload = coargrafptr->commload; for (coarfronnum = 0, finefronnum = coarfronnbr = coargrafptr->fronnbr; /* Re-cycle frontier array from coarse to fine graph */ coarfronnum < coarfronnbr; coarfronnum ++) { Gnum coarvertnum; Gnum finevertnum0; /* First multinode vertex */ Gnum finevertnum1; /* Second multinode vertex */ coarvertnum = coarfrontab[coarfronnum]; finevertnum0 = coarmulttax[coarvertnum].vertnum[0]; finevertnum1 = coarmulttax[coarvertnum].vertnum[1]; if (finevertnum0 != finevertnum1) { /* If multinode si made of two distinct vertices */ Gnum fineedgenum; Gnum partval; partval = coarparttax[coarvertnum]; #ifdef SCOTCH_DEBUG_KGRAPH2 coarfrontab[coarfronnum] = ~0; #endif /* SCOTCH_DEBUG_KGRAPH2 */ for (fineedgenum = fineverttax[finevertnum0]; fineedgenum < finevendtax[finevertnum0]; fineedgenum ++) { if (fineparttax[fineedgetax[fineedgenum]] != partval) { /* If first vertex belongs to frontier */ coarfrontab[coarfronnum] = finevertnum0; /* Record it in lieu of the coarse frontier vertex */ break; } } if (fineedgenum >= finegrafptr->s.vendtax[finevertnum0]) { /* If first vertex not in frontier */ coarfrontab[coarfronnum] = finevertnum1; /* Then second vertex must be in frontier */ continue; /* Skip to next multinode */ } for (fineedgenum = fineverttax[finevertnum1]; /* Check if second vertex also belongs to frontier */ fineedgenum < finevendtax[finevertnum1]; fineedgenum ++) { if (fineparttax[fineedgetax[fineedgenum]] != partval) { /* If second vertex belongs to frontier */ coarfrontab[finefronnum ++] = finevertnum1; /* Record it at the end of the recycled frontier array */ break; } } #ifdef SCOTCH_DEBUG_KGRAPH2 if (coarfrontab[coarfronnum] == ~0) { errorPrint ("kgraphMapMlUncoarsen: internal error"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ } else /* If coarse vertex is single node */ coarfrontab[coarfronnum] = finevertnum0; /* Then it belongs to the frontier */ } finegrafptr->fronnbr = finefronnum; #ifdef SCOTCH_DEBUG_KGRAPH2 if (kgraphCheck (finegrafptr) != 0) { errorPrint ("kgraphMapMlUncoarsen: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ return (0); } /* This routine performs the ** partitioning recursion. ** It returns: ** - 0 : if partitioning could be computed. ** - 1 : on error. */ static int kgraphMapMl2 ( Kgraph * restrict const grafptr, /*+ Active graph +*/ const KgraphMapMlParam * const paraptr) /*+ Method parameters +*/ { Kgraph coargrafdat; GraphCoarsenMulti * coarmulttab; /* Pointer to un-based multinode array */ int o; if (kgraphMapMlCoarsen (grafptr, &coargrafdat, &coarmulttab, paraptr) == 0) { if (((o = kgraphMapMl2 (&coargrafdat, paraptr)) == 0) && ((o = kgraphMapMlUncoarsen (grafptr, &coargrafdat, coarmulttab)) == 0) && ((o = kgraphMapSt (grafptr, paraptr->stratasc)) != 0)) /* Apply ascending strategy */ errorPrint ("kgraphMapMl2: cannot apply ascending strategy"); kgraphExit (&coargrafdat); } else { /* Cannot coarsen due to lack of memory or error */ if (((o = kgraphMapMlUncoarsen (grafptr, NULL, NULL)) == 0) && /* Finalize graph */ ((o = kgraphMapSt (grafptr, paraptr->stratlow)) != 0)) /* Apply low strategy */ errorPrint ("kgraphMapMl2: cannot apply low strategy"); } return (o); } /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the multi-level mapping. ** It returns: ** - 0 : if mapping could be computed. ** - 1 : on error. */ int kgraphMapMl ( Kgraph * const grafptr, /*+ Active graph +*/ const KgraphMapMlParam * const paraptr) /*+ Method parameters +*/ { Gnum levlnum; /* Save value for graph level */ int o; levlnum = grafptr->levlnum; /* Save graph level */ grafptr->levlnum = 0; /* Initialize coarsening level */ o = kgraphMapMl2 (grafptr, paraptr); /* Perform multi-level mapping */ grafptr->levlnum = levlnum; /* Restore graph level */ return (o); } scotch-6.0.4.dfsg/src/libscotch/vmesh_separate_st.c0000644002563400244210000003267511631447171025534 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vmesh_separate_st.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the global mesh **/ /** separation strategy and method tables. **/ /** **/ /** DATES : # Version 4.0 : from : 20 sep 2002 **/ /** to 08 feb 2003 **/ /** # Version 5.0 : from : 04 aug 2007 **/ /** to 04 aug 2007 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VMESH_SEPARATE_ST #include "module.h" #include "common.h" #include "gain.h" #include "parser.h" #include "graph.h" #include "vgraph.h" #include "vgraph_separate_st.h" #include "mesh.h" #include "mesh_coarsen.h" #include "vmesh.h" #include "vmesh_separate_fm.h" #include "vmesh_separate_gg.h" #include "vmesh_separate_gr.h" #include "vmesh_separate_ml.h" #include "vmesh_separate_zr.h" #include "vmesh_separate_st.h" /* ** The static and global variables. */ static Vmesh vmeshdummy; /* Dummy separator mesh for offset computations */ static union { VmeshSeparateFmParam param; StratNodeMethodData padding; } vmeshseparatedefaultfm = { { 200, 1000, 0.1L } }; static union { VmeshSeparateGgParam param; StratNodeMethodData padding; } vmeshseparatedefaultgg = { { 5 } }; static union { VmeshSeparateGrParam param; StratNodeMethodData padding; } vmeshseparatedefaultgr = { { &stratdummy } }; static union { VmeshSeparateMlParam param; StratNodeMethodData padding; } vmeshseparatedefaultml = { { 1000, 0.8L, MESHCOARSENNGB, &stratdummy, &stratdummy } }; static StratMethodTab vmeshseparatestmethtab[] = { /* Mesh separation methods array */ { VMESHSEPASTMETHFM, "f", vmeshSeparateFm, &vmeshseparatedefaultfm }, { VMESHSEPASTMETHGG, "h", vmeshSeparateGg, &vmeshseparatedefaultgg }, #ifdef SCOTCH_DEBUG_VMESH2 { VMESHSEPASTMETHGR, "v", vmeshSeparateGr, &vmeshseparatedefaultgr }, #endif /* SCOTCH_DEBUG_VMESH2 */ { VMESHSEPASTMETHML, "m", vmeshSeparateMl, &vmeshseparatedefaultml }, { VMESHSEPASTMETHZR, "z", vmeshSeparateZr, NULL }, { -1, NULL, NULL, NULL } }; static StratParamTab vmeshseparatestparatab[] = { /* Mesh separation method parameter list */ { VMESHSEPASTMETHFM, STRATPARAMINT, "move", (byte *) &vmeshseparatedefaultfm.param, (byte *) &vmeshseparatedefaultfm.param.movenbr, NULL }, { VMESHSEPASTMETHFM, STRATPARAMINT, "pass", (byte *) &vmeshseparatedefaultfm.param, (byte *) &vmeshseparatedefaultfm.param.passnbr, NULL }, { VMESHSEPASTMETHFM, STRATPARAMDOUBLE, "bal", (byte *) &vmeshseparatedefaultfm.param, (byte *) &vmeshseparatedefaultfm.param.deltrat, NULL }, { VMESHSEPASTMETHGG, STRATPARAMINT, "pass", (byte *) &vmeshseparatedefaultgg.param, (byte *) &vmeshseparatedefaultgg.param.passnbr, NULL }, #ifdef SCOTCH_DEBUG_VMESH2 { VMESHSEPASTMETHGR, STRATPARAMSTRAT, "strat", (byte *) &vmeshseparatedefaultgr.param, (byte *) &vmeshseparatedefaultgr.param.stratptr, (void *) &vgraphseparateststratab }, #endif /* SCOTCH_DEBUG_VMESH2 */ { VMESHSEPASTMETHML, STRATPARAMSTRAT, "asc", (byte *) &vmeshseparatedefaultml.param, (byte *) &vmeshseparatedefaultml.param.stratasc, (void *) &vmeshseparateststratab }, { VMESHSEPASTMETHML, STRATPARAMSTRAT, "low", (byte *) &vmeshseparatedefaultml.param, (byte *) &vmeshseparatedefaultml.param.stratlow, (void *) &vmeshseparateststratab }, { VMESHSEPASTMETHML, STRATPARAMCASE, "type", (byte *) &vmeshseparatedefaultml.param, (byte *) &vmeshseparatedefaultml.param.coartype, (void *) "hsn" }, { VMESHSEPASTMETHML, STRATPARAMINT, "vnod", (byte *) &vmeshseparatedefaultml.param, (byte *) &vmeshseparatedefaultml.param.vnodnbr, NULL }, { VMESHSEPASTMETHML, STRATPARAMDOUBLE, "rat", (byte *) &vmeshseparatedefaultml.param, (byte *) &vmeshseparatedefaultml.param.coarrat, NULL }, { VMESHSEPASTMETHNBR, STRATPARAMINT, NULL, NULL, NULL, NULL } }; static StratParamTab vmeshseparatestcondtab[] = { /* Mesh condition parameter table */ { STRATNODECOND, STRATPARAMINT, "edge", (byte *) &vmeshdummy, (byte *) &vmeshdummy.m.edgenbr, NULL }, { STRATNODECOND, STRATPARAMINT, "levl", (byte *) &vmeshdummy, (byte *) &vmeshdummy.levlnum, NULL }, { STRATNODECOND, STRATPARAMINT, "load", (byte *) &vmeshdummy, (byte *) &vmeshdummy.m.vnlosum, NULL }, { STRATNODECOND, STRATPARAMINT, "velm", (byte *) &vmeshdummy, (byte *) &vmeshdummy.m.velmnbr, NULL }, { STRATNODECOND, STRATPARAMINT, "vnod", (byte *) &vmeshdummy, (byte *) &vmeshdummy.m.vnodnbr, NULL }, { STRATNODENBR, STRATPARAMINT, NULL, NULL, NULL, NULL } }; StratTab vmeshseparateststratab = { /* Strategy tables for mesh separation methods */ vmeshseparatestmethtab, vmeshseparatestparatab, vmeshseparatestcondtab }; /*******************************************/ /* */ /* This is the generic separation routine. */ /* */ /*******************************************/ /* This routine computes the separation of ** the given graph according to the given ** strategy. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int vmeshSeparateSt ( Vmesh * restrict const meshptr, /*+ Separation mesh +*/ const Strat * restrict const strat) /*+ Separation strategy +*/ { StratTest val; VmeshStore save[2]; /* Results of the two strategies */ int o; #ifdef SCOTCH_DEBUG_VMESH2 if (sizeof (Gnum) != sizeof (INT)) { errorPrint ("vmeshSeparateSt: invalid type specification for parser variables"); return (1); } if ((sizeof (VmeshSeparateFmParam) > sizeof (StratNodeMethodData)) || (sizeof (VmeshSeparateGgParam) > sizeof (StratNodeMethodData)) || (sizeof (VmeshSeparateGrParam) > sizeof (StratNodeMethodData)) || (sizeof (VmeshSeparateMlParam) > sizeof (StratNodeMethodData))) { errorPrint ("vmeshSeparateSt: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_VMESH2 */ #ifdef SCOTCH_DEBUG_VMESH1 if (strat->tabl != &vmeshseparateststratab) { errorPrint ("vmeshSeparateSt: invalid parameter (1)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH1 */ o = 0; switch (strat->type) { case STRATNODECONCAT : o = vmeshSeparateSt (meshptr, strat->data.concat.strat[0]); /* Apply first strategy */ if (o == 0) /* If it worked all right */ o |= vmeshSeparateSt (meshptr, strat->data.concat.strat[1]); /* Then apply second strategy */ break; case STRATNODECOND : o = stratTestEval (strat->data.cond.test, &val, (void *) meshptr); /* Evaluate expression */ if (o == 0) { /* If evaluation was correct */ #ifdef SCOTCH_DEBUG_VMESH2 if ((val.typetest != STRATTESTVAL) && (val.typenode != STRATPARAMLOG)) { errorPrint ("vmeshSeparateSt: invalid test result"); o = 1; break; } #endif /* SCOTCH_DEBUG_VMESH2 */ if (val.data.val.vallog == 1) /* If expression is true */ o = vmeshSeparateSt (meshptr, strat->data.cond.strat[0]); /* Apply first strategy */ else { /* Else if expression is false */ if (strat->data.cond.strat[1] != NULL) /* And if there is an else statement */ o = vmeshSeparateSt (meshptr, strat->data.cond.strat[1]); /* Apply second strategy */ } } break; case STRATNODEEMPTY : break; case STRATNODESELECT : if (((vmeshStoreInit (meshptr, &save[0])) != 0) || /* Allocate save areas */ ((vmeshStoreInit (meshptr, &save[1])) != 0)) { errorPrint ("vmeshSeparateSt: out of memory"); vmeshStoreExit (&save[0]); return (1); } vmeshStoreSave (meshptr, &save[1]); /* Save initial bipartition */ vmeshSeparateSt (meshptr, strat->data.select.strat[0]); /* Apply first strategy */ vmeshStoreSave (meshptr, &save[0]); /* Save its result */ vmeshStoreUpdt (meshptr, &save[1]); /* Restore initial bipartition */ vmeshSeparateSt (meshptr, strat->data.select.strat[1]); /* Apply second strategy */ if ( (save[0].fronnbr < meshptr->fronnbr) || /* If first strategy is better */ ((save[0].fronnbr == meshptr->fronnbr) && (abs (save[0].ncmploaddlt) < abs (meshptr->ncmploaddlt)))) vmeshStoreUpdt (meshptr, &save[0]); /* Restore its result */ vmeshStoreExit (&save[0]); /* Free both save areas */ vmeshStoreExit (&save[1]); break; #ifdef SCOTCH_DEBUG_VMESH1 case STRATNODEMETHOD : #else /* SCOTCH_DEBUG_VMESH1 */ default : #endif /* SCOTCH_DEBUG_VMESH1 */ return (strat->tabl->methtab[strat->data.method.meth].func (meshptr, (void *) &strat->data.method.data)); #ifdef SCOTCH_DEBUG_VMESH1 default : errorPrint ("vmeshSeparateSt: invalid parameter (2)"); return (1); #endif /* SCOTCH_DEBUG_VMESH1 */ } return (o); } scotch-6.0.4.dfsg/src/libscotch/vdgraph_separate_zr.h0000644002563400244210000000520111631447170026037 0ustar trophimeutilisateurs du domaine/* Copyright 2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vdgraph_separate_zr.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the move-all-to-first-subdomain **/ /** distributed separation method. **/ /** **/ /** DATES : # Version 5.0 : from : 07 feb 2006 **/ /** to 07 feb 2006 **/ /** **/ /************************************************************/ /* ** The function prototypes. */ #ifndef VDGRAPH_SEPARATE_ZR #define static #endif int vdgraphSeparateZr (Vdgraph * const); #undef static scotch-6.0.4.dfsg/src/libscotch/dgraph_view.c0000644002563400244210000001633311631447170024307 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_view.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the distributed graph general **/ /** purpose routines. **/ /** **/ /** DATES : # Version P0.0 : from : 01 apr 1997 **/ /** to 01 apr 1997 **/ /** # Version P0.1 : from : 12 apr 1998 **/ /** to 20 jun 1998 **/ /** # Version 5.0 : from : 16 feb 2005 **/ /** to : 15 aug 2006 **/ /** # Version 5.1 : from : 11 aug 2010 **/ /** to : 12 aug 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DGRAPH #include "module.h" #include "common.h" #include "dgraph.h" /*************************************/ /* */ /* These routines handle distributed */ /* source graphs. */ /* */ /*************************************/ /* This routine displays the contents ** of the given graph structure. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int dgraphView ( const Dgraph * restrict const grafptr, FILE * const stream) { MPI_Comm proccomm; /* Graph communicator */ int procglbnbr; /* Number of processes sharing graph data */ int proclocnum; /* Number of this process */ int procngbnbr; int procngbnum; Gnum vertlocnum; Gnum edgelocnum; Gnum * edgelocptr; proccomm = grafptr->proccomm; /* Simplify */ MPI_Comm_size (proccomm, &procglbnbr); /* Rely on communicator data */ MPI_Comm_rank (proccomm, &proclocnum); fflush (stream); /* Flush previous data */ for (procngbnbr = 0; procngbnbr < procglbnbr; procngbnbr ++) { MPI_Barrier (proccomm); if (procngbnbr == proclocnum) { fprintf (stream, "Process %d:\n", proclocnum); fprintf (stream, " vertglbnbr: " GNUMSTRING "\n vertgstnbr: " GNUMSTRING "\n vertgstnnd: " GNUMSTRING "\n vertlocnbr: " GNUMSTRING "\n vertlocnnd: " GNUMSTRING "\n", (Gnum) grafptr->vertglbnbr, (Gnum) grafptr->vertgstnbr, (Gnum) grafptr->vertgstnnd, (Gnum) grafptr->vertlocnbr, (Gnum) grafptr->vertlocnnd); fprintf (stream, " vertloctax:"); if (grafptr->vendloctax == grafptr->vertloctax + 1) { for (vertlocnum = grafptr->baseval; vertlocnum <= grafptr->vertlocnnd; vertlocnum ++)/**/ fprintf (stream, " " GNUMSTRING, (Gnum) grafptr->vertloctax[vertlocnum]); fprintf (stream, " x\n vendloctax: = vertloctax + 1"); } else { for (vertlocnum = grafptr->baseval; vertlocnum < grafptr->vertlocnnd; vertlocnum ++) fprintf (stream, " " GNUMSTRING, (Gnum) grafptr->vertloctax[vertlocnum]); fprintf (stream, " vendloctax: x"); for (vertlocnum = grafptr->baseval; vertlocnum < grafptr->vertlocnnd; vertlocnum ++) fprintf (stream, " " GNUMSTRING, (Gnum) grafptr->vendloctax[vertlocnum]); } fprintf (stream, "\n edgeglbnbr: " GNUMSTRING "\n edgelocnbr: " GNUMSTRING "\n", (Gnum) grafptr->edgeglbnbr, (Gnum) grafptr->edgelocnbr); fprintf (stream, " edgeloctax:"); for (edgelocnum = grafptr->baseval, edgelocptr = grafptr->edgeloctax; edgelocnum < grafptr->edgelocnbr + grafptr->baseval; edgelocnum ++, edgelocptr ++) fprintf (stream, " " GNUMSTRING, (Gnum) *edgelocptr); if ((grafptr->flagval & DGRAPHHASEDGEGST) != 0) { fprintf (stream, "\n edgegsttax:"); for (edgelocnum = grafptr->baseval, edgelocptr = grafptr->edgegsttax; edgelocnum < grafptr->edgelocnbr + grafptr->baseval; edgelocnum ++, edgelocptr ++) fprintf (stream, " " GNUMSTRING, (Gnum) *edgelocptr); } fprintf (stream, "\n procdsptab:"); for (procngbnum = 0; procngbnum <= procglbnbr ; procngbnum ++) fprintf (stream, " " GNUMSTRING, (Gnum) grafptr->procdsptab[procngbnum]); fprintf (stream, "\n procngbnbr: %d", grafptr->procngbnbr); fprintf (stream, "\n procngbtab:"); for (procngbnum = 0; procngbnum < grafptr->procngbnbr; procngbnum ++) fprintf (stream, " %d", grafptr->procngbtab[procngbnum]); fprintf (stream, "\n procrcvtab:"); for (procngbnum = 0; procngbnum < grafptr->procglbnbr; procngbnum ++) fprintf (stream, " %d", grafptr->procrcvtab[procngbnum]); fprintf (stream, "\n procsndnbr: %d", grafptr->procsndnbr); fprintf (stream, "\n procsndtab:"); for (procngbnum = 0; procngbnum < grafptr->procglbnbr; procngbnum ++) fprintf (stream, " %d", grafptr->procsndtab[procngbnum]); fprintf (stream, "\n degrglbmax: " GNUMSTRING, (Gnum) grafptr->degrglbmax); fprintf (stream, "\n"); fflush (stream); /* Flush data */ } } MPI_Barrier (proccomm); return (0); } scotch-6.0.4.dfsg/src/libscotch/library_parser_f.c0000644002563400244210000001153412262647370025340 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_parser_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the Fortran API for the **/ /** strategy handling routines of the **/ /** libSCOTCH library. **/ /** **/ /** DATES : # Version 4.0 : from : 17 jan 2004 **/ /** to 17 mar 2005 **/ /** # Version 5.1 : from : 27 mar 2010 **/ /** to 27 mar 2010 **/ /** # Version 6.0 : from : 07 jan 2014 **/ /** to 07 jan 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "parser.h" #include "scotch.h" /***************************************/ /* */ /* These routines are the Fortran API */ /* for the ordering handling routines. */ /* */ /***************************************/ FORTRAN ( \ SCOTCHFSTRATINIT, scotchfstratinit, ( \ SCOTCH_Strat * const stratptr, \ int * const revaptr), \ (stratptr, revaptr)) { *revaptr = SCOTCH_stratInit (stratptr); } /* ** */ FORTRAN ( \ SCOTCHFSTRATEXIT, scotchfstratexit, ( \ SCOTCH_Strat * const stratptr), \ (stratptr)) { SCOTCH_stratExit (stratptr); } /* ** */ FORTRAN ( \ SCOTCHFSTRATFREE, scotchfstratfree, ( \ SCOTCH_Strat * const stratptr), \ (stratptr)) { SCOTCH_stratFree (stratptr); } /* ** */ FORTRAN ( \ SCOTCHFSTRATSAVE, scotchfstratsave, ( \ const SCOTCH_Strat * const stratptr, \ int * const fileptr, \ int * const revaptr), \ (stratptr, fileptr, revaptr)) { FILE * stream; /* Stream to build from handle */ int filenum; /* Duplicated handle */ int o; if ((filenum = dup (*fileptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFSTRATSAVE: cannot duplicate handle"); *revaptr = 1; /* Indicate error */ return; } if ((stream = fdopen (filenum, "w")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFSTRATSAVE: cannot open output stream"); close (filenum); *revaptr = 1; return; } o = SCOTCH_stratSave (stratptr, stream); fclose (stream); /* This closes filenum too */ *revaptr = o; } scotch-6.0.4.dfsg/src/libscotch/hmesh_induce.h0000644002563400244210000000317011631447170024443 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ #undef static scotch-6.0.4.dfsg/src/libscotch/geom.h0000644002563400244210000000656611631447170022753 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : geom.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the geometrical data handling **/ /** routines. **/ /** **/ /** DATES : # Version 3.3 : from : 13 dec 1998 **/ /** to 15 dec 1998 **/ /** # Version 3.4 : from : 10 oct 1999 **/ /** to 12 oct 1999 **/ /** # Version 4.0 : from : 24 nov 2001 **/ /** to 18 jan 2004 **/ /** # Version 5.1 : from : 04 nov 2010 **/ /** to 04 nov 2010 **/ /** **/ /************************************************************/ #define GEOM_H /* ** The type and structure definitions. */ /*+ Geometrical graph structure. +*/ typedef struct Geom_ { int dimnnbr; /*+ Geometry type (1, 2, or 3D) +*/ double * geomtab; /*+ Geometrical vertex array +*/ } Geom; /* ** The function prototypes. */ #ifndef GEOM #define static #endif int geomInit (Geom * restrict const); void geomExit (Geom * restrict const); #undef static scotch-6.0.4.dfsg/src/libscotch/vgraph_separate_vw.h0000644002563400244210000000540211631447171025700 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vgraph_separate_vw.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the move-all-to-first-subdomain **/ /** separation method. **/ /** **/ /** DATES : # Version 3.3 : from : 31 may 1999 **/ /** to 31 may 1999 **/ /** # Version 4.0 : from : 18 may 2004 **/ /** to 18 may 2004 **/ /** **/ /************************************************************/ /* ** The function prototypes. */ #ifndef VGRAPH_SEPARATE_VW #define static #endif int vgraphSeparateVw (Vgraph * const); #undef static scotch-6.0.4.dfsg/src/libscotch/library_dgraph_induce.c0000644002563400244210000001637312055776443026345 0ustar trophimeutilisateurs du domaine/* Copyright 2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_induce.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the **/ /** distributed graph induction routine of **/ /** the libSCOTCH library. **/ /** **/ /** DATES : # Version 6.0 : from : 30 aug 2012 **/ /** to 29 nov 2012 **/ /** **/ /** NOTES : # This code is directly derived from **/ /** the code of dgraphInducePart() and **/ /** of its subroutines. The only change **/ /** is that it uses Gnum's instead of **/ /** GraphPart's as part values. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "dgraph.h" #include "ptscotch.h" /***********************************/ /* */ /* This routine is the C API for */ /* the distributed graph induction */ /* routine. */ /* */ /***********************************/ /*+ This routine creates a distributed induced graph *** from the given graph, according to the partition *** map that is passed to the routine. *** It returns: *** - 0 : if the induced graph has been created. *** - !0 : on error. +*/ typedef struct _SCOTCHDgraphInducePartData_ { const Gnum * orgpartloctax; /* In the public interface, parts are represented as Gnum's */ Gnum indpartval; } _SCOTCHDgraphInducePartData; static Gnum _SCOTCHdgraphInducePart2 ( Dgraph * restrict const indgrafptr, Dgraph * restrict const orggrafptr, const void * restrict const orgdataptr, Gnum * restrict const orgindxgsttax) { Gnum orgvertlocnnd; Gnum orgvertlocnum; Gnum indvertlocnum; Gnum indvertglbnum; Gnum indedgelocmax; const Gnum * restrict const orgvertloctax = orggrafptr->vertloctax; const Gnum * restrict const orgvendloctax = orggrafptr->vendloctax; const Gnum * restrict const orgpartloctax = ((const _SCOTCHDgraphInducePartData * restrict const) orgdataptr)->orgpartloctax; const Gnum indpartval = ((const _SCOTCHDgraphInducePartData * restrict const) orgdataptr)->indpartval; Gnum * restrict const indvnumloctax = indgrafptr->vnumloctax; for (orgvertlocnum = indvertlocnum = orggrafptr->baseval, indvertglbnum = indgrafptr->procvrttab[indgrafptr->proclocnum], /* Fill index array while recomputing tighter upper bound on arcs */ orgvertlocnnd = orggrafptr->vertlocnnd, indedgelocmax = 0; orgvertlocnum < orgvertlocnnd; orgvertlocnum ++) { if (orgpartloctax[orgvertlocnum] == indpartval) { orgindxgsttax[orgvertlocnum] = indvertglbnum; /* Mark selected vertices */ indvnumloctax[indvertlocnum] = orgvertlocnum; indedgelocmax += orgvendloctax[orgvertlocnum] - orgvertloctax[orgvertlocnum]; indvertlocnum ++, indvertglbnum ++; } else orgindxgsttax[orgvertlocnum] = ~0; } #ifdef SCOTCH_DEBUG_DGRAPH2 if ((indvertlocnum - orggrafptr->baseval) != indgrafptr->vertlocnbr) { errorPrint ("dgraphInducePart2: inconsistent data"); dgraphExit (indgrafptr); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ return (indedgelocmax); } int SCOTCH_dgraphInducePart ( SCOTCH_Dgraph * const orggrafptr, /* Original graph */ const SCOTCH_Num * const orgpartloctab, /* Partition array */ const SCOTCH_Num indpartval, /* Part value of induced subgraph */ const SCOTCH_Num indvertlocnbr, /* Number of local vertices in part */ SCOTCH_Dgraph * const indgrafptr) /* Induced subgraph */ { _SCOTCHDgraphInducePartData orgdatadat; Gnum indvertloctmp; int o; #ifdef SCOTCH_DEBUG_LIBRARY1 MPI_Comm_compare (((Dgraph * restrict const) orggrafptr)->proccomm, ((Dgraph * restrict const) indgrafptr)->proccomm, &o); if ((o != MPI_IDENT) && (o != MPI_CONGRUENT)) { errorPrint ("SCOTCH_dgraphInducePart: communicators are not congruent"); return (1); } #endif /* SCOTCH_DEBUG_LIBRARY1 */ if (indvertlocnbr < 0) { /* If number of kept vertices is not known, compute it */ Gnum orgvertlocnum; Gnum orgvertlocnbr; for (orgvertlocnum = indvertloctmp = 0, orgvertlocnbr = ((Dgraph * restrict const) orggrafptr)->vertlocnbr; orgvertlocnum < orgvertlocnbr; orgvertlocnum ++) { if (orgpartloctab[orgvertlocnum] == indpartval) indvertloctmp ++; } } else indvertloctmp = indvertlocnbr; orgdatadat.orgpartloctax = orgpartloctab - ((Dgraph *) orggrafptr)->baseval; orgdatadat.indpartval = indpartval; o = dgraphInduce2 ((Dgraph *) orggrafptr, _SCOTCHdgraphInducePart2, &orgdatadat, indvertloctmp, NULL, (Dgraph *) indgrafptr); ((Dgraph *) indgrafptr)->vnumloctax = NULL; /* Do not impact subsequent inductions */ return (o); } scotch-6.0.4.dfsg/src/libscotch/vgraph_separate_ml.c0000644002563400244210000002611712474554132025657 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2009,2011,2014,2015 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vgraph_separate_ml.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module separates a separator **/ /** graph using a multi-level scheme. **/ /** **/ /** DATES : # Version 3.2 : from : 28 oct 1997 **/ /** to 05 nov 1997 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 4.0 : from : 13 dec 2001 **/ /** to 20 mar 2005 **/ /** # Version 5.1 : from : 11 nov 2009 **/ /** to 11 nov 2009 **/ /** # Version 6.0 : from : 09 mar 2011 **/ /** to 27 feb 2015 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VGRAPH_SEPARATE_ML #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "arch.h" #include "mapping.h" #include "graph_coarsen.h" #include "vgraph.h" #include "vgraph_separate_ml.h" #include "vgraph_separate_st.h" /*********************************************/ /* */ /* The coarsening and uncoarsening routines. */ /* */ /*********************************************/ /* This routine builds a coarser graph from the ** graph that is given on input. The coarser ** graphs differ at this stage from classical ** active graphs as their internal gains are not ** yet computed. ** It returns: ** - 0 : if the coarse graph has been built. ** - 1 : if threshold achieved or on error. */ static int vgraphSeparateMlCoarsen ( const Vgraph * restrict const finegrafptr, /*+ Finer graph +*/ Vgraph * restrict const coargrafptr, /*+ Coarser graph to build +*/ GraphCoarsenMulti * restrict * const coarmultptr, /*+ Pointer to un-based multinode table to build +*/ const VgraphSeparateMlParam * const paraptr) /*+ Method parameters +*/ { *coarmultptr = NULL; /* Allocate coarmulttab along with coarse graph */ if (graphCoarsen (&finegrafptr->s, &coargrafptr->s, coarmultptr, paraptr->coarnbr, paraptr->coarval, NULL, NULL, 0, NULL) != 0) return (1); /* Return if coarsening failed */ coargrafptr->parttax = NULL; /* Do not allocate partition data yet */ coargrafptr->frontab = finegrafptr->frontab; /* Re-use frontier array for coarser graph */ coargrafptr->levlnum = finegrafptr->levlnum + 1; /* Graph level is coarsening level */ return (0); } /* This routine propagates the separation of the ** coarser graph back to the finer graph, according ** to the multinode table of collapsed vertices. ** After the separation is propagated, it finishes ** to compute the parameters of the finer graph that ** were not computed at the coarsening stage. ** It returns: ** - 0 : if coarse graph data has been propagated to fine graph. ** - !0 : on error. */ static int vgraphSeparateMlUncoarsen ( Vgraph * restrict const finegrafptr, /*+ Finer graph +*/ const Vgraph * restrict const coargrafptr, /*+ Coarser graph +*/ const GraphCoarsenMulti * restrict const coarmulttab) /*+ Un-based multinode array +*/ { Gnum coarvertnbr; Gnum coarvertnum; /* Number of current coarse vertex */ Gnum finefronnbr; /* Number of frontier vertices in fine graph */ if (finegrafptr->parttax == NULL) { /* If partition array not yet allocated */ if ((finegrafptr->parttax = (GraphPart *) memAlloc (finegrafptr->s.vertnbr * sizeof (GraphPart))) == NULL) { errorPrint ("vgraphSeparateMlUncoarsen: out of memory"); return (1); /* Allocated data will be freed along with graph structure */ } finegrafptr->parttax -= finegrafptr->s.baseval; } if (coargrafptr != NULL) { /* If coarser graph provided */ GraphPart * restrict fineparttax; Gnum finesize1; /* Number of vertices in fine part 1 */ const GraphPart * restrict const coarparttab = coargrafptr->parttax + coargrafptr->s.baseval; Gnum * restrict const finefrontab = finegrafptr->frontab; finesize1 = coargrafptr->compsize[1]; /* Pre-allocate size */ fineparttax = finegrafptr->parttax; for (coarvertnum = finefronnbr = 0, coarvertnbr = coargrafptr->s.vertnbr; coarvertnum < coarvertnbr; coarvertnum ++) { Gnum finevertnum0; /* First multinode vertex */ Gnum finevertnum1; /* Second multinode vertex */ GraphPart coarpartval; /* Value of current multinode part */ finevertnum0 = coarmulttab[coarvertnum].vertnum[0]; finevertnum1 = coarmulttab[coarvertnum].vertnum[1]; coarpartval = coarparttab[coarvertnum]; fineparttax[finevertnum0] = coarpartval; if (coarpartval != 2) { /* If vertex is not in separator */ if (finevertnum0 != finevertnum1) { fineparttax[finevertnum1] = coarpartval; finesize1 += (Gnum) coarpartval; /* One extra vertex accounted for in part 1 if (coarpartval == 1) */ } } else { /* Vertex is in separator */ finefrontab[finefronnbr ++] = finevertnum0; if (finevertnum0 != finevertnum1) { fineparttax[finevertnum1] = coarpartval; finefrontab[finefronnbr ++] = finevertnum1; /* One extra vertex in separator */ } } } finegrafptr->fronnbr = finefronnbr; finegrafptr->compload[0] = coargrafptr->compload[0]; finegrafptr->compload[1] = coargrafptr->compload[1]; finegrafptr->compload[2] = coargrafptr->compload[2]; finegrafptr->comploaddlt = coargrafptr->comploaddlt; finegrafptr->compsize[0] = finegrafptr->s.vertnbr - finefronnbr - finesize1; finegrafptr->compsize[1] = finesize1; } else /* No coarse graph provided */ vgraphZero (finegrafptr); /* Assign all vertices to part 0 */ #ifdef SCOTCH_DEBUG_VGRAPH2 if (vgraphCheck (finegrafptr) != 0) { errorPrint ("vgraphSeparateMlUncoarsen: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ return (0); } /* This routine recursively performs the ** separation recursion. ** It returns: ** - 0 : if separator could be computed. ** - !0 : on error. */ static int vgraphSeparateMl2 ( Vgraph * restrict const grafptr, /* Vertex-separation graph */ const VgraphSeparateMlParam * const paraptr) /* Method parameters */ { Vgraph coargrafdat; GraphCoarsenMulti * restrict coarmulttab; int o; if (vgraphSeparateMlCoarsen (grafptr, &coargrafdat, &coarmulttab, paraptr) == 0) { if (((o = vgraphSeparateMl2 (&coargrafdat, paraptr)) == 0) && ((o = vgraphSeparateMlUncoarsen (grafptr, &coargrafdat, coarmulttab)) == 0) && ((o = vgraphSeparateSt (grafptr, paraptr->stratasc)) != 0)) /* Apply ascending strategy */ errorPrint ("vgraphSeparateMl2: cannot apply ascending strategy"); coargrafdat.frontab = NULL; /* Prevent frontab of fine graph from being freed */ vgraphExit (&coargrafdat); } else { /* Cannot coarsen due to lack of memory or error */ if (((o = vgraphSeparateMlUncoarsen (grafptr, NULL, NULL)) == 0) && /* Finalize graph */ ((o = vgraphSeparateSt (grafptr, paraptr->stratlow)) != 0)) /* Apply low strategy */ errorPrint ("vgraphSeparateMl2: cannot apply low strategy"); } return (o); } /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the muti-level separation. ** It returns: ** - 0 : if separator could be computed. ** - 1 : on error. */ int vgraphSeparateMl ( Vgraph * const grafptr, /*+ Vertex-separation graph +*/ const VgraphSeparateMlParam * const paraptr) /*+ Method parameters +*/ { Gnum levlnum; /* Save value for graph level */ int o; levlnum = grafptr->levlnum; /* Save graph level */ grafptr->levlnum = 0; /* Initialize coarsening level */ o = vgraphSeparateMl2 (grafptr, paraptr); /* Perform multi-level separation */ grafptr->levlnum = levlnum; /* Restore graph level */ return (o); } scotch-6.0.4.dfsg/src/libscotch/dgraph_band_grow.h0000644002563400244210000000636512030552451025301 0ustar trophimeutilisateurs du domaine/* Copyright 2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_band_grow.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file provides the prototypes of **/ /** the generic band graph growing **/ /** routines. **/ /** **/ /** DATES : # Version 6.0 : from : 26 sep 2012 **/ /** to : 26 sep 2012 **/ /** **/ /************************************************************/ /* ** The defines. */ #define DGRAPHBANDGROWNAMECOLL DGRAPHBANDGROWNAMECOLL2 (REPLACE (DGRAPHBANDGROWNAME)) #define DGRAPHBANDGROWNAMECOLL2(s) GLUE (s,Coll) #define DGRAPHBANDGROWNAMEPTOP DGRAPHBANDGROWNAMEPTOP2 (REPLACE (DGRAPHBANDGROWNAME)) #define DGRAPHBANDGROWNAMEPTOP2(s) GLUE (s,Ptop) /* ** The function prototypes. */ int DGRAPHBANDGROWNAMECOLL (Dgraph * restrict const, const Gnum, Gnum * restrict const, const Gnum, Gnum * restrict const, Gnum * restrict const, Gnum * restrict const, Gnum * restrict const); int DGRAPHBANDGROWNAMEPTOP (Dgraph * restrict const, const Gnum, Gnum * restrict const, const Gnum, Gnum * restrict const, Gnum * restrict const, Gnum * restrict const, Gnum * restrict const); scotch-6.0.4.dfsg/src/libscotch/kgraph_map_df_loop.c0000644002563400244210000005316412376151427025632 0ustar trophimeutilisateurs du domaine/* Copyright 2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph_map_df_loop.c **/ /** **/ /** AUTHOR : Sebastien FOURESTIER (v6.0) **/ /** Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module computes a k-way partition **/ /** of the given mapping graph by applying **/ /** a diffusion method to what is assumed **/ /** to be a band graph. **/ /** **/ /** DATES : # Version 6.0 : from : 05 jan 2010 **/ /** to : 23 aug 2014 **/ /** **/ /************************************************************/ /* Tests flags for mapping TODO remove it after performance tests */ /* #define KGRAPHDIFFMAPPNONE */ /* No special code for mapping */ /* #define KGRAPHDIFFMAPPMORE */ /* Give more liquid on expensive architecture edges */ #define KGRAPHDIFFMAPPLESS /* Give less liquid on expensive architecture edges */ /* ** The defines and includes. */ /****************************/ /* */ /* The diffusion subroutine */ /* pattern. */ /* */ /****************************/ /* This routine computes the diffusion of liquids ** on the given part of the k-way band graph. ** It returns: ** - void : in all cases */ static int KGRAPHMAPDFLOOPNAME ( KgraphMapDfThread * restrict thrdptr) /* Thread-dependent data */ { KgraphMapDfVertex * restrict difotax; /* Old diffusion value array */ KgraphMapDfVertex * restrict difntax; /* New diffusion value array */ KgraphMapDfSort * restrict sorttab; /* Liquid sort array */ Gnum vancnnd; Gnum vertnum; Anum domnnum; Gnum passnum; int velsmsk; int mappflag; /* We are computing a mapping */ KgraphMapDfData * restrict const loopptr = (KgraphMapDfData *) thrdptr->thrddat.grouptr; const Kgraph * restrict const grafptr = loopptr->grafptr; float * restrict const vanctab = loopptr->vanctab; float * restrict const valotab = loopptr->valotab; /* Fraction of load to leak */ Gnum * restrict const velstax = loopptr->velstax; const Gnum vertbas = thrdptr->vertbas; /* Range of non-anchor vertices to process */ const Gnum vertnnd = thrdptr->vertnnd; const Anum domnbas = thrdptr->domnbas; /* Range of anchor vertices to process */ const Anum domnnnd = thrdptr->domnnnd; const Anum domnnbr = grafptr->m.domnnbr; const Gnum crloval = grafptr->r.crloval; const Gnum cmloval = grafptr->r.cmloval; Anum * restrict const parttax = grafptr->m.parttax; const Anum * restrict const parotax = grafptr->r.m.parttax; const Gnum * restrict const verttax = grafptr->s.verttax; const Gnum * restrict const vendtax = grafptr->s.vendtax; const Gnum * restrict const velotax = grafptr->s.velotax; const Gnum * const edgetax = grafptr->s.edgetax; const Gnum * const edlotax = grafptr->s.edlotax; vancnnd = grafptr->s.vertnnd - domnnbr; velsmsk = 1; /* Assume no anchors are isolated */ if (edlotax != NULL) { for (domnnum = domnbas; domnnum < domnnnd; domnnum ++) { /* For all local anchor vertices */ Gnum edgenum; Gnum edgennd; Gnum velssum; for (edgenum = verttax[vancnnd + domnnum], edgennd = vendtax[vancnnd + domnnum], velssum = 0; edgenum < edgennd; edgenum ++) velssum += edlotax[edgenum]; velstax[vancnnd + domnnum] = velssum; velsmsk &= (velssum != 0); } } else { for (domnnum = domnbas; domnnum < domnnnd; domnnum ++) { Gnum velssum; velssum = vendtax[vancnnd + domnnum] - verttax[vancnnd + domnnum]; /* Local degree of anchor vertices */ velstax[vancnnd + domnnum] = velssum; velsmsk &= (velssum != 0); } } if (velsmsk == 0) { /* If graph is too small to have any usable anchors */ #ifdef KGRAPHMAPDFLOOPTHREAD loopptr->abrtval == 1; /* We will leave during the first iteration */ #else /* KGRAPHMAPDFLOOPTHREAD */ return (1); #endif /* KGRAPHMAPDFLOOPTHREAD */ } if ((sorttab = memAlloc (domnnbr * sizeof (KgraphMapDfSort))) == NULL) { /* Allocate here for memory affinity as it is a private array */ errorPrint (STRINGIFY (KGRAPHMAPDFLOOPNAME) ": out of memory"); #ifdef KGRAPHMAPDFLOOPTHREAD loopptr->abrtval = 1; #else /* KGRAPHMAPDFLOOPTHREAD */ return (1); #endif /* KGRAPHMAPDFLOOPTHREAD */ } if (velotax == NULL) { for (domnnum = domnbas; domnnum < domnnnd; domnnum ++) valotab[domnnum] = 1.0F; } else { for (domnnum = domnbas; domnnum < domnnnd; domnnum ++) valotab[domnnum] = (float) velotax[vancnnd + domnnum]; } difntax = loopptr->difntax; difotax = loopptr->difotax; if (edlotax != NULL) { for (vertnum = vertbas; vertnum < vertnnd; vertnum ++) { Gnum velssum; Gnum edgenum; Gnum edgennd; #ifdef SCOTCH_DEBUG_KGRAPH2 if ((vendtax[vertnum] - verttax[vertnum]) == 0) { errorPrint (STRINGIFY (KGRAPHMAPDFLOOPNAME) ": internal error (1)"); #ifdef KGRAPHMAPDFLOOPTHREAD loopptr->abrtval = 1; #else /* KGRAPHMAPDFLOOPTHREAD */ return (1); #endif /* KGRAPHMAPDFLOOPTHREAD */ } #endif /* SCOTCH_DEBUG_KGRAPH2 */ difotax[vertnum].partval = parttax[vertnum]; /* Set initial part by default */ difotax[vertnum].diffval = difotax[vertnum].fdifval = difotax[vertnum].mdisval = difotax[vertnum].mdidval = difntax[vertnum].fdifval = difntax[vertnum].mdisval = difntax[vertnum].mdidval = 0.0F; for (edgenum = verttax[vertnum], edgennd = vendtax[vertnum], velssum = 0; edgenum < edgennd; edgenum ++) velssum += edlotax[edgenum]; velstax[vertnum] = velssum; } } else { /* Graph has no edge loads */ for (vertnum = vertbas; vertnum < vertnnd; vertnum ++) { #ifdef SCOTCH_DEBUG_KGRAPH2 if ((vendtax[vertnum] - verttax[vertnum]) == 0) { errorPrint (STRINGIFY (KGRAPHMAPDFLOOPNAME) ": internal error (2)"); #ifdef KGRAPHMAPDFLOOPTHREAD loopptr->abrtval = 1; #else /* KGRAPHMAPDFLOOPTHREAD */ return (1); #endif /* KGRAPHMAPDFLOOPTHREAD */ } #endif /* SCOTCH_DEBUG_KGRAPH2 */ difotax[vertnum].partval = parttax[vertnum]; /* Set initial part by default */ difotax[vertnum].diffval = difotax[vertnum].fdifval = difotax[vertnum].mdisval = difotax[vertnum].mdidval = difntax[vertnum].fdifval = difntax[vertnum].mdisval = difntax[vertnum].mdidval = 0.0F; velstax[vertnum] = vendtax[vertnum] - verttax[vertnum]; } } for (domnnum = domnbas, vertnum = vancnnd + domnbas; /* For all the subset of anchor vertices */ domnnum < domnnnd; domnnum ++, vertnum ++) { float vancval; Gnum comploadbal; /* Compload to reach to get wished balance */ if (velstax[vancnnd + domnnum] <= 0) { vancval = vanctab[domnnum] = 0.0F; velstax[vertnum] = -1; } else { comploadbal = grafptr->comploadavg[domnnum]; vancval = ((float) comploadbal - valotab[domnnum]) / (float) velstax[vancnnd + domnnum]; /* Amount of liquid to be added at each step */ vanctab[domnnum] = comploadbal; } difotax[vertnum].diffval = vancval; /* Load anchor vertices for first pass */ difotax[vertnum].partval = difntax[vertnum].partval = domnnum; difntax[vertnum].diffval = /* In case of isolated anchors, do not risk overflow because of NaN */ difotax[vertnum].fdifval = difotax[vertnum].mdisval = difotax[vertnum].mdidval = difntax[vertnum].fdifval = difntax[vertnum].mdisval = difntax[vertnum].mdidval = 0.0F; /* Do not consider migration costs for anchors */ } #ifdef KGRAPHMAPDFLOOPTHREAD threadBarrier (thrdptr); if (loopptr->abrtval == 1) { /* If process alone or some decided to quit */ memFree (sorttab); /* Free local array */ return (1); } #endif /* KGRAPHMAPDFLOOPTHREAD */ #ifndef KGRAPHDIFFMAPPNONE if (archPart (grafptr->m.archptr)) mappflag = 0; else mappflag = 1; #else mappflag = 0; #endif /* KGRAPHDIFFMAPPNONE */ passnum = loopptr->passnbr; for ( ; passnum > 0; passnum --) { /* For all passes */ KgraphMapDfVertex * difttax; /* Temporary swap value */ Gnum vertnum; float veloval; veloval = 1.0F; /* Assume no vertex loads */ for (vertnum = vertbas; vertnum < vertnnd; vertnum ++) { /* For all local regular vertices */ Gnum edgenum; Gnum edgennd; Gnum soplval; /* Load sum of edges going to vertex old part */ Gnum sfplval; /* Load sum of edges going to vertex of other parts */ Gnum dfplval; /* Load sum of edges going to vertex of other parts * distval */ Gnum migrval; Anum partnbr; /* Number of active parts */ Anum partnum; float diffval; float signval; Anum paronum; Anum partcur; partnbr = 1; /* Keep vertex in first place to preserve its part */ partcur = sorttab[0].partval = difotax[vertnum].partval; /* Always keep old part value */ sorttab[0].diffval = 0.0F; /* Assume at first it is null */ sorttab[0].edlosum = 0; /* Assume at first there are no loads */ sorttab[0].distval = 1; /* Do not take distval of our part into account */ for (edgenum = verttax[vertnum], edgennd = vendtax[vertnum]; edgenum < edgennd; edgenum ++) { Gnum vertend; float diffval; float fdifval; float mdisval; float mdidval; Anum partval; Anum partnum; Gnum edloval; Anum distval; vertend = edgetax[edgenum]; edloval = (float) ((edlotax != NULL) ? edlotax[edgenum] : 1); partval = difotax[vertend].partval; diffval = difotax[vertend].diffval; /* Value is not yet scaled with respect to diffusion coefficient */ fdifval = difotax[vertend].fdifval; mdisval = difotax[vertend].mdisval; mdidval = difotax[vertend].mdidval; if ((mappflag == 1) && (partval != partcur)) diffval = fdifval; diffval *= edloval * crloval; if (parotax != NULL) { if (difotax[vertnum].partval == parotax[vertend]) diffval += mdisval; else diffval += mdidval; } for (partnum = 0; partnum < partnbr; partnum ++) { if (sorttab[partnum].partval == partval) { sorttab[partnum].diffval += diffval; /* Accumulate contribution in slot */ sorttab[partnum].edlosum += edloval; goto endloop1; /* Do not consider creating a new slot */ } } sorttab[partnbr].partval = partval; /* Create new slot */ sorttab[partnbr].distval = ((mappflag == 1) && (partcur != partval)) ? archDomDist (&grafptr->a, &grafptr->m.domntab[partcur], &grafptr->m.domntab[partval]) : 1; sorttab[partnbr].diffval = diffval; sorttab[partnbr].edlosum = edloval; partnbr ++; endloop1 : ; } if (mappflag == 1) for (partnum = 0; partnum < partnbr; partnum ++) #ifdef KGRAPHDIFFMAPPMORE sorttab[partnum].diffval *= sorttab[partnum].distval; #else /* KGRAPHDIFFMAPPLESS */ sorttab[partnum].diffval /= sorttab[partnum].distval; #endif /* KGRAPHDIFFMAPPMORE */ if (partnbr > 1) /* If not interior vertex */ kgraphMapDfSort (sorttab, partnbr); /* Sort array by descending amounts */ soplval = 0; if (parotax != NULL) { for (partnum = 0; partnum < partnbr; partnum ++) { if (sorttab[partnum].partval == parotax[vertnum]) { soplval = sorttab[partnum].edlosum; break; } } } sfplval = 0; dfplval = 0; if (mappflag == 1) { /* We are doing a mapping */ for (partnum = 1; partnum < partnbr; partnum ++) { sfplval += sorttab[partnum].edlosum; #ifdef KGRAPHDIFFMAPPMORE dfplval += sorttab[partnum].edlosum * sorttab[partnum].distval; #else /* KGRAPHDIFFMAPPLESS */ dfplval += sorttab[partnum].edlosum / sorttab[partnum].distval; #endif /* KGRAPHDIFFMAPPMORE */ } } difntax[vertnum].partval = sorttab[0].partval; /* New part is part of most abundant liquid */ diffval = sorttab[0].diffval; /* Get amount of most abundant liquid */ if (velotax != NULL) /* Account for capacity of barrel */ veloval = (float) velotax[vertnum]; diffval -= veloval; /* Leak liquid from barrel */ if (diffval <= 0.0F) /* Amount of liquid cannot be negative */ diffval = 0.0F; migrval = ((soplval == 0) || (soplval == velstax[vertnum])) ? 0 : grafptr->r.cmloval * ((grafptr->r.vmlotax != NULL) ? grafptr->r.vmlotax[vertnum] : 1); if (migrval > diffval) { migrval = diffval; diffval = 0; } else diffval -= migrval; diffval = diffval / (velstax[vertnum] * crloval); if (isnan (diffval)) { /* If overflow occured */ #ifdef SCOTCH_DEBUG_KGRAPH2 errorPrintW (STRINGIFY (KGRAPHMAPDFLOOPNAME) ": overflow (1)"); #endif /* SCOTCH_DEBUG_KGRAPH2 */ #ifdef KGRAPHMAPDFLOOPTHREAD loopptr->abrtval = 1; /* Threads need to halt */ goto abort1; /* Skip computations but synchronize */ #else /* KGRAPHMAPDFLOOPTHREAD */ goto abort2; /* Exit this loop without swapping arrays */ #endif /* KGRAPHMAPDFLOOPTHREAD */ } if (parotax != NULL) { if (migrval == 0) { difntax[vertnum].mdisval = difntax[vertnum].mdidval = 0; } else { if (parotax[vertnum] == sorttab[0].partval) { difntax[vertnum].mdisval = migrval / soplval; difntax[vertnum].mdidval = 0; } else { difntax[vertnum].mdisval = 0; difntax[vertnum].mdidval = migrval / (velstax[vertnum] - soplval); } } } difntax[vertnum].diffval = diffval; if (dfplval != 0) difntax[vertnum].fdifval = diffval * sfplval / dfplval; else difntax[vertnum].fdifval = 0; } for (domnnum = domnbas, vertnum = vancnnd + domnbas; /* For all the subset of anchor vertices */ domnnum < domnnnd; domnnum ++, vertnum ++) { Gnum edgenum; Gnum edgennd; Anum partnbr; /* Number of active parts */ Anum partnum; float diffval; float signval; partnbr = 1; /* Keep vertex in first place to preserve its part */ sorttab[0].partval = domnnum; /* Always keep initial part value */ sorttab[0].diffval = 0.0F; /* Assume at first it is null */ edgenum = verttax[vertnum]; edgennd = vendtax[vertnum]; if (edgenum == edgennd) /* If isolated anchor */ continue; /* Barrel is empty */ for ( ; edgenum < edgennd; edgenum ++) { /* For all edges except anchors */ Gnum vertend; float diffval; Anum partval; Anum partnum; vertend = edgetax[edgenum]; partval = difotax[vertend].partval; diffval = difotax[vertend].diffval; /* Value is not yet scaled with respect to diffusion coefficient */ diffval *= (float) ((edlotax != NULL) ? edlotax[edgenum] : 1); diffval *= crloval; for (partnum = 0; partnum < partnbr; partnum ++) { if (sorttab[partnum].partval == partval) { sorttab[partnum].diffval += diffval; /* Accumulate contribution in slot */ goto endloop2; /* Do not consider creating a new slot */ } } sorttab[partnbr].partval = partval; /* Create new slot */ sorttab[partnbr].diffval = diffval; partnbr ++; endloop2 : ; } if (partnbr > 1) /* If not interior vertex */ kgraphMapDfSort (sorttab, partnbr); /* Sort array by descending amounts */ diffval = sorttab[0].diffval; /* Get amount of most abundant liquid */ if (sorttab[0].partval != domnnum) /* Add liquid from tap to barrel */ diffval = vanctab[domnnum] - diffval; else diffval += vanctab[domnnum]; diffval = (diffval - valotab[domnnum]) / (velstax[vertnum] * crloval); /* Add input and leak liquid from barrel */ if (diffval <= 0.0F) /* Amount of liquid cannot be negative */ diffval = 0.0F; if (isnan (diffval)) { /* If overflow occured */ #ifdef SCOTCH_DEBUG_KGRAPH2 errorPrintW (STRINGIFY (KGRAPHMAPDFLOOPNAME) ": overflow (2)"); #endif /* SCOTCH_DEBUG_KGRAPH2 */ #ifdef KGRAPHMAPDFLOOPTHREAD loopptr->abrtval = 1; /* Threads need to halt */ goto abort1; /* Skip computations but synchronize */ #else /* KGRAPHMAPDFLOOPTHREAD */ goto abort2; /* Exit this loop without swapping arrays */ #endif /* KGRAPHMAPDFLOOPTHREAD */ } difntax[vertnum].partval = domnnum; /* Anchor part is always domain part */ difntax[vertnum].diffval = diffval; } difttax = (KgraphMapDfVertex *) difntax; /* Swap old and new diffusion arrays */ difntax = (KgraphMapDfVertex *) difotax; /* Casts to prevent IBM compiler from yelling */ difotax = (KgraphMapDfVertex *) difttax; abort1 : ; /* If overflow occured, resume here */ #ifdef KGRAPHMAPDFLOOPTHREAD threadBarrier (thrdptr); if (loopptr->abrtval == 1) /* If all threads need to abort */ break; #endif /* KGRAPHMAPDFLOOPTHREAD */ } abort2 : ; for (vertnum = vertbas; vertnum < vertnnd; vertnum ++) /* Set new part distribution of local vertices */ parttax[vertnum] = difntax[vertnum].partval; memFree (sorttab); /* Free local array */ return (0); } scotch-6.0.4.dfsg/src/libscotch/bdgraph_bipart_df.h0000644002563400244210000000723611631447170025440 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2009,2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bdgraph_bipart_df.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the parallel diffusion bipartition- **/ /** ing routine for distributed graphs. **/ /** **/ /** DATES : # Version 5.1 : from : 16 nov 2007 **/ /** to : 14 apr 2011 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ Small non-zero float value. +*/ #define BDGRAPHBIPARTDFEPSILON (1.0F / (float) (GNUMMAX)) /*+ Sign masking operator. +*/ #define BDGRAPHBIPARTDFGNUMSGNMSK(i) ((Gnum) 0 - (((Gunum) (i)) >> (sizeof (Gnum) * 8 - 1))) /* ** The type and structure definitions. */ /*+ Job selection policy types. +*/ typedef enum BdgraphBipartDfType_ { BDGRAPHBIPARTDFTYPEBAL = 0, /*+ Balance to average +*/ BDGRAPHBIPARTDFTYPEKEEP /*+ Preserve current imbalance +*/ } BdgraphBipartDfType; /*+ Method parameters. +*/ typedef struct BdgraphBipartDfParam_ { INT passnbr; /*+ Number of passes to do +*/ double cdifval; /*+ Coefficient of diffused load +*/ double cremval; /*+ Coefficient of remaining load +*/ BdgraphBipartDfType typeval; /*+ Type of balance to reach +*/ } BdgraphBipartDfParam; /* ** The function prototypes. */ #ifndef BDGRAPH_BIPART_DF #define static #endif int bdgraphBipartDf (Bdgraph * const, const BdgraphBipartDfParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/hdgraph_order_st.h0000644002563400244210000000651211631447170025331 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hdgraph_order_st.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data **/ /** declarations for the main distributed **/ /** graph ordering routine. **/ /** **/ /** DATES : # Version 5.0 : from : 14 apr 2006 **/ /** to : 14 apr 2006 **/ /** # Version 5.1 : from : 11 nov 2008 **/ /** to : 11 nov 2008 **/ /** **/ /************************************************************/ /* ** The type definitions. */ /*+ Method types. +*/ typedef enum HdgraphOrderStMethodType_ { HDGRAPHORDERSTMETHND = 0, /*+ Nested Dissection +*/ HDGRAPHORDERSTMETHSI, /*+ Simple +*/ HDGRAPHORDERSTMETHSQ, /*+ Sequential method +*/ HDGRAPHORDERSTMETHNBR /*+ Number of methods +*/ } HdgraphOrderStMethodType; /* ** The external declarations. */ extern StratTab hdgraphorderststratab; /* ** The function prototypes. */ #ifndef HDGRAPH_ORDER_ST #define static #endif int hdgraphOrderSt (const Hdgraph * restrict const, DorderCblk * restrict const, const Strat * const); #undef static scotch-6.0.4.dfsg/src/libscotch/library_dgraph_map.c0000644002563400244210000003645512055776677025667 0ustar trophimeutilisateurs du domaine/* Copyright 2008-2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_map.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the distri- **/ /** buted graph mapping routines of the **/ /** libSCOTCH library. **/ /** **/ /** DATES : # Version 5.1 : from : 12 jun 2008 **/ /** to 31 aug 2011 **/ /** # Version 6.0 : from : 14 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "parser.h" #include "dgraph.h" #include "arch.h" #include "dmapping.h" #include "kdgraph.h" #include "kdgraph_map_st.h" #include "library_dmapping.h" #include "ptscotch.h" /************************************/ /* */ /* These routines are the C API for */ /* the parallel mapping routines. */ /* */ /************************************/ /*+ This routine initializes an API opaque *** mapping with respect to the given source *** graph and the locations of output parameters. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_dgraphMapInit ( const SCOTCH_Dgraph * const grafptr, /*+ Graph to map +*/ SCOTCH_Dmapping * const mappptr, /*+ Mapping structure to initialize +*/ const SCOTCH_Arch * const archptr, /*+ Target architecture used to map +*/ SCOTCH_Num * const termloctab) /*+ Mapping array +*/ { LibDmapping * restrict srcmappptr; #ifdef SCOTCH_DEBUG_LIBRARY1 if (sizeof (SCOTCH_Dmapping) < sizeof (LibDmapping)) { errorPrint ("SCOTCH_dgraphMapInit: internal error"); return (1); } #endif /* SCOTCH_DEBUG_LIBRARY1 */ srcmappptr = (LibDmapping *) mappptr; srcmappptr->termloctab = ((termloctab == NULL) || ((void *) termloctab == (void *) grafptr)) ? NULL : termloctab; return (dmapInit (&srcmappptr->m, (Arch *) archptr)); } /*+ This routine frees an API mapping. *** It returns: *** - VOID : in all cases. +*/ void SCOTCH_dgraphMapExit ( const SCOTCH_Dgraph * const grafptr, SCOTCH_Dmapping * const mappptr) { dmapExit (&((LibDmapping *) mappptr)->m); } /*+ This routine saves the contents of *** the given mapping to the given stream. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_dgraphMapSave ( const SCOTCH_Dgraph * const grafptr, /*+ Graph to map +*/ const SCOTCH_Dmapping * const mappptr, /*+ Mapping to save +*/ FILE * const stream) /*+ Output stream +*/ { return (dmapSave (&((LibDmapping *) mappptr)->m, (Dgraph *) grafptr, stream)); } /*+ This routine computes a mapping *** of the API mapping structure with *** respect to the given strategy. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_dgraphMapCompute ( SCOTCH_Dgraph * const grafptr, /*+ Graph to map +*/ SCOTCH_Dmapping * const mappptr, /*+ Mapping to compute +*/ SCOTCH_Strat * const stratptr) /*+ Mapping strategy +*/ { Kdgraph mapgrafdat; /* Effective mapping graph */ Kdmapping mapmappdat; /* Initial mapping domain */ const Strat * mapstratptr; /* Pointer to mapping strategy */ LibDmapping * restrict srcmappptr; Dgraph * srcgrafptr; int o; srcgrafptr = (Dgraph *) grafptr; srcmappptr = (LibDmapping *) mappptr; #ifdef SCOTCH_DEBUG_DGRAPH2 if (dgraphCheck (srcgrafptr) != 0) { errorPrint ("SCOTCH_dgraphMapCompute: invalid input graph"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ if (*((Strat **) stratptr) == NULL) { /* Set default mapping strategy if necessary */ ArchDom archdomnorg; archDomFrst (&srcmappptr->m.archdat, &archdomnorg); if (archVar (&srcmappptr->m.archdat)) SCOTCH_stratDgraphClusterBuild (stratptr, 0, srcgrafptr->procglbnbr, 1, 1.0, 0.05); else SCOTCH_stratDgraphMapBuild (stratptr, 0, srcgrafptr->procglbnbr, archDomSize (&srcmappptr->m.archdat, &archdomnorg), 0.05); } mapstratptr = *((Strat **) stratptr); if (mapstratptr->tabl != &kdgraphmapststratab) { errorPrint ("SCOTCH_dgraphMapCompute: not a parallel graph mapping strategy"); return (1); } intRandInit (); /* Check that random number generator is initialized */ if (kdgraphInit (&mapgrafdat, srcgrafptr, &srcmappptr->m) != 0) return (1); mapmappdat.mappptr = &srcmappptr->m; if (((o = kdgraphMapSt (&mapgrafdat, &mapmappdat, mapstratptr)) == 0) && /* Perform mapping */ (srcmappptr->termloctab != NULL)) o = dmapTerm (&srcmappptr->m, &mapgrafdat.s, srcmappptr->termloctab); /* Use "&mapgrafdat.s" to take advantage of ghost arrays */ kdgraphExit (&mapgrafdat); return (o); } /*+ This routine computes a mapping of the *** given graph structure onto the given *** target architecture with respect to the *** given strategy. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_dgraphMap ( SCOTCH_Dgraph * const grafptr, /*+ Graph to map +*/ const SCOTCH_Arch * const archptr, /*+ Target architecture +*/ SCOTCH_Strat * const stratptr, /*+ Mapping strategy +*/ SCOTCH_Num * const termloctab) /*+ Mapping array +*/ { SCOTCH_Dmapping mappdat; int o; SCOTCH_dgraphMapInit (grafptr, &mappdat, archptr, termloctab); o = SCOTCH_dgraphMapCompute (grafptr, &mappdat, stratptr); SCOTCH_dgraphMapExit (grafptr, &mappdat); return (o); } /*+ This routine computes a partition of *** the given graph structure with respect *** to the given strategy. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_dgraphPart ( SCOTCH_Dgraph * const grafptr, /*+ Graph to map +*/ const SCOTCH_Num partnbr, /*+ Number of parts +*/ SCOTCH_Strat * const stratptr, /*+ Mapping strategy +*/ SCOTCH_Num * const termloctab) /*+ Mapping array +*/ { SCOTCH_Arch archdat; int o; SCOTCH_archInit (&archdat); SCOTCH_archCmplt (&archdat, partnbr); o = SCOTCH_dgraphMap (grafptr, &archdat, stratptr, termloctab); SCOTCH_archExit (&archdat); return (o); } /*+ This routine parses the given *** mapping strategy. *** It returns: *** - 0 : if string successfully scanned. *** - !0 : on error. +*/ int SCOTCH_stratDgraphMap ( SCOTCH_Strat * const stratptr, const char * const string) { if (*((Strat **) stratptr) != NULL) stratExit (*((Strat **) stratptr)); if ((*((Strat **) stratptr) = stratInit (&kdgraphmapststratab, string)) == NULL) { errorPrint ("SCOTCH_stratDgraphMap: error in parallel mapping strategy"); return (1); } return (0); } /*+ This routine provides predefined *** mapping strategies. *** It returns: *** - 0 : if string successfully initialized. *** - !0 : on error. +*/ int SCOTCH_stratDgraphMapBuild ( SCOTCH_Strat * const stratptr, /*+ Strategy to create +*/ const SCOTCH_Num flagval, /*+ Desired characteristics +*/ const SCOTCH_Num procnbr, /*+ Number of processes for running +*/ const SCOTCH_Num partnbr, /*+ Number of expected parts +*/ const double kbalval) /*+ Desired imbalance ratio +*/ { char bufftab[8192]; /* Should be enough */ char bbaltab[32]; char kbaltab[32]; char verttab[32]; Gnum vertnbr; char * difpptr; char * difsptr; char * exapptr; char * exasptr; char * muceptr; sprintf (kbaltab, "%lf", kbalval); sprintf (bbaltab, "%lf", kbalval); vertnbr = MAX (2000 * procnbr, 10000); vertnbr = MIN (vertnbr, 100000); sprintf (verttab, GNUMSTRING, vertnbr); strcpy (bufftab, "r{bal=,sep=m{vert=,asc=b{bnd=,org=},low=q{strat=(m{vert=80,low=h{pass=10}f{bal=,move=80},asc=b{bnd=f{bal=,move=80},org=f{bal=,move=80}}})},seq=q{strat=(m{vert=80,low=h{pass=10}f{bal=,move=80},asc=b{bnd=f{bal=,move=80},org=f{bal=,move=80}}})}},seq=r{bal=,poli=S,sep=(m{vert=80,low=h{pass=10}f{bal=,move=80},asc=b{bnd=f{bal=,move=80},org=f{bal=,move=80}}})}}"); stringSubst (bufftab, "", ((flagval & SCOTCH_STRATSPEED) != 0) ? "" : "m{vert=80,low=h{pass=10}f{bal=,move=80},asc=b{bnd=f{bal=,move=80},org=f{bal=,move=80}}}|"); if ((flagval & SCOTCH_STRATSCALABILITY) != 0) muceptr = "/(edge<10000000)?q{strat=f};"; /* Multi-centralization */ else muceptr = "q{strat=f}"; if ((flagval & SCOTCH_STRATBALANCE) != 0) { exapptr = "x{bal=0}"; exasptr = "f{bal=0}"; } else { exapptr = "x{bal=}"; /* Parallel exactifier */ exasptr = ""; } if ((flagval & SCOTCH_STRATSAFETY) != 0) { difpptr = ""; difsptr = ""; } else { difpptr = "(d{pass=40}|)"; difsptr = "(d{pass=40}|)"; } stringSubst (bufftab, "", muceptr); stringSubst (bufftab, "", exapptr); stringSubst (bufftab, "", exasptr); stringSubst (bufftab, "", difpptr); stringSubst (bufftab, "", difsptr); stringSubst (bufftab, "", bbaltab); stringSubst (bufftab, "", kbaltab); stringSubst (bufftab, "", verttab); if (SCOTCH_stratDgraphMap (stratptr, bufftab) != 0) { errorPrint ("SCOTCH_stratDgraphMapBuild: error in parallel mapping strategy"); return (1); } return (0); } /*+ This routine provides predefined *** clustering strategies. *** It returns: *** - 0 : if string successfully initialized. *** - !0 : on error. +*/ int SCOTCH_stratDgraphClusterBuild ( SCOTCH_Strat * const stratptr, /*+ Strategy to create +*/ const SCOTCH_Num flagval, /*+ Desired characteristics +*/ const SCOTCH_Num procnbr, /*+ Number of processes for running +*/ const SCOTCH_Num pwgtval, /*+ Threshold part load +*/ const double densval, /*+ Threshold density value +*/ const double bbalval) /*+ Maximum imbalance ratio +*/ { char bufftab[8192]; /* Should be enough */ char bbaltab[32]; char denstab[32]; char pwgttab[32]; char verttab[32]; Gnum vertnbr; char * difpptr; char * difsptr; char * exapptr; char * exasptr; char * muceptr; sprintf (bbaltab, "%lf", bbalval); sprintf (denstab, "%lf", densval); sprintf (pwgttab, GNUMSTRING, pwgtval); vertnbr = MAX (2000 * procnbr, 10000); vertnbr = MIN (vertnbr, 100000); sprintf (verttab, GNUMSTRING, vertnbr); strcpy (bufftab, "r{sep=/((load>)&!(edge>vert**(vert-1)))?m{vert=,asc=b{bnd=,org=},low=q{strat=(m{vert=80,low=h{pass=10}f{bal=,move=80},asc=b{bnd=f{bal=,move=80},org=f{bal=,move=80}}})},seq=q{strat=/((load>)&!(edge>vert**(vert-1)))?(m{vert=80,low=h{pass=10}f{bal=,move=80},asc=b{bnd=f{bal=,move=80},org=f{bal=,move=80}}});}};,seq=r{sep=/((load>)&!(edge>vert**(vert-1)))?(m{vert=80,low=h{pass=10}f{bal=,move=80},asc=b{bnd=f{bal=,move=80},org=f{bal=,move=80}}});}}"); stringSubst (bufftab, "", ((flagval & SCOTCH_STRATSPEED) != 0) ? "" : "m{vert=80,low=h{pass=10}f{bal=,move=80},asc=b{bnd=f{bal=,move=80},org=f{bal=,move=80}}}|"); if ((flagval & SCOTCH_STRATSCALABILITY) != 0) muceptr = "/(edge<10000000)?q{strat=f};"; /* Multi-centralization */ else muceptr = "q{strat=f}"; if ((flagval & SCOTCH_STRATBALANCE) != 0) { exapptr = "x{bal=0}"; exasptr = "f{bal=0}"; } else { exapptr = "x{bal=}"; /* Parallel exactifier */ exasptr = ""; } if ((flagval & SCOTCH_STRATSAFETY) != 0) { difpptr = ""; difsptr = ""; } else { difpptr = "(d{pass=40}|)"; difsptr = "(d{pass=40}|)"; } stringSubst (bufftab, "", muceptr); stringSubst (bufftab, "", exapptr); stringSubst (bufftab, "", exasptr); stringSubst (bufftab, "", difpptr); stringSubst (bufftab, "", difsptr); stringSubst (bufftab, "", bbaltab); stringSubst (bufftab, "", denstab); stringSubst (bufftab, "", pwgttab); stringSubst (bufftab, "", verttab); if (SCOTCH_stratDgraphMap (stratptr, bufftab) != 0) { errorPrint ("SCOTCH_stratDgraphClusterBuild: error in parallel mapping strategy"); return (1); } return (0); } scotch-6.0.4.dfsg/src/libscotch/vgraph_separate_ml.h0000644002563400244210000001005412220501372025640 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2011,2013 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vgraph_separate_ml.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the multi-level vertex separation **/ /** routines. **/ /** **/ /** DATES : # Version 3.2 : from : 28 oct 1997 **/ /** to 13 sep 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 4.0 : from : 13 dec 2001 **/ /** to 02 feb 2004 **/ /** # Version 6.0 : from : 16 apr 2011 **/ /** to 25 sep 2013 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct VgraphSeparateMlParam_ { INT coarnbr; /*+ Minimum number of vertices +*/ double coarval; /*+ Coarsening ratio +*/ GraphCoarsenType coartype; /*+ Edge matching function type +*/ Strat * stratlow; /*+ Strategy at lowest level +*/ Strat * stratasc; /*+ Strategy at ascending levels +*/ } VgraphSeparateMlParam; /* ** The function prototypes. */ #ifndef VGRAPH_SEPARATE_ML #define static #endif static int vgraphSeparateMlCoarsen (const Vgraph * const, Vgraph * const, GraphCoarsenMulti * restrict * const, const VgraphSeparateMlParam * const); static int vgraphSeparateMlUncoarsen (Vgraph * const, const Vgraph * const, const GraphCoarsenMulti * restrict const); int vgraphSeparateMl (Vgraph * const, const VgraphSeparateMlParam * const); static int vgraphSeparateMl2 (Vgraph * const, const VgraphSeparateMlParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/library_dgraph_induce_f.c0000644002563400244210000000676712055776473026663 0ustar trophimeutilisateurs du domaine/* Copyright 2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_induce_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API for **/ /** the distributed source graph handling **/ /** routines of the libSCOTCH library. **/ /** **/ /** DATES : # Version 6.0 : from : 30 aug 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "ptscotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the distributed graph handling */ /* routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFDGRAPHINDUCEPART, scotchfdgraphinducepart, ( \ SCOTCH_Dgraph * const orggrafptr, \ SCOTCH_Num * const orgpartloctab, \ SCOTCH_Num * const indpartval, \ SCOTCH_Num * const indvertlocnbr, \ SCOTCH_Dgraph * const indgrafptr, \ int * const revaptr), \ (orggrafptr, orgpartloctab, indpartval, indvertlocnbr, indgrafptr, revaptr)) { *revaptr = SCOTCH_dgraphInducePart (orggrafptr, orgpartloctab, *indpartval, *indvertlocnbr, indgrafptr); } scotch-6.0.4.dfsg/src/libscotch/library_mesh_order.c0000644002563400244210000004027512050770207025661 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_mesh_order.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the mesh **/ /** ordering routines of the libSCOTCH **/ /** library. **/ /** **/ /** DATES : # Version 3.2 : from : 19 aug 1998 **/ /** to 22 aug 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 27 mar 1999 **/ /** # Version 4.0 : from : 29 jan 2002 **/ /** to 20 dec 2005 **/ /** # Version 5.0 : from : 04 aug 2007 **/ /** to 31 may 2008 **/ /** # Version 5.1 : from : 29 mar 2010 **/ /** to 14 aug 2010 **/ /** # Version 6.0 : from : 14 nov 2012 **/ /** to 14 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "mesh.h" #include "order.h" #include "hmesh.h" #include "hmesh_order_st.h" #include "library_order.h" #include "scotch.h" /************************************/ /* */ /* These routines are the C API for */ /* the mesh ordering routines. */ /* */ /************************************/ /*+ This routine initializes an API ordering *** with respect to the given source graph *** and the locations of output parameters. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_meshOrderInit ( const SCOTCH_Mesh * const meshptr, /*+ Mesh to order +*/ SCOTCH_Ordering * const ordeptr, /*+ Ordering structure to initialize +*/ SCOTCH_Num * const permtab, /*+ Direct permutation array +*/ SCOTCH_Num * const peritab, /*+ Inverse permutation array +*/ SCOTCH_Num * const cblkptr, /*+ Pointer to number of column blocks +*/ SCOTCH_Num * const rangtab, /*+ Column block range array +*/ SCOTCH_Num * const treetab) /*+ Separator tree array +*/ { Mesh * srcmeshptr; LibOrder * libordeptr; #ifdef SCOTCH_DEBUG_LIBRARY1 if (sizeof (SCOTCH_Ordering) < sizeof (LibOrder)) { errorPrint ("SCOTCH_meshOrderInit: internal error"); return (1); } #endif /* SCOTCH_DEBUG_LIBRARY1 */ srcmeshptr = (Mesh *) meshptr; /* Use structure as source mesh */ libordeptr = (LibOrder *) ordeptr; libordeptr->permtab = ((permtab == NULL) || ((void *) permtab == (void *) meshptr)) ? NULL : (Gnum *) permtab; libordeptr->peritab = ((peritab == NULL) || ((void *) peritab == (void *) meshptr)) ? NULL : (Gnum *) peritab; libordeptr->cblkptr = ((cblkptr == NULL) || ((void *) cblkptr == (void *) meshptr)) ? NULL : (Gnum *) cblkptr; libordeptr->rangtab = ((rangtab == NULL) || ((void *) rangtab == (void *) meshptr)) ? NULL : (Gnum *) rangtab; libordeptr->treetab = ((treetab == NULL) || ((void *) treetab == (void *) meshptr)) ? NULL : (Gnum *) treetab; return (orderInit (&libordeptr->o, srcmeshptr->baseval, srcmeshptr->vnodnbr, libordeptr->peritab)); } /*+ This routine frees an API ordering. *** It returns: *** - VOID : in all cases. +*/ void SCOTCH_meshOrderExit ( const SCOTCH_Mesh * const meshptr, SCOTCH_Ordering * const ordeptr) { orderExit (&((LibOrder *) ordeptr)->o); } /*+ This routine saves the contents of *** the given ordering to the given stream. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_meshOrderSave ( const SCOTCH_Mesh * const meshptr, /*+ Mesh to order +*/ const SCOTCH_Ordering * const ordeptr, /*+ Ordering to save +*/ FILE * const stream) /*+ Output stream +*/ { return (orderSave (&((LibOrder *) ordeptr)->o, ((Mesh *) meshptr)->vlbltax, stream)); } /*+ This routine saves the mapping data *** associated with the given ordering *** to the given stream. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_meshOrderSaveMap ( const SCOTCH_Mesh * const meshptr, /*+ Mesh to order +*/ const SCOTCH_Ordering * const ordeptr, /*+ Ordering to save +*/ FILE * const stream) /*+ Output stream +*/ { return (orderSaveMap (&((LibOrder *) ordeptr)->o, ((Mesh *) meshptr)->vlbltax, stream)); } /*+ This routine saves to the given stream *** the separator tree data associated with *** the given ordering. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_meshOrderSaveTree ( const SCOTCH_Mesh * const meshptr, /*+ Mesh to order +*/ const SCOTCH_Ordering * const ordeptr, /*+ Ordering to save +*/ FILE * const stream) /*+ Output stream +*/ { return (orderSaveTree (&((LibOrder *) ordeptr)->o, ((Mesh *) meshptr)->vlbltax, stream)); } /*+ This routine computes an ordering *** of the API ordering structure with *** respect to the given strategy. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_meshOrderCompute ( SCOTCH_Mesh * const meshptr, /*+ Mesh to order +*/ SCOTCH_Ordering * const ordeptr, /*+ Ordering to compute +*/ SCOTCH_Strat * const stratptr) /*+ Ordering strategy +*/ { return (SCOTCH_meshOrderComputeList (meshptr, ordeptr, 0, NULL, stratptr)); } /*+ This routine computes a partial ordering *** of the listed nodes of the API ordering *** structure mesh with respect to the given *** strategy. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_meshOrderComputeList ( SCOTCH_Mesh * const meshptr, /*+ Mesh to order +*/ SCOTCH_Ordering * const ordeptr, /*+ Ordering to compute +*/ const SCOTCH_Num listnbr, /*+ Number of vertices in list +*/ const SCOTCH_Num * const listtab, /*+ List of vertex indices to order +*/ SCOTCH_Strat * const stratptr) /*+ Ordering strategy +*/ { LibOrder * libordeptr; /* Pointer to ordering */ Mesh * srcmeshptr; /* Pointer to source mesh */ Hmesh srcmeshdat; /* Halo source mesh structure */ VertList srclistdat; /* Subgraph vertex list */ VertList * srclistptr; /* Pointer to subgraph vertex list */ const Strat * ordstratptr; /* Pointer to ordering strategy */ srcmeshptr = (Mesh *) meshptr; #ifdef SCOTCH_DEBUG_MESH2 if (meshCheck (srcmeshptr) != 0) { errorPrint ("SCOTCH_meshOrderComputeList: invalid input mesh"); return (1); } #endif /* SCOTCH_DEBUG_MESH2 */ if (*((Strat **) stratptr) == NULL) /* Set default ordering strategy if necessary */ SCOTCH_stratMeshOrderBuild (stratptr, SCOTCH_STRATQUALITY, 0.1); ordstratptr = *((Strat **) stratptr); if (ordstratptr->tabl != &hmeshorderststratab) { errorPrint ("SCOTCH_meshOrderComputeList: not a mesh ordering strategy"); return (1); } memCpy (&srcmeshdat.m, srcmeshptr, sizeof (Mesh)); /* Copy non-halo mesh data */ srcmeshdat.m.flagval &= ~MESHFREETABS; /* Do not allow to free arrays */ srcmeshdat.vehdtax = srcmeshdat.m.vendtax; /* End of non-halo vertices */ srcmeshdat.veihnbr = 0; /* No halo isolated elements */ srcmeshdat.vnohnbr = srcmeshdat.m.vnodnbr; /* All nodes are non-halo */ srcmeshdat.vnohnnd = srcmeshdat.m.vnodnnd; /* No halo present */ srcmeshdat.vnhlsum = srcmeshdat.m.vnlosum; /* Sum of node vertex weights */ srcmeshdat.enohnbr = srcmeshdat.m.edgenbr; /* All edges are non-halo */ srcmeshdat.levlnum = 0; /* Start from level zero */ libordeptr = (LibOrder *) ordeptr; /* Get ordering */ srclistdat.vnumnbr = (Gnum) listnbr; /* Build vertex list */ srclistdat.vnumtab = (Gnum *) listtab; srclistptr = ((srclistdat.vnumnbr == 0) || (srclistdat.vnumnbr == srcmeshdat.m.vnodnbr)) ? NULL : &srclistdat; /* Is the list really necessary */ if (srclistptr != NULL) { errorPrint ("SCOTCH_meshOrderComputeList: node lists not yet implemented"); return (1); } intRandInit (); /* Check that random number generator is initialized */ hmeshOrderSt (&srcmeshdat, &libordeptr->o, 0, &libordeptr->o.cblktre, ordstratptr); #ifdef SCOTCH_DEBUG_LIBRARY2 orderCheck (&libordeptr->o); #endif /* SCOTCH_DEBUG_LIBRARY2 */ if (libordeptr->permtab != NULL) /* Build direct permutation if wanted */ orderPeri (libordeptr->o.peritab, libordeptr->o.baseval, libordeptr->o.vnodnbr, libordeptr->permtab, libordeptr->o.baseval); if (libordeptr->rangtab != NULL) /* Build range array if column block data wanted */ orderRang (&libordeptr->o, libordeptr->rangtab); if (libordeptr->treetab != NULL) /* Build separator tree array if wanted */ orderTree (&libordeptr->o, libordeptr->treetab); if (libordeptr->cblkptr != NULL) /* Set number of column blocks if wanted */ *(libordeptr->cblkptr) = libordeptr->o.cblknbr; meshExit (&srcmeshdat.m); /* Free in case mesh had been reordered */ return (0); } /*+ This routine computes an ordering *** of the API ordering structure with *** respect to the given strategy. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_meshOrder ( SCOTCH_Mesh * const meshptr, /*+ Mesh to order +*/ SCOTCH_Strat * const stratptr, /*+ Ordering strategy +*/ SCOTCH_Num * const permtab, /*+ Ordering permutation +*/ SCOTCH_Num * const peritab, /*+ Inverse permutation array +*/ SCOTCH_Num * const cblkptr, /*+ Pointer to number of column blocks +*/ SCOTCH_Num * const rangtab, /*+ Column block range array +*/ SCOTCH_Num * const treetab) /*+ Separator tree array +*/ { SCOTCH_Ordering ordedat; int o; SCOTCH_meshOrderInit (meshptr, &ordedat, permtab, peritab, cblkptr, rangtab, treetab); o = SCOTCH_meshOrderCompute (meshptr, &ordedat, stratptr); SCOTCH_meshOrderExit (meshptr, &ordedat); return (o); } /*+ This routine computes an ordering *** of the submesh of the API ordering *** structure mesh induced by the given *** vertex list, with respect to the given *** strategy. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_meshOrderList ( SCOTCH_Mesh * const meshptr, /*+ Mesh to order +*/ const SCOTCH_Num listnbr, /*+ Number of vertices in list +*/ const SCOTCH_Num * const listtab, /*+ List of vertex indices to order +*/ SCOTCH_Strat * const stratptr, /*+ Ordering strategy +*/ SCOTCH_Num * const permtab, /*+ Ordering permutation +*/ SCOTCH_Num * const peritab, /*+ Inverse permutation array +*/ SCOTCH_Num * const cblkptr, /*+ Pointer to number of column blocks +*/ SCOTCH_Num * const rangtab, /*+ Column block range array +*/ SCOTCH_Num * const treetab) /*+ Column block range array +*/ { SCOTCH_Ordering ordedat; int o; SCOTCH_meshOrderInit (meshptr, &ordedat, permtab, peritab, cblkptr, rangtab, treetab); o = SCOTCH_meshOrderComputeList (meshptr, &ordedat, listnbr, listtab, stratptr); SCOTCH_meshOrderExit (meshptr, &ordedat); return (o); } /*+ This routine checks the consistency *** of the given mesh ordering. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_meshOrderCheck ( const SCOTCH_Mesh * const meshptr, const SCOTCH_Ordering * const ordeptr) /*+ Ordering to check +*/ { return (orderCheck (&((LibOrder *) ordeptr)->o)); } /*+ This routine parses the given *** mesh ordering strategy. *** It returns: *** - 0 : if string successfully scanned. *** - !0 : on error. +*/ int SCOTCH_stratMeshOrder ( SCOTCH_Strat * const stratptr, const char * const string) { if (*((Strat **) stratptr) != NULL) stratExit (*((Strat **) stratptr)); if ((*((Strat **) stratptr) = stratInit (&hmeshorderststratab, string)) == NULL) { errorPrint ("SCOTCH_stratMeshOrder: error in ordering strategy"); return (1); } return (0); } /*+ This routine provides predefined *** ordering strategies. *** It returns: *** - 0 : if string successfully initialized. *** - !0 : on error. +*/ int SCOTCH_stratMeshOrderBuild ( SCOTCH_Strat * const stratptr, /*+ Strategy to create +*/ const SCOTCH_Num flagval, /*+ Desired characteristics +*/ const double balrat) /*+ Desired imbalance ratio +*/ { char bufftab[8192]; /* Should be enough */ char bbaltab[32]; strcpy (bufftab, "c{rat=0.7,cpr=n{sep=/(vnod>120)?m{vnod=100,low=h{pass=10},asc=f{bal=}}:;,ole=v{strat=d{cmin=0,cmax=10000000,frat=0}},ose=g},unc=n{sep=/(vnod>120)?m{vnod=100,low=h{pass=10},asc=f{bal=}}:;,ole=v{strat=d{cmin=0,cmax=10000000,frat=0}},ose=g}}"); sprintf (bbaltab, "%lf", balrat); stringSubst (bufftab, "", bbaltab); if (SCOTCH_stratMeshOrder (stratptr, bufftab) != 0) { errorPrint ("SCOTCH_stratMeshOrderBuild: error in sequential ordering strategy"); return (1); } return (0); } scotch-6.0.4.dfsg/src/libscotch/hall_order_hf.h0000644002563400244210000000602111631447170024576 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hall_order_hf.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the block-oriented Halo **/ /** Approximate (Multiple) Minimum Fill **/ /** ordering routine. **/ /** **/ /** DATES : # Version 3.4 : from : 15 may 2001 **/ /** to : 15 may 2001 **/ /** # Version 4.0 : from : 10 jan 2003 **/ /** to : 08 dec 2003 **/ /** **/ /************************************************************/ /* ** The function prototypes. */ #ifndef HALL_ORDER_HF #define static #endif void hallOrderHfR2hamdf4 (const Gnum n, const Gnum nbelts, const Gnum nbbuck, const Gnum iwlen, Gnum pe[], Gnum pfree, Gnum len[], Gnum iw[], Gnum nv[], Gnum elen[], Gnum last[], Gnum * ncmpa, Gnum degree[], Gnum wf[], Gnum next[], Gnum w[], Gnum head[]); #undef static scotch-6.0.4.dfsg/src/libscotch/mesh_coarsen.h0000644002563400244210000001251411631447170024460 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mesh_coarsen.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the source mesh coarsening **/ /** functions. **/ /** **/ /** DATES : # Version 4.0 : from : 19 oct 2003 **/ /** to 04 feb 2004 **/ /** **/ /************************************************************/ /* ** The defines. */ /** Prime number for cache-friendly perturbations. **/ #define MESHCOARSENPERTPRIME 31 /* Prime number */ /** Prime number for hashing vertex numbers. **/ #define MESHCOARSENHASHPRIME 17 /* Prime number */ /* ** The type and structure definitions. */ /*+ Here are the edge matching function types for coarsening. +*/ typedef enum MeshCoarsenType_ { MESHCOARSENNGB, /*+ Most neighbors matching +*/ MESHCOARSENNBR /*+ Number of matching types +*/ } MeshCoarsenType; /*+ A table made of such elements is used during coarsening to build the edge array of the new mesh, after the labeling of the vertices. +*/ typedef struct MeshCoarsenMult_ { Gnum finevelmnum[2]; } MeshCoarsenMult; /*+ A table made of such cells is used during coarsening to build the edge array of the elements of the new mesh. +*/ typedef struct MeshCoarsenHngb_ { Gnum coarvelmnum; /*+ Coarse origin element vertex (i.e. pass) number +*/ Gnum coarvnodnum; /*+ Neighbor fine node vertex number +*/ } MeshCoarsenHngb; /*+ A table made of such cells is used during coarsening to detect and merge bridge nodes, that is, nodes that connect only two coarse nodes together. +*/ typedef struct MeshCoarsenHbdg_ { Gnum coarvelmnum; /*+ Coarse origin element vertex (i.e. pass) number +*/ Gnum coarvelmend; /*+ Coarse end element vertex number +*/ Gnum coarvnodnum; /*+ Number of connecting coarse node +*/ } MeshCoarsenHbdg; /*+ A table made of such elements is used during coarsening to build the edge array of the new mesh, after the labeling of the vertices. +*/ typedef struct MeshCoarsenNgHash_ { Gnum velmnum; /*+ Origin element vertex (i.e. pass) number +*/ Gnum velmend; /*+ End element vertex number in fine mesh +*/ Gnum vnngnbr; /*+ Number of shared neighboring node vertices +*/ Gnum vnbgnbr; /*+ Number of bridge neighboring node vertices +*/ } MeshCoarsenNgHash; /* ** The function prototypes. */ #ifndef MESH_COARSEN #define static #endif int meshCoarsen (const Mesh * restrict const, Mesh * restrict const, Gnum * restrict * const, const Gnum, const double, const MeshCoarsenType); static void meshCoarsenMatchNg (const Mesh * restrict const, MeshCoarsenMult * restrict const, Gnum * restrict const, Gnum * restrict const, Gnum * restrict const, Gnum * restrict const); #undef static scotch-6.0.4.dfsg/src/libscotch/wgraph_part_ml.h0000644002563400244210000000737311631447170025027 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : wgraph_part_ml.h **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Charles-Edmond BICHOT (v5.1b) **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** multilevel framework for the vertex **/ /** overlapped graph partitioning. **/ /** **/ /** DATES : # Version 5.1 : from : 01 dec 2007 **/ /** to : 01 jul 2008 **/ /** # Version 6.0 : from : 05 nov 2009 **/ /** to : 16 apr 2011 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct WgraphPartMlParam_ { INT coarnbr; /*+ Minimum number of vertices per part +*/ double coarval; /*+ Coarsening ratio +*/ Strat * stratlow; /*+ Strategy at lowest level +*/ Strat * stratasc; /*+ Strategy at ascending levels +*/ } WgraphPartMlParam; /* ** The function prototypes. */ #ifndef WGRAPH_PART_ML #define static #endif static int wgraphPartMlCoarsen (const Wgraph * const, Wgraph * const, GraphCoarsenMulti * restrict * const, const WgraphPartMlParam * const); static int wgraphPartMlUncoarsen (Wgraph * const, const Wgraph * const, const GraphCoarsenMulti * restrict const); int wgraphPartMl (Wgraph * const, const WgraphPartMlParam * const); static int wgraphPartMl2 (Wgraph * const, const WgraphPartMlParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/hgraph_order_hx.c0000644002563400244210000001200711631447171025146 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hgraph_order_hx.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains service routines **/ /** for the hgraphOrderH{d|f} ordering **/ /** routines. **/ /** **/ /** DATES : # Version 4.0 : from : 23 jan 2004 **/ /** to : 28 jan 2004 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HGRAPH_ORDER_HX #include "module.h" #include "common.h" #include "graph.h" #include "hgraph.h" #include "hgraph_order_hx.h" /***********************************/ /* */ /* These are the service routines. */ /* */ /***********************************/ /* This routine fills the input arrays for ** the graph ordering routines. ** It returns: ** - void : in all cases. */ void hgraphOrderHxFill ( const Hgraph * restrict const grafptr, Gnum * restrict const petab, Gnum * restrict const lentab, Gnum * restrict const iwtab, Gnum * restrict const elentab, Gnum * restrict const pfreptr) { Gnum * restrict petax; Gnum * restrict iwtax; Gnum * restrict lentax; Gnum * restrict elentax; Gnum vertadj; /* Index adjustment for vertices */ Gnum vertnum; Gnum vertnew; Gnum edgenew; petax = petab - 1; /* Base HAMF arrays at base 1 */ iwtax = iwtab - 1; lentax = lentab - 1; elentax = elentab - 1; vertadj = 1 - grafptr->s.baseval; for (vertnum = grafptr->s.baseval, vertnew = edgenew = 1; /* Process non-halo vertices */ vertnum < grafptr->vnohnnd; vertnum ++, vertnew ++) { Gnum degrval; Gnum edgenum; degrval = grafptr->s.vendtax[vertnum] - grafptr->s.verttax[vertnum]; petax[vertnew] = edgenew; lentax[vertnew] = degrval; elentax[vertnew] = degrval; for (edgenum = grafptr->s.verttax[vertnum]; edgenum < grafptr->s.vendtax[vertnum]; edgenum ++, edgenew ++) iwtax[edgenew] = grafptr->s.edgetax[edgenum] + vertadj; } for ( ; vertnum < grafptr->s.vertnnd; vertnum ++, vertnew ++) { /* Process halo vertices */ Gnum degrval; Gnum edgenum; degrval = grafptr->s.verttax[vertnum] - grafptr->s.vendtax[vertnum]; petax[vertnew] = edgenew; lentax[vertnew] = (degrval != 0) ? degrval : (-1 - grafptr->s.vertnbr); elentax[vertnew] = 0; for (edgenum = grafptr->s.verttax[vertnum]; edgenum < grafptr->s.vendtax[vertnum]; edgenum ++, edgenew ++) iwtax[edgenew] = grafptr->s.edgetax[edgenum] + vertadj; } *pfreptr = edgenew; /* Set index to first free area */ } scotch-6.0.4.dfsg/src/libscotch/dgraph_io_save.c0000644002563400244210000001671112216517420024756 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2010,2013 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_io.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Cedric CHEVALIER **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the input/output routines for **/ /** distributed graphs. **/ /** **/ /** # Version P0.2 : from : 11 may 1999 **/ /** to 12 may 1999 **/ /** # Version 5.0 : from : 22 jul 2005 **/ /** to : 22 apr 2008 **/ /** # Version 5.1 : from : 11 aug 2010 **/ /** to : 11 aug 2010 **/ /** # Version 6.0 : from : 18 sep 2013 **/ /** to : 18 sep 2013 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DGRAPH_IO #include "module.h" #include "common.h" #include "dgraph.h" /* This routine saves a distributed source ** graph to the given streams. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int dgraphSave ( Dgraph * restrict const grafptr, /* Not const since halo may update structure */ FILE * const stream) { Gnum * restrict vlblgsttax; /* Based index to ghost label array */ Gnum vertlocnum; char propstr[4]; /* Property string */ int o; #ifdef SCOTCH_DEBUG_DGRAPH2 if (MPI_Barrier (grafptr->proccomm) != MPI_SUCCESS) { /* Synchronize for debugging */ errorPrint ("dgraphSave: communication error"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ vlblgsttax = NULL; /* Assume ghost label array is free */ if ((grafptr->vlblloctax != NULL) || /* If graph has vertex labels or */ (grafptr->edgeloctax == NULL) || /* If no global index edge array present or */ (grafptr->procvrttab[grafptr->procglbnbr] != grafptr->procdsptab[grafptr->procglbnbr])) { /* If graph may have holes in its numbering */ if (dgraphGhst (grafptr) != 0) { /* Compute ghost edge array */ errorPrint ("dgraphSave: cannot compute ghost edge array"); return (1); } if ((vlblgsttax = (Gnum *) memAlloc (grafptr->vertgstnbr * sizeof (Gnum))) == NULL) { errorPrint ("dgraphSave: out of memory"); return (1); } if (grafptr->vlblloctax != NULL) memCpy (vlblgsttax, grafptr->vlblloctax + grafptr->baseval, grafptr->vertlocnbr * sizeof (Gnum)); else { for (vertlocnum = 0; vertlocnum < grafptr->vertlocnbr; vertlocnum ++) /* vlblgsttax is not based yet at this time */ vlblgsttax[vertlocnum] = grafptr->procvrttab[grafptr->proclocnum] + vertlocnum; } if (dgraphHaloSync (grafptr, (byte *) vlblgsttax, GNUM_MPI) != 0) { /* vlblgsttax is not based yet at this time */ errorPrint ("dgraphSave: cannot halo labels"); memFree (vlblgsttax); return (1); } vlblgsttax -= grafptr->baseval; } propstr[0] = (vlblgsttax != NULL) ? '1' : '0'; /* Set property string */ propstr[1] = (grafptr->edloloctax != NULL) ? '1' : '0'; propstr[2] = (grafptr->veloloctax != NULL) ? '1' : '0'; propstr[3] = '\0'; if (fprintf (stream, "2\n" GNUMSTRING "\t" GNUMSTRING "\n" GNUMSTRING "\t" GNUMSTRING "\n" GNUMSTRING "\t" GNUMSTRING "\n" GNUMSTRING "\t%3s\n", /* Write file header */ (Gnum) grafptr->procglbnbr, (Gnum) grafptr->proclocnum, (Gnum) grafptr->vertglbnbr, (Gnum) grafptr->edgeglbnbr, (Gnum) grafptr->vertlocnbr, (Gnum) grafptr->edgelocnbr, (Gnum) grafptr->baseval, propstr) == EOF) { errorPrint ("dgraphSave: bad output (1)"); return (1); } o = 0; for (vertlocnum = grafptr->baseval; (vertlocnum < grafptr->vertlocnnd) && (o == 0); vertlocnum ++) { Gnum edgelocnum; if (vlblgsttax != NULL) /* Write vertex label if necessary */ o = (fprintf (stream, GNUMSTRING "\t", (Gnum) vlblgsttax[vertlocnum]) == EOF); if (grafptr->veloloctax != NULL) /* Write vertex load if necessary */ o |= (fprintf (stream, GNUMSTRING "\t", (Gnum) grafptr->veloloctax[vertlocnum]) == EOF); o |= (fprintf (stream, GNUMSTRING, (Gnum) (grafptr->vendloctax[vertlocnum] - grafptr->vertloctax[vertlocnum])) == EOF); /* Write vertex degree */ for (edgelocnum = grafptr->vertloctax[vertlocnum]; edgelocnum < grafptr->vendloctax[vertlocnum]; edgelocnum ++) { o |= (putc ('\t', stream) == EOF); if (grafptr->edloloctax != NULL) /* Write edge load if necessary */ o |= (fprintf (stream, "\t" GNUMSTRING " ", (Gnum) grafptr->edloloctax[edgelocnum]) == EOF); o |= (fprintf (stream, GNUMSTRING, (Gnum) ((vlblgsttax != NULL) /* Write edge end */ ? vlblgsttax[grafptr->edgegsttax[edgelocnum]] : grafptr->edgeloctax[edgelocnum])) == EOF); } o |= (putc ('\n', stream) == EOF); } if (o != 0) errorPrint ("dgraphSave: bad output (2)"); if (vlblgsttax != NULL) /* Free ghost label array if used */ memFree (vlblgsttax + grafptr->baseval); return (o); } scotch-6.0.4.dfsg/src/libscotch/library_mapping.h0000644002563400244210000000655412376052424025201 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010,2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_mapping.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the library ordering **/ /** structure. **/ /** **/ /** DATES : # Version 4.0 : from : 28 jun 2004 **/ /** to 28 jun 2004 **/ /** # Version 5.1 : from : 04 nov 2010 **/ /** to 17 nov 2010 **/ /** # Version 6.0 : from : 15 apr 2011 **/ /** to 23 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ User mapping option flags. +*/ #define LIBMAPPINGNONE 0x0000 /* No options set */ #define LIBMAPPINGFREEPART 0x0001 /* Free parttab array */ /* ** The type and structure definitions. */ /*+ User mapping. +*/ typedef struct LibMapping_ { Gnum flagval; Graph * grafptr; /*+ Graph data +*/ Arch * archptr; /*+ Architecture data +*/ Gnum * parttab; /*+ Mapping array +*/ } LibMapping; scotch-6.0.4.dfsg/src/libscotch/dgraph_fold.c0000644002563400244210000011004012412035044024236 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_fold.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles the distributed **/ /** source graph folding function. **/ /** **/ /** DATES : # Version 5.0 : from : 10 aug 2006 **/ /** to : 27 jun 2008 **/ /** # Version 5.1 : from : 12 nov 2008 **/ /** to : 04 jan 2011 **/ /** # Version 6.0 : from : 28 sep 2014 **/ /** to : 28 sep 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DGRAPH #include "module.h" #include "common.h" #include "dgraph.h" #include "dgraph_fold.h" #include "dgraph_fold_comm.h" /******************************/ /* */ /* This routine handles */ /* distributed source graphs. */ /* */ /******************************/ /* This routine builds a folded graph by merging graph ** data to the processes of the first half or to the ** second half of the communicator. ** The key value of the folded communicator is not ** changed as it is not relevant. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int dgraphFold ( const Dgraph * restrict const orggrafptr, const int partval, /* 0 for first half, 1 for second half */ Dgraph * restrict const fldgrafptr, const void * restrict const orgdataptr, /* Un-based array of data which must be folded, e.g. coarmulttab */ void ** restrict const flddataptr, /* Un-based array of data which must be folded, e.g. coarmulttab */ MPI_Datatype datatype) { int fldprocnbr; int fldprocnum; /* Index of local process in folded communicator */ int fldproccol; /* Color of receiver or not wanted in communicator */ MPI_Comm fldproccomm; /* Communicator of folded part */ int o; fldprocnbr = (orggrafptr->procglbnbr + 1) / 2; fldprocnum = orggrafptr->proclocnum; if (partval == 1) { fldprocnum = fldprocnum - fldprocnbr; fldprocnbr = orggrafptr->procglbnbr - fldprocnbr; } fldproccol = ((fldprocnum >= 0) && (fldprocnum < fldprocnbr)) ? 0 : MPI_UNDEFINED; if (MPI_Comm_split (orggrafptr->proccomm, fldproccol, fldprocnum, &fldproccomm) != MPI_SUCCESS) { errorPrint ("dgraphFold: communication error"); return (1); } o = dgraphFold2 (orggrafptr, partval, fldgrafptr, fldproccomm, orgdataptr, flddataptr, datatype); fldgrafptr->prockeyval = fldproccol; /* Key of folded communicator is always zero if no duplication occurs */ return (o); } int dgraphFold2 ( const Dgraph * restrict const orggrafptr, const int partval, /* 0 for first half, 1 for second half */ Dgraph * restrict const fldgrafptr, MPI_Comm fldproccomm, const void * restrict const orgdataptr, /* Un-based array of data which must be kept, e.g. coarmulttab */ void ** restrict const flddataptr, /* Un-based array of data which must be kept, e.g. coarmulttab */ MPI_Datatype datatype) { int fldcommtypval; /* Type of communication for this process */ DgraphFoldCommData * restrict fldcommdattab; /* Array of two communication data */ Gnum * restrict fldcommvrttab; /* Starting global send indices of communications */ Gnum * restrict fldvertidxtab; /* Start indices of vertex arrays */ Gnum * restrict fldedgeidxtab; /* Start indices of edge arrays */ Gnum * restrict fldedgecnttab; /* Number of edges exchanged during each communication */ Gnum * restrict fldedgecnptab; /* Temporary save for fldedgecnttab for MPI standard */ Gnum fldvertlocnbr; /* Number of vertices in local folded part */ Gnum fldedgelocsiz; /* (Upper bound of) number of edges in folded graph */ Gnum fldedlolocsiz; /* (Upper bound of) number of edge loads in folded graph */ int fldprocglbnbr; int fldproclocnum; /* Index of local process in folded communicator */ int fldvertadjnbr; Gnum * restrict fldvertadjtab; /* Array of global start indices for adjustment slots */ Gnum * restrict fldvertdlttab; /* Array of index adjustments for original global indices */ int cheklocval; int chekglbval; int commmax; int commnbr; int requnbr; MPI_Request * restrict requtab; int infosiz; /* Size of one information */ #ifdef SCOTCH_DEBUG_DGRAPH2 if (orggrafptr->vendloctax != (orggrafptr->vertloctax + 1)) { errorPrint ("dgraphFold2: graph must be compact"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ fldprocglbnbr = (orggrafptr->procglbnbr + 1) / 2; if (partval == 1) { fldproclocnum = orggrafptr->proclocnum - fldprocglbnbr; fldprocglbnbr = orggrafptr->procglbnbr - fldprocglbnbr; } else fldproclocnum = orggrafptr->proclocnum; fldcommtypval = ((fldproclocnum >= 0) && (fldproclocnum < fldprocglbnbr)) ? DGRAPHFOLDCOMMRECV : DGRAPHFOLDCOMMSEND; if (orgdataptr != NULL) MPI_Type_size (datatype, &infosiz); cheklocval = 0; fldcommdattab = NULL; fldvertidxtab = NULL; if (fldcommtypval == DGRAPHFOLDCOMMRECV) { /* If we are going to receive */ #ifdef SCOTCH_DEBUG_DGRAPH2 if (fldgrafptr == NULL) { errorPrint ("dgraphFold2: invalid parameters (1)"); return (1); } if (fldproccomm == MPI_COMM_NULL) { errorPrint ("dgraphFold2: invalid parameters (2)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ memSet (fldgrafptr, 0, sizeof (Dgraph)); /* Pre-initialize graph fields */ fldgrafptr->proccomm = fldproccomm; fldgrafptr->procglbnbr = fldprocglbnbr; fldgrafptr->proclocnum = fldproclocnum; fldgrafptr->flagval = DGRAPHFREEALL | DGRAPHVERTGROUP | DGRAPHEDGEGROUP; /* For premature freeing on error */ if (memAllocGroup ((void **) (void *) /* Allocate distributed graph private data */ &fldgrafptr->procdsptab, (size_t) ((fldprocglbnbr + 1) * sizeof (Gnum)), &fldgrafptr->proccnttab, (size_t) (fldprocglbnbr * sizeof (Gnum)), &fldgrafptr->procngbtab, (size_t) (fldprocglbnbr * sizeof (int)), &fldgrafptr->procrcvtab, (size_t) (fldprocglbnbr * sizeof (int)), &fldgrafptr->procsndtab, (size_t) (fldprocglbnbr * sizeof (int)), NULL) == NULL) { errorPrint ("dgraphFold2: out of memory (1)"); cheklocval = 1; } else if (dgraphFoldComm (orggrafptr, partval, &commmax, &fldcommtypval, &fldcommdattab, &fldcommvrttab, /* Process can become a sender receiver */ fldgrafptr->proccnttab, &fldvertadjnbr, &fldvertadjtab, &fldvertdlttab) != 0) { errorPrint ("dgraphFold2: cannot compute folding communications (1)"); cheklocval = 1; } else { Gnum fldvelolocnbr; if ((fldcommtypval & DGRAPHFOLDCOMMSEND) == 0) { /* If process is a normal receiver */ int i; for (i = 0, fldvertlocnbr = 0; (i < commmax) && (fldcommdattab[i].procnum != -1); i ++) fldvertlocnbr += fldcommdattab[i].vertnbr; commnbr = i; fldedgelocsiz = orggrafptr->edgeglbsmx * i; /* Upper bound on received edges */ if ((orggrafptr->degrglbmax > 0) && (fldvertlocnbr < (fldedgelocsiz / orggrafptr->degrglbmax))) /* Choose best upper bound on number of edges (avoid multiply overflow) */ fldedgelocsiz = fldvertlocnbr * orggrafptr->degrglbmax; fldedgelocsiz += orggrafptr->edgelocnbr; /* Add local edges and vertices */ fldvertlocnbr += orggrafptr->vertlocnbr; } else { /* Process is a sender receiver */ fldvertlocnbr = fldcommvrttab[0] - orggrafptr->procvrttab[orggrafptr->proclocnum]; /* Communications will remove vertices */ fldedgelocsiz = orggrafptr->vertloctax[fldvertlocnbr + orggrafptr->baseval] - orggrafptr->baseval; /* Exact number of edges */ fldgrafptr->edgelocnbr = fldgrafptr->edgelocsiz = fldedgelocsiz; } fldvelolocnbr = (orggrafptr->veloloctax != NULL) ? fldvertlocnbr : 0; if (memAllocGroup ((void **) (void *) /* Allocate distributed graph public data */ &fldgrafptr->vertloctax, (size_t) ((fldvertlocnbr + 1) * sizeof (Gnum)), &fldgrafptr->vnumloctax, (size_t) ( fldvertlocnbr * sizeof (Gnum)), &fldgrafptr->veloloctax, (size_t) ( fldvelolocnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("dgraphFold2: out of memory (2)"); cheklocval = 1; } else if (fldgrafptr->vertloctax -= orggrafptr->baseval, fldgrafptr->vnumloctax -= orggrafptr->baseval, fldgrafptr->vendloctax = fldgrafptr->vertloctax + 1, /* Folded graph is compact */ fldgrafptr->veloloctax = ((orggrafptr->veloloctax != NULL) ? (fldgrafptr->veloloctax - orggrafptr->baseval) : NULL), fldedlolocsiz = ((orggrafptr->edloloctax != NULL) ? fldedgelocsiz : 0), (fldgrafptr->edgeloctax = memAlloc ((fldedgelocsiz + fldedlolocsiz) * sizeof (Gnum))) == NULL) { /* Allocate single array for both edge arrays */ errorPrint ("dgraphFold2: out of memory (3)"); cheklocval = 1; } else { if (orgdataptr != NULL) { if ((*flddataptr = (byte *) memAlloc (fldvertlocnbr * infosiz)) == NULL) { errorPrint ("dgraphFold2: out of memory (4)"); cheklocval = 1; } } fldgrafptr->edgeloctax -= orggrafptr->baseval; /* Do not care about the validity of edloloctax at this stage */ } } } else { /* Process is a sender */ #ifdef SCOTCH_DEBUG_HDGRAPH2 if (fldproccomm != MPI_COMM_NULL) { errorPrint ("dgraphFold2: invalid parameters (3)"); return (1); } #endif /* SCOTCH_DEBUG_HDGRAPH2 */ if (dgraphFoldComm (orggrafptr, partval, &commmax, &fldcommtypval, &fldcommdattab, &fldcommvrttab, NULL, NULL, NULL, NULL) != 0) { errorPrint ("dgraphFold2: cannot compute folding communications (2)"); cheklocval = 1; } } if ((cheklocval == 0) && (memAllocGroup ((void **) (void *) /* Allocate folding data */ &fldvertidxtab, (size_t) (commmax * sizeof (Gnum)), &fldedgeidxtab, (size_t) (commmax * sizeof (Gnum)), &fldedgecnttab, (size_t) (commmax * sizeof (Gnum)), &fldedgecnptab, (size_t) (commmax * sizeof (Gnum)), &requtab, (size_t) (commmax * DGRAPHFOLDTAGNBR * sizeof (MPI_Request)), NULL) == NULL)) { errorPrint ("dgraphFold2: out of memory (5)"); cheklocval = 1; } #ifdef SCOTCH_DEBUG_DGRAPH1 /* Communication cannot be merged with a useful one */ if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, orggrafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphFold2: communication error (1)"); chekglbval = 1; } #else /* SCOTCH_DEBUG_DGRAPH1 */ chekglbval = cheklocval; #endif /* SCOTCH_DEBUG_DGRAPH1 */ if (chekglbval != 0) { if ((fldcommtypval & DGRAPHFOLDCOMMRECV) != 0) { if (fldvertidxtab != NULL) memFree (fldvertidxtab); /* Free group leader */ if (fldcommdattab != NULL) memFree (fldcommdattab); dgraphExit (fldgrafptr); } return (1); } requnbr = 0; /* Communications without further processing are placed at beginning of array */ if ((fldcommtypval & DGRAPHFOLDCOMMSEND) != 0) { /* If process is (also) a sender */ Gnum vertsndbas; Gnum vertsndnbr; int i; vertsndnbr = ((fldcommtypval & DGRAPHFOLDCOMMRECV) != 0) ? (fldcommvrttab[0] - orggrafptr->procvrttab[orggrafptr->proclocnum]) : 0; /* If process is also a receiver, start sending after kept vertices */ for (i = 0, vertsndbas = orggrafptr->baseval; /* For all send communications to perform */ (i < commmax) && (fldcommdattab[i].procnum != -1) && (cheklocval == 0); i ++) { vertsndbas += vertsndnbr; vertsndnbr = fldcommdattab[i].vertnbr; fldvertidxtab[i] = vertsndbas; fldedgeidxtab[i] = orggrafptr->vertloctax[vertsndbas]; fldedgecnptab[i] = /* Save fldedgecnttab in temporary array to read it while MPI communication in progress */ fldedgecnttab[i] = orggrafptr->vertloctax[vertsndbas + vertsndnbr] - orggrafptr->vertloctax[vertsndbas]; /* Graph is compact */ if (MPI_Isend (&fldedgecnptab[i], 1, GNUM_MPI, fldcommdattab[i].procnum, TAGFOLD + TAGVLBLLOCTAB, orggrafptr->proccomm, &requtab[requnbr ++]) != MPI_SUCCESS) { errorPrint ("dgraphFold2: communication error (2)"); cheklocval = 1; } } commnbr = i; for (i = 0; (i < commnbr) && (cheklocval == 0); i ++) { if (MPI_Isend (orggrafptr->vertloctax + fldvertidxtab[i], fldcommdattab[i].vertnbr, GNUM_MPI, fldcommdattab[i].procnum, TAGFOLD + TAGVERTLOCTAB, orggrafptr->proccomm, &requtab[requnbr ++]) != MPI_SUCCESS) { errorPrint ("dgraphFold2: communication error (3)"); cheklocval = 1; } } for (i = 0; (i < commnbr) && (cheklocval == 0); i ++) { if (MPI_Isend (orggrafptr->edgeloctax + fldedgeidxtab[i], fldedgecnttab[i], GNUM_MPI, fldcommdattab[i].procnum, TAGFOLD + TAGEDGELOCTAB, orggrafptr->proccomm, &requtab[requnbr ++]) != MPI_SUCCESS) { errorPrint ("dgraphFold2: communication error (4)"); cheklocval = 1; } } if (orggrafptr->veloloctax != NULL) { for (i = 0; (i < commnbr) && (cheklocval == 0); i ++) { if (MPI_Isend (orggrafptr->veloloctax + fldvertidxtab[i], fldcommdattab[i].vertnbr, GNUM_MPI, fldcommdattab[i].procnum, TAGFOLD + TAGVELOLOCTAB, orggrafptr->proccomm, &requtab[requnbr ++]) != MPI_SUCCESS) { errorPrint ("dgraphFold2: communication error (5)"); cheklocval = 1; } } } for (i = 0; (i < commnbr) && (cheklocval == 0); i ++) { int procsndnum; /* Rank of process to send to */ procsndnum = fldcommdattab[i].procnum; if ((orggrafptr->edloloctax != NULL) && (MPI_Isend (orggrafptr->edloloctax + fldedgeidxtab[i], fldedgecnttab[i], GNUM_MPI, procsndnum, TAGFOLD + TAGEDLOLOCTAB, orggrafptr->proccomm, &requtab[requnbr ++]) != MPI_SUCCESS)) { errorPrint ("dgraphFold2: communication error (6)"); cheklocval = 1; } else if ((orggrafptr->vnumloctax != NULL) && (MPI_Isend (orggrafptr->vnumloctax + fldvertidxtab[i], fldcommdattab[i].vertnbr, GNUM_MPI, procsndnum, TAGFOLD + TAGVNUMLOCTAB, orggrafptr->proccomm, &requtab[requnbr ++]) != MPI_SUCCESS)) { errorPrint ("dgraphFold2: communication error (7)"); cheklocval = 1; } else if ((orgdataptr != NULL) && (MPI_Isend ((byte *) orgdataptr + ((fldvertidxtab[i] - orggrafptr->baseval) * infosiz), fldcommdattab[i].vertnbr, datatype, procsndnum, TAGFOLD + TAGDATALOCTAB, orggrafptr->proccomm, &requtab[requnbr ++]) != MPI_SUCCESS)) { errorPrint ("dgraphFold2: communication error (8)"); cheklocval = 1; } } } /* Communications of sender-receivers will be completed in the receiving phase */ if ((fldcommtypval & DGRAPHFOLDCOMMRECV) != 0) { /* If process is (also) a receiver */ Gnum orgvertlocnbr; Gnum orgvertlocnnd; Gnum orgvertlocmin; Gnum orgvertlocmax; Gnum fldvertlocadj; Gnum fldvelolocsum; Gnum fldedgelocnum; Gnum fldedgelocnnd; int fldprocnum; int procngbmin; int procngbmax; int i; const Gnum * restrict const orgedgeloctax = orggrafptr->edgeloctax; Gnum * restrict const fldedgeloctax = fldgrafptr->edgeloctax; fldgrafptr->procvrttab = fldgrafptr->procdsptab; /* Graph does not have holes */ fldgrafptr->procdsptab[0] = orggrafptr->baseval; /* Build private data of folded graph and array */ for (fldprocnum = 0; fldprocnum < fldprocglbnbr; fldprocnum ++) /* New subdomain indices start from baseval */ fldgrafptr->procdsptab[fldprocnum + 1] = fldgrafptr->procdsptab[fldprocnum] + fldgrafptr->proccnttab[fldprocnum]; if ((fldcommtypval & DGRAPHFOLDCOMMSEND) == 0) { /* If process is a normal receiver */ Gnum fldedgelocbas; Gnum fldvertrcvbas; Gnum fldvertrcvnbr; for (i = 0, fldvertrcvbas = orggrafptr->vertlocnnd, fldvertrcvnbr = 0; /* For all receive communications to perform */ (i < commnbr) && (cheklocval == 0); i ++) { fldvertrcvbas += fldvertrcvnbr; fldvertrcvnbr = fldcommdattab[i].vertnbr; fldvertidxtab[i] = fldvertrcvbas; if (MPI_Irecv (&fldedgecnttab[i], 1, GNUM_MPI, fldcommdattab[i].procnum, TAGFOLD + TAGVLBLLOCTAB, orggrafptr->proccomm, &requtab[DGRAPHFOLDTAGENBR * commmax + i]) != MPI_SUCCESS) { errorPrint ("dgraphFold2: communication error (9)"); cheklocval = 1; } } for (i = 0; (i < commnbr) && (cheklocval == 0); i ++) { /* Let these communications progress while we process the edge size messages */ if (MPI_Irecv (fldgrafptr->vertloctax + fldvertidxtab[i], fldcommdattab[i].vertnbr, GNUM_MPI, fldcommdattab[i].procnum, TAGFOLD + TAGVERTLOCTAB, orggrafptr->proccomm, &requtab[DGRAPHFOLDTAGVERT * commmax + i]) != MPI_SUCCESS) { errorPrint ("dgraphFold2: communication error (10)"); cheklocval = 1; } } MPI_Waitall (commnbr, &requtab[DGRAPHFOLDTAGENBR * commmax], MPI_STATUSES_IGNORE); for (i = 0, fldedgelocbas = orggrafptr->vertloctax[orggrafptr->vertlocnnd]; (i < commnbr) && (cheklocval == 0); i ++) { fldedgeidxtab[i] = fldedgelocbas; fldedgelocbas += fldedgecnttab[i]; if (MPI_Irecv (fldgrafptr->edgeloctax + fldedgeidxtab[i], fldedgecnttab[i], GNUM_MPI, fldcommdattab[i].procnum, TAGFOLD + TAGEDGELOCTAB, orggrafptr->proccomm, &requtab[DGRAPHFOLDTAGEDGE * commmax + i]) != MPI_SUCCESS) { errorPrint ("dgraphFold2: communication error (11)"); cheklocval = 1; } } fldgrafptr->edgelocnbr = /* Get number of local edges */ fldgrafptr->edgelocsiz = fldedgelocbas - orggrafptr->baseval; if (orggrafptr->veloloctax != NULL) { for (i = 0; (i < commnbr) && (cheklocval == 0); i ++) { if (MPI_Irecv (fldgrafptr->veloloctax + fldvertidxtab[i], fldcommdattab[i].vertnbr, GNUM_MPI, fldcommdattab[i].procnum, TAGFOLD + TAGVELOLOCTAB, orggrafptr->proccomm, &requtab[DGRAPHFOLDTAGVELO * commmax + i]) != MPI_SUCCESS) { errorPrint ("dgraphFold2: communication error (12)"); cheklocval = 1; } } } if (orggrafptr->edloloctax != NULL) { fldgrafptr->edloloctax = fldgrafptr->edgeloctax + fldgrafptr->edgelocnbr; /* Set start index of edge load array */ for (i = 0; (i < commnbr) && (cheklocval == 0); i ++) { if (MPI_Irecv (fldgrafptr->edloloctax + fldedgeidxtab[i], fldedgecnttab[i], GNUM_MPI, fldcommdattab[i].procnum, TAGFOLD + TAGEDLOLOCTAB, orggrafptr->proccomm, &requtab[DGRAPHFOLDTAGEDLO * commmax + i]) != MPI_SUCCESS) { errorPrint ("dgraphFold2: communication error (13)"); cheklocval = 1; } } } for (i = 0; (i < commnbr) && (cheklocval == 0); i ++) { int procrcvnum; /* Rank of process to receive from */ Gnum vertrcvnbr; procrcvnum = fldcommdattab[i].procnum; vertrcvnbr = fldcommdattab[i].vertnbr; if ((orggrafptr->vnumloctax != NULL) && (MPI_Irecv (fldgrafptr->vnumloctax + fldvertidxtab[i], vertrcvnbr, GNUM_MPI, procrcvnum, TAGFOLD + TAGVNUMLOCTAB, orggrafptr->proccomm, &requtab[requnbr ++]) != MPI_SUCCESS)) { errorPrint ("dgraphFold2: communication error (14)"); cheklocval = 1; } else if ((orgdataptr != NULL) && (MPI_Irecv ((byte *) (*flddataptr) + ((fldvertidxtab[i] - orggrafptr->baseval) * infosiz), vertrcvnbr, datatype, procrcvnum, TAGFOLD + TAGDATALOCTAB, orggrafptr->proccomm, &requtab[requnbr ++]) != MPI_SUCCESS)) { errorPrint ("dgraphFold2: communication error (15)"); cheklocval = 1; } } orgvertlocnbr = orggrafptr->vertlocnbr; /* Process all local vertices */ orgvertlocnnd = orggrafptr->vertlocnnd; if (orggrafptr->vnumloctax == NULL) { /* If original graph does not have vertex numbers, create remote parts of vertex number array */ Gnum fldvertlocnum; Gnum fldvertlocadj; int i; Gnum * restrict const fldvnumloctax = fldgrafptr->vnumloctax; for (i = 0, fldvertlocnum = orgvertlocnnd; i < commnbr; i ++) { Gnum fldvertlocnnd; for (fldvertlocnnd = fldvertlocnum + fldcommdattab[i].vertnbr, fldvertlocadj = fldcommvrttab[i]; fldvertlocnum < fldvertlocnnd; fldvertlocnum ++) fldvnumloctax[fldvertlocnum] = fldvertlocadj ++; } } fldedgelocnnd = orggrafptr->vertloctax[orggrafptr->vertlocnnd]; fldvelolocsum = orggrafptr->velolocsum; /* In case there are vertex loads, we keep all of existing load */ } else { /* Receiver process is also a sender */ orgvertlocnbr = fldvertlocnbr; /* Process only remaining local vertices */ orgvertlocnnd = fldvertlocnbr + orggrafptr->baseval; if (orggrafptr->veloloctax != NULL) { /* If original graph has vertex loads */ Gnum fldvertlocnum; for (fldvertlocnum = orggrafptr->baseval, fldvelolocsum = 0; /* Accumulate load sum of remaining part */ fldvertlocnum < orgvertlocnnd; fldvertlocnum ++) fldvelolocsum += orggrafptr->veloloctax[fldvertlocnum]; } fldedgelocnnd = orggrafptr->vertloctax[orgvertlocnnd]; /* Reorder remaining local part of edge array */ if (orggrafptr->edloloctax != NULL) fldgrafptr->edloloctax = fldgrafptr->edgeloctax + fldgrafptr->edgelocnbr; /* Set start index of edge load array */ commnbr = 0; /* Turn sender-receiver into normal receiver without any communications to perform */ } for (procngbmin = 0, procngbmax = fldvertadjnbr; /* Initialize search accelerator */ procngbmax - procngbmin > 1; ) { int procngbmed; procngbmed = (procngbmax + procngbmin) / 2; if (fldvertadjtab[procngbmed] <= orggrafptr->procvrttab[orggrafptr->proclocnum]) procngbmin = procngbmed; else procngbmax = procngbmed; } orgvertlocmin = fldvertadjtab[procngbmin]; orgvertlocmax = fldvertadjtab[procngbmax]; fldvertlocadj = fldvertdlttab[procngbmin]; for (fldedgelocnum = orggrafptr->baseval; fldedgelocnum < fldedgelocnnd; fldedgelocnum ++) { Gnum orgvertlocend; orgvertlocend = orgedgeloctax[fldedgelocnum]; if ((orgvertlocend >= orgvertlocmin) && /* If end vertex is local */ (orgvertlocend < orgvertlocmax)) fldedgeloctax[fldedgelocnum] = orgvertlocend + fldvertlocadj; else { /* End vertex is not local */ int procngbnum; int procngbmax; for (procngbnum = 0, procngbmax = fldvertadjnbr; procngbmax - procngbnum > 1; ) { int procngbmed; procngbmed = (procngbmax + procngbnum) / 2; if (fldvertadjtab[procngbmed] <= orgvertlocend) procngbnum = procngbmed; else procngbmax = procngbmed; } fldedgeloctax[fldedgelocnum] = orgvertlocend + fldvertdlttab[procngbnum]; } } if (orggrafptr->veloloctax != NULL) /* If original graph has vertex loads */ memCpy (fldgrafptr->veloloctax + orggrafptr->baseval, /* Copy local part of vertex load array */ orggrafptr->veloloctax + orggrafptr->baseval, orgvertlocnbr * sizeof (Gnum)); if (orggrafptr->edloloctax != NULL) /* If original graph has edge loads */ memCpy (fldgrafptr->edloloctax + orggrafptr->baseval, /* Copy local part of edge load array */ orggrafptr->edloloctax + orggrafptr->baseval, (orggrafptr->vertloctax[orgvertlocnnd] - orggrafptr->baseval) * sizeof (Gnum)); if (orggrafptr->vnumloctax != NULL) /* If original graph has vertex numbers */ memCpy (fldgrafptr->vnumloctax + orggrafptr->baseval, /* Copy local part of vertex number array */ orggrafptr->vnumloctax + orggrafptr->baseval, orgvertlocnbr * sizeof (Gnum)); else { /* Build local part of vertex number array */ Gnum fldvertlocnum; Gnum fldvertlocadj; for (fldvertlocnum = orggrafptr->baseval, fldvertlocadj = orggrafptr->procvrttab[orggrafptr->proclocnum]; fldvertlocnum < orgvertlocnnd; fldvertlocnum ++) fldgrafptr->vnumloctax[fldvertlocnum] = fldvertlocadj ++; } memCpy (fldgrafptr->vertloctax + orggrafptr->baseval, /* Copy local part of vertex array, since it is compact */ orggrafptr->vertloctax + orggrafptr->baseval, orgvertlocnbr * sizeof (Gnum)); /* Last value is not copied */ fldgrafptr->vertloctax[fldvertlocnbr + orggrafptr->baseval] = fldgrafptr->edgelocnbr + orggrafptr->baseval; if (orgdataptr != NULL) /* If additional data present */ memCpy ((byte *) (*flddataptr), (byte *) orgdataptr, orgvertlocnbr * infosiz); /* Copy local part */ for (i = 0; i < commnbr; i ++) { int j; if (MPI_Waitany (commnbr, &requtab[DGRAPHFOLDTAGVERT * commmax], &j, MPI_STATUS_IGNORE) != MPI_SUCCESS) { errorPrint ("dgraphFold2: communication error (16)"); cheklocval = 1; } else { /* Adjust first remote part of vertex array */ Gnum fldvertlocnum; Gnum fldvertlocnnd; Gnum fldvertlocadj; Gnum * restrict const fldvertloctax = fldgrafptr->vertloctax; fldvertlocnum = fldvertidxtab[j]; fldvertlocadj = fldedgeidxtab[j] - fldgrafptr->vertloctax[fldvertlocnum]; for (fldvertlocnnd = fldvertlocnum + fldcommdattab[j].vertnbr; fldvertlocnum < fldvertlocnnd; fldvertlocnum ++) fldvertloctax[fldvertlocnum] += fldvertlocadj; } } for (i = 0; i < commnbr; i ++) { MPI_Status statdat; int j; if (MPI_Waitany (commnbr, &requtab[DGRAPHFOLDTAGEDGE * commmax], &j, &statdat) != MPI_SUCCESS) { errorPrint ("dgraphFold2: communication error (17)"); cheklocval = 1; } else if (cheklocval == 0) { /* Adjust remote part(s) of edge array */ Gnum orgvertlocmin; Gnum orgvertlocmax; Gnum fldvertlocadj; int procngbnum; int procngbmax; Gnum * restrict const fldedgeloctax = fldgrafptr->edgeloctax; #ifdef SCOTCH_DEBUG_DGRAPH2 int fldedgercvnbr; MPI_Get_count (&statdat, GNUM_MPI, &fldedgercvnbr); if (fldedgercvnbr != fldedgecnttab[j]) { errorPrint ("dgraphFold2: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ for (procngbnum = 0, procngbmax = fldvertadjnbr; /* Initialize search accelerator */ procngbmax - procngbnum > 1; ) { int procngbmed; procngbmed = (procngbmax + procngbnum) / 2; if (fldvertadjtab[procngbmed] <= fldcommvrttab[j]) procngbnum = procngbmed; else procngbmax = procngbmed; } orgvertlocmin = fldvertadjtab[procngbnum]; orgvertlocmax = fldvertadjtab[procngbmax]; fldvertlocadj = fldvertdlttab[procngbnum]; for (fldedgelocnum = fldedgeidxtab[j], fldedgelocnnd = fldedgelocnum + fldedgecnttab[j]; fldedgelocnum < fldedgelocnnd; fldedgelocnum ++) { /* Reorder end vertices */ Gnum orgvertlocend; #ifdef SCOTCH_DEBUG_DGRAPH2 if (fldedgelocnum >= (fldgrafptr->edgelocnbr + orggrafptr->baseval)) { errorPrint ("dgraphFold2: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ orgvertlocend = fldedgeloctax[fldedgelocnum]; if ((orgvertlocend >= orgvertlocmin) && /* If end vertex is local */ (orgvertlocend < orgvertlocmax)) fldedgeloctax[fldedgelocnum] = orgvertlocend + fldvertlocadj; else { int procngbnum; int procngbmax; for (procngbnum = 0, procngbmax = fldvertadjnbr; procngbmax - procngbnum > 1; ) { int procngbmed; procngbmed = (procngbmax + procngbnum) / 2; if (fldvertadjtab[procngbmed] <= orgvertlocend) procngbnum = procngbmed; else procngbmax = procngbmed; } fldedgeloctax[fldedgelocnum] = orgvertlocend + fldvertdlttab[procngbnum]; } } } } if (orggrafptr->veloloctax == NULL) /* If no vertex loads, reset graph vertex load to number of vertices */ fldvelolocsum = fldvertlocnbr; else { /* Graph has vertex loads and load of local part has already been computed */ for (i = 0; i < commnbr; i ++) { int j; if (MPI_Waitany (commnbr, &requtab[DGRAPHFOLDTAGVELO * commmax], &j, MPI_STATUS_IGNORE) != MPI_SUCCESS) { errorPrint ("dgraphFold2: communication error (18)"); cheklocval = 1; } else if (cheklocval == 0) { /* Accumulate vertex loads for received vertex load array */ Gnum fldvertlocnum; Gnum fldvertlocnnd; for (fldvertlocnum = fldvertidxtab[j], fldvertlocnnd = fldvertlocnum + fldcommdattab[j].vertnbr; fldvertlocnum < fldvertlocnnd; fldvertlocnum ++) fldvelolocsum += fldgrafptr->veloloctax[fldvertlocnum]; } } } if ((fldcommtypval & DGRAPHFOLDCOMMSEND) == 0) { /* If process is a normal receiver, edge arrays may have been oversized */ Gnum fldedgeloctmp; fldedgeloctmp = fldgrafptr->edgelocnbr; if (orggrafptr->edloloctax != NULL) { fldedgeloctmp *= 2; if (MPI_Waitall (commnbr, &requtab[DGRAPHFOLDTAGEDLO * commmax], MPI_STATUSES_IGNORE) != MPI_SUCCESS) { /* Wait for edge load sub-arrays */ errorPrint ("dgraphFold2: communication error (19)"); cheklocval = 1; } } fldgrafptr->edgeloctax = memRealloc (fldgrafptr->edgeloctax + orggrafptr->baseval, fldedgeloctmp * sizeof (Gnum)); fldgrafptr->edgeloctax -= orggrafptr->baseval; if (orggrafptr->edloloctax != NULL) fldgrafptr->edloloctax = fldgrafptr->edgeloctax + fldgrafptr->edgelocnbr; } fldgrafptr->baseval = orggrafptr->baseval; fldgrafptr->vertlocnbr = fldvertlocnbr; fldgrafptr->vertlocnnd = fldvertlocnbr + orggrafptr->baseval; fldgrafptr->velolocsum = fldvelolocsum; fldgrafptr->degrglbmax = orggrafptr->degrglbmax; if (dgraphBuild4 (fldgrafptr) != 0) { errorPrint ("dgraphFold2: cannot build folded graph"); dgraphExit (fldgrafptr); return (1); } #ifdef SCOTCH_DEBUG_DGRAPH2 if (dgraphCheck (fldgrafptr) != 0) { /* Check graph consistency; vnumloctab is not checked so no need to wait for it */ errorPrint ("dgraphFold2: internal error (3)"); dgraphExit (fldgrafptr); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ } memFree (fldcommdattab); /* Free group leader */ if (MPI_Waitall (requnbr, requtab, MPI_STATUSES_IGNORE) != MPI_SUCCESS) { /* Wait for all graph data to arrive because graph could be freed afterwards */ errorPrint ("dgraphFold2: communication error (20)"); cheklocval = 1; } memFree (fldvertidxtab); /* Free group leader including request array */ #ifdef SCOTCH_DEBUG_DGRAPH1 /* Communication cannot be merged with a useful one */ if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, orggrafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphFold2: communication error (21)"); chekglbval = 1; } #else /* SCOTCH_DEBUG_DGRAPH1 */ chekglbval = cheklocval; #endif /* SCOTCH_DEBUG_DGRAPH1 */ return (chekglbval); } scotch-6.0.4.dfsg/src/libscotch/library_dgraph_band_f.c0000644002563400244210000000662212055775450026300 0ustar trophimeutilisateurs du domaine/* Copyright 2011,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_band_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the Fortran API for the **/ /** distributed graph handling routines **/ /** of the libSCOTCH library. **/ /** **/ /** DATES : # Version 6.0 : from : 03 nov 2011 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "ptscotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the distributed graph handling */ /* routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFDGRAPHBAND, scotchfdgraphband, ( \ SCOTCH_Dgraph * const srcgrafptr, \ const SCOTCH_Num fronlocnbr, \ SCOTCH_Num * const fronloctab, \ const SCOTCH_Num distval, \ SCOTCH_Dgraph * const bndgrafptr, \ int * const revaptr), \ (srcgrafptr, fronlocnbr, fronloctab, distval, bndgrafptr, revaptr)) { *revaptr = SCOTCH_dgraphBand (srcgrafptr, fronlocnbr, fronloctab, distval, bndgrafptr); } scotch-6.0.4.dfsg/src/libscotch/dgraph_fold_comm.c0000644002563400244210000005724312412035044025270 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2009-2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_fold_comm.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module computes the communication **/ /** pattern of the distributed graph **/ /** folding process. **/ /** **/ /** DATES : # Version 5.0 : from : 23 may 2006 **/ /** to : 10 sep 2007 **/ /** # Version 5.1 : from : 18 jan 2009 **/ /** to : 10 sep 2011 **/ /** **/ /************************************************************/ #include "module.h" #include "common.h" #include "dgraph.h" #include "dgraph_fold_comm.h" /* This routine computes an optimized communication ** scheme for folding the data of a distributed graph. ** It is currently based on a maximum fixed number of ** communications per process. If this maximum is reached, ** the algorithm will fail. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int dgraphFoldComm ( const Dgraph * restrict const grafptr, const int partval, /* 0 for first half, 1 for second half */ int * restrict const commptr, /* Pointer to maximum number of communications per process */ int * restrict const commtypval, /* Process will be sender or receiver */ DgraphFoldCommData *restrict * restrict const commdatptr, /* Slots for communication */ Gnum *restrict * restrict const commvrtptr, /* Slots of starting global vertex send indices */ Gnum * restrict const proccnttab, /* Receive count array, for receivers */ int * restrict const vertadjnbrptr, /* Number of adjustment ranges, for receivers */ Gnum * restrict * restrict const vertadjptr, /* Pointer to global index adjustment array, for receivers */ Gnum * restrict * restrict const vertdltptr) /* Pointer to global delta adjustment array, for receivers */ { int commmax; /* Maximum number of communications per process */ int procnum; Gnum * restrict commvrttab; DgraphFoldCommData * restrict commdattab; DgraphFoldCommData * restrict procsrttab; /* Sort array */ int procsndbas; int procsndmnd; int procsndidx; int procrcvbas; int procrcvnnd; int procrcvidx; int fldprocnbr; Gnum * restrict vertadjtab; Gnum * restrict vertdlttab; int * restrict vertprmtab; /* Permutation array for adjustment range computations */ int i; #ifdef SCOTCH_DEBUG_DGRAPH2 DgraphFoldCommData * restrict procchktab; int chekloctab[2]; int chekglbtab[2]; if (grafptr->procglbnbr < 2) { errorPrint ("dgraphFoldComm: invalid parameters"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ if ((procsrttab = memAlloc (grafptr->procglbnbr * sizeof (DgraphFoldCommData))) == NULL) { errorPrint ("dgraphFoldComm: out of memory (1)"); return (1); } for (procnum = 0; procnum < grafptr->procglbnbr; procnum ++) { procsrttab[procnum].procnum = procnum; procsrttab[procnum].vertnbr = grafptr->proccnttab[procnum]; } fldprocnbr = (grafptr->procglbnbr + 1) / 2; /* Get number of processes in part 0 (always more than in part 1) */ intSort2asc1 (procsrttab, fldprocnbr); /* Sort both parts of processor array */ intSort2asc1 (procsrttab + fldprocnbr, grafptr->procglbnbr - fldprocnbr); if (partval == 0) { /* If part 0 will receive the data */ procrcvbas = 0; /* Receive by ascending weight order in first part */ procrcvnnd = fldprocnbr; procsndbas = grafptr->procglbnbr; /* Send by descending weight order in other part */ procsndmnd = fldprocnbr; } else { /* Part 1 will receive the data */ procrcvbas = fldprocnbr; /* Receive by ascending weight order in first part */ procrcvnnd = grafptr->procglbnbr; procsndbas = fldprocnbr; /* Send by descending weight order in other part */ procsndmnd = 0; fldprocnbr = grafptr->procglbnbr - fldprocnbr; } *commtypval = ((grafptr->proclocnum >= procrcvbas) && (grafptr->proclocnum < procrcvnnd)) ? DGRAPHFOLDCOMMRECV : DGRAPHFOLDCOMMSEND; #ifdef SCOTCH_DEBUG_DGRAPH2 if ((*commtypval == DGRAPHFOLDCOMMRECV) && ((proccnttab == NULL) || (vertadjptr == NULL) || (vertdltptr == NULL))) { errorPrint ("dgraphFoldComm: internal error (1)"); memFree (procsrttab); /* Free group leader */ return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ for (commmax = DGRAPHFOLDCOMMNBR, commdattab = NULL; ; commmax ++) { /* Start with small number of communications per process */ int procrcvnum; int procsndnum; int procsndnxt; /* Index of next sender to process after current sender */ Gnum vertglbsum; /* Global number of vertices already sent from all previous senders */ Gnum vertglbavg; /* Global average value of sent vertices to reach during current round */ Gnum vertsndrmn; /* Remaining number of vertices to send from current sending process */ int flagrcvval; /* Number of messages already sent by receiver and sender */ int flagsndval; int commtmp; if (commdattab != NULL) memFree (commdattab); commtmp = (proccnttab == NULL) ? 0 : commmax; if (memAllocGroup ((void **) (void *) &commdattab, (size_t) (commmax * sizeof (DgraphFoldCommData)), &commvrttab, (size_t) (commmax * sizeof (Gnum)), &vertadjtab, (size_t) (commtmp * grafptr->procglbnbr * sizeof (Gnum)), &vertdlttab, (size_t) (commtmp * grafptr->procglbnbr * sizeof (Gnum)), #ifdef SCOTCH_DEBUG_DGRAPH2 &procchktab, (size_t) (commmax * grafptr->procglbnbr * sizeof (DgraphFoldCommData)), #endif /* SCOTCH_DEBUG_DGRAPH2 */ &vertprmtab, (size_t) ((commmax + 1) * fldprocnbr * sizeof (int)), NULL) == NULL) { errorPrint ("dgraphFoldComm: out of memory (2)"); memFree (procsrttab); return (1); } for (i = 0; i < commmax; i ++) { /* Assume we will perform no communication at all */ commdattab[i].procnum = -1; commdattab[i].vertnbr = 0; } if (proccnttab != NULL) { /* If we are a receiver process, start filling count and adjustment arrays */ int procrcvtmp; memSet (vertprmtab, ~0, (commmax + 1) * fldprocnbr * sizeof (int)); /* Reset adjustment index arrays */ memSet (vertadjtab, ~0, commmax * grafptr->procglbnbr * sizeof (Gnum)); for (procrcvtmp = procrcvbas; procrcvtmp < procrcvnnd; procrcvtmp ++) { /* Fill count and adjustment arrays for receiver processes slots */ vertadjtab[procrcvtmp * commmax] = grafptr->procvrttab[procrcvtmp]; vertdlttab[procrcvtmp * commmax] = proccnttab[procrcvtmp - procrcvbas] = grafptr->proccnttab[procrcvtmp]; vertprmtab[(procrcvtmp - procrcvbas) * (commmax + 1)] = procrcvtmp * commmax; } } for (procrcvidx = procrcvbas; procrcvidx < (procrcvnnd - 1); procrcvidx ++, procrcvnnd --) { /* Overloaded receiver vertices will re-send some of their load */ Gnum vertsndnbr; /* Potential overload of receiver process */ procsndidx = procrcvnnd - 1; vertsndnbr = procsrttab[procsndidx].vertnbr - DATASIZE (grafptr->vertglbnbr, fldprocnbr, procsndidx - procrcvbas); if (vertsndnbr <= 0) /* If no further overload to improve, exit loop */ break; procrcvnum = procsrttab[procrcvidx].procnum; procsndnum = procsrttab[procsndidx].procnum; procsrttab[procrcvidx].vertnbr = - (procsrttab[procrcvidx].vertnbr + vertsndnbr); /* Flag as having had a communication */ if (proccnttab != NULL) { /* If we are a receiver process, fill count and adjustment arrays */ proccnttab[procrcvnum - procrcvbas] += vertsndnbr; proccnttab[procsndnum - procrcvbas] -= vertsndnbr; /* Vertices are transferred between receiver processes */ vertadjtab[procsndnum * commmax + 1] = grafptr->procvrttab[procsndnum] + grafptr->proccnttab[procsndnum] - vertsndnbr; vertdlttab[procsndnum * commmax + 1] = vertsndnbr; vertdlttab[procsndnum * commmax] -= vertsndnbr; vertprmtab[(procrcvnum - procrcvbas) * (commmax + 1) + 1] = procsndnum * commmax + 1; if (procsndnum == grafptr->proclocnum) { /* If we are the sender receiver process */ *commtypval = DGRAPHFOLDCOMMSEND | DGRAPHFOLDCOMMRECV; /* Indicate it */ commdattab[0].procnum = procrcvnum; /* Record communication */ commdattab[0].vertnbr = vertsndnbr; commvrttab[0] = grafptr->procvrttab[procsndnum] + grafptr->proccnttab[procsndnum] - vertsndnbr; /* Set starting global index of vertices to be sent */ } else if (procrcvnum == grafptr->proclocnum) { /* If we are the receiver receiver process */ commdattab[0].procnum = procsndnum; /* Record communication */ commdattab[0].vertnbr = vertsndnbr; commvrttab[0] = grafptr->procvrttab[procsndnum] + grafptr->proccnttab[procsndnum] - vertsndnbr; /* Set starting global index of vertices to be sent */ } } } while ((procsndmnd < procsndbas) && (procsrttab[procsndmnd].vertnbr == 0)) /* Do not account for empty sender processes */ procsndmnd ++; if (procsndmnd >= procsndbas) /* If there are no more sender processes */ break; /* We have completed communication computation */ procsndidx = procsndbas - 1; procsndnxt = procsndidx - 1; vertsndrmn = procsrttab[procsndidx].vertnbr; flagsndval = 0; procrcvidx = procrcvbas; procrcvnum = procsrttab[procrcvidx].procnum; flagrcvval = 0; vertglbavg = DATASIZE (grafptr->vertglbnbr, fldprocnbr, 0); vertglbsum = procsrttab[procrcvidx].vertnbr; /* Account for vertices already present in receiver process */ if (vertglbsum < 0) { /* If first receiver has already received a communication */ flagrcvval = 1; vertglbsum = - vertglbsum; procsrttab[procrcvidx].vertnbr = vertglbsum; /* Un-flag */ } while (1) { Gnum vertrcvrmn; /* Remaining number of vertices to receive */ Gnum vertsndnbr; /* Number of vertices actually sent and received */ Gnum vertsndnxt; /* Adjustment to add to vertex count of next sender */ int mesgrcvrmn; /* Number of message slots to receive small messages */ int flagsndnxt; #ifdef SCOTCH_DEBUG_DGRAPH2 if (flagrcvval + flagsndval >= (commmax * 2)) { errorPrint ("dgraphFoldComm: internal error (2)"); memFree (commdattab); /* Free group leader */ memFree (procsrttab); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ vertrcvrmn = (vertglbavg > vertglbsum) ? (vertglbavg - vertglbsum) : 0; /* Remaining space on receiver */ mesgrcvrmn = (vertsndrmn >= vertrcvrmn) ? (commmax - 1) : (commmax - 2); if ((procsndidx > procsndmnd) && /* If there remains small messages to be considered */ (((flagsndval == 0) && /* If sender has not sent anything yet or just started */ (flagrcvval < mesgrcvrmn)) || /* And receiver has space for larger messages to come */ ((flagrcvval == 0) && /* Or if receiver has not received anything yet */ (flagsndval < (commmax - 2)))) && /* And sender has enough slots to send */ (vertrcvrmn >= procsrttab[procsndmnd].vertnbr)) { /* And if receiver can hold small message entirely */ procsndnxt = procsndidx; /* Current large message will be processed next time */ procsndidx = procsndmnd; /* Process smallest message available to date */ flagsndnxt = flagsndval; /* Record location of next message to send */ flagsndval = 0; vertsndnxt = procsrttab[procsndnxt].vertnbr - vertsndrmn; /* Record vertices already sent */ vertsndnbr = /* All of its contents will be sent in one piece */ vertsndrmn = procsrttab[procsndmnd].vertnbr; procsndmnd ++; /* Small message has been processed */ } else { flagsndnxt = 0; vertsndnxt = 0; /* Next sender will not have been interrupted by a small message */ vertsndnbr = ((flagsndval >= (commmax - 1)) || /* If last chance to send for this process */ (((procrcvnnd - procrcvidx) * (commmax - 1) - flagrcvval) <= (procsndidx - procsndmnd))) /* Or if too few communications remain with sender receivers accounted for */ ? vertsndrmn /* Send all of the vertices to be sent */ : MIN (vertsndrmn, vertrcvrmn); /* Else just send what the receiver needs */ } procsndnum = procsrttab[procsndidx].procnum; if (vertsndnbr > 0) { /* If useful communication can take place */ if (proccnttab != NULL) { /* If we are a receiver process, fill count and adjustment arrays */ proccnttab[procrcvnum - procrcvbas] += vertsndnbr; vertadjtab[procsndnum * commmax + flagsndval] = grafptr->procvrttab[procsndnum] + grafptr->proccnttab[procsndnum] - vertsndrmn; vertdlttab[procsndnum * commmax + flagsndval] = vertsndnbr; vertprmtab[(procrcvnum - procrcvbas) * (commmax + 1) + 1 + flagrcvval] = procsndnum * commmax + flagsndval; if (procrcvnum == grafptr->proclocnum) { /* If we are the receiver process */ commdattab[flagrcvval].procnum = procsndnum; /* Record communication */ commdattab[flagrcvval].vertnbr = vertsndnbr; commvrttab[flagrcvval] = grafptr->procvrttab[procsndnum] + grafptr->proccnttab[procsndnum] - vertsndrmn; /* Set starting global index of vertices to be sent */ } } else if (procsndnum == grafptr->proclocnum) { /* If we are the sending process */ commdattab[flagsndval].procnum = procrcvnum; /* Record communication */ commdattab[flagsndval].vertnbr = vertsndnbr; commvrttab[flagsndval] = grafptr->procvrttab[procsndnum] + grafptr->proccnttab[procsndnum] - vertsndrmn; /* Set starting global index of vertices to be sent */ } vertglbsum += vertsndnbr; /* Account for vertices sent and received */ vertsndrmn -= vertsndnbr; flagsndval ++; flagrcvval ++; } if (vertsndrmn <= 0) { /* If sending process has sent everything */ procsndidx = procsndnxt; /* Process next vertex to send */ if (procsndidx < procsndmnd) /* If was last sending process, end loop */ break; procsndnxt = procsndidx - 1; /* Prepare next sender process */ flagsndval = flagsndnxt; /* Skip to next sending process */ vertsndrmn = procsrttab[procsndidx].vertnbr - vertsndnxt; } if ((flagrcvval >= commmax) || /* If receiver cannot receive more */ ((vertglbsum >= vertglbavg) && /* Or has received what it needed and is not forced to accept more */ (((procrcvnnd - procrcvidx) * (commmax - 1) - flagrcvval) > (procsndidx - procsndmnd)))) { if (++ procrcvidx >= procrcvnnd) /* If was last receiver, exit loop and go finalizing communication arrays */ break; procrcvnum = procsrttab[procrcvidx].procnum; /* Skip to next receiver process */ vertglbavg += DATASIZE (grafptr->vertglbnbr, fldprocnbr, procrcvidx - procrcvbas); if (procsrttab[procrcvidx].vertnbr >= 0) { /* If receiver did not receive from a sender receiver */ flagrcvval = 0; vertglbsum += procsrttab[procrcvidx].vertnbr; /* Account for vertices already present in receiver process */ } else { /* Receiver already received from a sender receiver */ flagrcvval = 1; /* Already a communication performed */ vertglbsum -= procsrttab[procrcvidx].vertnbr; /* Use negative value */ } } } if ((procsndidx <= procsndmnd) && (vertsndrmn <= 0)) /* If no sender vertex which has something to send remains */ break; /* Exit the loop on increasing number of communications */ } #ifdef SCOTCH_DEBUG_DGRAPH2 chekloctab[0] = - commmax; chekloctab[1] = commmax; if (MPI_Allreduce (chekloctab, chekglbtab, 2, MPI_INT, MPI_MAX, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphFoldComm: communication error"); memFree (commdattab); /* Free group leader */ return (1); } if ((chekglbtab[0] != chekloctab[0]) || (chekglbtab[1] != chekloctab[1])) { errorPrint ("dgraphFoldComm: internal error (3)"); memFree (commdattab); /* Free group leader */ return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ if (proccnttab != NULL) { /* If we are a receiver process */ int vertadjnbr; /* Number of adjustment slots */ Gnum vertadjsum; /* Current new starting position of current slot */ for (procnum = 0, vertadjsum = grafptr->baseval; procnum < ((commmax + 1) * fldprocnbr); procnum ++) { int vertprmnum; Gnum vertadjtmp; vertprmnum = vertprmtab[procnum]; if (vertprmnum == ~0) /* Skip empty slots */ continue; vertadjtmp = vertdlttab[vertprmnum]; /* Accumulate new slot indices and compute adjustments */ vertdlttab[vertprmnum] = vertadjsum - vertadjtab[vertprmnum]; vertadjsum += vertadjtmp; } for (procnum = vertadjnbr = 0; procnum < (commmax * grafptr->procglbnbr); procnum ++) { /* Compact vertex adjustment arrays */ if (vertadjtab[procnum] != -1) { vertadjtab[vertadjnbr] = vertadjtab[procnum]; vertdlttab[vertadjnbr] = vertdlttab[procnum]; vertadjnbr ++; } } vertadjtab[vertadjnbr] = grafptr->procvrttab[grafptr->procglbnbr]; /* Set upper bound on global vertex indices */ *vertadjnbrptr = vertadjnbr; *vertadjptr = vertadjtab; *vertdltptr = vertdlttab; } *commdatptr = commdattab; /* Set group leader */ *commvrtptr = commvrttab; *commptr = commmax; memFree (procsrttab); #ifdef SCOTCH_DEBUG_DGRAPH2 if (proccnttab == NULL) { /* If we are a sender process */ Gnum vertsndnbr; /* Number of vertices actually sent */ int i; for (i = 0, vertsndnbr = 0; (i < commmax) && (commdattab[i].procnum >= 0); i ++) vertsndnbr += commdattab[i].vertnbr; if (vertsndnbr != grafptr->vertlocnbr) { errorPrint ("dgraphFoldComm: internal error (4)"); memFree (commdattab); /* Free group leader */ return (1); } } if (MPI_Allgather (commdattab, 2 * commmax, GNUM_MPI, procchktab, 2 * commmax, GNUM_MPI, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphFoldComm: communication error"); memFree (commdattab); /* Free group leader */ return (1); } for (procnum = 0; procnum < grafptr->procglbnbr; procnum ++) { int commnum; for (commnum = 0; (commnum < commmax) && (procchktab[commmax * procnum + commnum].procnum != -1); commnum ++) { Gnum procend; Gnum vertnbr; int commend; procend = procchktab[commmax * procnum + commnum].procnum; vertnbr = procchktab[commmax * procnum + commnum].vertnbr; for (commend = 0; commend < commmax; commend ++) { if ((procchktab[commmax * procend + commend].procnum == procnum) && (procchktab[commmax * procend + commend].vertnbr == vertnbr)) break; } if (commend >= commmax) { errorPrint ("dgraphFoldComm: internal error (5)"); memFree (commdattab); /* Free group leader */ return (1); } } } #endif /* SCOTCH_DEBUG_DGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/bdgraph_bipart_ex.h0000644002563400244210000000751711631447170025465 0ustar trophimeutilisateurs du domaine/* Copyright 2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bdgraph_bipart_ex.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the parallel load imbalance **/ /** minimization bipartitioning routine **/ /** for distributed graphs. **/ /** **/ /** DATES : # Version 5.1 : from : 14 jul 2010 **/ /** to : 14 aug 2010 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct BdgraphBipartExParam_ { INT sbbtnbr; /*+ Number of sub-bits in the distributed gain structure +*/ double deltval; /*+ Maximum weight imbalance ratio +*/ } BdgraphBipartExParam; /* Sort structure for local vertices. First element used for intSort2asc1. */ typedef struct BdgraphBipartExSort_ { Gnum veloval; /* Load per process; TRICK: FIRST */ Gnum prioval; /* Priority value, not to sort by process rank */ Gnum procnum; /* Process number; TRICK: (Gnum) for sorting */ } BdgraphBipartExSort; /* Sort structure for individual moves. */ typedef struct BdgraphBipartExMove_ { Gnum veloval; /* Load per process; TRICK: FIRST */ Gnum vertnum; /* Vertex number */ } BdgraphBipartExMove; /* ** The function prototypes. */ #ifndef BDGRAPH_BIPART_EX #define static #endif int bdgraphBipartEx (Bdgraph * restrict const, const BdgraphBipartExParam * restrict const); #undef static scotch-6.0.4.dfsg/src/libscotch/library_dgraph_order_tree_dist_f.c0000644002563400244210000000772612055777764030571 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_order_tree_dist_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the Fortran API for the **/ /** distributed ordering distributed tree **/ /** building routine of the libSCOTCH **/ /** library. **/ /** **/ /** DATES : # Version 5.1 : from : 30 nov 2007 **/ /** to 30 nov 2007 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "ptscotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the ordering routines. */ /* */ /**************************************/ FORTRAN ( \ SCOTCHFDGRAPHORDERCBLKDIST, scotchfdgraphordercblkdist, ( \ const SCOTCH_Dgraph * const grafptr, \ const SCOTCH_Dordering * const ordeptr, \ SCOTCH_Num * const cblkglbptr), (grafptr, ordeptr, cblkglbptr)) { *cblkglbptr = SCOTCH_dgraphOrderCblkDist (grafptr, ordeptr); } /* ** */ FORTRAN ( \ SCOTCHFDGRAPHORDERTREEDIST, scotchfdgraphordertreedist, ( \ const SCOTCH_Dgraph * const grafptr, \ const SCOTCH_Dordering * const ordeptr, \ SCOTCH_Num * const treeglbtab, \ SCOTCH_Num * const sizeglbtab, \ int * const revaptr), \ (grafptr, ordeptr, treeglbtab, sizeglbtab, revaptr)) { *revaptr = SCOTCH_dgraphOrderTreeDist (grafptr, ordeptr, treeglbtab, sizeglbtab); } scotch-6.0.4.dfsg/src/libscotch/wgraph.h0000644002563400244210000001240411631447170023300 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : wgraph.h **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Francois PELLEGRINI **/ /** Charles-Edmond BICHOT (5.1b) **/ /** **/ /** FUNCTION : This module contains the data declarat- **/ /** ions for the vertex overlapped graph **/ /** partitioning. **/ /** **/ /** DATES : # Version 5.1 : from : 01 dec 2007 **/ /** to : 01 jul 2008 **/ /** # Version 6.0 : from : 05 nov 2009 **/ /** to : 04 nov 2010 **/ /** **/ /************************************************************/ #define WGRAPH_H /* ** The type and structure definitions. */ /*+ The graph structure. +*/ #ifndef ARCH_H typedef INT Anum; /*+ Generic integer +*/ #endif /* ARCH_H */ typedef struct Wgraph_ { Graph s; /*+ Source graph +*/ Anum partnbr; /*+ Current number of parts +*/ Gnum fronnbr; /*+ Number of frontier vertices +*/ Gnum fronload; /*+ load for frontier +*/ Gnum * frontab; /*+ Array of frontier vertex numbers +*/ Gnum * compload; /*+ Array of part loads +*/ Gnum * compsize; /*+ Array of part number of vertives +*/ Anum * parttax; /*+ Part array; can be allocated separately +*/ Gnum levlnum; } Wgraph; /*+ The save graph structure. +*/ typedef struct WgraphStore_ { Anum partnbr; /*+ Number of parts +*/ Gnum fronnbr; /*+ Number of frontier vertices +*/ Gnum fronload; /*+ Frontier load +*/ byte * datatab; /*+ Variable-sized data array +*/ } WgraphStore; /*+ This structure stores part lists. +*/ typedef struct WgraphPartList_ { Gnum vertnum; /*+ Number of vertex of which part is neighbor +*/ Anum nextidx; /*+ Pointer to index of next recorded neighbor +*/ } WgraphPartList; /* ** The function prototypes. */ #ifndef WGRAPH #define static #endif void wgraphInit (Wgraph * const, const Graph * restrict const, const Anum); void wgraphExit (Wgraph * const); int wgraphAlloc (Wgraph * const); void wgraphZero (Wgraph * const); int wgraphCheck (const Wgraph * const); int wgraphStoreInit (const Wgraph * const, WgraphStore * const); void wgraphStoreExit (WgraphStore * const); void wgraphStoreSave (const Wgraph * const, WgraphStore * const); void wgraphStoreUpdt (Wgraph * const, const WgraphStore * const); #undef static scotch-6.0.4.dfsg/src/libscotch/hall_order_hx.h0000644002563400244210000000624711631447170024632 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hall_order_hx.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the halo ordering service **/ /** routines. **/ /** **/ /** DATES : # Version 4.0 : from : 14 jan 2003 **/ /** to : 08 dec 2003 **/ /** **/ /************************************************************/ /* ** The function prototypes. */ #ifndef HALL_ORDER_HX #define static #endif int hallOrderHxBuild (const Gnum, const Gnum, const Gnum, const Gnum * restrict const, Order * restrict const, OrderCblk * restrict const, Gnum * restrict const, Gnum * restrict const, Gnum * restrict const, Gnum * restrict const, Gnum * restrict const, Gnum * restrict const, Gnum * restrict const, Gnum * restrict const, Gnum * restrict const, Gnum * restrict const, const Gnum, const Gnum, const float); Gnum hallOrderHxTree (const Gnum * restrict const, const Gnum * restrict const, const Gnum * restrict const, Gnum * restrict const, const Gnum, const Gnum); #undef static scotch-6.0.4.dfsg/src/libscotch/order_check.c0000644002563400244210000001430511631447171024256 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : order_check.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module checks the consistency of **/ /** orderings. **/ /** **/ /** DATES : # Version 4.0 : from : 19 dec 2001 **/ /** to 20 nov 2003 **/ /** # Version 5.0 : from : 26 jul 2007 **/ /** to 26 jul 2007 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define ORDER_CHECK #include "module.h" #include "common.h" #include "graph.h" #include "order.h" /************************************/ /* */ /* These routines handle orderings. */ /* */ /************************************/ /* This routine checks the consistency ** of the given ordering. ** It returns: ** - 0 : if ordering data are consistent. ** - !0 : on error. */ static int orderCheck2 ( const OrderCblk * restrict const cblkptr, Gnum * const cblknbr, Gnum * const treenbr) { if (cblkptr->vnodnbr < 1) { errorPrint ("orderCheck2: invalid number of vertex nodes (1)"); return (1); } if (cblkptr->cblktab != NULL) { /* If node has sons */ Gnum vnodnbr; Gnum cblknum; if (cblkptr->cblknbr <= 0) { errorPrint ("orderCheck2: invalid number of column blocks (1)"); return (1); } *cblknbr += cblkptr->cblknbr - 1; *treenbr += cblkptr->cblknbr; for (cblknum = vnodnbr = 0; cblknum < cblkptr->cblknbr; cblknum ++) { vnodnbr += cblkptr->cblktab[cblknum].vnodnbr; if (orderCheck2 (&cblkptr->cblktab[cblknum], cblknbr, treenbr) != 0) return (1); } if (vnodnbr != cblkptr->vnodnbr) { errorPrint ("orderCheck2: invalid number of vertex nodes (2)"); return (1); } } else if (cblkptr->cblknbr != 0) { errorPrint ("orderCheck2: invalid number of column blocks (2)"); return (1); } return (0); } int orderCheck ( const Order * restrict const ordeptr) { Gnum * restrict permtab; Gnum * restrict permtax; Gnum treenbr; Gnum cblknbr; Gnum vertnnd; Gnum vertnum; if (ordeptr->vnodnbr != ordeptr->cblktre.vnodnbr) { errorPrint ("orderCheck: invalid vertex count"); return (1); } if ((ordeptr->cblknbr < 0) || (ordeptr->cblknbr > ordeptr->treenbr)) { errorPrint ("orderCheck: invalid column block count (1)"); return (1); } if ((permtab = (Gnum *) memAlloc (ordeptr->vnodnbr * sizeof (Gnum))) == NULL) { errorPrint ("orderCheck: out of memory"); return (1); } memSet (permtab, ~0, ordeptr->cblktre.vnodnbr * sizeof (Gnum)); permtax = permtab - ordeptr->baseval; vertnnd = ordeptr->baseval + ordeptr->vnodnbr; for (vertnum = 0; vertnum < ordeptr->vnodnbr; vertnum ++) { if ((ordeptr->peritab[vertnum] < ordeptr->baseval) || /* If index not in range */ (ordeptr->peritab[vertnum] >= vertnnd)) { errorPrint ("orderCheck: invalid index"); memFree (permtab); return (1); } if (permtax[ordeptr->peritab[vertnum]] != ~0) { /* If index already used */ errorPrint ("orderCheck: duplicate index"); memFree (permtab); return (1); } permtax[ordeptr->peritab[vertnum]] = vertnum; /* Set who updated index */ } for (vertnum = 0; vertnum < ordeptr->vnodnbr; vertnum ++) { if (permtab[vertnum] == ~0) { /* If index not used */ errorPrint ("orderCheck: missing index"); memFree (permtab); return (1); } } memFree (permtab); treenbr = /* Assume there is just a root node */ cblknbr = 1; if (orderCheck2 (&ordeptr->cblktre, &cblknbr, &treenbr) != 0) return (1); if (cblknbr != ordeptr->cblknbr) { errorPrint ("orderCheck: invalid number of column blocks"); return (1); } if (treenbr != ordeptr->treenbr) { errorPrint ("orderCheck: invalid number of tree nodes"); return (1); } return (0); } scotch-6.0.4.dfsg/src/libscotch/bgraph_bipart_ml.c0000644002563400244210000003762312474554132025314 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007-2011,2014,2015 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bgraph_bipart_ml.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Luca SCARANO (v3.1) **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module bipartitions an active **/ /** graph using a multi-level scheme. **/ /** **/ /** DATES : # Version 3.1 : from : 24 oct 1995 **/ /** to 19 sep 1996 **/ /** # Version 3.2 : from : 20 sep 1996 **/ /** to 13 sep 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 12 mar 1999 **/ /** # Version 3.4 : from : 01 jun 2001 **/ /** to 01 jun 2001 **/ /** # Version 4.0 : from : 12 dec 2003 **/ /** to 20 mar 2005 **/ /** # Version 5.1 : from : 28 sep 2008 **/ /** to 27 mar 2011 **/ /** # Version 6.0 : from : 09 mar 2011 **/ /** to 27 feb 2015 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define BGRAPH_BIPART_ML #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "arch.h" #include "mapping.h" #include "graph_coarsen.h" #include "bgraph.h" #include "bgraph_bipart_ml.h" #include "bgraph_bipart_st.h" /*********************************************/ /* */ /* The coarsening and uncoarsening routines. */ /* */ /*********************************************/ /* This routine builds a coarser graph from the ** graph that is given on input. The coarser ** graphs differ at this stage from classical ** active graphs as their internal gains are not ** yet computed. ** It returns: ** - 0 : if the coarse graph has been built. ** - 1 : if threshold reached or on error. */ static int bgraphBipartMlCoarsen ( const Bgraph * const finegrafptr, /*+ Finer graph +*/ Bgraph * restrict const coargrafptr, /*+ Coarser graph to build +*/ GraphCoarsenMulti * restrict * const coarmultptr, /*+ Pointer to un-based multinode table to build +*/ const BgraphBipartMlParam * const paraptr) /*+ Method parameters +*/ { Gnum comploadtmp; /* Increase of imbalance range for coarse graph */ *coarmultptr = NULL; /* Allocate multloctab along with coarse graph */ if (graphCoarsen (&finegrafptr->s, &coargrafptr->s, coarmultptr, paraptr->coarnbr, paraptr->coarrat, NULL, NULL, 0, NULL) != 0) return (1); /* Return if coarsening failed */ if (finegrafptr->veextax != NULL) { /* Merge external gains for coarsened vertices */ GraphCoarsenMulti * restrict coarmulttab; Gnum * restrict coarveextab; Gnum coarvertnbr; Gnum coarvertnum; const Gnum * restrict const fineveextax = finegrafptr->veextax; if ((coarveextab = (Gnum *) memAlloc (coargrafptr->s.vertnbr * sizeof (Gnum))) == NULL) { errorPrint ("bgraphBipartMlCoarsen: out of memory"); graphExit (&coargrafptr->s); /* Only free Graph since veextab not allocated */ return (1); } coarmulttab = *coarmultptr; for (coarvertnum = 0, coarvertnbr = coargrafptr->s.vertnbr; coarvertnum < coarvertnbr; coarvertnum ++) { Gnum finevertnum0; /* First multinode vertex */ Gnum finevertnum1; /* Second multinode vertex */ finevertnum0 = coarmulttab[coarvertnum].vertnum[0]; finevertnum1 = coarmulttab[coarvertnum].vertnum[1]; coarveextab[coarvertnum] = (finevertnum0 != finevertnum1) ? fineveextax[finevertnum0] + fineveextax[finevertnum1] : fineveextax[finevertnum0]; } coargrafptr->s.flagval |= BGRAPHFREEVEEX; coargrafptr->veextax = coarveextab - coargrafptr->s.baseval; } else /* If fine graph does not have external gains */ coargrafptr->veextax = NULL; /* Coarse graph does not have external gains */ coargrafptr->s.flagval |= BGRAPHFREEPART; /* Only part array will have to be freed, as frontier is shared */ coargrafptr->parttax = NULL; /* Do not allocate partition data yet */ coargrafptr->frontab = finegrafptr->frontab; /* Use frontier array of finer graph as coarse frontier array */ comploadtmp = (finegrafptr->levlnum + 1) + (Gnum) (((double) MIN ((finegrafptr->compload0max - finegrafptr->compload0avg), (finegrafptr->compload0avg - finegrafptr->compload0min))) * 0.05); coargrafptr->compload0min = finegrafptr->compload0min - comploadtmp; /* Only set constant partition parameters as others will be set on uncoarsening */ coargrafptr->compload0max = finegrafptr->compload0max + comploadtmp; coargrafptr->compload0avg = finegrafptr->compload0avg; coargrafptr->commloadextn0 = finegrafptr->commloadextn0; coargrafptr->commgainextn0 = finegrafptr->commgainextn0; coargrafptr->domndist = finegrafptr->domndist; coargrafptr->domnwght[0] = finegrafptr->domnwght[0]; coargrafptr->domnwght[1] = finegrafptr->domnwght[1]; coargrafptr->vfixload[0] = finegrafptr->vfixload[0]; coargrafptr->vfixload[1] = finegrafptr->vfixload[1]; coargrafptr->levlnum = finegrafptr->levlnum + 1; return (0); } /* This routine propagates the bipartition of the ** coarser graph back to the finer graph, according ** to the multinode table of collapsed vertices. ** After the bipartition is propagated, it finishes ** to compute the parameters of the finer graph that ** were not computed at the coarsening stage. ** It returns: ** - 0 : if coarse graph data has been propagated to fine graph. ** - !0 : on error. */ static int bgraphBipartMlUncoarsen ( Bgraph * restrict const finegrafptr, /*+ Finer graph +*/ const Bgraph * const coargrafptr, /*+ Coarser graph +*/ const GraphCoarsenMulti * const coarmulttab) /*+ Pointer to un-based multinode array +*/ { Gnum coarvertnnd; Gnum coarvertnum; Gnum coarfronnbr; Gnum coarfronnum; Gnum * restrict coarfrontab; GraphPart * restrict coarparttax; GraphPart * restrict fineparttax; Gnum finefronnbr; Gnum finecompsize1; const GraphCoarsenMulti * const coarmulttax = coarmulttab - finegrafptr->s.baseval; const Gnum * restrict const fineverttax = finegrafptr->s.verttax; /* Fast accesses */ const Gnum * restrict const finevendtax = finegrafptr->s.vendtax; const Gnum * restrict const fineedgetax = finegrafptr->s.edgetax; if (finegrafptr->parttax == NULL) { /* If partition array not yet allocated */ if ((finegrafptr->parttax = (GraphPart *) memAlloc (finegrafptr->s.vertnbr * sizeof (GraphPart))) == NULL) { errorPrint ("bgraphBipartMlUncoarsen: out of memory"); return (1); /* Allocated data will be freed along with graph structure */ } finegrafptr->parttax -= finegrafptr->s.baseval; } if (coargrafptr == NULL) { /* If no coarse graph provided */ bgraphZero (finegrafptr); /* Assign all vertices to part 0 */ return (0); } coarparttax = coargrafptr->parttax; coarfrontab = coargrafptr->frontab; /* TRICK: also equal to finefrontab */ fineparttax = finegrafptr->parttax; finecompsize1 = coargrafptr->s.vertnbr - coargrafptr->compsize0; /* Pre-allocate sizes */ for (coarvertnum = coargrafptr->s.baseval, coarvertnnd = coargrafptr->s.vertnnd; coarvertnum < coarvertnnd; coarvertnum ++) { Gnum finevertnum0; /* First multinode vertex */ Gnum finevertnum1; /* Second multinode vertex */ GraphPart partval; finevertnum0 = coarmulttax[coarvertnum].vertnum[0]; finevertnum1 = coarmulttax[coarvertnum].vertnum[1]; partval = coarparttax[coarvertnum]; fineparttax[finevertnum0] = partval; if (finevertnum0 != finevertnum1) { fineparttax[finevertnum1] = partval; finecompsize1 += partval; /* Account for extra vertices created in part 1 */ } } finegrafptr->compload0 = coargrafptr->compload0; finegrafptr->compload0dlt = coargrafptr->compload0dlt; finegrafptr->compsize0 = finegrafptr->s.vertnbr - finecompsize1; finegrafptr->commload = coargrafptr->commload; finegrafptr->commgainextn = coargrafptr->commgainextn; finegrafptr->bbalval = coargrafptr->bbalval; for (coarfronnum = 0, finefronnbr = coarfronnbr = coargrafptr->fronnbr; /* Re-cycle frontier array from coarse to fine graph */ coarfronnum < coarfronnbr; coarfronnum ++) { Gnum coarvertnum; Gnum finevertnum0; /* First multinode vertex */ Gnum finevertnum1; /* Second multinode vertex */ coarvertnum = coarfrontab[coarfronnum]; finevertnum0 = coarmulttax[coarvertnum].vertnum[0]; finevertnum1 = coarmulttax[coarvertnum].vertnum[1]; if (finevertnum0 != finevertnum1) { /* If multinode is made of two distinct vertices */ GraphPart coarpartval; Gnum fineedgenum; coarpartval = coarparttax[coarvertnum]; #ifdef SCOTCH_DEBUG_BGRAPH2 coarfrontab[coarfronnum] = ~0; #endif /* SCOTCH_DEBUG_BGRAPH2 */ for (fineedgenum = fineverttax[finevertnum0]; fineedgenum < finevendtax[finevertnum0]; fineedgenum ++) { if (fineparttax[fineedgetax[fineedgenum]] != coarpartval) { /* If first vertex belongs to frontier */ coarfrontab[coarfronnum] = finevertnum0; /* Record it in lieu of the coarse frontier vertex */ break; } } if (fineedgenum >= finevendtax[finevertnum0]) { /* If first vertex not in frontier */ coarfrontab[coarfronnum] = finevertnum1; /* Then second vertex must be in frontier */ continue; /* Skip to next multinode */ } for (fineedgenum = fineverttax[finevertnum1]; /* Check if second vertex belong to frontier too */ fineedgenum < finevendtax[finevertnum1]; fineedgenum ++) { if (fineparttax[fineedgetax[fineedgenum]] != coarpartval) { /* If second vertex belongs to frontier */ coarfrontab[finefronnbr ++] = finevertnum1; /* Record it at the end of the recycled frontier array */ break; } } #ifdef SCOTCH_DEBUG_BGRAPH2 if (coarfrontab[coarfronnum] == ~0) { errorPrint ("bgraphBipartMlUncoarsen: internal error"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH2 */ } else /* If coarse vertex is single node */ coarfrontab[coarfronnum] = finevertnum0; /* Then it belongs to the frontier */ } finegrafptr->fronnbr = finefronnbr; #ifdef SCOTCH_DEBUG_BGRAPH2 if (bgraphCheck (finegrafptr) != 0) { errorPrint ("bgraphBipartMlUncoarsen: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH2 */ return (0); } /* This routine recursively performs the ** bipartitioning recursion. ** It returns: ** - 0 : if bipartitioning could be computed. ** - 1 : on error. */ static int bgraphBipartMl2 ( Bgraph * restrict const grafptr, /*+ Active graph +*/ const BgraphBipartMlParam * const paraptr) /*+ Method parameters +*/ { Bgraph coargrafdat; GraphCoarsenMulti * coarmulttab; int o; if (bgraphBipartMlCoarsen (grafptr, &coargrafdat, &coarmulttab, paraptr) == 0) { if (((o = bgraphBipartMl2 (&coargrafdat, paraptr)) == 0) && ((o = bgraphBipartMlUncoarsen (grafptr, &coargrafdat, coarmulttab)) == 0) && ((o = bgraphBipartSt (grafptr, paraptr->stratasc)) != 0)) /* Apply ascending strategy */ errorPrint ("bgraphBipartMl2: cannot apply ascending strategy"); bgraphExit (&coargrafdat); } else { if (((o = bgraphBipartMlUncoarsen (grafptr, NULL, NULL)) == 0) && /* Finalize graph */ ((o = bgraphBipartSt (grafptr, paraptr->stratlow)) != 0)) /* Apply low strategy */ errorPrint ("bgraphBipartMl2: cannot apply low strategy"); } return (o); } /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the multi-level bipartitioning. ** It returns: ** - 0 : if bipartitioning could be computed. ** - 1 : on error. */ int bgraphBipartMl ( Bgraph * restrict const grafptr, /*+ Active graph +*/ const BgraphBipartMlParam * const paraptr) /*+ Method parameters +*/ { Gnum levlnum; /* Save value for graph level */ int o; levlnum = grafptr->levlnum; /* Save graph level */ grafptr->levlnum = 0; /* Initialize coarsening level */ o = bgraphBipartMl2 (grafptr, paraptr); /* Perform multi-level bipartitioning */ grafptr->levlnum = levlnum; /* Restore graph level */ return (o); } scotch-6.0.4.dfsg/src/libscotch/wgraph_part_zr.c0000644002563400244210000000135011631447170025032 0ustar trophimeutilisateurs du domaine/* ** The defines and includes. */ #define WGRAPH_PART_ZR #include "module.h" #include "common.h" #include "graph.h" #include "wgraph.h" #include "wgraph_part_zr.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine moves all of the graph vertices ** to the first part of the partition. ** It returns: ** - 0 : if the bipartitioning could be computed. ** - !0 : on error. */ int wgraphPartZr ( Wgraph * const grafptr) /*+ Active graph +*/ { if (grafptr->compload[0] != grafptr->s.velosum) /* If not all vertices already in part zero */ wgraphZero (grafptr); return (0); } scotch-6.0.4.dfsg/src/libscotch/hmesh_order_hf.c0000644002563400244210000001612311631447170024761 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh_order_hf.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module orders a submesh using **/ /** the block-oriented Halo Approximate **/ /** (Multiple) Minimum Fill algorithm, **/ /** with super-variable accounting **/ /** R2HAMDf4 v2.0). **/ /** **/ /** DATES : # Version 4.0 : from : 08 dec 2003 **/ /** to : 09 dec 2003 **/ /** # Version 5.0 : from : 12 sep 2007 **/ /** to : 12 sep 2007 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HMESH_ORDER_HF #include "module.h" #include "common.h" #include "graph.h" #include "order.h" #include "mesh.h" #include "hmesh.h" #include "hall_order_hf.h" #include "hall_order_hx.h" #include "hmesh_order_hf.h" #include "hmesh_order_hx.h" #include "hmesh_order_si.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the ordering. ** It returns: ** - 0 : if the ordering could be computed. ** - !0 : on error. */ int hmeshOrderHf ( const Hmesh * restrict const meshptr, Order * restrict const ordeptr, const Gnum ordenum, OrderCblk * restrict const cblkptr, /*+ Single column-block +*/ const HmeshOrderHfParam * restrict const paraptr) { Gnum nbbuck; Gnum * restrict petab; Gnum pfree; Gnum iwlen; Gnum * restrict iwtab; Gnum * restrict lentab; Gnum * restrict nvartab; Gnum * restrict elentab; Gnum * restrict lasttab; Gnum * restrict leaftab; Gnum * restrict secntab; /* Array of index to first secondary variable */ Gnum * restrict nexttab; /* Array of index of next principal variable */ Gnum * restrict frsttab; Gnum * restrict headtab; /* Head array : nbbuck = 2 * n */ Gnum ncmpa; Gnum n; /* Number of nodes to order */ int o; n = meshptr->m.velmnbr + meshptr->m.vnodnbr; if (n < paraptr->colmin) /* If graph is too small, order simply */ return (hmeshOrderSi (meshptr, ordeptr, ordenum, cblkptr)); nbbuck = n * 2; iwlen = (Gnum) ((double) meshptr->m.edgenbr * HMESHORDERHFCOMPRAT) + 32; if (iwlen < n) /* Prepare to re-use array */ iwlen = n; if (memAllocGroup ((void **) (void *) &petab, (size_t) (n * sizeof (Gnum)), &iwtab, (size_t) (iwlen * sizeof (Gnum)), &lentab, (size_t) (n * sizeof (Gnum)), &nvartab, (size_t) (n * sizeof (Gnum)), &elentab, (size_t) (n * sizeof (Gnum)), &lasttab, (size_t) (n * sizeof (Gnum)), &leaftab, (size_t) (n * sizeof (Gnum)), &frsttab, (size_t) (n * sizeof (Gnum)), &secntab, (size_t) (n * sizeof (Gnum)), &nexttab, (size_t) (n * sizeof (Gnum)), &headtab, (size_t) ((nbbuck + 2) * sizeof (Gnum)), NULL) == NULL) { errorPrint ("hmeshOrderHf: out of memory"); return (1); } hmeshOrderHxFill (meshptr, petab, lentab, iwtab, elentab, &pfree); hallOrderHfR2hamdf4 (n, meshptr->m.velmnbr, nbbuck, iwlen, petab, pfree, lentab, iwtab, nvartab, elentab, lasttab, &ncmpa, leaftab, secntab, nexttab, frsttab, headtab); if (ncmpa < 0) { errorPrint ("hmeshOrderHf: internal error"); memFree (petab); /* Free group leader */ return (1); } o = hallOrderHxBuild (meshptr->m.baseval, n, meshptr->vnohnbr, (meshptr->m.vnumtax == NULL) ? NULL : meshptr->m.vnumtax + (meshptr->m.vnodbas - meshptr->m.baseval), /* Point to node part of vnumtab array */ ordeptr, cblkptr, nvartab - meshptr->m.baseval, lentab - meshptr->m.baseval, petab - meshptr->m.baseval, frsttab - meshptr->m.baseval, nexttab - meshptr->m.baseval, secntab - meshptr->m.baseval, iwtab - meshptr->m.baseval, elentab - meshptr->m.baseval, ordeptr->peritab + ordenum, /* Use given inverse permutation as inverse permutation space, never based */ leaftab, paraptr->colmin, paraptr->colmax, (float) paraptr->fillrat); memFree (petab); /* Free group leader */ return (o); } scotch-6.0.4.dfsg/src/libscotch/vdgraph_gather_all.c0000644002563400244210000002311711631447170025623 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vdgraph_gather_all.c **/ /** **/ /** AUTHORS : Cedric CHEVALIER **/ /** Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the routine which **/ /** builds a centralized Vgraph on all **/ /** processes by gathering the pieces of a **/ /** distributed Vdgraph. **/ /** **/ /** DATES : # Version 5.0 : from : 29 apr 2006 **/ /** to 01 mar 2008 **/ /** # Version 5.1 : from : 18 apr 2009 **/ /** to 30 jul 2010 **/ /** **/ /** NOTES : # The definitions of MPI_Gather and **/ /** MPI_Gatherv indicate that elements in **/ /** the receive array should not be **/ /** written more than once. Great care **/ /** should be taken to enforce this rule, **/ /** especially when the number of **/ /** vertices in the centralized graph is **/ /** smaller than the number of **/ /** processes. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VDGRAPH #include "module.h" #include "common.h" #include "comm.h" #include "graph.h" #include "vgraph.h" #include "dgraph.h" #include "vdgraph.h" /* This function gathers on all processes ** the pieces of a distributed Vdgraph to ** build a centralized Vgraph. ** It returns: ** - 0 : if graph data are consistent. ** - !0 : on error. */ int vdgraphGatherAll ( const Vdgraph * restrict const dgrfptr, /* Distributed graph */ Vgraph * restrict cgrfptr) /* Centralized graph */ { int * restrict froncnttab; /* Count array for gather operations */ int * restrict frondsptab; /* Displacement array for gather operations */ int fronlocnbr; /* Also int to enforce MPI standard */ int cheklocval; #ifdef SCOTCH_DEBUG_VDGRAPH1 int chekglbval; #endif /* SCOTCH_DEBUG_VDGRAPH1 */ int procnum; cheklocval = 0; #ifdef SCOTCH_DEBUG_VDGRAPH1 if (cgrfptr == NULL) /* Centralized graphs should be provided by all */ cheklocval = 1; if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("vdgraphGatherAll: communication error (1)"); return (1); } if (chekglbval != 0) { errorPrint ("vdgraphGatherAll: centralized graphs should be provided on every process"); return (1); } #endif /* SCOTCH_DEBUG_VDGRAPH1 */ if (dgraphGatherAll (&dgrfptr->s, &cgrfptr->s) != 0) { errorPrint ("vdgraphGatherAll: cannot build centralized graph"); return (1); } cgrfptr->parttax = NULL; /* In case of error */ cgrfptr->frontab = NULL; if (((cgrfptr->parttax = (GraphPart *) memAlloc (cgrfptr->s.vertnbr * sizeof (GraphPart))) == NULL) || ((cgrfptr->parttax -= cgrfptr->s.baseval, cgrfptr->frontab = (Gnum *) memAlloc (cgrfptr->s.vertnbr * sizeof (Gnum))) == NULL)) { errorPrint ("vdgraphGatherAll: out of memory (1)"); #ifndef SCOTCH_DEBUG_VDGRAPH1 vgraphExit (cgrfptr); return (1); } #else /* SCOTCH_DEBUG_VDGRAPH1 */ cheklocval = 1; } if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("vdgraphGatherAll: communication error (2)"); return (1); } if (chekglbval != 0) { vgraphExit (cgrfptr); return (1); } #endif /* SCOTCH_DEBUG_VDGRAPH1 */ cgrfptr->levlnum = dgrfptr->levlnum; /* Set level of separation graph as level of halo graph */ if (dgrfptr->partgsttax == NULL) { /* If distributed graph does not have a part array yet */ vgraphZero (cgrfptr); return (0); } if (memAllocGroup ((void **) (void *) /* Allocate tempory arrays to gather separator vertices */ &froncnttab, (size_t) (dgrfptr->s.procglbnbr * sizeof (int)), &frondsptab, (size_t) (dgrfptr->s.procglbnbr * sizeof (int)), NULL) == NULL) { errorPrint ("vdgraphGatherAll: out of memory (2)"); #ifndef SCOTCH_DEBUG_VDGRAPH1 vgraphExit (cgrfptr); return (1); } #else /* SCOTCH_DEBUG_VDGRAPH1 */ cheklocval = 1; } if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("vdgraphGatherAll: communication error (3)"); return (1); } if (chekglbval != 0) { if (froncnttab != NULL) memFree (froncnttab); vgraphExit (cgrfptr); return (1); } #endif /* SCOTCH_DEBUG_VDGRAPH1 */ if (commAllgatherv (dgrfptr->partgsttax + dgrfptr->s.baseval, dgrfptr->s.vertlocnbr, GRAPHPART_MPI, /* Get parttax of distributed graph */ cgrfptr->parttax, dgrfptr->s.proccnttab, dgrfptr->s.procdsptab, GRAPHPART_MPI, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("vdgraphGatherAll: communication error (4)"); return (1); } fronlocnbr = (int) dgrfptr->complocsize[2]; if (MPI_Allgather (&fronlocnbr, 1, MPI_INT, /* Compute how separator vertices are distributed */ froncnttab, 1, MPI_INT, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("vdgraphGatherAll: communication error (5)"); return (1); } frondsptab[0] = 0; /* Offset 0 for first process */ for (procnum = 1; procnum < dgrfptr->s.procglbnbr; procnum ++) /* Adjust index sub-arrays for all processes except the first one */ frondsptab[procnum] = frondsptab[procnum - 1] + froncnttab[procnum - 1]; if (MPI_Allgatherv (dgrfptr->fronloctab, fronlocnbr, GNUM_MPI, /* Gather separator vertices */ cgrfptr->frontab, froncnttab, frondsptab, GNUM_MPI, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("vdgraphGatherAll: communication error (6)"); return (1); } for (procnum = 1; procnum < dgrfptr->s.procglbnbr; procnum ++) { /* Adjust index sub-arrays for all processes except the first one */ Gnum vertnum; Gnum vertnnd; for (vertnum = (Gnum) frondsptab[procnum], vertnnd = vertnum + (Gnum) froncnttab[procnum]; vertnum < vertnnd; vertnum ++) cgrfptr->frontab[vertnum] += (Gnum) dgrfptr->s.procdsptab[procnum] - dgrfptr->s.baseval; } memFree (froncnttab); /* Free group leader */ for (procnum = 0; procnum < dgrfptr->s.proclocnum; procnum ++) /* Desynchronize random generators across processes */ cheklocval = intRandVal (2); intPerm (cgrfptr->frontab, dgrfptr->compglbsize[2]); /* Compute permutation of frontier array to have different solutions on every process */ cgrfptr->compload[0] = dgrfptr->compglbload[0]; /* Update other fields */ cgrfptr->compload[1] = dgrfptr->compglbload[1]; cgrfptr->compload[2] = dgrfptr->compglbload[2]; cgrfptr->comploaddlt = dgrfptr->compglbloaddlt; cgrfptr->compsize[0] = dgrfptr->compglbsize[0]; cgrfptr->compsize[1] = dgrfptr->compglbsize[1]; cgrfptr->fronnbr = dgrfptr->compglbsize[2]; #ifdef SCOTCH_DEBUG_VDGRAPH2 if (vgraphCheck (cgrfptr) != 0) { errorPrint ("vdgraphGatherAll: internal error"); vgraphExit (cgrfptr); return (1); } #endif /* SCOTCH_DEBUG_VDGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/library_dgraph_gather_f.c0000644002563400244210000000652412055776267026656 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_gather_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API for **/ /** the distributed source graph handling **/ /** routines of the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 12 jul 2007 **/ /** to 12 jul 2007 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "ptscotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the distributed graph handling */ /* routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFDGRAPHGATHER, scotchfdgraphgather, ( \ SCOTCH_Dgraph * const dgrfptr, \ SCOTCH_Graph * const cgrfptr, \ int * const revaptr), \ (dgrfptr, cgrfptr, revaptr)) { *revaptr = SCOTCH_dgraphGather (dgrfptr, cgrfptr); } scotch-6.0.4.dfsg/src/libscotch/hdgraph_induce.c0000644002563400244210000004362212051771077024760 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hdgraph_induce.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles the halo source **/ /** graph subgraph-making functions. **/ /** **/ /** DATES : # Version 5.0 : from : 19 apr 2006 **/ /** to : 10 sep 2007 **/ /** # Version 5.1 : from : 27 jun 2008 **/ /** to : 22 oct 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HDGRAPH #include "module.h" #include "common.h" #include "dgraph.h" #include "hdgraph.h" /******************************/ /* */ /* These routines handle halo */ /* distributed source graphs. */ /* */ /******************************/ /* This routine builds the graph induced ** by the original graph and the list of ** selected vertices. ** The induced vnumtab array is the global ** translation of the list array if the ** original graph does not have a vnumtab, ** or the proper subset of the original ** vnumtab else. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int hdgraphInduceList ( Hdgraph * restrict const orggrafptr, const Gnum indlistnbr, const Gnum * restrict const indlisttab, /* Local list of kept vertices */ Hdgraph * restrict const indgrafptr) { const Gnum * restrict orgvertloctax; const Gnum * restrict orgvendloctax; const Gnum * restrict orgveloloctax; const Gnum * restrict orgedgegsttax; const Gnum * restrict orgedgeloctax; Gnum * restrict orgindxgsttax; /* Based access to vertex translation array */ Gnum * restrict orgindxhaltax; /* Based access to halo vertex translation array */ Gnum * restrict indvertloctax; Gnum * restrict indveloloctax; Gnum indvertlocnnd; /* Based index of end of local vertex array */ Gnum indvertlocnum; /* Number of current vertex in induced graph */ Gnum indvertglbnum; /* Number of current vertex in global ordering */ Gnum * restrict indvendloctax; Gnum indvelolocnbr; /* Size of local vertex load array */ Gnum indvelolocsum; /* Sum of vertex loads */ Gnum indvhallocnum; /* Number of halo vertex to be declared */ Gnum * restrict indedgeloctax; Gnum indedgelocmax; /* (Approximate) number of edges in induced graph */ Gnum indedgelocsiz; /* Real size of edge array, including halo */ Gnum indedgelocnbr; /* Real number of edges in induced graph */ Gnum indedgelocnum; Gnum inddegrlocmax; /* Local maximum degree over non-halo vertices */ const Gnum * restrict indlisttax; /* Based access to list of kept vertices */ int cheklocval; int chekglbval; if (dgraphGhst (&orggrafptr->s) != 0) { /* Compute ghost edge array if not already present */ errorPrint ("hdgraphInduceList: cannot compute ghost edge array"); return (1); } memSet (indgrafptr, 0, sizeof (Hdgraph)); /* Pre-initialize graph fields */ indgrafptr->s.proccomm = orggrafptr->s.proccomm; indgrafptr->s.procglbnbr = orggrafptr->s.procglbnbr; indgrafptr->s.proclocnum = orggrafptr->s.proclocnum; indgrafptr->s.flagval = (DGRAPHFREEALL ^ DGRAPHFREECOMM) | DGRAPHVERTGROUP | DGRAPHEDGEGROUP; /* For premature freeing on error; do not free vhndloctab as it is grouped with vertloctab */ if (orggrafptr->s.veloloctax != NULL) { indvelolocnbr = indlistnbr; indvelolocsum = 0; } else { indvelolocnbr = 0; indvelolocsum = indlistnbr; } indedgelocmax = orggrafptr->s.edgelocnbr; /* Choose best upper bound on number of edges (avoid multiply overflow) */ if ((orggrafptr->s.degrglbmax > 0) && (indlistnbr < (indedgelocmax / orggrafptr->s.degrglbmax))) indedgelocmax = indlistnbr * orggrafptr->s.degrglbmax; indedgelocmax += orggrafptr->ehallocnbr; cheklocval = chekglbval = 0; if (memAllocGroup ((void **) (void *) /* Allocate distributed graph private data */ &indgrafptr->s.procdsptab, (size_t) ((orggrafptr->s.procglbnbr + 1) * sizeof (Gnum)), &indgrafptr->s.proccnttab, (size_t) (orggrafptr->s.procglbnbr * sizeof (Gnum)), &indgrafptr->s.procngbtab, (size_t) (orggrafptr->s.procglbnbr * sizeof (int)), &indgrafptr->s.procrcvtab, (size_t) (orggrafptr->s.procglbnbr * sizeof (int)), &indgrafptr->s.procsndtab, (size_t) (orggrafptr->s.procglbnbr * sizeof (int)), NULL) == NULL) { errorPrint ("hdgraphInduceList: out of memory (1)"); cheklocval = 1; } else if (memAllocGroup ((void **) (void *) /* Allocate distributed graph public data */ &indgrafptr->s.vertloctax, (size_t) ((indlistnbr + 1) * sizeof (Gnum)), /* Compact vertex arrays */ &indgrafptr->s.vendloctax, (size_t) (indlistnbr * sizeof (Gnum)), /* Vertex end array for non-halo vertices */ &indgrafptr->s.vnumloctax, (size_t) (indlistnbr * sizeof (Gnum)), &indgrafptr->s.veloloctax, (size_t) (indvelolocnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("hdgraphInduceList: out of memory (2)"); cheklocval = 1; } else if (indgrafptr->s.vertloctax -= orggrafptr->s.baseval, indgrafptr->s.vendloctax -= orggrafptr->s.baseval, indgrafptr->s.vnumloctax -= orggrafptr->s.baseval, indgrafptr->s.veloloctax = ((orggrafptr->s.veloloctax != NULL) ? indgrafptr->s.veloloctax - orggrafptr->s.baseval : NULL), memAllocGroup ((void **) (void *) &indgrafptr->s.edgeloctax, (size_t) (indedgelocmax * sizeof (Gnum)), /* Pre-allocate space for edgeloctab */ &orgindxgsttax, (size_t) (orggrafptr->s.vertgstnbr * sizeof (Gnum)), /* orgindxgsttab and orgindxhaltab are at the end */ &orgindxhaltax, (size_t) (orggrafptr->vhallocnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("hdgraphInduceList: out of memory (3)"); cheklocval = 1; } else indgrafptr->s.edgeloctax -= orggrafptr->s.baseval; if (cheklocval != 0) { /* In case of memory error */ Gnum procngbnum; int dummyval; dummyval = -1; chekglbval = 1; if (MPI_Allgather (&dummyval, 1, GNUM_MPI, /* Use proccnttab of orggraf as dummy receive array (will be regenerated) */ orggrafptr->s.proccnttab, 1, GNUM_MPI, indgrafptr->s.proccomm) != MPI_SUCCESS) errorPrint ("hdgraphInduceList: communication error (1)"); for (procngbnum = 1; procngbnum <= orggrafptr->s.procglbnbr; procngbnum ++) /* Rebuild proccnttab of orggraf */ orggrafptr->s.proccnttab[procngbnum - 1] = orggrafptr->s.procdsptab[procngbnum] - orggrafptr->s.procdsptab[procngbnum - 1]; } else { indgrafptr->s.procvrttab = indgrafptr->s.procdsptab; /* Graph does not have holes */ indgrafptr->s.procdsptab[0] = indlistnbr; if (MPI_Allgather (&indgrafptr->s.procdsptab[0], 1, GNUM_MPI, &indgrafptr->s.proccnttab[0], 1, GNUM_MPI, indgrafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("hdgraphInduceList: communication error (2)"); chekglbval = 1; } else { Gnum procngbnum; indgrafptr->s.procdsptab[0] = orggrafptr->s.baseval; /* Build vertex-to-process array */ for (procngbnum = 0; procngbnum < indgrafptr->s.procglbnbr; procngbnum ++) { /* Process potential error flags from other processes */ if (indgrafptr->s.proccnttab[procngbnum] < 0) { /* If error notified by another process */ chekglbval = 1; break; } indgrafptr->s.procdsptab[procngbnum + 1] = indgrafptr->s.procdsptab[procngbnum] + indgrafptr->s.proccnttab[procngbnum]; } } } if (chekglbval != 0) { /* If something went wrong in all of the above */ hdgraphExit (indgrafptr); return (1); } memSet (orgindxgsttax, ~0, orggrafptr->s.vertgstnbr * sizeof (Gnum)); /* Preset index arrays */ orgindxgsttax -= orggrafptr->s.baseval; memSet (orgindxhaltax, ~0, orggrafptr->vhallocnbr * sizeof (Gnum)); orgindxhaltax -= orggrafptr->s.baseval; indlisttax = indlisttab - orggrafptr->s.baseval; indvertlocnnd = indlistnbr + orggrafptr->s.baseval; for (indvertlocnum = orggrafptr->s.baseval, indvertglbnum = indgrafptr->s.procdsptab[indgrafptr->s.proclocnum]; /* Set adjustment for global ordering */ indvertlocnum < indvertlocnnd; indvertlocnum ++, indvertglbnum ++) orgindxgsttax[indlisttax[indvertlocnum]] = indvertglbnum; /* Mark selected vertices */ if (dgraphHaloSync (&orggrafptr->s, (byte *) (orgindxgsttax + orggrafptr->s.baseval), GNUM_MPI) != 0) { /* Share global indexing of subgraph vertices */ errorPrint ("hdgraphInduceList: cannot perform halo exchange"); hdgraphExit (indgrafptr); return (1); } orgvertloctax = orggrafptr->s.vertloctax; orgvendloctax = orggrafptr->s.vendloctax; orgveloloctax = orggrafptr->s.veloloctax; orgedgegsttax = orggrafptr->s.edgegsttax; orgedgeloctax = orggrafptr->s.edgeloctax; indvertloctax = indgrafptr->s.vertloctax; indvendloctax = indgrafptr->s.vendloctax; indveloloctax = indgrafptr->s.veloloctax; indedgeloctax = indgrafptr->s.edgeloctax; inddegrlocmax = 0; for (indvertlocnum = indedgelocnum = indvhallocnum = orggrafptr->s.baseval, indedgelocnbr = 0; indvertlocnum < indvertlocnnd; indvertlocnum ++) { Gnum orgvertlocnum; Gnum orgedgelocnum; Gnum orgdegrlocval; Gnum inddegrlocval; Gnum indedgelocnnd; orgvertlocnum = indlisttax[indvertlocnum]; orgdegrlocval = orgvendloctax[orgvertlocnum] - orgvertloctax[orgvertlocnum]; indvertloctax[indvertlocnum] = indedgelocnum; if (orgveloloctax != NULL) { /* If graph has vertex weights */ indvelolocsum += /* Accumulate vertex loads */ indveloloctax[indvertlocnum] = orgveloloctax[orgvertlocnum]; } indedgelocnnd = indedgelocnum + orgdegrlocval; #ifdef SCOTCH_DEBUG_HDGRAPH2 if (indedgelocnnd > (indedgelocmax + orggrafptr->s.baseval)) { errorPrint ("hdgraphInduceList: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_HDGRAPH2 */ for (orgedgelocnum = orgvertloctax[orgvertlocnum]; /* Process local and ghost non-halo vertices */ orgedgelocnum < orgvendloctax[orgvertlocnum]; orgedgelocnum ++) { Gnum orgvertlocend; Gnum indvertgstend; orgvertlocend = orgedgegsttax[orgedgelocnum]; #ifdef SCOTCH_DEBUG_HDGRAPH2 if ((orgvertlocend < orggrafptr->s.baseval) || (orgvertlocend > orggrafptr->s.vertgstnnd)) { errorPrint ("hdgraphInduceList: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_HDGRAPH2 */ indvertgstend = orgindxgsttax[orgvertlocend]; if (indvertgstend >= 0) /* If edge is local or halo */ indedgeloctax[indedgelocnum ++] = indvertgstend; /* Keep it as regular edge */ else { /* If edge is halo edge */ if (indvertgstend == ~0) /* If halo vertex not assigned yet */ orgindxgsttax[orgvertlocend] = indvertgstend = -2 - indvhallocnum ++; /* Set new halo number */ indedgeloctax[-- indedgelocnnd] = -2 - indvertgstend; } } #ifdef SCOTCH_DEBUG_HDGRAPH2 if (indedgelocnnd != indedgelocnum) { errorPrint ("hdgraphInduceList: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_HDGRAPH2 */ indvendloctax[indvertlocnum] = indedgelocnum; inddegrlocval = indedgelocnum - indvertloctax[indvertlocnum]; indedgelocnbr += inddegrlocval; if (inddegrlocmax < inddegrlocval) inddegrlocmax = inddegrlocval; for (indedgelocnum = indvertloctax[indvertlocnum] + orgdegrlocval; /* Process local halo vertices */ orgedgelocnum < orggrafptr->vhndloctax[orgvertlocnum]; orgedgelocnum ++) { Gnum orgvhallocend; Gnum indvhallocend; orgvhallocend = orgedgeloctax[orgedgelocnum]; /* Halo vertices only exist in the edgeloctab array */ #ifdef SCOTCH_DEBUG_HDGRAPH2 if ((orgvhallocend < orggrafptr->s.baseval) || (orgvhallocend >= (orggrafptr->vhallocnbr + orggrafptr->s.baseval))) { errorPrint ("hdgraphInduceList: inconsistent halo vertex numbers"); hdgraphExit (indgrafptr); return (1); } if (indedgelocnum >= (indedgelocmax + orggrafptr->s.baseval)) { errorPrint ("hdgraphInduceList: internal error (4)"); return (1); } #endif /* SCOTCH_DEBUG_HDGRAPH2 */ indvhallocend = orgindxhaltax[orgvhallocend]; if (indvhallocend == ~0) /* If halo vertex not assigned yet */ orgindxhaltax[orgvhallocend] = indvhallocend = indvhallocnum ++; /* Set new halo number */ indgrafptr->s.edgeloctax[indedgelocnum ++] = indvhallocend; } } indvertloctax[indvertlocnum] = indedgelocnum; /* Mark end of edge array for vhndloctax */ indedgelocsiz = indedgelocnum - orggrafptr->s.baseval; /* Global number of edges, both non-halo and halo */ indgrafptr->s.edgeloctax = memRealloc (indgrafptr->s.edgeloctax + orggrafptr->s.baseval, (size_t) (indedgelocsiz * sizeof (Gnum))); indgrafptr->s.edgeloctax -= orggrafptr->s.baseval; if (orggrafptr->s.vnumloctax != NULL) { /* Adjust vnumloctax */ for (indvertlocnum = orggrafptr->s.baseval; indvertlocnum < indvertlocnnd; indvertlocnum ++) indgrafptr->s.vnumloctax[indvertlocnum] = orggrafptr->s.vnumloctax[indlisttax[indvertlocnum]]; } else { Gnum orgvertglbadj; orgvertglbadj = orggrafptr->s.procvrttab[orggrafptr->s.proclocnum] - orggrafptr->s.baseval; /* Set adjustement for global ordering */ for (indvertlocnum = orggrafptr->s.baseval; indvertlocnum < indvertlocnnd; indvertlocnum ++) indgrafptr->s.vnumloctax[indvertlocnum] = indlisttax[indvertlocnum] + orgvertglbadj; } indgrafptr->vhallocnbr = indvhallocnum - orggrafptr->s.baseval; indgrafptr->vhndloctax = indgrafptr->s.vertloctax + 1; /* Compact edge array with halo vertices */ indgrafptr->ehallocnbr = indedgelocsiz - indedgelocnbr; /* Get number of halo edges by difference */ indgrafptr->levlnum = orggrafptr->levlnum + 1; /* Induced subgraph is one level below */ indgrafptr->s.baseval = orggrafptr->s.baseval; indgrafptr->s.vertlocnbr = indlistnbr; indgrafptr->s.vertlocnnd = indlistnbr + orggrafptr->s.baseval; indgrafptr->s.velolocsum = indvelolocsum; indgrafptr->s.edgelocnbr = indedgelocnbr; indgrafptr->s.edgelocsiz = indedgelocsiz; indgrafptr->s.degrglbmax = orggrafptr->s.degrglbmax; if (dgraphBuild4 (&indgrafptr->s) != 0) { errorPrint ("hdgraphInduceList: cannot build induced graph"); return (1); } #ifdef SCOTCH_DEBUG_HDGRAPH2 if (hdgraphCheck (indgrafptr) != 0) { /* Check graph consistency */ errorPrint ("hdgraphInduceList: internal error (5)"); hdgraphExit (indgrafptr); return (1); } #endif /* SCOTCH_DEBUG_HDGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/arch_hcub.h0000644002563400244210000001373412354532414023734 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : arch_hcub.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the hypercube graph target **/ /** architecture functions. **/ /** **/ /** DATES : # Version 0.0 : from : 01 dec 1992 **/ /** to : 24 mar 1993 **/ /** # Version 1.2 : from : 04 feb 1994 **/ /** to : 11 feb 1994 **/ /** # Version 1.3 : from : 20 apr 1994 **/ /** to : 20 apr 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to : 12 nov 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to : 30 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 09 aug 1995 **/ /** # Version 3.1 : from : 11 jun 1996 **/ /** to 11 jun 1996 **/ /** # Version 3.2 : from : 21 sep 1996 **/ /** to 13 may 1998 **/ /** # Version 4.0 : from : 11 nov 2003 **/ /** to 11 nov 2003 **/ /** # Version 5.1 : from : 21 jan 2008 **/ /** to 21 jan 2008 **/ /** # Version 6.0 : from : 14 fev 2011 **/ /** to 01 jul 2014 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ #ifndef ARCH_HCUB_H_STRUCT #define ARCH_HCUB_H_STRUCT /*+ The binary hypercube definitions. +*/ typedef struct ArchHcub_ { Anum dimmax; /*+ Number of hypercube dimensions +*/ } ArchHcub; typedef struct ArchHcubDom_ { Anum dimcur; /*+ Current dimension to be set +*/ Anum bitset; /*+ Bit set of set dimensions +*/ } ArchHcubDom; #endif /* ARCH_HCUB_H_STRUCT */ /* ** The function prototypes. */ #ifndef ARCH_NOPROTO #ifndef ARCH_HCUB_H_PROTO #define ARCH_HCUB_H_PROTO #ifndef ARCH_HCUB #define static #endif int archHcubArchLoad (ArchHcub * restrict const, FILE * restrict const); int archHcubArchSave (const ArchHcub * const, FILE * restrict const); #define archHcubArchFree NULL ArchDomNum archHcubDomNum (const ArchHcub * const, const ArchHcubDom * const); int archHcubDomTerm (const ArchHcub * const, ArchHcubDom * restrict const, const ArchDomNum); Anum archHcubDomSize (const ArchHcub * const, const ArchHcubDom * const); #define archHcubDomWght archHcubDomSize Anum archHcubDomDist (const ArchHcub * const, const ArchHcubDom * const, const ArchHcubDom * const); int archHcubDomFrst (const ArchHcub * const, ArchHcubDom * restrict const); int archHcubDomLoad (const ArchHcub * const, ArchHcubDom * restrict const, FILE * restrict const); int archHcubDomSave (const ArchHcub * const, const ArchHcubDom * const, FILE * restrict const); int archHcubDomBipart (const ArchHcub * const, const ArchHcubDom * const, ArchHcubDom * restrict const, ArchHcubDom * restrict const); int archHcubDomIncl (const ArchHcub * const, const ArchHcubDom * const, const ArchHcubDom * const); #ifdef SCOTCH_PTSCOTCH int archHcubDomMpiType (const ArchHcub * const, MPI_Datatype * const); #endif /* SCOTCH_PTSCOTCH */ #undef static #endif /* ARCH_HCUB_H_PROTO */ #endif /* ARCH_NOPROTO */ scotch-6.0.4.dfsg/src/libscotch/bgraph_bipart_bd.h0000644002563400244210000000645011655654532025275 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010,2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bgraph_bipart_bd.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the bipartition graph banding **/ /** module. **/ /** **/ /** DATES : Version 5.0 : from : 27 nov 2006 **/ /** to : 29 may 2007 **/ /** Version 5.1 : from : 04 nov 2010 **/ /** to : 04 nov 2010 **/ /** Version 6.0 : from : 07 nov 2011 **/ /** to : 07 nov 2011 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct BgraphBipartBdParam_ { Gnum distmax; /*+ Maximum distance to separator +*/ Strat * stratbnd; /*+ Strategy for band graph +*/ Strat * stratorg; /*+ Strategy for original graph +*/ } BgraphBipartBdParam; /* ** The function prototypes. */ int bgraphBipartBd (Bgraph * restrict const, const BgraphBipartBdParam * restrict const); scotch-6.0.4.dfsg/src/libscotch/vdgraph_separate_bd.h0000644002563400244210000000603111631447170025773 0ustar trophimeutilisateurs du domaine/* Copyright 2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vdgraph_separate_bd.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the band vertex separation **/ /** routine for distributed graphs. **/ /** **/ /** DATES : # Version 5.0 : from : 04 mar 2006 **/ /** to : 04 mar 2006 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct VdgraphSeparateBdParam_ { INT distmax; /*+ Width of band surrounding the separator +*/ Strat * strat; /*+ Separation strategy used on the band garph +*/ } VdgraphSeparateBdParam; /* ** The function prototypes. */ #ifndef VDGRAPH_SEPARATE_BD #define static #endif int vdgraphSeparateBd (Vdgraph * const, const VdgraphSeparateBdParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/arch_cmplt.c0000644002563400244210000002412212354555445024127 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010,2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : arch_cmplt.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module handles the complete graph **/ /** target architecture. **/ /** **/ /** DATES : # Version 0.0 : from : 01 dec 1992 **/ /** to : 24 mar 1993 **/ /** # Version 1.2 : from : 04 feb 1994 **/ /** to : 11 feb 1994 **/ /** # Version 1.3 : from : 20 apr 1994 **/ /** to : 20 apr 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to : 23 dec 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to : 29 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 08 sep 1995 **/ /** # Version 3.1 : from : 11 jun 1996 **/ /** to 11 jun 1996 **/ /** # Version 3.2 : from : 21 sep 1996 **/ /** to 13 may 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 4.0 : from : 09 jan 2004 **/ /** to 10 mar 2005 **/ /** # Version 5.1 : from : 19 jan 2008 **/ /** to 11 aug 2010 **/ /** # Version 6.0 : from : 14 fev 2011 **/ /** to 14 fev 2011 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define ARCH_CMPLT #include "module.h" #include "common.h" #include "arch.h" #include "arch_cmplt.h" /******************************************/ /* */ /* These are the complete graph routines. */ /* */ /******************************************/ /* This routine loads the complete ** graph architecture. ** It returns: ** - 0 : if the architecture has been successfully read. ** - !0 : on error. */ int archCmpltArchLoad ( ArchCmplt * restrict const archptr, FILE * restrict const stream) { long numnbr; #ifdef SCOTCH_DEBUG_ARCH1 if ((sizeof (ArchCmplt) > sizeof (ArchDummy)) || (sizeof (ArchCmpltDom) > sizeof (ArchDomDummy))) { errorPrint ("archCmpltArchLoad: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ if ((fscanf (stream, "%ld", &numnbr) != 1) || (numnbr < 1)) { errorPrint ("archCmpltArchLoad: bad input"); return (1); } archptr->numnbr = (Anum) numnbr; return (0); } /* This routine saves the ** complete graph architecture. ** It returns: ** - 0 : if the architecture has been successfully written. ** - !0 : on error. */ int archCmpltArchSave ( const ArchCmplt * const archptr, FILE * restrict const stream) { #ifdef SCOTCH_DEBUG_ARCH1 if ((sizeof (ArchCmplt) > sizeof (ArchDummy)) || (sizeof (ArchCmpltDom) > sizeof (ArchDomDummy))) { errorPrint ("archCmpltArchSave: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ if (fprintf (stream, ANUMSTRING " ", (Anum) archptr->numnbr) == EOF) { errorPrint ("archCmpltArchSave: bad output"); return (1); } return (0); } /* This function returns the smallest number ** of terminal domain included in the given ** domain. */ ArchDomNum archCmpltDomNum ( const ArchCmplt * const archptr, const ArchCmpltDom * const domptr) { return (domptr->nummin); /* Return vertex number */ } /* This function returns the terminal domain associated ** with the given terminal number in the architecture. ** It returns: ** - 0 : if label is valid and domain has been updated. ** - 1 : if label is invalid. ** - 2 : on error. */ int archCmpltDomTerm ( const ArchCmplt * const archptr, ArchCmpltDom * const domptr, const ArchDomNum domnum) { if (domnum < archptr->numnbr) { /* If valid label */ domptr->nummin = domnum; /* Set the domain */ domptr->numnbr = 1; return (0); } return (1); /* Cannot set domain */ } /* This function returns the number of ** elements in the complete domain. */ Anum archCmpltDomSize ( const ArchCmplt * const archptr, const ArchCmpltDom * const domptr) { return (domptr->numnbr); } /* This function returns the average ** distance between two complete ** subdomains. */ Anum archCmpltDomDist ( const ArchCmplt * const archptr, const ArchCmpltDom * const dom0ptr, const ArchCmpltDom * const dom1ptr) { return (((dom0ptr->nummin == dom1ptr->nummin) && /* All domains are at distance 1 */ (dom0ptr->numnbr == dom1ptr->numnbr)) ? 0 : 1); /* If they are different */ } /* This function sets the biggest ** domain available for this ** architecture. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archCmpltDomFrst ( const ArchCmplt * const archptr, ArchCmpltDom * restrict const domptr) { domptr->nummin = 0; domptr->numnbr = archptr->numnbr; return (0); } /* This routine reads domain information ** from the given stream. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archCmpltDomLoad ( const ArchCmplt * const archptr, ArchCmpltDom * restrict const domptr, FILE * const stream) { long nummin; long numnbr; if ((fscanf (stream, "%ld%ld", &nummin, &numnbr) != 2) || (numnbr < 1) || (numnbr + nummin > (long) archptr->numnbr)) { errorPrint ("archCmpltDomLoad: bad input"); return (1); } domptr->nummin = (Anum) nummin; domptr->numnbr = (Anum) numnbr; return (0); } /* This routine saves domain information ** to the given stream. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archCmpltDomSave ( const ArchCmplt * const archptr, const ArchCmpltDom * const domptr, FILE * const stream) { if (fprintf (stream, ANUMSTRING " " ANUMSTRING " ", (Anum) domptr->nummin, (Anum) domptr->numnbr) == EOF) { errorPrint ("archCmpltDomSave: bad output"); return (1); } return (0); } /* This function tries to split a complete ** graph domain into two subdomains. ** It returns: ** - 0 : if bipartitioning succeeded. ** - 1 : if bipartitioning could not be performed. ** - 2 : on error. */ int archCmpltDomBipart ( const ArchCmplt * const archptr, const ArchCmpltDom * const domptr, ArchCmpltDom * restrict const dom0ptr, ArchCmpltDom * restrict const dom1ptr) { if (domptr->numnbr <= 1) /* Return if cannot bipartition more */ return (1); dom0ptr->nummin = domptr->nummin; /* Bipartition vertices */ dom0ptr->numnbr = domptr->numnbr / 2; dom1ptr->nummin = domptr->nummin + dom0ptr->numnbr; dom1ptr->numnbr = domptr->numnbr - dom0ptr->numnbr; return (0); } /* This function checks if dom1 is ** included in dom0. ** It returns: ** - 0 : if dom1 is not included in dom0. ** - 1 : if dom1 is included in dom0. ** - 2 : on error. */ int archCmpltDomIncl ( const ArchCmplt * const archptr, const ArchCmpltDom * const dom0ptr, const ArchCmpltDom * const dom1ptr) { if ((dom1ptr->nummin >= dom0ptr->nummin) && ((dom1ptr->nummin + dom1ptr->numnbr) <= (dom0ptr->nummin + dom0ptr->numnbr))) return (1); return (0); } /* This function creates the MPI_Datatype for ** complete graph domains. ** It returns: ** - 0 : if type could be created. ** - 1 : on error. */ #ifdef SCOTCH_PTSCOTCH int archCmpltDomMpiType ( const ArchCmplt * const archptr, MPI_Datatype * const typeptr) { MPI_Type_contiguous (2, ANUM_MPI, typeptr); return (0); } #endif /* SCOTCH_PTSCOTCH */ scotch-6.0.4.dfsg/src/libscotch/library_dgraph_redist.c0000644002563400244210000001074312056000011026327 0ustar trophimeutilisateurs du domaine/* Copyright 2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_redist.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the data declara- **/ /** tions for the graph redistribution **/ /** routines. **/ /** **/ /** DATES : # Version 6.0 : from : 28 mar 2012 **/ /** to : 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "graph.h" #include "dgraph.h" #include "dgraph_redist.h" #include "ptscotch.h" /************************************/ /* */ /* These routines are the C API for */ /* the graph handling routines. */ /* */ /************************************/ /*+ This routine computes a distributed graph *** that matches the provided partition. *** It returns: *** - 0 : if redistributed graph created. *** - !0 : on error. +*/ int SCOTCH_dgraphRedist ( SCOTCH_Dgraph * const orggrafptr, const SCOTCH_Num * const partloctab, /* Array of part numbers for each local vertex */ const SCOTCH_Num * const permgsttab, /* Redistribution permutation array */ const SCOTCH_Num vertlocdlt, /* Extra size of local vertex array */ const SCOTCH_Num edgelocdlt, /* Extra size of local edge array */ SCOTCH_Dgraph * const redgrafptr) { SCOTCH_Num baseval; #ifdef SCOTCH_DEBUG_LIBRARY1 int o; MPI_Comm_compare (((Dgraph * restrict const) orggrafptr)->proccomm, ((Dgraph * restrict const) redgrafptr)->proccomm, &o); if ((o != MPI_IDENT) && (o != MPI_CONGRUENT)) { errorPrint ("SCOTCH_dgraphRedist: communicators are not congruent"); return (1); } #endif /* SCOTCH_DEBUG_LIBRARY1 */ baseval = ((Dgraph *) orggrafptr)->baseval; return (dgraphRedist ((Dgraph *) orggrafptr, ((partloctab != NULL) && (partloctab != (SCOTCH_Num *) orggrafptr)) ? (const Gnum * restrict const) (partloctab - baseval) : NULL, ((permgsttab != NULL) && (permgsttab != (SCOTCH_Num *) orggrafptr)) ? (const Gnum * restrict const) (permgsttab - baseval) : NULL, (vertlocdlt < 0) ? 0 : vertlocdlt, (edgelocdlt < 0) ? 0 : edgelocdlt, (Dgraph *) redgrafptr)); } scotch-6.0.4.dfsg/src/libscotch/hgraph_order_hd.c0000644002563400244210000001567011631447170025132 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hgraph_order_hd.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module orders a separator using **/ /** the block-oriented Halo Approximate **/ /** (Multiple) Minimum Degree algorithm, **/ /** with super-variable accounting (HaloAMD **/ /** v2.0). **/ /** **/ /** DATES : # Version 3.2 : from : 09 aug 1998 **/ /** to 18 aug 1998 **/ /** # Version 3.3 : from : 02 oct 1998 **/ /** to : 05 jan 1999 **/ /** # Version 4.0 : from : 14 jan 2003 **/ /** to : 23 jan 2004 **/ /** # Version 5.0 : from : 10 sep 2007 **/ /** to : 10 sep 2007 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HGRAPH_ORDER_HD #include "module.h" #include "common.h" #include "graph.h" #include "order.h" #include "hgraph.h" #include "hall_order_hx.h" #include "hall_order_hd.h" #include "hgraph_order_hd.h" #include "hgraph_order_hx.h" #include "hgraph_order_si.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the ordering. ** It returns: ** - 0 : if the ordering could be computed. ** - !0 : on error. */ int hgraphOrderHd ( const Hgraph * restrict const grafptr, Order * restrict const ordeptr, const Gnum ordenum, /*+ Zero-based ordering number +*/ OrderCblk * restrict const cblkptr, /*+ Multiple column-block +*/ const HgraphOrderHdParam * restrict const paraptr) { Gnum * restrict petab; Gnum pfree; Gnum iwlen; Gnum * restrict iwtab; Gnum * restrict lentab; Gnum * restrict nvartab; Gnum * restrict elentab; Gnum * restrict lasttab; Gnum * restrict leaftab; Gnum * restrict secntab; /* Array of index to first secondary variable */ Gnum * restrict nexttab; /* Array of index of next principal variable */ Gnum * restrict frsttab; Gnum ncmpa; Gnum n; /* Number of nodes to order (with halo or not) */ int o; if (grafptr->s.vertnbr < paraptr->colmin) /* If graph is too small, order simply */ return (hgraphOrderSi (grafptr, ordeptr, ordenum, cblkptr)); n = grafptr->s.vertnbr; iwlen = (Gnum) ((double) grafptr->s.edgenbr * HGRAPHORDERHDCOMPRAT) + 32; if (iwlen < n) /* Prepare to re-use array */ iwlen = n; if (memAllocGroup ((void **) (void *) &petab, (size_t) (n * sizeof (Gnum)), &iwtab, (size_t) (iwlen * sizeof (Gnum)), &lentab, (size_t) (n * sizeof (Gnum)), &nvartab, (size_t) (n * sizeof (Gnum)), &elentab, (size_t) (n * sizeof (Gnum)), &lasttab, (size_t) (n * sizeof (Gnum)), &leaftab, (size_t) (n * sizeof (Gnum)), &frsttab, (size_t) (n * sizeof (Gnum)), &secntab, (size_t) (n * sizeof (Gnum)), &nexttab, (size_t) (n * sizeof (Gnum)), NULL) == NULL) { errorPrint ("hgraphOrderHd: out of memory"); return (1); } hgraphOrderHxFill (grafptr, petab, lentab, iwtab, elentab, &pfree); hallOrderHdHalmd (n, 0, iwlen, petab, pfree, /* No elements here */ lentab, iwtab, nvartab, elentab, lasttab, &ncmpa, leaftab, secntab, nexttab, frsttab); if (ncmpa < 0) { errorPrint ("hgraphOrderHd: internal error"); memFree (petab); /* Free group leader */ return (1); } o = hallOrderHxBuild (grafptr->s.baseval, n, grafptr->vnohnbr, grafptr->s.vnumtax, ordeptr, cblkptr, nvartab - grafptr->s.baseval, lentab - grafptr->s.baseval, petab - grafptr->s.baseval, frsttab - grafptr->s.baseval, nexttab - grafptr->s.baseval, secntab - grafptr->s.baseval, iwtab - grafptr->s.baseval, elentab - grafptr->s.baseval, ordeptr->peritab + ordenum, /* Use given inverse permutation as inverse permutation space, never based */ leaftab, paraptr->colmin, paraptr->colmax, (float) paraptr->fillrat); memFree (petab); /* Free group leader */ return (o); } scotch-6.0.4.dfsg/src/libscotch/wgraph_store.c0000644002563400244210000001534311631447171024515 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : wgraph_store.c **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Charles-Edmond BICHOT (v5.1b) **/ /** **/ /** FUNCTION : This module contains the data store re- **/ /** lated rountines for the vertex overlap- **/ /** ped graph partitioning. **/ /** **/ /** DATES : # Version 5.1 : from : 01 dec 2007 **/ /** to : 01 jul 2008 **/ /** # Version 6.0 : from : 05 nov 2010 **/ /** to : 30 may 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define WGRAPH_STORE #include "module.h" #include "common.h" #include "graph.h" #include "arch.h" #include "wgraph.h" /**********************************/ /* */ /* Store graph handling routines. */ /* */ /**********************************/ /* This routine builds a save structure ** for the given active graph. ** It returns: ** - 0 : if allocation succeeded. ** - !0 : on error. */ int wgraphStoreInit ( const Wgraph * const grafptr, WgraphStore * const storptr) { Gnum savsize; savsize = 2 * grafptr->partnbr * sizeof (Gnum) + /* Compute size for frontier, part arrays, communication load and size */ grafptr->s.vertnbr * (sizeof (Gnum) + sizeof (Anum)); if ((storptr->datatab = (byte *) memAlloc (savsize)) == NULL) { /* Allocate save structure */ errorPrint ("wgraphStoreInit: out of memory"); return (1); } return (0); } /* This routine frees a save structure. ** It returns: ** - VOID : in all cases. */ void wgraphStoreExit ( WgraphStore * const storptr) { memFree (storptr->datatab); #ifdef SCOTCH_DEBUG_WGRAPH2 storptr->datatab = NULL; #endif /* SCOTCH_DEBUG_WGRAPH2 */ } /* This routine saves partition data from the ** given active graph to the given save structure. ** It returns: ** - VOID : in all cases. */ void wgraphStoreSave ( const Wgraph * const grafptr, WgraphStore * const storptr) { byte * compload; /* Pointer to part load data save area */ byte * compsize; /* Pointer to part size data save area */ byte * frontab; /* Pointer to frontier data save area */ byte * parttab; /* Pointer to partition data save area */ storptr->partnbr = grafptr->partnbr; /* Save partition parameters */ storptr->fronnbr = grafptr->fronnbr; storptr->fronload = grafptr->fronload; compload = storptr->datatab; /* Compute data offsets within save structure */ compsize = compload + grafptr->partnbr * sizeof (Gnum); frontab = compsize + grafptr->partnbr * sizeof (Gnum); parttab = frontab + grafptr->fronnbr * sizeof (Gnum); memCpy (compload, grafptr->compload, grafptr->partnbr * sizeof (Gnum)); memCpy (compsize, grafptr->compsize, grafptr->partnbr * sizeof (Gnum)); memCpy (frontab, grafptr->frontab, grafptr->fronnbr * sizeof (Gnum)); memCpy (parttab, grafptr->parttax + grafptr->s.baseval, grafptr->s.vertnbr * sizeof (Anum)); } /* This routine updates partition data of the ** given active graph, using the given save graph. ** It returns: ** - VOID : in all cases. */ void wgraphStoreUpdt ( Wgraph * const grafptr, const WgraphStore * const storptr) { byte * compload; /* Pointer to part load data save area */ byte * compsize; /* Pointer to part size data save area */ byte * frontab; /* Pointer to frontier data save area */ byte * parttab; /* Pointer to partition data save area */ grafptr->partnbr = storptr->partnbr; /* Load partition parameters */ grafptr->fronnbr = storptr->fronnbr; grafptr->fronload = storptr->fronload; compload = storptr->datatab; /* Compute data offsets within save structure */ compsize = compload + grafptr->partnbr * sizeof (Gnum); frontab = compsize + grafptr->partnbr * sizeof (Gnum); parttab = frontab + grafptr->fronnbr * sizeof (Gnum); memCpy (grafptr->compload, compload, grafptr->partnbr * sizeof (Gnum)); memCpy (grafptr->compsize, compsize, grafptr->partnbr * sizeof (Gnum)); memCpy (grafptr->frontab, frontab, grafptr->fronnbr * sizeof (Gnum)); memCpy (grafptr->parttax + grafptr->s.baseval, parttab, grafptr->s.vertnbr * sizeof (Anum)); #ifdef SCOTCH_DEBUG_WGRAPH2 if (wgraphCheck (grafptr) != 0) errorPrint ("wgraphStoreUpdt: inconsistent graph data"); #endif /* SCOTCH_DEBUG_WGRAPH2 */ } scotch-6.0.4.dfsg/src/libscotch/bgraph_bipart_ex.h0000644002563400244210000000723611631447170025317 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bgraph_bipart_ex.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the exact-balance post-processing **/ /** module. **/ /** **/ /** DATES : # Version 2.0 : from : 25 oct 1994 **/ /** to 26 oct 1994 **/ /** # Version 3.0 : from : 18 nov 1995 **/ /** to 20 nov 1995 **/ /** # Version 3.1 : from : 20 nov 1995 **/ /** to 20 nov 1995 **/ /** # Version 3.2 : from : 15 sep 1996 **/ /** to 13 sep 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 4.0 : from : 11 dec 2003 **/ /** to 11 dec 2003 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ System-defined constants. +*/ #define BGRAPHBIPARTEXGAINTABLSUBBITS 1 #define BGRAPHBIPARTEXSTATEFREE ((GainLink *) 0) /*+ Vertex in initial state (TRICK: must be 0) +*/ #define BGRAPHBIPARTEXSTATEUSED ((GainLink *) 1) /*+ Swapped vertex +*/ #define BGRAPHBIPARTEXSTATELINK ((GainLink *) 2) /*+ Currently in gain table if higher +*/ /* ** The function prototypes. */ #ifndef BGRAPH_BIPART_EX #define static #endif int bgraphBipartEx (Bgraph * restrict const); #undef static scotch-6.0.4.dfsg/src/libscotch/vmesh_check.c0000644002563400244210000002063312343131525024260 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vmesh_check.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the consistency **/ /** checker for separation meshes. **/ /** **/ /** DATES : # Version 4.0 : from : 21 mar 2003 **/ /** to 11 may 2004 **/ /** # Version 6.0 : from : 02 jun 2014 **/ /** to 02 jun 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VMESH #include "module.h" #include "common.h" #include "graph.h" #include "mesh.h" #include "vmesh.h" /*************************/ /* */ /* These routines handle */ /* separator meshes. */ /* */ /*************************/ /* This routine checks the consistency ** of the given separator mesh. ** It returns: ** - 0 : if mesh data are consistent. ** - !0 : on error. */ int vmeshCheck ( const Vmesh * const meshptr) { Gnum velmnum; /* Number of current element vertex */ Gnum vnodnum; /* Number of current node vertex */ Gnum fronnum; /* Number of current frontier vertex */ int * restrict frontax; /* Frontier flag array */ Gnum ecmpsize[2]; /* Elements never in separator */ Gnum ncmpsize[3]; Gnum ncmpload[3]; int o; if ((meshptr->ecmpsize[0] + meshptr->ecmpsize[1]) > meshptr->m.velmnbr) { errorPrint ("vmeshCheck: invalid element balance"); return (1); } if (meshptr->ncmploaddlt != (meshptr->ncmpload[0] - meshptr->ncmpload[1])) { errorPrint ("vmeshCheck: invalid node balance"); return (1); } ecmpsize[0] = ecmpsize[1] = 0; for (velmnum = meshptr->m.velmbas; velmnum < meshptr->m.velmnnd; velmnum ++) { Gnum edgecut[3]; /* Array of cut edges */ Gnum partnum; /* Part of current vertex */ Gnum eelmnum; /* Number of current edge */ partnum = meshptr->parttax[velmnum]; if ((partnum < 0) || (partnum > 1)) { errorPrint ("vmeshCheck: invalid part array (1)"); return (1); } ecmpsize[partnum] ++; if ((partnum != 0) && (meshptr->m.verttax[velmnum] == meshptr->m.vendtax[velmnum])) { errorPrint ("vmeshCheck: isolated element not in part 0"); return (1); } edgecut[0] = edgecut[1] = edgecut[2] = 0; for (eelmnum = meshptr->m.verttax[velmnum]; eelmnum < meshptr->m.vendtax[velmnum]; eelmnum ++) edgecut[meshptr->parttax[meshptr->m.edgetax[eelmnum]]] ++; if (partnum == 2) { if ((edgecut[0] != 0) || (edgecut[1] != 0)) { errorPrint ("vmeshCheck: separator element not surrounded by separator nodes"); return (1); } } else { if (edgecut[1 - partnum] != 0) { errorPrint ("vmeshCheck: element should be in separator (%ld)", (long) velmnum); return (1); } } } if ((meshptr->ecmpsize[0] != ecmpsize[0]) || (meshptr->ecmpsize[1] != ecmpsize[1])) { errorPrint ("vmeshCheck: invalid element parameters"); return (1); } ncmpload[0] = ncmpload[1] = ncmpload[2] = 0; ncmpsize[0] = ncmpsize[1] = ncmpsize[2] = 0; for (vnodnum = meshptr->m.vnodbas; vnodnum < meshptr->m.vnodnnd; vnodnum ++) { Gnum edgecut[3]; /* Array of cut edges */ Gnum partnum; /* Part of current vertex */ Gnum enodnum; /* Number of current edge */ partnum = meshptr->parttax[vnodnum]; if ((partnum < 0) || (partnum > 2)) { errorPrint ("vmeshCheck: invalid part array (2)"); return (1); } ncmpsize[partnum] ++; ncmpload[partnum] += (meshptr->m.vnlotax == NULL) ? 1 : meshptr->m.vnlotax[vnodnum]; edgecut[0] = edgecut[1] = edgecut[2] = 0; for (enodnum = meshptr->m.verttax[vnodnum]; enodnum < meshptr->m.vendtax[vnodnum]; enodnum ++) edgecut[meshptr->parttax[meshptr->m.edgetax[enodnum]]] ++; #ifdef SCOTCH_DEBUG_VMESH3 if (partnum == 2) { if ((edgecut[0] == 0) || (edgecut[1] == 0)) errorPrint ("vmeshCheck: no-use separator vertex%s (%ld)", /* Warning only */ ((meshptr->levlnum == 0) ? " at level 0" : ""), (long) vnodnum); } else { #else if (partnum != 2) { #endif /* SCOTCH_DEBUG_VMESH3 */ if (edgecut[1 - partnum] != 0) { errorPrint ("vmeshCheck: node should be in separator (%ld)", (long) vnodnum); return (1); } } } if ((meshptr->ncmpload[0] != ncmpload[0]) || (meshptr->ncmpload[1] != ncmpload[1]) || (meshptr->ncmpload[2] != ncmpload[2]) || (meshptr->ncmpsize[0] != ncmpsize[0]) || (meshptr->ncmpsize[1] != ncmpsize[1]) || (meshptr->fronnbr != ncmpsize[2])) { errorPrint ("vmeshCheck: invalid node parameters"); return (1); } if ((meshptr->fronnbr < 0) || (meshptr->fronnbr > meshptr->m.vnodnbr)) { errorPrint ("vmeshCheck: invalid number of frontier vertices"); return (1); } if ((frontax = memAlloc (meshptr->m.vnodnbr * sizeof (int))) == NULL) { errorPrint ("vmeshCheck: out of memory"); return (1); } memSet (frontax, 0, meshptr->m.vnodnbr * sizeof (int)); frontax -= meshptr->m.vnodbas; o = 1; /* Assume failure when checking */ for (fronnum = 0; fronnum < meshptr->fronnbr; fronnum ++) { Gnum vnodnum; vnodnum = meshptr->frontab[fronnum]; if ((vnodnum < meshptr->m.vnodbas) || (vnodnum >= meshptr->m.vnodnnd)) { errorPrint ("vmeshCheck: invalid vertex in frontier array"); goto fail; } if (meshptr->parttax[vnodnum] != 2) { errorPrint ("vmeshCheck: invalid frontier array"); goto fail; } if (frontax[vnodnum] != 0) { errorPrint ("vmeshCheck: duplicate node in frontier array"); goto fail; } frontax[vnodnum] = 1; } o = 0; /* Everything turned well */ fail : memFree (frontax + meshptr->m.vnodbas); return (o); } scotch-6.0.4.dfsg/src/libscotch/parser.c0000644002563400244210000006176412412577124023315 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010,2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : parser.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a static mapper. **/ /** This module is the strategy lexical and **/ /** syntactic analyzer. **/ /** **/ /** DATES : # Version 3.1 : from : 07 nov 1995 **/ /** to 02 may 1996 **/ /** # Version 3.2 : from : 07 oct 1996 **/ /** to 19 oct 1996 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 10 sep 2001 **/ /** # Version 4.0 : from : 20 dec 2001 **/ /** to 02 feb 2004 **/ /** # Version 5.0 : from : 20 feb 2008 **/ /** to 20 feb 2008 **/ /** # Version 5.1 : from : 22 oct 2008 **/ /** to 11 aug 2010 **/ /** # Version 6.0 : from : 01 jun 2012 **/ /** to 30 sep 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define PARSER #include "module.h" #include "common.h" #undef INTEGER /* In case someone defined them */ #undef DOUBLE #include "parser.h" #include "parser_yy.h" /* ** The static and global variables. */ static StratTab stratdummytab = { NULL, NULL, NULL }; /* Dummy strategy table for the dummy empty object */ Strat stratdummy = { &stratdummytab, STRATNODEEMPTY }; /* Dummy empty object for offset computations */ /**************************/ /* */ /* The strategy routines. */ /* */ /**************************/ /* This routine parses the given strategy ** string and builds the corresponding ** strategy tree. ** It returns: ** - !NULL : pointer to the strategy. ** - NULL : on error. */ Strat * stratInit ( const StratTab * const strattab, /*+ Pointer to strategy parsing table +*/ const char * const string) /*+ Strategy string to parse +*/ { #ifdef SCOTCH_DEBUG_PARSER1 if ((strattab == NULL) || (string == NULL)) { errorPrint ("stratInit: invalid parameter"); return (NULL); } #endif /* SCOTCH_DEBUG_PARSER1 */ return (stratParserParse (strattab, string)); /* Parse strategy string */ } /* This routine frees a strategy structure. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int stratExit ( Strat * const strat) { StratParamTab * paratab; /* Table of method parameters */ byte * paraofft; /* Offset of parameter within method structure */ unsigned int i; int o; if (strat == NULL) /* If node does not exist, abort */ return (0); o = 0; /* Assume everything will be all right */ switch (strat->type) { /* Recursively free sub-strategies */ case STRATNODECONCAT : o = stratExit (strat->data.concat.strat[0]); o |= stratExit (strat->data.concat.strat[1]); break; case STRATNODECOND : o = stratTestExit (strat->data.cond.test); o |= stratExit (strat->data.cond.strat[0]); if (strat->data.cond.strat[1] != NULL) o |= stratExit (strat->data.cond.strat[1]); break; case STRATNODESELECT : o = stratExit (strat->data.select.strat[0]); o |= stratExit (strat->data.select.strat[1]); break; case STRATNODEEMPTY : /* Empty strategy node */ if (strat == &stratdummy) /* If node is empty dummy node */ return (0); /* Return without freeing it */ break; case STRATNODEMETHOD : /* Method strategy node */ paratab = strat->tabl->paratab; /* Free the method parameters */ for (i = 0; paratab[i].name != NULL; i ++) { if ((paratab[i].meth == strat->data.method.meth) && /* For all parameters of that method */ (paratab[i].type == STRATPARAMSTRAT)) { /* Which are non-deprecated strategy parameters */ paraofft = (byte *) &strat->data.method.data + /* Compute parameter offset within method */ (paratab[i].dataofft - paratab[i].database); o |= stratExit (*((Strat **) paraofft)); /* Perform recursion */ } } break; #ifdef SCOTCH_DEBUG_PARSER2 default : errorPrint ("stratExit: invalid strategy node"); o = 1; break; #endif /* SCOTCH_DEBUG_PARSER2 */ } memFree (strat); /* Free strategy structure itself */ return (o); /* Return output code */ } /* This routine displays the given ** strategy structure. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int stratSave ( const Strat * const strat, FILE * const stream) { unsigned int paraflag; /* Flag set if method has parameters */ StratParamTab * paratab; /* Pointer to method parameter table */ byte * paraofft; /* Offset of parameter within method structure */ unsigned int i; int o; o = 0; switch (strat->type) { /* Recursively view sub-strategies */ case STRATNODECOND : if ((fprintf (stream, "(/(") == EOF) || (stratTestSave (strat->data.cond.test, stream) != 0) || (fprintf (stream, ")?(") == EOF) || (stratSave (strat->data.cond.strat[0], stream) != 0)) o = 1; if ((o == 0) && (strat->data.cond.strat[1] != NULL)) { if ((fprintf (stream, "):(") == EOF) || (stratSave (strat->data.cond.strat[1], stream) != 0)) o = 1; } if (o == 0) o = (fprintf (stream, ");)") == EOF); break; case STRATNODECONCAT : if ((stratSave (strat->data.concat.strat[0], stream) != 0) || (stratSave (strat->data.concat.strat[1], stream) != 0)) o = 1; break; case STRATNODESELECT : if ((fprintf (stream, "(") == EOF) || (stratSave (strat->data.select.strat[0], stream) != 0) || (fprintf (stream, "|") == EOF) || (stratSave (strat->data.select.strat[1], stream) != 0) || (fprintf (stream, ")") == EOF)) o = 1; case STRATNODEEMPTY : break; case STRATNODEMETHOD : if (fprintf (stream, "%s", strat->tabl->methtab[strat->data.method.meth].name) == EOF) { /* Print method name */ o = 1; break; } paraflag = 0; /* No method parameters seen yet */ paratab = strat->tabl->paratab; for (i = 0; paratab[i].name != NULL; i ++) { if ((paratab[i].meth == strat->data.method.meth) && /* For all parameters of that method */ ((paratab[i].type & STRATPARAMDEPRECATED) == 0)) { /* Which are not deprecated */ paraofft = (byte*) &strat->data.method.data + /* Compute parameter offset within method */ (paratab[i].dataofft - paratab[i].database); if (fprintf (stream, "%c%s=", /* Open or continue parameter list */ ((paraflag ++ == 0) ? '{' : ','), paratab[i].name) == EOF) { o = 1; break; } switch (paratab[i].type) { /* Print parameter value */ case STRATPARAMCASE : /* Case value */ o = (fprintf (stream, "%c", /* Print corresponding character */ ((char *) paratab[i].datasltr)[*((unsigned int *) paraofft)]) == EOF); break; case STRATPARAMINT : /* Integer value */ o = (fprintf (stream, INTSTRING, *((INT *) paraofft)) == EOF); break; case STRATPARAMDOUBLE : /* Double value */ o = (fprintf (stream, "%g", *((double *) paraofft)) == EOF); break; case STRATPARAMSTRAT : /* Strategy */ o = stratSave (*((Strat **) paraofft), stream); /* Perform recursion */ break; case STRATPARAMSTRING : /* String value */ o = (fprintf (stream, "%s", (char *) paraofft) == EOF); break; #ifdef SCOTCH_DEBUG_PARSER2 default : errorPrint ("stratSave: invalid parameter type"); return (1); #endif /* SCOTCH_DEBUG_PARSER2 */ } } if (o != 0) /* If an error has occured */ break; /* Abort the loop */ } if ((o == 0) && (paraflag != 0)) /* If there is a parameter list */ o |= (fprintf (stream, "}") == EOF); /* Close it */ break; #ifdef SCOTCH_DEBUG_PARSER2 default : errorPrint ("stratSave: invalid strategy node"); return (1); #endif /* SCOTCH_DEBUG_PARSER2 */ } if (o != 0) { errorPrint ("stratSave: bad output"); } return (o); } /*****************************************/ /* */ /* These routines handle strategy tests. */ /* */ /*****************************************/ /* This routine evaluates the ** given condition. ** It returns: ** - 0 : on success; eval updated. ** - !0 : on error. */ int stratTestEval ( const StratTest * restrict const test, StratTest * restrict const eval, /*+ Place where to return final value +*/ const void * restrict const data) /*+ Pointer to data structure where to read variables from +*/ { StratTest val[2]; /* Temporary evaluation variables */ StratTestType sign; /* Sign of comparison */ int o; #ifdef SCOTCH_DEBUG_PARSER1 if ((test == NULL) || (eval == NULL) || (data == NULL)) { errorPrint ("stratTestEval: invalid parameter"); return (1); } #endif /* SCOTCH_DEBUG_PARSER1 */ o = 0; /* Assume no error */ switch (test->typetest) { case STRATTESTNOT : /* Not operator */ o = stratTestEval (test->data.test[0], eval, data); #ifdef SCOTCH_DEBUG_PARSER2 if ((o == 0) && (eval->typenode != STRATPARAMLOG)) { errorPrint ("stratTestEval: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_PARSER2 */ eval->data.val.vallog = 1 - eval->data.val.vallog; break; case STRATTESTAND : /* And operator */ o = stratTestEval (test->data.test[0], eval, data); #ifdef SCOTCH_DEBUG_PARSER2 if ((o == 0) && (eval->typenode != STRATPARAMLOG)) { errorPrint ("stratTestEval: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_PARSER2 */ if ((o == 0) && (eval->data.val.vallog == 1)) { o = stratTestEval (test->data.test[1], eval, data); #ifdef SCOTCH_DEBUG_PARSER2 if (eval->typenode != STRATPARAMLOG) { errorPrint ("stratTestEval: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_PARSER2 */ } break; case STRATTESTOR : /* Or operator */ o = stratTestEval (test->data.test[0], eval, data); #ifdef SCOTCH_DEBUG_PARSER2 if ((o == 0) && (eval->typenode != STRATPARAMLOG)) { errorPrint ("stratTestEval: internal error (4)"); return (1); } #endif /* SCOTCH_DEBUG_PARSER2 */ if ((o == 0) && (eval->data.val.vallog == 0)) { o = stratTestEval (test->data.test[1], eval, data); #ifdef SCOTCH_DEBUG_PARSER2 if (eval->typenode != STRATPARAMLOG) { errorPrint ("stratTestEval: internal error (5)"); return (1); } #endif /* SCOTCH_DEBUG_PARSER2 */ } break; case STRATTESTLT : /* Less-than operator */ case STRATTESTEQ : /* Equal-to operator */ case STRATTESTGT : /* Greater-than operator */ o = stratTestEval (test->data.test[0], &val[0], data); o |= stratTestEval (test->data.test[1], &val[1], data); o |= stratTestEvalCast (&val[0], &val[1]); if (o != 0) break; sign = STRATTESTNBR; /* In case of error */ switch (val[0].typenode) { case STRATPARAMDOUBLE : sign = (val[0].data.val.valdbl < val[1].data.val.valdbl) ? STRATTESTLT : ((val[0].data.val.valdbl > val[1].data.val.valdbl) ? STRATTESTGT : STRATTESTEQ); break; case STRATPARAMINT : sign = (val[0].data.val.valint < val[1].data.val.valint) ? STRATTESTLT : ((val[0].data.val.valint > val[1].data.val.valint) ? STRATTESTGT : STRATTESTEQ); break; #ifdef SCOTCH_DEBUG_PARSER2 default : errorPrint ("stratTestEval: internal error (6)"); o = 1; break; #endif /* SCOTCH_DEBUG_PARSER2 */ } eval->typenode = STRATPARAMLOG; /* Build test result */ eval->data.val.vallog = (sign == test->typetest); break; case STRATTESTADD : /* Addition operator */ o = stratTestEval (test->data.test[0], &val[0], data); o |= stratTestEval (test->data.test[1], &val[1], data); o |= stratTestEvalCast (&val[0], &val[1]); if (o != 0) break; if (val[0].typenode == STRATPARAMDOUBLE) eval->data.val.valdbl = val[0].data.val.valdbl + val[1].data.val.valdbl; else eval->data.val.valint = val[0].data.val.valint + val[1].data.val.valint; eval->typenode = val[0].typenode; break; case STRATTESTSUB : /* Subtraction operator */ o = stratTestEval (test->data.test[0], &val[0], data); o |= stratTestEval (test->data.test[1], &val[1], data); o |= stratTestEvalCast (&val[0], &val[1]); if (o != 0) break; if (val[0].typenode == STRATPARAMDOUBLE) eval->data.val.valdbl = val[0].data.val.valdbl - val[1].data.val.valdbl; else eval->data.val.valint = val[0].data.val.valint - val[1].data.val.valint; eval->typenode = val[0].typenode; break; case STRATTESTMUL : /* Multiplication operator */ o = stratTestEval (test->data.test[0], &val[0], data); o |= stratTestEval (test->data.test[1], &val[1], data); o |= stratTestEvalCast (&val[0], &val[1]); if (o != 0) break; if (val[0].typenode == STRATPARAMDOUBLE) eval->data.val.valdbl = val[0].data.val.valdbl * val[1].data.val.valdbl; else eval->data.val.valint = val[0].data.val.valint * val[1].data.val.valint; eval->typenode = val[0].typenode; break; case STRATTESTMOD : /* Modulus operator */ o = stratTestEval (test->data.test[0], &val[0], data); o |= stratTestEval (test->data.test[1], &val[1], data); o |= stratTestEvalCast (&val[0], &val[1]); if (o != 0) break; if (val[0].typenode == STRATPARAMDOUBLE) eval->data.val.valdbl = fmod (val[0].data.val.valdbl, val[1].data.val.valdbl); else eval->data.val.valint = val[0].data.val.valint % val[1].data.val.valint; eval->typenode = val[0].typenode; break; case STRATTESTVAL : /* Constant value */ *eval = *test; /* Copy value */ break; case STRATTESTVAR : /* Variable */ switch (test->typenode) { case STRATPARAMDOUBLE : eval->data.val.valdbl = *((double *) ((byte *) data + test->data.var.datadisp)); break; case STRATPARAMINT : eval->data.val.valint = *((INT *) ((byte *) data + test->data.var.datadisp)); break; #ifdef SCOTCH_DEBUG_PARSER1 default : errorPrint ("stratTestEval: internal error (7)"); o = 1; break; #endif /* SCOTCH_DEBUG_PARSER1 */ } eval->typenode = test->typenode; break; #ifdef SCOTCH_DEBUG_PARSER1 default : errorPrint ("stratTestEval: invalid condition type (%u)", test->typetest); o = 1; break; #endif /* SCOTCH_DEBUG_PARSER1 */ } eval->typetest = STRATTESTVAL; return (o); } /* This routine casts the type of one ** of the two input values so as to ** get the same type for both values. ** It returns: ** - VOID : in all cases; */ static int stratTestEvalCast ( StratTest * const test0, StratTest * const test1) { #ifdef SCOTCH_DEBUG_PARSER2 if (((test0->typenode != STRATPARAMINT) && (test0->typenode != STRATPARAMDOUBLE)) || ((test1->typenode != STRATPARAMINT) && (test1->typenode != STRATPARAMDOUBLE))) { errorPrint ("stratTestEvalCast: internal error"); return (1); } #endif /* SCOTCH_DEBUG_PARSER2 */ if (test0->typenode != test1->typenode) { /* If value types differ */ if (test0->typenode == STRATPARAMDOUBLE) { test1->typenode = STRATPARAMDOUBLE; test1->data.val.valdbl = (double) test1->data.val.valint; } else { test0->typenode = STRATPARAMDOUBLE; test0->data.val.valdbl = (double) test0->data.val.valint; } } return (0); } /* This routine fres the given ** strategy condition. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int stratTestExit ( StratTest * const test) { int o; /* Output condition flag */ #ifdef SCOTCH_DEBUG_PARSER1 if (test == NULL) { errorPrint ("stratTestExit: invalid parameter"); return (1); } #endif /* SCOTCH_DEBUG_PARSER1 */ o = 0; switch (test->typetest) { case STRATTESTNOT : /* Not operator */ o = stratTestExit (test->data.test[0]); /* Free the son */ break; case STRATTESTAND : /* And operator */ case STRATTESTOR : /* Or operator */ case STRATTESTLT : /* Less-than operator */ case STRATTESTEQ : /* Equal-to operator */ case STRATTESTGT : /* Greater-than operator */ case STRATTESTMOD : /* Modulus operator */ case STRATTESTMUL : /* Multiplication operator */ case STRATTESTADD : /* Addition operator */ case STRATTESTSUB : /* Subtraction operator */ o = stratTestExit (test->data.test[0]); /* Free the sons */ o |= stratTestExit (test->data.test[1]); break; case STRATTESTVAL : /* Constant value */ case STRATTESTVAR : /* Variable */ break; #ifdef SCOTCH_DEBUG_PARSER1 default : errorPrint ("stratTestExit: invalid condition type (%u)", test->typetest); o = 1; break; #endif /* SCOTCH_DEBUG_PARSER1 */ } memFree (test); /* Free the structure */ return (o); } /* This routine displays the ** given strategy condition. ** It returns: ** - 0 : on success. ** - !0 : on error. */ static char strattestsaveop[STRATTESTNBR] = "|&!=><+-*%##"; static char * strattestsavepa[2][2] = { { "(", ")" }, { "", "" } }; int stratTestSave ( const StratTest * const test, FILE * const stream) { int i; int o; #ifdef SCOTCH_DEBUG_PARSER1 if ((test == NULL) || (stream == NULL)) { errorPrint ("stratTestSave: invalid parameter"); return (1); } #endif /* SCOTCH_DEBUG_PARSER1 */ o = 0; /* Assume no error */ switch (test->typetest) { case STRATTESTNOT : /* Not operator */ if ((fprintf (stream, "!(") == EOF) || (stratTestSave (test->data.test[0], stream) != 0) || (fprintf (stream, ")") == EOF)) o = 1; break; case STRATTESTAND : /* And operator */ case STRATTESTOR : /* Or operator */ case STRATTESTEQ : /* Equal-to operator */ case STRATTESTGT : /* Greater-than operator */ case STRATTESTLT : /* Less-than operator */ case STRATTESTADD : /* Addition operator */ case STRATTESTSUB : /* Subtraction operator */ case STRATTESTMUL : /* Multiplication operator */ case STRATTESTMOD : /* Modulus operator */ i = (test->data.test[0]->typetest < test->typetest) ? 1 : 0; fprintf (stream, "%s", strattestsavepa[i][0]); o = stratTestSave (test->data.test[0], stream); fprintf (stream, "%s", strattestsavepa[i][1]); if (o == 0) { fprintf (stream, "%c", strattestsaveop[test->typetest]); i = (test->data.test[1]->typetest < test->typetest) ? 1 : 0; fprintf (stream, "%s", strattestsavepa[i][0]); stratTestSave (test->data.test[1], stream); fprintf (stream, "%s", strattestsavepa[i][1]); } break; case STRATTESTVAL : /* Constant value */ switch (test->typenode) { case STRATPARAMDOUBLE : o = (fprintf (stream, "%lf", test->data.val.valdbl) == EOF); break; case STRATPARAMINT : o = (fprintf (stream, INTSTRING, (INT) test->data.val.valint) == EOF); break; #ifdef SCOTCH_DEBUG_PARSER2 default : errorPrint ("stratTestSave: invalid value type"); o = 1; #endif /* SCOTCH_DEBUG_PARSER2 */ } break; case STRATTESTVAR : /* Variable */ for (i = 0; test->data.var.datatab->condtab[i].name != NULL; i ++) { if ((test->data.var.datatab->condtab[i].dataofft - test->data.var.datatab->condtab[i].database) == test->data.var.datadisp) break; } if (test->data.var.datatab->condtab[i].name == NULL) { errorPrint ("stratTestSave: invalid variable displacement"); return (1); } o = (fprintf (stream, "%s", test->data.var.datatab->condtab[i].name) == EOF); break; #ifdef SCOTCH_DEBUG_PARSER2 default : errorPrint ("stratTestSave: invalid condition type (%u)", test->typetest); o = 1; #endif /* SCOTCH_DEBUG_PARSER2 */ } return (o); } scotch-6.0.4.dfsg/src/libscotch/library_graph_io_mmkt_f.c0000644002563400244210000001633211631447171026661 0ustar trophimeutilisateurs du domaine/* Copyright 2008,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_io_mmkt_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the Fortran API for the **/ /** graph i/o routines of the libSCOTCH **/ /** library. **/ /** **/ /** DATES : # Version 5.0 : from : 14 mar 2008 **/ /** to 14 mar 2008 **/ /** # Version 5.1 : from : 11 oct 2008 **/ /** to 27 mar 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the mapping routines. */ /* */ /**************************************/ /* String lengths are passed at the very ** end of the argument list. */ FORTRAN ( \ SCOTCHFGRAPHGEOMLOADMMKT, scotchfgraphgeomloadmmkt, ( \ SCOTCH_Graph * const grafptr, \ SCOTCH_Geom * const geomptr, \ const int * const filegrfptr, \ const int * const filegeoptr, \ const char * const dataptr, /* No use */ \ int * const revaptr, \ const int datanbr), \ (grafptr, geomptr, filegrfptr, filegeoptr, dataptr, revaptr, datanbr)) { FILE * filegrfstream; /* Streams to build from handles */ FILE * filegeostream; int filegrfnum; /* Duplicated handle */ int filegeonum; int o; if ((filegrfnum = dup (*filegrfptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFGRAPHGEOMLOADMMKT: cannot duplicate handle (1)"); *revaptr = 1; /* Indicate error */ return; } if ((filegeonum = dup (*filegeoptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFGRAPHGEOMLOADMMKT: cannot duplicate handle (2)"); close (filegrfnum); *revaptr = 1; /* Indicate error */ return; } if ((filegrfstream = fdopen (filegrfnum, "r")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFGRAPHGEOMLOADMMKT: cannot open input stream (1)"); close (filegrfnum); close (filegeonum); *revaptr = 1; return; } if ((filegeostream = fdopen (filegeonum, "r")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFGRAPHGEOMLOADMMKT: cannot open input stream (2)"); fclose (filegrfstream); close (filegeonum); *revaptr = 1; return; } o = SCOTCH_graphGeomLoadMmkt (grafptr, geomptr, filegrfstream, filegeostream, NULL); fclose (filegrfstream); /* This closes file descriptors too */ fclose (filegeostream); *revaptr = o; } /* String lengths are passed at the very ** end of the argument list. */ FORTRAN ( \ SCOTCHFGRAPHGEOMSAVEMMKT, scotchfgraphgeomsavemmkt, ( \ const SCOTCH_Graph * const grafptr, \ const SCOTCH_Geom * const geomptr, \ const int * const filegrfptr, \ const int * const filegeoptr, \ const char * const dataptr, /* No use */ \ int * const revaptr, \ const int datanbr), \ (grafptr, geomptr, filegrfptr, filegeoptr, dataptr, revaptr, datanbr)) { FILE * filegrfstream; /* Streams to build from handles */ FILE * filegeostream; int filegrfnum; /* Duplicated handle */ int filegeonum; int o; if ((filegrfnum = dup (*filegrfptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFGRAPHGEOMSAVEMMKT: cannot duplicate handle (1)"); *revaptr = 1; /* Indicate error */ return; } if ((filegeonum = dup (*filegeoptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFGRAPHGEOMSAVEMMKT: cannot duplicate handle (2)"); close (filegrfnum); *revaptr = 1; /* Indicate error */ return; } if ((filegrfstream = fdopen (filegrfnum, "w")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFGRAPHGEOMSAVEMMKT: cannot open output stream (1)"); close (filegrfnum); close (filegeonum); *revaptr = 1; return; } if ((filegeostream = fdopen (filegeonum, "w")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFGRAPHGEOMSAVEMMKT: cannot open output stream (2)"); fclose (filegrfstream); close (filegeonum); *revaptr = 1; return; } o = SCOTCH_graphGeomSaveMmkt (grafptr, geomptr, filegrfstream, filegeostream, NULL); fclose (filegrfstream); /* This closes file descriptors too */ fclose (filegeostream); *revaptr = o; } scotch-6.0.4.dfsg/src/libscotch/graph_list.h0000644002563400244210000001124611631447170024147 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : graph_list.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the source graph functions. **/ /** **/ /** DATES : # Version 0.0 : from : 02 dec 1992 **/ /** to 18 may 1993 **/ /** # Version 1.3 : from : 30 apr 1994 **/ /** to 18 may 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to 18 aug 1994 **/ /** # Version 3.0 : from : 07 jul 1995 **/ /** to 28 sep 1995 **/ /** # Version 3.1 : from : 28 nov 1995 **/ /** to 28 nov 1995 **/ /** # Version 3.2 : from : 07 sep 1996 **/ /** to 15 sep 1998 **/ /** # Version 3.3 : from : 28 sep 1998 **/ /** to 23 mar 1999 **/ /** # Version 3.4 : from : 20 mar 2000 **/ /** to 20 mar 2000 **/ /** # Version 4.0 : from : 24 nov 2001 **/ /** to 27 sep 2002 **/ /** # Version 5.1 : from : 04 nov 2010 **/ /** to 04 nov 2010 **/ /** **/ /************************************************************/ #define GRAPH_LIST_H /* ** The type and structure definitions. */ /*+ The vertex list structure. Since a vertex list always refers to a given graph, vertex indices contained in the vertex list array are based with respect to the base value of the associated graph. However, the array itself is not based. +*/ typedef struct VertList_ { Gnum vnumnbr; /*+ Number of vertices in list +*/ Gnum * vnumtab; /*+ Pointer to vertex array +*/ } VertList; /* ** The function prototypes. */ #ifndef GRAPH_LIST #define static #endif int listInit (VertList *); void listExit (VertList *); int listAlloc (VertList *, Gnum); int listFree (VertList *); int listLoad (VertList *, FILE *); int listSave (VertList *, FILE *); void listSort (VertList *); int listCopy (VertList *, VertList *); #undef static scotch-6.0.4.dfsg/src/libscotch/hall_order_hf.c0000644002563400244210000013060512375145321024576 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hall_order_hf.c **/ /** **/ /** AUTHOR : Patrick AMESTOY **/ /** Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module orders a halo graph or mesh **/ /** structure using the block-oriented Halo **/ /** Approximate (Multiple) Minimum Fill **/ /** algorithm, with super-variable **/ /** accounting R2HAMDf4 (v2.0). **/ /** **/ /** DATES : # Version 3.4 : from : 15 may 2001 **/ /** to : 23 nov 2001 **/ /** # Version 4.0 : from : 10 jan 2003 **/ /** to : 29 aug 2007 **/ /** # Version 5.1 : from : 08 dec 2010 **/ /** to : 08 dec 2010 **/ /** # Version 6.0 : from : 08 mar 2012 **/ /** to : 08 mar 2012 **/ /** **/ /** NOTES : # This module contains pieces of code **/ /** that belong to other people; see **/ /** below. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HALL_ORDER_HF #include "module.h" #include "common.h" #include "graph.h" #include "hall_order_hf.h" /* -- translated by f2c (version 19970219). */ /** -------------------------------------------------------------------- **/ /** December 8th 2003 **/ /** Unique version for both graph of variables and graphs of elements **/ /** Let us refer to as **/ /** Gv a graph with only variables **/ /** Ge a graph with both variables and elements **/ /** **/ /** Notations used: **/ /** **/ /** Let V be the set of nodes **/ /** V = Ve + V0 + V1 **/ /** V0 = Set of variable nodes (not in halo) **/ /** V1 = Set of variable nodes (in halo) **/ /** Ve = Set of element nodes **/ /** **/ /** All 3 sets are disjoint, Ve and V1 can be empty **/ /** **/ /** Modifications w.r.t. previous version : **/ /** **/ /** New Input: **/ /** --------- **/ /** nbelts : integer holding size of Ve **/ /** =0 if Gv (graph of variables) **/ /** >0 if Ge **/ /** **/ /** Extension of the meaning of input entry len for nodes in Ve **/ /** --------- **/ /** len(i) = | Adj(i) | if i \in V0 U Ve **/ /** ( Note that in the case of a GE graph **/ /** if v\in V0 then len(v) = nb of elements adjacent to v ) **/ /** len(i) = - | Adj(i) | if i \in V1 **/ /** or -N -1 if | Adj(i) | = 0 and i \in V1 **/ /** **/ /** Modified the meaning of input entry elen **/ /** --------- **/ /** if e \in Ve then elen (e) = -N-1 **/ /** if v \in V0 then elen (v) = External degree of v **/ /** Gv : elen (v) = len(v) **/ /** Ge : elen (v) **/ /** should be computed in SCOTCH **/ /** if v \in V1 then elen (v) = 0 **/ /** **/ /** **/ /** Output is unchanged **/ /** --------- **/ /** **/ /** **/ /** End remarks done on December 8th 2003 **/ /** ---------------------------------------------------------------------**/ /** **/ /** **/ /** AMF4 (version used on newton for uns tests) **/ /** given to Francois on Nov 31 2000 **/ /** Approximation of level4 of the minimum fill heuristic **/ /** (best approx of Min fill currently available based on collaborative **/ /** work between P. Amestoy, T. Davis and I. Duff) **/ /** **/ /** Remarks: **/ /** ------- **/ /** 1/ !!!!!!!! WARNING !!!!!!!!!! **/ /** TWO additionnal parameters w.r.t HALOAMD **/ /** -------------------------- **/ /** NBBUCK : integer greater than 1 (advised value is 2*N) **/ /** HEAD : HEAD(0:NBBUCK+1) integer array of size NBBUCK+2 **/ /** NOTE that it starts at index 0 !! **/ /** **/ /** 2/ Interface for MA41 or SCOTCH **/ /** **/ /** 3/ Nodes of V1 are amalgamated in one root supervariable **/ /** the complete tree (of V0+V1) is correct in the sense of **/ /** MC47B output interface (NV for V1 nodes is ok). **/ /** Output data (PE,NV) can then be exploited by MA41LD. **/ /** Variable in V1 cannot be characterized on output. **/ /** -------------------------------------------------------------------- **/ void hallOrderHfR2hamdf4 ( const Gnum n, /* Matrix order */ const Gnum nbelts, /* Number of elements */ const Gnum nbbuck, /* Number of buckets */ const Gnum iwlen, /* Length of array iw */ Gnum * restrict pe /* [] */, /* Array of indexes in iw of start of row i */ Gnum pfree, /* Useful size in iw */ Gnum * restrict len /* [] */, /* Array of lengths of adjacency lists */ Gnum * restrict iw /* [] */, /* Adjacency list array */ Gnum * restrict nv /* [] */, /* Array of element degrees */ Gnum * restrict elen /* [] */, /* Array that holds the inverse permutation */ Gnum * restrict last /* [] */, /* Array that holds the permutation */ Gnum * restrict ncmpaptr, /* Number of times array iw was compressed */ Gnum * restrict degree /* [] */, /* Array that holds degree data */ Gnum * restrict wf /* [] */, /* Flag array */ Gnum * restrict next /* [] */, /* Linked list structure */ Gnum * restrict w /* [] */, /* Flag array */ Gnum * restrict head /* [] */) /* Linked list structure */ { Gnum hash, pend, hmod, lenj, dmax, wflg, dext, psrc, pdst, wnvi, e, i, j, k, p, degme, x, nelme, nreal, lastd, nleft, ilast, jlast, inext, jnext, n2, p1, nvpiv, p2, p3, me = 0, nbflag, ln, we, pj, pn, mindeg, elenme, slenme, maxmem, newmem, wf3, wf4, deg, eln, mem, nel, pme, pas, nvi, nvj, pme1, pme2, knt1, knt2, knt3; Gnum ncmpa; float rmf, rmf1; /** Min fill approximation one extra array of size NBBUCK+2 is needed **/ /** INTEGER HEAD(0:NBBUCK+1) **/ /** -------------------------------------------------------------------- **/ /** HALOAMD_V6: (January 1999, P. Amestoy) **/ /** *********** **/ /** 1/ ERROR 2 detection followed by stop statement suppressed. **/ /** 2/ Pb 1 identified in V5 was not correctly solved. **/ /** **/ /** HALOAMD_V5: (December 1998, P. Amestoy) **/ /** *********** **/ /** 1/ Solved problem with matrix psmigr 1, because upper bound degree **/ /** DEG>N was considered as a node of V1. **/ /** **/ /** HALOAMD_V4: (October 1998, P. Amestoy) **/ /** *********** **/ /** Only MA41 interface (ok for both scotch and MA41) is included in **/ /** this file. **/ /** **/ /** HALOAMD_V3: (August 1998, P. Amestoy) **/ /** ********** **/ /** Solved problem in version 2: variables of V1 with len(i)=0 were not **/ /** well processed. See modification of the input to characterize those **/ /** variables. **/ /** Problem detected by Jacko Koster while experimenting with C version **/ /** 2 of haloAMD in the context of multiple front method based on **/ /** MA27: "if for an interface variable i, row i in the matrix has only **/ /** a nonzero entry on the diagonal, we first remove this entry and **/ /** len(i) is set to zero on input to HALOAMD. However, this means that **/ /** HALOAMD will treat variable i as an interior variable (in V0) **/ /** instead as an interface variable (in V1). It is indeed a bit **/ /** strange to have such interface variables but we encountered some **/ /** in our debugging experiments with some random partitionings. **/ /** Solution: **/ /** IF on input i \in V1 and len(i)=0 (that is adjlist(i)={}) THEN **/ /** len(i) must be set on input to -N-1. **/ /** ENDIF **/ /** Therefore, all variables i / len(i) < 0 and only those are in V1. **/ /** Variables with len(i) = -N-1 are then processed differently at the **/ /** beginning of the code. **/ /** **/ /** HALOAMD_V2: (April 1998) **/ /** ********** **/ /** The end of the tree (including links to block of flagged indices **/ /** is built) . The list of flagged indices is considered as a dense **/ /** amalgamated node. **/ /** Tested on rosanna: ~amestoy/MA41_NEW/SUN_RISC_dbl/SOFT **/ /** **/ /** Comments on the OUTPUT: **/ /** ---------------------- **/ /** **/ /** Let V= V0 U V1 the nodes of the initial graph (|V|=n). **/ /** The assembly tree corresponds to the tree of the supernodes (or **/ /** supervariables). Each node of the assembly tree is then composed of **/ /** one principal variable and a list of secondary variables. The list **/ /** of variable of a node (principal + secondary variables) then **/ /** describes the structure of the diagonal bloc of the supernode. **/ /** The elimination tree denotes the tree of all the variables(=nodes) **/ /** and is therefore of order n. The arrays NV(N) and PE(N) give a **/ /** description of the assembly tree. **/ /** **/ /** 1/ Description of array nv(N) (on OUPUT) **/ /** nv(i)=0 i is a secondary variable. **/ /** N+1> nv(i) >0 i is a principal variable, nv(i) holds the number **/ /** of elements in column i of L (true degree of i) **/ /** nv(i) = N+1 then i is a flagged variable (belonging to V1) **/ /** **/ /** 2/ Description of array PE(N) (on OUPUT) **/ /** pe(i) = -(father of variable/node i) in the elimination tree. **/ /** If nv (i) .gt. 0, then i represents a node in the assembly tree, **/ /** and the parent of i is -pe (i), or zero if i is a root. **/ /** If nv (i) = 0, then (i,-pe (i)) represents an edge in a **/ /** subtree, the root of which is a node in the assembly tree. **/ /** **/ /** 3/ Example: **/ /** Let If be a root node father of Is in the assembly tree. **/ /** If is the principal variable of the node If and let If1, If2, If3 **/ /** be the secondary variables of node If. Is is the principal **/ /** variable of the node Is and let Is1, Is2 be the secondary **/ /** variables of node Is. **/ /** Then: **/ /** NV(If1)=NV(If2)=NV(If3) = 0 (secondary variables) **/ /** NV(Is1)=NV(Is2) = 0 (secondary variables) **/ /** NV(If) > 0 (principal variable) **/ /** NV(Is) > 0 (principal variable) **/ /** PE(If) = 0 (root node) **/ /** PE(Is) = -If (If is the father of Is in the assembly tree) **/ /** PE(If1)=PE(If2)=PE(If3)= -If (If is the principal variable) **/ /** PE(Is1)=PE(Is2)= -Is (Is is the principal variable) **/ /** **/ /** HALOAMD_V1: (September 1997) **/ /** ********** **/ /** Initial version designed to experiment the numerical (fill-in) **/ /** impact of taking into account the halo. This code should be able to **/ /** experiment no-halo, partial halo, complete halo. **/ /** -------------------------------------------------------------------- **/ /** HALOAMD is designed to process a graph composed of two types **/ /** of nodes, V0 and V1, extracted from a larger gragh. **/ /** V0^V1 = {}, **/ /** We used Min. degree heuristic to order only **/ /** nodes in V0, but the adjacency to nodes **/ /** in V1 is taken into account during ordering. **/ /** Nodes in V1 are odered at last. **/ /** Adjacency between nodes of V1 need not be provided, **/ /** however |len(i)| must always corresponds to the number of **/ /** edges effectively provided in the adjacency list of i. **/ /** On input : **/ /** ******** **/ /** Nodes INODE in V1 are flagged with len(INODE) = -degree **/ /** Update version HALO V3 (August 1998): **/ /** if len(i)=0 and i \in V1 then len(i) must be set **/ /** on input to -N-1. **/ /** ERROR return : **/ /** ************ **/ /** Negative value in ncmpa indicates an error detected **/ /** by HALOAMD. **/ /** **/ /** The graph provided MUST follow the rule: **/ /** if (i,j) is an edge in the gragh then **/ /** j must be in the adjacency list of i AND **/ /** i must be in the adjacency list of j. **/ /** **/ /** REMARKS : **/ /** ------- **/ /** 1/ Providing edges between nodes of V1 should not **/ /** affect the final ordering, only the amount of edges **/ /** of the halo should effectively affect the solution. **/ /** This code should work in the following cases: **/ /** 1/ halo not provided **/ /** 2/ halo partially provided **/ /** 3/ complete halo **/ /** 4/ complete halo+interconnection between nodes of V1. **/ /** **/ /** 1/ should run and provide identical results (w.r.t to **/ /** current implementation of AMD in SCOTCH). **/ /** 3/ and 4/ should provide identical results. **/ /** **/ /** 2/ All modifications of the MC47 initial code are indicated **/ /** with begin HALO .. end HALO **/ /** **/ /** Ordering of nodes in V0 is based on Approximate Minimum Degree **/ /** ordering algorithm, with aggressive absorption: **/ /** Given a representation of the nonzero pattern of a symmetric matrix, **/ /** A, (excluding the diagonal) perform an approximate minimum **/ /** (UMFPACK/MA38-style) degree ordering to compute a pivot order **/ /** such that fill-in in the Cholesky **/ /** factors A = LL^T is kept low. At each step, the pivot **/ /** selected is the one with the minimum UMFPACK/MA38-style **/ /** upper-bound on the external degree. Aggresive absorption is **/ /** used to tighten the bound on the degree. This can result an **/ /** significant improvement in the quality of the ordering for **/ /** some matrices. **/ /** The approximate degree algorithm implemented here is the **/ /** symmetric analogue of the degree update algorithm in MA38, by **/ /** Davis and Duff, also in the Harwell Subroutine Library. **/ /** **/ /** **** CAUTION: ARGUMENTS ARE NOT CHECKED FOR ERRORS ON INPUT. ***** **/ /** ** If you want error checking, a more versatile input format, and ** **/ /** ** a simpler user interface, then use MC47A/AD in the Harwell ** **/ /** ** Subroutine Library, which checks for errors, transforms the ** **/ /** ** input, and calls MC47B/BD. ** **/ /** ******************************************************************** **/ /** References: (UF Tech Reports are available via anonymous ftp **/ /** to ftp.cis.ufl.edu:cis/tech-reports). **/ /** [1] Timothy A. Davis and Iain Duff, "An unsymmetric-pattern **/ /** multifrontal method for sparse LU factorization", **/ /** SIAM J. Matrix Analysis and Applications, to appear. **/ /** also Univ. of Florida Technical Report TR-94-038. **/ /** Discuss UMFPACK / MA38. **/ /** [2] Patrick Amestoy, Timothy A. Davis, and Iain S. Duff, **/ /** "An approximate minimum degree ordering algorithm," **/ /** SIAM J. Matrix Analysis and Applications (to appear), **/ /** also Univ. of Florida Technical Report TR-94-039. **/ /** Discusses this routine. **/ /** [3] Alan George and Joseph Liu, "The evolution of the **/ /** minimum degree ordering algorithm," SIAM Review, vol. **/ /** 31, no. 1, pp. 1-19, March 1989. We list below the **/ /** features mentioned in that paper that this code **/ /** includes: **/ /** mass elimination: **/ /** Yes. MA27 relied on supervariable detection for mass **/ /** elimination. **/ /** indistinguishable nodes: **/ /** Yes (we call these "supervariables"). This was also **/ /** in the MA27 code - although we modified the method of **/ /** detecting them (the previous hash was the true degree, **/ /** which we no longer keep track of). A supervariable is **/ /** a set of rows with identical nonzero pattern. All **/ /** variables in a supervariable are eliminated together. **/ /** Each supervariable has as its numerical name that of **/ /** one of its variables (its principal variable). **/ /** quotient graph representation: **/ /** Yes. We use the term "element" for the cliques formed **/ /** during elimination. This was also in the MA27 code. **/ /** The algorithm can operate in place, but it will work **/ /** more efficiently if given some "elbow room." **/ /** element absorption: **/ /** Yes. This was also in the MA27 code. **/ /** external degree: **/ /** Yes. The MA27 code was based on the true degree. **/ /** incomplete degree update and multiple elimination: **/ /** No. This was not in MA27, either. Our method of **/ /** degree update within MC47B/BD is element-based, not **/ /** variable-based. It is thus not well-suited for use **/ /** with incomplete degree update or multiple elimination. **/ /** -------------------------------------------------------------------- **/ /** Authors, and Copyright (C) 1995 by: **/ /** Timothy A. Davis, Patrick Amestoy, Iain S. Duff, & **/ /** John K. Reid. **/ /** Modified (V1) by P.R. Amestoy ENSEEIHT (1997) **/ /** Modified (V2) by P.R. Amestoy ENSEEIHT (1998) **/ /** Modified (V3) by P.R. Amestoy ENSEEIHT (1998) **/ /** Modified (V4) by P.R. Amestoy ENSEEIHT (1998) **/ /** Modified (V5) by P.R. Amestoy ENSEEIHT (1998) **/ /** Modified (V6) by P.R. Amestoy ENSEEIHT (1999) **/ /** **/ /** Dates: September, 1995 **/ /** September, 1997 (halo AMD V1) **/ /** April, 1998 (halo AMD V2) **/ /** August, 1998 (halo AMD V3) **/ -- w; /* Parameter adjustments */ -- next; -- wf; -- degree; -- last; -- elen; -- nv; -- len; -- pe; -- iw; /* -- head; Array head not updated since starts from 0 */ n2 = - (nbbuck + 1); /* pas = n / 8; [Update F.P. 20020715 selon hamf_20020220] Distance betweeen elements of the N, ..., NBBUCK entries of HEAD */ pas = MAX ((n / 8), 1); /* Distance betweeen elements of the N, ..., NBBUCK entries of HEAD */ wflg = 2; ncmpa = 0; nel = 0; hmod = MAX (1, nbbuck - 1); dmax = 0; mem = pfree - 1; maxmem = mem; mindeg = 0; rmf = (float) (n) * (float) (n - 1); /* Average sparsity of matrix; diagonal entry is not in mem */ nbflag = 0; lastd = 0; memSet (head, 0, (nbbuck + 2) * sizeof (Gnum)); memSet (last + 1, 0, n * sizeof (Gnum)); if (nbelts == 0) { /* Patch 8/12/03 */ memSet (elen + 1, 0, n * sizeof (Gnum)); for (i = 1; i <= n; i ++) { nv[i] = 1; w[i] = 1; if (len[i] < 0) { degree[i] = n2; nbflag ++; if (len[i] == - (n + 1)) { /* Patch 09/08/98 */ len[i] = 0; pe[i] = 0; /* Patch 12/12/03 : Because of compress, we force skipping those entries (which are anyway empty) */ } else len[i] = - len[i]; } else degree[i] = len[i]; } } else { /* Patch 08/12/03 : Duplicate part of previous loop to avoid sytematic testing for elements */ for (i = 1; i <= n; i ++) { nv[i] = 1; w[i] = 1; if (len[i] < 0) { /* i \in V1 */ degree[i] = n2; nbflag ++; if (len[i] == - (n + 1)) { /* Patch 09/08/98 */ len[i] = 0; pe[i] = 0; /* Patch 12/12/03 : because of compress, we force skipping those entries (which are anyway empty) */ elen[i] = 0; /* Patch 16/12/03 */ } else { len[i] = - len[i]; elen[i] = len[i]; /* Patch 16/12/03 : only elements are adjacent to a variable */ } } else { /* i \in Ve or V0 */ if (elen[i] < 0) { /* i \in Ve */ nel ++; degree[i] = len[i]; elen[i] = - nel; dmax = MAX (dmax, degree[i]); /* Patch 11/03/04 */ } else { degree[i] = elen[i]; elen[i] = len[i]; /* Patch 16/12/03 : only elements are adjacent to a variable */ } } } } #ifdef SCOTCH_DEBUG_ORDER2 if (nbelts != nel) /* Temporary Patch 8/12/03 */ printf ("error 8Dec2003\n"); #endif /* SCOTCH_DEBUG_ORDER2 */ nreal = n - nbflag; for (i = 1; i <= n; i ++) { if (elen[i] < 0 ) /* Patch 16/12/03 : Skip elements */ continue; deg = degree[i]; if (deg == n2) { deg = nbbuck + 1; if (lastd == 0) { lastd = i; head[deg] = i; next[i] = 0; last[i] = 0; } else { next[lastd] = i; last[i] = lastd; lastd = i; next[i] = 0; } } else if (deg > 0) { if (nbelts != 0) { /* Patch 04/01/04 */ Gnum l; /* Size of largest adjacent element */ Gnum m; /* Current edge being visited */ for (m = pe[i], l = 0; m < pe[i] + elen[i]; m ++) { Gnum o; /* Current element being visited */ o = iw[m]; if (len[o] > l) l = len[o]; } deg = (Gnum) ((float) deg * (float) (deg - 1) - (float) l * (float) (l - 1)) / 2; if (deg < 0) /* Patch 04/01/04 */ deg = 0; } wf[i] = deg; /* Patch 14/01/04 */ if (deg > n) deg = MIN ((deg - n) / pas + n, nbbuck); inext = head[deg]; if (inext != 0) last[inext] = i; next[i] = inext; head[deg] = i; } else { nel ++; elen[i] = - nel; pe[i] = 0; w[i] = 0; } } /* L20: */ nleft = n - nel; /* Patch v5 12/12/98 */ while (nel < nreal) { /* WHILE (selecting pivots) DO */ for (deg = mindeg; deg <= nbbuck; deg ++) { me = head[deg]; if (me > 0) break; /* GO to 50 */ } /* L40: */ mindeg = deg; if (me <= 0) { /* Error 1 */ *ncmpaptr = -n; return; } if (deg > n) { j = next[me]; k = wf[me]; while (j > 0) { if (wf[j] < k) { me = j; k = wf[me]; } j = next[j]; } ilast = last[me]; inext = next[me]; if (inext != 0) last[inext] = ilast; if (ilast != 0) next[ilast] = inext; else head[deg] = inext; /* me is at the head of the degree list */ } else { inext = next[me]; if (inext != 0) last[inext] = 0; head[deg] = inext; } elenme = elen[me]; elen[me] = - (nel + 1); nvpiv = nv[me]; nel += nvpiv; nv[me] = - nvpiv; degme = 0; if (elenme == 0) { pme1 = pe[me]; pme2 = pme1 - 1; for (p = pme1; p <= pme1 + len[me] - 1; p ++) { i = iw[p]; nvi = nv[i]; if (nvi > 0) { degme += nvi; nv[i] = - nvi; pme2 ++; iw[pme2] = i; if (degree[i] != n2) { ilast = last[i]; inext = next[i]; if (inext != 0) last[inext] = ilast; if (ilast != 0) next[ilast] = inext; else { if (wf[i] > n) deg = MIN ((wf[i] - n) / pas + n, nbbuck); else deg = wf[i]; head[deg] = inext; } } } } /* L60: */ newmem = 0; } else { p = pe[me]; pme1 = pfree; slenme = len[me] - elenme; for (knt1 = 1; knt1 <= elenme + 1; knt1 ++) { if (knt1 > elenme) { e = me; pj = p; ln = slenme; } else { e = iw[p ++]; pj = pe[e]; ln = len[e]; } for (knt2 = 1; knt2 <= ln; knt2 ++) { i = iw[pj ++]; nvi = nv[i]; if (nvi > 0) { if (pfree > iwlen) { pe[me] = p; len[me] -= knt1; if (len[me] == 0) pe[me] = 0; pe[e] = pj; len[e] = ln - knt2; if (len[e] == 0) pe[e] = 0; ncmpa ++; for (j = 1; j <= n; j ++) { pn = pe[j]; if (pn > 0) { pe[j] = iw[pn]; iw[pn] = - j; } } /* L70: */ pdst = 1; psrc = 1; pend = pme1 - 1; while (psrc <= pend) { /* L80: */ j = - iw[psrc ++]; if (j > 0) { iw[pdst] = pe[j]; pe[j] = pdst ++; lenj = len[j]; for (knt3 = 0; knt3 <= lenj - 2; knt3 ++) iw[pdst + knt3] = iw[psrc + knt3]; pdst = pdst + (lenj - 1); psrc = psrc + (lenj - 1); } } p1 = pdst; for (psrc = pme1; psrc <= pfree - 1; psrc ++, pdst ++) /* L100: */ iw[pdst] = iw[psrc]; pme1 = p1; pfree = pdst; pj = pe[e]; p = pe[me]; } degme += nvi; nv[i] = - nvi; iw[pfree] = i; pfree ++; if (degree[i] != n2) { ilast = last[i]; inext = next[i]; if (inext != 0) last[inext] = ilast; if (ilast != 0) next[ilast] = inext; else { if (wf[i] > n) deg = MIN ((wf[i] - n) / pas + n, nbbuck); else deg = wf[i]; head[deg] = inext; } } } } /* L110: */ if (e != me) { pe[e] = -me; w[e] = 0; } } /* L120: */ pme2 = pfree - 1; newmem = pfree - pme1; mem += newmem; maxmem = MAX (maxmem, mem); } degree[me] = degme; pe[me] = pme1; len[me] = pme2 - pme1 + 1; if (wflg + n <= wflg) { for (x = 1; x <= n; x ++) { if (w[x] != 0) w[x] = 1; } /* L130: */ wflg = 2; } for (pme = pme1; pme <= pme2; pme ++) { i = iw[pme]; eln = elen[i]; if (eln > 0) { nvi = - nv[i]; wnvi = wflg - nvi; for (p = pe[i]; p < pe[i] + eln; p ++) { e = iw[p]; we = w[e]; if (we >= wflg) we -= nvi; else if (we != 0) { we = degree[e] + wnvi; wf[e] = 0; } w[e] = we; } /* L140: */ } } /* L150: */ for (pme = pme1; pme <= pme2; pme ++) { i = iw[pme]; p1 = pe[i]; p2 = p1 + elen[i] - 1; pn = p1; hash = 0; deg = 0; wf3 = 0; wf4 = 0; nvi = - nv[i]; for (p = p1; p <= p2; p ++) { e = iw[p]; dext = w[e] - wflg; if (dext > 0) { if (wf[e] == 0) wf[e] = dext * ((2 * degree[e]) - dext - 1); wf4 += wf[e]; deg += dext; iw[pn ++] = e; hash += e; } else if (dext == 0) { pe[e] = -me; w[e] = 0; } } /* L160: */ elen[i] = pn - p1 + 1; p3 = pn; for (p = p2 + 1; p < p1 + len[i]; p ++) { j = iw[p]; nvj = nv[j]; if (nvj > 0) { deg += nvj; wf3 += nvj; iw[pn ++] = j; hash += j; } } /* L170: */ if (degree[i] == n2) deg = n2; if (deg == 0) { pe[i] = - me; nvi = - nv[i]; degme -= nvi; nvpiv += nvi; nel += nvi; nv[i] = 0; elen[i] = 0; } else { if (degree[i] != n2) { if (degree[i] < deg) { wf4 = 0; wf3 = 0; } else degree[i] = deg; } wf[i] = wf4 + 2 * nvi * wf3; iw[pn] = iw[p3]; iw[p3] = iw[p1]; iw[p1] = me; len[i] = pn - p1 + 1; if (deg != n2) { hash = (hash % hmod) + 1; j = head[hash]; if (j <= 0) { next[i] = - j; head[hash] = - i; } else { next[i] = last[j]; last[j] = i; } last[i] = hash; } } } /* L180: */ degree[me] = degme; dmax = MAX (dmax, degme); wflg += dmax; if (wflg + n <= wflg) { for (x = 1; x <= n; x ++) { if (w[x] != 0) w[x] = 1; } wflg = 2; } for (pme = pme1; pme <= pme2; pme ++) { i = iw[pme]; if ((nv[i] < 0) && (degree[i] != n2)) { hash = last[i]; j = head[hash]; if (j == 0) continue; if (j < 0) { i = - j; head[hash] = 0; } else { i = last[j]; last[j] = 0; } if (i == 0) continue; L200: /* WHILE LOOP: */ if (next[i] != 0) { ln = len[i]; eln = elen[i]; for (p = pe[i] + 1; p < pe[i] + ln; p ++) w[iw[p]] = wflg; jlast = i; j = next[i]; L220: /* WHILE LOOP: */ if (j != 0) { if (len[j] != ln) goto L240; if (elen[j] != eln) goto L240; for (p = pe[j] + 1; p < pe[j] + ln; p ++) { if (w[iw[p]] != wflg) goto L240; } /* L230: */ pe[j] = -i; if (wf[j] > wf[i]) wf[i] = wf[j]; nv[i] += nv[j]; nv[j] = 0; elen[j] = 0; j = next[j]; next[jlast] = j; goto L220; L240: jlast = j; j = next[j]; goto L220; } wflg ++; i = next[i]; if (i != 0) goto L200; } } } p = pme1; nleft = n - nel; for (pme = pme1; pme <= pme2; pme ++) { i = iw[pme]; nvi = - nv[i]; if (nvi > 0) { nv[i] = nvi; if (degree[i] != n2) { deg = MIN (degree[i] + degme, nleft) - nvi; if (degree[i] + degme > nleft) { deg = degree[i]; rmf1 = (float) deg * (float) (deg - 1 + (2 * degme)) - (float) wf[i]; degree[i] = nleft - nvi; deg = degree[i]; rmf = (float) deg * (float) (deg - 1) - (float) (degme - nvi) * (float) (degme - nvi - 1); rmf = MIN (rmf, rmf1); } else { deg = degree[i]; degree[i] = degree[i] + degme - nvi; rmf = (float) deg * (float) (deg - 1 + (2 * degme)) - (float) wf[i]; } wf[i] = (Gnum) (rmf / (float) (nvi + 1) + 0.5F); /* Patch 08/12/2010 */ wf[i] = MAX (0, wf[i]); deg = wf[i]; if (deg > n) deg = MIN ((deg - n) / pas + n, nbbuck); inext = head[deg]; if (inext != 0) last[inext] = i; next[i] = inext; last[i] = 0; head[deg] = i; mindeg = MIN (mindeg, deg); } iw[p ++] = i; } } /* L260: */ nv[me] = nvpiv + degme; len[me] = p - pme1; if (len[me] == 0) { pe[me] = 0; w[me] = 0; } if (newmem != 0) { pfree = p; mem = mem - newmem + len[me]; } } /* END WHILE (selecting pivots) */ if (nel < n) { /* Patch 12/12/98 (old: nreal < n) */ for (deg = mindeg; deg <= (nbbuck + 1); deg ++) { me = head[deg]; if (me > 0) break; } mindeg = deg; nelme = - (nel + 1); for (x = 1; x <= n; x ++) { if ((pe[x] > 0) && (elen[x] < 0)) pe[x] = - me; else if (degree[x] == n2) { nel += nv[x]; pe[x] = - me; elen[x] = 0; nv[x] = 0; /* Patch 12/12/98 (old: n + 1) */ } } elen[me] = nelme; nv[me] = n - nreal; /* Patch 12/12/98 (old: n + 1) */ pe[me] = 0; if (nel != n) { /* Error 2 */ *ncmpaptr = - (n + 1); return; } } for (i = 1; i <= n; i ++) { if (elen[i] == 0) { j = - pe[i]; while (elen[j] >= 0) /* L270: */ j = - pe[j]; e = j; k = - elen[e]; j = i; while (elen[j] >= 0) { /* L280: */ jnext = - pe[j]; pe[j] = - e; if (elen[j] == 0) elen[j] = k ++; j = jnext; } elen[e] = - k; } } /* L290: */ #ifdef DEAD_CODE for (i = 1; i <= n; i ++) { /* Patch 19/10/98 */ k = abs (elen[i]); last[k] = i; elen[i] = k; } /* L300: */ #endif /* DEAD_CODE */ /* pfree = maxmem; Patch 08/03/12 No need to update pfree */ *ncmpaptr = ncmpa; } scotch-6.0.4.dfsg/src/libscotch/arch_vhcub.h0000644002563400244210000001204512354534115024114 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : arch_vhcub.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the variable-sized hypercube **/ /** target architecture functions. **/ /** **/ /** DATES : # Version 3.4 : from : 08 nov 2001 **/ /** to 08 nov 2001 **/ /** # Version 4.0 : from : 04 nov 2003 **/ /** to 04 nov 2003 **/ /** # Version 5.1 : from : 21 jan 2008 **/ /** to 21 jan 2008 **/ /** # Version 6.0 : from : 14 fev 2011 **/ /** to 01 jul 2014 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ #ifndef ARCH_VHCUB_H_STRUCT #define ARCH_VHCUB_H_STRUCT /*+ The variable-sized hypercube bipartitioning definitions. +*/ typedef struct ArchVhcub_ { int padding; /*+ No data needed +*/ } ArchVhcub; typedef struct ArchVhcubDom_ { Anum termlvl; /*+ Terminal depth +*/ Anum termnum; /*+ Terminal number +*/ } ArchVhcubDom; #endif /* ARCH_VHCUB_H_STRUCT */ /* ** The function prototypes. */ #ifndef ARCH_NOPROTO #ifndef ARCH_VHCUB_H_PROTO #define ARCH_VHCUB_H_PROTO #ifndef ARCH_VHCUB #define static #endif #define archVhcubArchLoad NULL #define archVhcubArchSave NULL #define archVhcubArchFree NULL ArchDomNum archVhcubDomNum (const ArchVhcub * const, const ArchVhcubDom * const); int archVhcubDomTerm (const ArchVhcub * const, ArchVhcubDom * restrict const, const ArchDomNum); Anum archVhcubDomSize (const ArchVhcub * const, const ArchVhcubDom * const); #define archVhcubDomWght archVhcubDomSize Anum archVhcubDomDist (const ArchVhcub * const, const ArchVhcubDom * const, const ArchVhcubDom * const); int archVhcubDomFrst (const ArchVhcub * const, ArchVhcubDom * const); int archVhcubDomLoad (const ArchVhcub * const, ArchVhcubDom * const, FILE * const); int archVhcubDomSave (const ArchVhcub * const, const ArchVhcubDom * const, FILE * const); int archVhcubDomBipart (const ArchVhcub * const, const ArchVhcubDom * const, ArchVhcubDom * restrict const, ArchVhcubDom * restrict const); int archVhcubDomIncl (const ArchVhcub * const, const ArchVhcubDom * const, const ArchVhcubDom * const); #ifdef SCOTCH_PTSCOTCH int archVhcubDomMpiType (const ArchVhcub * const, MPI_Datatype * const); #endif /* SCOTCH_PTSCOTCH */ #undef static #endif /* ARCH_VHCUB_H_PROTO */ #endif /* ARCH_NOPROTO */ scotch-6.0.4.dfsg/src/libscotch/dgraph_build_grid3d.h0000644002563400244210000001215411631447170025672 0ustar trophimeutilisateurs du domaine/* Copyright 2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_build_grid3d.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the data **/ /** declarations for the distributed 3D **/ /** grid graph building routine. **/ /** **/ /** DATES : # Version 5.1 : from : 06 jun 2010 **/ /** to : 04 nov 2010 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ The multinode table element, which contains pairs of based indices of collapsed vertices. Both values are equal for uncollapsed vertices. +*/ typedef struct DgraphBuildGrid3DData_ { Gnum baseval; Gnum dimxval; Gnum dimyval; Gnum dimzval; Gnum * edgeloctax; Gnum * edloloctax; Gnum (* funcvrtptr) (const struct DgraphBuildGrid3DData_ * restrict const, const Gnum, Gnum, const Gnum, const Gnum, const Gnum); struct { /* Pre-computed data for 26-neighbor torus */ Gnum ngbxmin; Gnum ngbxmax; Gnum ngbymin; Gnum ngbymax; Gnum ngbzmin; Gnum ngbzmax; } t26; } DgraphBuildGrid3DData; /* ** The function prototypes. */ #ifndef DGRAPH_BUILD_GRID3D #define static #endif static Gnum dgraphBuildGrid3Dvertex26M (const DgraphBuildGrid3DData * restrict const, const Gnum, Gnum, const Gnum, const Gnum, const Gnum); static Gnum dgraphBuildGrid3Dvertex26T (const DgraphBuildGrid3DData * restrict const, const Gnum, Gnum, const Gnum, const Gnum, const Gnum); static Gnum dgraphBuildGrid3Dvertex6M (const DgraphBuildGrid3DData * restrict const, const Gnum, Gnum, const Gnum, const Gnum, const Gnum); static Gnum dgraphBuildGrid3Dvertex6T (const DgraphBuildGrid3DData * restrict const, const Gnum, Gnum, const Gnum, const Gnum, const Gnum); #undef static /* ** The macro definitions. */ #define DGRAPHBUILDGRID3DNGB(d,v,e,x,y,z) { \ Gnum edgeloctmp; \ Gnum vertglbend; \ edgeloctmp = (e); \ vertglbend = ((z) * (d)->dimyval + (y)) * (d)->dimxval + (x) + (d)->baseval; \ (d)->edgeloctax[edgeloctmp] = vertglbend; \ if ((d)->edloloctax != NULL) \ (d)->edloloctax[edgeloctmp] = ((vertglbend + (v)) % 16) + 1; \ } scotch-6.0.4.dfsg/src/libscotch/vgraph_separate_es.h0000644002563400244210000001317111631447170025654 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vgraph_separate_es.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the edge-separation-based node **/ /** separation module. **/ /** **/ /** DATES : # Version 3.2 : from : 24 oct 1996 **/ /** to : 07 sep 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 4.0 : from : 18 aug 2004 **/ /** to 19 aug 2004 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ Separator type. +*/ typedef enum VgraphSeparateEsWidth_ { VGRAPHSEPAESWIDTHTHIN, /*+ Thin vertex separator +*/ VGRAPHSEPAESWIDTHFAT /*+ Fat vertex separator +*/ } VgraphSeparateEsWidth; /*+ This structure holds the method parameters. +*/ typedef struct VgraphSeparateEsParam_ { Strat * strat; /*+ Edge bipartitioning strategy used +*/ VgraphSeparateEsWidth widtval; /*+ Separator width +*/ } VgraphSeparateEsParam; /*+ These are the type of subgraphs vertices belong to, used to represent the Dulmage- Mendelsohn decomposition. TRICK: item numbers have been carefully chosen, so that one can easily sort out vertices that belong to (HR u SC u VC) and to (HR u SR u VC). +*/ typedef enum VgraphSeparateEsType_ { VGRAPHSEPAESTYPEHC = 0x0000, VGRAPHSEPAESTYPEVR = 0x0001, VGRAPHSEPAESTYPEHRSCVC = 0x0002, /* Bit mask for testing */ VGRAPHSEPAESTYPESC = 0x0003, VGRAPHSEPAESTYPEHRSRVC = 0x0004, /* Bit mask for testing */ VGRAPHSEPAESTYPESR = 0x0005, VGRAPHSEPAESTYPEHR = 0x0006, VGRAPHSEPAESTYPEVC = 0x0007 } VgraphSeparateEsType; #define VGRAPHSEPAESTYPEBITC 1 /* Bit index for VGRAPHSEPAESTYPEHRSCVC */ #define VGRAPHSEPAESTYPEBITR 2 /* Bit index for VGRAPHSEPAESTYPEHRSRVC */ /*+ Vertex traversal flag. +*/ typedef enum VgraphSeparateEsTrav_ { VGRAPHSEPAESTRAVFREE = 0, /*+ Vertex not traversed +*/ VGRAPHSEPAESTRAVUSED, /*+ Vertex traversed by search for free rows +*/ VGRAPHSEPAESTRAVDRTY /*+ Vertex traversed by backtracking search for free columns +*/ } VgraphSeparateEsTrav; /* ** The function prototypes. */ #ifndef VGRAPH_SEPARATE_ES #define static #endif static int vgraphSeparateEsCover (const Graph * const, const Gnum, Gnum * const, Gnum * const); static int vgraphSeparateEsCoverAugment (const Gnum * restrict const, const Gnum, Gnum * restrict const, VgraphSeparateEsTrav * restrict const, const Gnum * restrict const, const Gnum * restrict const, const Gnum * restrict const, const Gnum); static void vgraphSeparateEsCoverCol (const Gnum * restrict const, VgraphSeparateEsType * restrict const, const Gnum * restrict const, const Gnum * restrict const, const Gnum * restrict const, const Gnum); static void vgraphSeparateEsCoverRow (const Gnum * restrict const, VgraphSeparateEsType * restrict const, const Gnum * restrict const, const Gnum * restrict const, const Gnum * restrict const, const Gnum); int vgraphSeparateEs (Vgraph * const, const VgraphSeparateEsParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/vgraph_separate_gp.c0000644002563400244210000002575611716327003025656 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vgraph_separate_gp.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module separates an active **/ /** graph using a vertex-oriented version **/ /** of the Gibbs-Poole-Stockmeyer **/ /** algorithm. **/ /** **/ /** DATES : # Version 4.0 : from : 15 may 2004 **/ /** to 17 may 2004 **/ /** # Version 5.0 : from : 12 sep 2007 **/ /** to 12 sep 2007 **/ /** # Version 5.1 : from : 09 nov 2008 **/ /** to 09 nov 2008 **/ /** # Version 6.0 : from : 10 feb 2011 **/ /** to 10 feb 2011 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VGRAPH_SEPARATE_GP #include "module.h" #include "common.h" #include "graph.h" #include "vgraph.h" #include "vgraph_separate_gp.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the bipartitioning. ** It returns: ** - 0 : if the bipartitioning could be computed. ** - !0 : on error. */ int vgraphSeparateGp ( Vgraph * restrict const grafptr, /*+ Separation graph +*/ const VgraphSeparateGpParam * const paraptr) /*+ Method parameters +*/ { VgraphSeparateGpQueue queudat; /* Vertex queue */ VgraphSeparateGpVertex * restrict vexxtax; /* Complementary vertex array */ Gnum rootnum; Gnum vertnum; Gnum fronnum; Gnum compsize1; Gnum compsize2; Gnum compload2; Gnum comploaddlt; const Gnum * restrict const verttax = grafptr->s.verttax; const Gnum * restrict const vendtax = grafptr->s.vendtax; const Gnum * restrict const velotax = grafptr->s.velotax; const Gnum * restrict const edgetax = grafptr->s.edgetax; GraphPart * restrict const parttax = grafptr->parttax; Gnum * restrict const frontab = grafptr->frontab; if (grafptr->compload[0] != grafptr->s.velosum) /* If not all vertices already in part 0 */ vgraphZero (grafptr); /* Move all graph vertices to part 0 */ if (memAllocGroup ((void **) (void *) &queudat.queutab, (size_t) (grafptr->s.vertnbr * sizeof (Gnum)), &vexxtax, (size_t) (grafptr->s.vertnbr * sizeof (VgraphSeparateGpVertex)), NULL) == NULL) { errorPrint ("vgraphSeparateGp: out of memory"); return (1); } memSet (vexxtax, 0, grafptr->s.vertnbr * sizeof (VgraphSeparateGpVertex)); /* Initialize pass numbers */ vexxtax -= grafptr->s.baseval; compload2 = 0; /* All vertices to part 0 */ comploaddlt = grafptr->s.velosum; for (rootnum = grafptr->s.baseval; /* Loop on connected components */ (rootnum < grafptr->s.vertnnd) && (comploaddlt > 0); rootnum ++) { Gnum passnum; /* Pass number */ Gnum diamnum; /* Number of current diameter vertex */ Gnum diamval; /* Current diameter value */ Gnum diamdeg; /* Degree of current diameter vertex */ int diamflag; /* Flag set if improvement in diameter between passes */ Gnum veloval; while (vexxtax[rootnum].passnum != 0) /* Find first unallocated vertex */ rootnum ++; for (diamnum = rootnum, diamval = diamdeg = 0, diamflag = 1, passnum = 1; /* Start from root */ (passnum < paraptr->passnbr) && (diamflag -- != 0); passnum ++) { /* Loop if improvements */ vgraphSeparateGpQueueFlush (&queudat); /* Flush vertex queue */ vgraphSeparateGpQueuePut (&queudat, diamnum); /* Start from diameter vertex */ vexxtax[diamnum].passnum = passnum; /* It has been enqueued */ vexxtax[diamnum].distval = 0; do { /* Loop on vertices in queue */ Gnum vertnum; Gnum distval; Gnum edgenum; vertnum = vgraphSeparateGpQueueGet (&queudat); /* Get vertex from queue */ distval = vexxtax[vertnum].distval; /* Get vertex distance */ if ((distval > diamval) || /* If vertex increases diameter */ ((distval == diamval) && /* Or is at diameter distance */ ((vendtax[vertnum] - verttax[vertnum]) < diamdeg))) { /* With smaller degree */ diamnum = vertnum; /* Set it as new diameter vertex */ diamval = distval; diamdeg = vendtax[vertnum] - verttax[vertnum]; diamflag = 1; } distval ++; /* Set neighbor distance */ for (edgenum = verttax[vertnum]; edgenum < vendtax[vertnum]; edgenum ++) { Gnum vertend; /* End vertex number */ vertend = edgetax[edgenum]; if (vexxtax[vertend].passnum < passnum) { /* If vertex not yet queued */ vgraphSeparateGpQueuePut (&queudat, vertend); /* Enqueue neighbor vertex */ vexxtax[vertend].passnum = passnum; vexxtax[vertend].distval = distval; } } } while (! vgraphSeparateGpQueueEmpty (&queudat)); /* As long as queue is not empty */ } vgraphSeparateGpQueueFlush (&queudat); /* Flush vertex queue */ vgraphSeparateGpQueuePut (&queudat, diamnum); /* Start from diameter vertex */ vexxtax[diamnum].passnum = passnum; /* It has been enqueued */ vexxtax[diamnum].distval = 0; veloval = (velotax != NULL) ? velotax[diamnum] : 1; parttax[diamnum] = 2; /* Move diameter vertex to separator */ comploaddlt -= veloval; compload2 += veloval; do { /* Loop on vertices in queue */ Gnum vertnum; Gnum veloval; Gnum distval; Gnum edgenum; vertnum = vgraphSeparateGpQueueGet (&queudat); /* Get vertex from queue */ veloval = (velotax != NULL) ? velotax[vertnum] : 1; distval = vexxtax[vertnum].distval + 1; parttax[vertnum] = 1; /* Move selected vertex from separator to part 1 */ comploaddlt -= veloval; compload2 -= veloval; for (edgenum = verttax[vertnum]; edgenum < vendtax[vertnum]; edgenum ++) { Gnum vertend; /* End vertex number */ Gnum veloval; vertend = edgetax[edgenum]; veloval = (velotax != NULL) ? velotax[vertend] : 1; if (vexxtax[vertend].passnum < passnum) { /* If vertex not yet queued */ vgraphSeparateGpQueuePut (&queudat, vertend); /* Enqueue neighbor vertex */ vexxtax[vertend].passnum = passnum; vexxtax[vertend].distval = distval; parttax[vertend] = 2; /* Move neighbor vertex to separator */ comploaddlt -= veloval; compload2 += veloval; } } } while ((comploaddlt > 0) && (! vgraphSeparateGpQueueEmpty (&queudat))); /* As long as balance not achieved and queue is not empty */ } grafptr->compload[0] = (grafptr->s.velosum + comploaddlt - compload2) / 2; grafptr->compload[1] = grafptr->s.velosum - compload2 - grafptr->compload[0]; grafptr->compload[2] = compload2; grafptr->comploaddlt = comploaddlt; memFree (queudat.queutab); /* Free group leader */ compsize1 = compsize2 = 0; for (vertnum = grafptr->s.baseval, fronnum = 0; vertnum < grafptr->s.vertnnd; vertnum ++) { Gnum partval; partval = (Gnum) parttax[vertnum]; compsize1 += (partval & 1); /* Superscalar update */ compsize2 += (partval >> 1); if (partval == 2) /* If vertex belongs to frontier */ frontab[fronnum ++] = vertnum; /* Record it in frontier array */ } grafptr->compsize[0] = grafptr->s.vertnbr - compsize1 - compsize2; grafptr->compsize[1] = compsize1; grafptr->fronnbr = compsize2; #ifdef SCOTCH_DEBUG_VGRAPH2 if (vgraphCheck (grafptr) != 0) { errorPrint ("vgraphSeparateGp: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/hmesh_induce.c0000644002563400244210000004505611631447171024450 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh_induce.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles the halo source **/ /** mesh subgraph-making functions. **/ /** **/ /** DATES : # Version 4.0 : from : 07 jan 2002 **/ /** to 11 may 2004 **/ /** # Version 5.0 : from : 22 dec 2006 **/ /** to 11 jun 2007 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HMESH #define HMESH_INDUCE #include "module.h" #include "common.h" #include "graph.h" #include "mesh.h" #include "hmesh.h" /*********************************************/ /* */ /* These routines handle halo source meshes. */ /* */ /*********************************************/ /* This routine builds the halo mesh induced ** by the original halo mesh and the array of ** selected node vertices. Elements which are ** adjacent to the selected nodes are themselves ** selected, as well as their adjacent node ** vertices, which comprise the new halo. ** In the induced halo mesh, elements are ** placed first, then non-halo nodes, then ** halo nodes. This order is quite important ** as it eases the building of vertex separation ** meshes from halo meshes, just by ignoring ** halo nodes. ** The induced vnumtab array is a baseval-based ** list of the selected node vertices if the ** original halo mesh does not have a vnumtab, or ** the proper subset of the original vnumtab else. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int hmeshInducePart ( const Hmesh * restrict const orgmeshptr, /* Pointer to original graph */ const GraphPart * restrict const orgparttax, /* Array of vertex partition flags */ const GraphPart orgpartval, /* Partition value of vertices to keep (0 or 1) */ const Gnum orgvelmnbr, /* Number of (maybe isolated) element vertices in selected part */ const Gnum orgvnodnbr, /* Number of node vertices in selected part */ const Gnum orgvnspnbr, /* Number of node vertices in separator */ Hmesh * restrict const indmeshptr) /* Pointer to induced halo submesh */ { Gnum orgvelmnum; /* Number of current element vertex in original halo mesh */ Gnum orgvnodnum; /* Number of current node vertex in original halo mesh */ Gnum * restrict orgindxtax; /* Original to induced vertex number translation array */ Gnum indvertnbr; /* Upper bound on the number of vertices in induced halo mesh */ Gnum indvertnum; /* Number of current vertex in induced mesh graph */ Gnum indvelmnbr; /* Number of element vertices in induced halo mesh */ Gnum indveihnbr; /* Number of newly created halo-isolated elements */ Gnum indvnodnbr; /* Upper bound on the number of node vertices in induced halo mesh */ Gnum indvnodnum; /* Number of current node vertex in induced halo mesh */ Gnum * restrict indedgetax; /* Based access to induced mesh graph edge arrays */ Gnum indedgenbr; /* (Approximate) number of edges in induced halo mesh */ Gnum indedgenum; /* Number of current edge in induced halo mesh */ Gnum * restrict indvnuhtax; /* Array of vertex numbers for halo nodes (aka vnumtab) */ Gnum indvelonbr; Gnum indvelosum; Gnum indvnlonbr; Gnum indvnlosum; Gnum indvnhlsum; indvelmnbr = orgvelmnbr - orgmeshptr->veihnbr; /* Remove known halo-isolated elements */ if (orgpartval == 0) /* If submesh is part zero */ indvelmnbr -= orgmeshptr->m.veisnbr; /* Also remove isolated elements, which belong to it */ indvnodnbr = orgvnodnbr + orgvnspnbr + orgmeshptr->m.vnodnnd - orgmeshptr->vnohnnd; /* Compute upper bound on number of node vertices */ indvertnbr = indvnodnbr + indvelmnbr; indedgenbr = ((orgmeshptr->m.degrmax > 0) && (indvertnbr < (orgmeshptr->m.edgenbr / orgmeshptr->m.degrmax))) /* Choose best upper bound on number of edges (avoid multiply overflow) */ ? (indvertnbr * orgmeshptr->m.degrmax) : orgmeshptr->m.edgenbr; memSet (indmeshptr, 0, sizeof (Hmesh)); /* Initialize halo mesh fields */ indmeshptr->m.baseval = orgmeshptr->m.baseval; /* Inherit mesh properties */ indmeshptr->m.flagval = MESHFREETABS | MESHVERTGROUP; indmeshptr->m.velmnbr = indvelmnbr; indmeshptr->m.velmbas = indmeshptr->m.baseval; /* Elements are placed first */ indmeshptr->m.velmnnd = indmeshptr->m.vnodbas = orgvelmnbr + indmeshptr->m.baseval; /* Node vertices are placed after elements */ indmeshptr->m.veisnbr = 0; /* All isolated elements will be removed in submesh */ indvelonbr = (orgmeshptr->m.velotax != NULL) ? indmeshptr->m.velmnbr : 0; indvnlonbr = (orgmeshptr->m.vnlotax != NULL) ? indvnodnbr : 0; if (memAllocGroup ((void **) (void *) &indmeshptr->m.verttax, (size_t) ((indvertnbr + 1) * sizeof (Gnum)), &indmeshptr->vehdtax, (size_t) ( orgvelmnbr * sizeof (Gnum)), /* vehdtab is limited to elements */ &indmeshptr->m.velotax, (size_t) ( indvelonbr * sizeof (Gnum)), &indmeshptr->m.vnlotax, (size_t) ( indvnlonbr * sizeof (Gnum)), &indmeshptr->m.vnumtax, (size_t) ( orgvnodnbr * sizeof (Gnum)), NULL) == NULL) { /* vnumtab is of size vnohnbr */ errorPrint ("hmeshInducePart: out of memory (1)"); /* Allocate induced mesh graph structure */ return (1); } indmeshptr->m.verttax -= indmeshptr->m.baseval; indmeshptr->m.vendtax = indmeshptr->m.verttax + 1; /* Compact array */ indmeshptr->m.velotax = (indvelonbr != 0) ? (indmeshptr->m.velotax - indmeshptr->m.velmbas) : NULL; indmeshptr->m.vnlotax = (indvnlonbr != 0) ? (indmeshptr->m.vnlotax - indmeshptr->m.vnodbas) : NULL; indmeshptr->m.vnumtax -= indmeshptr->m.vnodbas; /* Only for non-halo nodes */ indmeshptr->m.degrmax = orgmeshptr->m.degrmax; indmeshptr->vnohnbr = orgvnodnbr; indmeshptr->vnohnnd = indmeshptr->m.vnodbas + orgvnodnbr; indmeshptr->vehdtax -= indmeshptr->m.velmbas; indmeshptr->vnhlsum = orgvnodnbr; /* Assume no vertex loads */ if (memAllocGroup ((void **) (void *) &indedgetax, (size_t) (indedgenbr * sizeof (Gnum)), &orgindxtax, (size_t) ((orgmeshptr->m.velmnbr + orgmeshptr->m.vnodnbr) * sizeof (Gnum)), &indvnuhtax, (size_t) ((orgvnspnbr + orgmeshptr->m.vnodnnd - orgmeshptr->vnohnnd) * sizeof (Gnum)), NULL) == NULL) { errorPrint ("hmeshInducePart: out of memory (2)"); /* Allocate induced mesh graph structure */ hmeshExit (indmeshptr); return (1); } indedgetax -= indmeshptr->m.baseval; orgindxtax -= orgmeshptr->m.baseval; indvnuhtax -= indmeshptr->vnohnnd; /* Base array so as to catch halo nodes only */ indvnhlsum = 0; for (orgvnodnum = orgmeshptr->m.vnodbas, /* For all original non-halo node vertices */ indvnodnum = indmeshptr->m.vnodbas; /* And assuming all elements will be kept */ orgvnodnum < orgmeshptr->vnohnnd; orgvnodnum ++) { if (orgparttax[orgvnodnum] == orgpartval) { /* If in right part */ orgindxtax[orgvnodnum] = indvnodnum; /* Set new index of node */ indmeshptr->m.vnumtax[indvnodnum] = orgvnodnum - (orgmeshptr->m.vnodbas - orgmeshptr->m.baseval); if (orgmeshptr->m.vnlotax != NULL) indvnhlsum += (indmeshptr->m.vnlotax[indvnodnum] = orgmeshptr->m.vnlotax[orgvnodnum]); indvnodnum ++; } else if (orgparttax[orgvnodnum] == 2) /* If node belongs to separator */ orgindxtax[orgvnodnum] = ~0; /* Pre-set array for separator nodes */ } #ifdef SCOTCH_DEBUG_HMESH2 if ((indvnodnum - indmeshptr->m.vnodbas) != orgvnodnbr) { errorPrint ("hmeshInducePart: internal error (1)"); memFree (indedgetax + indmeshptr->m.baseval); hmeshExit (indmeshptr); return (1); } #endif /* SCOTCH_DEBUG_HMESH2 */ memSet (orgindxtax + orgmeshptr->vnohnnd, ~0, (orgmeshptr->m.vnodnnd - orgmeshptr->vnohnnd) * sizeof (Gnum)); /* Pre-set halo node vertices */ indveihnbr = 0; indvelosum = 0; indvnlosum = 0; for (orgvelmnum = orgmeshptr->m.velmbas, /* For all elements of original graph */ indvertnum = indedgenum = indmeshptr->m.baseval; /* Elements are placed first in vertex array */ orgvelmnum < orgmeshptr->m.velmnnd; orgvelmnum ++) { if (orgparttax[orgvelmnum] == orgpartval) { /* If element belongs to right part */ Gnum orgedgenum; Gnum indedgennd; /* Index of after-last edge position in edge array */ Gnum indedhdnum; /* Index of after-last edge linking to non-halo vertices */ orgedgenum = orgmeshptr->m.verttax[orgvelmnum]; if (orgedgenum == orgmeshptr->vehdtax[orgvelmnum]) /* If (halo-)isolated element vertex */ continue; /* Discard element in induced submesh */ #ifdef SCOTCH_DEBUG_HMESH2 if (indvertnum >= indmeshptr->m.velmnnd) { /* If too many element vertices kept */ errorPrint ("hmeshInducePart: internal error (2)"); /* Maybe a problem with veisnbr or veihnbr */ memFree (indedgetax + indmeshptr->m.baseval); hmeshExit (indmeshptr); return (1); } #endif /* SCOTCH_DEBUG_HMESH2 */ indmeshptr->m.verttax[indvertnum] = indedgenum; indedhdnum = orgmeshptr->m.vendtax[orgvelmnum] - orgmeshptr->m.verttax[orgvelmnum] + indedgenum; indedgennd = indedhdnum; if (orgmeshptr->m.velotax != NULL) { Gnum orgveloval; orgveloval = orgmeshptr->m.velotax[orgvelmnum]; indmeshptr->m.velotax[indvertnum] = orgveloval; indvelosum += orgveloval; } for ( ; orgedgenum < orgmeshptr->m.vendtax[orgvelmnum]; orgedgenum ++) { Gnum orgvertend; orgvertend = orgmeshptr->m.edgetax[orgedgenum]; if (orgindxtax[orgvertend] == ~0) { /* If found yet un-numbered halo node */ #ifdef SCOTCH_DEBUG_HMESH2 if ((orgvertend < orgmeshptr->vnohnnd) && (orgparttax[orgvertend] != 2)) { errorPrint ("hmeshInducePart: internal error (3)"); memFree (indedgetax + indmeshptr->m.baseval); hmeshExit (indmeshptr); return (1); } #endif /* SCOTCH_DEBUG_HMESH2 */ if (orgmeshptr->m.vnlotax != NULL) { Gnum orgvnloval; orgvnloval = orgmeshptr->m.vnlotax[orgvertend]; indmeshptr->m.vnlotax[indvnodnum] = orgvnloval; indvnlosum += orgvnloval; } orgindxtax[orgvertend] = indvnodnum; /* Set number of halo node */ indvnuhtax[indvnodnum] = orgvertend; /* Keep number of halo node */ indvnodnum ++; indedgetax[-- indedhdnum] = orgindxtax[orgvertend]; continue; } if (orgindxtax[orgvertend] < indmeshptr->vnohnnd) /* If non-halo vertex */ indedgetax[indedgenum ++] = orgindxtax[orgvertend]; else /* Else if halo vertex */ indedgetax[-- indedhdnum] = orgindxtax[orgvertend]; } #ifdef SCOTCH_DEBUG_HMESH2 if (indedgenum != indedhdnum) { errorPrint ("hmeshInducePart: internal error (4)"); memFree (indedgetax + indmeshptr->m.baseval); hmeshExit (indmeshptr); return (1); } #endif /* SCOTCH_DEBUG_HMESH2 */ if (indedhdnum == indmeshptr->m.verttax[indvertnum]) /* If element has halo nodes only */ indveihnbr ++; /* One more halo-isolated element created */ indmeshptr->vehdtax[indvertnum] = indedhdnum; indedgenum = indedgennd; orgindxtax[orgvelmnum] = indvertnum; indvertnum ++; /* One more element created */ } else orgindxtax[orgvelmnum] = ~0; } #ifdef SCOTCH_DEBUG_HMESH2 if (indvertnum != indmeshptr->m.velmnnd) { errorPrint ("hmeshInducePart: internal error (5)"); /* Maybe a problem with veisnbr or veihnbr */ memFree (indedgetax + indmeshptr->m.baseval); hmeshExit (indmeshptr); return (1); } #endif /* SCOTCH_DEBUG_HMESH2 */ indmeshptr->veihnbr = indveihnbr; indmeshptr->m.vnodnbr = indvnodnum - indmeshptr->m.vnodbas; indmeshptr->m.vnodnnd = indvertnum + indmeshptr->m.vnodnbr; indmeshptr->m.velosum = (indmeshptr->m.velotax != NULL) ? indvelosum : indmeshptr->m.velmnbr; if (indmeshptr->m.vnlotax != NULL) { /* If vertex loads wanted */ indmeshptr->m.vnlosum = indvnhlsum + indvnlosum; indmeshptr->vnhlsum = indvnhlsum; } else { indmeshptr->m.vnlosum = indmeshptr->m.vnodnbr; indmeshptr->vnhlsum = indmeshptr->vnohnbr; } indedgenbr = 2 * (indedgenum - indmeshptr->m.baseval); /* Twice as many arcs as element arcs */ for ( ; indvertnum < indmeshptr->vnohnnd; indvertnum ++) { /* For all non-halo induced node vertices */ Gnum orgvnodnum; Gnum orgedgenum; orgvnodnum = indmeshptr->m.vnumtax[indvertnum] + (orgmeshptr->m.vnodbas - orgmeshptr->m.baseval); /* Get number of original node */ indmeshptr->m.verttax[indvertnum] = indedgenum; for (orgedgenum = orgmeshptr->m.verttax[orgvnodnum]; orgedgenum < orgmeshptr->m.vendtax[orgvnodnum]; orgedgenum ++) { Gnum orgvertend; orgvertend = orgmeshptr->m.edgetax[orgedgenum]; #ifdef SCOTCH_DEBUG_HMESH2 if (orgindxtax[orgvertend] == ~0) { errorPrint ("hmeshInducePart: internal error (6)"); memFree (indedgetax + indmeshptr->m.baseval); hmeshExit (indmeshptr); return (1); } #endif /* SCOTCH_DEBUG_HMESH2 */ indedgetax[indedgenum ++] = orgindxtax[orgvertend]; } } indmeshptr->enohnbr = indedgenum - indmeshptr->m.baseval; for ( ; indvertnum < indmeshptr->m.vnodnnd; indvertnum ++) { /* For all halo induced node vertices */ Gnum orgvnodnum; Gnum orgedgenum; orgvnodnum = indvnuhtax[indvertnum]; /* Get number of original node */ indmeshptr->m.verttax[indvertnum] = indedgenum; for (orgedgenum = orgmeshptr->m.verttax[orgvnodnum]; orgedgenum < orgmeshptr->m.vendtax[orgvnodnum]; orgedgenum ++) { Gnum orgvertend; orgvertend = orgmeshptr->m.edgetax[orgedgenum]; if (orgindxtax[orgvertend] != ~0) { /* If end element belongs to right part */ indedgetax[indedgenum ++] = orgindxtax[orgvertend]; } } } indmeshptr->m.verttax[indvertnum] = indedgenum; /* Set end of edge array */ indmeshptr->m.edgenbr = indedgenum - indmeshptr->m.baseval; indmeshptr->m.vnodnnd = indvertnum; /* Record number of induced non-element vertices */ indmeshptr->m.vnodnbr = indvertnum - indmeshptr->m.vnodbas; if (orgmeshptr->m.vnumtax != NULL) { /* If source mesh is not original mesh */ for (indvnodnum = indmeshptr->m.vnodbas; indvnodnum < indmeshptr->vnohnnd; indvnodnum ++) indmeshptr->m.vnumtax[indvnodnum] = orgmeshptr->m.vnumtax[indmeshptr->m.vnumtax[indvnodnum] + (orgmeshptr->m.vnodbas - orgmeshptr->m.baseval)]; } indmeshptr->m.edgetax = memRealloc (indedgetax + indmeshptr->m.baseval, indedgenbr * sizeof (Gnum)); indmeshptr->m.edgetax -= indmeshptr->m.baseval; #ifdef SCOTCH_DEBUG_HMESH2 if (hmeshCheck (indmeshptr) != 0) { /* Check halo mesh consistency */ errorPrint ("hmeshInducePart: inconsistent halo mesh data"); hmeshExit (indmeshptr); return (1); } #endif /* SCOTCH_DEBUG_HMESH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/kdgraph_map_rb.c0000644002563400244210000002225012035310673024737 0ustar trophimeutilisateurs du domaine/* Copyright 2008,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kdgraph_map_rb.c **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module performs the Dual Recursive **/ /** Bipartitioning mapping algorithm **/ /** in parallel. **/ /** **/ /** DATES : # Version 5.1 : from : 16 apr 2008 **/ /** to 01 jul 2008 **/ /** # Version 6.0 : from : 03 oct 2012 **/ /** to 10 oct 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define KDGRAPH_MAP_RB #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "arch.h" #include "dgraph.h" #include "dmapping.h" #include "kdgraph.h" #include "kdgraph_map_rb.h" #include "kdgraph_map_rb_map.h" #include "kdgraph_map_rb_part.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* These routines add mapping fragments to the distributed ** mapping structure. */ DmappingFrag * kdgraphMapRbAdd2 ( const Gnum vertnbr, const Anum domnnbr) { DmappingFrag * restrict fragptr; if ((fragptr = memAlloc (sizeof (DmappingFrag))) == NULL) { errorPrint ("kdgraphMapRbAdd2: out of memory (1)"); return (NULL); } if (((fragptr->vnumtab = memAlloc (vertnbr * sizeof (Gnum))) == NULL) || ((fragptr->parttab = memAlloc (vertnbr * sizeof (Anum))) == NULL) || ((fragptr->domntab = memAlloc (domnnbr * sizeof (ArchDom))) == NULL)) { errorPrint ("kdgraphMapRbAdd2: out of memory (2)"); if (fragptr->vnumtab != NULL) { if (fragptr->parttab != NULL) memFree (fragptr->parttab); memFree (fragptr->vnumtab); } return (NULL); } fragptr->vertnbr = vertnbr; fragptr->domnnbr = domnnbr; return (fragptr); } int kdgraphMapRbAddBoth ( const Dgraph * restrict const grafptr, Dmapping * restrict const mappptr, const ArchDom * restrict const domnptr, /*+ Pointer to both subdomains +*/ const GraphPart * restrict const parttab) /*+ Bipartition graph part array +*/ { DmappingFrag * restrict fragptr; Anum * restrict fragparttab; Gnum vertlocnum; if ((fragptr = kdgraphMapRbAdd2 (grafptr->vertlocnbr, 2)) == NULL) /* Two domains */ return (1); fragptr->domntab[0] = domnptr[0]; fragptr->domntab[1] = domnptr[1]; if (parttab == NULL) /* If bipartition part array not set */ memSet (fragptr->parttab, 0, grafptr->vertlocnbr * sizeof (Anum)); else { fragparttab = fragptr->parttab; for (vertlocnum = 0; vertlocnum < grafptr->vertlocnbr; vertlocnum ++) fragparttab[vertlocnum] = (Anum) parttab[vertlocnum]; } if (grafptr->vnumloctax != NULL) memCpy (fragptr->vnumtab, grafptr->vnumloctax + grafptr->baseval, fragptr->vertnbr * sizeof (Gnum)); else { Gnum * restrict fragvnumtab; Gnum vertlocadj; Gnum vertlocnum; fragvnumtab = fragptr->vnumtab; for (vertlocnum = 0, vertlocadj = grafptr->procvrttab[grafptr->proclocnum]; vertlocnum < grafptr->vertlocnbr; vertlocnum ++) fragvnumtab[vertlocnum] = vertlocadj + vertlocnum; } dmapAdd (mappptr, fragptr); return (0); } int kdgraphMapRbAddOne ( const Dgraph * restrict const grafptr, Dmapping * restrict const mappptr, const ArchDom * restrict const domnptr) { DmappingFrag * restrict fragptr; if ((fragptr = kdgraphMapRbAdd2 (grafptr->vertlocnbr, 1)) == NULL) /* Only one domain */ return (1); fragptr->domntab[0] = *domnptr; /* Only one domain for this mapping fragment */ memSet (fragptr->parttab, 0, fragptr->vertnbr * sizeof (Anum)); /* All vertices mapped to it */ if (grafptr->vnumloctax != NULL) memCpy (fragptr->vnumtab, grafptr->vnumloctax + grafptr->baseval, fragptr->vertnbr * sizeof (Gnum)); else { Gnum * restrict fragvnumtab; Gnum vertlocadj; Gnum vertlocnum; fragvnumtab = fragptr->vnumtab; for (vertlocnum = 0, vertlocadj = grafptr->procvrttab[grafptr->proclocnum]; vertlocnum < grafptr->vertlocnbr; vertlocnum ++) fragvnumtab[vertlocnum] = vertlocadj + vertlocnum; } dmapAdd (mappptr, fragptr); return (0); } int kdgraphMapRbAddPart ( const Dgraph * restrict const grafptr, Dmapping * restrict const mappptr, const ArchDom * restrict const domnptr, /*+ Pointer to one subdomain +*/ const Gnum vertnbr, const GraphPart * const parttab, const GraphPart partval) { DmappingFrag * restrict fragptr; Gnum * restrict fragvnumtab; Gnum vertlocnum; Gnum partlocnum; if ((fragptr = kdgraphMapRbAdd2 (vertnbr, 1)) == NULL) /* Only one domain and a limited number of vertices */ return (1); fragptr->domntab[0] = *domnptr; /* Only one domain for this mapping fragment */ memSet (fragptr->parttab, 0, fragptr->vertnbr * sizeof (Anum)); /* All vertices mapped to it */ fragvnumtab = fragptr->vnumtab; if (grafptr->vnumloctax != NULL) { const Gnum * restrict vnumtab; for (vertlocnum = partlocnum = 0, vnumtab = grafptr->vnumloctax + grafptr->baseval; vertlocnum < grafptr->vertlocnbr; vertlocnum ++) { if (parttab[vertlocnum] == partval) { #ifdef SCOTCH_DEBUG_KDMAP2 if (partlocnum >= vertnbr) { errorPrint ("kdgraphMapRbAddPart: invalid parameters (1)"); return (1); } #endif /* SCOTCH_DEBUG_KDMAP2 */ fragvnumtab[partlocnum ++] = vnumtab[vertlocnum]; } } } else { Gnum vertlocadj; for (vertlocnum = partlocnum = 0, vertlocadj = grafptr->procvrttab[grafptr->proclocnum]; vertlocnum < grafptr->vertlocnbr; vertlocnum ++) { if (parttab[vertlocnum] == partval) { #ifdef SCOTCH_DEBUG_KDMAP2 if (partlocnum >= vertnbr) { errorPrint ("kdgraphMapRbAddPart: invalid parameters (2)"); return (1); } #endif /* SCOTCH_DEBUG_KDMAP2 */ fragvnumtab[partlocnum ++] = vertlocadj + vertlocnum; } } } #ifdef SCOTCH_DEBUG_KDMAP2 if (partlocnum != vertnbr) { errorPrint ("kdgraphMapRbAddPart: invalid parameters (3)"); return (1); } #endif /* SCOTCH_DEBUG_KDMAP2 */ dmapAdd (mappptr, fragptr); return (0); } /* ** This routine runs the parallel Dual ** Recursive Bipartitioning algorithm. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int kdgraphMapRb ( Kdgraph * restrict const grafptr, Kdmapping * restrict const mappptr, const KdgraphMapRbParam * restrict const paraptr) { if (grafptr->s.vertglbnbr == 0) /* If nothing to do, return immediately */ return (0); return (archPart (&mappptr->mappptr->archdat) /* If target architecture is some flavor of complete graph */ ? kdgraphMapRbPart (grafptr, mappptr, paraptr) : kdgraphMapRbMap (grafptr, mappptr, paraptr)); } scotch-6.0.4.dfsg/src/libscotch/bgraph_bipart_bd.c0000644002563400244210000007074112371155614025265 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bgraph_bipart_bd.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module builds a band graph around **/ /** the frontier in order to decrease **/ /** problem size for the strategy to be **/ /** applied. **/ /** **/ /** DATES : # Version 5.0 : from : 27 nov 2006 **/ /** to : 23 dec 2007 **/ /** # Version 5.1 : from : 09 nov 2008 **/ /** to : 26 mar 2011 **/ /** # Version 6.0 : from : 07 nov 2011 **/ /** to : 08 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define BGRAPH_BIPART_BD #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "arch.h" #include "bgraph.h" #include "bgraph_bipart_bd.h" #include "bgraph_bipart_st.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ int bgraphBipartBd ( Bgraph * restrict const orggrafptr, /*+ Active graph +*/ const BgraphBipartBdParam * const paraptr) /*+ Method parameters +*/ { Gnum * restrict queutab; Gnum queuheadval; Gnum queutailval; Gnum distmax; /* Maximum distance allowed */ Gnum * restrict orgindxtax; /* Based access to index array for original graph */ Gnum orgfronnum; Gnum ancfronnum; Gnum bndfronnum; Bgraph bndgrafdat; /* Band graph structure */ Gnum bndvertnbr; /* Number of regular vertices in band graph (without anchors) */ Gnum bndvertnnd; const Gnum * restrict bndvnumtax; /* Band vertex number array, recycling queutab */ Gnum * restrict bndveextax; /* External gain array of band graph, if present */ Gnum bndveexnbr; /* Number of external array vertices */ Gnum bndvelosum; /* Load of regular vertices in band graph */ Gnum bndedlosum; /* Sum of edge loads */ Gnum bndcompsize1; /* Number of regular vertices in part 1 of band graph */ Gnum bndcompload1; /* Load of regular vertices in part 1 */ Gnum bndvlvlnum; /* Index of first band graph vertex to belong to the last layer */ Gnum bndvertnum; Gnum bndeancnbr; /* Number of anchor edges */ Gnum bndedgenbr; /* Upper bound on the number of edges, including anchor edges */ Gnum bndedgenum; Gnum * restrict bndedgetax; Gnum * restrict bndedlotax; Gnum bndedgetmp; Gnum bnddegrmax; Gnum bndcommgainextn; /* Sum of all external gains in band graph */ Gnum bndcommgainextn1; /* Sum of external gains accounted for in load, since in part 1 */ size_t bndedlooftval; /* Offset of edge load array with respect to edge array */ const Gnum * restrict const orgverttax = orggrafptr->s.verttax; /* Fast accesses */ const Gnum * restrict const orgvendtax = orggrafptr->s.vendtax; const Gnum * restrict const orgvelotax = orggrafptr->s.velotax; const Gnum * restrict const orgedgetax = orggrafptr->s.edgetax; const Gnum * restrict const orgedlotax = orggrafptr->s.edlotax; GraphPart * restrict const orgparttax = orggrafptr->parttax; Gnum * restrict const orgfrontab = orggrafptr->frontab; if (orggrafptr->fronnbr == 0) /* If no separator vertices, apply strategy to full (original) graph */ return (bgraphBipartSt (orggrafptr, paraptr->stratorg)); distmax = (Gnum) paraptr->distmax; if (distmax < 1) /* Always at least one layer of vertices around separator */ distmax = 1; if (memAllocGroup ((void **) (void *) &queutab, (size_t) (orggrafptr->s.vertnbr * sizeof (Gnum)), &orgindxtax, (size_t) (orggrafptr->s.vertnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("bgraphBipartBd: out of memory (1)"); return (1); } memSet (orgindxtax, ~0, orggrafptr->s.vertnbr * sizeof (Gnum)); /* Initialize index array */ orgindxtax -= orggrafptr->s.baseval; queuheadval = orggrafptr->fronnbr; /* First layer is vertices in frontier array */ for (orgfronnum = 0, bndvertnnd = orggrafptr->s.baseval; /* Flag vertices belonging to frontier as band vertices */ orgfronnum < queuheadval; orgfronnum ++) { Gnum orgvertnum; orgvertnum = orgfrontab[orgfronnum]; orgindxtax[orgvertnum] = bndvertnnd ++; queutab[orgfronnum] = orgvertnum; /* Copy frontier array in queue array */ } bndvelosum = 0; bndedgenbr = 0; /* Estimate upper bound on the number of edges */ bndcompsize1 = 0; bndcompload1 = 0; queutailval = 0; bndvlvlnum = 0; /* Assume first layer is last layer */ while (distmax -- > 0) { /* For all passes except the last one */ Gnum orgvertnum; Gnum orgdistval; bndvlvlnum = queuheadval; /* Record start of last layer */ while (queutailval < bndvlvlnum) { /* For all vertices in queue */ Gnum orgvertnum; Gnum orgedgenum; Gnum orgpartval; orgvertnum = queutab[queutailval ++]; #ifdef SCOTCH_DEBUG_BGRAPH2 if ((orgvertnum < orggrafptr->s.baseval) || (orgvertnum >= orggrafptr->s.vertnnd)) { errorPrint ("bgraphBipartBd: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH2 */ bndedgenbr += orgvendtax[orgvertnum] - orgverttax[orgvertnum]; /* Exact number of edges */ orgpartval = orgparttax[orgvertnum]; bndcompsize1 += orgpartval; /* Count vertices in part 1 */ if (orgvelotax != NULL) { Gnum orgveloval; orgveloval = orgvelotax[orgvertnum]; bndvelosum += orgveloval; bndcompload1 += orgveloval * orgpartval; } for (orgedgenum = orgverttax[orgvertnum]; orgedgenum < orgvendtax[orgvertnum]; orgedgenum ++) { Gnum orgvertend; orgvertend = orgedgetax[orgedgenum]; if (orgindxtax[orgvertend] == ~0) { /* If vertex not visited yet */ orgindxtax[orgvertend] = bndvertnnd ++; /* Flag it as enqueued */ queutab[queuheadval ++] = orgvertend; /* Enqueue it */ } } } } bndedgenbr += queuheadval - queutailval; /* As many edges from anchors as remaining vertices */ while (queutailval < queuheadval) { /* Process vertices in last layer */ Gnum orgvertnum; Gnum orgpartval; orgvertnum = queutab[queutailval ++]; #ifdef SCOTCH_DEBUG_BGRAPH2 if ((orgvertnum < orggrafptr->s.baseval) || (orgvertnum >= orggrafptr->s.vertnnd)) { errorPrint ("bgraphBipartBd: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH2 */ bndedgenbr += orgvendtax[orgvertnum] - orgverttax[orgvertnum]; /* Upper bound on number of edges, including anchor edge */ orgpartval = orgparttax[orgvertnum]; bndcompsize1 += orgpartval; /* Count vertices in part 1 */ if (orgvelotax != NULL) { Gnum orgveloval; orgveloval = orgvelotax[orgvertnum]; bndvelosum += orgveloval; bndcompload1 += orgveloval * orgpartval; } } bndvertnbr = bndvertnnd - orggrafptr->s.baseval; if (orgvelotax == NULL) { bndvelosum = bndvertnbr; bndcompload1 = bndcompsize1; } if ((bndcompsize1 >= (orggrafptr->s.vertnbr - orggrafptr->compsize0)) || /* If either part has all of its vertices in band, use plain graph instead */ ((bndvertnbr - bndcompsize1) >= orggrafptr->compsize0)) { memFree (queutab); return (bgraphBipartSt (orggrafptr, paraptr->stratorg)); } /* TRICK: since always at least one missing vertex per part, there is room for anchor vertices */ queutab[bndvertnbr] = /* Anchor vertices do not have original vertex numbers */ queutab[bndvertnbr + 1] = -1; memSet (&bndgrafdat, 0, sizeof (Bgraph)); bndgrafdat.s.flagval = GRAPHFREETABS | GRAPHVERTGROUP | GRAPHEDGEGROUP | BGRAPHHASANCHORS; /* All Bgraph arrays are non-freeable by bgraphExit() */ bndgrafdat.s.baseval = orggrafptr->s.baseval; bndgrafdat.s.vertnbr = bndvertnbr += 2; /* "+ 2" for anchor vertices */ bndgrafdat.s.vertnnd = bndvertnnd + 2; bndveexnbr = (orggrafptr->veextax != NULL) ? bndvertnbr : 0; if (memAllocGroup ((void **) (void *) /* Do not allocate vnumtax but keep queutab instead */ &bndgrafdat.s.verttax, (size_t) ((bndvertnbr + 1) * sizeof (Gnum)), &bndgrafdat.s.velotax, (size_t) (bndvertnbr * sizeof (Gnum)), &bndveextax, (size_t) (bndveexnbr * sizeof (Gnum)), &bndgrafdat.frontab, (size_t) (bndvertnbr * sizeof (Gnum)), &bndgrafdat.parttax, (size_t) (bndvertnbr * sizeof (GraphPart)), NULL) == NULL) { errorPrint ("bgraphBipartBd: out of memory (2)"); memFree (queutab); return (1); } bndgrafdat.parttax -= orggrafptr->s.baseval; /* From now on we should free a Bgraph and not a Graph */ bndgrafdat.s.verttax -= orggrafptr->s.baseval; bndgrafdat.s.vendtax = bndgrafdat.s.verttax + 1; /* Band graph is compact */ bndgrafdat.s.velotax -= orggrafptr->s.baseval; bndgrafdat.s.vnumtax = queutab - orggrafptr->s.baseval; /* TRICK: re-use queue array as vertex number array since vertices taken in queue order; will not be freed as graph vertex arrays are said to be grouped */ bndgrafdat.s.velosum = orggrafptr->s.velosum; bndgrafdat.s.velotax[bndvertnnd] = orggrafptr->compload0 - (bndvelosum - bndcompload1); /* Set loads of anchor vertices */ bndgrafdat.s.velotax[bndvertnnd + 1] = orggrafptr->s.velosum - orggrafptr->compload0 - bndcompload1; if (bndveexnbr != 0) { bndveextax -= orggrafptr->s.baseval; bndgrafdat.veextax = bndveextax; } else bndveextax = NULL; if (memAllocGroup ((void **) (void *) &bndgrafdat.s.edgetax, (size_t) (bndedgenbr * sizeof (Gnum)), &bndgrafdat.s.edlotax, (size_t) (bndedgenbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("bgraphBipartBd: out of memory (3)"); bgraphExit (&bndgrafdat); memFree (queutab); return (1); } bndgrafdat.s.edgetax -= orggrafptr->s.baseval; bndgrafdat.s.edlotax -= orggrafptr->s.baseval; bndedgetax = bndgrafdat.s.edgetax; bndedlotax = bndgrafdat.s.edlotax; bndvnumtax = bndgrafdat.s.vnumtax; for (bndvertnum = bndedgenum = orggrafptr->s.baseval, bnddegrmax = bndedlosum = bndcommgainextn = bndcommgainextn1 = 0; bndvertnum < bndvlvlnum; bndvertnum ++) { /* Fill index array for vertices not belonging to last level */ Gnum orgvertnum; GraphPart orgpartval; Gnum orgedgenum; Gnum orgedloval; Gnum bnddegrval; orgvertnum = bndvnumtax[bndvertnum]; orgpartval = orgparttax[orgvertnum]; bndgrafdat.s.verttax[bndvertnum] = bndedgenum; bndgrafdat.s.velotax[bndvertnum] = (orgvelotax != NULL) ? orgvelotax[orgvertnum] : 1; bndgrafdat.parttax[bndvertnum] = orgpartval; if (bndveextax != NULL) { Gnum orgveexval; orgveexval = orggrafptr->veextax[orgvertnum]; bndveextax[bndvertnum] = orgveexval; bndcommgainextn += orgveexval; bndcommgainextn1 += orgveexval * (Gnum) orgpartval; } orgedloval = 1; /* Assume unity edge loads if not present */ for (orgedgenum = orgverttax[orgvertnum]; /* All edges of first levels are kept */ orgedgenum < orgvendtax[orgvertnum]; orgedgenum ++, bndedgenum ++) { #ifdef SCOTCH_DEBUG_BGRAPH2 if ((bndedgenum >= (bndedgenbr + orggrafptr->s.baseval)) || (orgindxtax[orgedgetax[orgedgenum]] < 0)) { errorPrint ("bgraphBipartBd: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH2 */ if (orgedlotax != NULL) orgedloval = orgedlotax[orgedgenum]; bndedlosum += orgedloval; bndedgetax[bndedgenum] = orgindxtax[orgedgetax[orgedgenum]]; bndedlotax[bndedgenum] = orgedloval; } bnddegrval = bndedgenum - bndgrafdat.s.verttax[bndvertnum]; if (bnddegrmax < bnddegrval) bnddegrmax = bnddegrval; } bndeancnbr = 0; for ( ; bndvertnum < bndvertnnd; bndvertnum ++) { /* Fill index array for vertices belonging to last level */ Gnum orgvertnum; Gnum orgedgenum; GraphPart orgpartval; Gnum bnddegrval; Gnum orgedloval; Gnum ancedloval; /* Accumulated edge load for anchor edge */ orgvertnum = bndvnumtax[bndvertnum]; orgpartval = orgparttax[orgvertnum]; bndgrafdat.s.verttax[bndvertnum] = bndedgenum; bndgrafdat.s.velotax[bndvertnum] = (orgvelotax != NULL) ? orgvelotax[orgvertnum] : 1; bndgrafdat.parttax[bndvertnum] = orgpartval; /* Record part for vertices of last level */ if (bndveextax != NULL) { Gnum orgveexval; orgveexval = orggrafptr->veextax[orgvertnum]; bndveextax[bndvertnum] = orgveexval; bndcommgainextn += orgveexval; bndcommgainextn1 += orgveexval * (Gnum) orgpartval; } ancedloval = 0; orgedloval = 1; /* Assume unity edge loads if not present */ for (orgedgenum = orgverttax[orgvertnum]; /* Keep only band edges */ orgedgenum < orgvendtax[orgvertnum]; orgedgenum ++) { Gnum bndvertend; #ifdef SCOTCH_DEBUG_BGRAPH2 if (bndedgenum >= (bndedgenbr + orggrafptr->s.baseval)) { errorPrint ("bgraphBipartBd: internal error (4)"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH2 */ if (orgedlotax != NULL) orgedloval = orgedlotax[orgedgenum]; bndedlosum += orgedloval; /* Normal arcs are accounted for twice; anchor arcs only once */ bndvertend = orgindxtax[orgedgetax[orgedgenum]]; if (bndvertend != ~0) { bndedgetax[bndedgenum] = bndvertend; bndedlotax[bndedgenum ++] = orgedloval; } else ancedloval += orgedloval; /* Accumulate loads of edges linking to anchor vertex */ } bndedlosum += ancedloval; /* Account for anchor edges a second time */ if (ancedloval > 0) { /* If vertex is connected to rest of part */ bndedlotax[bndedgenum] = ancedloval; bndedgetax[bndedgenum ++] = bndvertnnd + (Gnum) orgpartval; /* Add anchor edge to proper anchor vertex */ bndeancnbr ++; } bnddegrval = bndedgenum - bndgrafdat.s.verttax[bndvertnum]; if (bnddegrmax < bnddegrval) bnddegrmax = bnddegrval; } bndgrafdat.parttax[bndvertnnd] = 0; /* Set parts of anchor vertices */ bndgrafdat.parttax[bndvertnnd + 1] = 1; bndgrafdat.s.edlosum = bndedlosum; bndgrafdat.s.verttax[bndvertnnd] = bndedgenum; /* Mark end of regular edge array and start of first anchor edge array */ bndedgetmp = bndedgenum + bndeancnbr; #ifdef SCOTCH_DEBUG_BGRAPH2 if ((bndedgetmp - 1) >= (bndedgenbr + orggrafptr->s.baseval)) { errorPrint ("bgraphBipartBd: internal error (5)"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH2 */ bndgrafdat.s.edgenbr = bndedgetmp - orggrafptr->s.baseval; bndgrafdat.s.verttax[bndvertnnd + 2] = bndedgetmp; /* Mark end of edge array with anchor vertices */ for (bndvertnum = bndvlvlnum; bndvertnum < bndvertnnd; bndvertnum ++) { /* Fill anchor edge arrays */ Gnum orgvertnum; orgvertnum = bndvnumtax[bndvertnum]; if (bndgrafdat.s.verttax[bndvertnum + 1] > bndgrafdat.s.verttax[bndvertnum]) { /* If vertex is not isolated */ Gnum bndedgelst; /* Number of last edge */ Gnum bndvertend; bndedgelst = bndgrafdat.s.verttax[bndvertnum + 1] - 1; bndvertend = bndedgetax[bndedgelst]; /* Get last neighbor of its edge sub-array */ if (bndvertend >= bndvertnnd) { /* If it is an anchor */ Gnum bndedloval; bndedloval = bndedlotax[bndedgelst]; bndedlosum += bndedloval; if (bndvertend == bndvertnnd) { /* Add edge from proper anchor */ bndedgetax[bndedgenum] = bndvertnum; bndedlotax[bndedgenum ++] = bndedloval; } else { bndedgetax[-- bndedgetmp] = bndvertnum; bndedlotax[bndedgetmp] = bndedloval; } } } } bndgrafdat.s.verttax[bndvertnnd + 1] = bndedgenum; /* Mark end of edge array of first anchor and start of second */ #ifdef SCOTCH_DEBUG_BGRAPH2 if (bndedgenum != bndedgetmp) { errorPrint ("bgraphBipartBd: internal error (6)"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH2 */ if ((bndedgenum == bndgrafdat.s.verttax[bndvertnnd]) || /* If any of the anchor edges is isolated */ (bndedgenum == bndgrafdat.s.verttax[bndvertnnd + 2])) { bgraphExit (&bndgrafdat); /* Free all band graph related data */ memFree (queutab); return (bgraphBipartSt (orggrafptr, paraptr->stratorg)); /* Work on original graph */ } if (bnddegrmax < (bndgrafdat.s.verttax[bndvertnnd + 1] - bndgrafdat.s.verttax[bndvertnnd])) bnddegrmax = (bndgrafdat.s.verttax[bndvertnnd + 1] - bndgrafdat.s.verttax[bndvertnnd]); if (bnddegrmax < (bndgrafdat.s.verttax[bndvertnnd + 2] - bndgrafdat.s.verttax[bndvertnnd + 1])) bnddegrmax = (bndgrafdat.s.verttax[bndvertnnd + 2] - bndgrafdat.s.verttax[bndvertnnd + 1]); bndgrafdat.s.degrmax = bnddegrmax; bndedlooftval = bndedlotax - bndedgetax; bndgrafdat.s.edgetax = (Gnum *) memRealloc (bndedgetax + bndgrafdat.s.baseval, (bndedlooftval + bndgrafdat.s.edgenbr) * sizeof (Gnum)) - bndgrafdat.s.baseval; bndgrafdat.s.edlotax = bndgrafdat.s.edgetax + bndedlooftval; /* Use old index into old array as new index */ bndedgetax = bndgrafdat.s.edgetax; bndedlotax = bndgrafdat.s.edlotax; for (bndfronnum = 0, bndvertnum = orggrafptr->s.baseval; /* Fill band frontier array with first vertex indices as they make the separator */ bndfronnum < orggrafptr->fronnbr; bndfronnum ++, bndvertnum ++) bndgrafdat.frontab[bndfronnum] = bndvertnum; if (bndveextax != NULL) { Gnum bndcommloadintn; Gnum bndfronnnd; Gnum bndvertnum; Gnum bndedgenum; Gnum bndedloval; bndedloval = 1; /* Assume unity edge weights */ bndcommloadintn = 0; for (bndvertnum = orggrafptr->s.baseval, bndfronnnd = bndvertnum + orggrafptr->fronnbr; /* Compute communication load at frontier */ bndvertnum < bndfronnnd; bndvertnum ++) { Gnum bndpartval; bndpartval = (Gnum) bndgrafdat.parttax[bndvertnum]; if (bndpartval != 0) /* Process only frontier vertices in part 0 */ continue; for (bndedgenum = bndgrafdat.s.verttax[bndvertnum]; bndedgenum < bndgrafdat.s.vendtax[bndvertnum]; bndedgenum ++) { Gnum bndpartend; bndpartend = (Gnum) bndgrafdat.parttax[bndedgetax[bndedgenum]]; bndedloval = bndedlotax[bndedgenum]; bndcommloadintn += bndedloval * bndpartend; } } bndcommloadintn *= orggrafptr->domndist; bndveextax[bndvertnnd + 1] = (orggrafptr->commload - orggrafptr->commloadextn0 - bndcommloadintn) - bndcommgainextn1; bndveextax[bndvertnnd] = (orggrafptr->commload - orggrafptr->commloadextn0 - bndcommloadintn) - bndcommgainextn + bndcommgainextn1 + orggrafptr->commgainextn; } bndgrafdat.fronnbr = orggrafptr->fronnbr; bndgrafdat.compload0 = orggrafptr->compload0; bndgrafdat.compload0min = orggrafptr->compload0min; bndgrafdat.compload0max = orggrafptr->compload0max; bndgrafdat.compload0avg = orggrafptr->compload0avg; bndgrafdat.compload0dlt = orggrafptr->compload0dlt; bndgrafdat.compsize0 = bndvertnbr - bndcompsize1 - 1; /* "- 1" for anchor vertex in part 0 */ bndgrafdat.commload = orggrafptr->commload; bndgrafdat.commloadextn0 = orggrafptr->commloadextn0; bndgrafdat.commgainextn = orggrafptr->commgainextn; bndgrafdat.commgainextn0 = orggrafptr->commgainextn0; bndgrafdat.domndist = orggrafptr->domndist; bndgrafdat.domnwght[0] = orggrafptr->domnwght[0]; bndgrafdat.domnwght[1] = orggrafptr->domnwght[1]; bndgrafdat.vfixload[0] = orggrafptr->vfixload[0]; bndgrafdat.vfixload[1] = orggrafptr->vfixload[1]; bndgrafdat.bbalval = orggrafptr->bbalval; bndgrafdat.levlnum = orggrafptr->levlnum; #ifdef SCOTCH_DEBUG_BGRAPH2 if ((graphCheck (&bndgrafdat.s) != 0) || /* Check band graph consistency */ (bgraphCheck (&bndgrafdat) != 0)) { errorPrint ("bgraphBipartBd: inconsistent band graph data"); bgraphExit (&bndgrafdat); memFree (queutab); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH2 */ if (bgraphBipartSt (&bndgrafdat, paraptr->stratbnd) != 0) { /* Apply strategy to band graph */ errorPrint ("bgraphBipartBd: cannot bipartition band graph"); bgraphExit (&bndgrafdat); memFree (queutab); return (1); } if (bndgrafdat.parttax[bndvertnnd] == /* If band graph was too small and anchors went to the same part, apply strategy on full graph */ bndgrafdat.parttax[bndvertnnd + 1]) { bgraphExit (&bndgrafdat); memFree (queutab); return (bgraphBipartSt (orggrafptr, paraptr->stratorg)); } orggrafptr->compload0 = bndgrafdat.compload0; orggrafptr->compload0dlt = bndgrafdat.compload0dlt; orggrafptr->commload = bndgrafdat.commload; orggrafptr->commgainextn = bndgrafdat.commgainextn; orggrafptr->bbalval = bndgrafdat.bbalval; if (bndgrafdat.parttax[bndvertnnd] != 0) { /* If anchors swapped parts, swap all parts of original vertices */ Gnum orgvertnum; orggrafptr->compsize0 = orggrafptr->s.vertnbr - orggrafptr->compsize0 - bndcompsize1 + bndgrafdat.compsize0 - 1; /* "- 1" for anchor 0 */ for (orgvertnum = orggrafptr->s.baseval; orgvertnum < orggrafptr->s.vertnnd; orgvertnum ++) orgparttax[orgvertnum] ^= 1; } else orggrafptr->compsize0 = orggrafptr->compsize0 - (bndvertnbr - bndcompsize1) + bndgrafdat.compsize0 + 1; /* "+ 1" for anchor 0 */ for (bndvertnum = bndgrafdat.s.baseval; bndvertnum < bndvertnnd; bndvertnum ++) /* Update part array of full graph */ orgparttax[bndvnumtax[bndvertnum]] = bndgrafdat.parttax[bndvertnum]; for (bndfronnum = orgfronnum = ancfronnum = 0; /* Update frontier array of full graph */ bndfronnum < bndgrafdat.fronnbr; bndfronnum ++) { Gnum bndvertnum; Gnum orgvertnum; bndvertnum = bndgrafdat.frontab[bndfronnum]; orgvertnum = bndvnumtax[bndvertnum]; if (orgvertnum != -1) /* If frontier vertex is not an anchor vertex */ orgfrontab[orgfronnum ++] = orgvertnum; /* Record it as original frontier vertex */ else bndgrafdat.frontab[ancfronnum ++] = bndvertnum; /* Else record it for future processing */ } while (ancfronnum > 0) { /* For all recorded frontier anchor vertices */ Gnum bndvertnum; /* Index of frontier anchor vertex in band graph */ GraphPart ancpartval; bndvertnum = bndgrafdat.frontab[-- ancfronnum]; ancpartval = bndgrafdat.parttax[bndvertnum]; for (bndedgenum = bndgrafdat.s.verttax[bndvertnum]; bndedgenum < bndgrafdat.s.vendtax[bndvertnum]; bndedgenum ++) { Gnum bndvertend; /* Index of neighbor of anchor vertex in band graph */ Gnum orgvertnum; /* Index of neighbor of anchor vertex in original graph */ Gnum orgedgenum; bndvertend = bndedgetax[bndedgenum]; if (bndgrafdat.parttax[bndvertend] == ancpartval) /* If neighbor is in same part as anchor, skip to next */ continue; orgvertnum = bndvnumtax[bndvertend]; for (orgedgenum = orgverttax[orgvertnum]; /* For all neighbors of neighbor */ orgedgenum < orgvendtax[orgvertnum]; orgedgenum ++) { Gnum orgvertend; orgvertend = orgedgetax[orgedgenum]; /* Get end vertex in original graph */ if (orgindxtax[orgvertend] == ~0) { /* If vertex never considered before */ #ifdef SCOTCH_DEBUG_BGRAPH2 if (orgparttax[orgvertend] != ancpartval) { /* Original vertex should always be in same part as anchor */ errorPrint ("bgraphBipartBd: internal error (7)"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH2 */ orggrafptr->frontab[orgfronnum ++] = orgvertend; /* Add vertex to frontier array */ orgindxtax[orgvertend] = 0; /* Flag vertex as already enqueued */ } } } } orggrafptr->fronnbr = orgfronnum; bgraphExit (&bndgrafdat); /* Free band graph structures */ memFree (queutab); #ifdef SCOTCH_DEBUG_BGRAPH2 if (bgraphCheck (orggrafptr) != 0) { errorPrint ("bgraphBipartBd: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/common_thread.c0000644002563400244210000003772412413267755024646 0ustar trophimeutilisateurs du domaine/* Copyright 2012-2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : common_thread.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module provides routines to ease **/ /** the use of Posix threads. **/ /** **/ /** DATES : # Version 6.0 : from : 04 jul 2012 **/ /** to 02 oct 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #ifdef SCOTCH_PTHREAD_AFFINITY_LINUX #define _GNU_SOURCE #include #endif /* SCOTCH_PTHREAD_AFFINITY_LINUX */ #define COMMON_THREAD #ifndef COMMON_NOMODULE #include "module.h" #endif /* COMMON_NOMODULE */ #include "common.h" /*****************************/ /* */ /* Thread handling routines. */ /* */ /*****************************/ #if ((defined COMMON_PTHREAD) || (defined SCOTCH_PTHREAD)) /* These routines implement the classical barrier ** operations for systems that do not provide them. */ #ifdef COMMON_PTHREAD_BARRIER int threadBarrierInit ( ThreadBarrier * barrptr, void * attrptr, /* Not used */ int thrdnbr) { barrptr->thrdnbr = thrdnbr; barrptr->thrdcur = 0; barrptr->instnum = 0; pthread_mutex_init (&barrptr->mutedat, NULL); pthread_cond_init (&barrptr->conddat, NULL); return (0); } /* ** */ int threadBarrierDestroy ( ThreadBarrier * barrptr) { pthread_cond_destroy (&barrptr->conddat); pthread_mutex_destroy (&barrptr->mutedat); return (0); } /* ** */ int threadBarrierWait ( ThreadBarrier * barrptr) { int instnum; int thrdcur; int o; pthread_mutex_lock (&barrptr->mutedat); thrdcur = barrptr->thrdcur + 1; instnum = barrptr->instnum; o = 0; /* Assume thread will not be the last one */ if (thrdcur == barrptr->thrdnbr) { barrptr->thrdcur = 0; barrptr->instnum = instnum + 1; pthread_cond_broadcast (&barrptr->conddat); o = PTHREAD_BARRIER_SERIAL_THREAD; /* Last thread returns special value */ } else { barrptr->thrdcur = thrdcur; do pthread_cond_wait (&barrptr->conddat, &barrptr->mutedat); while (barrptr->instnum == instnum); } pthread_mutex_unlock (&barrptr->mutedat); return (o); } #endif /* COMMON_PTHREAD_BARRIER */ /* This routine performs a synchronous ** reduction operation on the given block ** of threads. The routine is called only ** if the two threads in the reduction binary ** tree exist. ** A final, global barrier may be necessary for ** all threads to benefit from the result of the ** reduction operation. ** It returns: ** - void : in all cases. */ void threadReduce ( void * const dataptr, /* Per-thread data block */ void * const contptr, /* Pointer to thread contents */ ThreadReduceFunc const redfptr, /* Pointer to reduction routine */ int rootnum) /* Root of reduction */ { ThreadHeader * restrict const thrdptr = (ThreadHeader *) dataptr; ThreadGroupHeader * restrict const grouptr = thrdptr->grouptr; const size_t datasiz = grouptr->datasiz; const int thrdnbr = grouptr->thrdnbr; const int thrdnum = thrdptr->thrdnum; int thrdnsk; /* Rank of thread in skewed reduction tree */ int thrdmsk; thrdnsk = (thrdnum + thrdnbr - rootnum) % thrdnbr; for (thrdmsk = 1; thrdmsk < thrdnbr; thrdmsk <<= 1) { int thrdesk; /* Skewed rank of end thread */ threadBarrierWait (&grouptr->barrdat); thrdesk = thrdnsk ^ thrdmsk; /* Get skewed rank of end thread */ if (thrdesk < thrdnbr) { /* If end thread exists */ if (thrdesk > thrdnsk) { /* If we are on the receiving side */ int thrdend; int thrddlt; thrdend = (thrdesk + rootnum) % thrdnbr; thrddlt = thrdend - thrdnum; redfptr (dataptr, contptr, (void *) ((byte *) contptr + thrddlt * datasiz)); /* Call reduction routine */ } else /* We are on the sending side */ thrdnsk += thrdnbr; /* Make sure we will no longer work */ } } } /* This routine performs a synchronous ** scan operation on the given block of ** threads. It requires a dummy area for ** storing every other result, hence the ** phase number that is passed to the ** auxiliary routine. ** It returns: ** - void : in all cases. */ void threadScan ( void * const dataptr, /* Per-thread data block */ void * const contptr, /* Pointer to thread contents */ ThreadScanFunc const scafptr) /* Scan function */ { ThreadHeader * restrict const thrdptr = (ThreadHeader *) dataptr; ThreadGroupHeader * restrict const grouptr = thrdptr->grouptr; const size_t datasiz = grouptr->datasiz; const int thrdnbr = grouptr->thrdnbr; const int thrdnum = thrdptr->thrdnum; int thrdmsk; int i; for (thrdmsk = 1, i = 0; thrdmsk < thrdnbr; thrdmsk <<= 1, i ^= 1) ; /* Determine number of steps to go */ if (i != 0) /* If number of steps is odd */ scafptr (dataptr, contptr, NULL, 0); /* Pre-copy to swap area so that it will end at the right place */ for (thrdmsk = 1; thrdmsk < thrdnbr; thrdmsk <<= 1, i ^= 1) { int thrdend; threadBarrierWait (&grouptr->barrdat); /* Barrier on all threads, even those which do not participate */ thrdend = thrdnum - thrdmsk; /* Get rank of end thread */ scafptr (dataptr, contptr, (thrdend >= 0) ? (void *) ((byte *) contptr - thrdmsk * datasiz) : NULL, i); /* If end thread exists, perform scan, else just copy */ } } /* This routine actually launches the ** initial thread routine, and performs ** the necessary joins. It is its task ** to set its affinity mask, as in some ** thread implementations threads can ** only set affinity for themselves. */ static void * threadLaunch2 ( void * dataptr) /* Per-thread data block */ { ThreadHeader * restrict const thrdptr = (ThreadHeader *) dataptr; ThreadGroupHeader * restrict const grouptr = thrdptr->grouptr; const size_t datasiz = grouptr->datasiz; const int thrdnbr = grouptr->thrdnbr; const int thrdnum = thrdptr->thrdnum; int thrdmsk; int o; #ifdef SCOTCH_PTHREAD_AFFINITY_LINUX cpu_set_t cpuset; #endif /* SCOTCH_PTHREAD_AFFINITY_LINUX */ #ifdef SCOTCH_PTHREAD_AFFINITY_LINUX CPU_ZERO (&cpuset); CPU_SET (thrdnum, &cpuset); /* Thread sets its own affinity */ pthread_setaffinity_np (thrdptr->thidval, sizeof (cpu_set_t), &cpuset); #endif /* SCOTCH_PTHREAD_AFFINITY_LINUX */ o = grouptr->stafptr (dataptr); /* Call start routine */ for (thrdmsk = 1; thrdmsk < thrdnbr; thrdmsk <<= 1) { volatile ThreadHeader * restrict thrdtmp; /* Pointer to thread header of other thread */ int thrdend; thrdend = thrdnum ^ thrdmsk; /* Get rank of end thread */ if (thrdend >= thrdnbr) /* If end thread does not exist */ continue; thrdtmp = (ThreadHeader *) ((byte *) dataptr + grouptr->datasiz * (thrdend - thrdnum)); while (thrdtmp->thrdnum == -1) ; /* Spin-lock until end thread created */ if (thrdnum > thrdend) { /* If we are on the sending side */ if (thrdtmp->thrdnum < 0) { /* If end thread could not be created */ pthread_detach (thrdptr->thidval); /* Detach since nobody will join for us */ o = 1; /* Set (useless) error return value */ } pthread_exit ((void *) (intptr_t) o); /* Exit anyway */ } else { if (thrdtmp->thrdnum < 0) /* If end thread could not be created */ o = 1; /* Set error return value */ else { void * o2; pthread_join (thrdtmp->thidval, &o2); /* Get return value from end thread */ o |= (int) (intptr_t) o2; /* Amalgamate return status */ if ((grouptr->joifptr != NULL) && /* If we have something to do */ (o == 0)) /* And if no error in both threads */ o |= grouptr->joifptr (dataptr, (void *) ((byte *) dataptr + thrdmsk * datasiz)); /* Call join routine */ } } } return ((void *) (intptr_t) o); /* Thread of rank 0 returns global status */ } /* This routine launches the given ** number of threads that will run the ** given start routine, and will end up ** calling the given join routine in a ** binary tree fashion. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int threadLaunch ( void * const gdatptr, /* Pointer to thread group data block */ void * const tdattab, /* Array of thread data */ const size_t datasiz, /* Size of individual data array cell */ ThreadLaunchStartFunc stafptr, /* Pointer to start routine */ ThreadLaunchJoinFunc joifptr, /* Pointer to join routine */ const int thrdnbr, /* Number of threads to run (including current) */ const int flagval) /* Flag for thread operation data structures */ { ThreadGroupHeader * const grouptr = (ThreadGroupHeader *) gdatptr; ThreadHeader * thrdptr; int thrdnum; byte * dataptr; void * o; grouptr->flagval = flagval; grouptr->datasiz = datasiz; grouptr->thrdnbr = thrdnbr; grouptr->stafptr = stafptr; grouptr->joifptr = joifptr; if ((flagval & THREADHASBARRIER) != 0) { if (threadBarrierInit (&grouptr->barrdat, NULL, thrdnbr) != 0) { errorPrint ("threadLaunch: cannot initialize barrier (1)"); return (1); } } for (thrdnum = 0, dataptr = (byte *) tdattab; /* Prepare threads for launching */ thrdnum < thrdnbr; thrdnum ++, dataptr += datasiz) { ThreadHeader * thrdptr; thrdptr = (ThreadHeader *) dataptr; thrdptr->thrdnum = -1; /* Set threads as not yet launched */ } __sync_synchronize (); /* Full memory barrier */ for (thrdnum = 1, dataptr = (byte *) tdattab + datasiz; /* Launch threads from 1 to (thrdnbr - 1) */ thrdnum < thrdnbr; thrdnum ++, dataptr += datasiz) { ThreadHeader * thrdptr; thrdptr = (ThreadHeader *) dataptr; thrdptr->grouptr = gdatptr; thrdptr->thrdnum = thrdnum; if (pthread_create (&thrdptr->thidval, NULL, threadLaunch2, (void *) dataptr) != 0) { errorPrint ("threadLaunch: cannot launch thread (%d)", thrdnum); return (1); } } thrdptr = (ThreadHeader *) tdattab; /* Run thread 0 */ thrdptr->grouptr = gdatptr; thrdptr->thidval = pthread_self (); thrdptr->thrdnum = 0; o = threadLaunch2 (tdattab); if ((flagval & THREADHASBARRIER) != 0) /* Free allocated resources */ threadBarrierDestroy (&grouptr->barrdat); return ((int) (intptr_t) o); } #else /* ((defined COMMON_PTHREAD) || (defined SCOTCH_PTHREAD)) */ /**********************************/ /* */ /* Thread handling routine stubs. */ /* */ /**********************************/ void threadReduce ( void * const dataptr, /* Per-thread data block */ void * const contptr, /* Pointer to thread contents */ ThreadReduceFunc const redfptr, /* Pointer to reduction routine */ int rootnum) /* Root of reduction */ { errorPrint ("threadReduce: Scotch not compiled with either COMMON_PTHREAD or SCOTCH_PTHREAD"); } void threadScan ( void * const dataptr, /* Per-thread data block */ void * const contptr, /* Pointer to thread contents */ ThreadScanFunc const scafptr) /* Scan function */ { errorPrint ("threadScan: Scotch not compiled with either COMMON_PTHREAD or SCOTCH_PTHREAD"); } int threadLaunch ( void * const gdatptr, /* Pointer to thread group data block */ void * const tdattab, /* Array of thread data */ const size_t datasiz, /* Size of individual data array cell */ ThreadLaunchStartFunc stafptr, /* Pointer to start routine */ ThreadLaunchJoinFunc joifptr, /* Pointer to join routine */ const int thrdnbr, /* Number of threads to run (including current) */ const int flagval) /* Flag for thread operation data structures */ { errorPrint ("threadLaunch: Scotch not compiled with either COMMON_PTHREAD or SCOTCH_PTHREAD"); return (1); } #endif /* ((defined COMMON_PTHREAD) || (defined SCOTCH_PTHREAD)) */ scotch-6.0.4.dfsg/src/libscotch/geom.c0000644002563400244210000000663511631447171022744 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : geom.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles the geometric **/ /** source graph functions. **/ /** **/ /** DATES : # Version 3.3 : from : 12 dec 1998 **/ /** to 21 dec 1998 **/ /** # Version 4.0 : from : 18 dec 2001 **/ /** to 26 nov 2003 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GEOM #include "module.h" #include "common.h" #include "geom.h" /********************************************/ /* */ /* These routines handle geometrical gdata. */ /* */ /********************************************/ /* This routine initializes a geometrical ** data structure. ** It returns: ** - 0 : in all cases. */ int geomInit ( Geom * restrict const geomptr) { geomptr->dimnnbr = 0; /* Initialize geometry */ geomptr->geomtab = NULL; return (0); } /* This routine frees a geometrical graph structure. ** It returns: ** - VOID : in all cases. */ void geomExit ( Geom * restrict const geomptr) { if (geomptr->geomtab != NULL) memFree (geomptr->geomtab); geomptr->dimnnbr = 0; geomptr->geomtab = NULL; } scotch-6.0.4.dfsg/src/libscotch/vdgraph_separate_ml.c0000644002563400244210000010477312412035044026014 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2010,2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vdgraph_separate_ml.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Cedric CHEVALIER (v5.0) **/ /** **/ /** FUNCTION : This module contains the multi-level **/ /** separation strategy. **/ /** **/ /** DATES : # Version 5.0 : from : 07 mar 2006 **/ /** to : 01 mar 2008 **/ /** # Version 5.1 : from : 14 dec 2008 **/ /** to : 26 aug 2010 **/ /** # Version 6.0 : from : 11 sep 2012 **/ /** to : 28 sep 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VDGRAPH_SEPARATE_ML #include "module.h" #include "common.h" #include "parser.h" #include "dgraph.h" #include "dgraph_coarsen.h" #include "vdgraph.h" #include "vdgraph_separate_ml.h" #include "vdgraph_separate_st.h" /*********************************************/ /* */ /* The coarsening and uncoarsening routines. */ /* */ /*********************************************/ /* This routine builds a coarser graph from the ** Dgraph that is given on input. The coarser ** Dgraphs differ at this stage from classical ** active Dgraphs as their internal gains are not ** yet computed. ** It returns: ** - 0 : if the coarse Dgraph has been built. ** - 1 : if threshold achieved or on error. */ static int vdgraphSeparateMlCoarsen ( Vdgraph * restrict const finegrafptr, /*+ Finer graph +*/ Vdgraph * restrict const coargrafptr, /*+ Coarser graph to build +*/ DgraphCoarsenMulti * restrict * const coarmultptr, /*+ Pointer to based multinode table to build +*/ const VdgraphSeparateMlParam * const paraptr) /*+ Method parameters +*/ { int foldval; switch (paraptr->foldval) { case 0 : foldval = DGRAPHCOARSENNONE; break; case 1 : foldval = DGRAPHCOARSENFOLD; break; case 2 : foldval = DGRAPHCOARSENFOLDDUP; break; #ifdef SCOTCH_DEBUG_VDGRAPH2 default : errorPrint ("vdgraphSeparateMlCoarsen: invalid parameter"); return (1); #endif /* SCOTCH_DEBUG_VDGRAPH2 */ } if ((finegrafptr->s.vertglbnbr / finegrafptr->s.procglbnbr) > paraptr->foldmax) /* If no need to fold */ foldval = DGRAPHCOARSENNONE; *coarmultptr = NULL; /* Let the routine create the multinode array */ dgraphInit (&coargrafptr->s, finegrafptr->s.proccomm); /* Re-use fine graph communicator */ if (dgraphCoarsen (&finegrafptr->s, &coargrafptr->s, coarmultptr, paraptr->passnbr, paraptr->coarnbr, paraptr->coarrat, foldval) != 0) return (1); /* Return if coarsening failed */ coargrafptr->fronloctab = NULL; coargrafptr->partgsttax = NULL; /* Do not allocate partition data yet */ if (coargrafptr->s.procglbnbr == 0) { /* Not a owner graph */ coargrafptr->s.vertlocnbr = 0; /* Set it to zero for vrcvdattab allocation */ return (0); } coargrafptr->levlnum = finegrafptr->levlnum + 1; /* Graph level is coarsening level */ if (coargrafptr->s.vertlocnbr <= finegrafptr->s.vertlocnbr) /* If (folded) coarser graph is smaller */ coargrafptr->fronloctab = finegrafptr->fronloctab; /* Re-use frontier array for coarser graph */ else { /* Else allocate new private frontier array */ if ((coargrafptr->fronloctab = memAlloc (coargrafptr->s.vertlocnbr * sizeof (Gnum))) == NULL) { errorPrint ("vdgraphSeparateMlCoarsen: out of memory"); dgraphExit (&coargrafptr->s); /* Only free Dgraph since fronloctab not allocated */ memFree (*coarmultptr); /* Free un-based array */ return (1); } } *coarmultptr -= coargrafptr->s.baseval; /* Base the multinode array */ return (0); } /* This routine is the reduction-loc operator which ** returns in inout[2] the rank of the process which ** holds the best partition. ** It returns: ** - void : in all cases. */ static void vdgraphSeparateMlOpBest ( const Gnum * const in, /* First operand */ Gnum * const inout, /* Second and output operand */ const int * const len, /* Number of instances ; should be 1, not used */ const MPI_Datatype * const typedat) /* MPI datatype ; not used */ { inout[5] |= in[5]; /* Memory error flag */ if (inout[0] == 1) { /* Handle cases when at least one of them is erroneous */ if (in[0] == 1) { if (inout[1] > in[1]) { /* To enforce commutativity, always keep smallest process number */ inout[1] = in[1]; inout[2] = in[2]; } return; } inout[0] = in[0]; /* Validity flag */ inout[1] = in[1]; /* Lead process rank */ inout[2] = in[2]; /* Lead process color */ inout[3] = in[3]; /* Separator size */ inout[4] = in[4]; /* Parts imbalance */ return; } else if (in[0] == 1) return; if ((in[3] < inout[3]) || /* Select best partition */ ((in[3] == inout[3]) && ((in[4] < inout[4]) || ((in[4] == inout[4]) && (in[1] < inout[1]))))) { inout[1] = in[1]; inout[2] = in[2]; inout[3] = in[3]; inout[4] = in[4]; } } /* This routine packs the neighbor data to be sent ** to one of the neighbors by part number. ** It returns: ** - void : in all cases. */ static void vdgraphSeparateMlPack ( Gnum * restrict const dataloctab, const Gnum datalocidx, Gnum * restrict ssndcnttab) { Gnum finevertsndnbr0; Gnum finevertsndnbr1; Gnum finevertsndnbr2; Gnum datalocnbr; finevertsndnbr0 = ssndcnttab[0]; finevertsndnbr1 = ssndcnttab[1]; finevertsndnbr2 = ssndcnttab[2]; datalocnbr = finevertsndnbr0 + finevertsndnbr1 + finevertsndnbr2; if (datalocnbr <= datalocidx) { /* If arrays do not overlap */ Gnum * restrict datadsttab = dataloctab + datalocidx; const Gnum * restrict const datasrctab = dataloctab + datalocidx * 2; Gnum datasrcnum; Gnum partidxtab[3]; partidxtab[0] = 0; partidxtab[1] = finevertsndnbr0; partidxtab[2] = finevertsndnbr0 + finevertsndnbr1; for (datasrcnum = 0, datalocnbr <<= 1; datasrcnum < datalocnbr; ) { /* Work on pairs of Gnum's */ Gnum finevertglbnum; Gnum finepartval; finevertglbnum = datasrctab[datasrcnum ++]; finepartval = datasrctab[datasrcnum ++]; datadsttab[partidxtab[finepartval] ++] = finevertglbnum; } } else { /* Arrays do overlap */ Gnum datadstnum; Gnum datasrcnum; Gnum datasrcnnd; Gnum datasrcnxt; datadstnum = datalocidx; for (datasrcnum = datalocidx << 1, datasrcnnd = datasrcnum + (finevertsndnbr0 << 1), datasrcnxt = datasrcnnd; /* Work on pairs of Gnum's */ datasrcnum < datasrcnnd; ) { Gnum finevertglbnum; Gnum finepartval; finevertglbnum = dataloctab[datasrcnum ++]; finepartval = dataloctab[datasrcnum ++]; if (finepartval != 0) { Gnum finevertglbtmp; #ifdef SCOTCH_DEBUG_VDGRAPH2 if ((finepartval < 1) || (finepartval > 2)) { errorPrint ("vdgraphSeparateMlPack: internal error (1)"); return; } #endif /* SCOTCH_DEBUG_VDGRAPH2 */ while (dataloctab[datasrcnxt + 1] != 0) { /* Find first vertex of part zero in next block */ datasrcnxt += 2; #ifdef SCOTCH_DEBUG_VDGRAPH2 if (datasrcnxt >= ((datalocidx + datalocnbr) << 1)) { errorPrint ("vdgraphSeparateMlPack: internal error (2)"); return; } #endif /* SCOTCH_DEBUG_VDGRAPH2 */ } finevertglbtmp = dataloctab[datasrcnxt]; dataloctab[datasrcnxt ++] = finevertglbnum; dataloctab[datasrcnxt ++] = finepartval; finevertglbnum = finevertglbtmp; } dataloctab[datadstnum ++] = finevertglbnum; } for (datasrcnnd += finevertsndnbr1 << 1, datasrcnxt = datasrcnnd; /* Work on pairs of Gnum's */ datasrcnum < datasrcnnd; ) { Gnum finevertglbnum; Gnum finepartval; finevertglbnum = dataloctab[datasrcnum ++]; finepartval = dataloctab[datasrcnum ++]; if (finepartval != 1) { Gnum finevertglbtmp; #ifdef SCOTCH_DEBUG_VDGRAPH2 if (finepartval != 2) { errorPrint ("vdgraphSeparateMlPack: internal error (3)"); return; } #endif /* SCOTCH_DEBUG_VDGRAPH2 */ while (dataloctab[datasrcnxt + 1] != 1) { /* Find first vertex of part one in next block */ datasrcnxt += 2; #ifdef SCOTCH_DEBUG_VDGRAPH2 if (datasrcnxt >= ((datalocidx + datalocnbr) << 1)) { errorPrint ("vdgraphSeparateMlPack: internal error (4)"); return; } #endif /* SCOTCH_DEBUG_VDGRAPH2 */ } finevertglbtmp = dataloctab[datasrcnxt]; dataloctab[datasrcnxt ++] = finevertglbnum; dataloctab[datasrcnxt ++] = finepartval; finevertglbnum = finevertglbtmp; } dataloctab[datadstnum ++] = finevertglbnum; } for (datasrcnnd += finevertsndnbr2 << 1; datasrcnum < datasrcnnd; ) { /* Work on pairs of Gnum's */ Gnum finevertglbnum; finevertglbnum = dataloctab[datasrcnum]; #ifdef SCOTCH_DEBUG_VDGRAPH2 if (dataloctab[datasrcnum + 1] != 2) { errorPrint ("vdgraphSeparateMlPack: internal error (5)"); return; } #endif /* SCOTCH_DEBUG_VDGRAPH2 */ datasrcnum += 2; dataloctab[datadstnum ++] = finevertglbnum; } } } /* This routine propagates the separation of the ** coarser graph back to the finer graph, according ** to the multinode table of collapsed vertices. ** After the separation is propagated, it finishes ** to compute the parameters of the finer graph that ** were not computed at the coarsening stage. ** It returns: ** - 0 : if coarse graph data has been propagated to the fine graph. ** - !0 : on error. */ static int vdgraphSeparateMlUncoarsen ( Vdgraph * restrict finegrafptr, /*+ Finer graph +*/ const Vdgraph * restrict const coargrafptr, /*+ Coarser graph +*/ const DgraphCoarsenMulti * restrict const coarmulttax) /*+ Based multinode array +*/ { Gnum coarvertnum; Gnum finevertlocadj; Gnum finecomplocload0; Gnum finecomplocload2; Gnum finecomplocsize1; Gnum finecomplocsize2; Gnum * restrict srcvdattab; Gnum * ssnddattab; /* TRICK: holds vrcvcnttab, vsnddsptab, vrcvdsptab */ Gnum * vrcvdattab; /* TRICK: overlaps with vsnddattab before packing [norestrict:async] */ Gnum * vsnddattab; /* [norestrict:async] */ int * vrcvcnttab; int * vsndcnttab; int * vrcvdsptab; int * vsnddsptab; int vrcvdspnum; int vsnddspnum; Gnum vrcvdatnum; MPI_Datatype besttypedat; /* Data type for finding best bipartition */ MPI_Op bestoperdat; /* Handle of MPI operator for finding best bipartition */ Gnum reduloctab[6]; Gnum reduglbtab[6]; int procnum; const Gnum * restrict fineveloglbtax; GraphPart * restrict finepartglbtax; Gnum * restrict const finefronloctab = finegrafptr->fronloctab; reduloctab[5] = 0; /* Assume everything is fine */ if (finegrafptr->partgsttax == NULL) { /* If partition array not yet allocated */ if (dgraphGhst (&finegrafptr->s) != 0) { /* Create ghost edge array and compute vertgstnbr */ errorPrint ("vdgraphSeparateMlUncoarsen: cannot compute ghost edge array"); reduloctab[5] = 1; /* Allocated data will be freed along with graph structure */ } else if ((finegrafptr->partgsttax = (GraphPart *) memAlloc (finegrafptr->s.vertgstnbr * sizeof (GraphPart))) == NULL) { errorPrint ("vdgraphSeparateMlUncoarsen: out of memory (1)"); reduloctab[5] = 1; /* Allocated data will be freed along with graph structure */ } else finegrafptr->partgsttax -= finegrafptr->s.baseval; } if (coargrafptr == NULL) { /* If coarser graph not provided */ #ifdef SCOTCH_DEBUG_BDGRAPH1 /* Communication cannot be overlapped by a useful one */ if (MPI_Allreduce (&reduloctab[5], &reduglbtab[5], 1, GNUM_MPI, MPI_SUM, finegrafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("vdgraphSeparateMlUncoarsen: communication error (1)"); return (1); } #else /* SCOTCH_DEBUG_BDGRAPH1 */ reduglbtab[5] = reduloctab[5]; #endif /* SCOTCH_DEBUG_BDGRAPH1 */ if (reduglbtab[5] != 0) return (1); vdgraphZero (finegrafptr); /* Assign all vertices to part 0 */ return (0); } if (memAllocGroup ((void **) (void *) &vsndcnttab, (size_t) (finegrafptr->s.procglbnbr * sizeof (int)), /* TRICK: srcvdattab after ssnddattab, after vsndcnttab */ &ssnddattab, (size_t) (finegrafptr->s.procglbnbr * 3 * sizeof (Gnum)), /* TRICK: ssnddattab is vrcvcnttab, vsnddsptab, vrcvdsptab */ &srcvdattab, (size_t) (finegrafptr->s.procglbnbr * 3 * sizeof (Gnum)), &vsnddattab, (size_t) (coargrafptr->s.vertlocnbr * 2 * sizeof (Gnum)), /* TRICK: vsnddattab overlaps with vrcvdattab */ &vrcvdattab, (size_t) (MAX ((coargrafptr->s.vertlocnbr * 2), finegrafptr->s.vertlocnbr) * sizeof (Gnum)), NULL) == NULL) { errorPrint ("vdgraphSeparateMlUncoarsen: out of memory (2)"); reduloctab[5] = 1; } if (coargrafptr->s.procglbnbr <= 0) { /* If unused folded coargrafptr */ reduloctab[0] = 1; /* Set it as invalid */ reduloctab[1] = 0; /* Useless rank */ reduloctab[2] = 1; /* Color is not the one of folded */ reduloctab[3] = /* Prevent Valgrind from yelling */ reduloctab[4] = 0; } else { reduloctab[0] = ((coargrafptr->compglbsize[0] == 0) || /* Empty separated parts are deemed invalid */ (coargrafptr->compglbsize[1] == 0)) ? 1 : 0; reduloctab[1] = finegrafptr->s.proclocnum; /* Set rank and color key according to coarse graph (sub)communicator */ reduloctab[2] = finegrafptr->s.prockeyval; reduloctab[3] = coargrafptr->compglbsize[2]; reduloctab[4] = coargrafptr->compglbloaddlt; } if ((MPI_Type_contiguous (6, GNUM_MPI, &besttypedat) != MPI_SUCCESS) || (MPI_Type_commit (&besttypedat) != MPI_SUCCESS) || (MPI_Op_create ((MPI_User_function *) vdgraphSeparateMlOpBest, 1, &bestoperdat) != MPI_SUCCESS)) { errorPrint ("vdgraphSeparateMlUncoarsen: communication error (2)"); return (1); } if (MPI_Allreduce (reduloctab, reduglbtab, 1, besttypedat, bestoperdat, finegrafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("vdgraphSeparateMlUncoarsen: communication error (3)"); return (1); } if ((MPI_Op_free (&bestoperdat) != MPI_SUCCESS) || (MPI_Type_free (&besttypedat) != MPI_SUCCESS)) { errorPrint ("vdgraphSeparateMlUncoarsen: communication error (4)"); return (1); } if (reduglbtab[5] != 0) { /* If memory error, return */ if (vsndcnttab != NULL) /* Partgsttax will be freed at the above level */ memFree (vsndcnttab); return (1); } if (reduglbtab[0] == 1) { /* If all possible partitions are invalid */ #ifdef SCOTCH_DEBUG_BDGRAPH2 errorPrintW ("vdgraphSeparateMlUncoarsen: no valid partition"); #endif /* SCOTCH_DEBUG_BDGRAPH2 */ return (1); /* All invalid partitions will lead to low method be applied at upper level */ } finevertlocadj = finegrafptr->s.procvrttab[finegrafptr->s.proclocnum] - finegrafptr->s.baseval; fineveloglbtax = (finegrafptr->s.veloloctax != NULL) ? (finegrafptr->s.veloloctax - finevertlocadj) : NULL; /* Array can be indexed with global vertex numbers */ finepartglbtax = finegrafptr->partgsttax - finevertlocadj; finegrafptr->complocload[0] = finegrafptr->complocload[1] = finegrafptr->complocload[2] = finegrafptr->complocsize[0] = finegrafptr->complocsize[1] = finegrafptr->complocsize[2] = 0; #ifdef SCOTCH_DEBUG_VDGRAPH2 memSet (finegrafptr->partgsttax + finegrafptr->s.baseval, 3, finegrafptr->s.vertgstnbr * sizeof (GraphPart)); /* Mark all vertices as unvisited */ #endif /* SCOTCH_DEBUG_VDGRAPH2 */ memSet (vsndcnttab, 0, ((byte *) srcvdattab) - ((byte *) vsndcnttab)); /* TRICK: Assume process has nothing to send in vsndcnttab and ssnddattab */ if (reduglbtab[2] == (Gnum) coargrafptr->s.prockeyval) { /* If we belong to the group of the lead process, we must browse and send local data */ Gnum fineveloval; Gnum finevertsndnbr1; Gnum finevertsndnbr2; Gnum finevertglbmin; Gnum finevertglbmax; Gnum finevertglbnnd; Gnum vsnddatnbr; Gnum vsnddatnum; Gnum vsnddattmp; const GraphPart * restrict const coarpartgsttax = coargrafptr->partgsttax; fineveloval = 1; /* Assume no vertex loads */ finevertglbmin = finegrafptr->s.procvrttab[finegrafptr->s.proclocnum]; finevertglbmax = finegrafptr->s.procvrttab[finegrafptr->s.proclocnum + 1]; finecomplocload0 = finecomplocload2 = finecomplocsize1 = finecomplocsize2 = 0; for (coarvertnum = coargrafptr->s.baseval, vsnddatnbr = 0; coarvertnum < coargrafptr->s.vertlocnnd; coarvertnum ++) { Gnum finevertglbnum; GraphPart coarpartval; coarpartval = coarpartgsttax[coarvertnum]; #ifdef SCOTCH_DEBUG_VDGRAPH2 if ((coarpartval < 0) || (coarpartval > 2)) { errorPrint ("vdgraphSeparateMlUncoarsen: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_VDGRAPH2 */ finevertglbnum = coarmulttax[coarvertnum].vertglbnum[0]; while (1) { /* Loop on both fine vertices of multinode */ Gnum finepartval; finepartval = (Gnum) coarpartval; if ((finevertglbnum >= finevertglbmin) && (finevertglbnum < finevertglbmax)) { /* Vertex is a local one */ #ifdef SCOTCH_DEBUG_VDGRAPH2 if (finepartglbtax[finevertglbnum] != 3) { errorPrint ("vdgraphSeparateMlUncoarsen: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_VDGRAPH2 */ finepartglbtax[finevertglbnum] = coarpartval; finecomplocsize1 += finepartval & 1; /* One extra vertex created in part 1 if (coarpartval == 1) */ if (fineveloglbtax != NULL) fineveloval = fineveloglbtax[finevertglbnum]; if (coarpartval == 2) { finecomplocload2 += fineveloval; finefronloctab[finecomplocsize2 ++] = finevertglbnum - finevertlocadj; } else finecomplocload0 += fineveloval & (finepartval - 1); } else { /* Non local vertex */ vsnddattab[vsnddatnbr ++] = finevertglbnum; /* Store index and part */ vsnddattab[vsnddatnbr ++] = finepartval; } if (finevertglbnum == coarmulttax[coarvertnum].vertglbnum[1]) /* If single-vertex multinode or both vertices processed */ break; finevertglbnum = coarmulttax[coarvertnum].vertglbnum[1]; /* Process second multinode */ } } finegrafptr->complocload[0] = finecomplocload0; /* Account for local vertices already processed */ finegrafptr->complocload[2] = finecomplocload2; finegrafptr->complocsize[1] = finecomplocsize1; finegrafptr->complocsize[2] = finecomplocsize2; intSort2asc1 ((void *) vsnddattab, vsnddatnbr >> 1); /* Sort vertices to send by ascending global numbers */ finevertsndnbr1 = finevertsndnbr2 = 0; for (vsnddatnum = vsnddattmp = 0, procnum = 0, finevertglbnnd = finegrafptr->s.procvrttab[1]; vsnddatnum < vsnddatnbr; ) { Gnum finevertglbnum; Gnum finepartval; finevertglbnum = vsnddattab[vsnddatnum]; finepartval = vsnddattab[vsnddatnum + 1]; if (finevertglbnum >= finevertglbnnd) { Gnum finevertsndnbr; finevertsndnbr = (vsnddatnum - vsnddattmp) >> 1; finevertsndnbr2 >>= 1; vsndcnttab[procnum] = (int) finevertsndnbr; ssnddattab[3 * procnum] = finevertsndnbr - finevertsndnbr1 - finevertsndnbr2; ssnddattab[3 * procnum + 1] = finevertsndnbr1; ssnddattab[3 * procnum + 2] = finevertsndnbr2; vdgraphSeparateMlPack (vsnddattab, vsnddattmp >> 1, ssnddattab + (3 * procnum)); do finevertglbnnd = finegrafptr->s.procvrttab[(++ procnum) + 1]; while (finevertglbnum >= finevertglbnnd); vsnddattmp = vsnddatnum; /* Set startpoint for new neighbor */ finevertsndnbr1 = finevertsndnbr2 = 0; } vsnddatnum += 2; finevertsndnbr1 += finepartval & 1; /* Count number of vertices in part 1 */ finevertsndnbr2 += finepartval & 2; /* Count twice number of vertices in part 2 */ } finevertsndnbr2 >>= 1; /* Complete data for last receiver process */ vsndcnttab[procnum] = (int) ((vsnddatnum - vsnddattmp) >> 1); ssnddattab[3 * procnum] = ((vsnddatnum - vsnddattmp) >> 1) - finevertsndnbr1 - finevertsndnbr2; ssnddattab[3 * procnum + 1] = finevertsndnbr1; ssnddattab[3 * procnum + 2] = finevertsndnbr2; vdgraphSeparateMlPack (vsnddattab, (Gnum) vsnddattmp >> 1, ssnddattab + (3 * procnum)); #ifdef SCOTCH_DEBUG_VDGRAPH2 if ((ssnddattab[3 * finegrafptr->s.proclocnum] != 0) || /* One should never send something to itself */ (ssnddattab[3 * finegrafptr->s.proclocnum + 1] != 0) || (ssnddattab[3 * finegrafptr->s.proclocnum + 2] != 0)) { errorPrint ("vdgraphSeparateMlUncoarsen: internal error (4)"); return (1); } #endif /* SCOTCH_DEBUG_VDGRAPH2 */ } if (MPI_Alltoall (ssnddattab, 3, GNUM_MPI, srcvdattab, 3, GNUM_MPI, finegrafptr->s.proccomm) != MPI_SUCCESS) { /* Exchange sizes */ errorPrint ("vdgraphSeparateMlUncoarsen: communication error (2)"); return (1); } vrcvcnttab = (int *) ssnddattab; /* TRICK: re-use ssnddattab */ vsnddsptab = vrcvcnttab + finegrafptr->s.procglbnbr; vrcvdsptab = vrcvcnttab + finegrafptr->s.procglbnbr * 2; for (procnum = 0, vsnddspnum = vrcvdspnum = 0; procnum < finegrafptr->s.procglbnbr; procnum ++) { /* Compute size of data to exchange */ vrcvcnttab[procnum] = (int) (srcvdattab[3 * procnum] + srcvdattab[3 * procnum + 1] + srcvdattab[3 * procnum + 2]); vrcvdsptab[procnum] = vrcvdspnum; vsnddsptab[procnum] = vsnddspnum; vrcvdspnum += vrcvcnttab[procnum]; vsnddspnum += vsndcnttab[procnum]; } if (MPI_Alltoallv (vsnddattab, vsndcnttab, vsnddsptab, GNUM_MPI, /* Exchange data */ vrcvdattab, vrcvcnttab, vrcvdsptab, GNUM_MPI, finegrafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("vdgraphSeparateMlUncoarsen: communication error (3)"); return (1); } finecomplocload0 = finegrafptr->complocload[0]; finecomplocload2 = finegrafptr->complocload[2]; finecomplocsize1 = finegrafptr->complocsize[1]; finecomplocsize2 = finegrafptr->complocsize[2]; for (procnum = 0, vrcvdatnum = 0; /* Process partition data per process number */ procnum < finegrafptr->s.procglbnbr; procnum ++) { Gnum vrcvdatnnd; vrcvdatnnd = vrcvdatnum + srcvdattab[3 * procnum]; if (fineveloglbtax != NULL) { for ( ; vrcvdatnum < vrcvdatnnd; vrcvdatnum ++) { Gnum finevertglbnum; finevertglbnum = vrcvdattab[vrcvdatnum]; #ifdef SCOTCH_DEBUG_VDGRAPH2 if (finepartglbtax[finevertglbnum] != 3) { errorPrint ("vdgraphSeparateMlUncoarsen: internal error (5)"); return (1); } #endif /* SCOTCH_DEBUG_VDGRAPH2 */ finepartglbtax[finevertglbnum] = 0; finecomplocload0 += fineveloglbtax[finevertglbnum]; } } else { finecomplocload0 += srcvdattab[3 * procnum]; for ( ; vrcvdatnum < vrcvdatnnd; vrcvdatnum ++) { #ifdef SCOTCH_DEBUG_VDGRAPH2 if (finepartglbtax[vrcvdattab[vrcvdatnum]] != 3) { errorPrint ("vdgraphSeparateMlUncoarsen: internal error (6)"); return (1); } #endif /* SCOTCH_DEBUG_VDGRAPH2 */ finepartglbtax[vrcvdattab[vrcvdatnum]] = 0; } } finecomplocsize1 += srcvdattab[3 * procnum + 1]; vrcvdatnnd = vrcvdatnum + srcvdattab[3 * procnum + 1]; for ( ; vrcvdatnum < vrcvdatnnd; vrcvdatnum ++) { #ifdef SCOTCH_DEBUG_VDGRAPH2 if (finepartglbtax[vrcvdattab[vrcvdatnum]] != 3) { errorPrint ("vdgraphSeparateMlUncoarsen: internal error (7)"); return (1); } #endif /* SCOTCH_DEBUG_VDGRAPH2 */ finepartglbtax[vrcvdattab[vrcvdatnum]] = 1; } vrcvdatnnd = vrcvdatnum + srcvdattab[3 * procnum + 2]; if (fineveloglbtax != NULL) { for ( ; vrcvdatnum < vrcvdatnnd; vrcvdatnum ++) { Gnum finevertglbnum; finevertglbnum = vrcvdattab[vrcvdatnum]; #ifdef SCOTCH_DEBUG_VDGRAPH2 if (finepartglbtax[finevertglbnum] != 3) { errorPrint ("vdgraphSeparateMlUncoarsen: internal error (8)"); return (1); } #endif /* SCOTCH_DEBUG_VDGRAPH2 */ finefronloctab[finecomplocsize2 ++] = finevertglbnum - finevertlocadj; finepartglbtax[finevertglbnum] = 2; finecomplocload2 += fineveloglbtax[finevertglbnum]; } } else { finecomplocload2 += srcvdattab[3 * procnum + 2]; for ( ; vrcvdatnum < vrcvdatnnd; vrcvdatnum ++) { Gnum finevertglbnum; finevertglbnum = vrcvdattab[vrcvdatnum]; #ifdef SCOTCH_DEBUG_VDGRAPH2 if (finepartglbtax[finevertglbnum] != 3) { errorPrint ("vdgraphSeparateMlUncoarsen: internal error (9)"); return (1); } #endif /* SCOTCH_DEBUG_VDGRAPH2 */ finefronloctab[finecomplocsize2 ++] = finevertglbnum - finevertlocadj; finepartglbtax[finevertglbnum] = 2; } } } finegrafptr->complocload[0] = finecomplocload0; finegrafptr->complocload[1] = finegrafptr->s.velolocsum - finecomplocload0 - finecomplocload2; finegrafptr->complocload[2] = finecomplocload2; finegrafptr->complocsize[0] = finegrafptr->s.vertlocnbr - finecomplocsize1 - finecomplocsize2; finegrafptr->complocsize[1] = finecomplocsize1; finegrafptr->complocsize[2] = finecomplocsize2; memFree (vsndcnttab); /* Free group leader */ reduloctab[0] = finegrafptr->complocload[0]; reduloctab[1] = finegrafptr->complocload[1]; reduloctab[2] = finegrafptr->complocload[2]; reduloctab[3] = finegrafptr->complocsize[0]; reduloctab[4] = finegrafptr->complocsize[1]; reduloctab[5] = finegrafptr->complocsize[2]; if (MPI_Allreduce (reduloctab, reduglbtab, 6, GNUM_MPI, MPI_SUM, finegrafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("vdgraphSeparateMlUncoarsen: communication error (4)"); return (1); } finegrafptr->compglbload[0] = reduglbtab[0]; finegrafptr->compglbload[1] = reduglbtab[1]; finegrafptr->compglbload[2] = reduglbtab[2]; finegrafptr->compglbsize[0] = reduglbtab[3]; finegrafptr->compglbsize[1] = reduglbtab[4]; finegrafptr->compglbsize[2] = reduglbtab[5]; finegrafptr->compglbloaddlt = reduglbtab[0] - reduglbtab[1]; #ifdef SCOTCH_DEBUG_VDGRAPH2 if (vdgraphCheck (finegrafptr) != 0) { errorPrint ("vdgraphSeparateMlUncoarsen: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_VDGRAPH2 */ return (0); } /* This routine recursively performs the ** separation recursion. ** It returns: ** - 0 : if separator could be computed. ** - !0 : on error. */ static int vdgraphSeparateMl2 ( Vdgraph * restrict const grafptr, /* Vertex-separation graph */ const VdgraphSeparateMlParam * const paraptr) /* Method parameters */ { Vdgraph coargrafdat; DgraphCoarsenMulti * restrict coarmulttax; int o; if (grafptr->s.procglbnbr <= 1) { /* No need to stay parallel */ if (((o = vdgraphSeparateMlUncoarsen (grafptr, NULL, NULL)) == 0) && /* Finalize graph */ ((o = vdgraphSeparateSt (grafptr, paraptr->stratseq)) != 0)) { #ifdef SCOTCH_DEBUG_VDGRAPH2 errorPrintW ("vdgraphSeparateMl2: cannot apply sequential strategy"); #endif /* SCOTCH_DEBUG_VDGRAPH2 */ } return (o); } coarmulttax = NULL; /* Assume multinode array is not allocated */ if (vdgraphSeparateMlCoarsen (grafptr, &coargrafdat, &coarmulttax, paraptr) == 0) { o = (coargrafdat.s.procglbnbr == 0) ? 0 : vdgraphSeparateMl2 (&coargrafdat, paraptr); /* Apply recursion on coarsened graph if it exists */ if ((o == 0) && ((o = vdgraphSeparateMlUncoarsen (grafptr, &coargrafdat, coarmulttax)) == 0) && ((o = vdgraphSeparateSt (grafptr, paraptr->stratasc)) != 0)) { /* Apply ascending strategy if uncoarsening worked */ #ifdef SCOTCH_DEBUG_VDGRAPH2 errorPrintW ("vdgraphSeparateMl2: cannot apply ascending strategy"); #endif /* SCOTCH_DEBUG_VDGRAPH2 */ } if (coargrafdat.fronloctab == grafptr->fronloctab) /* If coarse graph shares fronloctab with fine graph */ coargrafdat.fronloctab = NULL; /* Prevent fronloctab of fine graph from being freed */ vdgraphExit (&coargrafdat); if (coarmulttax != NULL) /* If multinode array has been allocated */ memFree (coarmulttax + grafptr->s.baseval); /* Free array */ if (o == 0) /* If multi-level failed, apply low strategy as fallback */ return (o); } if (((o = vdgraphSeparateMlUncoarsen (grafptr, NULL, NULL)) == 0) && /* Finalize graph */ ((o = vdgraphSeparateSt (grafptr, paraptr->stratlow)) != 0)) { /* Apply low strategy */ #ifdef SCOTCH_DEBUG_VDGRAPH2 errorPrintW ("vdgraphSeparateMl2: cannot apply low strategy"); #endif /* SCOTCH_DEBUG_VDGRAPH2 */ } return (o); } /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the muti-level separation. ** It returns: ** - 0 : if separator could be computed. ** - 1 : on error. */ int vdgraphSeparateMl ( Vdgraph * const grafptr, /*+ Vertex-separation graph +*/ const VdgraphSeparateMlParam * const paraptr) /*+ Method parameters +*/ { Gnum levlnum; /* Save value for graph level */ int o; levlnum = grafptr->levlnum; /* Save graph level */ grafptr->levlnum = 0; /* Initialize coarsening level */ o = vdgraphSeparateMl2 (grafptr, paraptr); /* Perform multi-level separation */ grafptr->levlnum = levlnum; /* Restore graph level */ return (o); } scotch-6.0.4.dfsg/src/libscotch/bdgraph_bipart_ml.h0000644002563400244210000001127012412035044025437 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2009,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bdgraph_bipart_ml.h **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the multi-level bipartition **/ /** routine for distributed graphs. **/ /** **/ /** DATES : # Version 5.1 : from : 30 oct 2007 **/ /** to : 29 oct 2009 **/ /** # Version 6.0 : from : 28 sep 2014 **/ /** to 28 sep 2014 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct BdgraphBipartMlParam_ { INT passnbr; /*+ Number of coarsening passes to go +*/ INT foldmax; /*+ Maximum number of vertices per processor to do folding +*/ int foldval; /*+ Type of folding +*/ INT coarnbr; /*+ Minimum number of vertices +*/ double coarrat; /*+ Coarsening ratio +*/ Strat * stratlow; /*+ Strategy at lowest level +*/ Strat * stratasc; /*+ Strategy at ascending levels +*/ Strat * stratseq; /*+ Strategy when running on a single processor +*/ } BdgraphBipartMlParam; typedef struct BdgraphBipartMlSort_ { Gnum vertnum; /*+ Global vertex index for uncoarsening +*/ Gnum procnum; /*+ Gnum to have same type +*/ } BdgraphBipartMlSort; /* ** The function prototypes. */ #ifndef BDGRAPH_BIPART_ML #define static #endif static int bdgraphBipartMlCoarsen (Bdgraph * const, Bdgraph * const, DgraphCoarsenMulti * restrict * const, const BdgraphBipartMlParam * const); static int bdgraphBipartMlUncoarsen (Bdgraph *, const Bdgraph * const, const DgraphCoarsenMulti * restrict const); static void bdgraphBipartMlOpBest (const Gnum * const, Gnum * const, const int * const, const MPI_Datatype * const); int bdgraphBipartMl (Bdgraph * const, const BdgraphBipartMlParam * const); static int bdgraphBipartMl2 (Bdgraph * const, const BdgraphBipartMlParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/mesh_graph.h0000644002563400244210000000606311631447170024131 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mesh_graph.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the source mesh to source graph **/ /** building routine. **/ /** **/ /** DATES : # Version 4.0 : from : 13 oct 2003 **/ /** to 13 oct 2003 **/ /** **/ /************************************************************/ /* ** The defines. */ /** Prime number for cache-friendly perturbations. **/ #define MESHGRAPHHASHPRIME 37 /* Prime number */ /* ** The type and structure definitions. */ /*+ A table made of such elements is used during graph building to build the edge array of the graph from the one of the mesh. +*/ typedef struct MeshGraphHash_ { Gnum vertnum; /*+ Origin vertex (i.e. pass) number in mesh +*/ Gnum vertend; /*+ End vertex number in mesh +*/ } MeshGraphHash; scotch-6.0.4.dfsg/src/libscotch/kgraph_map_rb_part.h0000644002563400244210000000567012371760345025645 0ustar trophimeutilisateurs du domaine/* Copyright 2008,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph_map_rb_part.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the Dual Recursive Bipartitioning **/ /** mapping algorithm. **/ /** **/ /** DATES : # Version 5.1 : from : 22 sep 2008 **/ /** to 14 apr 2011 **/ /** # Version 6.0 : from : 03 mar 2011 **/ /** to 10 aug 2014 **/ /** **/ /************************************************************/ /* ** The function prototypes. */ #ifndef KGRAPH_MAP_RB_PART #define static #endif int kgraphMapRbPart (const KgraphMapRbData * restrict const, const Graph * restrict const, const Anum, KgraphMapRbVflo * restrict); #undef static scotch-6.0.4.dfsg/src/libscotch/dorder_gather.h0000644002563400244210000001000011631447170024607 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dorder_gather.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the distributed ordering gathering **/ /** function. **/ /** **/ /** DATES : # Version 5.0 : from : 20 jul 2007 **/ /** to : 27 jul 2007 **/ /** # Version 5.1 : from : 04 nov 2010 **/ /** to : 04 nov 2010 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ Tag for MPI communications. +*/ #define DORDERGATHERNODESIZE (sizeof (DorderGatherNode) / sizeof (Gnum)) /* ** The type and structure definitions. */ /*+ This structure holds the tree definition. +*/ typedef struct DorderGatherLeaf_ { Gnum ordelocval; /*+ Starting index of inverse permutation +*/ Gnum vnodlocnbr; /*+ Number of node vertices in fragment +*/ } DorderGatherLeaf; /*+ This structure holds the separator tree structure. Because arrays of this structure is to be sent as a single contiguous array, all its fields must be of the same type. +*/ typedef struct DorderGatherNode_ { Gnum fathnum; /*+ Global number of father node +*/ Gnum typeval; /*+ Node type +*/ Gnum vnodnbr; /*+ Number of node vertices +*/ Gnum cblknum; /*+ Rank of node in father column block array +*/ } DorderGatherNode; /*+ This structure holds the separator tree structure. +*/ typedef struct DorderGatherCblk_ { Gnum cblknbr; /*+ Number of sons +*/ OrderCblk * cblktab; /*+ Pointer to sub-array +*/ } DorderGatherCblk; scotch-6.0.4.dfsg/src/libscotch/wgraph_part_zr.h0000644002563400244210000000023711631447170025042 0ustar trophimeutilisateurs du domaine/* ** The function prototypes. */ #ifndef WGRAPH_PART_ZR #define static #endif int wgraphPartZr (Wgraph * const); #undef static scotch-6.0.4.dfsg/src/libscotch/arch_cmplt.h0000644002563400244210000001420112354531105024114 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : arch_cmplt.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the complete graph target **/ /** architecture functions. **/ /** **/ /** DATES : # Version 0.0 : from : 01 dec 1992 **/ /** to : 24 mar 1993 **/ /** # Version 1.2 : from : 04 feb 1994 **/ /** to : 11 feb 1994 **/ /** # Version 1.3 : from : 20 apr 1994 **/ /** to : 20 apr 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to : 12 nov 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to : 30 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 24 jul 1995 **/ /** # Version 3.1 : from : 11 jun 1996 **/ /** to 11 jun 1996 **/ /** # Version 3.2 : from : 20 sep 1996 **/ /** to 13 may 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 4.0 : from : 09 jan 2004 **/ /** to 09 jan 2004 **/ /** # Version 5.1 : from : 19 jan 2008 **/ /** to 19 jan 2008 **/ /** # Version 6.0 : from : 14 fev 2011 **/ /** to 01 jul 2014 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ #ifndef ARCH_CMPLT_H_STRUCT #define ARCH_CMPLT_H_STRUCT /*+ The complete graph definitions. +*/ typedef struct ArchCmplt_ { Anum numnbr; /*+ Number of vertices +*/ } ArchCmplt; typedef struct ArchCmpltDom_ { Anum nummin; /*+ Minimum vertex number +*/ Anum numnbr; /*+ Number of vertices +*/ } ArchCmpltDom; #endif /* ARCH_CMPLT_H_STRUCT */ /* ** The function prototypes. */ #ifndef ARCH_NOPROTO #ifndef ARCH_CMPLT_H_PROTO #define ARCH_CMPLT_H_PROTO #ifndef ARCH_CMPLT #define static #endif int archCmpltArchLoad (ArchCmplt * restrict const, FILE * restrict const); int archCmpltArchSave (const ArchCmplt * const, FILE * restrict const); #define archCmpltArchFree NULL ArchDomNum archCmpltDomNum (const ArchCmplt * const, const ArchCmpltDom * const); int archCmpltDomTerm (const ArchCmplt * const, ArchCmpltDom * restrict const, const ArchDomNum); Anum archCmpltDomSize (const ArchCmplt * const, const ArchCmpltDom * const); #define archCmpltDomWght archCmpltDomSize Anum archCmpltDomDist (const ArchCmplt * const, const ArchCmpltDom * const, const ArchCmpltDom * const); int archCmpltDomFrst (const ArchCmplt * const, ArchCmpltDom * const); int archCmpltDomLoad (const ArchCmplt * const, ArchCmpltDom * const, FILE * const); int archCmpltDomSave (const ArchCmplt * const, const ArchCmpltDom * const, FILE * const); int archCmpltDomBipart (const ArchCmplt * const, const ArchCmpltDom * const, ArchCmpltDom * restrict const, ArchCmpltDom * restrict const); int archCmpltDomIncl (const ArchCmplt * const, const ArchCmpltDom * const, const ArchCmpltDom * const); #ifdef SCOTCH_PTSCOTCH int archCmpltDomMpiType (const ArchCmplt * const, MPI_Datatype * const); #endif /* SCOTCH_PTSCOTCH */ #undef static #endif /* ARCH_CMPLT_H_PROTO */ #endif /* ARCH_NOPROTO */ scotch-6.0.4.dfsg/src/libscotch/hmesh_order_gr.c0000644002563400244210000000737411631447170025004 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh_order_gr.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module orders a halo mesh by **/ /** turning it into a graph and using a **/ /** graph separation strategy. **/ /** **/ /** DATES : # Version 4.0 : from : 30 nov 2003 **/ /** to 27 jan 2004 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HMESH_ORDER_GR #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "order.h" #include "hgraph.h" #include "hgraph_order_st.h" #include "mesh.h" #include "hmesh.h" #include "hmesh_order_gr.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the ordering. ** It returns: ** - 0 : if the ordering could be computed. ** - !0 : on error. */ int hmeshOrderGr ( const Hmesh * restrict const meshptr, Order * restrict const ordeptr, const Gnum ordenum, OrderCblk * restrict const cblkptr, const HmeshOrderGrParam * const paraptr) { Hgraph grafdat; int o; hgraphInit (&grafdat); if (hmeshHgraph (meshptr, &grafdat) != 0) { /* Build halo graph with improper vnumtab */ errorPrint ("hmeshOrderGr: cannot build halo graph"); return (1); } if ((o = hgraphOrderSt (&grafdat, ordeptr, ordenum, cblkptr, paraptr->stratptr)) != 0) errorPrint ("hmeshOrderGr: cannot order graph"); hgraphFree (&grafdat); /* Free graph structure */ return (o); } scotch-6.0.4.dfsg/src/libscotch/vmesh_separate_gr.h0000644002563400244210000000565711631447170025522 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vmesh_separate_gr.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the the graph separation-based node **/ /** separation method. **/ /** **/ /** DATES : # Version 4.0 : from : 11 oct 2003 **/ /** to 11 oct 2003 **/ /** **/ /************************************************************/ /* ** The defines. */ /* ** The type and structure definitions. */ /*+ Method parameters. +*/ typedef struct VmeshSeparateGrParam_ { Strat * stratptr; /*+ Graph separation strategy +*/ } VmeshSeparateGrParam; /* ** The function prototypes. */ #ifndef VMESH_SEPARATE_GR #define static #endif int vmeshSeparateGr (Vmesh * restrict const, const VmeshSeparateGrParam * restrict const); #undef static scotch-6.0.4.dfsg/src/libscotch/graph_induce.h0000644002563400244210000000670011631447170024442 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : graph_induce.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the source graph sub-graph making **/ /** functions. **/ /** **/ /** DATES : # Version 0.0 : from : 02 dec 1992 **/ /** to 18 may 1993 **/ /** # Version 1.3 : from : 30 apr 1994 **/ /** to 18 may 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to 18 aug 1994 **/ /** # Version 3.0 : from : 07 jul 1995 **/ /** to 28 sep 1995 **/ /** # Version 3.1 : from : 28 nov 1995 **/ /** to 28 nov 1995 **/ /** # Version 3.2 : from : 07 sep 1996 **/ /** to 17 sep 1998 **/ /** # Version 4.0 : from : 28 nov 2001 **/ /** to 28 nov 2001 **/ /** **/ /************************************************************/ /* ** The function prototypes. */ #ifndef GRAPH_INDUCE #define static #endif static int graphInduce2 (const Graph * const, Graph * const, const Gnum, const Gnum, Gnum * const, const Gnum * const); #undef static scotch-6.0.4.dfsg/src/libscotch/kdgraph_map_rb.h0000644002563400244210000000731411631447170024754 0ustar trophimeutilisateurs du domaine/* Copyright 2008,2010,2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kdgraph_map_rb.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Jun-Ho HER (v6.0) **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the Parallel Dual Recursive **/ /** Bipartitioning mapping algorithm. **/ /** **/ /** DATES : # Version 5.1 : from : 16 apr 2008 **/ /** to 14 apr 2011 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ Method parameters. +*/ typedef struct KdgraphMapRbParam_ { Strat * stratsep; /*+ Bipartitioning strategy used +*/ Strat * stratseq; /*+ Sequential mapping strategy +*/ double kbalval; /*+ K-way imbalance ratio +*/ } KdgraphMapRbParam; /* ** The function prototypes. */ #ifndef KDGRAPH_MAP_RB #define static #endif DmappingFrag * kdgraphMapRbAdd2 (const Gnum, const Anum); int kdgraphMapRbAddBoth (const Dgraph * restrict const, Dmapping * restrict const, const ArchDom * restrict const, const GraphPart * restrict const); int kdgraphMapRbAddOne (const Dgraph * restrict const, Dmapping * restrict const, const ArchDom * restrict const); int kdgraphMapRbAddPart (const Dgraph * restrict const, Dmapping * restrict const, const ArchDom * restrict const, const Gnum, const GraphPart * const, const GraphPart); int kdgraphMapRb (Kdgraph * const, Kdmapping * const, const KdgraphMapRbParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/library_graph_map_io.c0000644002563400244210000002535012053747533026165 0ustar trophimeutilisateurs du domaine/* Copyright 2011,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_map_io.c **/ /** **/ /** AUTHOR : Sebastien FOURESTIER (v6.0) **/ /** Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles the API mappings **/ /** of the libSCOTCH library. **/ /** **/ /** DATES : # Version 6.0 : from : 16 apr 2011 **/ /** to 23 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "graph.h" #include "arch.h" #include "library_mapping.h" #include "library_graph_map_io.h" #include "scotch.h" /*************************************/ /* */ /* These routines are the C API for */ /* the API mapping handling */ /* routines. */ /* */ /*************************************/ /*+ This routine loads the contents of the *** given mapping array from the given stream. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphTabLoad ( const SCOTCH_Graph * const actgrafptr, /*+ Graph to map +*/ SCOTCH_Num * const parttab, /*+ Array to load +*/ FILE * const stream) /*+ Input stream +*/ { VertSort * vertsorttab; /* Pointer to graph sorting array */ int vertsortflag; /* Flag set if graph data sorted by label */ VertSort * mappsorttab; /* Pointer to mapping data sorting array */ int mappsortflag; /* Flag set if mapping data sorted by label */ Gnum mappsortval; Gnum mappfileval; Gnum mappfilenbr; /* Number of mapping pairs in file */ Gnum mappfilenum; /* Counter of mapping pairs in file */ Gnum * mappfiletab; /* Pointer to mapping data read from file */ Graph * grafptr; Gnum vertnum; Gnum i, j; grafptr = (Graph *) actgrafptr; memSet (parttab, ~0, grafptr->vertnbr * sizeof (Anum)); /* Pre-initialize the partition array */ if ((fscanf (stream, GNUMSTRING,&mappfileval) != 1) || /* Read number of mapping pairs */ (mappfileval < 1)) { errorPrint ("SCOTCH_graphTabLoad: bad input (1)"); return (1); } mappfilenbr = (Gnum) mappfileval; if (memAllocGroup ((void **) (void *) /* Allocate temporary data */ &mappfiletab, (size_t) (mappfilenbr * sizeof (Gnum)), &mappsorttab, (size_t) (mappfilenbr * sizeof (VertSort)), &vertsorttab, (size_t) (grafptr->vertnbr * sizeof (VertSort)), NULL) == NULL) { errorPrint ("SCOTCH_graphTabLoad: out of memory (1)"); return (1); } mappsortflag = 1; /* Assume mapping data sorted */ for (mappfilenum = 0; mappfilenum < mappfilenbr; mappfilenum ++) { if (fscanf (stream, GNUMSTRING GNUMSTRING, &mappsortval, &mappfileval) != 2) { errorPrint ("SCOTCH_graphTabLoad: bad input (2)"); memFree (mappfiletab); /* Free group leader */ return (1); } mappsorttab[mappfilenum].labl = mappsortval; mappsorttab[mappfilenum].num = mappfilenum; mappfiletab[mappfilenum] = mappfileval; if ((mappfilenum > 0) && /* Check if mapping data sorted */ (mappsorttab[mappfilenum].labl < mappsorttab[mappfilenum - 1].labl)) mappsortflag = 0; /* Mapping data not sorted */ } if (mappsortflag != 1) /* If mapping data not sorted */ intSort2asc1 (mappsorttab, mappfilenbr); /* Sort area by ascending labels */ for (mappfilenum = 1; mappfilenum < mappfilenbr; mappfilenum ++) { /* Check mapping data integrity */ if (mappsorttab[mappfilenum].labl == mappsorttab[mappfilenum - 1].labl) { errorPrint ("SCOTCH_graphTabLoad: duplicate vertex label"); memFree (mappfiletab); /* Free group leader */ return (1); } } if (grafptr->vlbltax != NULL) { /* If graph has vertex labels */ vertsortflag = 1; /* Assume graph data sorted */ for (vertnum = 0; vertnum < grafptr->vertnbr; vertnum ++) { vertsorttab[vertnum].labl = grafptr->vlbltax[vertnum]; vertsorttab[vertnum].num = vertnum; if ((vertnum > 0) && /* Check if graph data sorted */ (vertsorttab[vertnum].labl < vertsorttab[vertnum - 1].labl)) vertsortflag = 0; /* Graph data not sorted */ } if (vertsortflag != 1) /* If graph data not sorted */ intSort2asc1 (vertsorttab, grafptr->vertnbr); /* Sort sort area by ascending labels */ } else { /* Graph does not have vertex labels */ for (vertnum = 0; vertnum < grafptr->vertnbr; vertnum ++) { vertsorttab[vertnum].labl = vertnum + mappsorttab[0].labl; /* Use first index as base value */ vertsorttab[vertnum].num = vertnum; } } for (vertnum = 0, mappfilenum = 0; vertnum < grafptr->vertnbr; vertnum ++) { /* For all vertices in graph */ while ((mappfilenum < mappfilenbr) && (mappsorttab[mappfilenum].labl < vertsorttab[vertnum].labl)) mappfilenum ++; /* Search mapping vertex with same label */ if ((mappfilenum >= mappfilenbr) || (mappsorttab[mappfilenum].labl > vertsorttab[vertnum].labl)) /* If label does not exist */ continue; /* This vertex has no related mapping data */ ((Anum *) parttab)[vertsorttab[vertnum].num] = mappfiletab[mappsorttab[mappfilenum ++].num]; } memFree (mappfiletab); /* Free group leader */ return (0); } /*+ This routine loads the contents of *** the given user mapping from the *** given stream. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphMapLoad ( const SCOTCH_Graph * const actgrafptr, /*+ Graph to map +*/ const SCOTCH_Mapping * const mappptr, /*+ Mapping to save +*/ FILE * const stream) /*+ Output stream +*/ { Graph * grafptr; LibMapping * restrict lmapptr; grafptr = (Graph *) actgrafptr; lmapptr = (LibMapping *) mappptr; #ifdef SCOTCH_DEBUG_GRAPH2 if (grafptr != lmapptr->grafptr) { errorPrint ("SCOTCH_graphMapLoad: mapping structure must derive from graph"); return (1); } #endif /* SCOTCH_DEBUG_GRAPH2 */ if (lmapptr->parttab == NULL) { /* Allocate array if necessary */ if ((lmapptr->parttab = (Gnum *) memAlloc (grafptr->vertnbr * sizeof (Gnum))) == NULL) { errorPrint ("SCOTCH_graphMapLoad: out of memory"); return (1); } lmapptr->flagval |= LIBMAPPINGFREEPART; /* As the array was not allocated by the user, it will be freed */ } return (SCOTCH_graphTabLoad (actgrafptr, (SCOTCH_Num *) lmapptr->parttab, stream)); } /*+ This routine saves the contents of *** the given user mapping to the given *** stream. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphMapSave ( const SCOTCH_Graph * const actgrafptr, /*+ Graph to map +*/ const SCOTCH_Mapping * const mappptr, /*+ Mapping to save +*/ FILE * const stream) /*+ Output stream +*/ { Graph * grafptr; LibMapping * restrict lmapptr; Gnum vertnum; Gnum baseval; grafptr = (Graph *) actgrafptr; lmapptr = (LibMapping *) mappptr; #ifdef SCOTCH_DEBUG_GRAPH2 if (grafptr != lmapptr->grafptr) { errorPrint ("SCOTCH_graphMapSave: mapping structure must derive from graph"); return (1); } #endif /* SCOTCH_DEBUG_GRAPH2 */ const Gnum * restrict vlbltax = grafptr->vlbltax; const Gnum * restrict parttab = lmapptr->parttab; if (fprintf (stream, GNUMSTRING "\n", (Gnum) grafptr->vertnbr) == EOF) { errorPrint ("SCOTCH_graphMapSave: bad output (1)"); return (1); } baseval = grafptr->baseval; for (vertnum = baseval; vertnum < grafptr->vertnnd; vertnum ++) { if (fprintf (stream, GNUMSTRING "\t" GNUMSTRING "\n", (Gnum) ((vlbltax != NULL) ? vlbltax[vertnum] : vertnum), (Gnum) parttab[vertnum - baseval]) == EOF) { errorPrint ("SCOTCH_graphMapSave: bad output (2)"); return (1); } } return (0); } scotch-6.0.4.dfsg/src/libscotch/hmesh_order_gp.h0000644002563400244210000001041411631447170024774 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2009 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh_order_gp.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the Gibbs-Poole-Stockmeyer **/ /** node ordering routine. **/ /** **/ /** DATES : # Version 3.2 : from : 31 oct 1996 **/ /** to : 27 aug 1998 **/ /** # Version 3.3 : from : 02 oct 1998 **/ /** to : 02 oct 1998 **/ /** # Version 4.0 : from : 04 nov 2002 **/ /** to : 01 dec 2003 **/ /** # Version 5.1 : from : 01 oct 2009 **/ /** to : 01 oct 2009 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct HmeshOrderGpParam_ { INT passnbr; /*+ Number of passes to do +*/ } HmeshOrderGpParam; /*+ Complementary vertex structure. +*/ typedef struct HmeshOrderGpVertex_ { Gnum passnum; /*+ Number of pass when vertex selected +*/ Gnum vertdist; /*+ Current distance from diameter vertex +*/ } HmeshOrderGpVertex; /*+ Neighbor queue. +*/ typedef struct HmeshOrderGpQueue_ { Gnum * head; /*+ Head of distance queue +*/ Gnum * tail; /*+ Tail of distance queue +*/ Gnum * qtab; /*+ Array of queue elements +*/ } HmeshOrderGpQueue; /* ** The function prototypes. */ #ifndef HMESH_ORDER_GP #define static #endif int hmeshOrderGp (const Hmesh * const, Order * const, const Gnum, OrderCblk * const, const HmeshOrderGpParam * restrict const); #undef static /* ** The macro definitions. */ #define hmeshOrderGpQueueFlush(queue) ((queue)->head = (queue)->tail = (queue)->qtab) #define hmeshOrderGpQueueEmpty(queue) ((queue)->head <= (queue)->tail) #define hmeshOrderGpQueuePut(queue,vnum) (* ((queue)->head ++) = (vnum)) #define hmeshOrderGpQueueGet(queue) (* ((queue)->tail ++)) scotch-6.0.4.dfsg/src/libscotch/hgraph_order_gp.h0000644002563400244210000001043211631447170025141 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2009,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hgraph_order_gp.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the Gibbs-Poole-Stockmeyer **/ /** node ordering routine. **/ /** **/ /** DATES : # Version 3.2 : from : 31 oct 1996 **/ /** to : 27 aug 1998 **/ /** # Version 3.3 : from : 02 oct 1998 **/ /** to : 02 oct 1998 **/ /** # Version 4.0 : from : 03 feb 2002 **/ /** to : 01 dec 2003 **/ /** # Version 5.1 : from : 01 oct 2009 **/ /** to : 04 nov 2010 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct HgraphOrderGpParam_ { INT passnbr; /*+ Number of passes to do +*/ } HgraphOrderGpParam; /*+ Complementary vertex structure. +*/ typedef struct HgraphOrgerGpVertex_ { Gnum passnum; /*+ Number of pass when vertex selected +*/ Gnum vertdist; /*+ Current distance from diameter vertex +*/ } HgraphOrderGpVertex; /*+ Neighbor queue. +*/ typedef struct HgraphOrgerGpQueue_ { Gnum * head; /*+ Head of distance queue +*/ Gnum * tail; /*+ Tail of distance queue +*/ Gnum * qtab; /*+ Array of queue elements +*/ } HgraphOrgerGpQueue; /* ** The function prototypes. */ #ifndef HGRAPH_ORDER_GP #define static #endif int hgraphOrderGp (const Hgraph * const, Order * const, const Gnum, OrderCblk * const, const HgraphOrderGpParam * restrict const); #undef static /* ** The macro definitions. */ #define hgraphOrderGpQueueFlush(queue) ((queue)->head = (queue)->tail = (queue)->qtab) #define hgraphOrderGpQueueEmpty(queue) ((queue)->head <= (queue)->tail) #define hgraphOrderGpQueuePut(queue,vnum) (* ((queue)->head ++) = (vnum)) #define hgraphOrderGpQueueGet(queue) (* ((queue)->tail ++)) scotch-6.0.4.dfsg/src/libscotch/hgraph_order_hf.h0000644002563400244210000000703011631447171025131 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2009 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hgraph_order_hf.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the block-oriented Halo **/ /** Approximate (Multiple) Minimum Fill **/ /** graph ordering routine. **/ /** **/ /** DATES : # Version 3.4 : from : 15 may 2001 **/ /** to : 15 may 2001 **/ /** # Version 4.0 : from : 10 jan 2003 **/ /** to : 24 jan 2004 **/ /** # Version 5.1 : from : 01 oct 2009 **/ /** to : 01 oct 2009 **/ /** **/ /************************************************************/ /* ** The defines. */ #define HGRAPHORDERHFCOMPRAT 1.2L /*+ Compression ratio +*/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct HgraphOrderHfParam_ { INT colmin; /*+ Minimum number of columns +*/ INT colmax; /*+ Maximum number of columns +*/ double fillrat; /*+ Fill-in ratio +*/ } HgraphOrderHfParam; /* ** The function prototypes. */ #ifndef HGRAPH_ORDER_HF #define static #endif int hgraphOrderHf (const Hgraph * const, Order * const, const Gnum, OrderCblk * const, const HgraphOrderHfParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/dgraph_match.c0000644002563400244210000003235012225624075024427 0ustar trophimeutilisateurs du domaine/* Copyright 2008-2010,2012,2013 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_match.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Cedric CHEVALIER (v5.0) **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the distributed graph matching **/ /** routines. **/ /** **/ /** DATES : # Version 5.1 : from : 01 dec 2008 **/ /** to : 30 jul 2010 **/ /** # Version 6.0 : from : 03 oct 2012 **/ /** to : 10 oct 2013 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DGRAPH_MATCH #include "module.h" #include "common.h" #include "dgraph.h" #include "dgraph_coarsen.h" #include "dgraph_match.h" /*************************************/ /* */ /* These routines handle distributed */ /* source graphs. */ /* */ /*************************************/ /* This routine initializes a distributed graph ** structure. In order to avoid collective ** communication whenever possible, the allocation ** of send and receive index arrays is not performed ** in the routine itself, but rather delegated to ** subsequent routines such as dgraphBuild. ** However, these arrays will not be freed by ** dgraphFree, but by dgraphExit. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int dgraphMatchInit ( DgraphMatchData * restrict const mateptr, const float probval) { Gnum * restrict procvgbtab; int procngbnum; Gnum vertlocnbr; Gnum vertgstnbr; Dgraph * restrict const grafptr = mateptr->c.finegrafptr; const int * restrict const procngbtab = grafptr->procngbtab; const Gnum * restrict const procvrttab = grafptr->procvrttab; vertlocnbr = grafptr->vertlocnbr; vertgstnbr = grafptr->vertgstnbr; if (memAllocGroup ((void **) (void *) &mateptr->procvgbtab, (size_t) ((grafptr->procngbnbr + 1) * sizeof (Gnum)), &mateptr->queuloctab, (size_t) (vertlocnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("dgraphMatchInit: out of memory"); return (1); } mateptr->c.multlocnbr = 0; mateptr->mategsttax = mateptr->c.coargsttax; /* TRICK: re-use array */ mateptr->matelocnbr = 0; /* All vertices need to be processed */ mateptr->queulocnbr = 0; mateptr->probval = (grafptr->procngbnbr == 0) ? 1.0F : probval; memSet (mateptr->mategsttax + grafptr->vertlocnnd, ~0, (vertgstnbr - vertlocnbr) * sizeof (Gnum)); /* No ghost vertices matched to date */ for (procngbnum = 0, procvgbtab = mateptr->procvgbtab; procngbnum < grafptr->procngbnbr; procngbnum ++) procvgbtab[procngbnum] = (Gnum) procvrttab[procngbtab[procngbnum]]; procvgbtab[procngbnum] = (Gnum) procvrttab[grafptr->procglbnbr]; /* Mark end */ return (0); } /* This routine frees the contents of a matching ** data structure. ** It returns: ** - VOID : in all cases. */ void dgraphMatchExit ( DgraphMatchData * restrict const mateptr) { memFree (mateptr->procvgbtab); } /* These routines perform a round of computations ** among enqueued vertices to produce matching requests. ** They return: ** - 0 : on success. ** - !0 : on error. */ #define DGRAPHMATCHSCANNAME dgraphMatchSc /* Scan matching (no edge weights) */ #define DGRAPHMATCHSCANINIT \ probmax = (Gnum) (mateptr->probval * 32768.0); /* Compute integer threshold of random value */ #define DGRAPHMATCHSCANCOUNTDECL ; #define DGRAPHMATCHSCANCOUNTINIT \ probval = intRandVal (32768); /* Get proba for this vertex */ #define DGRAPHMATCHSCANCOUNTSELECT \ edgefrenbr ++; #define DGRAPHMATCHSCANFINDSELECT \ (edgefrenbr -- == 0) #include "dgraph_match_scan.c" #undef DGRAPHMATCHSCANFINDSELECT #undef DGRAPHMATCHSCANCOUNTSELECT #undef DGRAPHMATCHSCANCOUNTINIT #undef DGRAPHMATCHSCANCOUNTDECL #undef DGRAPHMATCHSCANINIT #undef DGRAPHMATCHSCANNAME #define DGRAPHMATCHSCANNAME dgraphMatchHy /* Heavy edge matching */ #define DGRAPHMATCHSCANINIT \ const Gnum * restrict const edloloctax = grafptr->edloloctax; \ if (edloloctax == NULL) { \ dgraphMatchSc (mateptr); \ return; \ } \ probmax = (Gnum) (mateptr->probval * 32768.0); /* Compute integer threshold of random value */ #define DGRAPHMATCHSCANCOUNTDECL \ Gnum edlolocmax; #define DGRAPHMATCHSCANCOUNTINIT \ edlolocmax = 0; \ probval = intRandVal (32768); /* Get proba for this vertex */ #define DGRAPHMATCHSCANCOUNTSELECT \ Gnum edlolocval; \ edlolocval = edloloctax[edgelocnum]; \ if (edlolocval > edlolocmax) { \ edlolocmax = edlolocval; \ edgefrenbr = 1; \ } \ else if (edlolocval == edlolocmax) \ edgefrenbr ++; #define DGRAPHMATCHSCANFINDSELECT \ ((edloloctax[edgelocnum] == edlolocmax) && \ (edgefrenbr -- == 0)) #include "dgraph_match_scan.c" #undef DGRAPHMATCHSCANFINDSELECT #undef DGRAPHMATCHSCANCOUNTSELECT #undef DGRAPHMATCHSCANCOUNTINIT #undef DGRAPHMATCHSCANCOUNTDECL #undef DGRAPHMATCHSCANINIT #undef DGRAPHMATCHSCANNAME #define DGRAPHMATCHSCANNAME dgraphMatchHl /* Heavy edge matching of lightest vertices */ #define DGRAPHMATCHSCANINIT \ const Gnum * restrict const veloloctax = grafptr->veloloctax; \ const Gnum * restrict const edloloctax = grafptr->edloloctax; \ if ((veloloctax == NULL) || (edloloctax == NULL)) { \ dgraphMatchHy (mateptr); \ return; \ } \ probmax = (1 * grafptr->veloglbsum) / (5 * grafptr->vertglbnbr); #define DGRAPHMATCHSCANCOUNTDECL \ Gnum edlolocmax; #define DGRAPHMATCHSCANCOUNTINIT \ edlolocmax = 0; \ probval = veloloctax[vertlocnum]; /* Process vertex if vertex weight smaller than threshold */ #define DGRAPHMATCHSCANCOUNTSELECT \ Gnum edlolocval; \ edlolocval = edloloctax[edgelocnum]; \ if (edlolocval > edlolocmax) { \ edlolocmax = edlolocval; \ edgefrenbr = 1; \ } \ else if (edlolocval == edlolocmax) \ edgefrenbr ++; #define DGRAPHMATCHSCANFINDSELECT \ ((edloloctax[edgelocnum] == edlolocmax) && \ (edgefrenbr -- == 0)) #include "dgraph_match_scan.c" #undef DGRAPHMATCHSCANFINDSELECT #undef DGRAPHMATCHSCANCOUNTSELECT #undef DGRAPHMATCHSCANCOUNTINIT #undef DGRAPHMATCHSCANCOUNTDECL #undef DGRAPHMATCHSCANINIT #undef DGRAPHMATCHSCANNAME #define DGRAPHMATCHSCANNAME dgraphMatchLc /* Local scan matching */ #define DGRAPHMATCHSCANINIT \ probmax = 0; /* Vertices will always be active */ #define DGRAPHMATCHSCANCOUNTDECL ; #define DGRAPHMATCHSCANCOUNTINIT \ probval = 0; /* Vertices will always be active */ #define DGRAPHMATCHSCANCOUNTSELECT \ if (vertgstend < vertlocnnd) \ edgefrenbr ++; \ else \ edgeendnbr --; #define DGRAPHMATCHSCANFINDSELECT \ ((vertgstend < vertlocnnd) && \ (edgefrenbr -- == 0)) #include "dgraph_match_scan.c" #undef DGRAPHMATCHSCANFINDSELECT #undef DGRAPHMATCHSCANCOUNTSELECT #undef DGRAPHMATCHSCANCOUNTINIT #undef DGRAPHMATCHSCANCOUNTDECL #undef DGRAPHMATCHSCANINIT #undef DGRAPHMATCHSCANNAME #define DGRAPHMATCHSCANNAME dgraphMatchLy /* Local heavy edge matching */ #define DGRAPHMATCHSCANINIT \ const Gnum * restrict const edloloctax = mateptr->c.finegrafptr->edloloctax; \ if (edloloctax == NULL) { \ dgraphMatchLc (mateptr); \ return; \ } \ probmax = 0; /* Vertices will always be active */ #define DGRAPHMATCHSCANCOUNTDECL \ Gnum edlolocmax; #define DGRAPHMATCHSCANCOUNTINIT \ edlolocmax = 0; \ probval = 0; /* Vertices will always be active */ #define DGRAPHMATCHSCANCOUNTSELECT \ if (vertgstend < vertlocnnd) { \ Gnum edlolocval; \ edlolocval = edloloctax[edgelocnum]; \ if (edlolocval > edlolocmax) { \ edlolocmax = edlolocval; \ edgefrenbr = 1; \ } \ else if (edlolocval == edlolocmax) \ edgefrenbr ++; \ } \ else \ edgeendnbr --; #define DGRAPHMATCHSCANFINDSELECT \ ((vertgstend < vertlocnnd) && \ (edloloctax[edgelocnum] == edlolocmax) && \ (edgefrenbr -- == 0)) #include "dgraph_match_scan.c" #undef DGRAPHMATCHSCANFINDSELECT #undef DGRAPHMATCHSCANCOUNTSELECT #undef DGRAPHMATCHSCANCOUNTINIT #undef DGRAPHMATCHSCANCOUNTDECL #undef DGRAPHMATCHSCANINIT #undef DGRAPHMATCHSCANNAME scotch-6.0.4.dfsg/src/libscotch/vgraph_separate_fm.c0000644002563400244210000013406112376731337025654 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vgraph_separate_fm.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module separates an active **/ /** graph using a vertex-oriented version **/ /** of our improved Fiduccia-Mattheyses **/ /** heuristics, similar in principle to **/ /** the algorithm of Ashcraft and Liu 1994. **/ /** **/ /** DATES : # Version 3.2 : from : 02 nov 1997 **/ /** to 17 jul 1997 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 31 dec 1998 **/ /** # Version 4.0 : from : 07 jan 2002 **/ /** to 18 aug 2004 **/ /** # Version 5.0 : from : 12 sep 2007 **/ /** to 22 may 2008 **/ /** # Version 5.1 : from : 10 nov 2008 **/ /** to 01 jun 2010 **/ /** # Version 6.0 : from : 31 mar 2014 **/ /** to 01 apr 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VGRAPH_SEPARATE_FM #include "module.h" #include "common.h" #include "gain.h" #include "graph.h" #include "vgraph.h" #include "vgraph_separate_gg.h" #include "vgraph_separate_fm.h" /* ** The static definitions. */ static VgraphSeparateFmVertex vexxdat; /* Dummy structure for computing offsets */ /*********************************/ /* */ /* Gain table handling routines. */ /* */ /*********************************/ /* This routine returns the vertex of best gain ** whose swap will keep the balance correct. ** It returns: ** - !NULL : pointer to the vertex gainlink. ** - NULL : if no more vertices available. */ static GainLink * vgraphSeparateFmTablGet ( GainTabl * const tablptr, /* Gain table */ const Gnum deltcur, /* Current imbalance */ const Gnum deltmax, /* Maximum imbalance */ const int partval) /* Current preferred */ { const VgraphSeparateFmVertex * vexxptr; /* Pointer to vertex of current link */ const GainLink * linkptr; /* Pointer to current gain link */ const GainLink * linkbest; /* Pointer to best link found */ const GainEntr * tablbest; /* Gain table entry of best link */ Gnum gaincur; /* Separator gain of current link */ Gnum gainbest; /* Separator gain of best link */ linkbest = NULL; /* Assume no candidate vertex found yet */ tablbest = tablptr->tend; gainbest = GAINMAX; for (linkptr = gainTablFrst (tablptr); /* Select candidate vertices */ (linkptr != NULL) && (linkptr->tabl <= tablbest); linkptr = gainTablNext (tablptr, linkptr)) { int vertpart; /* Part of current vertex */ vertpart = 0; /* Assume we point to gainlink0 */ vexxptr = (VgraphSeparateFmVertex *) linkptr; /* TRICK: gainlink0 is at beginning */ if (vexxptr->veloval >= 0) { /* If in fact we point to gainlink1 */ vertpart = 1; /* Then point to vertex structure */ vexxptr = (VgraphSeparateFmVertex *) ((byte *) vexxptr - ((byte *) &vexxdat.gainlink1 - (byte *) &vexxdat)); } gaincur = vexxptr->compgain[vertpart]; /* Get separator gain and vertex balance */ if (gaincur == vexxptr->veloval) /* If vertex is isolated separator vertex */ return ((GainLink *) linkptr); /* Select it immediatly */ if (abs (deltcur + (1 - 2 * vertpart) * (gaincur - 2 * vexxptr->veloval)) <= deltmax) { /* If vertex enforces balance */ if ((gaincur < gainbest) || /* And if it gives better gain */ ((gaincur == gainbest) && /* Or is in preferred part */ (partval == vertpart))) { linkbest = linkptr; /* Select it */ tablbest = linkptr->tabl; gainbest = gaincur; } } } return ((GainLink *) linkbest); /* Return best link found */ } /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ int vgraphSeparateFm ( Vgraph * restrict const grafptr, /*+ Active graph +*/ const VgraphSeparateFmParam * const paraptr) /*+ Method parameters +*/ { GainTabl * restrict tablptr; /* Pointer to gain tables */ INT passnbr; /* Maximum number of passes to go */ Gnum movenbr; /* Number of uneffective moves done */ int moveflag; /* Flag set if useful moves made */ Gnum savenbr; /* Position of current move */ VgraphSeparateFmSave * restrict savetab; /* Pointer to move array */ Gnum hashmax; /* Maximum number of elements in table */ Gnum hashsiz; /* Size of hash and save tables */ Gnum hashmsk; /* Mask for access to hash table */ Gnum hashnbr; /* Number of elements in hash table */ VgraphSeparateFmVertex * hashtab; /* Hash vertex table */ GainLink lockdat; /* Double linked list of locked vertices */ VgraphSeparateFmVertex * vexxptr; /* Pointer to current vertex */ VgraphSeparateFmVertex * sepaptr; /* Pointer to current vertex in table */ Gnum fronnum; /* Current index of frontier vertex */ Gnum comploaddlt; /* Current load imbalance */ Gnum comploaddltmat; /* Theoretical maximum unbalance */ Gnum comploaddltmax; /* Largest unbalance allowed */ Gnum comploaddltbst; /* Unbalance of best solution to date */ Gnum compload2; /* Current load of separator */ Gnum compload2bst; /* Separator load of best solution to date */ Gnum mswpnum; /* Number of current move sweep */ Gnum compsize1add; /* Number of vertices to add to counters */ Gnum compsize1sub; const Gnum * restrict const verttax = grafptr->s.verttax; /* Fast accesses */ const Gnum * restrict const vendtax = grafptr->s.vendtax; const Gnum * restrict const velotax = grafptr->s.velotax; const Gnum * restrict const edgetax = grafptr->s.edgetax; GraphPart * restrict const parttax = grafptr->parttax; comploaddltmat = (paraptr->deltrat > 0.0L) ? MAX ((Gnum) ((grafptr->compload[0] + grafptr->compload[1]) * paraptr->deltrat), ((2 * grafptr->s.velosum) / grafptr->s.vertnbr)) : 0; if (grafptr->fronnbr == 0) { /* If no frontier defined */ if (abs (grafptr->comploaddlt) <= comploaddltmat) /* If balance is achieved */ return (0); /* This algorithm is useless */ else { /* Imbalance must be fought */ VgraphSeparateGgParam paradat; paradat.passnbr = 4; /* Use a standard algorithm */ vgraphSeparateGg (grafptr, ¶dat); if (grafptr->fronnbr == 0) /* If new partition has no frontier */ return (0); /* This algorithm is still useless */ } } hashnbr = 16 * (grafptr->fronnbr + paraptr->movenbr + grafptr->s.degrmax) + 1; #ifdef SCOTCH_DEBUG_VGRAPH2 hashnbr /= 8; /* Ensure resizing routine will be called */ #endif /* SCOTCH_DEBUG_VGRAPH2 */ if (hashnbr > grafptr->s.vertnbr) hashnbr = grafptr->s.vertnbr; for (hashsiz = 512; hashsiz < hashnbr; hashsiz <<= 1) ; /* Get upper power of two */ hashmsk = hashsiz - 1; hashmax = hashsiz >> 2; /* Use hash table at 1/4 of its capacity */ if (((tablptr = gainTablInit (GAINMAX, VGRAPHSEPAFMGAINBITS)) == NULL) || /* Use logarithmic array only */ (memAllocGroup ((void **) (void *) &hashtab, (size_t) (hashsiz * sizeof (VgraphSeparateFmVertex)), &savetab, (size_t) (hashsiz * sizeof (VgraphSeparateFmSave)), NULL) == NULL)) { errorPrint ("vgraphSeparateFm: out of memory (1)"); if (tablptr != NULL) gainTablExit (tablptr); return (1); } memSet (hashtab, ~0, hashsiz * sizeof (VgraphSeparateFmVertex)); /* Set all vertex numbers to ~0 */ for (fronnum = 0, hashnbr = grafptr->fronnbr; /* Set initial gains */ fronnum < hashnbr; fronnum ++) { Gnum vertnum; Gnum hashnum; vertnum = grafptr->frontab[fronnum]; #ifdef SCOTCH_DEBUG_VGRAPH2 if (parttax[vertnum] != 2) { errorPrint ("vgraphSeparateFm: vertex not in separator"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ for (hashnum = (vertnum * VGRAPHSEPAFMHASHPRIME) & hashmsk; hashtab[hashnum].vertnum != ~0; hashnum = (hashnum + 1) & hashmsk) ; if (velotax != NULL) { /* If vertex loads present */ Gnum edgenum; Gnum veloval; Gnum compgain0; Gnum compgain01; for (edgenum = verttax[vertnum], compgain0 = compgain01 = 0; edgenum < vendtax[vertnum]; edgenum ++) { Gnum vertend; Gnum partend; Gnum veloend; vertend = edgetax[edgenum]; partend = (Gnum) parttax[vertend]; veloend = velotax[vertend]; compgain0 += (partend & 1) * veloend; compgain01 += (2 - (partend & 2)) * veloend; } veloval = velotax[vertnum]; hashtab[hashnum].veloval = - veloval; /* TRICK: -veloval: stored value is opposite of load */ hashtab[hashnum].compgain[0] = compgain0 - veloval; hashtab[hashnum].compgain[1] = (compgain01 >> 1) - compgain0 - veloval; } else { /* No vertex loads */ Gnum edgenum; Gnum compgain0; Gnum compgain2; for (edgenum = verttax[vertnum], compgain0 = compgain2 = 0; edgenum < vendtax[vertnum]; edgenum ++) { Gnum vertend; Gnum partend; vertend = edgetax[edgenum]; partend = (Gnum) parttax[vertend]; compgain0 += (partend & 1); compgain2 += (partend & 2); } hashtab[hashnum].veloval = -1; /* TRICK: -veloval */ hashtab[hashnum].compgain[0] = compgain0 - 1; hashtab[hashnum].compgain[1] = vendtax[vertnum] - verttax[vertnum] - (compgain2 >> 1) - compgain0 - 1; } hashtab[hashnum].partval = 2; hashtab[hashnum].vertnum = vertnum; gainTablAdd (tablptr, &hashtab[hashnum].gainlink0, hashtab[hashnum].compgain[0]); /* Link both directions of separator vertex */ gainTablAdd (tablptr, &hashtab[hashnum].gainlink1, hashtab[hashnum].compgain[1]); } comploaddltmax = MAX (comploaddltmat, abs (grafptr->comploaddlt)); /* Set current maximum distance */ comploaddltbst = grafptr->comploaddlt; compload2bst = grafptr->compload[2]; #ifdef SCOTCH_DEBUG_VGRAPH3 if (vgraphSeparateFmCheck (grafptr, hashtab, hashmsk, compload2bst, comploaddltbst) != 0) { errorPrint ("vgraphSeparateFm: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH3 */ passnbr = paraptr->passnbr; /* Set remaining number of passes */ savenbr = 0; /* For empty backtrack of first pass */ mswpnum = -1; /* Will be incremented afterwards */ lockdat.next = /* List of locked vertices is empty */ lockdat.prev = &lockdat; do { /* As long as there is improvement */ Gnum comploadabsdltbst; while (savenbr -- > 0) { /* Delete exceeding moves */ Gnum hashnum; int partval; hashnum = savetab[savenbr].hashnum; partval = savetab[savenbr].partval; hashtab[hashnum].partval = partval; /* Restore vertex data */ hashtab[hashnum].compgain[0] = savetab[savenbr].compgain[0]; hashtab[hashnum].compgain[1] = savetab[savenbr].compgain[1]; if (hashtab[hashnum].gainlink0.next >= VGRAPHSEPAFMSTATELINK) { /* If vertex is linked */ gainTablDel (tablptr, &hashtab[hashnum].gainlink0); /* Unlink it */ gainTablDel (tablptr, &hashtab[hashnum].gainlink1); hashtab[hashnum].gainlink0.next = VGRAPHSEPAFMSTATEFREE; /* Set it as free */ } if ((hashtab[hashnum].gainlink0.next == VGRAPHSEPAFMSTATEFREE) && (partval == 2)) { /* If vertex not locked and in separator */ gainTablAdd (tablptr, &hashtab[hashnum].gainlink0, hashtab[hashnum].compgain[0]); /* Re-link it */ gainTablAdd (tablptr, &hashtab[hashnum].gainlink1, hashtab[hashnum].compgain[1]); } } compload2 = compload2bst; /* Restore best separator parameters */ comploaddlt = comploaddltbst; comploadabsdltbst = abs (comploaddltbst); if (comploadabsdltbst > comploaddltmax) /* If the former state had a higher maximum imbalance ratio */ comploaddltmax = comploadabsdltbst; /* Restore this maximum imbalance ratio */ mswpnum ++; /* Forget all recorded moves */ #ifdef SCOTCH_DEBUG_VGRAPH3 if (vgraphSeparateFmCheck (grafptr, hashtab, hashmsk, compload2, comploaddlt) != 0) { errorPrint ("vgraphSeparateFm: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH3 */ while (lockdat.next != &lockdat) { /* For all vertices in locked list */ VgraphSeparateFmVertex * vexxptr; vexxptr = (VgraphSeparateFmVertex *) ((byte *) lockdat.next - ((byte *) &vexxdat.gainlink1 - (byte *) &vexxdat)); lockdat.next = (GainLink *) vexxptr->gainlink1.next; /* Unlink vertex from list */ if (vexxptr->partval == 2) { /* If vertex belongs to separator */ #ifdef SCOTCH_DEBUG_VGRAPH2 if (vexxptr->gainlink0.next != VGRAPHSEPAFMSTATEUSED) { errorPrint ("vgraphSeparateFm: linked non-used vertex"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ gainTablAdd (tablptr, &vexxptr->gainlink0, vexxptr->compgain[0]); /* Link it */ gainTablAdd (tablptr, &vexxptr->gainlink1, vexxptr->compgain[1]); } else /* Vertex does not belong to separator */ vexxptr->gainlink0.next = VGRAPHSEPAFMSTATEFREE; /* Set it as free for this run */ } lockdat.prev = &lockdat; /* Restore backward chaining */ moveflag = 0; /* No moves to date */ movenbr = /* No uneffective moves yet */ savenbr = 0; /* No recorded moves yet */ while ((movenbr < paraptr->movenbr) && /* As long as we can find effective vertices */ ((vexxptr = (VgraphSeparateFmVertex *) vgraphSeparateFmTablGet (tablptr, comploaddlt, comploaddltmax, (passnbr & 1))) != NULL)) { Gnum comploadabsdlt; int partval; /* Part of current vertex */ Gnum vertnum; Gnum edgenum; partval = 0; /* Assume we point to gainlink0 */ if (vexxptr->veloval >= 0) { /* If in fact we point to gainlink1 */ partval = 1; /* Then point to vertex structure */ vexxptr = (VgraphSeparateFmVertex *) ((byte *) vexxptr - ((byte *) &vexxptr->gainlink1 - (byte *) vexxptr)); } #ifdef SCOTCH_DEBUG_VGRAPH2 if (vexxptr->partval != 2) { errorPrint ("vgraphSeparateFm: linked non-separator vertex (1)"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ gainTablDel (tablptr, &vexxptr->gainlink0); /* Remove it from table */ gainTablDel (tablptr, &vexxptr->gainlink1); vexxptr->gainlink0.next = VGRAPHSEPAFMSTATESUCH; /* Mark it as used and avoid chaining */ vexxptr->gainlink1.prev = &lockdat; /* Lock it */ vexxptr->gainlink1.next = lockdat.next; lockdat.next->prev = &vexxptr->gainlink1; lockdat.next = &vexxptr->gainlink1; vertnum = vexxptr->vertnum; /* Get vertex number */ compload2 += vexxptr->compgain[partval]; comploaddlt -= (2 * partval - 1) * (vexxptr->compgain[partval] - 2 * vexxptr->veloval); /* TRICK: -veloval */ if (vexxptr->mswpnum != mswpnum) { /* If vertex data not yet recorded */ vexxptr->mswpnum = mswpnum; savetab[savenbr].hashnum = vexxptr - hashtab; savetab[savenbr].partval = 2; savetab[savenbr].compgain[0] = vexxptr->compgain[0]; savetab[savenbr].compgain[1] = vexxptr->compgain[1]; savenbr ++; /* One more move recorded */ } movenbr ++; /* One more move done */ sepaptr = NULL; /* No separator vertices to relink yet */ for (edgenum = verttax[vertnum]; /* Update neighbors */ edgenum < vendtax[vertnum]; edgenum ++) { Gnum vertend; Gnum hashnum; vertend = edgetax[edgenum]; for (hashnum = (vertend * VGRAPHSEPAFMHASHPRIME) & hashmsk; ; hashnum = (hashnum + 1) & hashmsk) { VgraphSeparateFmVertex * vexxend; /* Pointer to neighbor of current vertex */ vexxend = hashtab + hashnum; /* Point to neighbor */ if (vexxend->vertnum == ~0) { /* If neighbor does not exist yet */ if (parttax[vertend] == partval) /* If no use to create it */ break; /* Skip to next vertex */ #ifdef SCOTCH_DEBUG_VGRAPH2 if (parttax[vertend] != (1 - partval)) { errorPrint ("vgraphSeparateFm: undeclared separator vertex"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ vexxend->vertnum = vertend; /* Set its number (TRICK: mswpnum assumed to be always -1) */ vexxend->partval = 1 - partval; /* Vertex will be in separator */ vexxend->veloval = - ((velotax != NULL) ? velotax[vertend] : 1); vexxend->gainlink0.next = VGRAPHSEPAFMSTATEFREE; /* Vertex will be linked */ hashnbr ++; /* One more vertex in hash table */ #ifdef SCOTCH_DEBUG_VGRAPH2 if (hashnbr > hashmsk) { errorPrint ("vgraphSeparateFm: hash table overflow"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ } if (vexxend->vertnum == vertend) { /* If end vertex has been found */ if (vexxend->partval == 2) { /* If already in separator or chained */ if (vexxend->mswpnum != mswpnum) { /* If vertex data not yet recorded */ vexxend->mswpnum = mswpnum; savetab[savenbr].hashnum = hashnum; savetab[savenbr].partval = 2; savetab[savenbr].compgain[0] = vexxend->compgain[0]; savetab[savenbr].compgain[1] = vexxend->compgain[1]; savenbr ++; /* One more move recorded */ } vexxend->compgain[1 - partval] -= vexxptr->veloval; /* TRICK: -veloval */ if (vexxend->gainlink0.next >= VGRAPHSEPAFMSTATELINK) { /* If vertex is linked */ gainTablDel (tablptr, &vexxend->gainlink0); /* Unlink it temporarily */ gainTablDel (tablptr, &vexxend->gainlink1); /* TRICK: gainlink1.next != NULL */ vexxend->gainlink0.next = VGRAPHSEPAFMSTATEFREE; /* Mark separator vertex as temporarily unlinked */ vexxend->gainlink0.prev = (GainLink *) sepaptr; /* Chain it for relinking */ sepaptr = vexxend; } else if (vexxend->gainlink0.next == VGRAPHSEPAFMSTATEUSED) { vexxend->gainlink0.next = VGRAPHSEPAFMSTATESUCH; /* Mark separator vertex as chained-used */ vexxend->gainlink0.prev = (GainLink *) sepaptr; /* Chain it for relinking */ sepaptr = vexxend; } } else if (vexxend->partval == (1 - partval)) { /* Vertex is in other part */ Gnum edgeend; Gnum compgainp; /* Gain to be added to gain of part partval */ if (vexxend->mswpnum != mswpnum) { /* If vertex data not yet recorded */ vexxend->mswpnum = mswpnum; savetab[savenbr].hashnum = hashnum; savetab[savenbr].partval = 1 - partval; savetab[savenbr].compgain[0] = /* Vertex not in separator so gains are not relevant */ savetab[savenbr].compgain[1] = 0; savenbr ++; /* One more move recorded */ } vexxend->partval = 2; /* Vertex will be in separator */ vexxend->compgain[partval] = vexxend->veloval; /* Moved vertex still in separator */ vexxend->compgain[1 - partval] = vexxend->veloval - vexxptr->veloval; /* TRICK: -veloval */ for (edgeend = verttax[vertend], compgainp = 0; edgeend < vendtax[vertend]; edgeend ++) { Gnum vertent; Gnum hashnum; vertent = edgetax[edgeend]; for (hashnum = (vertent * VGRAPHSEPAFMHASHPRIME) & hashmsk; ; hashnum = (hashnum + 1) & hashmsk) { VgraphSeparateFmVertex * vexxent; /* Pointer to neighbor of neighbor of current vertex */ vexxent = hashtab + hashnum; if (vexxent->vertnum == ~0) { /* If neighbor does not exist */ #ifdef SCOTCH_DEBUG_VGRAPH2 if (parttax[vertent] != (1 - partval)) { errorPrint ("vgraphSeparateFm: broken separator (1)"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ compgainp += (velotax != NULL) ? velotax[vertent] : 1; break; /* Skip to next vertex */ } if (vexxent->vertnum == vertent) { /* If end vertex found */ #ifdef SCOTCH_DEBUG_VGRAPH2 if (vexxent->partval == partval) { errorPrint ("vgraphSeparateFm: broken separator (2)"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ if (vexxent->partval == 2) { /* If vertex is in separator (or is vexxptr) */ if (vexxent->mswpnum != mswpnum) { /* If vertex data not yet recorded */ vexxent->mswpnum = mswpnum; savetab[savenbr].hashnum = hashnum; savetab[savenbr].partval = 2; savetab[savenbr].compgain[0] = vexxent->compgain[0]; savetab[savenbr].compgain[1] = vexxent->compgain[1]; savenbr ++; /* One more move recorded */ } vexxent->compgain[partval] += vexxend->veloval; /* TRICK: -veloval */ if (vexxent->gainlink0.next >= VGRAPHSEPAFMSTATELINK) { /* If not already chained */ gainTablDel (tablptr, &vexxent->gainlink0); /* Unlink it temporarily */ gainTablDel (tablptr, &vexxent->gainlink1); /* TRICK: gainlink1.next != NULL */ vexxent->gainlink0.next = VGRAPHSEPAFMSTATEFREE; /* Mark separator vertex as temporarily unlinked */ vexxent->gainlink0.prev = (GainLink *) sepaptr; /* Chain it */ sepaptr = vexxent; } else if (vexxent->gainlink0.next == VGRAPHSEPAFMSTATEUSED) { vexxent->gainlink0.next = VGRAPHSEPAFMSTATESUCH; /* Mark separator vertex as chained-used */ vexxent->gainlink0.prev = (GainLink *) sepaptr; /* Chain it for relinking */ sepaptr = vexxent; } } else /* Vertex is in same part as vexxend */ compgainp -= vexxent->veloval; /* TRICK: -veloval */ break; } } } vexxend->compgain[partval] += compgainp; if (vexxend->gainlink0.next == VGRAPHSEPAFMSTATEUSED) /* If vertex was already used */ vexxend->gainlink0.next = VGRAPHSEPAFMSTATESUCH; /* Set it as separator-used-chained */ vexxend->gainlink0.prev = (GainLink *) sepaptr; /* Chain it for relinking */ sepaptr = vexxend; } break; /* If in same part, ignore */ } } } vexxptr->gainlink0.next = VGRAPHSEPAFMSTATEUSED; /* Mark it as used and not chained */ vexxptr->partval = partval; /* Set vertex part last */ while (sepaptr != NULL) { /* For all vertices in chain list */ vexxptr = sepaptr; /* Unlink vertex from list */ sepaptr = (VgraphSeparateFmVertex *) vexxptr->gainlink0.prev; #ifdef SCOTCH_DEBUG_VGRAPH2 if (vexxptr->partval != 2) { errorPrint ("vgraphSeparateFm: linked non-separator vertex (2)"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ if (vexxptr->gainlink0.next == VGRAPHSEPAFMSTATEFREE) { /* If vertex is not used */ gainTablAdd (tablptr, &vexxptr->gainlink0, vexxptr->compgain[0]); /* Link it */ gainTablAdd (tablptr, &vexxptr->gainlink1, vexxptr->compgain[1]); } else { vexxptr->gainlink0.next = VGRAPHSEPAFMSTATEUSED; if (vexxptr->compgain[partval] == vexxptr->veloval) { /* If immediate gain */ vexxptr->gainlink1.next->prev = vexxptr->gainlink1.prev; /* Remove vertex from lock list */ vexxptr->gainlink1.prev->next = vexxptr->gainlink1.next; gainTablAdd (tablptr, &vexxptr->gainlink0, vexxptr->compgain[0]); /* Link it */ gainTablAdd (tablptr, &vexxptr->gainlink1, vexxptr->compgain[1]); } } } #ifdef SCOTCH_DEBUG_VGRAPH3 if (vgraphSeparateFmCheck (grafptr, hashtab, hashmsk, compload2, comploaddlt) != 0) { errorPrint ("vgraphSeparateFm: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH3 */ if (hashnbr >= hashmax) { if (vgraphSeparateFmResize (&hashtab, &hashmax, &hashmsk, &savetab, savenbr, tablptr, &lockdat) != 0) { errorPrint ("vgraphSeparateFm: out of memory (2)"); return (1); } } comploadabsdltbst = abs (comploaddltbst); comploadabsdlt = abs (comploaddlt); if ((comploadabsdlt < comploaddltmat) || /* Record move only if it is within bounds */ (comploadabsdltbst > comploaddltmat)) { /* Or if we have always been out of bounds */ if (compload2 < compload2bst) { /* If move improves the cost */ compload2bst = compload2; /* This move was effective */ comploaddltbst = comploaddlt; movenbr = savenbr = 0; moveflag = 1; mswpnum ++; } else if (compload2 == compload2bst) { if (comploadabsdlt < comploadabsdltbst) { comploaddltbst = comploaddlt; /* This move was effective */ movenbr = savenbr = 0; moveflag = 1; mswpnum ++; } else if (comploadabsdlt == comploadabsdltbst) { comploaddltbst = comploaddlt; /* Might be the opposite, so record */ savenbr = 0; /* Forget backtracking */ mswpnum ++; } } } if (comploadabsdlt > comploaddltmax) /* If an isolated vertex unbalanced the partition */ comploaddltmax = comploadabsdlt; /* Record that we degraded maximum load imbalance */ else if (comploaddltmax > comploaddltmat) { /* Else if we must restrict distance bounds */ Gnum comploaddlttmp; comploaddlttmp = comploaddltmax; /* Save old working compdeltmax value */ comploaddltmax = MAX (comploaddltmat, comploadabsdlt); /* Restrict at most to the maximum */ if ((comploadabsdltbst > comploaddltmat) && /* If we have never achieved balance yet */ (comploaddltmax < comploaddlttmp)) { /* And if we have done something useful */ compload2bst = compload2; /* Then record best move done */ comploaddltbst = comploaddlt; movenbr = /* Never set moveflag so as not to create an infinite loop */ savenbr = 0; mswpnum ++; } } } } while ((moveflag != 0) && /* As long as vertices are moved */ (-- passnbr != 0)); /* And we are allowed to loop (TRICK for negative values) */ while (savenbr -- > 0) { /* Delete exceeding moves */ Gnum hashnum; int partval; hashnum = savetab[savenbr].hashnum; partval = savetab[savenbr].partval; hashtab[hashnum].partval = partval; /* Restore vertex part only for update computation */ } compload2 = compload2bst; /* Restore best separator parameters */ comploaddlt = comploaddltbst; compsize1add = /* Variables for superscalar update */ compsize1sub = 0; for (vexxptr = hashtab, fronnum = 0; /* Build new frontier */ vexxptr < hashtab + (hashmax << 2); vexxptr ++) { /* From all vertices in table */ Gnum vertnum; vertnum = vexxptr->vertnum; if (vertnum != ~0) { /* If vertex slot is used */ int partval; /* New part of current vertex */ int partold; /* Old part of current vertex */ partval = vexxptr->partval; partold = parttax[vexxptr->vertnum]; /* Get old part value from array */ if (partval != partold) { /* If vertex part changed */ parttax[vertnum] = partval; /* Set new part value */ compsize1add += (partval & 1); /* Superscalar update */ compsize1sub += (partold & 1); } if (partval == 2) /* If vertex belongs to cut */ grafptr->frontab[fronnum ++] = vertnum; /* Add vertex to frontier */ } } grafptr->compload[0] = ((grafptr->s.velosum - compload2) + comploaddlt) / 2; grafptr->compload[1] = ((grafptr->s.velosum - compload2) - comploaddlt) / 2; grafptr->compload[2] = compload2; grafptr->comploaddlt = comploaddlt; grafptr->compsize[1] = grafptr->compsize[1] + compsize1add - compsize1sub; grafptr->compsize[0] = grafptr->s.vertnbr - grafptr->compsize[1] - fronnum; grafptr->fronnbr = fronnum; #ifdef SCOTCH_DEBUG_VGRAPH2 if (vgraphCheck (grafptr) != 0) { errorPrint ("vgraphSeparateFm: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ memFree (hashtab); /* Free group leader */ gainTablExit (tablptr); return (0); } /* This routine doubles the size all of the arrays ** involved in handling the hash table and hash ** vertex arrays. ** It returns: ** - 0 : if resizing succeeded. ** - !0 : if out of memory. */ static int vgraphSeparateFmResize ( VgraphSeparateFmVertex * restrict * hashtabptr, /*+ Pointer to hash vertex table +*/ Gnum * const hashmaxptr, /*+ Pointer to maximum number of elements in table +*/ Gnum * const hashmskptr, /*+ Pointer to hash table mask +*/ VgraphSeparateFmSave * restrict * savetabptr, /*+ Pointer to move array +*/ const Gnum savenbr, /*+ Current number of active slots in move array +*/ GainTabl * const tablptr, /*+ Gain table +*/ GainLink * const lockptr) { VgraphSeparateFmVertex * restrict hashtab; /* Pointer to new hash table */ VgraphSeparateFmSave * savetab; /* Pointer to new save array */ VgraphSeparateFmSave * saveold; /* Pointer to translated old save array */ Gnum savenum; Gnum hashold; /* Size of old hash table (half of new) */ Gnum hashsiz; Gnum hashmax; Gnum hashmsk; Gnum hashsta; /* Start index of range of hash indices to move */ Gnum hashend; /* End index of range of hash indices to move */ Gnum hashnum; hashmax = *hashmaxptr << 1; /* Compute new sizes */ hashold = *hashmaxptr << 2; hashsiz = *hashmaxptr << 3; hashmsk = hashsiz - 1; if (memReallocGroup ((void *) *hashtabptr, &hashtab, (size_t) (hashsiz * sizeof (VgraphSeparateFmVertex)), &savetab, (size_t) (hashsiz * sizeof (VgraphSeparateFmSave)), NULL) == NULL) { errorPrint ("vgraphSeparateFmResize: out of memory"); return (1); } saveold = (VgraphSeparateFmSave *) ((byte *) hashtab + ((byte *) *savetabptr - (byte *) *hashtabptr)); for (savenum = savenbr - 1; savenum >= 0; savenum --) { /* Move save array, in reverse order */ savetab[savenum].compgain[1] = saveold[savenum].compgain[1]; savetab[savenum].compgain[0] = saveold[savenum].compgain[0]; savetab[savenum].partval = saveold[savenum].partval; savetab[savenum].hashnum = hashtab[saveold[savenum].hashnum].vertnum; /* Temporarily translate from hash index to number */ } *hashtabptr = hashtab; *hashmaxptr = hashmax; *hashmskptr = hashmsk; *savetabptr = savetab; memSet (hashtab + hashold, ~0, hashold * sizeof (VgraphSeparateFmVertex)); gainTablFree (tablptr); /* Reset gain table */ lockptr->next = /* Rebuild lock list */ lockptr->prev = lockptr; for (hashsta = hashold - 1; hashtab[hashsta].vertnum != ~0; hashsta --) ; /* Start index of first segment to reconsider is last empty slot */ hashend = hashold; /* First segment to reconsider ends at the end of the old array */ while (hashend != hashsta) { /* For each of the two segments to consider */ for (hashnum = hashsta; hashnum < hashend; hashnum ++) { /* Re-compute position of vertices in new table */ Gnum vertnum; vertnum = hashtab[hashnum].vertnum; if (vertnum != ~0) { /* If hash slot used */ Gnum hashnew; for (hashnew = (vertnum * VGRAPHSEPAFMHASHPRIME) & hashmsk; ; hashnew = (hashnew + 1) & hashmsk) { if (hashnew == hashnum) /* If hash slot is the same */ break; /* There is nothing to do */ if (hashtab[hashnew].vertnum == ~0) { /* If new slot is empty */ #ifdef SCOTCH_DEBUG_VGRAPH2 if ((hashnew > hashnum) && (hashnew < hashend)) { /* If vertex is not moved either before its old position or after the end of the segment */ errorPrint ("vgraphSeparateFmResize: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ hashtab[hashnew] = hashtab[hashnum]; /* Copy data to new slot */ hashtab[hashnum].mswpnum = ~0; /* TRICK: not tested at creation */ hashtab[hashnum].vertnum = ~0; /* Make old slot empty */ break; } } if (hashtab[hashnew].gainlink0.next >= VGRAPHSEPAFMSTATELINK) { /* If vertex was linked, re-link it */ gainTablAdd (tablptr, &hashtab[hashnew].gainlink0, hashtab[hashnew].compgain[0]); gainTablAdd (tablptr, &hashtab[hashnew].gainlink1, hashtab[hashnew].compgain[1]); } else if (hashtab[hashnew].gainlink0.next == VGRAPHSEPAFMSTATEUSED) { /* Re-lock used vertices */ hashtab[hashnew].gainlink1.prev = lockptr; /* Lock it */ hashtab[hashnew].gainlink1.next = lockptr->next; lockptr->next->prev = &hashtab[hashnew].gainlink1; lockptr->next = &hashtab[hashnew].gainlink1; } } } hashend = hashsta; /* End of second segment to consider is start of first one */ hashsta = 0; /* Start of second segment is beginning of array */ } /* After second segment, hashsta = hashend = 0 and loop stops */ for (savenum = 0; savenum < savenbr; savenum ++) { Gnum vertnum; Gnum hashnum; vertnum = savetab[savenum].hashnum; /* Get vertex number temporarily saved */ for (hashnum = (vertnum * VGRAPHSEPAFMHASHPRIME) & hashmsk; hashtab[hashnum].vertnum != vertnum; hashnum = (hashnum + 1) & hashmsk) { #ifdef SCOTCH_DEBUG_VGRAPH2 if (hashtab[hashnum].vertnum == ~0) { errorPrint ("vgraphSeparateFmResize: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ } savetab[savenum].hashnum = hashnum; /* Set new hash table index */ } return (0); } /* This routine checks the consistency of ** the hash structures. ** It returns: ** - 0 : in case of success. ** - !0 : in case of error. */ #ifdef SCOTCH_DEBUG_VGRAPH3 static int vgraphSeparateFmCheck ( const Vgraph * restrict const grafptr, const VgraphSeparateFmVertex * restrict const hashtab, const Gnum hashmsk, const Gnum compload2, const Gnum comploaddlt) { Gnum hashnum; Gnum comploadtmp[3]; const Gnum * restrict const verttax = grafptr->s.verttax; /* Fast accesses */ const Gnum * restrict const vendtax = grafptr->s.vendtax; const Gnum * restrict const velotax = grafptr->s.velotax; const Gnum * restrict const edgetax = grafptr->s.edgetax; const GraphPart * restrict const parttax = grafptr->parttax; comploadtmp[0] = grafptr->compload[0]; comploadtmp[1] = grafptr->compload[1]; comploadtmp[2] = grafptr->compload[2]; for (hashnum = 0; hashnum <= hashmsk; hashnum ++) { /* For all vertex slots */ Gnum vertnum; int partval; vertnum = hashtab[hashnum].vertnum; if (vertnum == ~0) /* If unallocated slot */ continue; /* Skip to next slot */ if (hashtab[hashnum].veloval != - ((velotax == NULL) ? 1 : velotax[vertnum])) { errorPrint ("vgraphSeparateFmCheck: invalid vertex load (1)"); return (1); } partval = hashtab[hashnum].partval; if ((partval < 0) || (partval > 2)) { errorPrint ("vgraphSeparateFmCheck: invalid part value"); return (1); } if (partval != parttax[vertnum]) { comploadtmp[parttax[vertnum]] += hashtab[hashnum].veloval; /* TRICK: -veloval */ comploadtmp[partval] -= hashtab[hashnum].veloval; } if (partval < 2) { /* If not separator vertex */ if (hashtab[hashnum].gainlink0.next >= VGRAPHSEPAFMSTATELINK) { errorPrint ("vgraphSeparateFmCheck: linked non-separator vertex"); return (1); } } else { /* Separator vertex */ Gnum compload[3]; Gnum edgenum; if (hashtab[hashnum].gainlink0.next == VGRAPHSEPAFMSTATEFREE) { errorPrint ("vgraphSeparateFmCheck: free separator vertex"); return (1); } compload[0] = compload[1] = compload[2] = 0; for (edgenum = verttax[vertnum]; /* For all element neighbors */ edgenum < vendtax[vertnum]; edgenum ++) { Gnum vertend; Gnum hashnum; int partend; Gnum veloend; vertend = edgetax[edgenum]; for (hashnum = (vertend * VGRAPHSEPAFMHASHPRIME) & hashmsk; ; hashnum = (hashnum + 1) & hashmsk) { if (hashtab[hashnum].vertnum == vertend) { /* If end vertex found */ partend = hashtab[hashnum].partval; veloend = hashtab[hashnum].veloval; if (veloend != - ((velotax == NULL) ? 1 : velotax[vertend])) { errorPrint ("vgraphSeparateFmCheck: invalid vertex load (2)"); return (1); } break; } if (hashtab[hashnum].vertnum == ~0) { /* If element not present */ partend = parttax[vertend]; veloend = - ((velotax == NULL) ? 1 : velotax[vertend]); break; } } compload[partend] += veloend; } if ((hashtab[hashnum].compgain[0] != (hashtab[hashnum].veloval - compload[1])) || (hashtab[hashnum].compgain[1] != (hashtab[hashnum].veloval - compload[0]))) { errorPrint ("vgraphSeparateFmCheck: invalid vertex gains"); return (1); } } } if (compload2 != comploadtmp[2]) { errorPrint ("vgraphSeparateFmCheck: invalid frontier load"); return (1); } if (comploaddlt != (comploadtmp[0] - comploadtmp[1])) { errorPrint ("vgraphSeparateFmCheck: invalid separator balance"); return (1); } return (0); } #endif /* SCOTCH_DEBUG_VGRAPH3 */ scotch-6.0.4.dfsg/src/libscotch/common_file.h0000644002563400244210000000547511631447171024312 0ustar trophimeutilisateurs du domaine/* Copyright 2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : common_file.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the file and file name handling **/ /** routines. **/ /** **/ /** DATES : # Version P0.5 : from : 21 may 2007 **/ /** to 21 may 2007 **/ /** **/ /************************************************************/ #define COMMON_FILE_H /* ** The type and structure definitions. */ /* Expansion string size and associated format string. */ #define FILENAMEDISTEXPANDNBR 10 /* TRICK: Change this value in ssprintf() format strings too */ #define FILENAMEDISTEXPANDSTR "%-10d" /* TRICK: Change this value if FILENAMEDISTEXPANDNBR changes */ scotch-6.0.4.dfsg/src/libscotch/common_memory.c0000644002563400244210000004744012035305336024667 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : common_memory.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a parallel direct block solver. **/ /** This module handles errors. **/ /** **/ /** DATES : # Version 0.0 : from : 07 sep 2001 **/ /** to 07 sep 2001 **/ /** # Version 0.1 : from : 14 apr 2001 **/ /** to 24 mar 2003 **/ /** # Version 2.0 : from : 01 jul 2008 **/ /** to : 01 jul 2008 **/ /** # Version 5.1 : from : 22 nov 2008 **/ /** to : 27 jun 2010 **/ /** # Version 6.0 : from : 11 jun 2012 **/ /** to : 10 oct 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define COMMON_MEMORY #ifndef COMMON_NOMODULE #include "module.h" #endif /* COMMON_NOMODULE */ #include "common.h" #define COMMON_MEMORY_SZSP (MAX ((sizeof (size_t)), (sizeof (double)))) /* Space for size, properly aligned */ #ifdef COMMON_MEMORY_CHECK #ifndef COMMON_MEMORY_TRACE #define COMMON_MEMORY_TRACE #endif /* COMMON_MEMORY_TRACE */ #define MEMORY_CHECK_BLOCKS 10000 #define MEMORY_CHECK_BORDER 16384 /* Huge sentinel block */ #define COMMON_MEMORY_SKEW MEMORY_CHECK_BORDER #define COMMON_MEMORY_OVHD (MEMORY_CHECK_BORDER * 2) static int memorycheckenabled = COMMON_MEMORY_CHECK; /* Set to 1 by default */ static char memorycheckmagktab[16] = { 0123, 0156, 0371, 0012, 0345, 0272, 0301, 0234, 0167, 0010, 0127, 0254, 0321, 0012, 0276, 0143 }; static void * memorycheckbloktab[MEMORY_CHECK_BLOCKS] = { NULL }; /* Pre-allocated static array, less easily wrecked by out-of-bound heap memory writes */ static int memorycheckbloknbr = 0; static void * memorycheckwtchval = NULL; /* Block address to watch */ #endif /* COMMON_MEMORY_CHECK */ /*********************************/ /* */ /* The memory checking routines. */ /* */ /*********************************/ #ifdef COMMON_MEMORY_CHECK static void memCheckBlock ( void * blokptr) { char * zoneptr; char * zoneend; int zoneidx; size_t bloksiz; bloksiz = *((size_t *) blokptr); for (zoneptr = (char *) blokptr + COMMON_MEMORY_SZSP, /* Check "before" sentinel */ zoneend = (char *) blokptr + MEMORY_CHECK_BORDER, zoneidx = 0; zoneptr < zoneend; ) { if (*zoneptr ++ != memorycheckmagktab[zoneidx ++ % 16]) { errorPrintW ("memoryCheck: error before block at %p, real size %ld", (char *) blokptr + MEMORY_CHECK_BORDER, (long) bloksiz); break; } } for (zoneptr = (char *) blokptr + MEMORY_CHECK_BORDER + bloksiz, /* Check "after" sentinel */ zoneend = (char *) zoneptr + MEMORY_CHECK_BORDER, zoneidx = 0; zoneptr < zoneend; ) { if (*zoneptr ++ != memorycheckmagktab[zoneidx ++ % 16]) { errorPrintW ("memoryCheck: error after block at %p, real size %ld", (char *) blokptr + MEMORY_CHECK_BORDER, (long) bloksiz); break; } } } int memCheck () { int bloknum; for (bloknum = 0; bloknum < memorycheckbloknbr; bloknum ++) memCheckBlock (memorycheckbloktab[bloknum]); } int memCheckToggle () { return (memorycheckenabled = (memorycheckenabled != 0) ? 0 : 1); } int memCheckExists ( void * blokptr) { void * bloktmp; int bloknum; bloktmp = (void *) ((char *) blokptr - MEMORY_CHECK_BORDER); for (bloknum = 0; bloknum < memorycheckbloknbr; bloknum ++) { if (memorycheckbloktab[bloknum] == bloktmp) return (1); } return (0); } size_t memCheckSize ( void * blokptr) { void * bloktmp; int bloknum; bloktmp = (void *) ((char *) blokptr - MEMORY_CHECK_BORDER); for (bloknum = 0; bloknum < memorycheckbloknbr; bloknum ++) { if (memorycheckbloktab[bloknum] == bloktmp) return (*((size_t *) bloktmp)); } return (-1); } void memCheckWatch ( void * blokptr) { memorycheckwtchval = blokptr; /* Record user location */ } static void memCheckEnlist ( void * blokptr, size_t bloksiz) { char * zoneptr; char * zoneend; int zoneidx; if (memorycheckbloknbr >= MEMORY_CHECK_BLOCKS) { errorPrintW ("memoryEnlist: too many blocks"); return; } if (memorycheckenabled != 0) memCheck (); memorycheckbloktab[memorycheckbloknbr ++] = blokptr; /* Insert block into checked block array */ for (zoneptr = (char *) blokptr + COMMON_MEMORY_SZSP, /* Set "before" sentinel */ zoneend = (char *) blokptr + MEMORY_CHECK_BORDER, zoneidx = 0; zoneptr < zoneend; ) *zoneptr ++ = memorycheckmagktab[zoneidx ++ % 16]; if (memorycheckwtchval == (void *) zoneend) /* Test user location */ errorPrintW ("memoryEnlist: watched block address %p enlisted", zoneend); for (zoneptr = (char *) blokptr + MEMORY_CHECK_BORDER + bloksiz, /* Set "after" sentinel */ zoneend = (char *) zoneptr + MEMORY_CHECK_BORDER, zoneidx = 0; zoneptr < zoneend; ) *zoneptr ++ = memorycheckmagktab[zoneidx ++ % 16]; } static void memCheckDelist ( void * blokptr) { int bloknum; if (memorycheckenabled != 0) memCheck (); for (bloknum = 0; bloknum < memorycheckbloknbr; bloknum ++) { if (memorycheckbloktab[bloknum] == blokptr) break; } if (bloknum == memorycheckbloknbr) { errorPrintW ("memoryDelist: block not found"); return; } if (memorycheckwtchval == (void *) ((char *) blokptr + MEMORY_CHECK_BORDER)) errorPrintW ("memoryDelist: watched block address %p unlisted", blokptr); memorycheckbloktab[bloknum] = memorycheckbloktab[-- memorycheckbloknbr]; /* Remove block from checked block array */ } #endif /* COMMON_MEMORY_CHECK */ /*********************************/ /* */ /* The memory handling routines. */ /* */ /*********************************/ /* This routine keeps track of the amount of ** allocated memory, and keeps track of the ** maximum allowed. */ #ifdef COMMON_MEMORY_TRACE #ifndef COMMON_MEMORY_SKEW #define COMMON_MEMORY_SKEW COMMON_MEMORY_SZSP /* Increase block size just to store size */ #define COMMON_MEMORY_OVHD COMMON_MEMORY_SKEW #endif /* COMMON_MEMORY_SKEW */ static intptr_t memorysiz = 0; /*+ Number of allocated bytes +*/ static intptr_t memorymax = 0; /*+ Maximum amount of allocated data +*/ #if (defined (COMMON_PTHREAD) || defined (SCOTCH_PTHREAD)) static int muteflag = 1; /*+ Flag for mutex initialization +*/ static pthread_mutex_t mutelocdat; /*+ Local mutex for updates +*/ #endif /* (defined (COMMON_PTHREAD) || defined (SCOTCH_PTHREAD)) */ /* This routine allocates and records ** a memory block. ** It returns: ** - NULL : if block could not be allocated. ** - !NULL : location of the allocated block. */ void * memAllocRecord ( size_t newsiz) { byte * newptr; #if (defined (COMMON_PTHREAD) || defined (SCOTCH_PTHREAD)) if (muteflag != 0) { /* Unsafe code with respect to race conditions but should work as first allocs are sequential */ muteflag = 0; pthread_mutex_init (&mutelocdat, NULL); /* Initialize local mutex */ } pthread_mutex_lock (&mutelocdat); /* Lock local mutex */ #endif /* (defined (COMMON_PTHREAD) || defined (SCOTCH_PTHREAD)) */ if ((newptr = malloc (newsiz + COMMON_MEMORY_OVHD)) != NULL) { /* Non-zero size will guarantee non-NULL pointers */ memorysiz += (intptr_t) newsiz; if (memorymax < memorysiz) memorymax = memorysiz; #ifdef COMMON_MEMORY_CHECK memCheckEnlist (newptr, newsiz); #endif /* COMMON_MEMORY_CHECK */ *((size_t *) newptr) = newsiz; /* Record size for freeing */ newptr += COMMON_MEMORY_SKEW; /* Skew pointer while enforcing alignment */ } #if (defined (COMMON_PTHREAD) || defined (SCOTCH_PTHREAD)) pthread_mutex_unlock (&mutelocdat); /* Unlock local mutex */ #endif /* (defined (COMMON_PTHREAD) || defined (SCOTCH_PTHREAD)) */ return ((void *) newptr); /* Return skewed pointer or NULL */ } /* This routine reallocates and records ** a memory block. ** It returns: ** - NULL : if block could not be reallocated. ** - !NULL : location of the reallocated block. */ void * memReallocRecord ( void * oldptr, size_t newsiz) { byte * tmpptr; byte * newptr; size_t oldsiz; tmpptr = ((byte *) oldptr) - COMMON_MEMORY_SKEW; oldsiz = *((size_t *) tmpptr); #if (defined (COMMON_PTHREAD) || defined (SCOTCH_PTHREAD)) pthread_mutex_lock (&mutelocdat); /* Lock local mutex */ #endif /* (defined (COMMON_PTHREAD) || defined (SCOTCH_PTHREAD)) */ #ifdef COMMON_MEMORY_CHECK memCheckDelist (tmpptr); #endif /* COMMON_MEMORY_CHECK */ if ((newptr = realloc (tmpptr, newsiz + COMMON_MEMORY_OVHD)) != NULL) { memorysiz -= (intptr_t) oldsiz; /* Subtract then add unsigned values to avoid handling signs */ memorysiz += (intptr_t) newsiz; if (memorymax < memorysiz) memorymax = memorysiz; #ifdef COMMON_MEMORY_CHECK memCheckEnlist (newptr, newsiz); #endif /* COMMON_MEMORY_CHECK */ *((size_t *) newptr) = newsiz; /* Record size for freeing */ newptr += COMMON_MEMORY_SKEW; /* Skew pointer while enforcing alignment */ } #if (defined (COMMON_PTHREAD) || defined (SCOTCH_PTHREAD)) pthread_mutex_unlock (&mutelocdat); /* Unlock local mutex */ #endif /* (defined (COMMON_PTHREAD) || defined (SCOTCH_PTHREAD)) */ return ((void *) newptr); /* Return skewed pointer or NULL */ } /* This routine frees a recorded ** memory block. ** It returns: ** - void : in all cases. */ void memFreeRecord ( void * oldptr) { byte * tmpptr; size_t oldsiz; tmpptr = ((byte *) oldptr) - COMMON_MEMORY_SKEW; oldsiz = *((size_t *) tmpptr); #if (defined (COMMON_PTHREAD) || defined (SCOTCH_PTHREAD)) pthread_mutex_lock (&mutelocdat); /* Lock local mutex */ #endif /* (defined (COMMON_PTHREAD) || defined (SCOTCH_PTHREAD)) */ #ifdef COMMON_MEMORY_CHECK memCheckDelist (tmpptr); #endif /* COMMON_MEMORY_CHECK */ free (tmpptr); memorysiz -= oldsiz; #if (defined (COMMON_PTHREAD) || defined (SCOTCH_PTHREAD)) pthread_mutex_unlock (&mutelocdat); /* Unlock local mutex */ #endif /* (defined (COMMON_PTHREAD) || defined (SCOTCH_PTHREAD)) */ } /* This routine returns the memory ** footprint of Scotch at the date ** of the call. ** It returns: ** - x : current memory footprint. */ IDX memCur () { intptr_t memotmp; #if (defined (COMMON_PTHREAD) || defined (SCOTCH_PTHREAD)) pthread_mutex_lock (&mutelocdat); /* Lock local mutex */ #endif /* (defined (COMMON_PTHREAD) || defined (SCOTCH_PTHREAD)) */ memotmp = memorysiz; #if (defined (COMMON_PTHREAD) || defined (SCOTCH_PTHREAD)) pthread_mutex_unlock (&mutelocdat); /* Unlock local mutex */ #endif /* (defined (COMMON_PTHREAD) || defined (SCOTCH_PTHREAD)) */ return ((IDX) memotmp); } /* This routine returns the maximum memory ** footprint of Scotch at the date of the ** call. ** It returns: ** - x : current maximum memory footprint. */ IDX memMax () { intptr_t memotmp; #if (defined (COMMON_PTHREAD) || defined (SCOTCH_PTHREAD)) pthread_mutex_lock (&mutelocdat); /* Lock local mutex */ #endif /* (defined (COMMON_PTHREAD) || defined (SCOTCH_PTHREAD)) */ memotmp = memorymax; #if (defined (COMMON_PTHREAD) || defined (SCOTCH_PTHREAD)) pthread_mutex_unlock (&mutelocdat); /* Unlock local mutex */ #endif /* (defined (COMMON_PTHREAD) || defined (SCOTCH_PTHREAD)) */ return ((IDX) memotmp); } #else /* COMMON_MEMORY_TRACE */ /* Dummy routines if not compiled with flag ** COMMON_MEMORY_TRACE set. */ IDX memCur () { return ((IDX) -1); } IDX memMax () { return ((IDX) -1); } #endif /* COMMON_MEMORY_TRACE */ /* This routine allocates a set of arrays in ** a single memAlloc()'ed array, the address ** of which is placed in the first argument. ** Arrays to be allocated are described as ** a duplet of ..., &ptr, size, ..., ** terminated by a NULL pointer. ** It returns: ** - !NULL : pointer to block, all arrays allocated. ** - NULL : no array allocated. */ void * memAllocGroup ( void ** memptr, /*+ Pointer to first argument to allocate +*/ ...) { va_list memlist; /* Argument list of the call */ byte ** memloc; /* Pointer to pointer of current argument */ size_t memoff; /* Offset value of argument */ byte * blkptr; /* Pointer to memory chunk */ memoff = 0; memloc = (byte **) memptr; /* Point to first memory argument */ va_start (memlist, memptr); /* Start argument parsing */ while (memloc != NULL) { /* As long as not NULL pointer */ memoff = (memoff + (sizeof (double) - 1)) & (~ (sizeof (double) - 1)); memoff += va_arg (memlist, size_t); memloc = va_arg (memlist, byte **); } if ((blkptr = (byte *) memAlloc (memoff)) == NULL) { /* If cannot allocate */ *memptr = NULL; /* Set first pointer to NULL */ return (NULL); } memoff = 0; memloc = (byte **) memptr; /* Point to first memory argument */ va_start (memlist, memptr); /* Restart argument parsing */ while (memloc != NULL) { /* As long as not NULL pointer */ memoff = (memoff + (sizeof (double) - 1)) & (~ (sizeof (double) - 1)); /* Pad */ *memloc = blkptr + memoff; /* Set argument address */ memoff += va_arg (memlist, size_t); /* Accumulate padded sizes */ memloc = va_arg (memlist, void *); /* Get next argument pointer */ } return ((void *) blkptr); } /* This routine reallocates a set of arrays in ** a single memRealloc()'ed array passed as ** first argument, and the address of which ** is placed in the second argument. ** Arrays to be allocated are described as ** a duplet of ..., &ptr, size, ..., ** terminated by a NULL pointer. ** It returns: ** - !NULL : pointer to block, all arrays allocated. ** - NULL : no array allocated. */ void * memReallocGroup ( void * oldptr, /*+ Pointer to block to reallocate +*/ ...) { va_list memlist; /* Argument list of the call */ byte ** memloc; /* Pointer to pointer of current argument */ size_t memoff; /* Offset value of argument */ byte * blkptr; /* Pointer to memory chunk */ memoff = 0; va_start (memlist, oldptr); /* Start argument parsing */ while ((memloc = va_arg (memlist, byte **)) != NULL) { /* As long as not NULL pointer */ memoff = (memoff + (sizeof (double) - 1)) & (~ (sizeof (double) - 1)); /* Pad */ memoff += va_arg (memlist, size_t); /* Accumulate padded sizes */ } if ((blkptr = (byte *) memRealloc (oldptr, memoff)) == NULL) /* If cannot allocate block */ return (NULL); memoff = 0; va_start (memlist, oldptr); /* Restart argument parsing */ while ((memloc = va_arg (memlist, byte **)) != NULL) { /* As long as not NULL pointer */ memoff = (memoff + (sizeof (double) - 1)) & (~ (sizeof (double) - 1)); /* Pad */ *memloc = blkptr + memoff; /* Set argument address */ memoff += va_arg (memlist, size_t); /* Accumulate padded sizes */ } return ((void *) blkptr); } /* This routine computes the offsets of arrays ** of given sizes and types with respect to a ** given base address passed as first argument. ** Arrays the offsets of which are to be computed ** are described as a duplet of ..., &ptr, size, ..., ** terminated by a NULL pointer. ** It returns: ** - !NULL : in all cases, pointer to the end of ** the memory area. */ void * memOffset ( void * memptr, /*+ Pointer to base address of memory area +*/ ...) { va_list memlist; /* Argument list of the call */ byte ** memloc; /* Pointer to pointer of current argument */ size_t memoff; /* Offset value of argument */ memoff = 0; va_start (memlist, memptr); /* Start argument parsing */ while ((memloc = va_arg (memlist, byte **)) != NULL) { /* As long as not NULL pointer */ memoff = (memoff + (sizeof (double) - 1)) & (~ (sizeof (double) - 1)); *memloc = (byte *) memptr + memoff; /* Set argument address */ memoff += va_arg (memlist, size_t); /* Accumulate padded sizes */ } return ((void *) ((byte *) memptr + memoff)); } scotch-6.0.4.dfsg/src/libscotch/hdgraph_fold.h0000644002563400244210000000654111631447171024437 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2009 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hdgraph_fold.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the distributed source graph **/ /** folding routines. **/ /** **/ /** # Version 5.0 : from : 06 sep 2006 **/ /** to 06 sep 2006 **/ /** # Version 5.1 : from : 03 jan 2009 **/ /** to 03 jan 2009 **/ /** **/ /************************************************************/ /* ** The defines. */ /* Slot indices used for point-to-point folding communications. First indices are used for communications without further processing. At the moment, there is one anonymous slot: vnumloctab. */ typedef enum HdgraphFoldTag_ { HDGRAPHFOLDTAGENBR = 1, /*+ Edge size message +*/ HDGRAPHFOLDTAGVERT, /*+ vertloctab message +*/ HDGRAPHFOLDTAGVEND, /*+ vendloctab message +*/ HDGRAPHFOLDTAGVELO, /*+ veloloctab message +*/ HDGRAPHFOLDTAGEDGE, /*+ edgeloctab message +*/ HDGRAPHFOLDTAGNBR /*+ Number of tags +*/ } HdgraphFoldTag; scotch-6.0.4.dfsg/src/libscotch/library_arch_build_f.c0000644002563400244210000001045311631447170026132 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_arch_build_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API for **/ /** the target architecture building **/ /** routine of the libSCOTCH library. **/ /** **/ /** DATES : # Version 4.0 : from : 17 mar 2005 **/ /** to 17 mar 2005 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /****************************************/ /* */ /* These routines are the Fortran API */ /* for the target architecture building */ /* routines. */ /* */ /****************************************/ /* ** */ FORTRAN ( \ SCOTCHFSTRATGRAPHBIPART, scotchfstratgraphbipart, ( \ SCOTCH_Strat * const stratptr, \ const char * const string, \ int * const revaptr, \ const int strnbr), \ (stratptr, string, revaptr, strnbr)) { char * restrict strtab; /* Pointer to null-terminated string */ if ((strtab = (char *) memAlloc (strnbr + 1)) == NULL) { /* Allocate temporary space */ errorPrint ("SCOTCHFSTRATGRAPHBIPART: out of memory (1)"); *revaptr = 1; } memCpy (strtab, string, strnbr); /* Copy string contents */ strtab[strnbr] = '\0'; /* Terminate string */ *revaptr = SCOTCH_stratGraphBipart (stratptr, strtab); /* Call original routine */ memFree (strtab); } /* ** */ FORTRAN ( \ SCOTCHFARCHBUILD, scotchfarchbuild, ( \ SCOTCH_Arch * const archptr, \ SCOTCH_Graph * const grafptr, \ const SCOTCH_Num * const listnbr, \ const SCOTCH_Num * const listptr, \ SCOTCH_Strat * const stratptr, \ int * const revaptr), \ (archptr, grafptr, listnbr, listptr, stratptr, revaptr)) { *revaptr = SCOTCH_archBuild (archptr, grafptr, *listnbr, listptr, stratptr); } scotch-6.0.4.dfsg/src/libscotch/kdgraph_map_rb_part.h0000644002563400244210000001211212035267572025777 0ustar trophimeutilisateurs du domaine/* Copyright 2008,2010,2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kdgraph_map_rb_part.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the Parallel Dual Recursive **/ /** Bipartitioning mapping algorithm. **/ /** **/ /** DATES : # Version 5.1 : from : 23 jun 2008 **/ /** to 31 aug 2011 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds folded graph data, whether centralized or distributed +*/ typedef struct KdgraphMapRbPartGraph_ { ArchDom domnorg; /*+ Domain to bipartition at this stage +*/ int procnbr; /*+ Number of processes holding graph +*/ INT levlnum; /*+ Level number +*/ union { Graph cgrfdat; /*+ Centralized graph +*/ Dgraph dgrfdat; /*+ Distributed graph +*/ } data; } KdgraphMapRbPartGraph; /*+ This structure holds the data passed to the subgraph building threads. +*/ typedef struct KdgraphMapRbPartThread_ { Dmapping * mappptr; /*+ Pointer to mapping structure +*/ Dgraph * orggrafptr; /*+ Pointer to original graph +*/ const ArchDom * inddomnptr; /*+ Pointer to subjob domain +*/ Gnum indvertnbr; /*+ Local number of vertices in subgraph +*/ GraphPart indpartval; /*+ Graph part from which to extract subgraph +*/ GraphPart * indparttax; /*+ Based local vertex partition flags in subgraph +*/ KdgraphMapRbPartGraph * fldgrafptr; /*+ Pointer to folded graph union area +*/ int fldpartval; /*+ Part of processor array to which to fold to +*/ int fldprocnbr; /*+ Number of processes in folded communicator +*/ int fldprocnum; /*+ Rank of process in folded communicator, or -1 +*/ MPI_Comm fldproccomm; /*+ Communicator for the folded graph, if any +*/ } KdgraphMapRbPartThread; /*+ This structure holds the data passed to each bipartitioning job. +*/ typedef struct KdgraphMapRbPartData_ { Dmapping * mappptr; const KdgraphMapRbParam * paraptr; double comploadrat; /*+ Ideal vertex load per target load +*/ double comploadmin; /*+ Minimum vertex load per target load +*/ double comploadmax; /*+ Maximum vertex load per target load +*/ } KdgraphMapRbPartData; /* ** The function prototypes. */ #ifndef KDGRAPH_MAP_RB #define static #endif int kdgraphMapRbPart (Kdgraph * const, Kdmapping * const, const KdgraphMapRbParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/library_dgraph_map_view_f.c0000644002563400244210000001052012055777141027172 0ustar trophimeutilisateurs du domaine/* Copyright 2008,2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_map_view_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the Fortran API for the **/ /** distributed mapping handling routines **/ /** of the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.1 : from : 27 jul 2008 **/ /** to 27 mar 2010 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "ptscotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the mapping routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFDGRAPHMAPVIEW, scotchfdgraphmapview, ( \ SCOTCH_Dgraph * const grafptr, \ const SCOTCH_Dmapping * const mapptr, \ int * const fileptr, \ int * const revaptr), \ (grafptr, mapptr, fileptr, revaptr)) { FILE * stream; /* Stream to build from handle */ int filenum; /* Duplicated handle */ int o; if (*fileptr == -1) /* If process does not want to open a stream */ stream = NULL; else { if ((filenum = dup (*fileptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFDGRAPHMAPVIEW: cannot duplicate handle"); *revaptr = 1; /* Indicate error */ return; } if ((stream = fdopen (filenum, "w")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFDGRAPHMAPVIEW: cannot open output stream"); close (filenum); *revaptr = 1; return; } } o = SCOTCH_dgraphMapView (grafptr, mapptr, stream); if (stream != NULL) /* If process has an open stream */ fclose (stream); /* This closes filenum too */ *revaptr = o; } scotch-6.0.4.dfsg/src/libscotch/library_dgraph_io_load.c0000644002563400244210000001024712055776526026500 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_io_load.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the distri- **/ /** buted source graph loading routine of **/ /** the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 13 may 2007 **/ /** to 13 may 2007 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "graph.h" #include "dgraph.h" #include "ptscotch.h" /****************************************/ /* */ /* These routines are the C API for the */ /* distributed graph handling routines. */ /* */ /****************************************/ /*+ This routine loads the given opaque graph *** structure with the data of the given stream. *** The base value allows the user to set the *** graph base to 0 or 1, or to the base value *** of the stream if the base value is equal *** to -1. On input, vertex loads are discarded if *** flagval is 1, edge loads are discarded if flagval *** is 2, and both if flagval is set to 3. *** It returns: *** - 0 : if the loading succeeded. *** - !0 : on error. +*/ int SCOTCH_dgraphLoad ( SCOTCH_Dgraph * const grafptr, FILE * const stream, const SCOTCH_Num baseval, const SCOTCH_Num flagval) { GraphFlag srcgrafflag; /* Graph flags */ if ((baseval < -1) || (baseval > 1)) { errorPrint ("SCOTCH_dgraphLoad: invalid base parameter"); return (1); } if ((flagval < 0) || (flagval > 3)) { errorPrint ("SCOTCH_dgraphLoad: invalid flag parameter"); return (1); } srcgrafflag = (((flagval & 1) != 0) ? GRAPHIONOLOADVERT : 0) + (((flagval & 2) != 0) ? GRAPHIONOLOADEDGE : 0); return (dgraphLoad ((Dgraph * const) grafptr, stream, (Gnum) baseval, srcgrafflag)); } scotch-6.0.4.dfsg/src/libscotch/graph_io_scot.c0000644002563400244210000003043011631447171024623 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : graph_io_scot.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the I/O routines **/ /** for handling the Scotch graph format. **/ /** **/ /** DATES : # Version 3.2 : from : 06 nov 1997 **/ /** to 26 may 1998 **/ /** # Version 3.3 : from : 13 dec 1998 **/ /** to 21 dec 1998 **/ /** # Version 4.0 : from : 18 dec 2001 **/ /** to 22 dec 2005 **/ /** # Version 5.0 : from : 13 sep 2006 **/ /** to 27 feb 2008 **/ /** # Version 5.1 : from : 11 aug 2010 **/ /** to 11 aug 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GRAPH_IO_SCOT #include "module.h" #include "common.h" #include "geom.h" #include "graph.h" #include "graph_io_scot.h" /* This routine loads the geometrical graph ** in the Scotch graph format, and allocates ** the proper structures. ** - 0 : on success. ** - !0 : on error. */ int graphGeomLoadScot ( Graph * restrict const grafptr, /* Graph to load */ Geom * restrict const geomptr, /* Geometry to load */ FILE * const filesrcptr, /* Topological data */ FILE * const filegeoptr, /* No use */ const char * const dataptr) /* No use */ { void * coorfileptr; /* Temporary pointer to comply with C99 rules */ double * restrict coorfiletab; /* Pointer to geometric data read from file */ GraphGeomScotSort * restrict coorsorttab; /* Pointer to geometric data sorting array */ int coorsortflag; /* Flag set if geometric data sorted by label */ Gnum coornbr; /* Number of geometric coordinates in file */ Gnum coornum; /* Number of current coordinate */ GraphGeomScotSort * restrict vertsorttab; /* Pointer to graph sorting array */ int vertsortflag; /* Flag set if graph data sorted by label */ Gnum vertnum; /* Current graph vertex */ Gnum dimnnbr; /* Dimension of geometry file */ int o; if (filesrcptr != NULL) { if (graphLoad (grafptr, filesrcptr, -1, 0) != 0) return (1); } if (filegeoptr == NULL) return (0); if ((intLoad (filegeoptr, &dimnnbr) != 1) || /* Read type and number of geometry items */ (intLoad (filegeoptr, &coornbr) != 1) || (dimnnbr < 1) || (dimnnbr > 3)) { errorPrint ("graphGeomLoadScot: bad input (1)"); return (1); } if ((filesrcptr != NULL) && (grafptr->vertnbr != coornbr)) { errorPrint ("graphGeomLoadScot: inconsistent number of vertices"); return (1); } if (grafptr->vertnbr == 0) return (0); if ((geomptr->geomtab == NULL) && /* Allocate geometry if necessary */ ((geomptr->geomtab = (double *) memAlloc (grafptr->vertnbr * dimnnbr * sizeof (double))) == NULL)) { errorPrint ("graphGeomLoadScot: out of memory (1)"); return (1); } if (memAllocGroup ((void **) &coorfileptr, (size_t) (coornbr * dimnnbr * sizeof (double)), &coorsorttab, (size_t) (coornbr * sizeof (GraphGeomScotSort)), &vertsorttab, (size_t) (grafptr->vertnbr * sizeof (GraphGeomScotSort)), NULL) == NULL) { errorPrint ("graphGeomLoadScot: out of memory (2)"); return (1); } coorfiletab = coorfileptr; o = 0; coorsortflag = 1; /* Assume geometry data sorted */ for (coornum = 0; (o == 0) && (coornum < coornbr); coornum ++) { Gnum vlblnum; o = 1 - intLoad (filegeoptr, &vlblnum); coorsorttab[coornum].labl = vlblnum; coorsorttab[coornum].num = coornum; if ((coornum > 0) && /* Check if geometry data sorted */ (coorsorttab[coornum].labl < coorsorttab[coornum - 1].labl)) coorsortflag = 0; /* Geometry data not sorted */ o |= 1 - fscanf (filegeoptr, "%lf", /* Read X coordinate */ &coorfiletab[coornum * dimnnbr]); if (dimnnbr > 1) { o |= 1 - fscanf (filegeoptr, "%lf", /* Read Y coordinate */ &coorfiletab[(coornum * dimnnbr) + 1]); if (dimnnbr > 2) o |= 1 - fscanf (filegeoptr, "%lf", /* Read Z coordinate */ &coorfiletab[(coornum * dimnnbr) + 2]); } } if (o != 0) { errorPrint ("graphGeomLoadScot: bad input (2)"); memFree (coorfiletab); /* Free group leader */ return (1); } if (coorsortflag != 1) /* If geometry data not sorted */ intSort2asc1 (coorsorttab, coornbr); /* Sort sort area by ascending labels */ for (coornum = 1; coornum < coornbr; coornum ++) { /* Check geometric data integrity */ if (coorsorttab[coornum].labl == coorsorttab[coornum - 1].labl) { errorPrint ("graphGeomLoadScot: duplicate vertex label"); memFree (coorfiletab); /* Free group leader */ return (1); } } if (grafptr->vlbltax != NULL) { /* If graph has vertex labels */ vertsortflag = 1; /* Assume graph data sorted */ for (vertnum = 0; vertnum < grafptr->vertnbr; vertnum ++) { vertsorttab[vertnum].labl = grafptr->vlbltax[vertnum + grafptr->baseval]; vertsorttab[vertnum].num = vertnum; if ((vertnum > 0) && /* Check if graph data sorted */ (vertsorttab[vertnum].labl < vertsorttab[vertnum - 1].labl)) vertsortflag = 0; /* Graph data not sorted */ } if (vertsortflag != 1) /* If graph data not sorted */ intSort2asc1 (vertsorttab, grafptr->vertnbr); /* Sort sort area by ascending labels */ } else { /* Graph does not have vertex labels */ for (vertnum = 0; vertnum < grafptr->vertnbr; vertnum ++) vertsorttab[vertnum].labl = vertsorttab[vertnum].num = vertnum; } for (coornum = vertnum = 0; vertnum < grafptr->vertnbr; vertnum ++) { /* For all vertices in graph */ while ((coornum < coornbr) && (coorsorttab[coornum].labl < vertsorttab[vertnum].labl)) coornum ++; /* Search geometry vertex with same label */ if ((coornum >= coornbr) || (coorsorttab[coornum].labl > vertsorttab[vertnum].labl)) { /* If label does not exist */ errorPrint ("graphGeomLoadScot: vertex geometry data not found (%d)", vertsorttab[vertnum].labl); memFree (coorfiletab); /* Free group leader */ return (1); } memCpy (&geomptr->geomtab[vertsorttab[vertnum].num * dimnnbr], &coorfiletab[coorsorttab[coornum ++].num * dimnnbr], dimnnbr * sizeof (double)); } memFree (coorfiletab); /* Free group leader */ return (0); } /* This routine saves the source process graph ** in the Scotch source and geometry formats. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int graphGeomSaveScot ( const Graph * restrict const grafptr, /* Graph to save */ const Geom * restrict const geomptr, /* Geometry to save */ FILE * const filesrcptr, /* Topological data */ FILE * const filegeoptr, /* No use */ const char * const dataptr) /* No use */ { Gnum vertnum; int dimnnbr; int o; if (filesrcptr != NULL) { if (graphSave (grafptr, filesrcptr) != 0) /* Save graph structural data */ return (1); } dimnnbr = geomptr->dimnnbr; o = 0; if (geomptr->geomtab != NULL) { /* If geometrical data present */ o = (fprintf (filegeoptr, GNUMSTRING "\n" GNUMSTRING "\n", /* Output file header */ (Gnum) geomptr->dimnnbr, (Gnum) grafptr->vertnbr) == EOF); switch (dimnnbr) { /* Output geometry data */ case 1 : for (vertnum = grafptr->baseval; (o == 0) && (vertnum < grafptr->vertnnd); vertnum ++) o |= (fprintf (filegeoptr, GNUMSTRING "\t%lf\n", (Gnum) ((grafptr->vlbltax != NULL) ? grafptr->vlbltax[vertnum] : vertnum), (double) geomptr->geomtab[(vertnum - grafptr->baseval) * dimnnbr]) == EOF); break; case 2 : for (vertnum = grafptr->baseval; (o == 0) && (vertnum < grafptr->vertnnd); vertnum ++) o |= (fprintf (filegeoptr, GNUMSTRING "\t%lf\t%lf\n", (Gnum) ((grafptr->vlbltax != NULL) ? grafptr->vlbltax[vertnum] : vertnum), (double) geomptr->geomtab[(vertnum - grafptr->baseval) * dimnnbr], (double) geomptr->geomtab[(vertnum - grafptr->baseval) * dimnnbr + 1]) == EOF); break; case 3 : for (vertnum = grafptr->baseval; (o == 0) && (vertnum < grafptr->vertnnd); vertnum ++) o |= (fprintf (filegeoptr, GNUMSTRING "\t%lf\t%lf\t%lf\n", (Gnum) ((grafptr->vlbltax != NULL) ? grafptr->vlbltax[vertnum] : vertnum), (double) geomptr->geomtab[(vertnum - grafptr->baseval) * dimnnbr], (double) geomptr->geomtab[(vertnum - grafptr->baseval) * dimnnbr + 1], (double) geomptr->geomtab[(vertnum - grafptr->baseval) * dimnnbr + 2]) == EOF); break; #ifdef SCOTCH_DEBUG_GRAPH2 default : errorPrint ("graphGeomSaveScot: invalid geometry type"); return (1); #endif /* SCOTCH_DEBUG_GRAPH2 */ } if (o != 0) { errorPrint ("graphGeomSaveScot: bad output"); } } return (o); } scotch-6.0.4.dfsg/src/libscotch/vdgraph_separate_df.h0000644002563400244210000000701111631447170025776 0ustar trophimeutilisateurs du domaine/* Copyright 2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vdgraph_separate_df.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the parallel diffusion separation **/ /** routine for distributed graphs. **/ /** **/ /** DATES : # Version 5.1 : from : 05 nov 2007 **/ /** to : 07 nov 2007 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ Small non-zero float value. +*/ #define VDGRAPHSEPARATEDFEPSILON (1.0F / (float) (GNUMMAX)) /*+ Sign masking operator. +*/ #define VDGRAPHSEPARATEDFGNUMSGNMSK(i) ((Gnum) 0 - (((Gunum) (i)) >> (sizeof (Gnum) * 8 - 1))) /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct VdgraphSeparateDfParam_ { INT partval; /*+ Part to aggregate to separator +*/ INT passnbr; /*+ Number of passes to do +*/ double cdifval; /*+ Coefficient of diffused load +*/ double cremval; /*+ Coefficient of remaining load +*/ double deltval; /*+ Maximum imbalance ratio +*/ } VdgraphSeparateDfParam; /* ** The function prototypes. */ #ifndef VDGRAPH_SEPARATE_DF #define static #endif int vdgraphSeparateDf (Vdgraph * const, const VdgraphSeparateDfParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/bgraph_bipart_gg.c0000644002563400244210000004113712376612664025302 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2009,2011,2013,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bgraph_bipart_gg.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Luca SCARANO (v3.1) **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module computes a bipartition of **/ /** a bipartition graph by multiple runs of **/ /** the greedy graph growing algorithm. **/ /** **/ /** DATES : # Version 3.1 : from : 07 jan 1996 **/ /** to 07 jun 1996 **/ /** # Version 3.2 : from : 20 sep 1996 **/ /** to 13 sep 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 3.4 : from : 01 jun 2001 **/ /** to 01 jun 2001 **/ /** # Version 4.0 : from : 09 jan 2004 **/ /** to 01 sep 2004 **/ /** # Version 5.0 : from : 02 jan 2007 **/ /** to 04 feb 2007 **/ /** # Version 5.1 : from : 21 nov 2007 **/ /** to 22 feb 2011 **/ /** # Version 6.0 : from : 23 fev 2011 **/ /** to 08 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define BGRAPH_BIPART_GG #define SCOTCH_TABLE_GAIN #include "module.h" #include "common.h" #include "gain.h" #include "fibo.h" #include "graph.h" #include "arch.h" #include "bgraph.h" #include "bgraph_bipart_gg.h" /* ** The static variables. */ static const Gnum bgraphbipartggloadone = 1; static const Gnum bgraphbipartggloadzero = 0; /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ #ifndef SCOTCH_TABLE_GAIN /* bgraphBipartFmCmpFunc(a,b) must return a negative ** number if a is "better" than b. The smaller, the ** better. */ static int bgraphBipartGgCmpFunc ( const FiboNode * const data0ptr, /* TRICK: BgraphBipartFmLink is FIRST in BgraphBipartFmVertex */ const FiboNode * const data1ptr) { const BgraphBipartGgVertex * const node0ptr = (BgraphBipartGgVertex *) data0ptr; const BgraphBipartGgVertex * const node1ptr = (BgraphBipartGgVertex *) data1ptr; if (node0ptr->commgain < node1ptr->commgain) return (-1); if (node0ptr->commgain > node1ptr->commgain) return (1); return (0); } #endif /* SCOTCH_TABLE_GAIN */ /* This routine performs the bipartitioning. ** It returns: ** - 0 : if bipartitioning could be computed. ** - 1 : on error. */ int bgraphBipartGg ( Bgraph * restrict const grafptr, /*+ Active graph +*/ const BgraphBipartGgParam * const paraptr) /*+ Method parameters +*/ { BgraphBipartGgTabl tabldat; /* Gain table */ BgraphBipartGgVertex * vexxtax; /* Extended vertex array [norestrict] */ BgraphBipartGgVertex * vexxptr; /* Pointer to current vertex to swap */ const Gnum * restrict veexptr; /* Pointer to external gain of current vertex */ Gnum * restrict permtab; /* Permutation table for finding new roots */ Gnum permnum; /* Current permutation index */ const Gnum * restrict velobax; /* Data for handling of optional arrays */ Gnum velomsk; const byte * restrict veexbab; /* Un-based array for external gains */ int veexsiz; const Gnum * edlobax; /* Pointer to array or dummy value [norestrict] */ Gnum edlomsk; byte * restrict flagtax; Gnum vertnum; Gnum fronnum; Gnum compsize1; Gnum commgainextn; unsigned int passnum; Anum domndist; Anum domndist2; /* Two times domndist */ const Gnum * restrict const verttax = grafptr->s.verttax; /* Fast accesses */ const Gnum * restrict const vendtax = grafptr->s.vendtax; const Gnum * restrict const edgetax = grafptr->s.edgetax; const Gnum * const edlotax = grafptr->s.edlotax; /* [norestrict] */ const Gnum * restrict const veextax = grafptr->veextax; if ((bgraphBipartGgTablInit (&tabldat) != 0) || ((vexxtax = (BgraphBipartGgVertex *) memAlloc (grafptr->s.vertnbr * sizeof (BgraphBipartGgVertex))) == NULL)) { errorPrint ("bgraphBipartGg: out of memory (1)"); bgraphBipartGgTablExit (&tabldat); return (1); } vexxtax -= grafptr->s.baseval; /* Base access to vexxtax */ permtab = NULL; /* Do not allocate permutation array yet */ domndist = grafptr->domndist; domndist2 = grafptr->domndist * 2; if (edlotax == NULL) { /* If graph has no edge weights */ Gnum vertnum; for (vertnum = grafptr->s.baseval; vertnum < grafptr->s.vertnnd; vertnum ++) { Gnum commload; commload = (vendtax[vertnum] - verttax[vertnum]) * domndist; vexxtax[vertnum].commgain0 = (veextax == NULL) ? commload : commload + veextax[vertnum]; } edlobax = &bgraphbipartggloadone; edlomsk = 0; } else { /* Graph has edge weights */ Gnum vertnum; for (vertnum = grafptr->s.baseval; vertnum < grafptr->s.vertnnd; vertnum ++) { Gnum commload; Gnum edgenum; for (edgenum = verttax[vertnum], commload = 0; edgenum < vendtax[vertnum]; edgenum ++) commload += edlotax[edgenum]; commload *= domndist; vexxtax[vertnum].commgain0 = (veextax == NULL) ? commload : commload + veextax[vertnum]; } edlobax = edlotax; edlomsk = ~((Gnum) 0); /* TRICK: assume that ~0 is -1 */ } if (grafptr->s.velotax == NULL) { /* Set accesses to optional arrays */ velobax = &bgraphbipartggloadone; /* In case vertices not weighted (least often) */ velomsk = 0; } else { velobax = grafptr->s.velotax; velomsk = ~((Gnum) 0); } if (veextax == NULL) { veexbab = (byte *) &bgraphbipartggloadzero; veexsiz = 0; } else { veexbab = (byte *) (veextax + grafptr->s.baseval); veexsiz = sizeof (Gnum); } for (passnum = 0; passnum < paraptr->passnbr; passnum ++) { /* For all passes */ Gnum vertnum; Gnum commload; Gnum compload0dlt; for (vertnum = grafptr->s.baseval; vertnum < grafptr->s.vertnnd; vertnum ++) { /* Reset extended vertex array */ bgraphBipartGgSetFree (&vexxtax[vertnum]); vexxtax[vertnum].commgain = vexxtax[vertnum].commgain0; } bgraphBipartGgTablFree (&tabldat); /* Reset gain table */ permnum = 0; /* No permutation built yet */ compload0dlt = grafptr->s.velosum - grafptr->compload0avg; /* Reset bipartition parameters */ commload = grafptr->commloadextn0; vexxptr = vexxtax + (grafptr->s.baseval + intRandVal (grafptr->s.vertnbr)); /* Randomly select first root vertex */ do { /* For all root vertices, till balance */ #ifdef SCOTCH_TABLE_GAIN vexxptr->gainlink.next = /* TRICK: allow deletion of root vertex */ vexxptr->gainlink.prev = (GainLink *) vexxptr; #ifdef SCOTCH_DEBUG_BGRAPH2 vexxptr->gainlink.tabl = NULL; #endif /* SCOTCH_DEBUG_BGRAPH2 */ #endif /* SCOTCH_TABLE_GAIN */ do { /* As long as vertices can be retrieved */ const Gnum * restrict edgeptr; /* Pointer to current end vertex index */ const Gnum * restrict edgetnd; /* Pointer to end of edge array */ const Gnum * restrict edloptr; /* Pointer to current edge load */ Gnum vertnum; /* Number of current vertex */ Gnum veloval; /* Load of selected vertex */ #ifndef SCOTCH_TABLE_GAIN if (bgraphBipartGgIsTabl (vexxptr)) #endif /* SCOTCH_TABLE_GAIN */ bgraphBipartGgTablDel (&tabldat, vexxptr); /* Remove vertex from table */ vertnum = vexxptr - vexxtax; /* Get number of selected vertex */ veloval = velobax[vertnum & velomsk]; if (abs (compload0dlt - veloval) >= abs (compload0dlt)) { /* If swapping would cause imbalance */ #ifndef SCOTCH_TABLE_GAIN bgraphBipartGgNext (vexxptr) = BGRAPHBIPARTGGSTATELINK; /* Vertex belongs to frontier of part 0 */ #endif /* SCOTCH_TABLE_GAIN */ permnum = grafptr->s.vertnbr; /* Terminate swapping process */ vexxptr = NULL; break; } bgraphBipartGgSetUsed (vexxptr); /* Mark it as swapped */ compload0dlt -= veloval; /* Update partition parameters */ commload += vexxptr->commgain; for (edgeptr = edgetax + verttax[vertnum], /* (Re-)link neighbors */ edgetnd = edgetax + vendtax[vertnum], edloptr = edlobax + (verttax[vertnum] & edlomsk); edgeptr < edgetnd; edgeptr ++, edloptr -= edlomsk) { /* TRICK: assume that ~0 is -1 */ BgraphBipartGgVertex * vexxend; /* Pointer to end vertex of current edge */ vexxend = vexxtax + *edgeptr; /* Point to end vertex */ if (! bgraphBipartGgIsUsed (vexxend)) { /* If vertex needs to be updated */ vexxend->commgain -= *edloptr * domndist2; /* Adjust gain value */ if (bgraphBipartGgIsTabl (vexxend)) /* If vertex is linked */ bgraphBipartGgTablDel (&tabldat, vexxend); /* Remove it from table */ bgraphBipartGgTablAdd (&tabldat, vexxend); /* (Re-)link vertex in table */ } } } while ((vexxptr = (BgraphBipartGgVertex *) bgraphBipartGgTablFrst (&tabldat)) != NULL); if (permnum == 0) { /* If permutation has not been built yet */ if (permtab == NULL) { /* If permutation array not allocated yet */ if ((permtab = (Gnum *) memAlloc (grafptr->s.vertnbr * sizeof (Gnum))) == NULL) { errorPrint ("bgraphBipartGg: out of memory (3)"); memFree (vexxtax + grafptr->s.baseval); bgraphBipartGgTablExit (&tabldat); return (1); } intAscn (permtab, grafptr->s.vertnbr, grafptr->s.baseval); /* Initialize based permutation array */ } intPerm (permtab, grafptr->s.vertnbr); /* Build random permutation */ } for ( ; permnum < grafptr->s.vertnbr; permnum ++) { /* Find next root vertex */ if (bgraphBipartGgIsFree (&vexxtax[permtab[permnum]])) { vexxptr = vexxtax + permtab[permnum ++]; break; } } } while (vexxptr != NULL); if ((passnum == 0) || /* If first try */ ( (grafptr->commload > commload) || /* Or if better solution reached */ ((grafptr->commload == commload) && (abs (grafptr->compload0dlt) > abs (compload0dlt))))) { Gnum vertnum; grafptr->compload0dlt = compload0dlt; /* Set graph parameters */ grafptr->commload = commload; for (vertnum = grafptr->s.baseval; vertnum < grafptr->s.vertnnd; vertnum ++) /* Copy bipartition state with flag 2 for tabled vertices */ grafptr->parttax[vertnum] = (bgraphBipartGgIsTabl (&vexxtax[vertnum])) ? 2 : (GraphPart) ((intptr_t) bgraphBipartGgNext (&vexxtax[vertnum])); } } flagtax = (byte *) (vexxtax + grafptr->s.baseval) - grafptr->s.baseval; /* Re-use extended vertex array for flag array */ memSet (flagtax + grafptr->s.baseval, ~0, grafptr->s.vertnbr * sizeof (byte)); for (vertnum = grafptr->s.baseval, veexptr = (Gnum *) veexbab, fronnum = 0, compsize1 = 0, commgainextn = grafptr->commgainextn0; vertnum < grafptr->s.vertnnd; vertnum ++, veexptr = (Gnum *) ((byte *) veexptr + veexsiz)) { int partval; partval = grafptr->parttax[vertnum]; if (partval > 1) { /* If vertex belongs to frontier of part 0 */ Gnum edgenum; Gnum frontmp; /* Temporary count value for frontier */ grafptr->frontab[fronnum ++] = vertnum; /* Then it belongs to the frontier */ grafptr->parttax[vertnum] = 0; /* And it belongs to part 0 */ for (edgenum = verttax[vertnum], frontmp = 1; edgenum < vendtax[vertnum]; edgenum ++) { Gnum vertend; vertend = edgetax[edgenum]; if (grafptr->parttax[vertend] == 1) { /* If vertex belongs to other part */ frontmp = 0; /* Then first frontier vertex was useful */ if (flagtax[vertend] != 0) { /* If vertex has not yet been flagged */ grafptr->frontab[fronnum ++] = vertend; /* Then add it to the frontier */ flagtax[vertend] = 0; /* Flag it */ } } } fronnum -= frontmp; /* Remove vertex from frontier if it was useless */ } partval &= 1; compsize1 += partval; commgainextn -= partval * 2 * *veexptr; } grafptr->fronnbr = fronnum; grafptr->compload0 = grafptr->compload0avg + grafptr->compload0dlt; grafptr->compsize0 = grafptr->s.vertnbr - compsize1; grafptr->commgainextn = commgainextn; grafptr->bbalval = (double) ((grafptr->compload0dlt < 0) ? (- grafptr->compload0dlt) : grafptr->compload0dlt) / (double) grafptr->compload0avg; if (permtab != NULL) /* Free work arrays */ memFree (permtab); memFree (vexxtax + grafptr->s.baseval); bgraphBipartGgTablExit (&tabldat); #ifdef SCOTCH_DEBUG_BGRAPH2 if (bgraphCheck (grafptr) != 0) { errorPrint ("bgraphBipartGg: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/library_dgraph_stat.c0000644002563400244210000003005212473175025026030 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_stat.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the source **/ /** graph handling routines of the **/ /** libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 23 jun 2007 **/ /** to 03 apr 2008 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 oct 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "dgraph.h" #include "library_dgraph_stat.h" #include "ptscotch.h" /* ** The static variables. */ static int dgraphstatblentab[2] = { 7, 3 }; static MPI_Datatype dgraphstattypetab[2] = { GNUM_MPI, MPI_DOUBLE }; /************************************/ /* */ /* These routines are the C API for */ /* the graph handling routines. */ /* */ /************************************/ /* This routine is the reduction-loc operator which ** returns in inout[2] the rank of the process which ** holds the best partition. ** It returns: ** - void : in all cases. */ static void dgraphStatReduceAll ( const DgraphStatData * const in, /* First operand */ DgraphStatData * const inout, /* Second and output operand */ const int * const len, /* Number of instances; should be 1, not used */ const MPI_Datatype * const typedat) /* MPI datatype; not used */ { if (inout->velomin > in->velomin) inout->velomin = in->velomin; if (inout->velomax < in->velomax) inout->velomax = in->velomax; if (inout->degrmin > in->degrmin) inout->degrmin = in->degrmin; if (inout->degrmax < in->degrmax) inout->degrmax = in->degrmax; if (inout->edlomin > in->edlomin) inout->edlomin = in->edlomin; if (inout->edlomax < in->edlomax) inout->edlomax = in->edlomax; inout->edlosum += in->edlosum; inout->velodlt += in->velodlt; inout->degrdlt += in->degrdlt; inout->edlodlt += in->edlodlt; } /*+ This routine computes statistics *** on the given distributed graph. *** It returns: *** - VOID : in all cases. +*/ int SCOTCH_dgraphStat ( const SCOTCH_Dgraph * const grafptr, SCOTCH_Num * const velominptr, SCOTCH_Num * const velomaxptr, SCOTCH_Num * const velosumptr, double * veloavgptr, double * velodltptr, SCOTCH_Num * const degrminptr, SCOTCH_Num * const degrmaxptr, double * degravgptr, double * degrdltptr, SCOTCH_Num * const edlominptr, SCOTCH_Num * const edlomaxptr, SCOTCH_Num * const edlosumptr, double * edloavgptr, double * edlodltptr) { const Dgraph * srcgrafptr; DgraphStatData srcgstadat; DgraphStatData srclstadat; MPI_Datatype srctypedat; MPI_Aint srcdisptab[2]; MPI_Op srcoperdat; Gnum vertlocnum; double veloglbavg; double velolocdlt; Gnum degrlocmin; Gnum degrlocmax; double degrglbavg; double degrlocdlt; Gnum edloglbsum; double edloglbavg; double edlolocdlt; int o; srcgrafptr = (Dgraph *) grafptr; velolocdlt = 0.0L; if (srcgrafptr->vertglbnbr > 0) { if (srcgrafptr->veloloctax != NULL) { /* If graph has vertex loads */ const Gnum * restrict veloloctax; Gnum velolocmin; Gnum velolocmax; veloloctax = srcgrafptr->veloloctax; velolocmin = GNUMMAX; velolocmax = 0; veloglbavg = (double) srcgrafptr->veloglbsum / (double) srcgrafptr->vertglbnbr; for (vertlocnum = srcgrafptr->baseval; vertlocnum < srcgrafptr->vertlocnnd; vertlocnum ++) { Gnum velolocval; velolocval = veloloctax[vertlocnum]; if (velolocval < velolocmin) velolocmin = velolocval; if (velolocval > velolocmax) velolocmax = velolocval; velolocdlt += fabs ((double) velolocval - veloglbavg); } srclstadat.velomin = velolocmin; srclstadat.velomax = velolocmax; } else { srclstadat.velomin = srclstadat.velomax = 1; veloglbavg = 1.0L; } } else { srclstadat.velomin = srclstadat.velomax = 0; veloglbavg = 0.0L; } srclstadat.velodlt = velolocdlt; degrlocmax = 0; degrlocdlt = 0.0L; if (srcgrafptr->vertglbnbr > 0) { degrlocmin = GNUMMAX; degrglbavg = (double) srcgrafptr->edgeglbnbr / (double) srcgrafptr->vertglbnbr; for (vertlocnum = srcgrafptr->baseval; vertlocnum < srcgrafptr->vertlocnnd; vertlocnum ++) { Gnum degrlocval; degrlocval = srcgrafptr->vendloctax[vertlocnum] - srcgrafptr->vertloctax[vertlocnum]; /* Get vertex degree */ if (degrlocval < degrlocmin) degrlocmin = degrlocval; if (degrlocval > degrlocmax) degrlocmax = degrlocval; degrlocdlt += fabs ((double) degrlocval - degrglbavg); } } else { degrlocmin = 0; degrglbavg = 0.0L; } srclstadat.degrmin = degrlocmin; srclstadat.degrmax = degrlocmax; srclstadat.degrdlt = degrlocdlt; edlolocdlt = 0.0L; if (srcgrafptr->edgeglbnbr > 0) { if (srcgrafptr->edloloctax != NULL) { /* If graph has edge loads */ Gnum edlolocmin; Gnum edlolocmax; Gnum edlolocsum; edlolocmin = GNUMMAX; edlolocmax = 0; edlolocsum = 0; for (vertlocnum = srcgrafptr->baseval; vertlocnum < srcgrafptr->vertlocnnd; vertlocnum ++) { Gnum edgelocnum; for (edgelocnum = srcgrafptr->vertloctax[vertlocnum]; edgelocnum < srcgrafptr->vendloctax[vertlocnum]; edgelocnum ++) { Gnum edlolocval; edlolocval = srcgrafptr->edloloctax[edgelocnum]; edlolocsum += edlolocval; if (edlolocval < edlolocmin) /* Account for edge load */ edlolocmin = edlolocval; if (edlolocval > edlolocmax) edlolocmax = edlolocval; } } if (MPI_Allreduce (&edlolocsum, &edloglbsum, 1, GNUM_MPI, MPI_SUM, srcgrafptr->proccomm) != MPI_SUCCESS) { errorPrint ("SCOTCH_dgraphStat: communication error (1)"); return (1); } edloglbavg = (double) edloglbsum / (double) (2 * srcgrafptr->edgeglbnbr); for (vertlocnum = srcgrafptr->baseval; vertlocnum < srcgrafptr->vertlocnnd; vertlocnum ++) { Gnum edgelocnum; for (edgelocnum = srcgrafptr->vertloctax[vertlocnum]; edgelocnum < srcgrafptr->vendloctax[vertlocnum]; edgelocnum ++) edlolocdlt += fabs ((double) srcgrafptr->edloloctax[edgelocnum] - edloglbavg); } } else { srclstadat.edlomin = srclstadat.edlomax = 1; edloglbsum = srcgrafptr->edgeglbnbr / 2; edloglbavg = 1.0L; } } else { srclstadat.edlomin = srclstadat.edlomax = 0; edloglbsum = 0; edloglbavg = 0.0L; } srclstadat.edlodlt = edlolocdlt; #if ((defined COMMON_MPI_VERSION) && (COMMON_MPI_VERSION <= 100)) MPI_Address (&srclstadat.velomin, &srcdisptab[0]); MPI_Address (&srclstadat.velodlt, &srcdisptab[1]); #else /* ((defined COMMON_MPI_VERSION) && (COMMON_MPI_VERSION <= 100)) */ MPI_Get_address (&srclstadat.velomin, &srcdisptab[0]); MPI_Get_address (&srclstadat.velodlt, &srcdisptab[1]); #endif /* ((defined COMMON_MPI_VERSION) && (COMMON_MPI_VERSION <= 100)) */ srcdisptab[1] -= srcdisptab[0]; srcdisptab[0] -= srcdisptab[0]; o = 1; /* Assume something will go wrong */ #if ((defined COMMON_MPI_VERSION) && (COMMON_MPI_VERSION <= 100)) if ((MPI_Type_struct (2, dgraphstatblentab, srcdisptab, dgraphstattypetab, &srctypedat) == MPI_SUCCESS) && #else /* ((defined COMMON_MPI_VERSION) && (COMMON_MPI_VERSION <= 100)) */ if ((MPI_Type_create_struct (2, dgraphstatblentab, srcdisptab, dgraphstattypetab, &srctypedat) == MPI_SUCCESS) && #endif /* ((defined COMMON_MPI_VERSION) && (COMMON_MPI_VERSION <= 100)) */ (MPI_Type_commit (&srctypedat) == MPI_SUCCESS)) { if (MPI_Op_create ((MPI_User_function *) dgraphStatReduceAll, 0, &srcoperdat) == MPI_SUCCESS) { if (MPI_Allreduce (&srclstadat, &srcgstadat, 1, srctypedat, srcoperdat, srcgrafptr->proccomm) == MPI_SUCCESS) o = 0; MPI_Op_free (&srcoperdat); } MPI_Type_free (&srctypedat); } if (o != 0) { errorPrint ("SCOTCH_dgraphStat: communication error (2)"); return (1); } if (velominptr != NULL) *velominptr = (SCOTCH_Num) srcgstadat.velomin; if (velomaxptr != NULL) *velomaxptr = (SCOTCH_Num) srcgstadat.velomax; if (velosumptr != NULL) *velosumptr = (SCOTCH_Num) srcgrafptr->veloglbsum; if (veloavgptr != NULL) *veloavgptr = (double) veloglbavg; if (velodltptr != NULL) *velodltptr = srcgstadat.velodlt / (double) srcgrafptr->vertglbnbr; if (degrminptr != NULL) *degrminptr = (SCOTCH_Num) srcgstadat.degrmin; if (degrmaxptr != NULL) *degrmaxptr = (SCOTCH_Num) srcgstadat.degrmax; if (degravgptr != NULL) *degravgptr = (double) degrglbavg; if (degrdltptr != NULL) *degrdltptr = srcgstadat.degrdlt / (double) srcgrafptr->vertglbnbr; if (edlominptr != NULL) *edlominptr = (SCOTCH_Num) srcgstadat.edlomin; if (edlomaxptr != NULL) *edlomaxptr = (SCOTCH_Num) srcgstadat.edlomax; if (edlosumptr != NULL) *edlosumptr = (SCOTCH_Num) edloglbsum; if (edloavgptr != NULL) *edloavgptr = (double) edloglbavg; if (edlodltptr != NULL) *edlodltptr = srcgstadat.edlodlt / (double) srcgrafptr->edgeglbnbr; return (0); } scotch-6.0.4.dfsg/src/libscotch/mapping.c0000644002563400244210000004544012405757470023453 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007-2009,2011,2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mapping.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module handles (partial) mappings. **/ /** **/ /** DATES : # Version 0.0 : from : 31 mar 1993 **/ /** to 31 mar 1993 **/ /** # Version 1.0 : from : 04 oct 1993 **/ /** to 06 oct 1993 **/ /** # Version 1.1 : from : 15 oct 1993 **/ /** to 15 oct 1993 **/ /** # Version 1.3 : from : 09 apr 1994 **/ /** to 11 may 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to 17 nov 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to 18 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 19 oct 1995 **/ /** # Version 3.1 : from : 30 oct 1995 **/ /** to 14 jun 1996 **/ /** # Version 3.2 : from : 23 aug 1996 **/ /** to 07 sep 1998 **/ /** # Version 3.3 : from : 19 oct 1998 **/ /** to 30 mar 1999 **/ /** # Version 3.4 : from : 11 sep 2001 **/ /** to 08 nov 2001 **/ /** # Version 4.0 : from : 16 jan 2004 **/ /** to 05 jan 2005 **/ /** # Version 5.1 : from : 25 jun 2008 **/ /** to 28 apr 2009 **/ /** # Version 6.0 : from : 04 mar 2011 **/ /** to 16 sep 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define MAPPING #include "module.h" #include "common.h" #include "graph.h" #include "arch.h" #include "mapping.h" /***********************************/ /* */ /* These routines handle mappings. */ /* */ /***********************************/ /* This routine builds a mapping. ** It returns: ** - 0 : if mapping successfully initialized. ** - !0 : on error. */ void mapInit ( Mapping * restrict const mappptr, /*+ Mapping structure +*/ const Graph * restrict const grafptr, /*+ Graph data +*/ const Arch * restrict const archptr, /*+ Architecture data +*/ const ArchDom * restrict const domnptr) /*+ Target architecture initial domain +*/ { Anum domnmax; /* Maximum number of domains */ domnmax = (archVar (archptr) != 0) /* If target architecture is variable-sized */ ? MIN (1023, grafptr->vertnbr) /* Pre-set number of domains */ : archDomSize (archptr, domnptr); /* Else get architecture size */ domnmax ++; /* +1 for empty domain in mapBuild()/mapLoad() */ mapInit2 (mappptr, grafptr, archptr, domnptr, domnmax, 0); } void mapInit2 ( Mapping * restrict const mappptr, /*+ Mapping structure +*/ const Graph * restrict const grafptr, /*+ Graph data +*/ const Arch * restrict const archptr, /*+ Architecture data +*/ const ArchDom * restrict const domnptr, /*+ Target architecture initial domain +*/ const Anum domnmax, const Anum domnnbr) { mappptr->flagval = MAPPINGNONE; mappptr->grafptr = grafptr; mappptr->archptr = archptr; mappptr->parttax = NULL; mappptr->domntab = NULL; mappptr->domnnbr = domnnbr; mappptr->domnmax = domnmax; mappptr->domnorg = *domnptr; /* Use provided domain as original domain (e.g. when running a piece of parallel partitioning) */ } /* This routine allocates the contents of a mapping. ** It returns: ** - 0 : if mapping successfully allocated. ** - !0 : on error. */ int mapAlloc ( Mapping * restrict const mappptr) /*+ Mapping structure to fill +*/ { if ((mappptr->flagval & MAPPINGFREEPART) == 0) { /* If no private partition array yet */ Anum * restrict parttab; if ((parttab = (Anum *) memAlloc (mappptr->grafptr->vertnbr * sizeof (Anum))) == NULL) { errorPrint ("mapAlloc: out of memory (1)"); return (1); } mappptr->flagval |= MAPPINGFREEPART; mappptr->parttax = parttab - mappptr->grafptr->baseval; } if ((mappptr->flagval & MAPPINGFREEDOMN) == 0) { /* If no private domain array yet */ if ((mappptr->domntab = (ArchDom *) memAlloc (mappptr->domnmax * sizeof (ArchDom))) == NULL) { errorPrint ("mapAlloc: out of memory (2)"); return (1); } mappptr->flagval |= MAPPINGFREEDOMN; } return (0); } /* This routine resizes the domain array of a ** mapping and preserves its existing contents. ** It returns: ** - 0 : if mapping successfully allocated. ** - !0 : on error. */ int mapResize ( Mapping * restrict const mappptr, /*+ Mapping structure to fill +*/ const Anum domnmax) { int flagval; const ArchDom * restrict domntab; flagval = mappptr->flagval; /* Save old flag value */ domntab = mappptr->domntab; /* Save pointer to old domain array */ if (mapResize2 (mappptr, domnmax) != 0) /* Resize array */ return (1); if (flagval != mappptr->flagval) /* If a new private array has been created */ memCpy (mappptr->domntab, domntab, mappptr->domnnbr * sizeof (ArchDom)); return (0); } /* This routine resizes the domain array of a ** mapping without preserving its existing contents. ** It returns: ** - 0 : if mapping successfully allocated. ** - !0 : on error. */ int mapResize2 ( Mapping * restrict const mappptr, /*+ Mapping structure to fill +*/ const Anum domnmax) { ArchDom * domntab; domntab = ((mappptr->flagval & MAPPINGFREEDOMN) != 0) /* If it was a privately owned array */ ? memRealloc (mappptr->domntab, domnmax * sizeof (ArchDom)) /* Reallocate it */ : memAlloc (domnmax * sizeof (ArchDom)); /* Else allocate it privately */ if (domntab == NULL) { errorPrint ("mapResize2: out of memory"); return (1); } mappptr->domntab = domntab; mappptr->domnmax = domnmax; mappptr->flagval |= MAPPINGFREEDOMN; /* Array is now private anyway */ return (0); } /* This routine builds an initial mapping. ** It returns: ** - void : in all cases. */ void mapFrst ( Mapping * restrict const mappptr) /*+ Mapping structure to fill +*/ { mappptr->domnnbr = 1; /* One domain in mapping to date */ mappptr->domntab[0] = mappptr->domnorg; /* Set first domain */ memSet (mappptr->parttax + mappptr->grafptr->baseval, 0, mappptr->grafptr->vertnbr * sizeof (Anum)); /* Set parttax to first domain */ } /* This routine frees the contents ** of the given mapping. ** It returns: ** - void : in all cases. */ void mapFree ( Mapping * const mappptr) { if (((mappptr->flagval & MAPPINGFREEDOMN) != 0) && /* If domntab must be freed */ (mappptr->domntab != NULL)) /* And if exists */ memFree (mappptr->domntab); /* Free it */ if (((mappptr->flagval & MAPPINGFREEPART) != 0) && /* If parttax must be freed */ (mappptr->parttax != NULL)) /* And if exists */ memFree (mappptr->parttax + mappptr->grafptr->baseval); /* Free it */ mappptr->parttax = NULL; mappptr->domntab = NULL; } /* This routine frees the contents ** of the given mapping. ** It returns: ** - void : in all cases. */ void mapExit ( Mapping * const mappptr) { mapFree (mappptr); #ifdef SCOTCH_DEBUG_MAP2 memSet (mappptr, ~0, sizeof (Mapping)); #endif /* SCOTCH_DEBUG_MAP2 */ } /* This routine copies a mapping onto another. ** It returns: ** - 0 : if mapping successfully copied. ** - !0 : on error. */ int mapCopy ( Mapping * restrict const mappptr, /*+ Mapping to set +*/ const Mapping * restrict const mapoptr) /*+ Old mapping +*/ { ArchDom * domntab; Anum domnnbr; Gnum baseval; #ifdef SCOTCH_DEBUG_MAP2 if (mappptr->grafptr->vertnbr != mapoptr->grafptr->vertnbr) { errorPrint ("mapCopy: mappings do not match"); return (1); } #endif /* SCOTCH_DEBUG_MAP2 */ baseval = mapoptr->grafptr->baseval; domnnbr = mapoptr->domnnbr; if (domnnbr > mappptr->domnmax) { /* If we have to resize domain array */ if (mapResize2 (mappptr, domnnbr) != 0) /* Resize it */ return (1); } mappptr->domnnbr = domnnbr; memCpy (mappptr->domntab, mapoptr->domntab, domnnbr * sizeof (ArchDom)); memCpy (mappptr->parttax + baseval, mapoptr->parttax + baseval, mapoptr->grafptr->vertnbr * sizeof (Anum)); return (0); } /* This routine builds a mapping from a ** terminal domain partition array. ** It returns: ** - 0 : if mapping successfully filled. ** - !0 : on error. */ static int mapBuild2 ( Mapping * restrict const mappptr, /*+ Mapping to set +*/ MappingHash * restrict * const hashtabptr, /*+ Pointer to hash table to set up +*/ Gnum * const hashsizptr) /*+ Size of hash table +*/ { ArchDom domndat; MappingHash * hashtab; Gnum hashnbr; /* Prospective number of cells in table */ Gnum hashsiz; /* Size of hash table */ const Arch * restrict const archptr = mappptr->archptr; #ifdef SCOTCH_DEBUG_MAP2 if (mappptr->domnmax < 1) { errorPrint ("mapBuild2: domain array is too small"); return (1); } #endif /* SCOTCH_DEBUG_MAP2 */ archDomFrst (archptr, &domndat); hashnbr = (archVar (archptr) == 0) /* If fixed size architecture */ ? archDomSize (archptr, &domndat) /* Get maximum size of distinct terminal domains */ : mappptr->grafptr->vertnbr; /* Else take upper bound as number of vertices */ hashnbr ++; /* Add one extra slot for unknown terminal domain */ for (hashsiz = 32; hashsiz < hashnbr; hashsiz <<= 1) ; /* Get upper power of two */ hashsiz <<= 2; /* Fill hash table at 25% maximum */ if ((hashtab = (MappingHash *) memAlloc (hashsiz * sizeof (MappingHash))) == NULL) { errorPrint ("mapBuild2: out of memory"); return (1); } memSet (hashtab, ~0, hashsiz * sizeof (MappingHash)); /* Set all vertex numbers to ~0 */ *hashtabptr = hashtab; *hashsizptr = hashsiz; return (0); } static int mapBuild3 ( Mapping * restrict const mappptr, /*+ Mapping to fill +*/ MappingHash * restrict const hashtab, /*+ Hash table +*/ const Gnum hashsiz, /*+ Hash table size +*/ const Anum * restrict const termtax) /*+ Terminal array to load +*/ { ArchDom * restrict domntab; Anum domnnbr; Anum domnmax; Gnum hashmsk; Gnum vertnnd; Gnum vertnum; int o; const Arch * restrict const archptr = mappptr->archptr; Anum * restrict const parttax = mappptr->parttax; o = 1; /* Assume loop will fail */ hashmsk = hashsiz - 1; domntab = mappptr->domntab; domnnbr = mappptr->domnnbr; domnmax = mappptr->domnmax; for (vertnum = mappptr->grafptr->baseval, vertnnd = mappptr->grafptr->vertnnd; vertnum < vertnnd; vertnum ++) { Gnum hashnum; Anum termnum; Anum domnnum; termnum = termtax[vertnum]; if (termnum == ~0) /* If unknown part, skip it */ continue; for (hashnum = (termnum * MAPPINGHASHPRIME) & hashmsk; ; hashnum = (hashnum + 1) & hashmsk) { if (hashtab[hashnum].termnum == termnum) { /* If hash slot found */ domnnum = hashtab[hashnum].domnnum; /* Domain number found */ break; } if (hashtab[hashnum].termnum == ~0) { /* If hash slot empty */ hashtab[hashnum].termnum = termnum; /* Create slot */ hashtab[hashnum].domnnum = domnnbr; if (domnnbr == domnmax) { domnmax += (domnmax >> 2) + 8; /* Increase size by 25% */ if (mapResize (mappptr, domnmax) != 0) goto fail; domntab = mappptr->domntab; /* Re-read pointer in case it changed */ } archDomTerm (archptr, &domntab[domnnbr], termnum); /* Create slot with terminal number domain */ domnnum = domnnbr ++; /* Get position of new slot; one more slot created */ break; } } parttax[vertnum] = domnnum; /* Refer to the proper domain */ } o = 0; /* Success */ fail: mappptr->domnnbr = domnnbr; /* Set updated number of domains */ memFree (hashtab); /* Free hash table */ return (o); } int mapBuild ( Mapping * restrict const mappptr, /*+ Mapping to set +*/ const Anum * restrict const termtax) /*+ Terminal array to load +*/ { MappingHash * restrict hashtab; Gnum hashsiz; /* Size of hash table */ if (mapBuild2 (mappptr, &hashtab, &hashsiz) != 0) return (1); return (mapBuild3 (mappptr, hashtab, hashsiz, termtax)); } /* This routine updates a mapping with a ** terminal domain partition array. ** It returns: ** - 0 : if mapping successfully updated. ** - !0 : on error. */ int mapMerge ( Mapping * restrict const mappptr, /*+ Mapping to set +*/ const Anum * restrict const termtab) /*+ Terminal array to load +*/ { MappingHash * restrict hashtab; Gnum hashsiz; /* Size of hash table */ Gnum hashmsk; Anum domnnbr; Anum domnnum; const Arch * restrict const archptr = mappptr->archptr; const ArchDom * restrict const domntab = mappptr->domntab; if (mapBuild2 (mappptr, &hashtab, &hashsiz) != 0) return (1); hashmsk = hashsiz - 1; for (domnnum = 0, domnnbr = mappptr->domnnbr; domnnum < domnnbr; domnnum ++) { const ArchDom * domnptr; Gnum hashnum; Anum termnum; domnptr = &domntab[domnnum]; if (archDomSize (archptr, domnptr) != 1) /* If domain is not terminal, skip it */ continue; termnum = archDomNum (archptr, domnptr); for (hashnum = (termnum * MAPPINGHASHPRIME) & hashmsk; ; hashnum = (hashnum + 1) & hashmsk) { /* Fill hash table with existing domains */ #ifdef SCOTCH_DEBUG_MAP2 if (hashtab[hashnum].termnum == termnum) { /* If hash slot found */ errorPrint ("mapMerge: internal error"); /* Multiple domains with same terminal number */ return (1); } #endif /* SCOTCH_DEBUG_MAP2 */ if (hashtab[hashnum].termnum == ~0) { /* If hash slot empty */ hashtab[hashnum].termnum = termnum; /* Create slot */ hashtab[hashnum].domnnum = domnnum; break; } } } return (mapBuild3 (mappptr, hashtab, hashsiz, termtab)); /* Add new domains to existing domain array */ } /* This routine propagates back mapping ** information to a terminal part array. ** It returns: ** - void : in all cases. */ void mapTerm ( const Mapping * restrict const mappptr, Anum * restrict const termtax) { Gnum vertnnd; Gnum vertnum; const Arch * restrict const archptr = mappptr->archptr; const ArchDom * restrict const domntab = mappptr->domntab; const Anum * restrict const parttax = mappptr->parttax; vertnum = mappptr->grafptr->baseval; if (domntab != NULL) { for (vertnnd = mappptr->grafptr->vertnnd; vertnum < vertnnd; vertnum ++) termtax[vertnum] = archDomNum (archptr, &domntab[parttax[vertnum]]); } else memSet (termtax + vertnum, ~0, mappptr->grafptr->vertnbr * sizeof (Anum)); } scotch-6.0.4.dfsg/src/libscotch/library_dgraph_gather.c0000644002563400244210000001214212055776227026336 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_gather.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the distri- **/ /** buted source graph handling routines of **/ /** the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 12 jul 2007 **/ /** to 17 jul 2007 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "graph.h" #include "dgraph.h" #include "ptscotch.h" /************************************/ /* */ /* These routines are the C API for */ /* the graph handling routines. */ /* */ /************************************/ /*+ This routine gathers the data of a *** distributed graph on a centralized graph. *** It returns: *** - 0 : if the centralization succeeded. *** - !0 : on error. +*/ int SCOTCH_dgraphGather ( const SCOTCH_Dgraph * const dgrfptr, SCOTCH_Graph * const cgrfptr) { Dgraph * restrict srcdgrfptr; Gnum reduloctab[3]; Gnum reduglbtab[3]; srcdgrfptr = (Dgraph *) dgrfptr; if ((cgrfptr != NULL) && (((void *) cgrfptr) != ((void *) dgrfptr))) { /* If centralized graph provided */ reduloctab[0] = 1; /* Process is a potential root */ reduloctab[1] = (Gnum) srcdgrfptr->proclocnum; } else { /* Process is not a root */ reduloctab[0] = 0; reduloctab[1] = 0; } if (srcdgrfptr->edloloctax == NULL) /* Compute sum of edge loads for access to low-level routines */ reduloctab[2] = srcdgrfptr->edgelocnbr; else { Gnum vertlocnum; Gnum edlolocsum; for (vertlocnum = srcdgrfptr->baseval, edlolocsum = 0; vertlocnum < srcdgrfptr->vertlocnnd; vertlocnum ++) { Gnum edgelocnum; Gnum edgelocnnd; for (edgelocnum = srcdgrfptr->vertloctax[vertlocnum], edgelocnnd = srcdgrfptr->vendloctax[vertlocnum]; edgelocnum < edgelocnnd; edgelocnum ++) edlolocsum += srcdgrfptr->edloloctax[edgelocnum]; } reduloctab[2] = edlolocsum; } if (MPI_Allreduce (reduloctab, reduglbtab, 3, GNUM_MPI, MPI_SUM, srcdgrfptr->proccomm) != MPI_SUCCESS) { errorPrint ("SCOTCH_dgraphGather: communication error"); return (1); } if (reduglbtab[0] == 1) /* If only one single root */ return (dgraphGatherAll2 (srcdgrfptr, (Graph *) cgrfptr, reduglbtab[2], (int) reduglbtab[1])); else if (reduglbtab[0] == srcdgrfptr->procglbnbr) /* If all processes are roots */ return (dgraphGatherAll2 (srcdgrfptr, (Graph *) cgrfptr, reduglbtab[2], -1)); errorPrint ("SCOTCH_dgraphGather: invalid number of roots"); return (1); } scotch-6.0.4.dfsg/src/libscotch/dgraph_coarsen.c0000644002563400244210000014131612416717356024777 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_coarsen.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Cedric CHEVALIER (v5.0) **/ /** **/ /** FUNCTION : This file implements the coarsening **/ /** phase of the multi-level method. **/ /** The implementation uses several **/ /** processes, which could have several **/ /** threads each (3 at this time). **/ /** **/ /** DATES : # Version 5.0 : from : 27 jul 2005 **/ /** to : 15 may 2008 **/ /** # Version 5.1 : from : 23 jun 2008 **/ /** to : 20 feb 2011 **/ /** # Version 6.0 : from : 11 sep 2012 **/ /** to : 28 sep 2014 **/ /** **/ /************************************************************/ #define DGRAPH_COARSEN #include "module.h" #include "common.h" #include "dgraph.h" #include "dgraph_allreduce.h" #include "dgraph_coarsen.h" #include "dgraph_match.h" /******************************/ /* */ /* Graph coarsening routines. */ /* */ /******************************/ static int dgraphCoarsenInit ( DgraphCoarsenData * restrict const coarptr, /*+ Coarsening data structure +*/ Dgraph * restrict const finegrafptr, /*+ Graph to coarsen +*/ Dgraph * restrict const coargrafptr) /*+ Coarse graph to build +*/ { int procglbnbr; int procglbnum; int procngbnbr; int procngbnum; int procngbnxt; int vertrcvnbr; int vertsndnbr; Gnum vertlocnbr; Gnum vertgstnbr; int vdsprcvnum; int vdspsndnum; byte * bufftab; size_t buffsiz; const int * restrict const fineprocngbtab = finegrafptr->procngbtab; const int * restrict const fineprocrcvtab = finegrafptr->procrcvtab; const int * restrict const fineprocsndtab = finegrafptr->procsndtab; vertlocnbr = finegrafptr->vertlocnbr; vertgstnbr = finegrafptr->vertgstnbr; procglbnbr = finegrafptr->procglbnbr; procngbnbr = finegrafptr->procngbnbr; vertrcvnbr = vertgstnbr - vertlocnbr; vertsndnbr = finegrafptr->procsndnbr; coarptr->coarprvptr = NULL; /* Assume nothing to free on error */ coarptr->multloctmp = NULL; coarptr->nsndidxtab = NULL; coarptr->nrcvidxtab = NULL; if ((coarptr->coarprvptr = memAllocGroup ((void **) (void *) /* Allocate distributed coarse graph private data */ &coargrafptr->procdsptab, (size_t) ((procglbnbr + 1) * sizeof (Gnum)), &coargrafptr->proccnttab, (size_t) (procglbnbr * sizeof (Gnum)), &coargrafptr->procngbtab, (size_t) (procglbnbr * sizeof (int)), &coargrafptr->procrcvtab, (size_t) (procglbnbr * sizeof (int)), &coargrafptr->procsndtab, (size_t) (procglbnbr * sizeof (int)), NULL)) == NULL) { errorPrint ("dgraphCoarsenInit: out of memory (1)"); return (1); } coargrafptr->procvrttab = coargrafptr->procdsptab; /* Coarse graph has no holes */ if (coarptr->multloctab == NULL) { /* If no multinode array provided */ if ((coarptr->multloctab = memAlloc (vertlocnbr * sizeof (DgraphCoarsenMulti))) == NULL) { errorPrint ("dgraphCoarsenInit: out of memory (2)"); dgraphCoarsenExit (coarptr); return (1); } coarptr->multloctmp = coarptr->multloctab; /* Array will have to be freed on error */ } if (memAllocGroup ((void **) (void *) /* Data used up to edge exchange phase at coarse graph build time */ &coarptr->nrcvidxtab, (size_t) (procngbnbr * sizeof (int)), &coarptr->vrcvdsptab, (size_t) ((procglbnbr + 1) * sizeof (int)), /* TRICK: "+1" for size count */ &coarptr->coargsttax, (size_t) (vertgstnbr * sizeof (Gnum)), &coarptr->procgsttax, (size_t) (vertrcvnbr * sizeof (int)), /* TRICK: Only purely ghost part of array will be used */ &coarptr->vrcvdattab, (size_t) (vertrcvnbr * sizeof (DgraphCoarsenVert)), NULL) == NULL) { errorPrint ("dgraphCoarsenInit: out of memory (3)"); dgraphCoarsenExit (coarptr); return (1); } buffsiz = 2 * MAX ((procngbnbr * sizeof (MPI_Request)), (procglbnbr * sizeof (int))); if (memAllocGroup ((void **) (void *) /* Data released after coarse vertex index exchange phase */ &coarptr->nsndidxtab, (size_t) (procngbnbr * sizeof (int)), &coarptr->vsnddsptab, (size_t) ((procglbnbr + 1) * sizeof (int)), /* TRICK: "+1" for size count check */ &bufftab, (size_t) buffsiz, &coarptr->dcntloctab, (size_t) (procglbnbr * sizeof (DgraphCoarsenCount)), &coarptr->dcntglbtab, (size_t) (procglbnbr * sizeof (DgraphCoarsenCount)), &coarptr->vsnddattab, (size_t) (vertsndnbr * sizeof (DgraphCoarsenVert)), NULL) == NULL) { errorPrint ("dgraphCoarsenInit: out of memory (4)"); dgraphCoarsenExit (coarptr); return (1); } coarptr->nrcvreqtab = (MPI_Request *) (void *) bufftab; /* TRICK: point-to-point requests and collective arrays share same space */ coarptr->nsndreqtab = coarptr->nrcvreqtab + procngbnbr; coarptr->vrcvcnttab = (int *) (void *) bufftab; coarptr->vsndcnttab = coarptr->vrcvcnttab + procglbnbr; for (procglbnum = 0, vdsprcvnum = vdspsndnum = 0; /* Build communication index arrays */ procglbnum < procglbnbr; procglbnum ++) { coarptr->vrcvdsptab[procglbnum] = vdsprcvnum; coarptr->vsnddsptab[procglbnum] = vdspsndnum; vdsprcvnum += fineprocrcvtab[procglbnum]; vdspsndnum += fineprocsndtab[procglbnum]; } coarptr->vrcvdsptab[procglbnum] = vdsprcvnum; /* Mark end of communication index arrays */ coarptr->vsnddsptab[procglbnum] = vdspsndnum; for (procngbnum = procngbnxt = 0; procngbnum < procngbnbr; procngbnum ++) { if ((procngbnxt == 0) && (fineprocngbtab[procngbnum] > finegrafptr->proclocnum)) { /* Find index of first neighbor of higher rank */ procngbnxt = procngbnum; break; } } coarptr->procngbnxt = procngbnxt; coarptr->coargsttax -= finegrafptr->baseval; coarptr->finegrafptr = finegrafptr; coarptr->coargrafptr = coargrafptr; memSet (coarptr->dcntloctab, 0, procglbnbr * sizeof (DgraphCoarsenCount)); memSet (coarptr->procgsttax, ~0, vertrcvnbr * sizeof (int)); /* Values have not yet been computed */ coarptr->procgsttax -= vertlocnbr + finegrafptr->baseval; /* TRICK: base array such that only purely ghost part is used */ coarptr->edgekptnbr = 0; return (0); } static void dgraphCoarsenExit ( DgraphCoarsenData * restrict const coarptr) /*+ Coarsening data structure +*/ { if (coarptr->nsndidxtab != NULL) /* Auxiliary array is released after first phase of coarse graph building */ memFree (coarptr->nsndidxtab); if (coarptr->nrcvidxtab != NULL) memFree (coarptr->nrcvidxtab); if (coarptr->multloctmp != NULL) /* If multinode array not provided nor passed back to calling routine */ memFree (coarptr->multloctmp); if (coarptr->coarprvptr != NULL) /* If ownership of coarse graph private data not yet transferred to it */ memFree (coarptr->coarprvptr); } static int dgraphCoarsenBuildColl ( DgraphCoarsenData * restrict const coarptr) { Gnum vertlocadj; int procngbnbr; int procngbnum; MPI_Comm proccomm = coarptr->finegrafptr->proccomm; Dgraph * restrict const grafptr = coarptr->finegrafptr; const int * restrict const procngbtab = grafptr->procngbtab; Gnum * restrict const coargsttax = coarptr->coargsttax; int * restrict const vsndcnttab = coarptr->vsndcnttab; int * restrict const vrcvdsptab = coarptr->coargrafptr->procrcvtab; /* TRICK: use coarse graph procrcvtab and procsndtab */ int * restrict const vsnddsptab = coarptr->coargrafptr->procsndtab; int * restrict const nrcvidxtab = coarptr->nrcvidxtab; int * restrict const nsndidxtab = coarptr->nsndidxtab; procngbnbr = grafptr->procngbnbr; vertlocadj = grafptr->procvrttab[grafptr->proclocnum] - grafptr->baseval; memSet (vsndcnttab, 0, grafptr->procglbnbr * sizeof (int)); memSet (vrcvdsptab, 0, grafptr->procglbnbr * sizeof (int)); memSet (vsnddsptab, 0, grafptr->procglbnbr * sizeof (int)); for (procngbnum = 0; procngbnum < procngbnbr; procngbnum ++) { int procglbnum; procglbnum = procngbtab[procngbnum]; vsndcnttab[procglbnum] = 2 * (nsndidxtab[procngbnum] - coarptr->vsnddsptab[procglbnum]); vrcvdsptab[procglbnum] = 2 * coarptr->vrcvdsptab[procglbnum]; vsnddsptab[procglbnum] = 2 * coarptr->vsnddsptab[procglbnum]; } if (MPI_Alltoall (vsndcnttab, 1, MPI_INT, coarptr->vrcvcnttab, 1, MPI_INT, proccomm) != MPI_SUCCESS) { errorPrint ("dgraphCoarsenBuildColl: communication error (1)"); return (1); } if (MPI_Alltoallv (coarptr->vsnddattab, vsndcnttab, vsnddsptab, GNUM_MPI, coarptr->vrcvdattab, coarptr->vrcvcnttab, vrcvdsptab, GNUM_MPI, proccomm) != MPI_SUCCESS) { errorPrint ("dgraphCoarsenBuildColl: communication error (2)"); return (1); } for (procngbnum = 0; procngbnum < procngbnbr; procngbnum ++) { /* For all received data chunks */ int vrcvidxnnd; int vrcvidxnum; int procglbnum; int statsiz; const DgraphCoarsenVert * restrict const vrcvdattab = coarptr->vrcvdattab; /* After data is received */ procglbnum = procngbtab[procngbnum]; statsiz = coarptr->vrcvcnttab[procglbnum]; for (vrcvidxnum = coarptr->vrcvdsptab[procglbnum], vrcvidxnnd = vrcvidxnum + (statsiz / 2); /* TRICK: each message item costs 2 Gnum's */ vrcvidxnum < vrcvidxnnd; vrcvidxnum ++) { Gnum vertglbnum; /* Our global number (the one seen as mate by sender) */ Gnum vertlocnum; /* Our local number (the one seen as mate by sender) */ Gnum multglbnum; /* Global number of coarse vertex */ vertglbnum = vrcvdattab[vrcvidxnum].datatab[0]; multglbnum = vrcvdattab[vrcvidxnum].datatab[1]; vertlocnum = vertglbnum - vertlocadj; #ifdef SCOTCH_DEBUG_DGRAPH2 if ((vertlocnum < grafptr->baseval) || /* If matching request is not directed towards our process */ (vertlocnum >= grafptr->vertlocnnd)) { errorPrint ("dgraphCoarsenBuildColl: internal error"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ coargsttax[vertlocnum] = multglbnum; } nrcvidxtab[procngbnum] = vrcvidxnnd; /* Keep receive end index for preparing edge arrays */ } return (0); } static int dgraphCoarsenBuildPtop ( DgraphCoarsenData * restrict const coarptr) { Gnum vertlocadj; int procngbnbr; int procngbnum; int vrcvreqnbr; MPI_Comm proccomm = coarptr->finegrafptr->proccomm; Dgraph * restrict const grafptr = coarptr->finegrafptr; const int * restrict const procngbtab = grafptr->procngbtab; Gnum * restrict const coargsttax = coarptr->coargsttax; const int * restrict const vrcvdsptab = coarptr->vrcvdsptab; const int * restrict const vsnddsptab = coarptr->vsnddsptab; int * restrict const nrcvidxtab = coarptr->nrcvidxtab; int * restrict const nsndidxtab = coarptr->nsndidxtab; procngbnbr = grafptr->procngbnbr; vertlocadj = grafptr->procvrttab[grafptr->proclocnum] - grafptr->baseval; if (procngbnbr > 0) { /* No communication else */ procngbnum = coarptr->procngbnxt; /* Post receives in descending order */ do { int procglbnum; procngbnum = (procngbnum + (procngbnbr - 1)) % procngbnbr; /* Pre-decrement neighbor rank */ procglbnum = procngbtab[procngbnum]; if (MPI_Irecv (coarptr->vrcvdattab + vrcvdsptab[procglbnum], 2 * (vrcvdsptab[procglbnum + 1] - vrcvdsptab[procglbnum]), GNUM_MPI, procglbnum, TAGCOARSEN, proccomm, &coarptr->nrcvreqtab[procngbnum]) != MPI_SUCCESS) { errorPrint ("dgraphCoarsenBuildPtop: communication error (1)"); return (1); } } while (procngbnum != coarptr->procngbnxt); procngbnum = coarptr->procngbnxt; /* Post sends in ascending order */ do { int procglbnum; procglbnum = procngbtab[procngbnum]; if (MPI_Isend (coarptr->vsnddattab + vsnddsptab[procglbnum], 2 * (nsndidxtab[procngbnum] - vsnddsptab[procglbnum]), GNUM_MPI, procglbnum, TAGCOARSEN, proccomm, &coarptr->nsndreqtab[procngbnum]) != MPI_SUCCESS) { errorPrint ("dgraphCoarsenBuildPtop: communication error (2)"); return (1); } procngbnum = (procngbnum + 1) % procngbnbr; /* Post-increment neighbor rank */ } while (procngbnum != coarptr->procngbnxt); } for (vrcvreqnbr = procngbnbr; vrcvreqnbr > 0; vrcvreqnbr --) { /* For all pending receive requests */ int vrcvidxnnd; int vrcvidxnum; int procngbnum; MPI_Status statdat; int statsiz; int o; #ifdef SCOTCH_DETERMINISTIC procngbnum = vrcvreqnbr - 1; o = MPI_Wait (&coarptr->nrcvreqtab[procngbnum], &statdat); #else /* SCOTCH_DETERMINISTIC */ o = MPI_Waitany (procngbnbr, coarptr->nrcvreqtab, &procngbnum, &statdat); #endif /* SCOTCH_DETERMINISTIC */ if ((o != MPI_SUCCESS) || (MPI_Get_count (&statdat, GNUM_MPI, &statsiz) != MPI_SUCCESS)) { errorPrint ("dgraphCoarsenBuildPtop: communication error (3)"); return (1); } #ifdef SCOTCH_DEBUG_DGRAPH2 if (statdat.MPI_SOURCE != procngbtab[procngbnum]) { errorPrint ("dgraphCoarsenBuildPtop: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ { const DgraphCoarsenVert * restrict const vrcvdattab = coarptr->vrcvdattab; /* After data is received */ for (vrcvidxnum = vrcvdsptab[procngbtab[procngbnum]], vrcvidxnnd = vrcvidxnum + (statsiz / 2); /* TRICK: each message item costs 2 Gnum's */ vrcvidxnum < vrcvidxnnd; vrcvidxnum ++) { Gnum vertglbnum; /* Our global number (the one seen as mate by sender) */ Gnum vertlocnum; /* Our local number (the one seen as mate by sender) */ Gnum multglbnum; /* Global number of coarse vertex */ vertglbnum = vrcvdattab[vrcvidxnum].datatab[0]; multglbnum = vrcvdattab[vrcvidxnum].datatab[1]; vertlocnum = vertglbnum - vertlocadj; #ifdef SCOTCH_DEBUG_DGRAPH2 if ((vertlocnum < grafptr->baseval) || /* If matching request is not directed towards our process */ (vertlocnum >= grafptr->vertlocnnd)) { errorPrint ("dgraphCoarsenBuildPtop: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ coargsttax[vertlocnum] = multglbnum; } nrcvidxtab[procngbnum] = vrcvidxnnd; /* Keep receive end index for preparing edge arrays */ } } if (MPI_Waitall (procngbnbr, coarptr->nsndreqtab, MPI_STATUSES_IGNORE) != MPI_SUCCESS) { /* Wait for send requests to complete */ errorPrint ("dgraphCoarsenBuildPtop: communication error (4)"); return (1); } return (0); } /* This routine performs the coarsening of edges ** with respect to the coarmulttax array computed ** by dgraphMatch. All data must be available when ** running (all receptions done). This function is ** inspired by libscotch/src/graph_coarsen_edge.c. */ DGRAPHALLREDUCEMAXSUMOP (3, 1) static int dgraphCoarsenBuild ( DgraphCoarsenData * restrict const coarptr) { Gnum vertlocnum; Gnum vertlocadj; Gnum edgelocnbr; Gnum edlolocval; Gnum * restrict ercvdattab; Gnum * restrict esnddattab; int * restrict ercvcnttab; int * restrict esndcnttab; int * restrict ercvdsptab; int * restrict esnddsptab; int ercvdspval; int esnddspval; int ercvdatsiz; int esnddatsiz; DgraphCoarsenMulti * restrict multloctax; Gnum multlocnum; Gnum multlocadj; int procngbnbr; int procngbnum; int procnum; Gnum coarvertglbnum; Gnum coarvertlocnum; Gnum coarvertlocnnd; Gnum * restrict coarvertloctax; Gnum * restrict coarveloloctax; Gnum coarvelolocsum; Gnum coardegrlocmax; Gnum coaredgelocnum; Gnum * restrict coaredgeloctax; Gnum * restrict coaredloloctax; Gnum coarhashnbr; /* Size of hash table */ Gnum coarhashmsk; /* Mask for access hash table */ DgraphCoarsenHash * restrict coarhashtab; /* Table of edges to other multinodes */ Gnum reduloctab[4]; Gnum reduglbtab[4]; int cheklocval; int chekglbval; #ifdef SCOTCH_DEBUG_DGRAPH2 int * restrict ercvdbgtab; #endif /* SCOTCH_DEBUG_DGRAPH2 */ MPI_Comm proccomm = coarptr->finegrafptr->proccomm; Dgraph * restrict const grafptr = coarptr->finegrafptr; Dgraph * restrict const coargrafptr = coarptr->coargrafptr; Gnum * restrict const coargsttax = coarptr->coargsttax; const int * restrict const procngbtab = grafptr->procngbtab; const int * restrict const procgsttax = coarptr->procgsttax; const Gnum * restrict const vertloctax = grafptr->vertloctax; const Gnum * restrict const vendloctax = grafptr->vendloctax; const Gnum * restrict const veloloctax = grafptr->veloloctax; const Gnum * restrict const edgeloctax = grafptr->edgeloctax; const Gnum * restrict const edgegsttax = grafptr->edgegsttax; const Gnum * restrict const edloloctax = grafptr->edloloctax; const DgraphCoarsenMulti * restrict const multloctab = coarptr->multloctab; DgraphCoarsenVert * const vrcvdattab = coarptr->vrcvdattab; /* [norestrict:async] */ DgraphCoarsenVert * restrict const vsnddattab = coarptr->vsnddattab; int * restrict const nsndidxtab = coarptr->nsndidxtab; #ifdef SCOTCH_DEBUG_DGRAPH2 memSet (coargsttax + grafptr->baseval, ~0, grafptr->vertgstnbr * sizeof (Gnum)); #endif /* SCOTCH_DEBUG_DGRAPH2 */ procngbnbr = grafptr->procngbnbr; for (procngbnum = 0; procngbnum < procngbnbr; procngbnum ++) /* Reset indices for sending messages */ nsndidxtab[procngbnum] = coarptr->vsnddsptab[procngbtab[procngbnum]]; vertlocadj = grafptr->procvrttab[grafptr->proclocnum] - grafptr->baseval; multlocadj = coarptr->coargrafptr->procdsptab[grafptr->proclocnum]; for (multlocnum = 0; multlocnum < coarptr->multlocnbr; multlocnum ++) { Gnum vertlocnum0; Gnum vertlocnum1; vertlocnum0 = multloctab[multlocnum].vertglbnum[0] - vertlocadj; #ifdef SCOTCH_DEBUG_DGRAPH2 if ((vertlocnum0 < grafptr->baseval) || (vertlocnum0 >= grafptr->vertlocnnd)) { errorPrint ("dgraphCoarsenBuild: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ coargsttax[vertlocnum0] = multlocnum + multlocadj; vertlocnum1 = multloctab[multlocnum].vertglbnum[1]; if (vertlocnum1 >= 0) { /* If second vertex is local */ vertlocnum1 -= vertlocadj; #ifdef SCOTCH_DEBUG_DGRAPH2 if ((vertlocnum1 < grafptr->baseval) || (vertlocnum1 >= grafptr->vertlocnnd)) { errorPrint ("dgraphCoarsenBuild: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ coargsttax[vertlocnum1] = multlocnum + multlocadj; /* Don't care if single multinode */ } else { Gnum edgelocnum; Gnum vertglbnum1; Gnum vertgstnum1; int coarsndidx; int procngbnum; edgelocnum = -2 - vertlocnum1; #ifdef SCOTCH_DEBUG_DGRAPH2 if ((edgelocnum < grafptr->baseval) || (edgelocnum >= (grafptr->edgelocsiz + grafptr->baseval))) { errorPrint ("dgraphCoarsenBuild: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ vertglbnum1 = edgeloctax[edgelocnum]; vertgstnum1 = edgegsttax[edgelocnum]; procngbnum = procgsttax[vertgstnum1]; /* Find neighbor owner process */ if (procngbnum < 0) { /* If neighbor had not been computed */ errorPrint ("dgraphCoarsenBuild: internal error (4)"); return (1); } coarsndidx = nsndidxtab[procngbnum] ++; /* Get position of message in send array */ #ifdef SCOTCH_DEBUG_DGRAPH2 if (coarsndidx >= coarptr->vsnddsptab[procngbtab[procngbnum] + 1]) { errorPrint ("dgraphCoarsenBuild: internal error (5)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ vsnddattab[coarsndidx].datatab[0] = vertglbnum1; vsnddattab[coarsndidx].datatab[1] = multlocnum + multlocadj; /* Send multinode value */ } } if (coarptr->multloctmp != NULL) { /* If we allocated the multinode array */ coarptr->multloctmp = coarptr->multloctab = memRealloc (coarptr->multloctab, coarptr->multlocnbr * sizeof (DgraphCoarsenMulti)); /* In the mean time, resize multinode array */ } if ((((grafptr->flagval & DGRAPHCOMMPTOP) != 0) ? dgraphCoarsenBuildPtop : dgraphCoarsenBuildColl) (coarptr) != 0) return (1); #ifdef SCOTCH_DEBUG_DGRAPH2 if (MPI_Barrier (proccomm) != MPI_SUCCESS) { errorPrint ("dgraphCoarsenBuild: communication error (1)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ ercvcnttab = coarptr->coargrafptr->procrcvtab; /* TRICK: re-use some private coarse graph arrays after vertex exchange phase */ ercvdsptab = coarptr->coargrafptr->procsndtab; for (procnum = 0, ercvdspval = 0; procnum < grafptr->procglbnbr; procnum ++) { /* TRICK: dcntglbtab array no longer needed afterwards; can be freed */ ercvdsptab[procnum] = ercvdspval; ercvcnttab[procnum] = coarptr->dcntglbtab[procnum].vertsndnbr * ((veloloctax != NULL) ? 2 : 1) + coarptr->dcntglbtab[procnum].edgesndnbr * ((edloloctax != NULL) ? 2 : 1); ercvdspval += ercvcnttab[procnum]; } memFree (coarptr->nsndidxtab); /* Free now useless work memory */ coarptr->nsndidxtab = NULL; /* This block won't be reclaimed */ #ifdef SCOTCH_DEBUG_DGRAPH2 for (vertlocnum = grafptr->baseval; vertlocnum < grafptr->vertlocnnd; vertlocnum ++) { if (coargsttax[vertlocnum] < 0) { errorPrint ("dgraphCoarsenBuild: invalid matching"); return (1); } } #endif /* SCOTCH_DEBUG_DGRAPH2 */ if (dgraphHaloSync (grafptr, coargsttax + grafptr->baseval, GNUM_MPI) != 0) { errorPrint ("dgraphCoarsenBuild: cannot propagate multinode indices"); return (1); } edgelocnbr = coarptr->edgekptnbr + coarptr->edgercvnbr; /* Upper bound on number of edges */ ercvdatsiz = coarptr->vertrcvnbr + coarptr->edgercvnbr; /* Basic size: degrees plus edge data */ esnddatsiz = coarptr->vertsndnbr + coarptr->edgesndnbr; if (grafptr->veloloctax != NULL) { /* Add vertex loads if necessary */ ercvdatsiz += coarptr->vertrcvnbr; esnddatsiz += coarptr->vertsndnbr; } if (grafptr->edloloctax != NULL) { /* Add edge loads if necessary */ ercvdatsiz += coarptr->edgercvnbr; esnddatsiz += coarptr->edgesndnbr; } #ifdef SCOTCH_DEBUG_DGRAPH2 if (ercvdspval != ercvdatsiz) { errorPrint ("dgraphCoarsenBuild: internal error (6)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ for (coarhashmsk = 31; coarhashmsk < grafptr->degrglbmax; coarhashmsk = coarhashmsk * 2 + 1) ; coarhashmsk = coarhashmsk * 4 + 3; coarhashnbr = coarhashmsk + 1; cheklocval = 0; coargrafptr->flagval = DGRAPHFREETABS | DGRAPHFREEPRIV | DGRAPHVERTGROUP; /* Coarse graph is not yet based */ coarptr->coarprvptr = NULL; /* Transfer ownership of private arrays to coarse graph */ if (memAllocGroup ((void **) (void *) &coargrafptr->vertloctax, (size_t) ((coarptr->multlocnbr + 1) * sizeof (Gnum)), &coargrafptr->veloloctax, (size_t) ( coarptr->multlocnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("dgraphCoarsenBuild: out of memory (1)"); cheklocval = 1; } else if ((coargrafptr->edgeloctax = memAlloc (edgelocnbr * sizeof (Gnum))) == NULL) { errorPrint ("dgraphCoarsenBuild: out of memory (2)"); cheklocval = 1; } else if ((coargrafptr->edloloctax = memAlloc (edgelocnbr * sizeof (Gnum))) == NULL) { errorPrint ("dgraphCoarsenBuild: out of memory (3)"); cheklocval = 1; } else if ((coarptr->nsndidxtab = memAllocGroup ((void **) (void *) /* TRICK: allow data array to be released on error */ &esndcnttab, (size_t) (grafptr->procglbnbr * sizeof (int)), &esnddsptab, (size_t) (grafptr->procglbnbr * sizeof (int)), &esnddattab, (size_t) (esnddatsiz * sizeof (Gnum)), &ercvdattab, (size_t) (ercvdatsiz * sizeof (Gnum)), #ifdef SCOTCH_DEBUG_DGRAPH2 &ercvdbgtab, (size_t) (grafptr->procglbnbr * sizeof (int)), #endif /* SCOTCH_DEBUG_DGRAPH2 */ &coarhashtab, (size_t) (coarhashnbr * sizeof (DgraphCoarsenHash)), NULL)) == NULL) { errorPrint ("dgraphCoarsenBuild: out of memory (4)"); cheklocval = 1; } #ifdef SCOTCH_DEBUG_DGRAPH1 /* Communication cannot be overlapped by a useful one */ if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_SUM, proccomm) != MPI_SUCCESS) { errorPrint ("dgraphCoarsenBuild: communication error (2)"); chekglbval = 1; } #else /* SCOTCH_DEBUG_DGRAPH1 */ chekglbval = cheklocval; #endif /* SCOTCH_DEBUG_DGRAPH1 */ if (chekglbval != 0) { dgraphFree (coargrafptr); return (1); } memSet (coarhashtab, ~0, coarhashnbr * sizeof (DgraphCoarsenHash)); coargrafptr->baseval = grafptr->baseval; coargrafptr->vertlocnnd = coargrafptr->baseval + coargrafptr->vertlocnbr; coargrafptr->vertloctax -= coargrafptr->baseval; coargrafptr->vendloctax = coargrafptr->vertloctax + 1; /* Graph is compact */ coargrafptr->veloloctax -= coargrafptr->baseval; coargrafptr->edgeloctax -= coargrafptr->baseval; coargrafptr->edloloctax -= coargrafptr->baseval; for (procngbnum = procnum = 0, esnddspval = 0; procngbnum < procngbnbr; procngbnum ++) { int procglbnum; int vrcvidxnnd; int vrcvidxnum; procglbnum = procngbtab[procngbnum]; while (procnum < procglbnum) { /* Fill empty slots */ esnddsptab[procnum] = esnddspval; esndcnttab[procnum] = 0; procnum ++; } esnddsptab[procnum] = esnddspval; for (vrcvidxnum = coarptr->vrcvdsptab[procglbnum], vrcvidxnnd = coarptr->nrcvidxtab[procngbnum]; /* For all multinode requests received, in order */ vrcvidxnum < vrcvidxnnd; vrcvidxnum ++) { Gnum vertlocnum; Gnum edgelocnum; Gnum edgelocnnd; vertlocnum = vrcvdattab[vrcvidxnum].datatab[0] - vertlocadj; edgelocnum = vertloctax[vertlocnum]; edgelocnnd = vendloctax[vertlocnum]; #ifdef SCOTCH_DEBUG_DGRAPH2 if ((esnddspval + ((veloloctax != NULL) ? 2 : 1) + ((edloloctax != NULL) ? 2 : 1) * (edgelocnnd - edgelocnum)) > esnddatsiz) { errorPrint ("dgraphCoarsenBuild: internal error (7)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ esnddattab[esnddspval ++] = (edgelocnnd - edgelocnum); /* Write degree */ if (veloloctax != NULL) esnddattab[esnddspval ++] = veloloctax[vertlocnum]; if (edloloctax != NULL) { for ( ; edgelocnum < edgelocnnd; edgelocnum ++) { esnddattab[esnddspval ++] = coargsttax[edgegsttax[edgelocnum]]; esnddattab[esnddspval ++] = edloloctax[edgelocnum]; } } else { for ( ; edgelocnum < edgelocnnd; edgelocnum ++) esnddattab[esnddspval ++] = coargsttax[edgegsttax[edgelocnum]]; } } esndcnttab[procnum] = esnddspval - esnddsptab[procnum]; procnum ++; } while (procnum < grafptr->procglbnbr) { /* Complete fill-in of empty slots */ esnddsptab[procnum] = esnddspval; esndcnttab[procnum] = 0; procnum ++; } #ifdef SCOTCH_DEBUG_DGRAPH2 if (esnddspval != esnddatsiz) { errorPrint ("dgraphCoarsenBuild: internal error (8)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ while (procnum < grafptr->procglbnbr) { /* Complete edge data send displacement array */ esnddsptab[procnum] = esnddspval; esndcnttab[procnum] = 0; procnum ++; } #ifdef SCOTCH_DEBUG_DGRAPH2 if (MPI_Alltoall (esndcnttab, 1, MPI_INT, ercvdbgtab, 1, MPI_INT, proccomm) != MPI_SUCCESS) { errorPrint ("dgraphCoarsenBuild: communication error (3)"); return (1); } for (procnum = 0; procnum < grafptr->procglbnbr; procnum ++) { if (ercvdbgtab[procnum] != ercvcnttab[procnum]) { errorPrint ("dgraphCoarsenBuild: internal error (9)"); return (1); } } #endif /* SCOTCH_DEBUG_DGRAPH2 */ if (MPI_Alltoallv (esnddattab, esndcnttab, esnddsptab, GNUM_MPI, ercvdattab, ercvcnttab, ercvdsptab, GNUM_MPI, proccomm) != MPI_SUCCESS) { errorPrint ("dgraphCoarsenBuild: communication error (4)"); return (1); } for (procngbnum = 0; procngbnum < procngbnbr; procngbnum ++) ercvdsptab[procngbnum] = ercvdsptab[procngbtab[procngbnum]]; multloctax = coarptr->multloctab - grafptr->baseval; edlolocval = 1; coarvelolocsum = 0; coardegrlocmax = 0; coarvertloctax = coargrafptr->vertloctax; coarveloloctax = coargrafptr->veloloctax; coaredgeloctax = coargrafptr->edgeloctax; coaredloloctax = coargrafptr->edloloctax; for (coarvertlocnum = coaredgelocnum = grafptr->baseval, coarvertglbnum = multlocadj, coarvertlocnnd = coarvertlocnum + coargrafptr->vertlocnbr; coarvertlocnum < coarvertlocnnd; coarvertlocnum ++, coarvertglbnum ++) { Gnum coarvelolocval; Gnum vertlocnum; int i; coarvertloctax[coarvertlocnum] = coaredgelocnum; i = 0; coarvelolocval = 0; vertlocnum = multloctax[coarvertlocnum].vertglbnum[0] - vertlocadj; while (1) { /* Pseudo-infinite loop on both vertices of the multinode */ Gnum vertglbnum; Gnum edgelocnum; Gnum edgelocnnd; Gnum degrlocval; int procngbnum; int ercvidxnum; coarvelolocval += (veloloctax != NULL) ? veloloctax[vertlocnum] : 1; for (edgelocnum = vertloctax[vertlocnum], edgelocnnd = vendloctax[vertlocnum]; /* Loop on edges of first (and sometimes second) local mate */ edgelocnum < edgelocnnd; edgelocnum ++) { Gnum coarvertglbend; Gnum h; coarvertglbend = coargsttax[edgegsttax[edgelocnum]]; if (coarvertglbend == coarvertglbnum) /* If end of collapsed edge */ continue; if (edloloctax != NULL) edlolocval = edloloctax[edgelocnum]; for (h = (coarvertglbend * COARHASHPRIME) & coarhashmsk; ; h = (h + 1) & coarhashmsk) { if (coarhashtab[h].vertorgnum != coarvertglbnum) { /* If old slot */ coarhashtab[h].vertorgnum = coarvertglbnum; /* Mark it in reference array */ coarhashtab[h].vertendnum = coarvertglbend; coarhashtab[h].edgelocnum = coaredgelocnum; #ifdef SCOTCH_DEBUG_DGRAPH2 if (coaredgelocnum >= (edgelocnbr + coargrafptr->baseval)) { errorPrint ("dgraphCoarsenBuild: internal error (10)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ coaredgeloctax[coaredgelocnum] = coarvertglbend; /* One more edge created */ coaredloloctax[coaredgelocnum] = edlolocval; coaredgelocnum ++; break; /* Give up hashing */ } if (coarhashtab[h].vertendnum == coarvertglbend) { /* If coarse edge already exists */ coaredloloctax[coarhashtab[h].edgelocnum] += edlolocval; break; /* Give up hashing */ } } } if (i ++ > 0) /* If second local vertex has been processed, exit */ break; vertglbnum = multloctax[coarvertlocnum].vertglbnum[1]; if (vertglbnum >= 0) { /* If second multinode vertex is local */ if ((vertglbnum - vertlocadj) == vertlocnum) /* If single multinode */ break; vertlocnum = (vertglbnum - vertlocadj); continue; } edgelocnum = -2 - vertglbnum; multloctax[coarvertlocnum].vertglbnum[1] = edgeloctax[edgelocnum]; /* Set second vertex of multinode */ procngbnum = procgsttax[edgegsttax[edgelocnum]]; ercvidxnum = ercvdsptab[procngbnum]; degrlocval = ercvdattab[ercvidxnum ++]; coarvelolocval += (veloloctax != NULL) ? ercvdattab[ercvidxnum ++] : 1; while (degrlocval -- > 0) { Gnum coarvertglbend; Gnum h; coarvertglbend = ercvdattab[ercvidxnum ++]; if (edloloctax != NULL) edlolocval = ercvdattab[ercvidxnum ++]; if (coarvertglbend == coarvertglbnum) /* If end of collapsed edge */ continue; for (h = (coarvertglbend * COARHASHPRIME) & coarhashmsk; ; h = (h + 1) & coarhashmsk) { if (coarhashtab[h].vertorgnum != coarvertglbnum) { /* If old slot */ coarhashtab[h].vertorgnum = coarvertglbnum; /* Mark it in reference array */ coarhashtab[h].vertendnum = coarvertglbend; coarhashtab[h].edgelocnum = coaredgelocnum; #ifdef SCOTCH_DEBUG_DGRAPH2 if (coaredgelocnum >= (edgelocnbr + coargrafptr->baseval)) { errorPrint ("dgraphCoarsenBuild: internal error (11)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ coaredgeloctax[coaredgelocnum] = coarvertglbend; /* One more edge created */ coaredloloctax[coaredgelocnum] = edlolocval; coaredgelocnum ++; break; /* Give up hashing */ } if (coarhashtab[h].vertendnum == coarvertglbend) { /* If coarse edge already exists */ coargrafptr->edloloctax[coarhashtab[h].edgelocnum] += edlolocval; break; /* Give up hashing */ } } } ercvdsptab[procngbnum] = ercvidxnum; /* Write back updated receive index */ break; /* Exit loop after processing remote mate */ } coarvelolocsum += coarvelolocval; coarveloloctax[coarvertlocnum] = coarvelolocval; if (coardegrlocmax < (coaredgelocnum - coarvertloctax[coarvertlocnum])) coardegrlocmax = (coaredgelocnum - coarvertloctax[coarvertlocnum]); } coarvertloctax[coarvertlocnum] = coaredgelocnum; /* Set end of compact edge array */ coargrafptr->velolocsum = coarvelolocsum; coargrafptr->veloglbsum = grafptr->veloglbsum; coargrafptr->edgelocnbr = coargrafptr->edgelocsiz = coaredgelocnum - coargrafptr->baseval; coargrafptr->edgeloctax = memRealloc (coaredgeloctax + coargrafptr->baseval, coargrafptr->edgelocnbr * sizeof (Gnum)); coargrafptr->edgeloctax -= coargrafptr->baseval; coargrafptr->edloloctax = memRealloc (coaredloloctax + coargrafptr->baseval, coargrafptr->edgelocnbr * sizeof (Gnum)); coargrafptr->edloloctax -= coargrafptr->baseval; reduloctab[0] = coargrafptr->vertlocnbr; /* Get maximum over all processes */ reduloctab[1] = coargrafptr->edgelocnbr; reduloctab[2] = coardegrlocmax; /* Get local maximum degree */ reduloctab[3] = coargrafptr->edgelocnbr; if (dgraphAllreduceMaxSum (reduloctab, reduglbtab, 3, 1, proccomm) != 0) { errorPrint ("dgraphCoarsenBuild: communication error (5)"); return (1); } coargrafptr->vertglbmax = reduglbtab[0]; coargrafptr->edgeglbmax = reduglbtab[1]; coargrafptr->degrglbmax = reduglbtab[2]; /* It is now a real global maximum degree */ coargrafptr->edgeglbnbr = reduglbtab[3]; coargrafptr->edgeglbsmx = coargrafptr->edgeglbmax; return (0); } /***************************/ /* */ /* The coarsening routine. */ /* */ /***************************/ /* This routine coarsens the given fine distributed ** graph, as long as the coarsening ratio remains ** below some threshold value and the coarsened graph ** is not too small. ** If a multinode array is provided (*multlocptr != NULL), ** it must be of a size sufficient to hold multinode data ** in any configuration, including in the case of folding ** with duplication, where folded data is spread across ** floor(P/2) processes. ** It returns: ** - 0 : if the graph has been coarsened. ** - 1 : if the graph could not be coarsened. ** - 2 : on error. */ int dgraphCoarsen ( Dgraph * restrict const finegrafptr, /*+ Graph to coarsen +*/ Dgraph * restrict const coargrafptr, /*+ Coarse graph to build +*/ DgraphCoarsenMulti * restrict * const multlocptr, /*+ Pointer to un-based multinode array +*/ const Gnum passnbr, /*+ Number of coarsening passes to go +*/ const Gnum coarnbr, /*+ Minimum number of coarse vertices +*/ const double coarrat, /*+ Maximum contraction ratio +*/ const int flagval) /*+ Flag value +*/ { DgraphMatchData matedat; /* Matching state data; includes coarsening handling data */ Gnum vertrcvnbr; /* Overall number of vertices to be received from neighbors */ Gnum edgercvnbr; /* Overall number of edges to be received from neighbors */ Gnum vertsndnbr; /* Overall number of vertices to be sent to neighbors */ Gnum edgesndnbr; /* Overall number of edges to be sent to neighbors */ int cheklocval; int chekglbval; Gnum coarvertmax; Gnum passnum; int procnum; int o; #ifdef SCOTCH_DEBUG_DGRAPH1 if (coarrat < 0.5L) /* If impossible coarsening ratio wanted */ return (1); /* We will never succeed */ #endif /* SCOTCH_DEBUG_DGRAPH1 */ coarvertmax = (Gnum) ((double) finegrafptr->vertglbnbr * coarrat); /* Maximum number of coarse vertices */ if (coarvertmax < coarnbr) /* If there are too few vertices in graph */ return (1); /* It is useless to go any further */ if (dgraphGhst (finegrafptr) != 0) { /* Compute ghost edge array of fine graph if not already present */ errorPrint ("dgraphCoarsen: cannot compute ghost edge array"); return (2); } matedat.c.flagval = flagval; matedat.c.multloctab = *multlocptr; /* Propagate the provided multinode array or NULL if it has to be allocated */ cheklocval = dgraphCoarsenInit (&matedat.c, finegrafptr, coargrafptr); cheklocval |= dgraphMatchInit (&matedat, 0.5F); #ifdef SCOTCH_DEBUG_DGRAPH1 /* This communication cannot be covered by a useful one */ if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, finegrafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphCoarsen: communication error (1)"); return (2); } #else /* SCOTCH_DEBUG_DGRAPH1 */ chekglbval = cheklocval; #endif /* SCOTCH_DEBUG_DGRAPH1 */ if (chekglbval != 0) return (2); for (passnum = 0; passnum < passnbr; passnum ++) { ((passnum == 0) ? dgraphMatchHl : dgraphMatchHy) (&matedat); /* If first pass, process lightest vertices first */ if ((((finegrafptr->flagval & DGRAPHCOMMPTOP) != 0) ? dgraphMatchSyncPtop : dgraphMatchSyncColl) (&matedat) != 0) { errorPrint ("dgraphCoarsen: cannot perform matching"); dgraphMatchExit (&matedat); dgraphCoarsenExit (&matedat.c); return (2); } } dgraphMatchLy (&matedat); /* All remaining vertices are matched locally */ #ifdef SCOTCH_DEBUG_DGRAPH2 if (dgraphMatchCheck (&matedat) != 0) { errorPrint ("dgraphCoarsen: invalid matching"); dgraphMatchExit (&matedat); dgraphCoarsenExit (&matedat.c); return (2); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ dgraphMatchExit (&matedat); vertsndnbr = edgesndnbr = 0; for (procnum = 0; procnum < finegrafptr->procglbnbr; procnum ++) { vertsndnbr += matedat.c.dcntloctab[procnum].vertsndnbr; edgesndnbr += matedat.c.dcntloctab[procnum].edgesndnbr; matedat.c.dcntloctab[procnum].vertlocnbr = matedat.c.multlocnbr; } matedat.c.vertsndnbr = vertsndnbr; matedat.c.edgesndnbr = edgesndnbr; if (MPI_Alltoall (matedat.c.dcntloctab, 3, GNUM_MPI, matedat.c.dcntglbtab, 3, GNUM_MPI, finegrafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphCoarsen: communication error (2)"); return (2); } vertrcvnbr = edgercvnbr = 0; coargrafptr->procdsptab[0] = finegrafptr->baseval; /* Build vertex-to-process array */ for (procnum = 0; procnum < finegrafptr->procglbnbr; procnum ++) { Gnum proccntval; vertrcvnbr += matedat.c.dcntglbtab[procnum].vertsndnbr; edgercvnbr += matedat.c.dcntglbtab[procnum].edgesndnbr; proccntval = matedat.c.dcntglbtab[procnum].vertlocnbr; coargrafptr->proccnttab[procnum] = proccntval; coargrafptr->procdsptab[procnum + 1] = coargrafptr->procdsptab[procnum] + proccntval; } coargrafptr->vertlocnbr = matedat.c.multlocnbr; coargrafptr->vertglbnbr = coargrafptr->procdsptab[finegrafptr->procglbnbr] - finegrafptr->baseval; matedat.c.vertrcvnbr = vertrcvnbr; matedat.c.edgercvnbr = edgercvnbr; if (coargrafptr->vertglbnbr > coarvertmax) { /* If coarsening ratio not met */ dgraphCoarsenExit (&matedat.c); return (1); } if (dgraphCoarsenBuild (&matedat.c) != 0) { /* Build coarse graph */ dgraphCoarsenExit (&matedat.c); return (2); } #ifdef SCOTCH_DEBUG_DGRAPH2 if (dgraphCheck (coargrafptr) != 0) { /* Check graph consistency */ errorPrint ("dgraphCoarsen: inconsistent graph data"); dgraphFree (coargrafptr); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ matedat.c.multloctmp = NULL; /* So that it will not be freed */ dgraphCoarsenExit (&matedat.c); /* Free all other temporary arrays */ o = 0; /* Assume everything is now all right */ #ifdef PTSCOTCH_FOLD_DUP if (((flagval & DGRAPHCOARSENFOLDDUP) != 0) && /* If some form of folding is requested */ (coargrafptr->procglbnbr >= 2)) { /* And if there is need to it */ Dgraph coargrafdat; /* Coarse graph data before folding */ DgraphCoarsenMulti * coarmultptr; /* Pointer to folded multinode array */ MPI_Datatype coarmultype; MPI_Type_contiguous (2, GNUM_MPI, &coarmultype); /* Define type for MPI transfer */ MPI_Type_commit (&coarmultype); /* Commit new type */ coargrafdat = *coargrafptr; /* Copy unfolded coarse graph data to save area */ coarmultptr = NULL; /* Assume we will not get a multinode array */ if ((flagval & DGRAPHCOARSENFOLDDUP) == DGRAPHCOARSENFOLD) { /* Do a simple folding */ memSet (coargrafptr, 0, sizeof (Dgraph)); /* Also reset procglbnbr for unused processes */ o = dgraphFold (&coargrafdat, 0, coargrafptr, (void *) matedat.c.multloctab, (void **) (void *) &coarmultptr, coarmultype); } else { /* Do a duplicant-folding */ int loopval; int dumyval; o = dgraphFoldDup (&coargrafdat, coargrafptr, (void *) matedat.c.multloctab, (void **) (void *) &coarmultptr, coarmultype); loopval = intRandVal (finegrafptr->proclocnum + intRandVal (finegrafptr->proclocnum * 2 + 1) + 1); while (loopval --) /* Desynchronize pseudo-random generator across processes */ dumyval = intRandVal (2); } dgraphExit (&coargrafdat); /* Free unfolded graph */ MPI_Type_free (&coarmultype); if (*multlocptr == NULL) /* If unfolded multinode array was not user-provided, free it */ memFree (matedat.c.multloctab); *multlocptr = coarmultptr; /* Return folded multinode array or NULL */ } else /* No folding at all */ #endif /* PTSCOTCH_FOLD_DUP */ *multlocptr = matedat.c.multloctab; /* Return un-based pointer (maybe the same as initially user-provided) */ return (o); } scotch-6.0.4.dfsg/src/libscotch/hmesh_order_bl.h0000644002563400244210000000613111631447170024764 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2009,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh_order_bl.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the block splitting algorithm. **/ /** **/ /** DATES : # Version 4.0 : from : 28 sep 2002 **/ /** to 04 jan 2005 **/ /** # Version 5.1 : from : 01 oct 2009 **/ /** to : 04 nov 2010 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct HmeshOrderBlParam_ { Strat * strat; /*+ Ordering strategy +*/ INT cblkmin; /*+ Block splitting size +*/ } HmeshOrderBlParam; /* ** The function prototypes. */ #ifndef HMESH_ORDER_BL #define static #endif int hmeshOrderBl (const Hmesh * const, Order * const, const Gnum, OrderCblk * const, const HmeshOrderBlParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/vgraph_separate_th.c0000644002563400244210000001130111631447170025644 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : separate_th.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module thins a vertex separator. **/ /** **/ /** DATES : # Version 3.3 : from : 17 oct 1998 **/ /** to 17 oct 1998 **/ /** # Version 4.0 : from : 12 dec 2001 **/ /** to 06 jan 2002 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VGRAPH_SEPARATE_TH #include "module.h" #include "common.h" #include "graph.h" #include "vgraph.h" #include "vgraph_separate_th.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the bipartitioning. ** It returns: ** - 0 : if the bipartitioning could be computed. ** - !0 : on error. */ int vgraphSeparateTh ( Vgraph * const grafptr) { Gnum fronnbr; /* Current number of frontier vertices */ Gnum fronnum; /* Number of current frontier vertex */ Gnum commcut[3]; /* Cut count array ([3] for halo) */ fronnbr = grafptr->fronnbr; /* Get current number of frontier vertices */ for (fronnum = 0; fronnum < fronnbr; ) { Gnum vertnum; Gnum edgenum; vertnum = grafptr->frontab[fronnum]; /* Get vertex number */ commcut[0] = commcut[1] = commcut[2] = 0; for (edgenum = grafptr->s.verttax[vertnum]; edgenum < grafptr->s.vendtax[vertnum]; edgenum ++) commcut[grafptr->parttax[grafptr->s.edgetax[edgenum]]] ++; if (commcut[0] == 0) { grafptr->parttax[vertnum] = 1; grafptr->compload[1] += (grafptr->s.velotax == NULL) ? 1 : grafptr->s.velotax[vertnum]; grafptr->compsize[1] ++; grafptr->frontab[fronnum] = grafptr->frontab[-- fronnbr]; /* Replace frontier vertex by another */ } else if (commcut[1] == 0) { grafptr->parttax[vertnum] = 0; grafptr->compload[0] += (grafptr->s.velotax == NULL) ? 1 : grafptr->s.velotax[vertnum]; grafptr->compsize[0] ++; grafptr->frontab[fronnum] = grafptr->frontab[-- fronnbr]; /* Replace frontier vertex by another */ } else fronnum ++; /* Keep vertex in separator */ } grafptr->fronnbr = fronnbr; /* Set new frontier parameters */ grafptr->compload[2] = grafptr->s.velosum - (grafptr->compload[0] + grafptr->compload[1]); grafptr->comploaddlt = grafptr->compload[0] - grafptr->compload[1]; return (0); } scotch-6.0.4.dfsg/src/libscotch/dgraph_ghst.h0000644002563400244210000000663011631447171024307 0ustar trophimeutilisateurs du domaine/* Copyright 2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /**********************************************************/ /* */ /* NAME : dgraph_ghst.h */ /* */ /* AUTHOR : Francois PELLEGRINI */ /* Francois CHATENET (P0.0) */ /* Sebastien FOUCAULT (P0.0) */ /* Nicolas GICQUEL (P0.1) */ /* Jerome LACOSTE (P0.1) */ /* */ /* FUNCTION : Part of a parallel static mapper. */ /* These lines are the data declarations */ /* for the halo building routine. */ /* */ /* # Version P0.0 : from : 01 apr 1997 */ /* to 20 jun 1997 */ /* # Version P0.1 : from : 12 apr 1998 */ /* to 20 jun 1998 */ /* # Version 5.0 : from : 28 feb 2006 */ /* to 31 dec 2006 */ /* */ /**********************************************************/ /* ** The defines. */ /* procsidtab-related values. */ #define DGRAPHGHSTSIDMAX ((int) ((unsigned int) (1 << (sizeof (int) * 8 - 1)) - 2U)) /* Maximum leap value for procsidtab entries */ /* ** The type and structure definitions. */ /* Sort structure for ghost edges. */ typedef struct DgraphGhstSort_ { Gnum vertglbnum; /* Global end vertex number */ Gnum edgegstnum; /* Number of ghost edge */ } DgraphGhstSort; scotch-6.0.4.dfsg/src/libscotch/mesh_io.c0000644002563400244210000004125011631447170023427 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mesh_io.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles the source graph **/ /** input/output functions. **/ /** **/ /** DATES : # Version 4.0 : from : 05 nov 2002 **/ /** to 06 may 2004 **/ /** # Version 5.0 : from : 12 sep 2007 **/ /** to 27 feb 2008 **/ /** # Version 5.1 : from : 11 aug 2010 **/ /** to 11 aug 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define MESH_IO #include "module.h" #include "common.h" #include "graph.h" #include "graph_io.h" #include "mesh.h" #include "mesh_io.h" /******************************************/ /* */ /* These routines handle source mesh I/O. */ /* */ /******************************************/ /* This routine loads a source mesh from ** the given stream. ** Edge loads, whenever present, are ** always discarded. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int meshLoad ( Mesh * restrict const meshptr, /* Mesh structure to fill */ FILE * restrict const stream, /* Stream from which to read graph data */ const Gnum baseval) /* Base value (-1 means keep file base) */ { Gnum edgenum; /* Number of edges really allocated */ Gnum edgennd; Gnum vertnbr; Gnum velmnbr; /* Number of elements in mesh */ Gnum velmbas; /* Base index for element vertices */ Gnum vnodnbr; /* Number of nodes in mesh */ Gnum vnodbas; /* Base index for node vertices */ Gnum vlblmax; /* Maximum vertex label number */ Gnum vlblval; /* Value where to read vertex label */ Gnum velonbr; /* Size of vertex load array */ Gnum veloval; /* Value where to read vertex load */ Gnum vlblnbr; /* Size of vertex label array */ Gnum edloval; /* Value where to read edge load */ Gnum edgeval; /* Value where to read edge end */ Gnum baseadj; Gnum versval; Gnum degrmax; Gnum propval; char proptab[4]; Gnum vertbastab[2]; Gnum vertnndtab[2]; Gnum edgeadjtab[2]; int i; memSet (meshptr, 0, sizeof (Mesh)); if ((intLoad (stream, &versval) != 1) || /* Read version number */ (versval != 1)) { errorPrint ("meshLoad: bad input (1)"); return (1); } if ((intLoad (stream, &velmnbr) != 1) || /* Read rest of header */ (intLoad (stream, &vnodnbr) != 1) || (intLoad (stream, &meshptr->edgenbr) != 1) || (intLoad (stream, &velmbas) != 1) || (intLoad (stream, &vnodbas) != 1) || (intLoad (stream, &propval) != 1) || (velmnbr < 0) || (vnodnbr < 0) || (velmbas < 0) || (vnodbas < 0) || (propval < 0) || (propval > 111) || (((velmbas + velmnbr) != vnodbas) && ((vnodbas + vnodnbr) != velmbas))) { errorPrint ("meshLoad: bad input (2)"); return (1); } sprintf (proptab, "%3.3d", (int) propval); /* Compute file properties */ proptab[0] -= '0'; /* Vertex labels flag */ proptab[1] -= '0'; /* Edge weights flag */ proptab[2] -= '0'; /* Vertex loads flag */ baseadj = MIN (velmbas, vnodbas); /* Get file graph base value */ if (baseval == -1) { /* If keep file graph base */ meshptr->baseval = baseadj; /* Set graph base as file base */ baseadj = 0; /* No base adjustment needed */ } else { /* If set graph base */ meshptr->baseval = baseval; /* Set wanted graph base */ baseadj = baseval - baseadj; /* Update base adjust */ } meshptr->flagval = MESHFREEVERT | MESHVERTGROUP; /* Edge array grouped with vertex array */ meshptr->velmnbr = velmnbr; meshptr->velmbas = velmbas + baseadj; meshptr->velmnnd = velmnbr + (velmbas + baseadj); meshptr->vnodnbr = vnodnbr; meshptr->vnodbas = vnodbas + baseadj; meshptr->vnodnnd = vnodnbr + (vnodbas + baseadj); vertnbr = velmnbr + vnodnbr; velonbr = (proptab[2] != 0) ? vertnbr : 0; vlblnbr = (proptab[0] != 0) ? vertnbr : 0; if (memAllocGroup ((void **) (void *) &meshptr->verttax, (size_t) ((vertnbr + 1) * sizeof (Gnum)), &meshptr->vlbltax, (size_t) ( vlblnbr * sizeof (Gnum)), &meshptr->velotax, (size_t) ( velonbr * sizeof (Gnum)), /* Allocate single array for both element and node vertices */ &meshptr->edgetax, (size_t) ( meshptr->edgenbr * sizeof (Gnum)), NULL) == NULL) { /* Edge array grouped with vertex arrays */ errorPrint ("meshLoad: out of memory (1)"); meshFree (meshptr); return (1); } meshptr->verttax -= meshptr->baseval; meshptr->vendtax = meshptr->verttax + 1; /* Use compact vertex array */ meshptr->velotax = (velonbr != 0) ? (meshptr->velotax - meshptr->baseval) : NULL; /* Store based load array access in velotax */ meshptr->vnlotax = meshptr->velotax; meshptr->vlbltax = (vlblnbr != 0) ? (meshptr->vlbltax - meshptr->baseval) : NULL; meshptr->velosum = meshptr->velmnbr; /* Assume element and node vertices not weighted */ meshptr->vnlosum = meshptr->vnodnbr; meshptr->edgetax -= meshptr->baseval; degrmax = 0; edgennd = meshptr->edgenbr + meshptr->baseval; edgenum = meshptr->baseval; /* No edges allocated yet */ vlblmax = vertnbr + meshptr->baseval - 1; /* No vertex labels known */ if (meshptr->velmbas <= meshptr->vnodbas) { /* If elements first */ vertbastab[0] = meshptr->velmbas; vertnndtab[0] = meshptr->velmnnd; edgeadjtab[0] = meshptr->vnodbas - meshptr->baseval; vertbastab[1] = meshptr->vnodbas; vertnndtab[1] = meshptr->vnodnnd; edgeadjtab[1] = meshptr->velmbas - meshptr->baseval; } else { vertbastab[0] = meshptr->vnodbas; vertnndtab[0] = meshptr->vnodnnd; edgeadjtab[0] = meshptr->velmbas - meshptr->baseval; vertbastab[1] = meshptr->velmbas; vertnndtab[1] = meshptr->velmnnd; edgeadjtab[1] = meshptr->vnodbas - meshptr->baseval; } for (i = 0; i < 2; i ++) { /* For both kinds of vertices */ Gnum vertbas; Gnum vertnnd; Gnum edgeadj; Gnum vertnum; Gnum velosum; Gnum velomax; vertbas = vertbastab[i]; vertnnd = vertnndtab[i]; edgeadj = edgeadjtab[i]; velosum = 0; velomax = 1; /* Assume vertex loads all equal to 1 */ for (vertnum = vertbas; vertnum < vertnnd; vertnum ++) { /* For all vertices of same kind */ Gnum degrval; if (meshptr->vlbltax != NULL) { /* If must read label */ if (intLoad (stream, &vlblval) != 1) { /* Read label data */ errorPrint ("meshLoad: bad input (3)"); meshFree (meshptr); return (1); } meshptr->vlbltax[vertnum] = vlblval + vertbas + baseadj; /* Adjust vertex label */ if (meshptr->vlbltax[vertnum] > vlblmax) /* Get maximum vertex label */ vlblmax = meshptr->vlbltax[vertnum]; } if (proptab[2] != 0) { /* If must read vertex load */ if ((intLoad (stream, &veloval) != 1) || /* Read vertex load data */ (veloval < 1)) { errorPrint ("meshLoad: bad input (4)"); meshFree (meshptr); return (1); } if (veloval > velomax) velomax = veloval; meshptr->velotax[vertnum] = veloval; velosum += veloval; } if (intLoad (stream, °rval) != 1) { /* Read vertex degree */ errorPrint ("meshLoad: bad input (5)"); meshFree (meshptr); return (1); } if (degrmax < degrval) /* Set maximum degree */ degrmax = degrval; meshptr->verttax[vertnum] = edgenum; /* Set index in edge array */ degrval += edgenum; if (degrval > edgennd) { /* Check if edge array overflows */ errorPrint ("meshLoad: invalid arc count (1)"); meshFree (meshptr); return (1); } for ( ; edgenum < degrval; edgenum ++) { if (proptab[1] != 0) { /* If must read edge load */ if (intLoad (stream, &edloval) != 1) { /* Read edge load data (useless) */ errorPrint ("meshLoad: bad input (6)"); meshFree (meshptr); return (1); } } if (intLoad (stream, &edgeval) != 1) { /* Read edge data */ errorPrint ("meshLoad: bad input (7)"); meshFree (meshptr); return (1); } meshptr->edgetax[edgenum] = edgeval + edgeadj; } } if (vertbastab[i] == meshptr->velmbas) { /* If elements are processed */ if (velomax == 1) /* If element loads not significant */ meshptr->velotax = NULL; else meshptr->velosum = velosum; } else { if (velomax == 1) /* If node loads not significant */ meshptr->vnlotax = NULL; else meshptr->vnlosum = velosum; } } meshptr->verttax[vertnbr + meshptr->baseval] = meshptr->edgenbr + meshptr->baseval; /* Set end of edge array */ if (edgenum != edgennd) { /* Check if number of edges is valid */ errorPrint ("meshLoad: invalid arc count (2)"); meshFree (meshptr); return (1); } meshptr->degrmax = degrmax; if (meshptr->vlbltax != NULL) { /* If vertex label renaming necessary */ if (graphLoad2 (meshptr->baseval, vertnbr + meshptr->baseval, meshptr->verttax, /* Rename edge ends */ meshptr->vendtax, meshptr->edgetax, vlblmax, meshptr->vlbltax) != 0) { errorPrint ("meshLoad: cannot relabel vertices"); meshFree (meshptr); return (1); } } #ifdef SCOTCH_DEBUG_MESH2 if (meshCheck (meshptr) != 0) { /* Check mesh consistency */ errorPrint ("meshLoad: inconsistent mesh data"); meshFree (meshptr); return (1); } #endif /* SCOTCH_DEBUG_MESH2 */ return (0); } /* This routine saves a source mesh to ** the given stream. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int meshSave ( const Mesh * restrict const meshptr, FILE * restrict const stream) { char propstr[4]; /* Property string */ Gnum vertbastab[2]; Gnum vertnndtab[2]; Gnum * velotabtab[2]; Gnum edgeadjtab[2]; int i; int o; propstr[0] = (meshptr->vlbltax != NULL) ? '1' : '0'; /* Set property string */ propstr[1] = '0'; /* No edge loads written */ propstr[2] = ((meshptr->velotax != NULL) || (meshptr->vnlotax != NULL)) ? '1' : '0'; propstr[3] = '\0'; if (fprintf (stream, "1\n" GNUMSTRING "\t" GNUMSTRING "\t" GNUMSTRING "\n" GNUMSTRING "\t" GNUMSTRING "\t%3s\n", /* Write file header */ (Gnum) meshptr->velmnbr, (Gnum) meshptr->vnodnbr, (Gnum) meshptr->edgenbr, (Gnum) meshptr->velmbas, (Gnum) meshptr->vnodbas, propstr) == EOF) { errorPrint ("meshSave: bad output (1)"); return (1); } vertbastab[0] = meshptr->baseval; vertnndtab[1] = meshptr->velmnbr + meshptr->vnodnbr + meshptr->baseval; if (meshptr->velmbas <= meshptr->vnodbas) { /* If elements first */ vertnndtab[0] = meshptr->velmnnd; velotabtab[0] = meshptr->velotax; edgeadjtab[0] = meshptr->vnodbas - meshptr->baseval; vertbastab[1] = meshptr->vnodbas; velotabtab[0] = meshptr->vnlotax; edgeadjtab[1] = meshptr->velmbas - meshptr->baseval; } else { vertnndtab[0] = meshptr->vnodnnd; velotabtab[0] = meshptr->vnlotax; edgeadjtab[0] = meshptr->velmbas - meshptr->baseval; vertbastab[1] = meshptr->velmbas; velotabtab[1] = meshptr->velotax; edgeadjtab[1] = meshptr->vnodbas - meshptr->baseval; } for (i = 0; i < 2; i ++) { /* For both kinds of vertices */ Gnum vertbas; Gnum vertnnd; Gnum * restrict velotax; Gnum edgeadj; Gnum vertnum; vertbas = vertbastab[i]; vertnnd = vertnndtab[i]; velotax = velotabtab[i]; edgeadj = edgeadjtab[i]; for (vertnum = vertbas, o = 0; (vertnum < vertnnd) && (o == 0); vertnum ++) { Gnum edgenum; if (meshptr->vlbltax != NULL) /* Write vertex label if necessary */ o = (fprintf (stream, GNUMSTRING "\t", (Gnum) meshptr->vlbltax[vertnum]) == EOF); if (propstr[2] != '0') /* Write vertex load if necessary */ o |= (fprintf (stream, GNUMSTRING "\t", (Gnum) ((velotax != NULL) ? velotax[vertnum] : 1)) == EOF); o |= (fprintf (stream, GNUMSTRING, (Gnum) (meshptr->vendtax[vertnum] - meshptr->verttax[vertnum])) == EOF); /* Write vertex degree */ for (edgenum = meshptr->verttax[vertnum]; (edgenum < meshptr->vendtax[vertnum]) && (o == 0); edgenum ++) { o |= (putc ('\t', stream) == EOF); o |= (intSave (stream, /* Write edge end */ (meshptr->vlbltax != NULL) ? meshptr->vlbltax[meshptr->edgetax[edgenum]] : meshptr->edgetax[edgenum] - edgeadj) != 1); } o |= (putc ('\n', stream) == EOF); } } if (o != 0) errorPrint ("meshSave: bad output (2)"); return (o); } scotch-6.0.4.dfsg/src/libscotch/graph_io_chac.c0000644002563400244210000003331212225614644024554 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010,2013 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : graph_io_chac.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the I/O routines **/ /** for handling the Chaco graph format. **/ /** **/ /** DATES : # Version 3.2 : from : 06 nov 1997 **/ /** to 26 may 1998 **/ /** # Version 3.3 : from : 13 dec 1998 **/ /** to 24 dec 1998 **/ /** # Version 3.4 : from : 05 oct 1999 **/ /** to : 04 feb 2000 **/ /** # Version 4.0 : from : 18 dec 2001 **/ /** to 19 jan 2004 **/ /** # Version 5.0 : from : 04 feb 2007 **/ /** to 21 may 2008 **/ /** # Version 5.1 : from : 02 dec 2008 **/ /** to 11 aug 2010 **/ /** # Version 6.0 : from : 10 oct 2013 **/ /** to 10 oct 2013 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GRAPH_IO_CHAC #include "module.h" #include "common.h" #include "geom.h" #include "graph.h" /* This routine loads the geometrical graph ** in the Chaco graph format, and allocates ** the proper structures. ** - 0 : on success. ** - !0 : on error. */ int graphGeomLoadChac ( Graph * restrict const grafptr, /* Graph to load */ Geom * restrict const geomptr, /* Geometry to load */ FILE * const filesrcptr, /* Topological data */ FILE * const filegeoptr, /* No use */ const char * const dataptr) /* No use */ { char chalinetab[80]; /* Header line */ long chavertnbr; /* Number of vertices */ Gnum chavertnum; /* Number of vertex read */ long chaedgenbr; /* Number of edges */ long chaflagval; /* Flag on numeric form */ char chaflagstr[4]; /* Flag for optional data */ int chabuffcar; /* Buffer for line processing */ Gnum edgenum; Gnum edlosum; Gnum vertnum; Gnum velosum; Gnum vlblmax; Gnum degrmax; do { /* Skip comment lines */ chabuffcar = getc (filesrcptr); /* Read first character */ if (chabuffcar == '%') { /* If comment line */ fscanf (filesrcptr, "%*[^\n]"); /* Purge line */ getc (filesrcptr); /* Purge newline */ } } while (chabuffcar == '%'); ungetc (chabuffcar, filesrcptr); chaflagval = 0; if ((fscanf (filesrcptr, "%79[^\n]%*[^\n]", chalinetab) != 1) || /* Read graph header */ (sscanf (chalinetab, "%ld%ld%ld", &chavertnbr, &chaedgenbr, &chaflagval) < 2)) { errorPrint ("graphGeomLoadChac: bad input (1)"); return (1); } getc (filesrcptr); /* Purge newline (cannot be merged with above fscanf) */ chaflagstr[0] = /* Pre-set flag array */ chaflagstr[1] = chaflagstr[2] = chaflagstr[3] = '\0'; chaflagstr[0] = '0' + ((chaflagval / 100) % 10); /* Set the flags */ chaflagstr[1] = '0' + ((chaflagval / 10) % 10); chaflagstr[2] = '0' + ((chaflagval) % 10); grafptr->flagval = GRAPHFREETABS; grafptr->baseval = 1; /* Chaco graphs are based */ grafptr->vertnbr = chavertnbr; grafptr->vertnnd = chavertnbr + 1; grafptr->edgenbr = chaedgenbr * 2; /* We are counting arcs */ if (((grafptr->verttax = (Gnum *) memAlloc (grafptr->vertnnd * sizeof (Gnum))) == NULL) || ((grafptr->edgetax = (Gnum *) memAlloc (grafptr->edgenbr * sizeof (Gnum))) == NULL)) { errorPrint ("graphGeomLoadChac: out of memory (1)"); if (grafptr->verttax != NULL) memFree (grafptr->verttax); return (1); } grafptr->edgetax -= grafptr->baseval; grafptr->verttax -= grafptr->baseval; grafptr->vendtax = grafptr->verttax + 1; if (chaflagstr[0] != '0') { if ((grafptr->vlbltax = (Gnum *) memAlloc (chavertnbr * sizeof (Gnum))) == NULL) { errorPrint ("graphGeomLoadChac: out of memory (2)"); memFree (grafptr); return (1); } grafptr->vlbltax -= grafptr->baseval; } velosum = grafptr->vertnbr; /* Assume no vertex loads */ if (chaflagstr[1] != '0') { if ((grafptr->velotax = (Gnum *) memAlloc (chavertnbr * sizeof (Gnum))) == NULL) { errorPrint ("graphGeomLoadChac: out of memory (3)"); memFree (grafptr); return (1); } grafptr->velotax -= grafptr->baseval; velosum = 0; } edlosum = grafptr->edgenbr; if (chaflagstr[2] != '0') { if ((grafptr->edlotax = (Gnum *) memAlloc (grafptr->edgenbr * sizeof (Gnum))) == NULL) { errorPrint ("graphGeomLoadChac: out of memory (4)"); memFree (grafptr); return (1); } grafptr->edlotax -= grafptr->baseval; edlosum = 0; } for (vertnum = edgenum = grafptr->baseval, degrmax = vlblmax = 0; vertnum < grafptr->vertnnd; vertnum ++) { do { /* Skip comment lines */ chabuffcar = getc (filesrcptr); /* Read first character */ if (chabuffcar == '%') { /* If comment line */ fscanf (filesrcptr, "%*[^\n]"); /* Purge line */ getc (filesrcptr); /* Purge newline */ } } while (chabuffcar == '%'); ungetc (chabuffcar, filesrcptr); /* Put character back to filesrcptr */ if (grafptr->vlbltax != NULL) { if ((intLoad (filesrcptr, &grafptr->vlbltax[vertnum]) != 1) || (grafptr->vlbltax[vertnum] < 1) || (grafptr->vlbltax[vertnum] > chavertnbr)) { errorPrint ("graphGeomLoadChac: bad input (2)"); graphFree (grafptr); return (1); } if (grafptr->vlbltax[vertnum] > vlblmax) vlblmax = grafptr->vlbltax[vertnum]; } if (grafptr->velotax != NULL) { if ((intLoad (filesrcptr, &grafptr->velotax[vertnum]) != 1) || (grafptr->velotax[vertnum] < 1)) { errorPrint ("graphGeomLoadChac: bad input (3)"); graphFree (grafptr); return (1); } velosum += grafptr->velotax[vertnum]; } grafptr->verttax[vertnum] = edgenum; /* Set based edge array index */ while (1) { /* Read graph edges */ fscanf (filesrcptr, "%*[ \t\r]"); /* Skip white spaces except '\n' */ chabuffcar = getc (filesrcptr); /* Read next char */ if (chabuffcar == EOF) /* If end of file reached */ chabuffcar = '\n'; /* Indicate line as complete */ if (chabuffcar == '\n') /* Exit loop if line is complete */ break; ungetc (chabuffcar, filesrcptr); /* Else put character back to stream */ if ((intLoad (filesrcptr, &chavertnum) != 1) || (chavertnum < 1) || (chavertnum > chavertnbr) || ((grafptr->edlotax != NULL) && ((intLoad (filesrcptr, &grafptr->edlotax[edgenum]) != 1) || (edlosum += grafptr->edlotax[edgenum], grafptr->edlotax[edgenum] < 1)))) { errorPrint ("graphGeomLoadChac: bad input (4)"); graphFree (grafptr); return (1); } if (edgenum > (grafptr->edgenbr + grafptr-> baseval)) { /* Test edge array overflow */ errorPrint ("graphGeomLoadChac: bad input (5)"); graphFree (grafptr); return (1); } grafptr->edgetax[edgenum ++] = chavertnum; } if ((edgenum - grafptr->verttax[vertnum]) > degrmax) degrmax = edgenum - grafptr->verttax[vertnum]; } grafptr->verttax[vertnum] = edgenum; /* Set end of based vertex array */ grafptr->velosum = velosum; grafptr->edlosum = edlosum; grafptr->degrmax = degrmax; if (grafptr->vlbltax != NULL) { /* If graph has labels */ if (graphLoad2 (grafptr->baseval, grafptr->vertnnd, /* Un-label graph data */ grafptr->verttax, grafptr->vendtax, grafptr->edgetax, vlblmax, grafptr->vlbltax) != 0) { errorPrint ("graphGeomLoadChac: cannot relabel graph"); graphFree (grafptr); return (1); } } #ifdef SCOTCH_DEBUG_GRAPH2 if (graphCheck (grafptr) != 0) { /* Check graph consistency */ errorPrint ("graphGeomLoadChac: internal error"); graphFree (grafptr); return (1); } #endif /* SCOTCH_DEBUG_GRAPH2 */ return (0); } /* This routine saves the geometrical graph ** in the Chaco graph format. ** It returns: ** - 0 : on succes ** - !0 : on error. */ int graphGeomSaveChac ( const Graph * restrict const grafptr, /* Graph to save */ const Geom * restrict const geomptr, /* Geometry to save */ FILE * const filesrcptr, /* Topological data */ FILE * const filegeoptr, /* No use */ const char * const dataptr) /* No use */ { Gnum baseadj; /* Base adjustment */ Gnum vertnum; /* Current vertex */ Gnum edgenum; /* Current edge */ char * sepaptr; /* Separator string */ int o; baseadj = 1 - grafptr->baseval; /* Output base is always 1 */ o = (fprintf (filesrcptr, GNUMSTRING "\t" GNUMSTRING "\t%c%c%c\n", /* Write graph header */ (Gnum) grafptr->vertnbr, (Gnum) (grafptr->edgenbr / 2), ((grafptr->vlbltax != NULL) ? '1' : '0'), ((grafptr->velotax != NULL) ? '1' : '0'), ((grafptr->edlotax != NULL) ? '1' : '0')) < 0); for (vertnum = grafptr->baseval; (o == 0) && (vertnum < grafptr->vertnnd); vertnum ++) { sepaptr = ""; /* Start lines as is */ if (grafptr->vlbltax != NULL) { o |= (fprintf (filesrcptr, GNUMSTRING, (Gnum) (grafptr->vlbltax[vertnum] + baseadj)) < 0); sepaptr = "\t"; } if (grafptr->velotax != NULL) { o |= (fprintf (filesrcptr, "%s" GNUMSTRING, sepaptr, (Gnum) grafptr->velotax[vertnum]) < 0); sepaptr = "\t"; } for (edgenum = grafptr->verttax[vertnum]; (o == 0) && (edgenum < grafptr->vendtax[vertnum]); edgenum ++) { if (grafptr->vlbltax != NULL) o |= (fprintf (filesrcptr, "%s" GNUMSTRING, sepaptr, (Gnum) (grafptr->vlbltax[grafptr->edgetax[edgenum]] + baseadj)) < 0); else o |= (fprintf (filesrcptr, "%s" GNUMSTRING, sepaptr, (Gnum) (grafptr->edgetax[edgenum] + baseadj)) < 0); if (grafptr->edlotax != NULL) o |= (fprintf (filesrcptr, " " GNUMSTRING, (Gnum) grafptr->edlotax[edgenum]) < 0); sepaptr = "\t"; } o |= (fprintf (filesrcptr, "\n") < 0); } if (o != 0) errorPrint ("graphGeomSaveChac: bad output"); return (o); } scotch-6.0.4.dfsg/src/libscotch/hgraph_induce.c0000644002563400244210000003644512473142131024610 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010,2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hgraph_induce.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles the halo source **/ /** graph subgraph-making functions. **/ /** **/ /** DATES : # Version 4.0 : from : 02 jan 2002 **/ /** to 25 feb 2004 **/ /** # Version 5.0 : from : 19 dec 2006 **/ /** to 11 jun 2008 **/ /** # Version 5.1 : from : 24 oct 2010 **/ /** to 24 oct 2010 **/ /** # Version 6.0 : from : 27 mar 2012 **/ /** to 07 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HGRAPH #define HGRAPH_INDUCE #include "module.h" #include "common.h" #include "graph.h" #include "hgraph.h" #include "hgraph_induce.h" /*********************************************/ /* */ /* These routines handle halo source graphs. */ /* */ /*********************************************/ /* This routine builds the graph induced ** by the original graph and the list of ** selected vertices. ** The induced vnumtab array is the list ** array if the original graph does not have ** a vnumtab, or the proper subset of the ** original vnumtab else. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int hgraphInduceList ( const Hgraph * restrict const orggrafptr, /* Pointer to original graph */ const VertList * restrict const orglistptr, /* Pointer to vertex list */ const Gnum orghalonbr, /* Upper bound of number of vertices in halo */ Hgraph * restrict const indgrafptr) /* Pointer to induced subgraph */ { Gnum * restrict orgindxtax; /* Original to induced vertex number translation */ Gnum * restrict indedgetab; /* Origin of induced graph edge arrays */ Gnum indvertnbr; /* Number of vertices in induced graph */ Gnum indvertnum; /* Number of current vertex in induced graph */ Gnum indvelosiz; Gnum indedgenbr; /* (Approximate) number of edges in induced graph */ Gnum indedgesiz; /* (Approximate) size of edge and edge load arrays */ memSet (indgrafptr, 0, sizeof (Hgraph)); /* Pre-initialize graph fields */ indgrafptr->s.flagval = GRAPHFREETABS | GRAPHVERTGROUP | GRAPHEDGEGROUP; indgrafptr->s.baseval = orggrafptr->s.baseval; indvertnbr = orglistptr->vnumnbr + orghalonbr; /* Compute upper bound on number of vertices */ indvelosiz = (orggrafptr->s.velotax != NULL) ? indvertnbr : 0; if (memAllocGroup ((void **) (void *) &indgrafptr->s.verttax, (size_t) ((indvertnbr + 1) * sizeof (Gnum)), &indgrafptr->vnhdtax, (size_t) ( orglistptr->vnumnbr * sizeof (Gnum)), /* Put closest to beginning of array because no padding after */ &indgrafptr->s.velotax, (size_t) ( indvertnbr * sizeof (Gnum)), &indgrafptr->s.vnumtax, (size_t) ( indvertnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("hgraphInduceList: out of memory (1)"); /* Allocate induced graph structure */ return (1); } memCpy (indgrafptr->s.vnumtax, orglistptr->vnumtab, orglistptr->vnumnbr * sizeof (Gnum)); /* Copy vertex number array from list */ indgrafptr->s.velotax = (orggrafptr->s.velotax != NULL) ? (indgrafptr->s.velotax - indgrafptr->s.baseval) : NULL; indgrafptr->s.verttax -= indgrafptr->s.baseval; indgrafptr->s.vnumtax -= indgrafptr->s.baseval; indgrafptr->vnhdtax -= indgrafptr->s.baseval; indgrafptr->vnohnbr = orglistptr->vnumnbr; indgrafptr->vnohnnd = orglistptr->vnumnbr + indgrafptr->s.baseval; indedgenbr = ((orggrafptr->s.degrmax > 0) && (indvertnbr < (orggrafptr->s.edgenbr / orggrafptr->s.degrmax))) /* Choose best upper bound on number of edges (avoid multiply overflow) */ ? (indvertnbr * orggrafptr->s.degrmax) : orggrafptr->s.edgenbr; indedgesiz = (orggrafptr->s.edlotax != NULL) ? indedgenbr * 2 : indedgenbr; /* Account for edge load array size if graph has edge weights */ if (memAllocGroup ((void **) (void *) /* If cannot allocate edge arrays with approximation */ &indedgetab, (size_t) (indedgesiz * sizeof (Gnum)), &orgindxtax, (size_t) (orggrafptr->s.vertnbr * sizeof (Gnum)), NULL) == NULL) { indedgenbr = hgraphInduce3 (orggrafptr, orglistptr); /* Count real number of edges */ indedgesiz = (orggrafptr->s.edlotax != NULL) ? indedgenbr * 2 : indedgenbr; /* Account for edge load array size if graph has edge weights */ if ((indedgenbr < 0) || /* If cannot compute real number of edges */ (memAllocGroup ((void **) (void *) /* Or cannot allocate edge arrays with real values */ &indedgetab, (size_t) (indedgesiz * sizeof (Gnum)), &orgindxtax, (size_t) (orggrafptr->s.vertnbr * sizeof (Gnum)), NULL) == NULL)) { errorPrint ("hgraphInduceList: out of memory (2)"); hgraphExit (indgrafptr); return (1); } } memSet (orgindxtax, ~0, orggrafptr->s.vertnbr * sizeof (Gnum)); /* Preset index array */ orgindxtax -= orggrafptr->s.baseval; /* Base access to orgindxtab */ for (indvertnum = indgrafptr->s.baseval; indvertnum < indgrafptr->vnohnnd; indvertnum ++) /* For all non-halo vertices */ orgindxtax[indgrafptr->s.vnumtax[indvertnum]] = indvertnum; /* Mark selected vertices */ return (hgraphInduce2 (orggrafptr, orgindxtax, indgrafptr, indedgenbr, indedgetab)); } /* This routine finalizes the building of the ** halo graph induced by the original halo graph. ** Vertices belonging to the old halo remain to ** be numbered. ** It returns: ** - 0 : on success. ** - !0 : on error. */ static int hgraphInduce2 ( const Hgraph * restrict const orggrafptr, /* Pointer to original graph */ Gnum * restrict const orgindxtax, /* Array of numbers of selected vertices */ Hgraph * restrict const indgrafptr, /* Pointer to induced graph */ const Gnum indedgenbr, /* (Approximate) number of edges in induced graph */ Gnum * restrict const indedgetab) /* Pointer to pre-allocated space for edge arrays */ { void * restrict indedgetnd; /* End of compacted edge array */ Gnum indvertnum; /* Current vertex number in induced halo graph */ indedgetnd = memOffset (indedgetab, &indgrafptr->s.edgetax, (size_t) (indedgenbr * sizeof (Gnum)), NULL); indgrafptr->s.edgetax = indedgetab - indgrafptr->s.baseval; #ifdef SCOTCH_DEBUG_HGRAPH2 if (indedgetnd > (void *) (orgindxtax + orggrafptr->s.baseval)) { errorPrint ("hgraphInduce2: invalid edge array size (1)"); hgraphExit (indgrafptr); return (1); } #endif /* SCOTCH_DEBUG_HGRAPH2 */ if (orggrafptr->s.edlotax != NULL) { size_t indedlooftval; /* Offset of edge load array with respect to edge array */ indedgetnd = memOffset (indedgetnd, &indgrafptr->s.edlotax, (size_t) (indedgenbr * sizeof (Gnum)), NULL); indgrafptr->s.edlotax -= indgrafptr->s.baseval; #ifdef SCOTCH_DEBUG_HGRAPH2 if (indedgetnd > (void *) (orgindxtax + orggrafptr->s.baseval)) { errorPrint ("hgraphInduce2: invalid edge array size (2)"); hgraphExit (indgrafptr); /* Indedgetab is now freed as part of indgrafptr */ return (1); } #endif /* SCOTCH_DEBUG_HGRAPH2 */ hgraphInduce2L (orggrafptr, orgindxtax, indgrafptr); indedlooftval = indgrafptr->s.edlotax - indgrafptr->s.edgetax; memReallocGroup ((void *) indedgetab, /* Implicitely free orgindxtab */ &indgrafptr->s.edgetax, (size_t) (indedgenbr * sizeof (Gnum)), /* Keep first offset as estimated number of edges */ &indgrafptr->s.edlotax, (size_t) (indgrafptr->s.edgenbr * sizeof (Gnum)), /* Use real number of edges for second array */ NULL); indgrafptr->s.edgetax -= indgrafptr->s.baseval; indgrafptr->s.edlotax = indgrafptr->s.edgetax + indedlooftval; /* Use old index into old array as new index */ } else { hgraphInduce2U (orggrafptr, orgindxtax, indgrafptr); indgrafptr->s.edgetax = memRealloc ((void *) indedgetab, indgrafptr->s.edgenbr * sizeof (Gnum)); /* Use real number of edges, implicitely free orgindxtab */ indgrafptr->s.edgetax -= indgrafptr->s.baseval; } indgrafptr->s.vendtax = indgrafptr->s.verttax + 1; /* Use compact representation of arrays */ indgrafptr->levlnum = orggrafptr->levlnum + 1; /* Induced subgraph is one level below */ if (orggrafptr->s.vnumtax != NULL) { /* Adjust vnumtax */ const Gnum * restrict const orgvnumtax = orggrafptr->s.vnumtax; Gnum * restrict const indvnumtax = indgrafptr->s.vnumtax; for (indvertnum = indgrafptr->s.baseval; indvertnum < indgrafptr->s.vertnnd; indvertnum ++) indvnumtax[indvertnum] = orgvnumtax[indvnumtax[indvertnum]]; } #ifdef SCOTCH_DEBUG_HGRAPH2 if (hgraphCheck (indgrafptr) != 0) { /* Check graph consistency */ errorPrint ("hgraphInduce2: inconsistent graph data"); hgraphExit (indgrafptr); return (1); } #endif /* SCOTCH_DEBUG_HGRAPH2 */ return (0); } #define HGRAPHINDUCE2U #define HGRAPHINDUCE2NAME hgraphInduce2U #define HGRAPHINDUCE2EDLOINIT(e) #define HGRAPHINDUCE2EDLOSUM indgrafptr->s.edgenbr #define HGRAPHINDUCE2ENOHINIT #define HGRAPHINDUCE2ENOHSUM indgrafptr->enohnbr #include "hgraph_induce_edge.c" #undef HGRAPHINDUCE2NAME #undef HGRAPHINDUCE2EDLOINIT #undef HGRAPHINDUCE2EDLOSUM #undef HGRAPHINDUCE2ENOHINIT #undef HGRAPHINDUCE2ENOHSUM #undef HGRAPHINDUCE2U #define HGRAPHINDUCE2L #define HGRAPHINDUCE2NAME hgraphInduce2L #define HGRAPHINDUCE2EDLOINIT(e) indedlosum += indedlotax[e] = orgedlotax[orgedgenum] #define HGRAPHINDUCE2EDLOSUM indedlosum #define HGRAPHINDUCE2ENOHINIT indenohsum += orgedlotax[orgedgenum] #define HGRAPHINDUCE2ENOHSUM indenohsum #include "hgraph_induce_edge.c" #undef HGRAPHINDUCE2NAME #undef HGRAPHINDUCE2EDLOINIT #undef HGRAPHINDUCE2EDLOSUM #undef HGRAPHINDUCE2ENOHINIT #undef HGRAPHINDUCE2ENOHSUM #undef HGRAPHINDUCE2L /* This routine computes the exact number of edges ** required to build the induced halo subgraph. It ** is used when larger approximations lead to an ** out-of-memory error message. As a side effect, ** yet unnumbered halo vertices of the induced ** subgraph are numbered and the induced halo graph ** data are updated accordingly. ** It returns: ** - >=0 : number of edges in induced halo graph. ** - -1 : if out of memory (this is helpless). */ static Gnum hgraphInduce3 ( const Hgraph * restrict const orggrafptr, /* Pointer to original graph */ const VertList * restrict const orglistptr) /* Pointer to vertex list */ { Gnum indedgenbr; /* Revised number of edges in induced halo graph */ Gnum indvertnum; /* Current vertex number in induced halo graph */ Gnum * restrict orgindxtax; /* Array of numbers of selected vertices */ const Gnum * restrict const orglistvnumtab = orglistptr->vnumtab; const Gnum * restrict const orgverttax = orggrafptr->s.verttax; const Gnum * restrict const orgvendtax = orggrafptr->s.vendtax; const Gnum * restrict const orgedgetax = orggrafptr->s.edgetax; if ((orgindxtax = memAlloc (orggrafptr->s.vertnbr * sizeof (Gnum))) == NULL) return (-1); memSet (orgindxtax, ~0, orggrafptr->s.vertnbr * sizeof (Gnum)); /* Preset index array */ orgindxtax -= orggrafptr->s.baseval; /* Base access to orgindxtab */ for (indvertnum = 0; indvertnum < orglistptr->vnumnbr; indvertnum ++) /* For all vertices in list */ orgindxtax[orglistvnumtab[indvertnum]] = indvertnum; /* Mark selected vertices */ for (indvertnum = 0, indedgenbr = 0; /* For all vertices in list */ indvertnum < orglistptr->vnumnbr; indvertnum ++) { Gnum orgvertnum; /* Current vertex number in original halo graph */ Gnum orgedgenum; /* Current edge number in original halo graph */ orgvertnum = orglistvnumtab[indvertnum]; /* Get number of original vertex */ indedgenbr += orgvendtax[orgvertnum] - orgverttax[orgvertnum]; /* Add degree of original vertex */ for (orgedgenum = orgverttax[orgvertnum]; /* For all neighbors of original halo vertex */ orgedgenum < orgvendtax[orgvertnum]; orgedgenum ++) { if (orgindxtax[orgedgetax[orgedgenum]] == ~0) /* If neighbor is halo vertex */ indedgenbr ++; /* Account for the arc once more */ } } memFree (orgindxtax + orggrafptr->s.baseval); return (indedgenbr); } scotch-6.0.4.dfsg/src/libscotch/hmesh_order_cp.c0000644002563400244210000006010711631447170024767 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh_order_cp.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module performs compession of mesh **/ /** nodes, by merging nodes having the same **/ /** adjacency structure. **/ /** **/ /** DATES : # Version 4.0 : from : 08 feb 2004 **/ /** to 05 jan 2005 **/ /** # Version 5.0 : from : 25 jul 2007 **/ /** to : 12 sep 2007 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HMESH_ORDER_CP #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "order.h" #include "mesh.h" #include "hmesh.h" #include "hmesh_order_cp.h" #include "hmesh_order_st.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the ordering. ** It returns: ** - 0 : if the ordering could be computed. ** - !0 : on error. */ int hmeshOrderCp ( const Hmesh * restrict const finemeshptr, Order * restrict const fineordeptr, const Gnum ordenum, /*+ Zero-based ordering number +*/ OrderCblk * restrict const cblkptr, /*+ Single column-block +*/ const HmeshOrderCpParam * restrict const paraptr) { Hmesh coarmeshdat; /* Compressed halo submesh */ Order coarordedat; /* Ordering of compressed halo submesh */ Gnum * restrict coarperitab; /* Coarse permutation array */ const Gnum * restrict coarperitax; /* Temporary based access to coarperitab */ Gnum coarvertnum; /* Number of current compressed vertex */ Gnum * restrict coarvsiztax; /* Array of coarse vertex sizes (as number of merged fine vertices) */ Gnum coaredgenum; /* Number of current compressed edge */ Gnum * restrict coarvpostax; /* Position in fine permutation of fine vertices merged into same vertex */ Gnum coarvnodmax; Gnum coarvertmax; Gnum * restrict finecoartax; /* Original to compressed vertex number array */ HmeshOrderCpHash * restrict finehashtab; /* Neighbor hash table */ Gnum finehashmsk; /* Mask for access to hash table */ int * restrict finehasptab; /* Pre-hashing table */ Gnum finehaspmsk; /* Mask for access to pre-hashing table */ Gnum * restrict finehsumtax; /* Array of hash values for each original vertex */ Gnum finevertnbr; /* Number of fine vertices in compressed elimination tree */ Gnum finevsizsum; /* Sum of compressed vertex sizes to build fine inverse permutation */ Gnum coarvsizsiz; /* Size of array of sizes of coarse nodes */ Gnum coarvelmnbr; /* Number of coarse element vertices */ Gnum * restrict coarverttax; Gnum * restrict coarvnlotax; Gnum * restrict coaredgetax; Gnum * restrict coarfinetax; Gnum finevnodnum; Gnum coarvnodnbr; Gnum finevelmnum; Gnum coarvnodnnd; Gnum coardegrmax; Gnum coarvnodnum; if (finemeshptr->vnohnbr != finemeshptr->m.vnodnbr) { errorPrint ("hmeshOrderCp: halo meshes not supported yet"); return (1); } coarvelmnbr = finemeshptr->m.velmnbr; /* To date, keep isolated elements */ coarvnodmax = (Gnum) ((double) finemeshptr->vnohnbr * paraptr->comprat) + (finemeshptr->m.vnodnbr - finemeshptr->vnohnbr); coarvertmax = coarvnodmax + coarvelmnbr; coarvsizsiz = (finemeshptr->m.vnlotax == NULL) ? 0 : coarvnodmax; for (finehashmsk = 15; /* Set neighbor hash table size */ finehashmsk < finemeshptr->m.degrmax; finehashmsk = finehashmsk * 2 + 1) ; finehashmsk = finehashmsk * 4 + 3; /* Fill hash table at 1/4 of capacity */ if (memAllocGroup ((void **) (void *) &coarverttax, (size_t) ((coarvertmax + 1) * sizeof (Gnum)), &coarvsiztax, (size_t) (coarvsizsiz * sizeof (Gnum)), /* TRICK: if no vertex loads, coarvsiztax points to coarvnodtax */ &coarvnlotax, (size_t) (coarvnodmax * sizeof (Gnum)), /* Only change node weights */ &finecoartax, (size_t) (finemeshptr->m.vnodnbr * sizeof (Gnum)), &coaredgetax, (size_t) (finemeshptr->m.edgenbr * sizeof (Gnum)), &finehsumtax, (size_t) (finemeshptr->m.vnodnbr * sizeof (Gnum)), &finehashtab, (size_t) ((finehashmsk + 1) * sizeof (HmeshOrderCpHash)), &coarperitab, (size_t) (coarvnodmax * sizeof (Gnum)), /* TODO: move after resize */ &coarfinetax, (size_t) (coarvnodmax * sizeof (Gnum)), NULL) == NULL) { errorPrint ("hmeshOrderCp: out of memory (1)"); return (1); } /* TODO : resize after success */ finehsumtax -= finemeshptr->m.vnodbas; /* TRICK: do not base finecoartax yet (see later) */ finehasptab = (int *) finecoartax; /* Use finecoartab as temporary pre-hash table */ for (finehaspmsk = 1; /* Get pre-hash mask that fits in finecoartab */ finehaspmsk <= finemeshptr->m.vnodnbr; /* Smallest (2^i)-1 value > vertnbr */ finehaspmsk = finehaspmsk * 2 + 1) ; finehaspmsk >>= 1; /* Ensure masked data will always fit into finecoartab array */ finehaspmsk = (finehaspmsk * (sizeof (Gnum) / sizeof (int))) + ((sizeof (Gnum) / sizeof (int)) - 1); if (finehaspmsk >= ((sizeof (int) << (3 + 1)) - 1)) /* Only use 1/8 of array for pre-hashing, for increased cache locality */ finehaspmsk >>= 3; memSet (finehasptab, 0, (finehaspmsk + 1) * sizeof (int)); /* Initialize pre-hash table */ for (finevnodnum = finemeshptr->m.vnodbas, coarvnodnbr = finemeshptr->m.vnodnbr; /* For all non-halo node vertices */ finevnodnum < finemeshptr->vnohnnd; finevnodnum ++) { Gnum fineenodnum; /* Current edge number */ Gnum finehsumval; /* Hash sum value */ Gnum finehsumbit; for (fineenodnum = finemeshptr->m.verttax[finevnodnum], finehsumval = 0; fineenodnum < finemeshptr->m.vendtax[finevnodnum]; fineenodnum ++) finehsumval += finemeshptr->m.edgetax[fineenodnum]; finehsumtax[finevnodnum] = finehsumval; finehsumbit = finehsumval & ((sizeof (int) << 3) - 1); /* Get bit mask and byte position (division should be optimized into a shift) */ finehsumval /= (sizeof (int) << 3); finehsumval &= finehaspmsk; /* Make hash sum value fit into finehasptab */ coarvnodnbr -= (finehasptab[finehsumval] >> finehsumbit) & 1; /* If hash value already in pre-hash table, maybe one more vertex compressed */ finehasptab[finehsumval] |= (1 << finehsumbit); /* Put value into pre-hash table anyway */ } if (coarvnodnbr > coarvnodmax) { /* If mesh needs not be compressed */ memFree (coarverttax); /* Group leader not yet based */ return (hmeshOrderSt (finemeshptr, fineordeptr, ordenum, cblkptr, paraptr->stratunc)); } memSet (finecoartax, ~0, finemeshptr->m.vnodnbr * sizeof (Gnum)); memSet (&coarmeshdat, 0, sizeof (Hmesh)); /* Initialize compressed halo mesh structure */ coarmeshdat.m.flagval = MESHFREEVERT | MESHVERTGROUP; /* Free only coarverttab as group leader */ coarmeshdat.m.baseval = finemeshptr->m.baseval; coarmeshdat.m.velmbas = coarmeshdat.m.baseval; coarmeshdat.m.velmnbr = coarvelmnbr; /* Mesh compression does not touch elements, apart from isolated elements */ coarmeshdat.m.velmnnd = coarmeshdat.m.vnodbas = coarvelmnbr + coarmeshdat.m.baseval; coarmeshdat.m.veisnbr = finemeshptr->m.veisnbr; /* To date, keep all isolated element vertices, if any */ coarmeshdat.m.velosum = finemeshptr->m.velosum; coarmeshdat.m.vnlosum = finemeshptr->m.vnlosum; coarverttax -= coarmeshdat.m.baseval; coarvsiztax -= coarmeshdat.m.vnodbas; /* TRICK: if no vertex loads, coarvsiztax points to coarvnodtax */ coarvnlotax -= coarmeshdat.m.vnodbas; coaredgetax -= coarmeshdat.m.baseval; finecoartax -= finemeshptr->m.vnodbas; coarmeshdat.m.verttax = coarverttax; coarmeshdat.m.vendtax = coarverttax + 1; /* Use compact representation of arrays */ coarmeshdat.m.velotax = finemeshptr->m.velotax; /* Re-use element vertex load array, if any */ coarmeshdat.m.vnlotax = coarvnlotax; coarmeshdat.m.edgetax = coaredgetax; coarfinetax -= coarmeshdat.m.vnodbas; memSet (finehashtab, ~0, (finehashmsk + 1) * sizeof (HmeshOrderCpHash)); for (finevelmnum = finemeshptr->m.velmbas, coarvertnum = coaredgenum = coarmeshdat.m.baseval, /* Build element arrays */ coarvnodnnd = coarmeshdat.m.baseval + finemeshptr->m.velmnbr, coardegrmax = 0; finevelmnum < finemeshptr->m.velmnnd; finevelmnum ++) { Gnum fineeelmnum; Gnum coardegrval; fineeelmnum = finemeshptr->m.verttax[finevelmnum]; #ifdef DEAD_CODE if (fineeelmnum == finemeshptr->m.vendtax[finevelmnum]) /* Skip isolated elements */ continue; #endif #ifdef SCOTCH_DEBUG_ORDER2 if (coarvertnum >= coarmeshdat.m.velmnnd) { /* If too many elements declared */ errorPrint ("hmeshOrderCp: internal error (1)"); /* Maybe problem with veisnbr */ return (1); } #endif /* SCOTCH_DEBUG_ORDER2 */ coarverttax[coarvertnum] = coaredgenum; for ( ; fineeelmnum < finemeshptr->m.vendtax[finevelmnum]; fineeelmnum ++) { Gnum finevnodnum; Gnum coarvnodnum; finevnodnum = finemeshptr->m.edgetax[fineeelmnum]; coarvnodnum = finecoartax[finevnodnum]; if (coarvnodnum != ~0) { /* If fine node already considered */ if (coarvnodnum >= 0) /* If node is leader of cluster */ coaredgetax[coaredgenum ++] = coarvnodnum; /* Add it to coarse mesh */ } else { /* Fine node not yet considered */ Gnum finehsumval; Gnum finedegrval; Gnum fineeelmngb; Gnum coarvsizval; /* Number of fine node vertices in coarse node vertex */ if (coarvnodnnd >= (coarvnodmax + coarmeshdat.m.vnodbas)) { /* If mesh needs not be compressed */ memFree (coarverttax + coarmeshdat.m.baseval); return (hmeshOrderSt (finemeshptr, fineordeptr, ordenum, cblkptr, paraptr->stratunc)); } coarvsizval = 1; /* Cluster leader it at least alone */ coarvnodnum = coarvnodnnd ++; /* Node is leader of future cluster */ finecoartax[finevnodnum] = coarvnodnum; /* Record node as cluster leader */ coaredgetax[coaredgenum ++] = coarvnodnum; /* Add leader to coarse mesh */ coarfinetax[coarvnodnum] = finevnodnum; /* Record node to build edge sub-array */ finehsumval = finehsumtax[finevnodnum]; /* Get hash sum of cluster leader */ finedegrval = finemeshptr->m.vendtax[finevnodnum] - finemeshptr->m.verttax[finevnodnum]; for (fineeelmngb = fineeelmnum + 1; /* For all remaining edges of current element */ fineeelmngb < finemeshptr->m.vendtax[finevelmnum]; fineeelmngb ++) { Gnum finevnodngb; Gnum fineenodngb; finevnodngb = finemeshptr->m.edgetax[fineeelmngb]; /* Get index of neighboring node */ if ((finecoartax[finevnodngb] != ~0) || /* If node has already been processed or */ (finehsumval != finehsumtax[finevnodngb]) || /* If hash sum does not match, skip node */ (finedegrval != (finemeshptr->m.vendtax[finevnodngb] - finemeshptr->m.verttax[finevnodngb]))) continue; if (finehashtab[(finevelmnum * HMESHORDERCPHASHPRIME) & finehashmsk].vnodnum != finevnodnum) { /* If hash table not yet filled */ Gnum fineenodnum; for (fineenodnum = finemeshptr->m.verttax[finevnodnum]; fineenodnum < finemeshptr->m.vendtax[finevnodnum]; fineenodnum ++) { Gnum finevelmend; Gnum finehelmend; finevelmend = finemeshptr->m.edgetax[fineenodnum]; for (finehelmend = (finevelmend * HMESHORDERCPHASHPRIME) & finehashmsk; finehashtab[finehelmend].vnodnum == finevnodnum; finehelmend = (finehelmend + 1) & finehashmsk) ; finehashtab[finehelmend].vnodnum = finevnodnum; /* Fill hash table with node adjacency */ finehashtab[finehelmend].velmnum = finevelmend; } } for (fineenodngb = finemeshptr->m.verttax[finevnodngb]; fineenodngb < finemeshptr->m.vendtax[finevnodngb]; fineenodngb ++) { Gnum finevelmngb; Gnum finehelmngb; finevelmngb = finemeshptr->m.edgetax[fineenodngb]; for (finehelmngb = (finevelmngb * HMESHORDERCPHASHPRIME) & finehashmsk; ; finehelmngb = (finehelmngb + 1) & finehashmsk) { if (finehashtab[finehelmngb].vnodnum != finevnodnum) /* If adjacencies differ, break */ goto loop_failed; if (finehashtab[finehelmngb].velmnum == finevelmngb) /* If neighbor found, process next neighbor */ break; } } finecoartax[finevnodngb] = -2 - coarvnodnum; /* Set index of cluster non-leader */ coarvsizval ++; /* One more non-leader in cluster */ loop_failed: ; } coarvsiztax[coarvnodnum] = coarvsizval; } } coardegrval = coaredgenum - coarverttax[coarvertnum]; if (coardegrval > coardegrmax) coardegrmax = coardegrval; coarvertnum ++; /* One more coarse element created */ } #ifdef SCOTCH_DEBUG_ORDER2 if (coarvertnum != coarmeshdat.m.velmnnd) { /* If too many elements declared */ errorPrint ("hmeshOrderCp: internal error (2)"); /* Maybe problem with veisnbr */ return (1); } #endif /* SCOTCH_DEBUG_ORDER2 */ coarmeshdat.m.vnodnnd = coarvnodnnd; coarmeshdat.m.vnodnbr = coarvnodnnd - coarmeshdat.m.vnodbas; #ifdef SCOTCH_DEBUG_ORDER2 for (finevnodnum = finemeshptr->m.vnodbas; finevnodnum < finemeshptr->m.vnodnnd; finevnodnum ++) { if (finecoartax[finevnodnum] == ~0) { errorPrint ("hmeshOrderCp: internal error (3)"); return (1); } } #endif /* SCOTCH_DEBUG_ORDER2 */ for ( ; coarvertnum < coarmeshdat.m.vnodnnd; coarvertnum ++) { /* Build node arrays */ Gnum finevnodnum; Gnum fineenodnum; Gnum coardegrval; coarverttax[coarvertnum] = coaredgenum; finevnodnum = coarfinetax[coarvertnum]; coardegrval = finemeshptr->m.vendtax[finevnodnum] - finemeshptr->m.verttax[finevnodnum]; for (fineenodnum = finemeshptr->m.verttax[finevnodnum]; fineenodnum < finemeshptr->m.vendtax[finevnodnum]; fineenodnum ++) coaredgetax[coaredgenum ++] = finemeshptr->m.edgetax[fineenodnum] - (finemeshptr->m.velmbas - coarmeshdat.m.velmbas); if (coardegrval > coardegrmax) coardegrmax = coardegrval; } coarverttax[coarvertnum] = coaredgenum; /* Set end of vertex array */ coarmeshdat.m.edgenbr = coaredgenum - coarmeshdat.m.baseval; coarmeshdat.m.degrmax = coardegrmax; coarmeshdat.vnohnbr = coarmeshdat.m.vnodnbr; /* Halo meshes not yet supported */ coarmeshdat.vnohnnd = coarmeshdat.m.vnodnnd; coarmeshdat.vehdtax = coarmeshdat.m.vendtax; /* Only element part of vendtab will be accessed through vehdtab */ coarmeshdat.vnhlsum = coarmeshdat.m.vnlosum; coarmeshdat.enohnbr = coarmeshdat.m.edgenbr; if (finemeshptr->m.vnlotax != NULL) { /* If fine mesh has node vertex loads */ memSet (coarmeshdat.m.vnlotax + coarmeshdat.m.vnodbas, 0, coarmeshdat.m.vnodnbr * sizeof (Gnum)); for (finevnodnum = finemeshptr->m.vnodbas; finevnodnum < finemeshptr->m.vnodnnd; finevnodnum ++) { /* Compute vertex loads for compressed mesh */ coarmeshdat.m.vnlotax[finecoartax[finevnodnum]] += finemeshptr->m.vnlotax[finevnodnum]; } } #ifdef SCOTCH_DEBUG_ORDER2 if (hmeshCheck (&coarmeshdat) != 0) { errorPrint ("hmeshOrderCp: internal error (4)"); hmeshExit (&coarmeshdat); return (1); } #endif /* SCOTCH_DEBUG_ORDER2 */ orderInit (&coarordedat, coarmeshdat.m.baseval, coarmeshdat.m.vnodnbr, coarperitab); /* Build ordering of compressed submesh */ if (hmeshOrderSt (&coarmeshdat, &coarordedat, 0, &coarordedat.cblktre, paraptr->stratcpr) != 0) { hmeshExit (&coarmeshdat); return (1); } coarvsiztax += (coarmeshdat.m.vnodbas - coarmeshdat.m.baseval); /* Adjust array to match permutation bounds */ *cblkptr = coarordedat.cblktre; /* Link sub-tree to ordering */ coarordedat.cblktre.cblktab = NULL; /* Unlink sub-tree from sub-ordering */ finevertnbr = hmeshOrderCpTree (coarordedat.peritab, /* Expand sub-tree */ coarvsiztax, cblkptr, 0); #ifdef SCOTCH_DEBUG_ORDER2 if (finevertnbr != finemeshptr->m.vnodnbr) { errorPrint ("hmeshOrderCp: internal error (5)"); hmeshExit (&coarmeshdat); return (1); } #endif /* SCOTCH_DEBUG_ORDER2 */ fineordeptr->treenbr += coarordedat.cblknbr; /* Adjust number of tree nodes */ fineordeptr->cblknbr += coarordedat.cblknbr - 1; /* Adjust number of column blocks */ coarvpostax = coarmeshdat.m.verttax; /* Recycle verttab (not velotab as may be merged with coarvsiztab) */ coarperitax = coarperitab - coarmeshdat.m.vnodbas; for (coarvnodnum = coarmeshdat.m.vnodbas, finevsizsum = 0; /* Compute initial indices for inverse permutation expansion */ coarvnodnum < coarmeshdat.m.vnodnnd; coarvnodnum ++) { coarvpostax[coarperitax[coarvnodnum]] = finevsizsum; finevsizsum += coarvsiztax[coarperitax[coarvnodnum]]; } coarvpostax = coarmeshdat.m.verttax + (coarmeshdat.m.baseval - coarmeshdat.m.vnodbas); for (finevnodnum = finemeshptr->m.vnodbas; finevnodnum < finemeshptr->m.vnodnnd; finevnodnum ++) { /* Compute fine permutation */ Gnum coarvnodnum; coarvnodnum = finecoartax[finevnodnum]; /* Get index of corresponding coarse node */ if (coarvnodnum < 0) /* If node is not cluster leader */ coarvnodnum = -2 - coarvnodnum; /* Get index of cluster leader */ fineordeptr->peritab[coarvpostax[coarvnodnum] ++] = finevnodnum + (finemeshptr->m.baseval - finemeshptr->m.vnodbas); } orderExit (&coarordedat); hmeshExit (&coarmeshdat); return (0); } /* This routine turns the coarse elimination ** tree produced by the ordering of the coarse ** mesh into a fine elimination tree, according ** to the cardinality of the coarse vertices. ** It returns: ** - !0 : overall number of fine vertices, in all cases. */ static Gnum hmeshOrderCpTree ( const Gnum * restrict const coarperitab, /* Coarse inverse permutation */ const Gnum * restrict const coarvsiztax, /* Array of fine sizes of coarse vertices */ OrderCblk * restrict const coficblkptr, /* Current coarse/fine column block cell */ Gnum coarordenum) /* Compressed vertex to start expansion at */ { Gnum finevertnbr; /* Number of fine vertices in subtree */ finevertnbr = 0; /* No fine vertices yet */ if (coficblkptr->cblktab == NULL) { /* If leaf of column block tree */ Gnum coarvnumnum; for (coarvnumnum = coarordenum; coarvnumnum < coarordenum + coficblkptr->vnodnbr; coarvnumnum ++) finevertnbr += coarvsiztax[coarperitab[coarvnumnum]]; /* Sum-up fine vertices */ } else { Gnum coarvertnbr; /* Number of coarse vertices in cell */ Gnum coarvertsum; /* Number of coarse vertices in subtree */ Gnum coficblknum; /* Index in column block array */ for (coficblknum = 0, coarvertsum = coarordenum; /* Start at current coarse index */ coficblknum < coficblkptr->cblknbr; coficblknum ++) { coarvertnbr = coficblkptr->cblktab[coficblknum].vnodnbr; /* Save number of coarse vertices */ finevertnbr += hmeshOrderCpTree (coarperitab, coarvsiztax, &coficblkptr->cblktab[coficblknum], coarvertsum); coarvertsum += coarvertnbr; /* Sum-up coarse vertices */ } } coficblkptr->vnodnbr = finevertnbr; /* Set number of fine vertices */ return (finevertnbr); /* Return accumulated number */ } scotch-6.0.4.dfsg/src/libscotch/graph_io.h0000644002563400244210000000671411631447170023607 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : graph_io.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the source graph input/output **/ /** functions. **/ /** **/ /** DATES : # Version 0.0 : from : 02 dec 1992 **/ /** to 18 may 1993 **/ /** # Version 1.3 : from : 30 apr 1994 **/ /** to 18 may 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to 18 aug 1994 **/ /** # Version 3.0 : from : 07 jul 1995 **/ /** to 28 sep 1995 **/ /** # Version 3.1 : from : 28 nov 1995 **/ /** to 28 nov 1995 **/ /** # Version 3.2 : from : 07 sep 1996 **/ /** to 15 may 1999 **/ /** # Version 4.0 : from : 25 nov 2001 **/ /** to 25 nov 2001 **/ /** **/ /************************************************************/ /* ** The function prototypes. */ #ifndef GRAPH_IO #define static #endif int graphLoad2 (const Gnum, const Gnum, const Gnum * const, const Gnum * const, Gnum * const, const Gnum, const Gnum * const); #undef static scotch-6.0.4.dfsg/src/libscotch/fibo.h0000644002563400244210000002604611650651076022741 0ustar trophimeutilisateurs du domaine/* Copyright 2010,2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : fibo.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the definitions of **/ /** the generic Fibonacci trees. **/ /** **/ /** DATES : # Version 5.1 : from : 01 may 2010 **/ /** to 12 may 2010 **/ /** # Version 6.0 : from : 22 oct 2011 **/ /** to 22 oct 2011 **/ /** **/ /** NOTES : # Since this module is to be used as **/ /** the gain keeping data structure for **/ /** local optimization algorithms, the **/ /** computation of the best node needs **/ /** only to be done when actually picking **/ /** the vertex, while many insertions and **/ /** deletions (neighbor vertices) can **/ /** take place in the mean time. This is **/ /** why this data structure does not keep **/ /** track of the best node, as most **/ /** implementations do. **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /* The doubly linked list structure. */ typedef struct FiboLink_ { struct FiboNode_ * prevptr; /*+ Pointer to previous sibling element +*/ struct FiboNode_ * nextptr; /*+ Pointer to next sibling element +*/ } FiboLink; /* The tree node data structure. The deflval variable merges degree and flag variables. The degree of a node is smaller than "bitsizeof (INT)", so it can hold on an "int". The flag value is stored in the lowest bit of the value. */ typedef struct FiboNode_ { struct FiboNode_ * pareptr; /*+ Pointer to parent element, if any +*/ struct FiboNode_ * chldptr; /*+ Pointer to first child element, if any +*/ FiboLink linkdat; /*+ Pointers to sibling elements +*/ int deflval; /*+ Lowest bit: flag value; other bits: degree value +*/ } FiboNode; /* The tree data structure. The fake dummy node aims at handling root node insertion without any test. This is important as many insertions have to be performed. */ typedef struct FiboTree_ { FiboNode rootdat; /*+ Dummy node for fast root insertion +*/ FiboNode ** restrict degrtab; /*+ Consolidation array of size "bitsizeof (INT)" +*/ int (* cmpfptr) (const FiboNode * const, const FiboNode * const); /*+ Comparison routine +*/ } FiboTree; /* ** The marco definitions. */ #define fiboTreeLinkAfter(o,n) do { \ FiboNode * nextptr; \ nextptr = (o)->linkdat.nextptr; \ (n)->linkdat.nextptr = nextptr; \ (n)->linkdat.prevptr = (o); \ nextptr->linkdat.prevptr = (n); \ (o)->linkdat.nextptr = (n); \ } while (0) #define fiboTreeUnlink(n) do { \ (n)->linkdat.prevptr->linkdat.nextptr = (n)->linkdat.nextptr; \ (n)->linkdat.nextptr->linkdat.prevptr = (n)->linkdat.prevptr; \ } while (0) #define fiboTreeAddMacro(t,n) do { \ (n)->pareptr = NULL; \ (n)->chldptr = NULL; \ (n)->deflval = 0; \ fiboTreeLinkAfter (&((t)->rootdat), (n)); \ } while (0) #define fiboTreeMinMacro(t) (fiboTreeConsolidate (t)) #define fiboTreeCutChildren(t,n) do { \ FiboNode * chldptr; \ chldptr = (n)->chldptr; \ if (chldptr != NULL) { \ FiboNode * cendptr; \ cendptr = chldptr; \ do { \ FiboNode * nextptr; \ nextptr = chldptr->linkdat.nextptr; \ chldptr->pareptr = NULL; \ fiboTreeLinkAfter (&((t)->rootdat), chldptr); \ chldptr = nextptr; \ } while (chldptr != cendptr); \ } \ } while (0) #define fiboTreeDelMacro(t,n) do { \ FiboNode * pareptr; \ FiboNode * rghtptr; \ pareptr = (n)->pareptr; \ fiboTreeUnlink (n); \ fiboTreeCutChildren ((t), (n)); \ if (pareptr == NULL) \ break; \ rghtptr = (n)->linkdat.nextptr; \ while (1) { \ FiboNode * gdpaptr; \ int deflval; \ deflval = pareptr->deflval - 2; \ pareptr->deflval = deflval | 1; \ gdpaptr = pareptr->pareptr; \ pareptr->chldptr = (deflval <= 1) ? NULL : rghtptr; \ if (((deflval & 1) == 0) || (gdpaptr == NULL)) \ break; \ rghtptr = pareptr->linkdat.nextptr; \ fiboTreeUnlink (pareptr); \ pareptr->pareptr = NULL; \ fiboTreeLinkAfter (&((t)->rootdat), pareptr); \ pareptr = gdpaptr; \ } \ } while (0) /* ** The function prototypes. */ #define fiboTreeAddIsMacro #define fiboTreeAdd fiboTreeAddMacro /* #define fiboTreeDel fiboTreeDelMacro */ /* #define fiboTreeMin fiboTreeMinMacro */ #ifndef FIBO #define static #endif int fiboTreeInit (FiboTree * const, int (*) (const FiboNode * const, const FiboNode * const)); void fiboTreeExit (FiboTree * const); void fiboTreeFree (FiboTree * const); FiboNode * fiboTreeConsolidate (FiboTree * const); #ifndef fiboTreeAddIsMacro void fiboTreeAdd (FiboTree * const, FiboNode * const); #endif /* fiboTreeAddIsMacro */ #ifndef fiboTreeDelIsMacro void fiboTreeDel (FiboTree * const, FiboNode * const); #endif /* fiboTreeDelIsMacro */ #ifndef fiboTreeMinIsMacro FiboNode * fiboTreeMin (FiboTree * const); #endif /* fiboTreeMinIsMacro */ #ifdef SCOTCH_DEBUG_FIBO3 int fiboTreeCheck (const FiboTree * const); static int fiboTreeCheck2 (const FiboNode * const); #endif /* SCOTCH_DEBUG_FIBO3 */ #undef static scotch-6.0.4.dfsg/src/libscotch/library_pt_f.h0000644002563400244210000001257312055000732024461 0ustar trophimeutilisateurs du domaine!* Copyright 2004,2007,2009,2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS !* !* This file is part of the Scotch software package for static mapping, !* graph partitioning and sparse matrix ordering. !* !* This software is governed by the CeCILL-C license under French law !* and abiding by the rules of distribution of free software. You can !* use, modify and/or redistribute the software under the terms of the !* CeCILL-C license as circulated by CEA, CNRS and INRIA at the following !* URL: "http://www.cecill.info". !* !* As a counterpart to the access to the source code and rights to copy, !* modify and redistribute granted by the license, users are provided !* only with a limited warranty and the software's author, the holder of !* the economic rights, and the successive licensors have only limited !* liability. !* !* In this respect, the user's attention is drawn to the risks associated !* with loading, using, modifying and/or developing or reproducing the !* software by the user in light of its specific status of free software, !* that may mean that it is complicated to manipulate, and that also !* therefore means that it is reserved for developers and experienced !* professionals having in-depth computer knowledge. Users are therefore !* encouraged to load and test the software's suitability as regards !* their requirements in conditions enabling the security of their !* systems and/or data to be ensured and, more generally, to use and !* operate it in the same conditions as regards security. !* !* The fact that you are presently reading this means that you have had !* knowledge of the CeCILL-C license and that you accept its terms. !* !*********************************************************** !* ** !* NAME : library_pt_f.h ** !* ** !* AUTHOR : Francois PELLEGRINI ** !* ** !* FUNCTION : FORTRAN declaration file for the ** !* LibPtscotch parallel static mapping and ** !* sparse matrix block ordering sequential ** !* library. ** !* ** !* DATES : # Version 3.4 : from : 04 feb 2000 ** !* to 22 oct 2001 ** !* # Version 4.0 : from : 16 jan 2004 ** !* to 16 jan 2004 ** !* # Version 5.0 : from : 26 apr 2006 ** !* to 26 apr 2006 ** !* # Version 5.1 : from : 26 mar 2009 ** !* to 12 feb 2011 ** !* # Version 6.0 : from : 22 oct 2011 ** !* to 27 nov 2012 ** !* ** !*********************************************************** !* Flag definitions for the coarsening !* routines. INTEGER SCOTCH_COARSENNOMERGE PARAMETER (SCOTCH_COARSENNOMERGE = 16384) !* Flag definitions for the strategy !* string selection routines. INTEGER SCOTCH_STRATDEFAULT INTEGER SCOTCH_STRATQUALITY INTEGER SCOTCH_STRATSPEED INTEGER SCOTCH_STRATBALANCE INTEGER SCOTCH_STRATSAFETY INTEGER SCOTCH_STRATSCALABILITY INTEGER SCOTCH_STRATRECURSIVE INTEGER SCOTCH_STRATREMAP INTEGER SCOTCH_STRATLEVELMAX INTEGER SCOTCH_STRATLEVELMIN INTEGER SCOTCH_STRATLEAFSIMPLE INTEGER SCOTCH_STRATSEPASIMPLE PARAMETER (SCOTCH_STRATDEFAULT = 0) PARAMETER (SCOTCH_STRATQUALITY = 1) PARAMETER (SCOTCH_STRATSPEED = 2) PARAMETER (SCOTCH_STRATBALANCE = 4) PARAMETER (SCOTCH_STRATSAFETY = 8) PARAMETER (SCOTCH_STRATSCALABILITY = 16) PARAMETER (SCOTCH_STRATRECURSIVE = 256) PARAMETER (SCOTCH_STRATREMAP = 512) PARAMETER (SCOTCH_STRATLEVELMAX = 4096) PARAMETER (SCOTCH_STRATLEVELMIN = 8192) PARAMETER (SCOTCH_STRATLEAFSIMPLE = 16384) PARAMETER (SCOTCH_STRATSEPASIMPLE = 32768) !* Size definitions for the SCOTCH opaque !* structures. These structures must be !* allocated as arrays of DOUBLEPRECISION !* values for proper padding. The dummy !* sizes are computed at compile-time by !* program "dummysizes". INTEGER SCOTCH_ARCHDIM INTEGER SCOTCH_DGRAPHDIM INTEGER SCOTCH_DGRAPHHALOREQDIM INTEGER SCOTCH_DORDERDIM INTEGER SCOTCH_GEOMDIM INTEGER SCOTCH_GRAPHDIM INTEGER SCOTCH_MAPDIM INTEGER SCOTCH_MESHDIM INTEGER SCOTCH_ORDERDIM INTEGER SCOTCH_STRATDIM PARAMETER (SCOTCH_ARCHDIM = DUMMYSIZEARCH) PARAMETER (SCOTCH_DGRAPHDIM = DUMMYSIZEDGRAPH) PARAMETER (SCOTCH_DGRAPHHALOREQDIM = DUMMYSIZEDGRAPHHALOREQ) PARAMETER (SCOTCH_DORDERDIM = DUMMYSIZEDORDER) PARAMETER (SCOTCH_GEOMDIM = DUMMYSIZEGEOM) PARAMETER (SCOTCH_GRAPHDIM = DUMMYSIZEGRAPH) PARAMETER (SCOTCH_MAPDIM = DUMMYSIZEMAP) PARAMETER (SCOTCH_MESHDIM = DUMMYSIZEMESH) PARAMETER (SCOTCH_ORDERDIM = DUMMYSIZEORDER) PARAMETER (SCOTCH_STRATDIM = DUMMYSIZESTRAT) scotch-6.0.4.dfsg/src/libscotch/vmesh_separate_gr.c0000644002563400244210000001421411631447171025503 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vmesh_separate_gr.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module separates a node separation **/ /** mesh by turning the mesh into a graph **/ /** and using a graph separation strategy. **/ /** **/ /** DATES : # Version 4.0 : from : 13 oct 2003 **/ /** to 13 oct 2003 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VMESH_SEPARATE_GR #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "vgraph.h" #include "vgraph_separate_st.h" #include "mesh.h" #include "vmesh.h" #include "vmesh_separate_gr.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the bipartitioning. ** It returns: ** - 0 : if the bipartitioning could be computed. ** - !0 : on error. */ int vmeshSeparateGr ( Vmesh * restrict const meshptr, /*+ Node separation mesh +*/ const VmeshSeparateGrParam * restrict const paraptr) /*+ Method parameters +*/ { Vgraph grafdat; Gnum fronnum; Gnum velmnum; Gnum ecmpsize1; graphInit (&grafdat.s); if (meshGraph (&meshptr->m, &grafdat.s) != 0) { errorPrint ("vmeshSeparateGr: cannot build graph"); return (1); } grafdat.parttax = meshptr->parttax + (meshptr->m.vnodbas - grafdat.s.baseval); /* Get node area of part array */ grafdat.compload[0] = meshptr->ncmpload[0]; grafdat.compload[1] = meshptr->ncmpload[1]; grafdat.compload[2] = meshptr->ncmpload[2]; grafdat.comploaddlt = meshptr->ncmploaddlt; grafdat.compsize[0] = meshptr->ncmpsize[0]; grafdat.compsize[1] = meshptr->ncmpsize[1]; grafdat.fronnbr = meshptr->fronnbr; grafdat.frontab = meshptr->frontab; /* Re-use frontier array */ grafdat.levlnum = meshptr->levlnum; for (fronnum = 0; fronnum < grafdat.fronnbr; fronnum ++) grafdat.frontab[fronnum] -= (meshptr->m.vnodbas - grafdat.s.baseval); #ifdef SCOTCH_DEBUG_VMESH2 if (vgraphCheck (&grafdat) != 0) { errorPrint ("vmeshSeparateGr: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH2 */ if (vgraphSeparateSt (&grafdat, paraptr->stratptr) != 0) { errorPrint ("vmeshSeparateGr: cannot separate graph"); return (1); } for (fronnum = 0; fronnum < grafdat.fronnbr; fronnum ++) /* Restore mesh-based frontier array */ grafdat.frontab[fronnum] += (meshptr->m.vnodbas - grafdat.s.baseval); meshptr->ncmpload[0] = grafdat.compload[0]; meshptr->ncmpload[1] = grafdat.compload[1]; meshptr->ncmpload[2] = grafdat.compload[2]; meshptr->ncmploaddlt = grafdat.comploaddlt; meshptr->ncmpsize[0] = grafdat.compsize[0]; meshptr->ncmpsize[1] = grafdat.compsize[1]; meshptr->fronnbr = grafdat.fronnbr; for (velmnum = meshptr->m.velmbas, ecmpsize1 = 0; velmnum < meshptr->m.velmnnd; velmnum ++) { /* Compute part of all elements */ Gnum eelmnum; GraphPart partval; partval = 0; /* Empty elements move to part 0 */ for (eelmnum = meshptr->m.verttax[velmnum]; eelmnum < meshptr->m.vendtax[velmnum]; eelmnum ++) { Gnum vnodnum; vnodnum = meshptr->m.edgetax[eelmnum]; partval = meshptr->parttax[vnodnum]; if (partval != 2) break; } partval &= 1; /* In case all nodes in separator */ ecmpsize1 += (Gnum) partval; /* Count elements in part 1 */ meshptr->parttax[velmnum] = partval; /* Set part of element */ } meshptr->ecmpsize[0] = meshptr->m.velmnbr - ecmpsize1; meshptr->ecmpsize[1] = ecmpsize1; #ifdef SCOTCH_DEBUG_VMESH2 if (vmeshCheck (meshptr) != 0) { errorPrint ("vmeshSeparateGr: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/module.h0000644002563400244210000012612212474564457023316 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007-2015 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : module.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This is the global configuration file **/ /** for the whole libSCOTCH library module. **/ /** **/ /** DATES : # Version 3.2 : from : 22 jun 1998 **/ /** to 13 may 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 03 oct 1998 **/ /** # Version 3.4 : from : 01 nov 2001 **/ /** to 01 nov 2001 **/ /** # Version 4.0 : from : 12 dec 2001 **/ /** to 24 nov 2005 **/ /** # Version 5.0 : from : 24 feb 2007 **/ /** to 24 jul 2007 **/ /** # Version 5.1 : from : 25 oct 2007 **/ /** to 20 feb 2011 **/ /** # Version 6.0 : from : 12 sep 2008 **/ /** to 01 mar 2015 **/ /** **/ /************************************************************/ #define MODULE_H /* ** Version string. */ #define SCOTCH_VERSION_STRING SCOTCH_VERSION_STRING2(SCOTCH_VERSION) "." SCOTCH_VERSION_STRING2(SCOTCH_RELEASE) "." SCOTCH_VERSION_STRING2(SCOTCH_PATCHLEVEL) #define SCOTCH_VERSION_STRING2(x) SCOTCH_VERSION_STRING3(x) #define SCOTCH_VERSION_STRING3(x) #x /* ** Debug values. */ #ifdef SCOTCH_DEBUG_ALL #ifndef SCOTCH_DEBUG #define SCOTCH_DEBUG #endif /* SCOTCH_DEBUG */ #define COMMON_DEBUG #define SCOTCH_DEBUG_ARCH2 #define SCOTCH_DEBUG_FIBO2 #define SCOTCH_DEBUG_GAIN2 #define SCOTCH_DEBUG_PARSER2 #define SCOTCH_DEBUG_BDGRAPH2 #define SCOTCH_DEBUG_BGRAPH2 #define SCOTCH_DEBUG_DGRAPH2 #define SCOTCH_DEBUG_DMAP2 #define SCOTCH_DEBUG_DORDER2 #define SCOTCH_DEBUG_GEOM2 #define SCOTCH_DEBUG_GRAPH2 #define SCOTCH_DEBUG_HDGRAPH2 #define SCOTCH_DEBUG_HGRAPH2 #define SCOTCH_DEBUG_HMESH2 #define SCOTCH_DEBUG_KDGRAPH2 #define SCOTCH_DEBUG_KDMAP2 #define SCOTCH_DEBUG_KGRAPH2 #define SCOTCH_DEBUG_LIBRARY2 #define SCOTCH_DEBUG_MAP2 #define SCOTCH_DEBUG_MESH2 #define SCOTCH_DEBUG_ORDER2 #define SCOTCH_DEBUG_PARSER2 #define SCOTCH_DEBUG_VDGRAPH2 #define SCOTCH_DEBUG_VGRAPH2 #define SCOTCH_DEBUG_VMESH2 #define SCOTCH_DEBUG_WGRAPH2 #endif /* SCOTCH_DEBUG_ALL */ #ifdef SCOTCH_DEBUG #define SCOTCH_DEBUG_ARCH1 #define SCOTCH_DEBUG_FIBO1 #define SCOTCH_DEBUG_GAIN1 #define SCOTCH_DEBUG_PARSER1 #define SCOTCH_DEBUG_BDGRAPH1 #define SCOTCH_DEBUG_BGRAPH1 #define SCOTCH_DEBUG_DGRAPH1 #define SCOTCH_DEBUG_DMAP1 #define SCOTCH_DEBUG_DORDER1 #define SCOTCH_DEBUG_GEOM1 #define SCOTCH_DEBUG_GRAPH1 #define SCOTCH_DEBUG_HDGRAPH1 #define SCOTCH_DEBUG_HGRAPH1 #define SCOTCH_DEBUG_HMESH1 #define SCOTCH_DEBUG_KDGRAPH1 #define SCOTCH_DEBUG_KDMAP1 #define SCOTCH_DEBUG_KGRAPH1 #define SCOTCH_DEBUG_LIBRARY1 #define SCOTCH_DEBUG_MAP1 #define SCOTCH_DEBUG_MESH1 #define SCOTCH_DEBUG_ORDER1 #define SCOTCH_DEBUG_PARSER1 #define SCOTCH_DEBUG_VDGRAPH1 #define SCOTCH_DEBUG_VGRAPH1 #define SCOTCH_DEBUG_VMESH1 #define SCOTCH_DEBUG_WGRAPH1 #endif /* SCOTCH_DEBUG */ /* ** Function renaming. */ #if ((! defined SCOTCH_COMMON_EXTERNAL) || (defined SCOTCH_COMMON_RENAME)) #define memCur SCOTCH_memCur #define memMax SCOTCH_memMax #define clockGet _SCOTCHclockGet #define commonStubDummy _SCOTCHcommonStubDummy #define errorPrint SCOTCH_errorPrint #define errorPrintW SCOTCH_errorPrintW #define errorProg SCOTCH_errorProg #define fileBlockClose _SCOTCHfileBlockClose #define fileBlockOpen _SCOTCHfileBlockOpen #define fileBlockOpenDist _SCOTCHfileBlockOpenDist #define fileCompress _SCOTCHfileCompress #define fileCompressType _SCOTCHfileCompressType #define fileUncompress _SCOTCHfileUncompress #define fileUncompressType _SCOTCHfileUncompressType #define fileNameDistExpand _SCOTCHfileNameDistExpand #define intLoad _SCOTCHintLoad #define intSave _SCOTCHintSave #define intAscn _SCOTCHintAscn #define intGcd _SCOTCHintGcd #define intPerm _SCOTCHintPerm #define intRandInit _SCOTCHintRandInit #define intRandProc _SCOTCHintRandProc #define intRandReset _SCOTCHintRandReset #define intRandSeed _SCOTCHintRandSeed #ifndef COMMON_RANDOM_SYSTEM #define intRandVal _SCOTCHintRandVal #endif /* COMMON_RANDOM_SYSTEM */ #define intSort1asc1 _SCOTCHintSort1asc1 #define intSort2asc1 _SCOTCHintSort2asc1 #define intSort2asc2 _SCOTCHintSort2asc2 #define intSort3asc1 _SCOTCHintSort3asc1 #define intSort3asc2 _SCOTCHintSort3asc2 #define memAllocGroup _SCOTCHmemAllocGroup #define memAllocRecord _SCOTCHmemAllocRecord #define memCheck _SCOTCHmemCheck #define memCheckExists _SCOTCHmemCheckExists #define memCheckSize _SCOTCHmemCheckSize #define memCheckToggle _SCOTCHmemCheckToggle #define memCheckWatch _SCOTCHmemCheckWatch #define memFreeRecord _SCOTCHmemFreeRecord #define memReallocGroup _SCOTCHmemReallocGroup #define memReallocRecord _SCOTCHmemReallocRecord #define memOffset _SCOTCHmemOffset #define stringSubst _SCOTCHstringSubst #define usagePrint _SCOTCHusagePrint #endif /* ((! defined SCOTCH_COMMON_EXTERNAL) || (defined SCOTCH_COMMON_RENAME)) */ #ifdef SCOTCH_RENAME #define archInit _SCOTCHarchInit #define archExit _SCOTCHarchExit #define archFree _SCOTCHarchFree #define archLoad _SCOTCHarchLoad #define archSave _SCOTCHarchSave /* #define archName _SCOTCHarchName Already a macro */ #define archClass _SCOTCHarchClass #define archClassTab _SCOTCHarchClassTab #define archDomLoad _SCOTCHarchDomLoad #define archDomSave _SCOTCHarchDomSave #ifdef SCOTCH_DEBUG_ARCH2 /* If already redefined */ #define archDomNum _SCOTCHarchDomNum #define archDomDist _SCOTCHarchDomDist #define archDomFrst _SCOTCHarchDomFrst #define archDomIncl _SCOTCHarchDomIncl #define archDomSize _SCOTCHarchDomSize #define archDomTerm _SCOTCHarchDomTerm #define archDomWght _SCOTCHarchDomWght #define archDomBipart _SCOTCHarchDomBipart #endif /* SCOTCH_DEBUG_ARCH2 */ #define archDomMpiType _SCOTCHarchDomMpiType #define archBuild _SCOTCHarchBuild #define archCmpltArchLoad _SCOTCHarchCmpltArchLoad #define archCmpltArchSave _SCOTCHarchCmpltArchSave #define archCmpltDomNum _SCOTCHarchCmpltDomNum #define archCmpltDomTerm _SCOTCHarchCmpltDomTerm #define archCmpltDomSize _SCOTCHarchCmpltDomSize /* #define archCmpltDomWght _SCOTCHarchCmpltDomWght Already a macro */ #define archCmpltDomDist _SCOTCHarchCmpltDomDist #define archCmpltDomFrst _SCOTCHarchCmpltDomFrst #define archCmpltDomIncl _SCOTCHarchCmpltDomIncl #define archCmpltDomLoad _SCOTCHarchCmpltDomLoad #define archCmpltDomSave _SCOTCHarchCmpltDomSave #define archCmpltDomBipart _SCOTCHarchCmpltDomBipart #define archCmpltDomMpiType _SCOTCHarchCmpltDomMpiType #define archCmpltwArchBuild _SCOTCHarchCmpltwArchBuild #define archCmpltwArchFree _SCOTCHarchCmpltwArchFree #define archCmpltwArchLoad _SCOTCHarchCmpltwArchLoad #define archCmpltwArchSave _SCOTCHarchCmpltwArchSave #define archCmpltwDomNum _SCOTCHarchCmpltwDomNum #define archCmpltwDomTerm _SCOTCHarchCmpltwDomTerm #define archCmpltwDomSize _SCOTCHarchCmpltwDomSize #define archCmpltwDomWght _SCOTCHarchCmpltwDomWght #define archCmpltwDomDist _SCOTCHarchCmpltwDomDist #define archCmpltwDomFrst _SCOTCHarchCmpltwDomFrst #define archCmpltwDomIncl _SCOTCHarchCmpltwDomIncl #define archCmpltwDomLoad _SCOTCHarchCmpltwDomLoad #define archCmpltwDomSave _SCOTCHarchCmpltwDomSave #define archCmpltwDomBipart _SCOTCHarchCmpltwDomBipart #define archCmpltwDomMpiType _SCOTCHarchCmpltwDomMpiType #define archDecoArchBuild _SCOTCHarchDecoArchBuild #define archDecoArchFree _SCOTCHarchDecoArchFree #define archDecoArchLoad _SCOTCHarchDecoArchLoad #define archDecoArchSave _SCOTCHarchDecoArchSave #define archDecoDomNum _SCOTCHarchDecoDomNum #define archDecoDomTerm _SCOTCHarchDecoDomTerm #define archDecoDomSize _SCOTCHarchDecoDomSize #define archDecoDomWght _SCOTCHarchDecoDomWght #define archDecoDomDist _SCOTCHarchDecoDomDist #define archDecoDomFrst _SCOTCHarchDecoDomFrst #define archDecoDomIncl _SCOTCHarchDecoDomIncl #define archDecoDomLoad _SCOTCHarchDecoDomLoad #define archDecoDomSave _SCOTCHarchDecoDomSave #define archDecoDomBipart _SCOTCHarchDecoDomBipart #define archDecoDomMpiType _SCOTCHarchDecoDomMpiType #define archDistArchLoad _SCOTCHarchDistArchLoad #define archDistArchSave _SCOTCHarchDistArchSave #define archDistArchBuild _SCOTCHarchDistArchBuild #define archDistDomNum _SCOTCHarchDistDomNum #define archDistDomTerm _SCOTCHarchDistDomTerm #define archDistDomSize _SCOTCHarchDistDomSize #define archDistDomWght _SCOTCHarchDistDomWght #define archDistDomDist _SCOTCHarchDistDomDist #define archDistDomFrst _SCOTCHarchDistDomFrst #define archDistDomIncl _SCOTCHarchDistDomIncl #define archDistDomLoad _SCOTCHarchDistDomLoad #define archDistDomSave _SCOTCHarchDistDomSave #define archDistDomBipart _SCOTCHarchDistDomBipart #define archDistDomMpiType _SCOTCHarchDistDomMpiType #define archHcubArchLoad _SCOTCHarchHcubArchLoad #define archHcubArchSave _SCOTCHarchHcubArchSave #define archHcubDomNum _SCOTCHarchHcubDomNum #define archHcubDomTerm _SCOTCHarchHcubDomTerm #define archHcubDomSize _SCOTCHarchHcubDomSize /* #define archHcubDomWght _SCOTCHarchHcubDomWght Already a macro */ #define archHcubDomDist _SCOTCHarchHcubDomDist #define archHcubDomFrst _SCOTCHarchHcubDomFrst #define archHcubDomIncl _SCOTCHarchHcubDomIncl #define archHcubDomLoad _SCOTCHarchHcubDomLoad #define archHcubDomSave _SCOTCHarchHcubDomSave #define archHcubDomBipart _SCOTCHarchHcubDomBipart #define archHcubDomMpiType _SCOTCHarchHcubDomMpiType #define archLtleafArchLoad _SCOTCHarchLtleafArchLoad #define archLtleafArchSave _SCOTCHarchLtleafArchSave #define archLtleafDomNum _SCOTCHarchLtleafDomNum #define archLtleafDomTerm _SCOTCHarchLtleafDomTerm #define archTleafArchLoad _SCOTCHarchTleafArchLoad #define archTleafArchFree _SCOTCHarchTleafArchFree #define archTleafArchSave _SCOTCHarchTleafArchSave #define archTleafDomNum _SCOTCHarchTleafDomNum #define archTleafDomTerm _SCOTCHarchTleafDomTerm #define archTleafDomSize _SCOTCHarchTleafDomSize /* #define archTleafDomWght _SCOTCHarchTleafDomWght Already a macro */ #define archTleafDomDist _SCOTCHarchTleafDomDist #define archTleafDomFrst _SCOTCHarchTleafDomFrst #define archTleafDomIncl _SCOTCHarchTleafDomIncl #define archTleafDomLoad _SCOTCHarchTleafDomLoad #define archTleafDomSave _SCOTCHarchTleafDomSave #define archTleafDomBipart _SCOTCHarchTleafDomBipart #define archTleafDomMpiType _SCOTCHarchTleafDomMpiType #define archMesh2ArchLoad _SCOTCHarchMesh2ArchLoad #define archMesh2ArchSave _SCOTCHarchMesh2ArchSave #define archMesh2DomNum _SCOTCHarchMesh2DomNum #define archMesh2DomTerm _SCOTCHarchMesh2DomTerm #define archMesh2DomSize _SCOTCHarchMesh2DomSize /* #define archMesh2DomWght _SCOTCHarchMesh2DomWght Already a macro */ #define archMesh2DomDist _SCOTCHarchMesh2DomDist #define archMesh2DomFrst _SCOTCHarchMesh2DomFrst #define archMesh2DomIncl _SCOTCHarchMesh2DomIncl #define archMesh2DomLoad _SCOTCHarchMesh2DomLoad #define archMesh2DomSave _SCOTCHarchMesh2DomSave #define archMesh2DomBipart _SCOTCHarchMesh2DomBipart #define archMesh2DomBipartO _SCOTCHarchMesh2DomBipartO #define archMesh2DomBipartU _SCOTCHarchMesh2DomBipartU #define archMesh2DomMpiType _SCOTCHarchMesh2DomMpiType #define archMesh3ArchLoad _SCOTCHarchMesh3ArchLoad #define archMesh3ArchSave _SCOTCHarchMesh3ArchSave #define archMesh3DomNum _SCOTCHarchMesh3DomNum #define archMesh3DomTerm _SCOTCHarchMesh3DomTerm #define archMesh3DomSize _SCOTCHarchMesh3DomSize /* #define archMesh3DomWght _SCOTCHarchMesh3DomWght Already a macro */ #define archMesh3DomDist _SCOTCHarchMesh3DomDist #define archMesh3DomFrst _SCOTCHarchMesh3DomFrst #define archMesh3DomIncl _SCOTCHarchMesh3DomIncl #define archMesh3DomLoad _SCOTCHarchMesh3DomLoad #define archMesh3DomSave _SCOTCHarchMesh3DomSave #define archMesh3DomBipart _SCOTCHarchMesh3DomBipart #define archMesh3DomMpiType _SCOTCHarchMesh3DomMpiType #define archTermArchLoad _SCOTCHarchTermArchLoad #define archTermArchSave _SCOTCHarchTermArchSave #define archTermDomNum _SCOTCHarchTermDomNum #define archTermDomTerm _SCOTCHarchTermDomTerm #define archTermDomSize _SCOTCHarchTermDomSize /* #define archTermDomWght _SCOTCHarchTermDomWght Already a macro */ #define archTermDomDist _SCOTCHarchTermDomDist #define archTermDomFrst _SCOTCHarchTermDomFrst #define archTermDomIncl _SCOTCHarchTermDomIncl #define archTermDomLoad _SCOTCHarchTermDomLoad #define archTermDomSave _SCOTCHarchTermDomSave #define archTermDomBipart _SCOTCHarchTermDomBipart #define archTermDomMpiType _SCOTCHarchTermDomMpiType #define archTorus2ArchLoad _SCOTCHarchTorus2ArchLoad #define archTorus2ArchSave _SCOTCHarchTorus2ArchSave #define archTorus2DomNum _SCOTCHarchTorus2DomNum #define archTorus2DomTerm _SCOTCHarchTorus2DomTerm #define archTorus2DomSize _SCOTCHarchTorus2DomSize /* #define archTorus2DomWght _SCOTCHarchTorus2DomWght Already a macro */ #define archTorus2DomDist _SCOTCHarchTorus2DomDist /* #define archTorus2DomFrst _SCOTCHarchTorus2DomFrst Already a macro */ #define archTorus2DomIncl _SCOTCHarchTorus2DomIncl #define archTorus2DomBipart _SCOTCHarchTorus2DomBipart /* #define archTorus2DomLoad _SCOTCHarchTorus2DomLoad Already a macro */ /* #define archTorus2DomSave _SCOTCHarchTorus2DomSave Already a macro */ #define archTorus2DomBipart _SCOTCHarchTorus2DomBipart /* #define archTorus2DomMpiType _SCOTCHarchTorus2DomMpiTypeA lready a macro */ #define archTorus3ArchLoad _SCOTCHarchTorus3ArchLoad #define archTorus3ArchSave _SCOTCHarchTorus3ArchSave #define archTorus3DomNum _SCOTCHarchTorus3DomNum #define archTorus3DomTerm _SCOTCHarchTorus3DomTerm #define archTorus3DomSize _SCOTCHarchTorus3DomSize /* #define archTorus3DomWght _SCOTCHarchTorus3DomWght Already a macro */ #define archTorus3DomDist _SCOTCHarchTorus3DomDist /* #define archTorus3DomFrst _SCOTCHarchTorus3DomFrst Already a macro */ #define archTorus3DomIncl _SCOTCHarchTorus3DomIncl /* #define archTorus3DomLoad _SCOTCHarchTorus3DomLoad Already a macro */ /* #define archTorus3DomSave _SCOTCHarchTorus3DomSave Already a macro */ #define archTorus3DomBipart _SCOTCHarchTorus3DomBipart /* #define archTorus3DomMpiType _SCOTCHarchTorus3DomMpiType Already a macro */ #define archTorusXArchLoad _SCOTCHarchTorusXArchLoad #define archTorusXArchSave _SCOTCHarchTorusXArchSave #define archTorusXDomNum _SCOTCHarchTorusXDomNum #define archTorusXDomTerm _SCOTCHarchTorusXDomTerm #define archTorusXDomSize _SCOTCHarchTorusXDomSize /* #define archTorusXDomWght _SCOTCHarchTorusXDomWght Already a macro */ #define archTorusXDomDist _SCOTCHarchTorusXDomDist #define archTorusXDomFrst _SCOTCHarchTorusXDomFrst #define archTorusXDomIncl _SCOTCHarchTorusXDomIncl #define archTorusXDomLoad _SCOTCHarchTorusXDomLoad #define archTorusXDomSave _SCOTCHarchTorusXDomSave #define archTorusXDomBipart _SCOTCHarchTorusXDomBipart #define archTorusXDomMpiType _SCOTCHarchTorusXDomMpiType /* #define archVcmpltArchLoad _SCOTCHarchVcmpltArchLoad Already a macro */ /* #define archVcmpltArchSave _SCOTCHarchVcmpltArchSave Already a macro */ #define archVcmpltDomNum _SCOTCHarchVcmpltDomNum #define archVcmpltDomTerm _SCOTCHarchVcmpltDomTerm #define archVcmpltDomSize _SCOTCHarchVcmpltDomSize /* #define archVcmpltDomWght _SCOTCHarchVcmpltDomWght Already a macro */ #define archVcmpltDomDist _SCOTCHarchVcmpltDomDist #define archVcmpltDomFrst _SCOTCHarchVcmpltDomFrst #define archVcmpltDomIncl _SCOTCHarchVcmpltDomIncl #define archVcmpltDomBipart _SCOTCHarchVcmpltDomBipart #define archVcmpltDomLoad _SCOTCHarchVcmpltDomLoad #define archVcmpltDomSave _SCOTCHarchVcmpltDomSave #define archVcmpltDomBipart _SCOTCHarchVcmpltDomBipart #define archVcmpltDomMpiType _SCOTCHarchVcmpltDomMpiType /* #define archVhcubArchLoad _SCOTCHarchVhcubArchLoad Already a macro */ /* #define archVhcubArchSave _SCOTCHarchVhcubArchSave Already a macro */ #define archVhcubDomNum _SCOTCHarchVhcubDomNum #define archVhcubDomTerm _SCOTCHarchVhcubDomTerm #define archVhcubDomSize _SCOTCHarchVhcubDomSize /* #define archVhcubDomWght _SCOTCHarchVhcubDomWght Already a macro */ #define archVhcubDomDist _SCOTCHarchVhcubDomDist #define archVhcubDomFrst _SCOTCHarchVhcubDomFrst #define archVhcubDomIncl _SCOTCHarchVhcubDomIncl #define archVhcubDomLoad _SCOTCHarchVhcubDomLoad #define archVhcubDomSave _SCOTCHarchVhcubDomSave #define archVhcubDomBipart _SCOTCHarchVhcubDomBipart #define archVhcubDomMpiType _SCOTCHarchVhcubDomMpiType #define bdgraphInit _SCOTCHbdgraphInit #define bdgraphInit2 _SCOTCHbdgraphInit2 #define bdgraphExit _SCOTCHbdgraphExit #define bdgraphZero _SCOTCHbdgraphZero #define bdgraphbipartststratab _SCOTCHbdgraphbipartststratab #define bdgraphCheck _SCOTCHbdgraphCheck #define bdgraphGatherAll _SCOTCHbdgraphGatherAll #define bdgraphBipartBd _SCOTCHbdgraphBipartBd #define bdgraphBipartDf _SCOTCHbdgraphBipartDf #define bdgraphBipartEx _SCOTCHbdgraphBipartEx #define bdgraphBipartMl _SCOTCHbdgraphBipartMl #define bdgraphBipartSq _SCOTCHbdgraphBipartSq #define bdgraphBipartSt _SCOTCHbdgraphBipartSt #define bdgraphBipartZr _SCOTCHbdgraphBipartZr #define bdgraphStoreInit _SCOTCHbdgraphStoreInit #define bdgraphStoreExit _SCOTCHbdgraphStoreExit #define bdgraphStoreSave _SCOTCHbdgraphStoreSave #define bdgraphStoreUpdt _SCOTCHbdgraphStoreUpdt #define bgraphbipartststratab _SCOTCHbgraphbipartststratab #define bgraphInit _SCOTCHbgraphInit #define bgraphInit2 _SCOTCHbgraphInit2 #define bgraphInit3 _SCOTCHbgraphInit3 #define bgraphInit4 _SCOTCHbgraphInit4 #define bgraphInit5 _SCOTCHbgraphInit5 #define bgraphExit _SCOTCHbgraphExit #define bgraphCheck _SCOTCHbgraphCheck #define bgraphSwal _SCOTCHbgraphSwal #define bgraphZero _SCOTCHbgraphZero #define bgraphBipartBd _SCOTCHbgraphBipartBd #define bgraphBipartDf _SCOTCHbgraphBipartDf #define bgraphBipartDf2 _SCOTCHbgraphBipartDf2 #define bgraphBipartDfJoin _SCOTCHbgraphBipartDfJoin #define bgraphBipartEx _SCOTCHbgraphBipartEx #define bgraphBipartFm _SCOTCHbgraphBipartFm #define bgraphBipartGg _SCOTCHbgraphBipartGg #define bgraphBipartGp _SCOTCHbgraphBipartGp #define bgraphBipartMl _SCOTCHbgraphBipartMl #define bgraphBipartSt _SCOTCHbgraphBipartSt #define bgraphBipartZr _SCOTCHbgraphBipartZr #define bgraphStoreInit _SCOTCHbgraphStoreInit #define bgraphStoreExit _SCOTCHbgraphStoreExit #define bgraphStoreSave _SCOTCHbgraphStoreSave #define bgraphStoreUpdt _SCOTCHbgraphStoreUpdt #if ((defined INTSIZE64) || (defined COMM)) #define commAllgatherv _SCOTCHcommAllgatherv #define commGatherv _SCOTCHcommGatherv #define commScatterv _SCOTCHcommScatterv #endif /* ((defined INTSIZE64) || (defined COMM)) */ #define dgraphAllreduceMaxSum2 _SCOTCHdgraphAllreduceMaxSum2 #define dgraphBuild _SCOTCHdgraphBuild #define dgraphBuild2 _SCOTCHdgraphBuild2 #define dgraphBuild3 _SCOTCHdgraphBuild3 #define dgraphBuild4 _SCOTCHdgraphBuild4 #define dgraphBuildGrid3D _SCOTCHdgraphBuildGrid3D #define dgraphBuildHcub _SCOTCHdgraphBuildHcub #define dgraphCheck _SCOTCHdgraphCheck #define dgraphBand _SCOTCHdgraphBand #define dgraphBandColl _SCOTCHdgraphBandColl #define dgraphBandPtop _SCOTCHdgraphBandPtop #define dgraphCoarsen _SCOTCHdgraphCoarsen #define dgraphExit _SCOTCHdgraphExit #define dgraphFold _SCOTCHdgraphFold #define dgraphFold2 _SCOTCHdgraphFold2 #define dgraphFoldComm _SCOTCHdgraphFoldComm #define dgraphFoldDup _SCOTCHdgraphFoldDup #define dgraphFree _SCOTCHdgraphFree #define dgraphGather _SCOTCHdgraphGather #define dgraphGatherAll _SCOTCHdgraphGatherAll #define dgraphGatherAll2 _SCOTCHdgraphGatherAll2 /* #define dgraphGhst _SCOTCHdgraphGhst Already a macro */ /* #define dgraphGhstReplace _SCOTCHdgraphGhstReplace Already a macro */ #define dgraphGhst2 _SCOTCHdgraphGhst2 #define dgraphGrow _SCOTCHdgraphGrow /* Used before macro replacement */ #define dgraphGrowColl _SCOTCHdgraphGrowColl #define dgraphGrowPtop _SCOTCHdgraphGrowPtop #define dgraphHaloSync _SCOTCHdgraphHaloSync #define dgraphHaloAsync _SCOTCHdgraphHaloAsync #define dgraphHaloWait _SCOTCHdgraphHaloWait #define dgraphHaloCheck _SCOTCHdgraphHaloCheck #define dgraphInduceList _SCOTCHdgraphInduceList #define dgraphInducePart _SCOTCHdgraphInducePart #define dgraphInduce2 _SCOTCHdgraphInduce2 #define dgraphInit _SCOTCHdgraphInit #define dgraphLoad _SCOTCHdgraphLoad #define dgraphMatchInit _SCOTCHdgraphMatchInit #define dgraphMatchExit _SCOTCHdgraphMatchExit #define dgraphMatchSync _SCOTCHdgraphMatchSync #define dgraphMatchSyncColl _SCOTCHdgraphMatchSyncColl #define dgraphMatchSyncPtop _SCOTCHdgraphMatchSyncPtop #define dgraphMatchCheck _SCOTCHdgraphMatchCheck #define dgraphMatchHl _SCOTCHdgraphMatchHl #define dgraphMatchHy _SCOTCHdgraphMatchHy #define dgraphMatchLc _SCOTCHdgraphMatchLc #define dgraphMatchLy _SCOTCHdgraphMatchLy #define dgraphMatchSc _SCOTCHdgraphMatchSc #define dgraphRedist _SCOTCHdgraphRedist #define dgraphSave _SCOTCHdgraphSave #define dgraphScatter _SCOTCHdgraphScatter #define dgraphView _SCOTCHdgraphView #define dmapInit _SCOTCHdmapInit #define dmapExit _SCOTCHdmapExit #define dmapAdd _SCOTCHdmapAdd #define dmapTerm _SCOTCHdmapTerm #define dmapSave _SCOTCHdmapSave #define dorderDispose _SCOTCHdorderDispose #define dorderExit _SCOTCHdorderExit #define dorderFree _SCOTCHdorderFree #define dorderFrst _SCOTCHdorderFrst #define dorderGather _SCOTCHdorderGather #define dorderGatherTree _SCOTCHdorderGatherTree #define dorderInit _SCOTCHdorderInit #define dorderNew _SCOTCHdorderNew #define dorderNewSequ _SCOTCHdorderNewSequ #define dorderNewSequIndex _SCOTCHdorderNewSequIndex #define dorderPerm _SCOTCHdorderPerm #define dorderSave _SCOTCHdorderSave #define dorderSaveBlock _SCOTCHdorderSaveBlock #define dorderSaveMap _SCOTCHdorderSaveMap #define dorderSaveTree _SCOTCHdorderSaveTree #define dorderSaveTree2 _SCOTCHdorderSaveTree2 #define dorderCblkDist _SCOTCHdorderCblkDist #define dorderTreeDist _SCOTCHdorderTreeDist #define fiboTreeCheck _SCOTCHfiboTreeCheck #define fiboTreeConsolidate _SCOTCHfiboTreeConsolidate /* #define fiboTreeAdd _SCOTCHfiboTreeAdd Already a macro */ #define fiboTreeDel _SCOTCHfiboTreeDel #define fiboTreeExit _SCOTCHfiboTreeExit #define fiboTreeFree _SCOTCHfiboTreeFree #define fiboTreeInit _SCOTCHfiboTreeInit #define fiboTreeMin _SCOTCHfiboTreeMin #define gainTablAddLin _SCOTCHgainTablAddLin #define gainTablAddLog _SCOTCHgainTablAddLog #define gainTablCheck _SCOTCHgainTablCheck #ifdef SCOTCH_DEBUG_GAIN1 /* If not already redefined as accelerated macro */ #define gainTablDel _SCOTCHgainTablDel #endif /* SCOTCH_DEBUG_GAIN1 */ #define gainTablExit _SCOTCHgainTablExit #define gainTablFree _SCOTCHgainTablFree #define gainTablFrst _SCOTCHgainTablFrst #define gainTablInit _SCOTCHgainTablInit #define gainTablNext _SCOTCHgainTablNext #define geomExit _SCOTCHgeomExit #define geomInit _SCOTCHgeomInit #define graphInit _SCOTCHgraphInit #define graphExit _SCOTCHgraphExit #define graphFree _SCOTCHgraphFree #define graphLoad _SCOTCHgraphLoad #define graphLoad2 _SCOTCHgraphLoad2 #define graphSave _SCOTCHgraphSave #define graphBand _SCOTCHgraphBand #define graphBase _SCOTCHgraphBase #define graphCheck _SCOTCHgraphCheck #define graphCoarsen _SCOTCHgraphCoarsen #define graphInduceList _SCOTCHgraphInduceList #define graphInducePart _SCOTCHgraphInducePart #define graphMatch _SCOTCHgraphMatch #define graphMatchInit _SCOTCHgraphMatchInit #define graphGeomLoadChac _SCOTCHgraphGeomLoadChac #define graphGeomLoadHabo _SCOTCHgraphGeomLoadHabo #define graphGeomLoadMmkt _SCOTCHgraphGeomLoadMmkt #define graphGeomLoadScot _SCOTCHgraphGeomLoadScot #define graphGeomSaveChac _SCOTCHgraphGeomSaveChac #define graphGeomSaveScot _SCOTCHgraphGeomSaveScot #define graphGeomSaveMmkt _SCOTCHgraphGeomSaveMmkt #define graphPtscotch _SCOTCHgraphPtscotch #define hallOrderHdHalmd _SCOTCHhallOrderHdHalmd #define hallOrderHfR2hamdf4 _SCOTCHhallOrderHfR2hamdf4 #define hallOrderHxBuild _SCOTCHhallOrderHxBuild #define hallOrderHxTree _SCOTCHhallOrderHxTree #define hdgraphorderststratab _SCOTCHhdgraphorderststratab #define hdgraphInit _SCOTCHhdgraphInit #define hdgraphExit _SCOTCHhdgraphExit #define hdgraphCheck _SCOTCHhdgraphCheck #define hdgraphFold _SCOTCHhdgraphFold #define hdgraphFold2 _SCOTCHhdgraphFold2 #define hdgraphGather _SCOTCHhdgraphGather #define hdgraphInduceList _SCOTCHhdgraphInduceList #define hdgraphOrderNd _SCOTCHhdgraphOrderNd #define hdgraphOrderSi _SCOTCHhdgraphOrderSi #define hdgraphOrderSq _SCOTCHhdgraphOrderSq #define hdgraphOrderSq2 _SCOTCHhdgraphOrderSq2 #define hdgraphOrderSt _SCOTCHhdgraphOrderSt #define hgraphorderststratab _SCOTCHhgraphorderststratab #define hgraphInit _SCOTCHhgraphInit #define hgraphExit _SCOTCHhgraphExit #define hgraphFree _SCOTCHhgraphFree #define hgraphInduceList _SCOTCHhgraphInduceList #define hgraphCheck _SCOTCHhgraphCheck #define hgraphOrderBl _SCOTCHhgraphOrderBl #define hgraphOrderCp _SCOTCHhgraphOrderCp #define hgraphOrderGp _SCOTCHhgraphOrderGp #define hgraphOrderHd _SCOTCHhgraphOrderHd #define hgraphOrderHf _SCOTCHhgraphOrderHf #define hgraphOrderHxFill _SCOTCHhgraphOrderHxFill #define hgraphOrderKp _SCOTCHhgraphOrderKp #define hgraphOrderNd _SCOTCHhgraphOrderNd #define hgraphOrderSi _SCOTCHhgraphOrderSi #define hgraphOrderSt _SCOTCHhgraphOrderSt #define hgraphUnhalo _SCOTCHhgraphUnhalo #define hmeshorderststratab _SCOTCHhmeshorderststratab #define hmeshExit _SCOTCHhmeshExit #define hmeshBase _SCOTCHhmeshBase #define hmeshCheck _SCOTCHhmeshCheck #define hmeshInducePart _SCOTCHhmeshInducePart #define hmeshHgraph _SCOTCHhmeshHgraph #define hmeshMesh _SCOTCHhmeshMesh #define hmeshOrderBl _SCOTCHhmeshOrderBl #define hmeshOrderCp _SCOTCHhmeshOrderCp #define hmeshOrderGp _SCOTCHhmeshOrderGp #define hmeshOrderGr _SCOTCHhmeshOrderGr #define hmeshOrderHd _SCOTCHhmeshOrderHd #define hmeshOrderHf _SCOTCHhmeshOrderHf #define hmeshOrderHxFill _SCOTCHhmeshOrderHxFill #define hmeshOrderNd _SCOTCHhmeshOrderNd #define hmeshOrderSi _SCOTCHhmeshOrderSi #define hmeshOrderSt _SCOTCHhmeshOrderSt #define kdgraphmapststratab _SCOTCHkdgraphmapststratab #define kdgraphInit _SCOTCHkdgraphInit #define kdgraphExit _SCOTCHkdgraphExit #define kdgraphGather _SCOTCHkdgraphGather #define kdgraphMapRb _SCOTCHkdgraphMapRb #define kdgraphMapRbAdd2 _SCOTCHkdgraphMapRbAdd2 #define kdgraphMapRbAddBoth _SCOTCHkdgraphMapRbAddBoth #define kdgraphMapRbAddOne _SCOTCHkdgraphMapRbAddOne #define kdgraphMapRbAddPart _SCOTCHkdgraphMapRbAddPart #define kdgraphMapRbMap _SCOTCHkdgraphMapRbMap #define kdgraphMapRbPart _SCOTCHkdgraphMapRbPart #define kdgraphMapSt _SCOTCHkdgraphMapSt #define kgraphmapststratab _SCOTCHkgraphmapststratab #define kgraphInit _SCOTCHkgraphInit #define kgraphExit _SCOTCHkgraphExit #define kgraphCheck _SCOTCHkgraphCheck #define kgraphBand _SCOTCHkgraphBand #define kgraphCost _SCOTCHkgraphCost #define kgraphFron _SCOTCHkgraphFron #define kgraphFrst _SCOTCHkgraphFrst #define kgraphMapBd _SCOTCHkgraphMapBd #define kgraphMapCp _SCOTCHkgraphMapCp #define kgraphMapDf _SCOTCHkgraphMapDf #define kgraphMapEx _SCOTCHkgraphMapEx #define kgraphMapFm _SCOTCHkgraphMapFm #define kgraphMapMl _SCOTCHkgraphMapMl #define kgraphMapRb _SCOTCHkgraphMapRb #define kgraphMapRbMap _SCOTCHkgraphMapRbMap #define kgraphMapRbBgraph _SCOTCHkgraphMapRbBgraph #define kgraphMapRbPart _SCOTCHkgraphMapRbPart #define kgraphMapRbVfloBuild _SCOTCHkgraphMapRbVfloBuild #define kgraphMapRbVfloMerge _SCOTCHkgraphMapRbVfloMerge #define kgraphMapRbVfloSplit _SCOTCHkgraphMapRbVfloSplit #define kgraphMapSt _SCOTCHkgraphMapSt #define kgraphStoreInit _SCOTCHkgraphStoreInit #define kgraphStoreExit _SCOTCHkgraphStoreExit #define kgraphStoreSave _SCOTCHkgraphStoreSave #define kgraphStoreUpdt _SCOTCHkgraphStoreUpdt #define listInit _SCOTCHlistInit #define listExit _SCOTCHlistExit #define listAlloc _SCOTCHlistAlloc #define listFree _SCOTCHlistFree #define listLoad _SCOTCHlistLoad #define listSave _SCOTCHlistSave #define listSort _SCOTCHlistSort #define listCopy _SCOTCHlistCopy #define mapInit _SCOTCHmapInit #define mapInit2 _SCOTCHmapInit2 #define mapExit _SCOTCHmapExit #define mapAlloc _SCOTCHmapAlloc #define mapBuild _SCOTCHmapBuild #define mapCopy _SCOTCHmapCopy #define mapFree _SCOTCHmapFree #define mapFrst _SCOTCHmapFrst #define mapLoad _SCOTCHmapLoad #define mapMerge _SCOTCHmapMerge #define mapResize _SCOTCHmapResize #define mapResize2 _SCOTCHmapResize2 #define mapSave _SCOTCHmapSave #define mapTerm _SCOTCHmapTerm #define meshInit _SCOTCHmeshInit #define meshExit _SCOTCHmeshExit #define meshFree _SCOTCHmeshFree #define meshLoad _SCOTCHmeshLoad #define meshSave _SCOTCHmeshSave #define meshBase _SCOTCHmeshBase #define meshGraph _SCOTCHmeshGraph #define meshCoarsen _SCOTCHmeshCoarsen #define meshInduceList _SCOTCHmeshInduceList #define meshInducePart _SCOTCHmeshInducePart #define meshInduceSepa _SCOTCHmeshInduceSepa #define meshCheck _SCOTCHmeshCheck #define meshGeomLoadHabo _SCOTCHmeshGeomLoadHabo #define meshGeomLoadScot _SCOTCHmeshGeomLoadScot #define meshGeomSaveScot _SCOTCHmeshGeomSaveScot #define orderInit _SCOTCHorderInit #define orderExit _SCOTCHorderExit #define orderLoad _SCOTCHorderLoad #define orderSave _SCOTCHorderSave #define orderSaveMap _SCOTCHorderSaveMap #define orderSaveTree _SCOTCHorderSaveTree #define orderCheck _SCOTCHorderCheck #define orderPeri _SCOTCHorderPeri #define orderRang _SCOTCHorderRang #define orderTree _SCOTCHorderTree #define parsermethtokentab _SCOTCHparsermethtokentab #define parserparamcurr _SCOTCHparserparamcurr #define parserstratcurr _SCOTCHparserstratcurr #define parserstrattab _SCOTCHparserstrattab #define stratdummy _SCOTCHstratdummy #define stratInit _SCOTCHstratInit #define stratExit _SCOTCHstratExit #define stratSave _SCOTCHstratSave #define stratCondEval _SCOTCHstratCondEval #define stratCondExit _SCOTCHstratCondExit #define stratCondSave _SCOTCHstratCondSave #define stratParserInit _SCOTCHstratParserInit #define stratParserInput _SCOTCHstratParserInput #define stratParserLex _SCOTCHstratParserLex #define stratParserRemain _SCOTCHstratParserRemain #define stratParserSelect _SCOTCHstratParserSelect #define stratParserError _SCOTCHstratParserError #define stratParserParse _SCOTCHstratParserParse #define stratParserParse2 _SCOTCHstratParserParse2 #define stratTestEval _SCOTCHstratTestEval #define stratTestExit _SCOTCHstratTestExit #define stratTestSave _SCOTCHstratTestSave #define threadLaunch _SCOTCHthreadLaunch #define threadReduce _SCOTCHthreadReduce #define threadScan _SCOTCHthreadScan #define vdgraphseparateststratab _SCOTCHvdgraphseparateststratab #define vdgraphCheck _SCOTCHvdgraphCheck #define vdgraphExit _SCOTCHvdgraphExit #define vdgraphGatherAll _SCOTCHvdgraphGatherAll #define vdgraphInit _SCOTCHvdgraphInit #define vdgraphSeparateBd _SCOTCHvdgraphSeparateBd #define vdgraphSeparateDf _SCOTCHvdgraphSeparateDf #define vdgraphSeparateMl _SCOTCHvdgraphSeparateMl #define vdgraphSeparateSq _SCOTCHvdgraphSeparateSq #define vdgraphSeparateSt _SCOTCHvdgraphSeparateSt #define vdgraphSeparateZr _SCOTCHvdgraphSeparateZr #define vdgraphStoreExit _SCOTCHvdgraphStoreExit #define vdgraphStoreInit _SCOTCHvdgraphStoreInit #define vdgraphStoreSave _SCOTCHvdgraphStoreSave #define vdgraphStoreUpdt _SCOTCHvdgraphStoreUpdt #define vdgraphZero _SCOTCHvdgraphZero #define vgraphseparateststratab _SCOTCHvgraphseparateststratab #define vgraphInit _SCOTCHvgraphInit #define vgraphExit _SCOTCHvgraphExit #define vgraphCheck _SCOTCHvgraphCheck #define vgraphZero _SCOTCHvgraphZero #define vgraphSeparateBd _SCOTCHvgraphSeparateBd #define vgraphSeparateDf _SCOTCHvgraphSeparateDf #define vgraphSeparateEs _SCOTCHvgraphSeparateEs #define vgraphSeparateFm _SCOTCHvgraphSeparateFm #define vgraphSeparateGg _SCOTCHvgraphSeparateGg #define vgraphSeparateGp _SCOTCHvgraphSeparateGp #define vgraphSeparateMl _SCOTCHvgraphSeparateMl #define vgraphSeparateMt _SCOTCHvgraphSeparateMt #define vgraphSeparateSt _SCOTCHvgraphSeparateSt #define vgraphSeparateTh _SCOTCHvgraphSeparateTh #define vgraphSeparateVw _SCOTCHvgraphSeparateVw #define vgraphSeparateZr _SCOTCHvgraphSeparateZr #define vgraphStoreInit _SCOTCHvgraphStoreInit #define vgraphStoreExit _SCOTCHvgraphStoreExit #define vgraphStoreSave _SCOTCHvgraphStoreSave #define vgraphStoreUpdt _SCOTCHvgraphStoreUpdt #define vmeshseparateststratab _SCOTCHvmeshseparateststratab #define vmeshExit _SCOTCHvmeshExit #define vmeshCheck _SCOTCHvmeshCheck #define vmeshZero _SCOTCHvmeshZero #define vmeshSeparateFm _SCOTCHvmeshSeparateFm #define vmeshSeparateGg _SCOTCHvmeshSeparateGg #define vmeshSeparateGr _SCOTCHvmeshSeparateGr #define vmeshSeparateMl _SCOTCHvmeshSeparateMl #define vmeshSeparateSt _SCOTCHvmeshSeparateSt #define vmeshSeparateZr _SCOTCHvmeshSeparateZr #define vmeshStoreInit _SCOTCHvmeshStoreInit #define vmeshStoreExit _SCOTCHvmeshStoreExit #define vmeshStoreSave _SCOTCHvmeshStoreSave #define vmeshStoreUpdt _SCOTCHvmeshStoreUpdt #define wgraphpartststratab _SCOTCHwgraphpartststratab #define wgraphAlloc _SCOTCHwgraphAlloc #define wgraphInit _SCOTCHwgraphInit #define wgraphExit _SCOTCHwgraphExit #define wgraphCheck _SCOTCHwgraphCheck #define wgraphZero _SCOTCHwgraphZero #define wgraphPartFm _SCOTCHwgraphPartFm #define wgraphPartGg _SCOTCHwgraphPartGg #define wgraphPartGp _SCOTCHwgraphPartGp #define wgraphPartMl _SCOTCHwgraphPartMl #define wgraphPartRb _SCOTCHwgraphPartRb #define wgraphPartSt _SCOTCHwgraphPartSt #define wgraphPartZr _SCOTCHwgraphPartZr #define wgraphStoreInit _SCOTCHwgraphStoreInit #define wgraphStoreExit _SCOTCHwgraphStoreExit #define wgraphStoreSave _SCOTCHwgraphStoreSave #define wgraphStoreUpdt _SCOTCHwgraphStoreUpdt #endif /* SCOTCH_RENAME */ scotch-6.0.4.dfsg/src/libscotch/bdgraph_bipart_ml.c0000644002563400244210000010641512412035044025440 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bdgraph_bipart_ml.c **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module bipartitions a distributed **/ /** graph using a multi-level scheme. **/ /** **/ /** DATES : # Version 5.1 : from : 30 oct 2007 **/ /** to : 14 apr 2011 **/ /** : # Version 6.0 : from : 11 sep 2011 **/ /** to : 28 sep 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define BDGRAPH_BIPART_ML #include "module.h" #include "common.h" #include "parser.h" #include "arch.h" #include "dgraph.h" #include "dgraph_coarsen.h" #include "bdgraph.h" #include "bdgraph_bipart_ml.h" #include "bdgraph_bipart_st.h" /*********************************************/ /* */ /* The coarsening and uncoarsening routines. */ /* */ /*********************************************/ /* This routine builds a coarser graph from the ** Dgraph that is given on input. The coarser ** Dgraphs differ at this stage from classical ** active Dgraphs as their internal gains are not ** yet computed. ** It returns: ** - 0 : if the coarse Dgraph has been built. ** - 1 : if threshold reached or on error. */ static int bdgraphBipartMlCoarsen ( Bdgraph * restrict const finegrafptr, /*+ Finer graph +*/ Bdgraph * restrict const coargrafptr, /*+ Coarser graph to build +*/ DgraphCoarsenMulti * restrict * const coarmultptr, /*+ Pointer to multinode table to build +*/ const BdgraphBipartMlParam * const paraptr) /*+ Method parameters +*/ { int foldval; switch (paraptr->foldval) { case 0 : foldval = DGRAPHCOARSENNONE; break; case 1 : foldval = DGRAPHCOARSENFOLD; break; case 2 : foldval = DGRAPHCOARSENFOLDDUP; break; #ifdef SCOTCH_DEBUG_BGRAPH2 default : errorPrint ("bdgraphBipartMlCoarsen: invalid parameter"); return (1); #endif /* SCOTCH_DEBUG_BDGRAPH2 */ } if ((finegrafptr->s.vertglbnbr / finegrafptr->s.procglbnbr) > paraptr->foldmax) /* If no need to fold */ foldval = DGRAPHCOARSENNONE; *coarmultptr = NULL; /* Let the routine create the multinode array */ dgraphInit (&coargrafptr->s, finegrafptr->s.proccomm); /* Re-use fine graph communicator */ if (dgraphCoarsen (&finegrafptr->s, &coargrafptr->s, coarmultptr, paraptr->passnbr, paraptr->coarnbr, paraptr->coarrat, foldval) != 0) return (1); /* Return if coarsening failed */ *coarmultptr -= coargrafptr->s.baseval; /* Base pointer to multinode array */ coargrafptr->partgsttax = NULL; /* Do not allocate partition data yet */ coargrafptr->fronloctab = NULL; coargrafptr->fronglbnbr = 0; if (coargrafptr->s.procglbnbr == 0) { /* Not owner of graph */ coargrafptr->veexloctax = NULL; return (0); } if (finegrafptr->veexloctax != NULL) { /* Merge external gains for coarsened vertices */ DgraphCoarsenMulti * restrict coarmulttax; Gnum * restrict coarveexloctax; Gnum coarvertlocnum; if ((coarveexloctax = (Gnum *) memAlloc (coargrafptr->s.vertlocnbr * sizeof (Gnum))) == NULL) { errorPrint ("bdgraphBipartMlCoarsen: out of memory"); dgraphExit (&coargrafptr->s); /* Only free Dgraph since veexloctax not allocated */ memFree (*coarmultptr + coargrafptr->s.baseval); return (1); } coarveexloctax -= coargrafptr->s.baseval; coargrafptr->veexloctax = coarveexloctax; coarmulttax = *coarmultptr; for (coarvertlocnum = coargrafptr->s.baseval; coarvertlocnum < coargrafptr->s.vertlocnnd; coarvertlocnum++) { Gnum finevertnum0; /* First multinode vertex */ Gnum finevertnum1; /* Second multinode vertex */ finevertnum0 = coarmulttax[coarvertlocnum].vertglbnum[0]; finevertnum1 = coarmulttax[coarvertlocnum].vertglbnum[1]; coarveexloctax[coarvertlocnum] = (finevertnum0 != finevertnum1) ? finegrafptr->veexloctax[finevertnum0] + finegrafptr->veexloctax[finevertnum1] : finegrafptr->veexloctax[finevertnum0]; } } else /* If fine graph does not have external gains */ coargrafptr->veexloctax = NULL; /* Coarse graph does not have external gains */ coargrafptr->veexglbsum = finegrafptr->veexglbsum; coargrafptr->compglbload0min = finegrafptr->compglbload0min; /* Only set constant partition parameters as others will be set on uncoarsening */ coargrafptr->compglbload0max = finegrafptr->compglbload0max; coargrafptr->compglbload0avg = finegrafptr->compglbload0avg; coargrafptr->commglbloadextn0 = finegrafptr->commglbloadextn0; coargrafptr->commglbgainextn0 = finegrafptr->commglbgainextn0; coargrafptr->domndist = finegrafptr->domndist; coargrafptr->domnwght[0] = finegrafptr->domnwght[0]; coargrafptr->domnwght[1] = finegrafptr->domnwght[1]; coargrafptr->levlnum = finegrafptr->levlnum + 1; return (0); } /* This routine is the reduction-loc operator which ** returns in inout[2] the rank of the process which ** holds the best partition. ** It returns: ** - void : in all cases. */ static void bdgraphBipartMlOpBest ( const Gnum * const in, /* First operand */ Gnum * const inout, /* Second and output operand */ const int * const len, /* Number of instances ; should be 1, not used */ const MPI_Datatype * const typedat) /* MPI datatype ; not used */ { inout[5] |= in[5]; /* Memory error flag */ if (inout[0] == 1) { /* Handle cases when at least one of them is erroneous */ if (in[0] == 1) { if (inout[1] > in[1]) /* To enforce commutativity, always keep smallest process number */ inout[1] = in[1]; inout[2] = in[2]; return; } inout[0] = in[0]; /* Validity flag */ inout[1] = in[1]; /* Lead process rank */ inout[2] = in[2]; /* Lead process color */ inout[3] = in[3]; /* Communication load */ inout[4] = in[4]; /* Load imbalance */ return; } else if (in[0] == 1) return; if ((in[3] < inout[3]) || /* Select best partition */ ((in[3] == inout[3]) && ((in[4] < inout[4]) || ((in[4] == inout[4]) && (in[1] < inout[1]))))) { inout[1] = in[1]; inout[2] = in[2]; inout[3] = in[3]; inout[4] = in[4]; } } /* This routine propagates the bipartitioning of the ** coarser graph back to the finer graph, according ** to the multinode table of collapsed vertices. ** After the bipartitioning is propagated, it finishes ** to compute the parameters of the finer graph that ** were not computed at the coarsening stage. ** It returns: ** - 0 : if coarse graph data has been propagated to fine graph. ** - !0 : on error. */ static int bdgraphBipartMlUncoarsen ( Bdgraph * restrict finegrafptr, /*+ Finer graph +*/ const Bdgraph * restrict const coargrafptr, /*+ Coarser graph +*/ const DgraphCoarsenMulti * restrict const coarmulttax) /*+ Multinode array +*/ { Gnum baseval; Gnum finefronlocnbr; Gnum finefronlocnum; Gnum fineedlolocval; Gnum finevertlocadj; /* Global vertex adjustment */ Gnum finevertlocnum; Gnum finevertlocnnd; /* Index for frontier array fronloctab */ Gnum finecomplocsize1; Gnum finecomplocload1; Gnum finecommlocloadintn; Gnum finecommlocloadextn; Gnum finecommlocgainextn; int vrcvdspnbr; int vsnddspnbr; int * restrict vrcvcnttab; int * restrict vsndcnttab; int * restrict vrcvdsptab; int * restrict vsnddsptab; Gnum * restrict vrcvdattab; Gnum * restrict vsnddattab; Gnum * restrict vsndidxtab; BdgraphBipartMlSort * restrict sortloctab; /* Array of vertices to send to their owner */ Gnum sortlocnbr; Gnum sortlocnum; int procnum; MPI_Datatype besttypedat; /* Data type for finding best bipartition */ MPI_Op bestoperdat; /* Handle of MPI operator for finding best bipartition */ Gnum reduloctab[6]; /* "6": both for selecting best and propagating data */ Gnum reduglbtab[6]; const Gnum * restrict coarfronloctab; GraphPart * restrict coarpartgsttax; GraphPart * restrict finepartgsttax; Gnum * restrict finefronloctab; const int fineprocglbnbr = finegrafptr->s.procglbnbr; const Gnum * restrict const fineprocvrttab = finegrafptr->s.procvrttab; const Gnum * restrict const fineedgegsttax = finegrafptr->s.edgegsttax; const Gnum * restrict const finevertloctax = finegrafptr->s.vertloctax; const Gnum * restrict const finevendloctax = finegrafptr->s.vendloctax; const Gnum * restrict const fineveloloctax = finegrafptr->s.veloloctax; const Gnum * restrict const fineveexloctax = finegrafptr->veexloctax; const Gnum * restrict const fineedloloctax = finegrafptr->s.edloloctax; reduloctab[5] = 0; /* Assume everything is fine */ if (finegrafptr->partgsttax == NULL) { /* If partition array not yet allocated */ if (dgraphGhst (&finegrafptr->s) != 0) { /* Create ghost edge array and compute vertgstnbr */ errorPrint ("bdgraphBipartMlUncoarsen: cannot compute ghost edge array"); reduloctab[5] = 1; /* Allocated data will be freed along with graph structure */ } else if ((finegrafptr->partgsttax = (GraphPart *) memAlloc (finegrafptr->s.vertgstnbr * sizeof (GraphPart))) == NULL) { errorPrint ("bdgraphBipartMlUncoarsen: out of memory (1)"); reduloctab[5] = 1; /* Allocated data will be freed along with graph structure */ } else if (finegrafptr->partgsttax -= finegrafptr->s.baseval, (finegrafptr->fronloctab = (Gnum *) memAlloc (finegrafptr->s.vertlocnbr * sizeof (Gnum))) == NULL) { errorPrint ("bdgraphBipartMlUncoarsen: out of memory (2)"); reduloctab[5] = 1; /* Allocated data will be freed along with graph structure */ } } if (coargrafptr == NULL) { /* If coarser graph not provided */ #ifdef SCOTCH_DEBUG_BDGRAPH1 /* Communication cannot be overlapped by a useful one */ if (MPI_Allreduce (&reduloctab[5], &reduglbtab[5], 1, GNUM_MPI, MPI_SUM, finegrafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphBipartMlUncoarsen: communication error (1)"); return (1); } #else /* SCOTCH_DEBUG_BDGRAPH1 */ reduglbtab[5] = reduloctab[5]; #endif /* SCOTCH_DEBUG_BDGRAPH1 */ if (reduglbtab[5] != 0) return (1); bdgraphZero (finegrafptr); /* Assign all vertices to part 0 */ #ifdef SCOTCH_DEBUG_BDGRAPH2 if (bdgraphCheck (finegrafptr) != 0) { errorPrint ("bdgraphBipartMlUncoarsen: inconsistent graph data (1)"); return (1); } #endif /* SCOTCH_DEBUG_BDGRAPH2 */ return (0); } if (coargrafptr->s.procglbnbr <= 0) { /* If unused folded coargrafptr */ reduloctab[0] = 1; /* Set it as invalid */ reduloctab[1] = 0; /* Useless rank */ reduloctab[2] = 1; /* Color is not the one of folded */ reduloctab[3] = /* Prevent Valgrind from yelling */ reduloctab[4] = 0; } else { reduloctab[0] = ((coargrafptr->compglbload0 == 0) || /* Empty subdomains are deemed invalid */ (coargrafptr->compglbload0 == coargrafptr->s.veloglbsum)) ? 1 : 0; reduloctab[1] = finegrafptr->s.proclocnum; /* Set rank and color key according to coarse graph (sub)communicator */ reduloctab[2] = finegrafptr->s.prockeyval; reduloctab[3] = coargrafptr->commglbload; reduloctab[4] = coargrafptr->compglbload0dlt; } if ((MPI_Type_contiguous (6, GNUM_MPI, &besttypedat) != MPI_SUCCESS) || (MPI_Type_commit (&besttypedat) != MPI_SUCCESS) || (MPI_Op_create ((MPI_User_function *) bdgraphBipartMlOpBest, 1, &bestoperdat) != MPI_SUCCESS)) { errorPrint ("bdgraphBipartMlUncoarsen: communication error (2)"); return (1); } if (MPI_Allreduce (reduloctab, reduglbtab, 1, besttypedat, bestoperdat, finegrafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphBipartMlUncoarsen: communication error (3)"); return (1); } if ((MPI_Op_free (&bestoperdat) != MPI_SUCCESS) || (MPI_Type_free (&besttypedat) != MPI_SUCCESS)) { errorPrint ("bdgraphBipartMlUncoarsen: communication error (4)"); return (1); } if (reduglbtab[5] != 0) /* If memory error, return */ return (1); if (reduglbtab[0] == 1) { /* If all possible partitions are invalid */ #ifdef SCOTCH_DEBUG_BDGRAPH2 errorPrintW ("bdgraphBipartMlUncoarsen: no valid partition"); #endif /* SCOTCH_DEBUG_BDGRAPH2 */ return (1); /* All invalid partitions will lead to low method be applied at upper level */ } if (memAllocGroup ((void **) (void *) &vrcvcnttab, (size_t) (fineprocglbnbr * sizeof (int)), &vrcvdsptab, (size_t) (fineprocglbnbr * sizeof (int)), &vsnddsptab, (size_t) (fineprocglbnbr * sizeof (int)), &vsndcnttab, (size_t) (fineprocglbnbr * sizeof (int)), &vsndidxtab, (size_t) (fineprocglbnbr * sizeof (Gnum) * 4), /* TRICK: sortloctab after vsndidxtab after vsndcnttab */ &sortloctab, (size_t) (2 * coargrafptr->s.vertlocnbr * sizeof (BdgraphBipartMlSort)), NULL) == NULL) { errorPrint ("bdgraphBipartMlUncoarsen: out of memory (3)"); reduloctab[5] = 1; } #ifdef SCOTCH_DEBUG_BDGRAPH1 /* Communication cannot be overlapped by a useful one */ if (MPI_Allreduce (&reduloctab[5], &reduglbtab[5], 1, GNUM_MPI, MPI_SUM, finegrafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphBipartMlUncoarsen: communication error (5)"); return (1); } #else /* SCOTCH_DEBUG_BDGRAPH1 */ reduglbtab[5] = reduloctab[5]; #endif /* SCOTCH_DEBUG_BDGRAPH1 */ if (reduglbtab[5] != 0) { if (vrcvcnttab != NULL) memFree (vrcvcnttab); return (1); } memSet (vsndcnttab, 0, ((byte *) sortloctab) - ((byte *) vsndcnttab)); /* TRICK: sortloctab after vsndidxtab after vsndcnttab */ baseval = finegrafptr->s.baseval; coarfronloctab = coargrafptr->fronloctab; coarpartgsttax = coargrafptr->partgsttax; finepartgsttax = finegrafptr->partgsttax; finevertlocnnd = finegrafptr->s.vertlocnnd; finevertlocadj = finegrafptr->s.procvrttab[finegrafptr->s.proclocnum] - baseval; finefronloctab = finegrafptr->fronloctab; finecomplocsize1 = 0; finecomplocload1 = 0; finecommlocloadextn = 0; finecommlocgainextn = 0; #ifdef SCOTCH_DEBUG_BDGRAPH2 memSet (finepartgsttax + baseval, ~0, finegrafptr->s.vertgstnbr * sizeof (GraphPart)); /* All vertices are unvisited */ #endif /* SCOTCH_DEBUG_BDGRAPH2 */ finefronlocnbr = 0; sortlocnbr = 0; if (reduglbtab[2] == (Gnum) coargrafptr->s.prockeyval) { /* If we belong to the group of the lead process, we must browse and send local data */ Gnum coarfronlocnum; Gnum coarvertlocnum; for (coarfronlocnum = 0; coarfronlocnum < coargrafptr->fronlocnbr; coarfronlocnum ++) coarpartgsttax[coarfronloctab[coarfronlocnum]] |= 2; /* Flag vertex as belonging to frontier */ for (coarvertlocnum = baseval; coarvertlocnum < coargrafptr->s.vertlocnnd; coarvertlocnum ++) { GraphPart coarpartval; Gnum coarpartmsk; Gnum finevertglbnum; Gnum finevertlocnum; int i; coarpartval = coarpartgsttax[coarvertlocnum]; coarpartmsk = (Gnum) (coarpartval & 1); i = 0; do { finevertglbnum = coarmulttax[coarvertlocnum].vertglbnum[i]; finevertlocnum = finevertglbnum - finevertlocadj; if ((finevertlocnum >= baseval) && /* If vertex is local */ (finevertlocnum < finevertlocnnd)) { #ifdef SCOTCH_DEBUG_BDGRAPH2 if (finepartgsttax[finevertlocnum] != ((GraphPart) ~0)) { errorPrint ("bdgraphBipartMlUncoarsen: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_BDGRAPH2 */ finepartgsttax[finevertlocnum] = (coarpartval & 1); finecomplocsize1 += coarpartmsk; /* One extra vertex created in part 1 if (coarpartval == 1) */ if ((coarpartval & 2) != 0) /* If coarse frontier vertex, add fine vertex to fine frontier */ finefronloctab[finefronlocnbr ++] = finevertlocnum; if (fineveloloctax != NULL) { Gnum veloval; veloval = fineveloloctax[finevertlocnum]; finecomplocload1 += veloval & (- coarpartmsk); } if (fineveexloctax != NULL) { Gnum veexval; veexval = fineveexloctax[finevertlocnum]; finecommlocloadextn += veexval * coarpartmsk; finecommlocgainextn += veexval * (1 - 2 * coarpartmsk); } } else { int procngbnum; int procngbmax; procngbnum = 0; procngbmax = fineprocglbnbr; while ((procngbmax - procngbnum) > 1) { /* Find owner process by dichotomy on procvgbtab */ int procngbmed; procngbmed = (procngbmax + procngbnum) / 2; if (fineprocvrttab[procngbmed] > finevertglbnum) procngbmax = procngbmed; else procngbnum = procngbmed; } vsndidxtab[4 * procngbnum + coarpartval] ++; /* One of four counters per process number will be incremented */ sortloctab[sortlocnbr].vertnum = finevertglbnum; sortloctab[sortlocnbr].procnum = ((procngbnum + (fineprocglbnbr * coarpartmsk)) ^ (- (Gnum) (coarpartval >> 1))); /* Embed part and frontier information */ sortlocnbr ++; } i ++; /* Process next multinode vertex */ } while (finevertglbnum != coarmulttax[coarvertlocnum].vertglbnum[1]); /* If not single node */ } for (procnum = 0; procnum < fineprocglbnbr; procnum ++) { /* Aggregate data to be sent */ vsndcnttab[procnum] = vsndidxtab[4 * procnum] + vsndidxtab[4 * procnum + 1] + vsndidxtab[4 * procnum + 2] + vsndidxtab[4 * procnum + 3]; if (vsndcnttab[procnum] != 0) /* If we will send data to neighbor */ vsndcnttab[procnum] += 3; /* Add control data to message size */ } } if (MPI_Alltoall (vsndcnttab, 1, MPI_INT, vrcvcnttab, 1, MPI_INT, finegrafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphBipartMlUncoarsen: communication error (3)"); return (1); } for (procnum = 0, vrcvdspnbr = vsnddspnbr = 0; /* Build communication index arrays */ procnum < fineprocglbnbr; procnum ++) { vrcvdsptab[procnum] = vrcvdspnbr; vsnddsptab[procnum] = vsnddspnbr; vrcvdspnbr += vrcvcnttab[procnum]; vsnddspnbr += vsndcnttab[procnum]; } if (memAllocGroup ((void **) (void *) &vrcvdattab, (size_t) (vrcvdspnbr * sizeof (Gnum)), &vsnddattab, (size_t) (vsnddspnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("bdgraphBipartMlUncoarsen: out of memory (4)"); reduloctab[5] = 1; } #ifdef SCOTCH_DEBUG_BDGRAPH1 /* Communication cannot be overlapped by a useful one */ if (MPI_Allreduce (&reduloctab[5], &reduglbtab[5], 1, GNUM_MPI, MPI_SUM, finegrafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphBipartMlUncoarsen: communication error (4)"); return (1); } #else /* SCOTCH_DEBUG_BDGRAPH1 */ reduglbtab[5] = reduloctab[5]; #endif /* SCOTCH_DEBUG_BDGRAPH1 */ if (reduglbtab[5] != 0) { if (vrcvdattab != NULL) memFree (vrcvdattab); if (vrcvcnttab != NULL) memFree (vrcvcnttab); return (1); } for (procnum = 0; procnum < fineprocglbnbr; procnum ++) { Gnum vsnddspval; vsnddspval = vsnddsptab[procnum]; if (vsndcnttab[procnum] != 0) { Gnum vsndidxnum; vsnddattab[vsnddspval] = vsndidxtab[4 * procnum]; vsnddattab[vsnddspval + 1] = vsndidxtab[4 * procnum + 1]; vsnddattab[vsnddspval + 2] = vsndidxtab[4 * procnum + 2]; vsnddspval += 3; /* Compute sub-array indices to pack vertices to be sent */ vsndidxnum = vsndidxtab[4 * procnum]; vsndidxtab[4 * procnum] = vsnddspval; vsnddspval += vsndidxnum; vsndidxnum = vsndidxtab[4 * procnum + 1]; vsndidxtab[4 * procnum + 1] = vsnddspval; vsnddspval += vsndidxnum; vsndidxnum = vsndidxtab[4 * procnum + 2]; vsndidxtab[4 * procnum + 2] = vsnddspval; vsnddspval += vsndidxnum; vsndidxtab[4 * procnum + 3] = vsnddspval; } } for (sortlocnum = 0; sortlocnum < sortlocnbr; sortlocnum ++) { /* For all vertices to send */ Gnum vertglbend; Gnum procngbnum; int partval; vertglbend = sortloctab[sortlocnum].vertnum; procngbnum = sortloctab[sortlocnum].procnum; partval = 0; /* Extract frontier and part data from process number */ if (procngbnum < 0) { partval = 2; procngbnum ^= (Gnum) -1; } if (procngbnum >= fineprocglbnbr) { partval |= 1; procngbnum -= fineprocglbnbr; } #ifdef SCOTCH_DEBUG_BDGRAPH2 if (((partval < 3) && (vsndidxtab[4 * procngbnum + partval] >= vsndidxtab[4 * procngbnum + partval + 1])) || (vsndidxtab[4 * procngbnum + partval] >= (vsnddsptab[procngbnum] + vsndcnttab[procngbnum]))) { errorPrint ("bdgraphBipartMlUncoarsen: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_BDGRAPH2 */ vsnddattab[vsndidxtab[4 * procngbnum + partval] ++] = vertglbend; /* Pack vertex in proper sub-array */ } if (MPI_Alltoallv (vsnddattab, vsndcnttab, vsnddsptab, GNUM_MPI, vrcvdattab, vrcvcnttab, vrcvdsptab, GNUM_MPI, finegrafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphBipartMlUncoarsen: communication error (5)"); return (1); } for (procnum = 0; procnum < fineprocglbnbr; ++ procnum) { /* Update local ones from the buffer for receiving data */ Gnum vrcvidxnum; Gnum vrcvidxnnd; if (vrcvcnttab[procnum] == 0) /* If nothing received from this process, skip it */ continue; finecomplocsize1 += (vrcvcnttab[procnum] - 3) - vrcvdattab[vrcvdsptab[procnum]] - vrcvdattab[vrcvdsptab[procnum] + 2]; for (vrcvidxnum = vrcvdsptab[procnum] + 3, vrcvidxnnd = vrcvidxnum + vrcvdattab[vrcvdsptab[procnum]]; /* Vertices in sub-array 0 */ vrcvidxnum < vrcvidxnnd; vrcvidxnum ++) { Gnum finevertlocnum; finevertlocnum = vrcvdattab[vrcvidxnum] - finevertlocadj; #ifdef SCOTCH_DEBUG_BDGRAPH2 if ((finevertlocnum < baseval) || (finevertlocnum >= finevertlocnnd)) { errorPrint ("bdgraphBipartMlUncoarsen: internal error (4)"); return (1); } #endif /* SCOTCH_DEBUG_BDGRAPH2 */ finepartgsttax[finevertlocnum] = 0; } for (vrcvidxnnd = vrcvidxnum + vrcvdattab[vrcvdsptab[procnum] + 1]; /* Vertices in sub-array 1 */ vrcvidxnum < vrcvidxnnd; vrcvidxnum ++) { Gnum finevertlocnum; finevertlocnum = vrcvdattab[vrcvidxnum] - finevertlocadj; #ifdef SCOTCH_DEBUG_BDGRAPH2 if ((finevertlocnum < baseval) || (finevertlocnum >= finevertlocnnd)) { errorPrint ("bdgraphBipartMlUncoarsen: internal error (5)"); return (1); } #endif /* SCOTCH_DEBUG_BDGRAPH2 */ finepartgsttax[finevertlocnum] = 1; if (fineveloloctax != NULL) finecomplocload1 += fineveloloctax[finevertlocnum]; if (fineveexloctax != NULL) { Gnum veexval; veexval = fineveexloctax[finevertlocnum]; finecommlocloadextn += veexval; finecommlocgainextn -= veexval; } } for (vrcvidxnnd = vrcvidxnum + vrcvdattab[vrcvdsptab[procnum] + 2]; /* Vertices in sub-array 2 */ vrcvidxnum < vrcvidxnnd; vrcvidxnum ++) { Gnum finevertlocnum; finevertlocnum = vrcvdattab[vrcvidxnum] - finevertlocadj; #ifdef SCOTCH_DEBUG_BDGRAPH2 if ((finevertlocnum < baseval) || (finevertlocnum >= finevertlocnnd)) { errorPrint ("bdgraphBipartMlUncoarsen: internal error (6)"); return (1); } #endif /* SCOTCH_DEBUG_BDGRAPH2 */ finepartgsttax[finevertlocnum] = 0; finefronloctab[finefronlocnbr ++] = finevertlocnum; } for (vrcvidxnnd = vrcvdsptab[procnum] + vrcvcnttab[procnum]; /* Vertices in sub-array 3 */ vrcvidxnum < vrcvidxnnd; vrcvidxnum ++) { Gnum finevertlocnum; finevertlocnum = vrcvdattab[vrcvidxnum] - finevertlocadj; #ifdef SCOTCH_DEBUG_BDGRAPH2 if ((finevertlocnum < baseval) || (finevertlocnum >= finevertlocnnd)) { errorPrint ("bdgraphBipartMlUncoarsen: internal error (7)"); return (1); } #endif /* SCOTCH_DEBUG_BDGRAPH2 */ finepartgsttax[finevertlocnum] = 1; finefronloctab[finefronlocnbr ++] = finevertlocnum; if (fineveloloctax != NULL) finecomplocload1 += fineveloloctax[finevertlocnum]; if (fineveexloctax != NULL) { Gnum veexval; veexval = fineveexloctax[finevertlocnum]; finecommlocloadextn += veexval; finecommlocgainextn -= veexval; } } } #ifdef SCOTCH_DEBUG_BDGRAPH2 for (finevertlocnum = baseval; finevertlocnum < finevertlocnnd; finevertlocnum ++) { if (finepartgsttax[finevertlocnum] == ((GraphPart) ~0)) { errorPrint ("bdgraphBipartMlUncoarsen: internal error (8)"); return (1); } } #endif /* SCOTCH_DEBUG_BDGRAPH2 */ if (dgraphHaloSync (&finegrafptr->s, (byte *) (finepartgsttax + baseval), GRAPHPART_MPI) != 0) { errorPrint ("bdgraphBipartMlUncoarsen: cannot perform halo exchange"); return (1); } finecommlocloadintn = 0; fineedlolocval = 1; /* Assume edges are not weighted */ for (finefronlocnum = 0; finefronlocnum < finefronlocnbr; finefronlocnum ++) { Gnum finevertlocnum; Gnum fineedgelocnum; Gnum partval; Gnum commcut; finevertlocnum = finefronloctab[finefronlocnum]; partval = finepartgsttax[finevertlocnum]; for (fineedgelocnum = finevertloctax[finevertlocnum], commcut = 0; fineedgelocnum < finevendloctax[finevertlocnum]; fineedgelocnum ++) { Gnum partdlt; partdlt = partval ^ finepartgsttax[fineedgegsttax[fineedgelocnum]]; commcut += partdlt; if (fineedloloctax != NULL) fineedlolocval = fineedloloctax[fineedgelocnum]; finecommlocloadintn += partdlt * fineedlolocval; /* Counted in both part, should be divided by 2 in summing up phase */ } if (commcut == 0) /* If vertex does not really belong to frontier */ finefronloctab[finefronlocnum --] = finefronloctab[-- finefronlocnbr]; /* Replace vertex and redo */ } memFree (vrcvdattab); /* Free group leaders */ memFree (vrcvcnttab); finegrafptr->fronlocnbr = finefronlocnbr; finegrafptr->complocsize0 = finegrafptr->s.vertlocnbr - finecomplocsize1; finegrafptr->complocload0 = (fineveloloctax == NULL) ? finegrafptr->complocsize0 : (finegrafptr->s.velolocsum - finecomplocload1); reduloctab[0] = finegrafptr->complocload0; reduloctab[1] = finegrafptr->complocsize0; reduloctab[2] = finegrafptr->fronlocnbr; reduloctab[3] = finecommlocloadintn; reduloctab[4] = finecommlocloadextn; reduloctab[5] = finecommlocgainextn; MPI_Allreduce (reduloctab, reduglbtab, 6, GNUM_MPI, MPI_SUM, finegrafptr->s.proccomm); finegrafptr->compglbload0 = reduglbtab[0]; finegrafptr->compglbload0dlt = finegrafptr->compglbload0 - finegrafptr->compglbload0avg; finegrafptr->compglbsize0 = reduglbtab[1]; finegrafptr->fronglbnbr = reduglbtab[2]; finegrafptr->commglbload = ((reduglbtab[3] / 2) * finegrafptr->domndist + reduglbtab[4] + finegrafptr->commglbloadextn0); finegrafptr->commglbgainextn = reduglbtab[5]; finegrafptr->bbalglbval = coargrafptr->bbalglbval; #ifdef SCOTCH_DEBUG_BDGRAPH2 if (bdgraphCheck (finegrafptr) != 0) { errorPrint ("bdgraphBipartMlUncoarsen: inconsistent graph data (2)"); return (1); } #endif /* SCOTCH_DEBUG_BDGRAPH2 */ return (0); } /* This routine performs the ** bipartitioning recursion. ** It returns: ** - 0 : if bipartitioning could be computed. ** - !0 : on error. */ static int bdgraphBipartMl2 ( Bdgraph * restrict const grafptr, /* Active graph */ const BdgraphBipartMlParam * const paraptr) /* Method parameters */ { Bdgraph coargrafdat; DgraphCoarsenMulti * restrict coarmulttax; int o; if (grafptr->s.procglbnbr <= 1) { /* Enter into sequential mode */ if (((o = bdgraphBipartMlUncoarsen (grafptr, NULL, NULL)) == 0) && /* Finalize graph */ ((o = bdgraphBipartSt (grafptr, paraptr->stratseq)) != 0)) { #ifdef SCOTCH_DEBUG_BDGRAPH2 errorPrintW ("bdgraphBipartMl2: cannot apply sequential strategy"); #endif /* SCOTCH_DEBUG_BDGRAPH2 */ } return (o); } coarmulttax = NULL; /* Assume multinode array is not allocated */ if (bdgraphBipartMlCoarsen (grafptr, &coargrafdat, &coarmulttax, paraptr) == 0) { o = (coargrafdat.s.procglbnbr == 0) ? 0 : bdgraphBipartMl2 (&coargrafdat, paraptr); /* Apply recursion on coarsened graph if it exists */ if ((o == 0) && ((o = bdgraphBipartMlUncoarsen (grafptr, &coargrafdat, coarmulttax)) == 0) && ((o = bdgraphBipartSt (grafptr, paraptr->stratasc)) != 0)) { /* Apply ascending strategy if uncoarsening worked */ #ifdef SCOTCH_DEBUG_BDGRAPH2 errorPrintW ("bdgraphBipartMl2: cannot apply ascending strategy"); #endif /* SCOTCH_DEBUG_BDGRAPH2 */ } bdgraphExit (&coargrafdat); if (coarmulttax != NULL) /* If multinode array has been allocated */ memFree (coarmulttax + grafptr->s.baseval); /* Free array */ if (o == 0) /* If multi-level failed, apply low strategy as fallback */ return (o); } if (((o = bdgraphBipartMlUncoarsen (grafptr, NULL, NULL)) == 0) && /* Finalize graph */ ((o = bdgraphBipartSt (grafptr, paraptr->stratlow)) != 0)) { /* Apply low strategy */ #ifdef SCOTCH_DEBUG_BDGRAPH2 errorPrintW ("bdgraphBipartMl2: cannot apply low strategy"); #endif /* SCOTCH_DEBUG_BDGRAPH2 */ } return (o); } /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the muti-level bipartitioning. ** It returns: ** - 0 : if bipartitioning could be computed. ** - 1 : on error. */ int bdgraphBipartMl ( Bdgraph * const grafptr, /*+ Active graph +*/ const BdgraphBipartMlParam * const paraptr) /*+ Method parameters +*/ { Gnum levlnum; /* Save value for graph level */ int o; levlnum = grafptr->levlnum; /* Save graph level */ grafptr->levlnum = 0; /* Initialize coarsening level */ o = bdgraphBipartMl2 (grafptr, paraptr); /* Perform multi-level bipartitioning */ grafptr->levlnum = levlnum; /* Restore graph level */ return (o); } scotch-6.0.4.dfsg/src/libscotch/vgraph_separate_zr.h0000644002563400244210000000540211631447170025676 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vgraph_separate_zr.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the move-all-to-first-subdomain **/ /** separation method. **/ /** **/ /** DATES : # Version 3.3 : from : 31 may 1999 **/ /** to 31 may 1999 **/ /** # Version 4.0 : from : 19 dec 2001 **/ /** to 01 jan 2002 **/ /** **/ /************************************************************/ /* ** The function prototypes. */ #ifndef VGRAPH_SEPARATE_ZR #define static #endif int vgraphSeparateZr (Vgraph * const); #undef static scotch-6.0.4.dfsg/src/libscotch/arch_vcmplt.h0000644002563400244210000001301012377071372024311 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : arch_vcmplt.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the variable-sized complete graph **/ /** target architecture functions. **/ /** **/ /** DATES : # Version 3.0 : from : 01 jul 1995 **/ /** to 09 aug 1995 **/ /** # Version 3.1 : from : 20 jul 1996 **/ /** to 20 jul 1996 **/ /** # Version 3.2 : from : 15 oct 1996 **/ /** to 14 may 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 3.4 : from : 08 nov 2001 **/ /** to 08 nov 2001 **/ /** # Version 4.0 : from : 05 nov 2003 **/ /** to 05 nov 2003 **/ /** # Version 5.1 : from : 21 jan 2008 **/ /** to 21 jan 2008 **/ /** # Version 6.0 : from : 14 fev 2011 **/ /** to 26 aug 2014 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ #ifndef ARCH_VCMPLT_H_STRUCT #define ARCH_VCMPLT_H_STRUCT /*+ The variable-sized complete graph bipartitioning definitions. +*/ typedef struct ArchVcmplt_ { int padding; /*+ No data needed +*/ } ArchVcmplt; typedef struct ArchVcmpltDom_ { Anum termlvl; /*+ Terminal depth +*/ Anum termnum; /*+ Terminal number +*/ } ArchVcmpltDom; #endif /* ARCH_VCMPLT_H_STRUCT */ /* ** The function prototypes. */ #ifndef ARCH_NOPROTO #ifndef ARCH_VCMPLT_H_PROTO #define ARCH_VCMPLT_H_PROTO #ifndef ARCH_VCMPLT #define static #endif #define archVcmpltArchLoad NULL #define archVcmpltArchSave NULL #define archVcmpltArchFree NULL ArchDomNum archVcmpltDomNum (const ArchVcmplt * const, const ArchVcmpltDom * const); int archVcmpltDomTerm (const ArchVcmplt * const, ArchVcmpltDom * restrict const, const ArchDomNum); Anum archVcmpltDomSize (const ArchVcmplt * const, const ArchVcmpltDom * const); #define archVcmpltDomWght archVcmpltDomSize Anum archVcmpltDomDist (const ArchVcmplt * const, const ArchVcmpltDom * const, const ArchVcmpltDom * const); int archVcmpltDomFrst (const ArchVcmplt * const, ArchVcmpltDom * const); int archVcmpltDomLoad (const ArchVcmplt * const, ArchVcmpltDom * const, FILE * const); int archVcmpltDomSave (const ArchVcmplt * const, const ArchVcmpltDom * const, FILE * const); int archVcmpltDomBipart (const ArchVcmplt * const, const ArchVcmpltDom * const, ArchVcmpltDom * restrict const, ArchVcmpltDom * restrict const); int archVcmpltDomIncl (const ArchVcmplt * const, const ArchVcmpltDom * const, const ArchVcmpltDom * const); #ifdef SCOTCH_PTSCOTCH int archVcmpltDomMpiType (const ArchVcmplt * const, MPI_Datatype * const); #endif /* SCOTCH_PTSCOTCH */ #undef static #endif /* ARCH_VCMPLT_H_PROTO */ #endif /* ARCH_NOPROTO */ scotch-6.0.4.dfsg/src/libscotch/hgraph.h0000644002563400244210000001131212037541150023250 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hgraph.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the source halo graph structure. **/ /** **/ /** DATES : # Version 4.0 : from : 02 jan 2002 **/ /** to 30 apr 2004 **/ /** # Version 5.0 : from : 19 dec 2006 **/ /** to 19 dec 2006 **/ /** # Version 5.1 : from : 04 nov 2010 **/ /** to 04 nov 2010 **/ /** # Version 6.0 : from : 17 oct 2012 **/ /** to 17 oct 2012 **/ /** **/ /************************************************************/ #define HGRAPH_H /* ** The defines. */ /*+ Graph option flags. +*/ #define HGRAPHFREEVNHD 0x0400 /* Free vnhdtab array */ #define HGRAPHFREETABS (GRAPHFREETABS | HGRAPHFREEVNHD) /* ** The type and structure definitions. */ /*+ Halo graph structure. +*/ typedef struct Hgraph_ { Graph s; /*+ Source graph +*/ Gnum vnohnbr; /*+ Number of non-halo vertices +*/ Gnum vnohnnd; /*+ Based number of first halo vertex in graph (s.vertnnd if none) +*/ Gnum * vnhdtax; /*+ End vertex array for non-halo vertices [vnohnbr, based] +*/ Gnum vnlosum; /*+ Sum of vertex loads for non-halo vertices only (<= s.velosum) +*/ Gnum enohnbr; /*+ Number of non-halo edges +*/ Gnum enohsum; /*+ Sum of non-halo edge loads +*/ Gnum levlnum; /*+ Nested dissection level +*/ } Hgraph; /* ** The function prototypes. */ #ifndef HGRAPH #define static #endif int hgraphInit (Hgraph * const); void hgraphExit (Hgraph * const); void hgraphFree (Hgraph * const); Gnum hgraphBase (Hgraph * const, const Gnum); int hgraphCheck (const Hgraph *); int hgraphInduceList (const Hgraph * const, const VertList * const, const Gnum, Hgraph * const); void hgraphUnhalo (const Hgraph * const, Graph * const); #undef static scotch-6.0.4.dfsg/src/libscotch/hgraph_order_nd.c0000644002563400244210000002674712370202131025132 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010,2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hgraph_order_nd.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module orders graphs using the **/ /** nested dissection algorithm. **/ /** **/ /** DATES : # Version 3.2 : from : 17 oct 1996 **/ /** to : 21 aug 1998 **/ /** # Version 3.3 : from : 02 oct 1998 **/ /** to 13 mar 1999 **/ /** # Version 4.0 : from : 03 jan 2002 **/ /** to 24 dec 2004 **/ /** # Version 5.0 : from : 19 dec 2006 **/ /** to 25 jul 2007 **/ /** # Version 5.1 : from : 24 oct 2010 **/ /** to 24 oct 2010 **/ /** # Version 6.0 : from : 17 oct 2012 **/ /** to 05 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HGRAPH_ORDER_ND #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "order.h" #include "hgraph.h" #include "hgraph_order_nd.h" #include "hgraph_order_st.h" #include "vgraph.h" #include "vgraph_separate_st.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the ordering. ** It returns: ** - 0 : if the ordering could be computed. ** - !0 : on error. */ int hgraphOrderNd ( const Hgraph * restrict const grafptr, Order * restrict const ordeptr, const Gnum ordenum, OrderCblk * restrict const cblkptr, const HgraphOrderNdParam * restrict const paraptr) { Hgraph indgrafdat; /* Halo graph data */ Gnum * vspvnumptr[3]; /* Pointers to vertex lists to fill */ VertList vsplisttab[3]; /* Array of separated part lists */ Vgraph vspgrafdat; /* Vertex separation graph data */ Gnum vspvertnum; /* Current vertex in separation graph */ int o; hgraphUnhalo (grafptr, &vspgrafdat.s); /* Keep only non-halo vertices for separation */ if ((vspgrafdat.frontab = (Gnum *) memAlloc (vspgrafdat.s.vertnbr * sizeof (Gnum))) == NULL) { errorPrint ("hgraphOrderNd: out of memory (1)"); return (1); } if ((vspgrafdat.parttax = (GraphPart *) memAlloc (vspgrafdat.s.vertnbr * sizeof (GraphPart))) == NULL) { errorPrint ("hgraphOrderNd: out of memory (2)"); memFree (vspgrafdat.frontab); return (1); } memSet (vspgrafdat.parttax, 0, vspgrafdat.s.vertnbr * sizeof (GraphPart)); /* Set all vertices to part 0 */ vspgrafdat.parttax -= vspgrafdat.s.baseval; vspgrafdat.fronnbr = 0; vspgrafdat.compload[0] = vspgrafdat.s.velosum; vspgrafdat.compload[1] = 0; vspgrafdat.compload[2] = 0; vspgrafdat.comploaddlt = vspgrafdat.s.velosum; vspgrafdat.compsize[0] = vspgrafdat.s.vertnbr; vspgrafdat.compsize[1] = 0; vspgrafdat.fronnbr = 0; vspgrafdat.levlnum = grafptr->levlnum; /* Set level of separation graph as level of halo graph */ if (vgraphSeparateSt (&vspgrafdat, paraptr->sepstrat) != 0) { /* Separate vertex-separation graph */ vgraphExit (&vspgrafdat); return (1); } if ((vspgrafdat.compsize[0] == 0) || /* If could not separate more */ (vspgrafdat.compsize[1] == 0)) { vgraphExit (&vspgrafdat); /* Free useless space */ hgraphOrderSt (grafptr, ordeptr, ordenum, cblkptr, paraptr->ordstratlea); /* Order this leaf */ return (0); /* Leaf has been processed */ } vsplisttab[0].vnumnbr = vspgrafdat.compsize[0]; /* Build vertex lists within frontier array */ vsplisttab[0].vnumtab = vspgrafdat.frontab + vspgrafdat.fronnbr; vsplisttab[1].vnumnbr = vspgrafdat.compsize[1]; vsplisttab[1].vnumtab = vsplisttab[0].vnumtab + vsplisttab[0].vnumnbr; vsplisttab[2].vnumnbr = vspgrafdat.fronnbr; vsplisttab[2].vnumtab = vspgrafdat.frontab; vspvnumptr[0] = vsplisttab[0].vnumtab; vspvnumptr[1] = vsplisttab[1].vnumtab; vspvnumptr[2] = vsplisttab[2].vnumtab; for (vspvertnum = vspgrafdat.s.baseval; vspvertnum < vspgrafdat.s.vertnnd; vspvertnum ++) { /* Fill lists */ *vspvnumptr[vspgrafdat.parttax[vspvertnum]] ++ = vspvertnum; #ifdef SCOTCH_DEBUG_HGRAPH2 if (vspgrafdat.parttax[vspvertnum] != 2) { /* If vertex does not separate */ Gnum vspedgenum; GraphPart vsppartnum; vsppartnum = 1 - vspgrafdat.parttax[vspvertnum]; /* Get opposite part value */ for (vspedgenum = vspgrafdat.s.verttax[vspvertnum]; vspedgenum < vspgrafdat.s.vendtax[vspvertnum]; vspedgenum ++) { if (vspgrafdat.parttax[vspgrafdat.s.edgetax[vspedgenum]] == vsppartnum) { /* If an edge crosses the separator */ errorPrint ("hgraphOrderNd: internal error (1)"); vgraphExit (&vspgrafdat); return (1); } } } #endif /* SCOTCH_DEBUG_HGRAPH2 */ } #ifdef SCOTCH_DEBUG_HGRAPH2 if ((vspvnumptr[0] != vsplisttab[0].vnumtab + vsplisttab[0].vnumnbr) || (vspvnumptr[1] != vsplisttab[1].vnumtab + vsplisttab[1].vnumnbr) || (vspvnumptr[2] != vsplisttab[2].vnumtab + vsplisttab[2].vnumnbr)) { errorPrint ("hgraphOrderNd: internal error (2)"); vgraphExit (&vspgrafdat); return (1); } #endif /* SCOTCH_DEBUG_HGRAPH2 */ memFree (vspgrafdat.parttax + vspgrafdat.s.baseval); /* Free useless space */ #ifdef SCOTCH_DEBUG_HGRAPH2 vspgrafdat.parttax = NULL; /* Will cause bug if re-read */ #endif /* SCOTCH_DEBUG_HGRAPH2 */ cblkptr->typeval = ORDERCBLKNEDI; /* Node becomes a nested dissection node */ if ((cblkptr->cblktab = (OrderCblk *) memAlloc (3 * sizeof (OrderCblk))) == NULL) { errorPrint ("hgraphOrderNd: out of memory (2)"); memFree (vspgrafdat.frontab); /* Free remaining space */ return (1); } cblkptr->cblktab[0].typeval = ORDERCBLKOTHR; /* Build column blocks */ cblkptr->cblktab[0].vnodnbr = vsplisttab[0].vnumnbr; cblkptr->cblktab[0].cblknbr = 0; cblkptr->cblktab[0].cblktab = NULL; cblkptr->cblktab[1].typeval = ORDERCBLKOTHR; cblkptr->cblktab[1].vnodnbr = vsplisttab[1].vnumnbr; cblkptr->cblktab[1].cblknbr = 0; cblkptr->cblktab[1].cblktab = NULL; if (vsplisttab[2].vnumnbr != 0) { /* If separator not empty */ cblkptr->cblknbr = 3; /* It is a three-cell tree node */ ordeptr->cblknbr += 2; /* Two more column blocks created */ ordeptr->treenbr += 3; /* Three more tree nodes created */ cblkptr->cblktab[2].typeval = ORDERCBLKOTHR; cblkptr->cblktab[2].vnodnbr = vsplisttab[2].vnumnbr; cblkptr->cblktab[2].cblknbr = 0; cblkptr->cblktab[2].cblktab = NULL; if (graphInduceList (&grafptr->s, &vsplisttab[2], &indgrafdat.s) != 0) { /* Perform non-halo induction for separator, as it will get highest numbers */ errorPrint ("hgraphOrderNd: cannot build induced subgraph (1)"); memFree (vspgrafdat.frontab); /* Free remaining space */ return (1); } indgrafdat.vnohnbr = indgrafdat.s.vertnbr; /* Fill halo graph structure of non-halo graph */ indgrafdat.vnohnnd = indgrafdat.s.vertnnd; indgrafdat.vnhdtax = indgrafdat.s.vendtax; indgrafdat.vnlosum = indgrafdat.s.velosum; indgrafdat.enohnbr = indgrafdat.s.edgenbr; indgrafdat.enohsum = indgrafdat.s.edlosum; indgrafdat.levlnum = grafptr->levlnum; /* Separator graph is at level of original graph */ o = hgraphOrderSt (&indgrafdat, ordeptr, ordenum + vsplisttab[0].vnumnbr + vsplisttab[1].vnumnbr, cblkptr->cblktab + 2, paraptr->ordstratsep); hgraphExit (&indgrafdat); } else { /* Separator is empty */ cblkptr->cblknbr = 2; /* It is a two-cell tree node */ ordeptr->cblknbr ++; /* One more column block created */ ordeptr->treenbr += 2; /* Two more tree nodes created */ o = 0; /* No separator ordering computed */ } if (o == 0) { if ((hgraphInduceList (grafptr, &vsplisttab[0], vsplisttab[2].vnumnbr + grafptr->s.vertnbr - grafptr->vnohnbr, &indgrafdat)) != 0) { errorPrint ("hgraphOrderNd: cannot build induced subgraph (2)"); memFree (vspgrafdat.frontab); /* Free remaining space */ return (1); } o = hgraphOrderNd (&indgrafdat, ordeptr, ordenum, cblkptr->cblktab, paraptr); hgraphExit (&indgrafdat); } if (o == 0) { if ((hgraphInduceList (grafptr, &vsplisttab[1], vsplisttab[2].vnumnbr + grafptr->s.vertnbr - grafptr->vnohnbr, &indgrafdat)) != 0) { errorPrint ("hgraphOrderNd: cannot build induced subgraph (3)"); memFree (vspgrafdat.frontab); /* Free remaining space */ return (1); } o = hgraphOrderNd (&indgrafdat, ordeptr, ordenum + vsplisttab[0].vnumnbr, cblkptr->cblktab + 1, paraptr); hgraphExit (&indgrafdat); } memFree (vspgrafdat.frontab); /* Free remaining space */ return (o); } scotch-6.0.4.dfsg/src/libscotch/vgraph_separate_gp.h0000644002563400244210000001002011631447170025641 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vgraph_separate_gp.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the Gibbs, Poole, and Stockmeyer **/ /** graph separation algorithm. **/ /** **/ /** DATES : # Version 4.0 : from : 14 may 2004 **/ /** to 17 may 2004 **/ /** # Version 5.1 : from : 04 nov 2010 **/ /** to 04 nov 2010 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ Method parameters. +*/ typedef struct VgraphSeparateGpParam_ { INT passnbr; /*+ Number of passes to do +*/ } VgraphSeparateGpParam; /*+ Complementary vertex structure. +*/ typedef struct VgraphSeparateGpVertex_ { Gnum passnum; /*+ Number of pass when vertex selected +*/ Gnum distval; /*+ Current distance from diameter vertex +*/ } VgraphSeparateGpVertex; /*+ Neighbor queue. +*/ typedef struct VgraphSeparateGpQueue_ { Gnum headnum; /*+ Head of distance queue +*/ Gnum tailnum; /*+ Tail of distance queue +*/ Gnum * queutab; /*+ Array of queue elements +*/ } VgraphSeparateGpQueue; /* ** The function prototypes. */ #ifndef VGRAPH_SEPARATE_GP #define static #endif int vgraphSeparateGp (Vgraph * restrict const, const VgraphSeparateGpParam * restrict const); #undef static /* ** The macro definitions. */ #define vgraphSeparateGpQueueFlush(queue) ((queue)->headnum = (queue)->tailnum = 0) #define vgraphSeparateGpQueueEmpty(queue) ((queue)->headnum <= (queue)->tailnum) #define vgraphSeparateGpQueuePut(queue,vnum) ((queue)->queutab[(queue)->headnum ++] = (vnum)) #define vgraphSeparateGpQueueGet(queue) ((queue)->queutab[(queue)->tailnum ++]) scotch-6.0.4.dfsg/src/libscotch/wgraph_part_rb.c0000644002563400244210000003771312376160236025020 0ustar trophimeutilisateurs du domaine/* Copyright 2010,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : wgraph_part_rb.c **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module performs the vertex overla- **/ /** pped graph partitioning based on recur- **/ /** sive bipartitioning approach. **/ /** **/ /** DATES : # Version 6.0 : from : 16 mar 2010 **/ /** to 12 aug 2014 **/ /** **/ /** NOTES : # This code derives from the code of **/ /** kgraph_map_rb_part.c for the vertex **/ /** overlapped graph partitioning. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define WGRAPH_PART_RB #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "arch.h" #include "arch_cmplt.h" #include "mapping.h" #include "vgraph.h" #include "vgraph_separate_st.h" #include "vgraph_separate_zr.h" #include "wgraph.h" #include "wgraph_part_rb.h" #include "scotch.h" /* ** The static variables. */ static const Gnum wgraphpartrbloadone = 1; /********************************************/ /* */ /* This is the entry point for the vertex */ /* overlapped graph partitioning based on */ /* recursive bipartitioning approach. */ /* */ /********************************************/ /* This routine runs recursive ** bipartitioning approach. ** It returns: ** - 0 : on success. ** - !0 : on error. */ static int wgraphPartRb3 ( const Graph * restrict const orggrafptr, /* Graph to induce and bipartition */ const GraphPart * restrict const orgparttax, /* Part array of original graph */ const GraphPart indpartval, /* Part of graph to consider */ const int domnnum, /* Index of domain onto which map the part */ Mapping * restrict const mappptr) /* Final mapping */ { Gnum vertnum; if (orgparttax == NULL) { /* If graph is full graph */ #ifdef SCOTCH_DEBUG_WGRAPH2 if ((orggrafptr->vnumtax != NULL) || (domnnum != 0)) { errorPrint ("wgraphPartRb3: internal error"); return (1); } #endif /* SCOTCH_DEBUG_WGRAPH2 */ memSet (mappptr->parttax + mappptr->grafptr->baseval, 0, orggrafptr->vertnbr * sizeof (ArchDomNum)); } else { /* Graph to consider is a subgraph of the original graph */ if (orggrafptr->vnumtax == NULL) { /* If original graph is not itself a subgraph */ for (vertnum = orggrafptr->baseval; vertnum < orggrafptr->vertnnd; vertnum ++) { /* For all graph vertices */ if (orgparttax[vertnum] == indpartval) /* If vertex belongs to the right part */ mappptr->parttax[vertnum] = domnnum; } } else { for (vertnum = orggrafptr->baseval; vertnum < orggrafptr->vertnnd; vertnum ++) { /* For all graph vertices */ if (orgparttax[vertnum] == indpartval) /* If vertex belongs to the right part */ mappptr->parttax[orggrafptr->vnumtax[vertnum]] = domnnum; } } } return (0); } static int wgraphPartRb2 ( WgraphPartRbData * restrict const dataptr, /* Top-level graph and partition data */ Graph * restrict const orggrafptr, /* Graph to induce and bipartition */ const GraphPart * restrict const orgparttax, /* Part array of original graph to consider */ const GraphPart indpartval, /* Part of graph to consider */ const int indvertnbr, /* Number of vertices in part or in graph */ const int domnnum) /* Index of domain onto which map the part */ { Graph indgrafdat; Graph * indgrafptr; Vgraph actgrafdat; Anum domnsubidx; Anum domnsubdlt; ArchDom domnsubtab[2]; /* Target subdomains */ Anum domnsubnum[2]; /* Index of subdomains in mapping */ Gnum grafsubsiz[2]; Gnum vertnum; Mapping * restrict mappptr; int i; int o; mappptr = &dataptr->mappdat; o = archDomBipart (mappptr->archptr, &mappptr->domntab[domnnum], &domnsubtab[0], &domnsubtab[1]); switch (o) { case 1 : /* If target domain is terminal */ return (wgraphPartRb3 (orggrafptr, orgparttax, indpartval, domnnum, mappptr)); /* Update mapping and return */ case 2 : /* On error */ errorPrint ("wgraphPartRb2: cannot bipartition domain"); return (1); } indgrafptr = orggrafptr; /* Assume we will work on the original graph */ if (orgparttax != NULL) { /* If not the case, build induced subgraph */ indgrafptr = &indgrafdat; if (graphInducePart (orggrafptr, orgparttax, indvertnbr, indpartval, &indgrafdat) != 0) { errorPrint ("wgraphPartRb2: cannot induce graph"); return (1); } } actgrafdat.s = *indgrafptr; actgrafdat.s.vlbltax = NULL; if ((actgrafdat.frontab = (Gnum *) memAlloc (actgrafdat.s.vertnbr * sizeof (Gnum))) == NULL) { errorPrint ("wgraphPartRb2: out of memory (1)"); return (1); } if ((actgrafdat.parttax = (GraphPart *) memAlloc (actgrafdat.s.vertnbr * sizeof (GraphPart))) == NULL) { errorPrint ("wgraphPartRb2: out of memory (2)"); memFree (actgrafdat.frontab); return (1); } actgrafdat.parttax -= actgrafdat.s.baseval; vgraphZero (&actgrafdat); /* Create active graph */ if (vgraphSeparateSt (&actgrafdat, dataptr->stratptr) != 0) { /* Perform bipartitioning */ errorPrint ("wgraphPartRb2: cannot bipartition graph"); vgraphExit (&actgrafdat); return (1); } if (actgrafdat.s.vnumtax == NULL) { /* If the active graph is not itself a subgraph */ for (vertnum = actgrafdat.s.baseval; vertnum < actgrafdat.s.vertnnd; vertnum ++) { /* For all graph vertices */ if (actgrafdat.parttax[vertnum] == 2) { /* If vertex belongs to frontier */ mappptr->parttax[vertnum] = -1; actgrafdat.parttax[vertnum] = 3; } } } else { for (vertnum = actgrafdat.s.baseval; vertnum < actgrafdat.s.vertnnd; vertnum ++) { /* For all graph vertices */ if (actgrafdat.parttax[vertnum] == 2) { /* If vertex belongs to frontier */ mappptr->parttax[actgrafdat.s.vnumtax[vertnum]]= -1; actgrafdat.parttax[vertnum] = 3; } } } domnsubdlt = mappptr->domnnbr - domnnum; /* Increment in domain number */ domnsubidx = domnnum - domnsubdlt; /* Place where to insert subdomain */ mappptr->domnnbr --; /* One less subdomain as for now */ grafsubsiz[0] = actgrafdat.compsize[0]; grafsubsiz[1] = actgrafdat.compsize[1]; o = 0; for (i = 1; i >= 0; i --) { /* For all subparts */ if (grafsubsiz[i] <= 0) /* If subpart is empty, skip it */ continue; mappptr->domnnbr ++; /* One more subdomain to account for */ domnsubidx += domnsubdlt; /* Compute location of subdomain */ domnsubnum[i] = domnsubidx; /* Record it before recursion */ mappptr->domntab[domnsubidx] = domnsubtab[i]; /* Write it at this place */ } if (o == 0) { for (i = 1; i >= 0; i --) { /* For all subparts */ if (grafsubsiz[i] <= 0) /* If subpart is empty, skip it */ continue; if ((o = wgraphPartRb2 (dataptr, indgrafptr, actgrafdat.parttax, (GraphPart) i, grafsubsiz[i], domnsubnum[i])) != 0) return (1); /* If problem in recursion, stop */ } } memFree (actgrafdat.frontab); /* Frontier array of bipartitioning graph is no longer necessary */ memFree (actgrafdat.parttax + actgrafdat.s.baseval); /* Frontier array of bipartitioning graph is no longer necessary */ if (indgrafptr == &indgrafdat) /* If an induced subgraph had been created */ graphExit (indgrafptr); /* Free it */ return (o); } int wgraphPartRb ( Wgraph * restrict const grafptr, const WgraphPartRbParam * restrict const paraptr) { const Anum * restrict parttax; Anum partval; Gnum vertnum; Gnum velomsk; const Gnum * restrict velobax; /* Data for handling of optional arrays */ Gnum * restrict frontab; Gnum fronnbr; Gnum fronload; Gnum * restrict compload; Gnum * restrict compsize; WgraphPartRbData datadat; Arch archdat; WgraphPartList * restrict listtab; const Gnum * restrict const verttax = grafptr->s.verttax; const Gnum * restrict const vendtax = grafptr->s.vendtax; const Gnum * restrict const edgetax = grafptr->s.edgetax; if ((listtab = (WgraphPartList *) memAlloc ((grafptr->partnbr + 1) * sizeof (WgraphPartList))) == NULL) { /* TRICK: "+1" to create slot for a "-1" index */ errorPrint ("wgraphPartRb: out of memory (1)"); return (1); } listtab ++; /* TRICK: Trim array so that listtab[-1] is valid */ memSet (listtab, ~0, grafptr->partnbr * sizeof (WgraphPartList)); /* Set vertex indices to ~0 */ datadat.grafptr = &grafptr->s; datadat.frontab = grafptr->frontab; /* Re-use frontier array */ datadat.fronnbr = 0; datadat.stratptr = paraptr->stratptr; datadat.mappdat.grafptr = &grafptr->s; datadat.mappdat.parttax = grafptr->parttax; /* Re-use part array */ datadat.mappdat.domnmax = grafptr->partnbr + 1; datadat.mappdat.domnnbr = 1; SCOTCH_archCmplt ((SCOTCH_Arch *) &archdat, grafptr->partnbr); /* Create a complete graph architecture */ datadat.mappdat.archptr = &archdat; archDomFrst (datadat.mappdat.archptr, &datadat.mappdat.domnorg); /* Get first domain of architecture */ if ((datadat.mappdat.domntab = (ArchDom *) memAlloc ((grafptr->partnbr + 2) * sizeof (ArchDom))) == NULL) { errorPrint ("wgraphPartRb: out of memory (2)"); memFree (listtab - 1); /* TRICK: free array using its real beginning */ return (1); } datadat.mappdat.domntab[0] = datadat.mappdat.domnorg; /* Set first domain */ if (wgraphPartRb2 (&datadat, &grafptr->s, NULL, 0, grafptr->s.vertnbr, 0) != 0) { errorPrint ("wgraphPartRb: internal error (1)"); return (1); } if (grafptr->s.velotax == NULL) { /* Set accesses to optional arrays */ velobax = &wgraphpartrbloadone; /* In case vertices not weighted (least often) */ velomsk = 0; } else { velobax = grafptr->s.velotax; velomsk = ~((Gnum) 0); } compload = grafptr->compload; compsize = grafptr->compsize; memSet (compload, 0, grafptr->partnbr * sizeof (Gnum)); memSet (compsize, 0, grafptr->partnbr * sizeof (Gnum)); parttax = grafptr->parttax; frontab = grafptr->frontab; fronnbr = fronload = 0; for (vertnum = grafptr->s.baseval; vertnum < grafptr->s.vertnnd; vertnum ++) { Gnum partval; partval = parttax[vertnum]; if (partval >= 0) { compload[partval] += velobax[vertnum & velomsk]; compsize[partval] ++; } else { /* Vertex is in separator */ Gnum listidx; /* Index of first neighbor part */ Gnum edgenum; Gnum veloval; frontab[fronnbr ++] = vertnum; /* Add vertex to frontier */ fronload += velobax[vertnum & velomsk]; listidx = -1; /* No neighboring parts recorded yet */ listtab[-1].vertnum = vertnum; /* Separator neighbors will not be considered */ for (edgenum = verttax[vertnum]; edgenum < vendtax[vertnum]; edgenum ++) { /* Compute gain */ Gnum vertend; Gnum partend; vertend = edgetax[edgenum]; partend = parttax[vertend]; if (listtab[partend].vertnum != vertnum) { /* If part not yet considered */ listtab[partend].vertnum = vertnum; /* Link it in list of neighbors */ listtab[partend].nextidx = listidx; listidx = partend; } } veloval = velobax[vertnum & velomsk]; while (listidx != -1) { /* For all neighboring parts found */ compload[listidx] += veloval; /* Add load of separator vertex to part */ compsize[listidx] ++; listidx = listtab[listidx].nextidx; } } } grafptr->fronnbr = fronnbr; grafptr->fronload = fronload; #if 0 /* TODO REMOVE */ for (partval = 0; partval < grafptr->partnbr; partval ++) printf("\033[0;33mcompload[%d] %d %d\033[0m\n", partval, grafptr->compload[partval], grafptr->compsize[partval]); #endif memFree (datadat.mappdat.domntab); /* Free only newly allocated array of mapping */ memFree (listtab - 1); /* TRICK: free array using its real beginning */ #ifdef SCOTCH_DEBUG_WGRAPH2 if (wgraphCheck (grafptr) != 0) { errorPrint ("wgraphPartRb: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_WGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/vgraph_separate_st.c0000644002563400244210000004117112330455234025664 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2011-2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vgraph_separate_st.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module contains the global **/ /** separation strategy and method tables. **/ /** **/ /** DATES : # Version 3.2 : from : 25 oct 1996 **/ /** to 14 nov 1997 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 31 may 1999 **/ /** # Version 4.0 : from : 06 jan 2002 **/ /** to 28 mar 2006 **/ /** # Version 5.0 : from : 12 sep 2006 **/ /** to : 02 oct 2007 **/ /** # Version 5.1 : from : 30 oct 2007 **/ /** to : 01 jul 2008 **/ /** # Version 6.0 : from : 09 mar 2011 **/ /** to 01 may 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VGRAPH_SEPARATE_ST #include "module.h" #include "common.h" #include "gain.h" #include "parser.h" #include "graph.h" #include "arch.h" #include "mapping.h" #include "graph_coarsen.h" #include "bgraph.h" #include "bgraph_bipart_st.h" #include "vgraph.h" #include "vgraph_separate_bd.h" #include "vgraph_separate_es.h" #include "vgraph_separate_fm.h" #include "vgraph_separate_gg.h" #include "vgraph_separate_gp.h" #include "vgraph_separate_ml.h" #include "vgraph_separate_th.h" #include "vgraph_separate_st.h" #include "vgraph_separate_vw.h" #include "vgraph_separate_zr.h" /* ** The static and global variables. */ static Vgraph vgraphdummy; /* Dummy separator graph for offset computations */ static union { VgraphSeparateBdParam param; StratNodeMethodData padding; } vgraphseparatedefaultbd = { { 3, &stratdummy, &stratdummy } }; static union { VgraphSeparateEsParam param; StratNodeMethodData padding; } vgraphseparatedefaultes = { { &stratdummy, VGRAPHSEPAESWIDTHTHIN } }; static union { VgraphSeparateFmParam param; StratNodeMethodData padding; } vgraphseparatedefaultfm = { { 200, 1000, 0.1L } }; static union { VgraphSeparateGgParam param; StratNodeMethodData padding; } vgraphseparatedefaultgg = { { 5 } }; static union { VgraphSeparateGpParam param; StratNodeMethodData padding; } vgraphseparatedefaultgp = { { 9 } }; static union { VgraphSeparateMlParam param; StratNodeMethodData padding; } vgraphseparatedefaultml = { { 100, 0.8L, GRAPHCOARHEM, &stratdummy, &stratdummy } }; static StratMethodTab vgraphseparatestmethtab[] = { /* Graph separation methods array */ { VGRAPHSEPASTMETHBD, "b", vgraphSeparateBd, &vgraphseparatedefaultbd }, { VGRAPHSEPASTMETHES, "e", vgraphSeparateEs, &vgraphseparatedefaultes }, { VGRAPHSEPASTMETHFM, "f", vgraphSeparateFm, &vgraphseparatedefaultfm }, { VGRAPHSEPASTMETHGG, "h", vgraphSeparateGg, &vgraphseparatedefaultgg }, { VGRAPHSEPASTMETHGP, "g", vgraphSeparateGp, &vgraphseparatedefaultgp }, { VGRAPHSEPASTMETHML, "m", vgraphSeparateMl, &vgraphseparatedefaultml }, { VGRAPHSEPASTMETHVW, "v", vgraphSeparateVw, NULL }, { VGRAPHSEPASTMETHZR, "z", vgraphSeparateZr, NULL }, { -1, NULL, NULL, NULL } }; static StratParamTab vgraphseparatestparatab[] = { /* Graph separation method parameter list */ { VGRAPHSEPASTMETHBD, STRATPARAMSTRAT, "bnd", (byte *) &vgraphseparatedefaultbd.param, (byte *) &vgraphseparatedefaultbd.param.stratbnd, (void *) &vgraphseparateststratab }, { VGRAPHSEPASTMETHBD, STRATPARAMSTRAT, "org", (byte *) &vgraphseparatedefaultbd.param, (byte *) &vgraphseparatedefaultbd.param.stratorg, (void *) &vgraphseparateststratab }, { VGRAPHSEPASTMETHBD, STRATPARAMINT, "width", (byte *) &vgraphseparatedefaultbd.param, (byte *) &vgraphseparatedefaultbd.param.distmax, NULL }, { VGRAPHSEPASTMETHES, STRATPARAMSTRAT, "strat", (byte *) &vgraphseparatedefaultes.param, (byte *) &vgraphseparatedefaultes.param.strat, (void *) &bgraphbipartststratab }, { VGRAPHSEPASTMETHES, STRATPARAMCASE, "type", (byte *) &vgraphseparatedefaultes.param, (byte *) &vgraphseparatedefaultes.param.widtval, (void *) "tf" }, { VGRAPHSEPASTMETHFM, STRATPARAMINT, "move", (byte *) &vgraphseparatedefaultfm.param, (byte *) &vgraphseparatedefaultfm.param.movenbr, NULL }, { VGRAPHSEPASTMETHFM, STRATPARAMINT, "pass", (byte *) &vgraphseparatedefaultfm.param, (byte *) &vgraphseparatedefaultfm.param.passnbr, NULL }, { VGRAPHSEPASTMETHFM, STRATPARAMDOUBLE, "bal", (byte *) &vgraphseparatedefaultfm.param, (byte *) &vgraphseparatedefaultfm.param.deltrat, NULL }, { VGRAPHSEPASTMETHGG, STRATPARAMINT, "pass", (byte *) &vgraphseparatedefaultgg.param, (byte *) &vgraphseparatedefaultgg.param.passnbr, NULL }, { VGRAPHSEPASTMETHGP, STRATPARAMINT, "pass", (byte *) &vgraphseparatedefaultgp.param, (byte *) &vgraphseparatedefaultgp.param.passnbr, NULL }, { VGRAPHSEPASTMETHML, STRATPARAMSTRAT, "asc", (byte *) &vgraphseparatedefaultml.param, (byte *) &vgraphseparatedefaultml.param.stratasc, (void *) &vgraphseparateststratab }, { VGRAPHSEPASTMETHML, STRATPARAMSTRAT, "low", (byte *) &vgraphseparatedefaultml.param, (byte *) &vgraphseparatedefaultml.param.stratlow, (void *) &vgraphseparateststratab }, { VGRAPHSEPASTMETHML, STRATPARAMCASE, "type", (byte *) &vgraphseparatedefaultml.param, (byte *) &vgraphseparatedefaultml.param.coartype, (void *) "hs" }, { VGRAPHSEPASTMETHML, STRATPARAMINT, "vert", (byte *) &vgraphseparatedefaultml.param, (byte *) &vgraphseparatedefaultml.param.coarnbr, NULL }, { VGRAPHSEPASTMETHML, STRATPARAMDOUBLE, "rat", (byte *) &vgraphseparatedefaultml.param, (byte *) &vgraphseparatedefaultml.param.coarval, NULL }, { VGRAPHSEPASTMETHNBR, STRATPARAMINT, NULL, NULL, NULL, NULL } }; static StratParamTab vgraphseparatestcondtab[] = { /* Graph condition parameter table */ { STRATNODECOND, STRATPARAMINT, "edge", (byte *) &vgraphdummy, (byte *) &vgraphdummy.s.edgenbr, NULL }, { STRATNODECOND, STRATPARAMINT, "levl", (byte *) &vgraphdummy, (byte *) &vgraphdummy.levlnum, NULL }, { STRATNODECOND, STRATPARAMINT, "load", (byte *) &vgraphdummy, (byte *) &vgraphdummy.s.velosum, NULL }, { STRATNODECOND, STRATPARAMINT, "vert", (byte *) &vgraphdummy, (byte *) &vgraphdummy.s.vertnbr, NULL }, { STRATNODENBR, STRATPARAMINT, NULL, NULL, NULL, NULL } }; StratTab vgraphseparateststratab = { /* Strategy tables for vertex separation methods */ vgraphseparatestmethtab, vgraphseparatestparatab, vgraphseparatestcondtab }; /*******************************************/ /* */ /* This is the generic separation routine. */ /* */ /*******************************************/ /* This routine computes the separation of ** the given graph according to the given ** strategy. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int vgraphSeparateSt ( Vgraph * restrict const grafptr, /*+ Separation graph +*/ const Strat * restrict const strat) /*+ Separation strategy +*/ { StratTest val; VgraphStore savetab[2]; /* Results of the two strategies */ Gnum compload2; /* Saved separator load */ int o; #ifdef SCOTCH_DEBUG_VGRAPH2 if (sizeof (Gnum) != sizeof (INT)) { errorPrint ("vgraphSeparateSt: invalid type specification for parser variables"); return (1); } if ((sizeof (VgraphSeparateFmParam) > sizeof (StratNodeMethodData)) || (sizeof (VgraphSeparateGgParam) > sizeof (StratNodeMethodData)) || (sizeof (VgraphSeparateGpParam) > sizeof (StratNodeMethodData)) || (sizeof (VgraphSeparateMlParam) > sizeof (StratNodeMethodData))) { errorPrint ("vgraphSeparateSt: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ #ifdef SCOTCH_DEBUG_VGRAPH1 if ((strat->tabl != &vgraphseparateststratab) && (strat != &stratdummy)) { errorPrint ("vgraphSeparateSt: invalid parameter (1)"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH1 */ o = 0; switch (strat->type) { case STRATNODECONCAT : o = vgraphSeparateSt (grafptr, strat->data.concat.strat[0]); /* Apply first strategy */ if (o == 0) /* If it worked all right */ o |= vgraphSeparateSt (grafptr, strat->data.concat.strat[1]); /* Then apply second strategy */ break; case STRATNODECOND : o = stratTestEval (strat->data.cond.test, &val, (void *) grafptr); /* Evaluate expression */ if (o == 0) { /* If evaluation was correct */ #ifdef SCOTCH_DEBUG_VGRAPH2 if ((val.typetest != STRATTESTVAL) || (val.typenode != STRATPARAMLOG)) { errorPrint ("vgraphSeparateSt: invalid test result"); o = 1; break; } #endif /* SCOTCH_DEBUG_VGRAPH2 */ if (val.data.val.vallog == 1) /* If expression is true */ o = vgraphSeparateSt (grafptr, strat->data.cond.strat[0]); /* Apply first strategy */ else { /* Else if expression is false */ if (strat->data.cond.strat[1] != NULL) /* And if there is an else statement */ o = vgraphSeparateSt (grafptr, strat->data.cond.strat[1]); /* Apply second strategy */ } } break; case STRATNODEEMPTY : break; case STRATNODESELECT : if (((vgraphStoreInit (grafptr, &savetab[0])) != 0) || /* Allocate save areas */ ((vgraphStoreInit (grafptr, &savetab[1])) != 0)) { errorPrint ("vgraphSeparateSt: out of memory"); vgraphStoreExit (&savetab[0]); return (1); } vgraphStoreSave (grafptr, &savetab[1]); /* Save initial bipartition */ if (vgraphSeparateSt (grafptr, strat->data.select.strat[0]) != 0) { /* If first strategy didn't work */ vgraphStoreUpdt (grafptr, &savetab[1]); /* Restore initial bipartition */ vgraphStoreSave (grafptr, &savetab[0]); /* Save it as result */ } else { /* First strategy worked */ vgraphStoreSave (grafptr, &savetab[0]); /* Save its result */ vgraphStoreUpdt (grafptr, &savetab[1]); /* Restore initial bipartition */ } if (vgraphSeparateSt (grafptr, strat->data.select.strat[1]) != 0) /* If second strategy didn't work */ vgraphStoreUpdt (grafptr, &savetab[1]); /* Restore initial bipartition as its result */ compload2 = grafptr->s.velosum - savetab[0].compload[0] - savetab[0].compload[1]; /* Compute saved separator load */ if ( (compload2 < grafptr->compload[2]) || /* If first strategy is better */ ((compload2 == grafptr->compload[2]) && (abs (savetab[0].comploaddlt) < abs (grafptr->comploaddlt)))) vgraphStoreUpdt (grafptr, &savetab[0]); /* Restore its result */ vgraphStoreExit (&savetab[0]); /* Free both save areas */ vgraphStoreExit (&savetab[1]); break; #ifdef SCOTCH_DEBUG_VGRAPH1 case STRATNODEMETHOD : #else /* SCOTCH_DEBUG_VGRAPH1 */ default : #endif /* SCOTCH_DEBUG_VGRAPH1 */ return (strat->tabl->methtab[strat->data.method.meth].func (grafptr, (void *) &strat->data.method.data)); #ifdef SCOTCH_DEBUG_VGRAPH1 default : errorPrint ("vgraphSeparateSt: invalid parameter (2)"); return (1); #endif /* SCOTCH_DEBUG_VGRAPH1 */ } return (o); } scotch-6.0.4.dfsg/src/libscotch/hmesh_order_gp.c0000644002563400244210000002772511631447170025004 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh_order_gp.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module orders a subgraph (most **/ /** likely a separator) using the Gibbs, **/ /** Poole, and Stockmeyer algorithm. **/ /** **/ /** DATES : # Version 3.2 : from : 31 oct 1996 **/ /** to 27 aug 1998 **/ /** # Version 3.3 : from : 02 oct 1998 **/ /** to : 02 oct 1998 **/ /** # Version 4.0 : from : 05 nov 2002 **/ /** to : 27 jan 2004 **/ /** # Version 5.0 : from : 12 sep 2007 **/ /** to : 12 sep 2007 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HMESH_ORDER_GP #include "module.h" #include "common.h" #include "graph.h" #include "order.h" #include "mesh.h" #include "hmesh.h" #include "hmesh_order_gp.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the ordering. ** It returns: ** - 0 : if the ordering could be computed. ** - !0 : on error. */ int hmeshOrderGp ( const Hmesh * restrict const meshptr, Order * restrict const ordeptr, const Gnum ordenum, OrderCblk * restrict const cblkptr, /*+ Single column-block +*/ const HmeshOrderGpParam * restrict const paraptr) { HmeshOrderGpQueue queue; /* Neighbor queue */ HmeshOrderGpVertex * restrict vexxtax; /* Based access to vertex array */ HmeshOrderGpVertex * rootptr; /* Pointer to root vertex */ Gnum passnum; /* Pass number */ int passflag; /* Flag set if diameter changed */ Gnum vdianum; /* Vertex which achieves diameter */ Gnum vdiadist; /* Maximum diameter value found */ Gnum vnodnbr; /* Number of vertices found yet */ Gnum ordeval; /* Current ordering value */ if (memAllocGroup ((void **) (void *) &queue.qtab, (size_t) ((meshptr->vnohnnd - meshptr->m.baseval) * sizeof (Gnum)), &vexxtax, (size_t) ((meshptr->m.velmnbr + meshptr->m.vnodnbr) * sizeof (HmeshOrderGpVertex)), NULL) == NULL) { errorPrint ("hmeshOrderGp: out of memory"); return (1); } vexxtax -= meshptr->m.baseval; /* Base vexxtab array */ memSet (vexxtax + meshptr->m.velmbas, 0, meshptr->m.velmnbr * sizeof (HmeshOrderGpVertex)); /* Initialize pass numbers for */ memSet (vexxtax + meshptr->m.vnodbas, 0, (meshptr->vnohnnd - meshptr->m.vnodbas) * sizeof (HmeshOrderGpVertex)); /* All but halo node vertices */ for (vnodnbr = 0, ordeval = ordenum, rootptr = vexxtax + meshptr->m.vnodbas, passnum = 1; /* For all connected components */ vnodnbr < meshptr->vnohnbr; passnum ++) { while (rootptr->passnum != 0) /* Find first unallocated root */ rootptr ++; vdianum = rootptr - vexxtax; /* Start from found root */ vdiadist = 0; for (passflag = 1; (passflag -- != 0) && (passnum <= paraptr->passnbr); passnum ++) { /* Loop if modifications */ hmeshOrderGpQueueFlush (&queue); /* Flush vertex queue */ hmeshOrderGpQueuePut (&queue, vdianum); /* Start from diameter vertex */ vexxtax[vdianum].passnum = passnum; /* It has been enqueued */ vexxtax[vdianum].vertdist = 0; /* It is at distance zero */ do { /* Loop on vertices in queue */ Gnum vnodnum; /* Number of current vertex */ Gnum vnoddist; /* Distance of current vertex */ Gnum enodnum; vnodnum = hmeshOrderGpQueueGet (&queue); /* Get vertex from queue */ vnoddist = vexxtax[vnodnum].vertdist; /* Get vertex distance */ if ((vnoddist > vdiadist) || /* If vertex increases diameter */ ((vnoddist == vdiadist) && /* Or is at diameter distance */ ((meshptr->m.vendtax[vnodnum] - meshptr->m.verttax[vnodnum]) < /* With smaller degree */ (meshptr->m.vendtax[vdianum] - meshptr->m.verttax[vdianum])))) { vdianum = vnodnum; /* Set it as new diameter vertex */ vdiadist = vnoddist; passflag = 1; } vnoddist ++; /* Set neighbor distance */ for (enodnum = meshptr->m.verttax[vnodnum]; enodnum < meshptr->m.vendtax[vnodnum]; enodnum ++) { Gnum velmnum; Gnum eelmnum; velmnum = meshptr->m.edgetax[enodnum]; /* Get neighboring element */ if (vexxtax[velmnum].passnum >= passnum) /* If element already scanned */ continue; /* Skip to next element */ vexxtax[velmnum].passnum = passnum; /* Set element as scanned */ for (eelmnum = meshptr->m.verttax[velmnum]; /* For all neighboring non-halo nodes */ eelmnum < meshptr->vehdtax[velmnum]; eelmnum ++) { Gnum vnodend; /* Neighboring node */ vnodend = meshptr->m.edgetax[eelmnum]; /* Get neighboring node */ if (vexxtax[vnodend].passnum < passnum) { /* If node vertex not yet enqueued */ hmeshOrderGpQueuePut (&queue, vnodend); /* Enqueue neighbor vertex */ vexxtax[vnodend].passnum = passnum; vexxtax[vnodend].vertdist = vnoddist; } } } } while (! hmeshOrderGpQueueEmpty (&queue)); /* As long as queue is not empty */ } hmeshOrderGpQueueFlush (&queue); /* Flush vertex queue */ hmeshOrderGpQueuePut (&queue, vdianum); /* Start from diameter vertex */ vexxtax[vdianum].passnum = passnum; /* It has been enqueued */ do { /* Loop on vertices in queue */ Gnum vnodnum; /* Number of current vertex */ Gnum vnoddist; /* Distance of current vertex */ vnodnum = hmeshOrderGpQueueGet (&queue); /* Get vertex from queue */ if (vexxtax[vnodnum].passnum > passnum) /* If vertex already ordered */ continue; /* Skip to next vertex in queue */ vnoddist = vexxtax[vnodnum].vertdist; /* Get vertex distance */ do { /* Loop on vertices in layer */ Gnum enodnum; Gnum enodnnd; ordeptr->peritab[ordeval] = (meshptr->m.vnumtax == NULL) /* Order node vertex */ ? vnodnum - (meshptr->m.vnodbas - meshptr->m.baseval) : meshptr->m.vnumtax[vnodnum]; #ifdef SCOTCH_DEBUG_ORDER2 if ((ordeptr->peritab[ordeval] < ordeptr->baseval) || (ordeptr->peritab[ordeval] >= (ordeptr->baseval + ordeptr->vnodnbr))) { errorPrint ("hmeshOrderGp: invalid permutation index"); return (1); } #endif /* SCOTCH_DEBUG_ORDER2 */ ordeval ++; vexxtax[vnodnum].passnum = (passnum + 1); /* Set vertex as ordered */ vnodnbr ++; /* Count it */ for (enodnum = meshptr->m.verttax[vnodnum], enodnnd = meshptr->m.vendtax[vnodnum], vnodnum = ~0; enodnum < enodnnd; enodnum ++) { /* Order node vertices with high locality */ Gnum velmnum; /* Neighboring element */ Gnum eelmnum; velmnum = meshptr->m.edgetax[enodnum]; /* Get neighboring element */ if (vexxtax[velmnum].passnum >= passnum) /* If element already scanned */ continue; /* Skip to next element */ vexxtax[velmnum].passnum = passnum; /* Set element as scanned */ for (eelmnum = meshptr->m.verttax[velmnum]; /* For all neighboring non-halo nodes */ eelmnum < meshptr->vehdtax[velmnum]; eelmnum ++) { Gnum vnodend; /* Neighboring node */ vnodend = meshptr->m.edgetax[eelmnum]; /* Get neighboring node */ if (vexxtax[vnodend].passnum <= passnum) { /* If vertex not ordered yet */ if ((vnodnum == ~0) && /* If no next vertex set yet */ (vexxtax[vnodend].vertdist == vnoddist)) /* And in same layer */ vnodnum = vnodend; /* Set neighbor as next vertex */ else if (vexxtax[vnodend].passnum < passnum) { /* If not enqueued yet */ hmeshOrderGpQueuePut (&queue, vnodend); /* Enqueue neighbor vertex */ vexxtax[vnodend].passnum = passnum; /* Set it as enqueued */ } } } } } while (vnodnum != ~0); } while (! hmeshOrderGpQueueEmpty (&queue)); /* As long as queue is not empty */ } #ifdef SCOTCH_DEBUG_ORDER2 for (ordeval = ordenum; ordeval < (ordenum + meshptr->vnohnbr); ordeval ++) { if (ordeptr->peritab[ordeval] == ~0) { errorPrint ("hmeshOrderGp: internal error"); memFree (queue.qtab); /* Free group leader */ return (1); } } #endif /* SCOTCH_DEBUG_ORDER2 */ memFree (queue.qtab); /* Free group leader */ return (0); } scotch-6.0.4.dfsg/src/libscotch/dgraph_coarsen.h0000644002563400244210000002111512412035044024755 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2009,2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_coarsen.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Cedric CHEVALIER (v5.0) **/ /** **/ /** FUNCTION : This file implements the distributed **/ /** graph coarsening method. **/ /** **/ /** DATES : # Version 5.0 : from : 27 Jul 2005 **/ /** to : 24 feb 2007 **/ /** # Version 5.1 : from : 11 nov 2008 **/ /** to : 26 may 2009 **/ /** # Version 6.0 : from : 18 sep 2012 **/ /** to : 28 sep 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ Graph option flags. Their values must be equal to those defined in library.h and library_f.h +*/ #define DGRAPHCOARSENNONE 0x0000 /* No options set */ #define DGRAPHCOARSENFOLD 0x0100 /* Do folding without duplication */ #define DGRAPHCOARSENFOLDDUP 0x0300 /* Do folding with duplication */ #define DGRAPHCOARSENNOMERGE 0x4000 /* Do not merge isolated vertices */ /* ** The type and structure definitions. */ /*+ The multinode table element, which contains pairs of based indices of collapsed vertices. Both values are equal for uncollapsed vertices. +*/ typedef struct DgraphCoarsenMulti_ { Gnum vertglbnum[2]; /*+ Global indices of the collapsed vertices of a multinode +*/ } DgraphCoarsenMulti; /* This structure defines vertex data exchange cell. It can have many uses depending on the type of algorithm. */ typedef struct DgraphCoarsenVert_ { Gnum datatab[2]; /*+ Two values +*/ } DgraphCoarsenVert; /* This structure defines the inter-process vertex and edge count structure. At matching time, it records the amount of data to be sent to each neighbor process. */ typedef struct DgraphCoarsenCount_ { Gnum vertsndnbr; Gnum edgesndnbr; Gnum vertlocnbr; } DgraphCoarsenCount; /*+ A table made of such elements is used during coarsening to build the edge array of the new graph, after the labeling of the vertices. +*/ typedef struct DgraphCoarsenHash_ { Gnum vertorgnum; /*+ Origin vertex (i.e. pass) number +*/ Gnum vertendnum; /*+ Other end vertex number +*/ Gnum edgelocnum; /*+ Number of corresponding edge +*/ } DgraphCoarsenHash; /*+ This structure gathers all data necessary to the proper execution of the coarsening and matching routines. +*/ typedef struct DgraphCoarsenData_ { int flagval; /*+ Flag value +*/ Dgraph * finegrafptr; /*+ Pointer to fine graph +*/ Dgraph * coargrafptr; /*+ Pointer to coarse graph which is built +*/ int * coarprvptr; /*+ Pointer to coarse private data to free in case of error +*/ DgraphCoarsenVert * vrcvdattab; /*+ Area reserved for receiving vertex messages +*/ DgraphCoarsenVert * vsnddattab; /*+ Area reserved for sending vertex messages +*/ int * vrcvcnttab; /*+ Count data for vertex receive sub-arrays +*/ int * vsndcnttab; /*+ Count data for vertex send sub-arrays +*/ int * vrcvdsptab; /*+ Displacement for vertex receive sub-arrays [+1] +*/ int * vsnddsptab; /*+ Displacement data for vertex send sub-arrays [+1] +*/ int * nrcvidxtab; /*+ Count array for neighbor receive sub-arrays +*/ int * nsndidxtab; /*+ Count array for neighbor send sub-arrays +*/ MPI_Request * nrcvreqtab; /*+ Request array for receive requests +*/ MPI_Request * nsndreqtab; /*+ TRICK: nsndreqtab = (nrcvreqtab + procngbnbr) +*/ int * procgsttax; /*+ Array giving the neighbor process index of each ghost vertex +*/ int procngbnxt; /*+ Index of first neighbor of higher rank than current process +*/ DgraphCoarsenCount * dcntloctab; /*+ Count array for sending vertices and edges +*/ DgraphCoarsenCount * dcntglbtab; /*+ Count array for receiving vertices and edges +*/ Gnum * coargsttax; /*+ Fine-to-coarse vertex index array +*/ DgraphCoarsenMulti * multloctmp; /*+ Pointer to multloctab structure to free (if any) +*/ DgraphCoarsenMulti * multloctab; /*+ Structure which contains the result of the matching +*/ Gnum multlocnbr; /*+ Index of next multinode to be created +*/ Gnum vertrcvnbr; /*+ Number of fine vertices to be received +*/ Gnum edgercvnbr; /*+ Number of fine edges to be received +*/ Gnum edgekptnbr; /*+ Upper bound on number of edges kept from finer graph +*/ Gnum vertsndnbr; /*+ Number of fine vertices to be sent +*/ Gnum edgesndnbr; /*+ Number of fine edges to be sent +*/ } DgraphCoarsenData; /* ** The function prototypes. */ #ifndef DGRAPH_COARSEN #define static #endif static int dgraphCoarsenInit (DgraphCoarsenData * restrict const, Dgraph * restrict const, Dgraph * restrict const); static void dgraphCoarsenExit (DgraphCoarsenData * restrict const); static int dgraphCoarsenBuild (DgraphCoarsenData * restrict const); int dgraphCoarsen (Dgraph * restrict const, Dgraph * restrict const, DgraphCoarsenMulti * restrict * const, const Gnum, const Gnum, const double, const int); #undef static scotch-6.0.4.dfsg/src/libscotch/library_arch.c0000644002563400244210000004063412374742714024461 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2009-2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_arch.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module is the API for the target **/ /** architecture handling routines of the **/ /** libSCOTCH library. **/ /** **/ /** DATES : # Version 3.2 : from : 18 aug 1998 **/ /** to : 18 aug 1998 **/ /** # Version 3.3 : from : 02 oct 1998 **/ /** to : 29 mar 1999 **/ /** # Version 3.4 : from : 01 nov 2001 **/ /** to : 01 nov 2001 **/ /** # Version 4.0 : from : 13 jan 2004 **/ /** to : 13 jan 2004 **/ /** # Version 5.0 : from : 12 sep 2007 **/ /** to : 12 sep 2007 **/ /** # Version 5.1 : from : 05 jun 2009 **/ /** to : 13 feb 2011 **/ /** # Version 6.0 : from : 14 fev 2011 **/ /** to 19 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "graph.h" #include "arch.h" #include "arch_cmplt.h" #include "arch_cmpltw.h" #include "arch_hcub.h" #include "arch_mesh.h" #include "arch_tleaf.h" #include "arch_torus.h" #include "arch_vcmplt.h" #include "arch_vhcub.h" #include "scotch.h" /***************************************/ /* */ /* These routines are the C API for */ /* the architecture handling routines. */ /* */ /***************************************/ /*+ This routine reserves a memory area *** of a size sufficient to store a *** target architecture. *** It returns: *** - !NULL : if the initialization succeeded. *** - NULL : on error. +*/ SCOTCH_Arch * SCOTCH_archAlloc () { return ((SCOTCH_Arch *) memAlloc (sizeof (SCOTCH_Arch))); } /*+ This routine initializes the opaque *** architecture structure used to handle *** target architectures in the Scotch library. *** It returns: *** - 0 : if the initialization succeeded. *** - !0 : on error. +*/ int SCOTCH_archInit ( SCOTCH_Arch * const archptr) { if (sizeof (SCOTCH_Num) != sizeof (Anum)) { errorPrint ("SCOTCH_archInit: internal error (1)"); return (1); } if (sizeof (SCOTCH_Arch) < sizeof (Arch)) { errorPrint ("SCOTCH_archInit: internal error (2)"); return (1); } return (archInit ((Arch *) archptr)); } /*+ This routine frees the contents of the *** given opaque architecture structure. *** It returns: *** - VOID : in all cases. +*/ void SCOTCH_archExit ( SCOTCH_Arch * const archptr) { archExit ((Arch *) archptr); } /*+ This routine loads the given opaque *** architecture structure with the data of *** the given stream. *** It returns: *** - 0 : if the loading succeeded. *** - !0 : on error. +*/ int SCOTCH_archLoad ( SCOTCH_Arch * const archptr, FILE * const stream) { return (archLoad ((Arch *) archptr, stream)); } /*+ This routine saves the given opaque *** architecture structure to the given *** stream. *** It returns: *** - 0 : if the saving succeeded. *** - !0 : on error. +*/ int SCOTCH_archSave ( const SCOTCH_Arch * const archptr, FILE * const stream) { return (archSave ((Arch *) archptr, stream)); } /*+ This routine returns the name of the *** given target architecture. *** It returns: *** - !NULL : pointer to the name of the *** target architecture. +*/ char * SCOTCH_archName ( const SCOTCH_Arch * const archptr) { return (archName ((const Arch * const) archptr)); } /*+ This routine returns the size of the *** given target architecture. *** It returns: *** - !0 : size of the target architecture. +*/ SCOTCH_Num SCOTCH_archSize ( const SCOTCH_Arch * const archptr) { ArchDom domdat; archDomFrst ((Arch *) archptr, &domdat); /* Get first domain */ return (archDomSize ((Arch *) archptr, &domdat)); /* Return domain size */ } /*+ This routine tells if the given architecture *** is a variable-sized architecture or not. *** It returns: *** - 0 : if the architecture is not variable-sized. *** - 1 : if the architecture is variable-sized. +*/ int SCOTCH_archVar ( const SCOTCH_Arch * const archptr) { return ((archVar ((Arch *) archptr) != 0) ? 1 : 0); } /*+ These routines fill the contents of the given *** opaque target structure so as to yield target *** architectures of the given types. *** It returns: *** - 0 : if the computation succeeded. *** - !0 : on error. +*/ int SCOTCH_archCmplt ( SCOTCH_Arch * const archptr, const SCOTCH_Num numnbr) { Arch * tgtarchptr; ArchCmplt * tgtarchdatptr; if (sizeof (SCOTCH_Num) != sizeof (Gnum)) { errorPrint ("SCOTCH_archCmplt: internal error"); return (1); } tgtarchptr = (Arch *) archptr; tgtarchdatptr = (ArchCmplt *) (void *) (&tgtarchptr->data); tgtarchptr->class = archClass ("cmplt"); tgtarchptr->flagval = tgtarchptr->class->flagval; /* Copy architecture flag */ tgtarchdatptr->numnbr = (Anum) numnbr; return (0); } /* ** */ int SCOTCH_archCmpltw ( SCOTCH_Arch * const archptr, const SCOTCH_Num vertnbr, const SCOTCH_Num * const velotab) { Arch * tgtarchptr; if (sizeof (SCOTCH_Num) != sizeof (Gnum)) { errorPrint ("SCOTCH_archCmpltw: internal error"); return (1); } tgtarchptr = (Arch *) archptr; tgtarchptr->class = archClass ("cmpltw"); tgtarchptr->flagval = tgtarchptr->class->flagval; /* Copy architecture flag */ return (archCmpltwArchBuild ((ArchCmpltw *) (void *) (&tgtarchptr->data), vertnbr, velotab)); } /* ** */ int SCOTCH_archHcub ( SCOTCH_Arch * const archptr, const SCOTCH_Num dimmax) /*+ Number of dimensions +*/ { Arch * tgtarchptr; ArchHcub * tgtarchdatptr; if (sizeof (SCOTCH_Num) != sizeof (Gnum)) { errorPrint ("SCOTCH_archHcub: internal error"); return (1); } tgtarchptr = (Arch *) archptr; tgtarchdatptr = (ArchHcub *) (void *) (&tgtarchptr->data); tgtarchptr->class = archClass ("hcub"); tgtarchptr->flagval = tgtarchptr->class->flagval; /* Copy architecture flag */ tgtarchdatptr->dimmax = (Anum) dimmax; return (0); } /* ** */ int SCOTCH_archMesh2 ( SCOTCH_Arch * const archptr, const SCOTCH_Num dimxval, const SCOTCH_Num dimyval) { Arch * tgtarchptr; ArchMesh2 * tgtarchdatptr; if (sizeof (SCOTCH_Num) != sizeof (Gnum)) { errorPrint ("SCOTCH_archMesh2: internal error"); return (1); } tgtarchptr = (Arch *) archptr; tgtarchdatptr = (ArchMesh2 *) (void *) (&tgtarchptr->data); tgtarchptr->class = archClass ("mesh2D"); tgtarchptr->flagval = tgtarchptr->class->flagval; /* Copy architecture flag */ tgtarchdatptr->c[0] = (Anum) dimxval; tgtarchdatptr->c[1] = (Anum) dimyval; return (0); } /* ** */ int SCOTCH_archMesh3 ( SCOTCH_Arch * const archptr, const SCOTCH_Num dimxval, const SCOTCH_Num dimyval, const SCOTCH_Num dimzval) { Arch * tgtarchptr; ArchMesh3 * tgtarchdatptr; if (sizeof (SCOTCH_Num) != sizeof (Gnum)) { errorPrint ("SCOTCH_archMesh3: internal error"); return (1); } tgtarchptr = (Arch *) archptr; tgtarchdatptr = (ArchMesh3 *) (void *) (&tgtarchptr->data); tgtarchptr->class = archClass ("mesh3D"); tgtarchptr->flagval = tgtarchptr->class->flagval; /* Copy architecture flag */ tgtarchdatptr->c[0] = (Anum) dimxval; tgtarchdatptr->c[1] = (Anum) dimyval; tgtarchdatptr->c[2] = (Anum) dimzval; return (0); } /* ** */ int SCOTCH_archTleaf ( SCOTCH_Arch * const archptr, const SCOTCH_Num levlnbr, /*+ Number of levels in architecture +*/ const SCOTCH_Num * const sizetab, /*+ Size array, by increasing level number +*/ const SCOTCH_Num * const linktab) /*+ Link cost array, by increasing level number +*/ { Anum levlnum; Anum sizeval; Arch * tgtarchptr; ArchTleaf * tgtarchdatptr; if (sizeof (SCOTCH_Num) != sizeof (Gnum)) { errorPrint ("SCOTCH_archTleaf: internal error"); return (1); } tgtarchptr = (Arch *) archptr; tgtarchdatptr = (ArchTleaf *) (void *) (&tgtarchptr->data); tgtarchptr->class = archClass ("tleaf"); tgtarchptr->flagval = tgtarchptr->class->flagval; /* Copy architecture flag */ if ((tgtarchdatptr->sizetab = memAlloc ((levlnbr * 2 + 1) * sizeof (Anum))) == NULL) { /* TRICK: One more slot for linktab[-1] */ errorPrint ("SCOTCH_archTleaf: out of memory"); return (1); } tgtarchdatptr->levlnbr = (Anum) levlnbr; tgtarchdatptr->linktab = tgtarchdatptr->sizetab + tgtarchdatptr->levlnbr + 1; tgtarchdatptr->linktab[-1] = 0; /* TRICK: Dummy slot for for level-0 communication */ tgtarchdatptr->permtab = NULL; /* Assume no permutation array */ for (levlnum = 0, sizeval = 1; levlnum < tgtarchdatptr->levlnbr; levlnum ++) { tgtarchdatptr->sizetab[levlnum] = sizetab[levlnum]; tgtarchdatptr->linktab[levlnum] = linktab[levlnum]; sizeval *= tgtarchdatptr->sizetab[levlnum]; } tgtarchdatptr->termnbr = sizeval; return (0); } /* ** */ int SCOTCH_archLtleaf ( SCOTCH_Arch * const archptr, const SCOTCH_Num levlnbr, /*+ Number of levels in architecture +*/ const SCOTCH_Num * const sizetab, /*+ Size array, by increasing level number +*/ const SCOTCH_Num * const linktab, /*+ Link cost array, by increasing level number +*/ const SCOTCH_Num permnbr, /*+ Number of permutation indices +*/ const SCOTCH_Num * const permtab) /*+ Permutation array +*/ { Anum levlnum; Anum permnum; Anum sizeval; Arch * tgtarchptr; ArchTleaf * tgtarchdatptr; if (SCOTCH_archTleaf (archptr, levlnbr, sizetab, linktab) != 0) /* Build tree part */ return (1); tgtarchptr = (Arch *) archptr; tgtarchdatptr = (ArchTleaf *) (void *) (&tgtarchptr->data); tgtarchptr->class = archClass ("ltleaf"); /* Override class */ if ((tgtarchdatptr->permtab = memAlloc (permnbr * 2 * sizeof (Anum))) == NULL) { /* TRICK: space for peritab too */ errorPrint ("SCOTCH_archLtleaf: out of memory"); return (1); } tgtarchdatptr->permnbr = (Anum) permnbr; tgtarchdatptr->peritab = tgtarchdatptr->permtab + permnbr; for (permnum = 0; permnum < tgtarchdatptr->permnbr; permnum ++) tgtarchdatptr->permtab[permnum] = permtab[permnum]; for (permnum = 0; permnum < tgtarchdatptr->permnbr; permnum ++) /* Build inverse permutation */ tgtarchdatptr->peritab[tgtarchdatptr->permtab[permnum]] = permnum; return (0); } /* ** */ int SCOTCH_archTorus2 ( SCOTCH_Arch * const archptr, const SCOTCH_Num dimxval, const SCOTCH_Num dimyval) { Arch * tgtarchptr; ArchTorusX * tgtarchdatptr; if (sizeof (SCOTCH_Num) != sizeof (Gnum)) { errorPrint ("SCOTCH_archTorus2: internal error"); return (1); } tgtarchptr = (Arch *) archptr; tgtarchdatptr = (ArchTorusX *) (void *) (&tgtarchptr->data); tgtarchptr->class = archClass ("torus2D"); tgtarchptr->flagval = tgtarchptr->class->flagval; /* Copy architecture flag */ tgtarchdatptr->dimmax = 2; tgtarchdatptr->c[0] = (Anum) dimxval; tgtarchdatptr->c[1] = (Anum) dimyval; return (0); } /* ** */ int SCOTCH_archTorus3 ( SCOTCH_Arch * const archptr, const SCOTCH_Num dimxval, const SCOTCH_Num dimyval, const SCOTCH_Num dimzval) { Arch * tgtarchptr; ArchTorusX * tgtarchdatptr; if (sizeof (SCOTCH_Num) != sizeof (Gnum)) { errorPrint ("SCOTCH_archTorus3: internal error"); return (1); } tgtarchptr = (Arch *) archptr; tgtarchdatptr = (ArchTorusX *) (void *) (&tgtarchptr->data); tgtarchptr->class = archClass ("torus3D"); tgtarchptr->flagval = tgtarchptr->class->flagval; /* Copy architecture flag */ tgtarchdatptr->dimmax = 3; tgtarchdatptr->c[0] = (Anum) dimxval; tgtarchdatptr->c[1] = (Anum) dimyval; tgtarchdatptr->c[2] = (Anum) dimzval; return (0); } /* ** */ int SCOTCH_archTorusX ( SCOTCH_Arch * const archptr, const SCOTCH_Num dimnbr, /*+ Number of dimensions in architecture +*/ const SCOTCH_Num * const dimtab) /*+ Array of dimensions +*/ { Arch * tgtarchptr; ArchTorusX * tgtarchdatptr; if (sizeof (SCOTCH_Num) != sizeof (Gnum)) { errorPrint ("SCOTCH_archTorusX: internal error"); return (1); } if (dimnbr > ARCHTORUSDIMMAX) { errorPrint ("SCOTCH_archTorusX: too many dimensions"); return (1); } tgtarchptr = (Arch *) archptr; tgtarchdatptr = (ArchTorusX *) (void *) (&tgtarchptr->data); tgtarchptr->class = archClass ("torusXD"); tgtarchptr->flagval = tgtarchptr->class->flagval; /* Copy architecture flag */ tgtarchdatptr->dimmax = dimnbr; memCpy (tgtarchdatptr->c, dimtab, dimnbr * sizeof (SCOTCH_Num)); /* Copy dimension array */ return (0); } /* ** */ int SCOTCH_archVcmplt ( SCOTCH_Arch * const archptr) { Arch * tgtarchptr; if (sizeof (SCOTCH_Num) != sizeof (Gnum)) { errorPrint ("SCOTCH_archVcmplt: internal error"); return (1); } tgtarchptr = (Arch *) archptr; tgtarchptr->class = archClass ("varcmplt"); tgtarchptr->flagval = tgtarchptr->class->flagval; /* Copy architecture flag */ return (0); } /* ** */ int SCOTCH_archVhcub ( SCOTCH_Arch * const archptr) { Arch * tgtarchptr; if (sizeof (SCOTCH_Num) != sizeof (Gnum)) { errorPrint ("SCOTCH_archVhcub: internal error"); return (1); } tgtarchptr = (Arch *) archptr; tgtarchptr->class = archClass ("varhcub"); tgtarchptr->flagval = tgtarchptr->class->flagval; /* Copy architecture flag */ return (0); } scotch-6.0.4.dfsg/src/libscotch/bgraph_check.c0000644002563400244210000002077712376715054024425 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2009,2013,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bgraph_check.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the bipartition **/ /** graph consistency checking routine. **/ /** **/ /** DATES : # Version 4.0 : from : 08 jan 2004 **/ /** to 07 dec 2005 **/ /** # Version 5.1 : from : 04 oct 2009 **/ /** to 04 oct 2009 **/ /** # Version 6.0 : from : 06 oct 2013 **/ /** to 25 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define BGRAPH #include "module.h" #include "common.h" #include "graph.h" #include "arch.h" #include "bgraph.h" /*************************/ /* */ /* These routines handle */ /* bipartition graphs. */ /* */ /*************************/ /* This routine checks the consistency ** of the given bipartition graph. ** It returns: ** - 0 : if graph data are consistent. ** - !0 : on error. */ int bgraphCheck ( const Bgraph * restrict const grafptr) { int * restrict flagtax; /* Frontier flag array */ Gnum vertnum; /* Number of current vertex */ Gnum fronnum; /* Number of frontier vertex */ Gnum compload[2]; Gnum compsize[2]; Gnum commloadintn; Gnum commloadextn; Gnum commgainextn; Gnum edloval; int o; const Gnum * restrict const verttax = grafptr->s.verttax; const Gnum * restrict const vendtax = grafptr->s.vendtax; const Gnum * restrict const velotax = grafptr->s.velotax; const Gnum * restrict const edgetax = grafptr->s.edgetax; const Gnum * restrict const edlotax = grafptr->s.edlotax; const GraphPart * restrict const parttax = grafptr->parttax; const Gnum * restrict const frontab = grafptr->frontab; if (grafptr->compload0avg != (Gnum) (((double) (grafptr->s.velosum + grafptr->vfixload[0] + grafptr->vfixload[1]) * (double) grafptr->domnwght[0]) / (double) (grafptr->domnwght[0] + grafptr->domnwght[1])) - grafptr->vfixload[0]) { errorPrint ("bgraphCheck: invalid average load"); return (1); } if (grafptr->compload0 != (grafptr->compload0avg + grafptr->compload0dlt)) { errorPrint ("bgraphCheck: invalid load balance"); return (1); } for (vertnum = grafptr->s.baseval; vertnum < grafptr->s.vertnnd; vertnum ++) { if ((parttax[vertnum] | 1) != 1) { /* If part is neither 0 nor 1 */ errorPrint ("bgraphCheck: invalid part array"); return (1); } } if ((grafptr->fronnbr < 0) || (grafptr->fronnbr > grafptr->s.vertnbr)) { errorPrint ("bgraphCheck: invalid number of frontier vertices"); return (1); } if ((flagtax = memAlloc (grafptr->s.vertnbr * sizeof (int))) == NULL) { errorPrint ("bgraphCheck: out of memory"); return (1); } memSet (flagtax, ~0, grafptr->s.vertnbr * sizeof (int)); flagtax -= grafptr->s.baseval; o = 1; /* Assume failure when checking */ for (fronnum = 0; fronnum < grafptr->fronnbr; fronnum ++) { Gnum vertnum; Gnum edgenum; GraphPart partval; GraphPart flagval; vertnum = frontab[fronnum]; if ((vertnum < grafptr->s.baseval) || (vertnum >= grafptr->s.vertnnd)) { errorPrint ("bgraphCheck: invalid vertex index in frontier array"); goto fail; } if (flagtax[vertnum] != ~0) { errorPrint ("bgraphCheck: duplicate vertex in frontier array"); goto fail; } flagtax[vertnum] = 0; partval = parttax[vertnum]; for (edgenum = verttax[vertnum], flagval = 0; edgenum < vendtax[vertnum]; edgenum ++) flagval |= parttax[edgetax[edgenum]] ^ partval; /* Flag set if neighbor part differs from vertex part */ if (flagval == 0) { errorPrint ("bgraphCheck: invalid vertex in frontier array"); goto fail; } } compload[0] = compload[1] = 0; compsize[0] = compsize[1] = 0; commloadintn = 0; commloadextn = grafptr->commloadextn0; commgainextn = 0; edloval = 1; /* Assume edges are not weighted */ for (vertnum = grafptr->s.baseval; vertnum < grafptr->s.vertnnd; vertnum ++) { Gnum partval; /* Part of current vertex */ Gnum edgenum; /* Number of current edge */ Gnum commcut[2]; partval = (Gnum) parttax[vertnum]; if (grafptr->veextax != NULL) { Gnum veexval; veexval = grafptr->veextax[vertnum]; commloadextn += veexval * partval; commgainextn += veexval * (1 - 2 * partval); } compload[partval] += (velotax == NULL) ? 1 : velotax[vertnum]; compsize[partval] ++; commcut[partval] = 1; /* Create loop to account for own vertex part */ commcut[1 - partval] = 0; for (edgenum = verttax[vertnum]; edgenum < vendtax[vertnum]; edgenum ++) { int partend; int partdlt; if (edlotax != NULL) edloval = edlotax[edgenum]; partend = parttax[edgetax[edgenum]]; partdlt = partval ^ partend; commcut[partend] ++; commloadintn += partdlt * edloval * partend; /* Only count loads once, when (partend == 1) */ } if ((commcut[0] != 0) && (commcut[1] != 0) && /* If vertex should be in frontier array */ (flagtax[vertnum] != 0)) { errorPrint ("bgraphCheck: vertex should be in frontier array"); goto fail; } } if (compsize[0] != grafptr->compsize0) { errorPrint ("bgraphCheck: invalid part size"); goto fail; } if (compload[0] != grafptr->compload0) { errorPrint ("bgraphCheck: invalid part load"); goto fail; } if ((commloadintn * grafptr->domndist + commloadextn) != grafptr->commload) { errorPrint ("bgraphCheck: invalid communication loads"); goto fail; } if (commgainextn != grafptr->commgainextn) { errorPrint ("bgraphCheck: invalid communication gains"); goto fail; } o = 0; /* Everything turned well */ fail : memFree (flagtax + grafptr->s.baseval); return (o); } scotch-6.0.4.dfsg/src/libscotch/hmesh_order_gr.h0000644002563400244210000000572611631447171025011 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh_order_gr.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the graph-based node ordering **/ /** routine. **/ /** **/ /** DATES : # Version 4.0 : from : 30 nov 2003 **/ /** to : 30 nov 2003 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct HmeshOrderGrParam_ { Strat * stratptr; /*+ Graph ordering strategy +*/ } HmeshOrderGrParam; /* ** The function prototypes. */ #ifndef HMESH_ORDER_GR #define static #endif int hmeshOrderGr (const Hmesh * const, Order * restrict const, const Gnum, OrderCblk * restrict const, const HmeshOrderGrParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/library_dgraph_build_f.c0000644002563400244210000001037712055775635026502 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_build_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API for **/ /** the distributed source graph handling **/ /** routines of the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 24 feb 2007 **/ /** to 18 jul 2007 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "ptscotch.h" /********************************************/ /* */ /* These routines are the Fortran API for */ /* the distributed graph handling routines. */ /* */ /********************************************/ /* ** */ FORTRAN ( \ SCOTCHFDGRAPHBUILD, scotchfdgraphbuild, ( \ SCOTCH_Dgraph * const grafptr, \ const SCOTCH_Num * const baseptr, \ const SCOTCH_Num * const vertlocptr, \ const SCOTCH_Num * const vertlocmpt, \ SCOTCH_Num * const vertloctab, \ SCOTCH_Num * const vendloctab, \ SCOTCH_Num * const veloloctab, \ SCOTCH_Num * const vlblloctab, \ const SCOTCH_Num * const edgelocptr, \ const SCOTCH_Num * const edgelocptz, \ SCOTCH_Num * const edgeloctab, \ SCOTCH_Num * const edgegsttab, \ SCOTCH_Num * const edloloctab, \ int * const revaptr), \ (grafptr, baseptr, vertlocptr, vertlocmpt, \ vertloctab, vendloctab, veloloctab, \ vlblloctab, edgelocptr, edgelocptz, \ edgeloctab, edgegsttab, edloloctab, \ revaptr)) { *revaptr = SCOTCH_dgraphBuild (grafptr, *baseptr, *vertlocptr, *vertlocmpt, vertloctab, vendloctab, veloloctab, vlblloctab, *edgelocptr, *edgelocptz, edgeloctab, edgegsttab, edloloctab); } scotch-6.0.4.dfsg/src/libscotch/kgraph_map_rb_map.c0000644002563400244210000013373612400017526025441 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007-2009,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph_map_rb_map.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module performs the Dual Recursive **/ /** Bipartitioning mapping algorithm. **/ /** **/ /** DATES : # Version 0.0 : from : 31 mar 1993 **/ /** to 31 mar 1993 **/ /** # Version 1.0 : from : 04 oct 1993 **/ /** to 06 oct 1993 **/ /** # Version 1.1 : from : 15 oct 1993 **/ /** to 15 oct 1993 **/ /** # Version 1.3 : from : 09 apr 1994 **/ /** to 11 may 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to 17 nov 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to 18 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 19 oct 1995 **/ /** # Version 3.1 : from : 30 oct 1995 **/ /** to 14 jun 1996 **/ /** # Version 3.2 : from : 23 aug 1996 **/ /** to 07 sep 1998 **/ /** # Version 3.3 : from : 19 oct 1998 **/ /** to 08 dec 1998 **/ /** # Version 3.4 : from : 01 jun 2001 **/ /** to 07 nov 2001 **/ /** # Version 4.0 : from : 12 jan 2004 **/ /** to 06 mar 2005 **/ /** # Version 5.1 : from : 22 nov 2007 **/ /** to 04 feb 2009 **/ /** # Version 6.0 : from : 03 mar 2011 **/ /** to 29 aug 2014 **/ /** **/ /** NOTES : # This code is a complete rewrite of **/ /** the original code of kgraphMapRb(), **/ /** hence the kept history. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define KGRAPH_MAP_RB_MAP #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "arch.h" #include "mapping.h" #include "bgraph.h" #include "bgraph_bipart_st.h" #include "kgraph.h" #include "kgraph_map_rb.h" #include "kgraph_map_rb_map.h" /* ** The static variables. */ static KgraphMapRbMapPoolLink kgraphmaprbmappooldummy; /* Dummy links for pool routines; TRICK */ /************************************/ /* */ /* These routines handle job pools. */ /* */ /************************************/ /* This routine initializes the job pool ** structures. ** It returns: ** - 0 : in case of success. ** - !0 : on error. */ static int kgraphMapRbMapPoolInit ( KgraphMapRbMapPoolData * restrict const poolptr, const KgraphMapRbData * restrict const dataptr) { int flagval; Mapping * restrict const mappptr = dataptr->mappptr; flagval = 0; if (archVar (mappptr->archptr) != 0) flagval |= KGRAPHMAPRBMAPARCHVAR; if (archPart (mappptr->archptr) != 0) { flagval |= KGRAPHMAPRBMAPARCHCMPLT; poolptr->polival = KGRAPHMAPRBPOLILEVEL; /* A simple policy will do */ poolptr->grafptr = NULL; /* We don't need top level graph data */ } else { poolptr->polival = dataptr->paraptr->polival; /* Enforce original policy */ poolptr->grafptr = dataptr->grafptr; /* We will need top-level graph data */ } poolptr->pfixtax = dataptr->pfixtax; poolptr->linktab[0].prev = /* Initialize doubly linked list as empty, pointing to the dummy element */ poolptr->linktab[0].next = poolptr->linktab[1].prev = poolptr->linktab[1].next = &kgraphmaprbmappooldummy; poolptr->pooltab[0] = &poolptr->linktab[0]; poolptr->pooltab[1] = (dataptr->paraptr->flagjobtie != 0) ? &poolptr->linktab[0] : &poolptr->linktab[1]; if ((poolptr->jobtab = (KgraphMapRbMapJob *) memAlloc (mappptr->domnmax * sizeof (KgraphMapRbMapJob))) == NULL) { errorPrint ("kgraphMapRbMapPoolInit: out of memory (2)"); return (1); } poolptr->jobtab[0].poolflag = 0; /* In case kgraphMapRbPoolExit() is called just afterwards on single-domain mapping */ poolptr->mappptr = mappptr; poolptr->domntab[0] = mappptr->domntab; /* Use original domain array */ if (dataptr->paraptr->flagmaptie != 0) { /* If mappings are tied, use same domain array */ poolptr->domntab[1] = mappptr->domntab; flagval |= KGRAPHMAPRBMAPPARTHALF; /* Updates will only involve half of the vertices */ } else { if ((poolptr->domntab[1] = (ArchDom *) memAlloc (mappptr->domnmax * sizeof (ArchDom))) == NULL) { errorPrint ("kgraphMapRbMapPoolInit: out of memory (3)"); memFree (poolptr->jobtab); return (1); } } poolptr->flagval = flagval; return (0); } /* This routine frees all of the internal arrays ** involved in the DRB algorithms. Great care ** should be taken that this routine always ** succeeds, whatever part of the algorithm it ** is called from. ** It returns: ** - VOID : in all cases. */ static void kgraphMapRbMapPoolExit ( KgraphMapRbMapPoolData * restrict const poolptr) { Anum domnnbr; Anum jobnum; Mapping * restrict const mappptr = poolptr->mappptr; domnnbr = mappptr->domnnbr; for (jobnum = 0; jobnum < domnnbr; jobnum ++) { /* For all potential jobs in both pools */ if (poolptr->jobtab[jobnum].poolflag != 0) { /* If job slot is active */ graphExit (&poolptr->jobtab[jobnum].grafdat); /* Free job graph, if not clone of original graph */ } } if (mappptr->domntab != poolptr->domntab[1]) { /* If current mapping domain array is not original domain array */ if ((mappptr->flagval & MAPPINGFREEDOMN) != 0) /* If mapping domain array was privately owned, free it */ memFree (mappptr->domntab); mappptr->flagval |= MAPPINGFREEDOMN; /* Keep current domain array as private mapping domain array */ mappptr->domntab = poolptr->domntab[1]; } memFree (poolptr->jobtab); } /* This routine swaps the internal arrays ** involved in the DRB algorithms. ** It returns: ** - VOID : in all cases. */ static void kgraphMapRbMapPoolSwap ( KgraphMapRbMapPoolData * restrict const poolptr) { KgraphMapRbMapPoolLink * linktmp; ArchDom * domntmp; linktmp = poolptr->pooltab[0]; poolptr->pooltab[0] = poolptr->pooltab[1]; poolptr->pooltab[1] = linktmp; domntmp = poolptr->domntab[0]; poolptr->domntab[0] = poolptr->domntab[1]; poolptr->domntab[1] = domntmp; } /* This routine doubles the size all of the arrays ** involved in handling the target architecture, ** to make room for new domains of variable-sized ** architectures. ** It returns: ** - 0 : if resize succeeded. ** - !0 : if out of memory. */ static int kgraphMapRbMapPoolResize ( KgraphMapRbMapPoolData * restrict const poolptr) { KgraphMapRbMapJob * restrict jobtab; /* Pointer to (new) job array */ Anum domnnbr; /* Current (max) number of domains */ Anum domnmax; /* New maximum number of domains */ int i; domnnbr = poolptr->mappptr->domnmax; /* Current max size */ domnmax = domnnbr + (domnnbr >> 2) + 8; /* Increase size by 25% */ if ((jobtab = (KgraphMapRbMapJob *) memRealloc (poolptr->jobtab, domnmax * sizeof (KgraphMapRbMapJob))) == NULL) { errorPrint ("kgraphMapRbMapPoolResize: out of memory (1)"); return (1); } if (jobtab != poolptr->jobtab) { /* If job array moved */ KgraphMapRbMapJob * joboldtab; /* Pointer to start of old job array */ KgraphMapRbMapJob * joboldtnd; /* Pointer to end of old job array */ Anum jobnum; /* Temporary job index */ intptr_t jobdlt; /* Address delta value */ joboldtab = poolptr->jobtab; joboldtnd = joboldtab + domnnbr; jobdlt = (byte *) jobtab - (byte *) joboldtab; /* Compute delta between new and old addresses */ for (jobnum = 0; jobnum < domnnbr; jobnum ++) { if ((jobtab[jobnum].poollink.prev >= (KgraphMapRbMapPoolLink *) joboldtab) && /* If old pointers within bounds of old array, adjust them */ (jobtab[jobnum].poollink.prev < (KgraphMapRbMapPoolLink *) joboldtnd)) jobtab[jobnum].poollink.prev = (KgraphMapRbMapPoolLink *) ((byte *) jobtab[jobnum].poollink.prev + jobdlt); if ((jobtab[jobnum].poollink.next >= (KgraphMapRbMapPoolLink *) joboldtab) && (jobtab[jobnum].poollink.next < (KgraphMapRbMapPoolLink *) joboldtnd)) jobtab[jobnum].poollink.next = (KgraphMapRbMapPoolLink *) ((byte *) jobtab[jobnum].poollink.next + jobdlt); } if (poolptr->linktab[0].next != &kgraphmaprbmappooldummy) /* Update first pool pointer */ poolptr->linktab[0].next = (KgraphMapRbMapPoolLink *) ((byte *) poolptr->linktab[0].next + jobdlt); if (poolptr->pooltab[0] != poolptr->pooltab[1]) { /* If job pools not tied */ if (poolptr->linktab[1].next != &kgraphmaprbmappooldummy) /* Update second pool pointer */ poolptr->linktab[1].next = (KgraphMapRbMapPoolLink *) ((byte *) poolptr->linktab[1].next + jobdlt); } poolptr->jobtab = jobtab; /* Set new memory location of job array */ } i = (poolptr->domntab[1] == poolptr->mappptr->domntab) ? 1 : 0; /* Find which domain array is that of the mapping */ if (mapResize (poolptr->mappptr, domnmax) != 0) { errorPrint ("kgraphMapRbMapPoolResize: out of memory (2)"); return (1); } if (poolptr->domntab[1] != poolptr->domntab[0]) { /* If two domain arrays present */ ArchDom * domntab; if ((domntab = (ArchDom *) memRealloc (poolptr->domntab[i ^ 1], domnmax * sizeof (ArchDom))) == NULL) { /* Reallocate other domain array */ errorPrint ("kgraphMapRbMapPoolResize: out of memory (3)"); return (1); } poolptr->domntab[i ^ 1] = domntab; /* Set (possibly new) memory location of other domain array */ } else poolptr->domntab[i ^ 1] = poolptr->mappptr->domntab; /* Both domain arrays point to the same (new) location */ poolptr->domntab[i] = poolptr->mappptr->domntab; /* Set (possibly new) memory location of mapping domain array */ return (0); } /**********************************************/ /* */ /* These routines handle bipartitioning jobs. */ /* */ /**********************************************/ /* This routine adds a job to pool 1 of the ** given pool data structure. ** It returns: ** - VOID : in all cases. */ static void kgraphMapRbMapPoolAdd ( KgraphMapRbMapPoolLink * restrict const linkptr, KgraphMapRbMapJob * const jobptr) { jobptr->poollink.prev = linkptr; /* Link job in pool: TRICK */ jobptr->poollink.next = linkptr->next; jobptr->poolflag = 1; /* Job is in pool */ jobptr->poolptr = linkptr; /* Point to the pool */ linkptr->next->prev = &jobptr->poollink; linkptr->next = &jobptr->poollink; } /* This routine gets the best job available from ** the given pool, according to the given policy. ** It returns: ** - !NULL : pointer to the job. ** - NULL : if the pool is empty. */ static KgraphMapRbMapJob * kgraphMapRbMapPoolGet ( KgraphMapRbMapPoolData * const poolptr) { KgraphMapRbMapJob * jobbest; /* Best job found */ KgraphMapRbMapJob * jobptr; jobbest = (KgraphMapRbMapJob *) poolptr->pooltab[0]->next; /* Get first job in pool */ for (jobptr = jobbest; /* For all jobs in pool */ jobptr != (KgraphMapRbMapJob *) (void *) &kgraphmaprbmappooldummy; jobptr = (KgraphMapRbMapJob *) jobptr->poollink.next) { if (jobptr->priolvl > jobbest->priolvl) /* If the current job has stronger priority */ jobbest = jobptr; /* Select it as the best job */ } if (jobbest != (KgraphMapRbMapJob *) (void *) &kgraphmaprbmappooldummy) { /* If job found */ jobbest->poollink.next->prev = jobbest->poollink.prev; /* Remove it from pool */ jobbest->poollink.prev->next = jobbest->poollink.next; /* But do not mark it unused */ } else /* Dummy job means no job found */ jobbest = NULL; return (jobbest); } /* This routine adds a job to the given pool ** as the first bipartitioning job. ** It returns: ** - VOID : in all cases. */ static void kgraphMapRbMapPoolFrst ( KgraphMapRbMapPoolData * const poolptr, KgraphMapRbMapJob * const jobptr) /* Job to be added */ { switch (poolptr->polival) { /* Set job priority value */ case KGRAPHMAPRBPOLIRANDOM : jobptr->prioval = jobptr->priolvl = intRandVal (INTVALMAX); break; case KGRAPHMAPRBPOLILEVEL : case KGRAPHMAPRBPOLINGLEVEL : jobptr->prioval = jobptr->grafdat.vertnbr; jobptr->priolvl = 0; break; case KGRAPHMAPRBPOLISIZE : case KGRAPHMAPRBPOLINGSIZE : jobptr->prioval = jobptr->priolvl = jobptr->grafdat.vertnbr; break; #ifdef SCOTCH_DEBUG_KGRAPH2 default : errorPrint ("kgraphMapRbMapPoolFrst: unknown job selection policy"); jobptr->prioval = 0; jobptr->priolvl = 0; return; #endif /* SCOTCH_DEBUG_KGRAPH2 */ } kgraphMapRbMapPoolAdd (poolptr->pooltab[0], jobptr); /* Add job to pool */ } /* This routine updates the given job ** table with both of the given subjob ** data. ** This routine can be called only if ** the parent jobs of the vertices to ** be updated still exist. ** It returns: ** - VOID : in all cases. */ static void kgraphMapRbMapPoolUpdt1 ( KgraphMapRbMapPoolData * const poolptr, const KgraphMapRbMapJob * const joboldptr, /* Job to be removed */ const GraphPart * const parttax, KgraphMapRbMapJob * const jobnewptr, /* Its only active subjob */ const GraphPart partval) { Gnum prioval; Gnum priolvl; priolvl = 0; /* Prepare for neighbor updating methods */ switch (poolptr->polival) { /* Set job priority value */ case KGRAPHMAPRBPOLIRANDOM : prioval = priolvl = intRandVal (INTVALMAX); break; case KGRAPHMAPRBPOLILEVEL : priolvl = joboldptr->priolvl + 1; case KGRAPHMAPRBPOLINGLEVEL : prioval = joboldptr->prioval - 1; break; case KGRAPHMAPRBPOLISIZE : priolvl = jobnewptr->grafdat.vertnbr; case KGRAPHMAPRBPOLINGSIZE : prioval = jobnewptr->grafdat.vertnbr; break; #ifdef SCOTCH_DEBUG_KGRAPH2 default : errorPrint ("kgraphMapRbMapPoolUpdt1: unknown job selection policy"); jobnewptr->prioval = 0; jobnewptr->priolvl = 0; return; #endif /* SCOTCH_DEBUG_KGRAPH2 */ } jobnewptr->prioval = prioval; if (poolptr->polival >= KGRAPHMAPRBPOLINEIGHBOR) { /* If neighbors have to be updated */ Gnum prioold; KgraphMapRbMapJob * restrict const jobtab = poolptr->jobtab; const Anum * restrict const mapparttax = poolptr->mappptr->parttax; /* Based pointer to mapping part array */ const Anum * restrict const toppfixtax = poolptr->pfixtax; const Gnum * restrict const topverttax = poolptr->grafptr->verttax; /* Point to top-level graph arrays */ const Gnum * restrict const topvendtax = poolptr->grafptr->vendtax; const Gnum * restrict const topedgetax = poolptr->grafptr->edgetax; prioold = joboldptr->prioval; if (joboldptr->grafdat.vertnbr < poolptr->grafptr->vertnbr) { /* If subgraph is not top graph, change priority of neighboring jobs of old job */ Gnum jobvertnnd; Gnum jobvertnum; const Gnum * restrict const jobverttax = joboldptr->grafdat.verttax; const Gnum * restrict const jobvendtax = joboldptr->grafdat.vendtax; const Gnum * restrict const jobvnumtax = joboldptr->grafdat.vnumtax; jobnewptr->poolflag = 0; /* TRICK: avoid new job being considered for update */ for (jobvertnum = joboldptr->grafdat.baseval, jobvertnnd = joboldptr->grafdat.vertnnd; jobvertnum < jobvertnnd; jobvertnum ++) { Gnum topvertnum; Gnum topedgenum; if (parttax[jobvertnum] == partval) /* If vertex belongs to part which is still alive */ continue; /* Do not consider update part as removed */ topvertnum = jobvnumtax[jobvertnum]; /* If graph is smaller than top graph, then vnumtax must exist */ if ((topvendtax[topvertnum] - topverttax[topvertnum]) == /* If vertex is internal, skip it */ (jobvendtax[jobvertnum] - jobverttax[jobvertnum])) continue; for (topedgenum = topverttax[topvertnum]; topedgenum < topvendtax[topvertnum]; topedgenum ++) { KgraphMapRbMapJob * restrict jobnghbptr; /* (Old ?) job of neighbor vertex */ Gnum topvertend; topvertend = topedgetax[topedgenum]; if ((toppfixtax != NULL) && (toppfixtax[topvertend] >= 0)) { #ifdef SCOTCH_DEBUG_KGRAPH2 if (mapparttax[topvertend] != ~0) { errorPrint ("kgraphMapRbMapPoolUpdt1: internal error (1)"); return; } #endif /* SCOTCH_DEBUG_KGRAPH2 */ continue; } jobnghbptr = &jobtab[mapparttax[topvertend]]; /* Get pointer to neighboring job */ if ((jobnghbptr->poolflag != 0) && /* If neighbor is active */ (jobnghbptr->prioval <= prioold)) /* And had not already a stronger priority */ jobnghbptr->priolvl ++; /* Update neighbor priority */ } } jobnewptr->poolflag = 1; /* TRICK: new job is active again */ } if (jobnewptr->grafdat.vertnbr < poolptr->grafptr->vertnbr) { /* If subgraph is not top graph, update priority of neighbors of new job only */ Gnum jobvertnnd; Gnum jobvertnum; const Gnum * restrict const jobverttax = jobnewptr->grafdat.verttax; const Gnum * restrict const jobvendtax = jobnewptr->grafdat.vendtax; const Gnum * restrict const jobvnumtax = jobnewptr->grafdat.vnumtax; for (jobvertnum = jobnewptr->grafdat.baseval, jobvertnnd = jobnewptr->grafdat.vertnnd; jobvertnum < jobvertnnd; jobvertnum ++) { Gnum topvertnum; Gnum topedgenum; topvertnum = jobvnumtax[jobvertnum]; /* For subjobs jobvnumtax always exists */ if ((topvendtax[topvertnum] - topverttax[topvertnum]) == /* If vertex is internal, skip it */ (jobvendtax[jobvertnum] - jobverttax[jobvertnum])) continue; for (topedgenum = topverttax[topvertnum]; topedgenum < topvendtax[topvertnum]; topedgenum ++) { KgraphMapRbMapJob * restrict jobnghbptr; /* (Old ?) job of neighbor vertex */ Gnum topvertend; topvertend = topedgetax[topedgenum]; if ((toppfixtax != NULL) && (toppfixtax[topvertend] >= 0)) { #ifdef SCOTCH_DEBUG_KGRAPH2 if (mapparttax[topvertend] != ~0) { errorPrint ("kgraphMapRbMapPoolUpdt1: internal error (2)"); return; } #endif /* SCOTCH_DEBUG_KGRAPH2 */ continue; } jobnghbptr = &jobtab[mapparttax[topvertend]]; /* Get pointer to neighboring job */ if (jobnghbptr == jobnewptr) /* If it is the current job, do not consider the edge */ continue; if ((jobnghbptr->poolflag == 0) || /* If neighbor is not active */ (prioval > jobnghbptr->prioval)) /* Or if we have higher priority */ priolvl ++; /* Increase our priority */ else if ((prioval < jobnghbptr->prioval) && /* Else if neighbor has higher one */ (prioold >= jobnghbptr->prioval)) /* Which it did not already have */ jobnghbptr->priolvl ++; /* Update neighbor priority */ } } } } jobnewptr->priolvl = priolvl; kgraphMapRbMapPoolAdd (poolptr->pooltab[1], jobnewptr); /* Add job to pool */ } static void kgraphMapRbMapPoolUpdt2 ( KgraphMapRbMapPoolData * const poolptr, const KgraphMapRbMapJob * const joboldptr, /* Job to be removed */ const GraphPart * const parttax, KgraphMapRbMapJob * const jobnewptr0, /* Its two subjobs */ KgraphMapRbMapJob * const jobnewptr1) { KgraphMapRbMapJob * restrict jobnewtab[2]; int i; jobnewtab[0] = jobnewptr0; jobnewtab[1] = jobnewptr1; for (i = 1; i >= 0; i --) { KgraphMapRbMapJob * jobnewptr; Gnum prioval; Gnum priolvl; jobnewptr = jobnewtab[i]; /* Get concerned subjob */ priolvl = 0; /* Prepare for neighbor updating methods */ switch (poolptr->polival) { /* Set job priority value */ case KGRAPHMAPRBPOLIRANDOM : prioval = priolvl = intRandVal (INTVALMAX); break; case KGRAPHMAPRBPOLILEVEL : priolvl = joboldptr->priolvl + 1; case KGRAPHMAPRBPOLINGLEVEL : prioval = joboldptr->prioval - 1; break; case KGRAPHMAPRBPOLISIZE : priolvl = jobnewptr->grafdat.vertnbr; case KGRAPHMAPRBPOLINGSIZE : prioval = jobnewptr->grafdat.vertnbr; break; #ifdef SCOTCH_DEBUG_KGRAPH2 default : errorPrint ("kgraphMapRbMapPoolUpdt2: unknown job selection policy"); jobnewptr->prioval = 0; jobnewptr->priolvl = 0; return; #endif /* SCOTCH_DEBUG_KGRAPH2 */ } jobnewptr0->prioval = prioval + 1; /* TRICK: when processing subdomain 1, subdomain 0 has higher priority value */ jobnewptr->prioval = prioval; /* Then in its turn subdomain 0 will have its proper priority value */ if (poolptr->polival >= KGRAPHMAPRBPOLINEIGHBOR) { /* If neighbors have to be updated */ Gnum jobvertnnd; Gnum jobvertnum; Gnum prioold; KgraphMapRbMapJob * restrict const jobtab = poolptr->jobtab; const Anum * restrict const mapparttax = poolptr->mappptr->parttax; /* Based pointer to mapping part array */ const Anum * restrict const toppfixtax = poolptr->pfixtax; const Gnum * restrict const topverttax = poolptr->grafptr->verttax; /* Point to top-level graph arrays */ const Gnum * restrict const topvendtax = poolptr->grafptr->vendtax; const Gnum * restrict const topedgetax = poolptr->grafptr->edgetax; const Gnum * restrict const jobverttax = jobnewptr->grafdat.verttax; const Gnum * restrict const jobvendtax = jobnewptr->grafdat.vendtax; const Gnum * restrict const jobvnumtax = jobnewptr->grafdat.vnumtax; prioold = joboldptr->prioval; for (jobvertnum = jobnewptr->grafdat.baseval, jobvertnnd = jobnewptr->grafdat.vertnnd; jobvertnum < jobvertnnd; jobvertnum ++) { Gnum topvertnum; Gnum topedgenum; topvertnum = jobvnumtax[jobvertnum]; /* For subjobs jobvnumtax always exists */ if ((topvendtax[topvertnum] - topverttax[topvertnum]) == /* If vertex is internal, skip it */ (jobvendtax[jobvertnum] - jobverttax[jobvertnum])) continue; for (topedgenum = topverttax[topvertnum]; topedgenum < topvendtax[topvertnum]; topedgenum ++) { KgraphMapRbMapJob * jobnghbptr; /* (Old ?) job of neighbor vertex */ Gnum topvertend; topvertend = topedgetax[topedgenum]; if ((toppfixtax != NULL) && (toppfixtax[topvertend] >= 0)) { #ifdef SCOTCH_DEBUG_KGRAPH2 if (mapparttax[topvertend] != ~0) { errorPrint ("kgraphMapRbMapPoolUpdt2: internal error"); return; } #endif /* SCOTCH_DEBUG_KGRAPH2 */ continue; } jobnghbptr = &jobtab[mapparttax[topvertend]]; /* Get pointer to neighboring job */ if ((jobnghbptr->poolflag != 0) && /* If neighbor is in active job */ (jobnghbptr->prioval > prioval) && /* Which gained priority over us */ (jobnghbptr->prioval <= prioold)) { jobnghbptr->priolvl ++; /* Update neighbor priority */ } if ((jobnghbptr->poolflag == 0) || /* If neighbor is fully known */ (jobnghbptr->prioval < prioval)) /* Or has smaller priority value */ priolvl ++; /* Then we should be processed */ } } } jobnewptr->priolvl = priolvl; /* Set new priority */ kgraphMapRbMapPoolAdd (poolptr->pooltab[1], jobnewptr); /* Add job to pool */ } } /* ** This routine removes the influence of the ** given job from its neighbor jobs. ** It returns: ** - VOID : in all cases. */ static void kgraphMapRbMapPoolRemv ( KgraphMapRbMapPoolData * const poolptr, const KgraphMapRbMapJob * const joboldptr) /* Job to be removed */ { KgraphMapRbMapJob * restrict jobtab; const Anum * restrict mapparttax; /* Based pointer to mapping part array */ const Gnum * restrict jobvnumtax; const Gnum * restrict jobverttax; const Gnum * restrict jobvendtax; const Gnum * restrict topverttax; const Gnum * restrict topvendtax; const Gnum * restrict topedgetax; if (poolptr->polival >= KGRAPHMAPRBPOLINEIGHBOR) { /* If neighbors have to be modified */ Gnum jobvertnnd; Gnum jobvertnum; Gnum prioold; KgraphMapRbMapJob * restrict const jobtab = poolptr->jobtab; const Anum * restrict const mapparttax = poolptr->mappptr->parttax; /* Based pointer to mapping part array */ const Anum * restrict const toppfixtax = poolptr->pfixtax; const Gnum * restrict const topverttax = poolptr->grafptr->verttax; /* Point to top-level graph arrays */ const Gnum * restrict const topvendtax = poolptr->grafptr->vendtax; const Gnum * restrict const topedgetax = poolptr->grafptr->edgetax; const Gnum * restrict const jobverttax = joboldptr->grafdat.verttax; const Gnum * restrict const jobvendtax = joboldptr->grafdat.vendtax; const Gnum * restrict const jobvnumtax = joboldptr->grafdat.vnumtax; prioold = joboldptr->prioval; for (jobvertnum = joboldptr->grafdat.baseval, jobvertnnd = joboldptr->grafdat.vertnnd; jobvertnum < jobvertnnd; jobvertnum ++) { Gnum topvertnum; /* Source graph vertex number */ Gnum topedgenum; /* Source graph edge number */ topvertnum = (jobvnumtax == NULL) ? jobvertnum : jobvnumtax[jobvertnum]; if ((topvendtax[topvertnum] - topverttax[topvertnum]) == /* If vertex is internal, skip it */ (jobvendtax[jobvertnum] - jobverttax[jobvertnum])) continue; for (topedgenum = topverttax[topvertnum]; topedgenum < topvendtax[topvertnum]; topedgenum ++) { KgraphMapRbMapJob * jobnghbptr; /* (Old ?) job of neighbor vertex */ Gnum topvertend; topvertend = topedgetax[topedgenum]; if ((toppfixtax != NULL) && (toppfixtax[topvertend] >= 0)) { #ifdef SCOTCH_DEBUG_KGRAPH2 if (mapparttax[topvertend] != ~0) { errorPrint ("kgraphMapRbMapPoolRemv: internal error (1)"); return; } #endif /* SCOTCH_DEBUG_KGRAPH2 */ continue; } jobnghbptr = &jobtab[mapparttax[topvertend]]; /* Get pointer to neighboring job */ if ((jobnghbptr->poolflag != 0) && /* If neighbor job is active */ (jobnghbptr->prioval <= prioold)) /* And had not already a stronger priority */ jobnghbptr->priolvl ++; /* Increase its priority since we are now inactive */ } } } } /**********************************************/ /* */ /* These routines handle the pool part array. */ /* */ /**********************************************/ static void kgraphMapRbMapPartBoth ( KgraphMapRbMapPoolData * restrict const poolptr, const Bgraph * restrict const actgrafptr, const Anum * restrict const jobsubnum) { Gnum actvertnum; const GraphPart * restrict actparttax; Anum * restrict mapparttax; Anum mappartval1; Anum mappartdlt; actparttax = actgrafptr->parttax; mapparttax = poolptr->mappptr->parttax; mappartval1 = jobsubnum[1]; mappartdlt = jobsubnum[0] - jobsubnum[1]; if (actgrafptr->s.vnumtax != NULL) { const Gnum * restrict actvnumtax; actvnumtax = actgrafptr->s.vnumtax; for (actvertnum = actgrafptr->s.baseval; actvertnum < actgrafptr->s.vertnnd; actvertnum ++) { #ifdef SCOTCH_DEBUG_KGRAPH2 if (mapparttax[actvnumtax[actvertnum]] == ~0) { errorPrint ("kgraphMapRbMapPartBoth: internal error (1)"); return; } #endif /* SCOTCH_DEBUG_KGRAPH2 */ mapparttax[actvnumtax[actvertnum]] = mappartval1 + ((((Anum) actparttax[actvertnum]) - 1) & mappartdlt); } } else { for (actvertnum = actgrafptr->s.baseval; actvertnum < actgrafptr->s.vertnnd; actvertnum ++) { #ifdef SCOTCH_DEBUG_KGRAPH2 if (mapparttax[actvertnum] == ~0) { errorPrint ("kgraphMapRbMapPartBoth: internal error (2)"); return; } #endif /* SCOTCH_DEBUG_KGRAPH2 */ mapparttax[actvertnum] = mappartval1 + ((((Anum) actparttax[actvertnum]) - 1) & mappartdlt); } } } static void kgraphMapRbMapPartOne ( KgraphMapRbMapPoolData * restrict const poolptr, const Bgraph * restrict const actgrafptr, const Anum jobsubnum1) { Gnum actvertnum; const GraphPart * restrict actparttax; Anum * restrict mapparttax; actparttax = actgrafptr->parttax; mapparttax = poolptr->mappptr->parttax; if (actgrafptr->s.vnumtax != NULL) { const Gnum * restrict actvnumtax; actvnumtax = actgrafptr->s.vnumtax; for (actvertnum = actgrafptr->s.baseval; actvertnum < actgrafptr->s.vertnnd; actvertnum ++) { if (actparttax[actvertnum] == 1) { #ifdef SCOTCH_DEBUG_KGRAPH2 if (mapparttax[actvnumtax[actvertnum]] == ~0) { errorPrint ("kgraphMapRbMapPartOne: internal error (1)"); return; } #endif /* SCOTCH_DEBUG_KGRAPH2 */ mapparttax[actvnumtax[actvertnum]] = jobsubnum1; } } } else { for (actvertnum = actgrafptr->s.baseval; actvertnum < actgrafptr->s.vertnnd; actvertnum ++) { if (actparttax[actvertnum] == 1) { #ifdef SCOTCH_DEBUG_KGRAPH2 if (mapparttax[actvertnum] == ~0) { errorPrint ("kgraphMapRbMapPartOne: internal error (2)"); return; } #endif /* SCOTCH_DEBUG_KGRAPH2 */ mapparttax[actvertnum] = jobsubnum1; } } } } /********************************************/ /* */ /* This is the entry point for the Dual */ /* Recursive Bipartitioning mapping method. */ /* */ /********************************************/ /* This routine runs the Dual Recursive ** Bipartitioning algorithm. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int kgraphMapRbMap ( const KgraphMapRbData * restrict const dataptr, /*+ Global mapping data +*/ const Graph * restrict const grafptr, /*+ Graph to map, without fixed vertices +*/ const Anum vflonbr, /*+ Number of fixed vertex load slots +*/ KgraphMapRbVflo * restrict const vflotab) /*+ Array of fixed vertex load slots +*/ { KgraphMapRbMapPoolData pooldat; /* Data for handling jobs and job pools */ ArchDom domnsubtab[2]; /* Subdomains of current job domain */ KgraphMapRbMapJob joborgdat; /* Aera to save original job data */ Anum jobsubnum[2]; /* Number of subjob slots in job array */ Gnum jobsubsiz[2]; /* Sizes of subjobs */ Bgraph actgrafdat; /* Bipartition graph */ double comploadmin; /* Minimum vertex load per target load */ double comploadmax; /* Maximum vertex load per target load */ int i; Mapping * restrict const mappptr = dataptr->mappptr; mapFrst (mappptr); /* Initialize mapping */ #ifdef SCOTCH_DEBUG_KGRAPH2 if (dataptr->pfixtax != NULL) { /* In debug mode, fixed vertex parts are set to ~0 */ Gnum vertnnd; Gnum vertnum; Anum * restrict const parttax = mappptr->parttax; const Anum * restrict const pfixtax = dataptr->pfixtax; for (vertnum = dataptr->grafptr->baseval, vertnnd = dataptr->grafptr->vertnnd; vertnum < vertnnd; vertnum ++) { if (pfixtax[vertnum] >= 0) parttax[vertnum] = ~0; } } mappptr->domnmax = 1; /* Force resizing of job arrays, for debugging */ #endif /* SCOTCH_DEBUG_KGRAPH2 */ if (kgraphMapRbMapPoolInit (&pooldat, dataptr) != 0) /* Initialize pool data; done first for kgraphMapRbMapPoolExit() to succeed afterwards */ return (1); if ((((pooldat.flagval & KGRAPHMAPRBMAPARCHVAR) == 0) && (archDomSize (mappptr->archptr, &mappptr->domnorg) <= 1)) || /* If single-vertex domain */ (((pooldat.flagval & KGRAPHMAPRBMAPARCHVAR) != 0) && (grafptr->vertnbr <= 1))) { /* Or if variable-sized architecture with single vertex graph */ kgraphMapRbMapPoolExit (&pooldat); return (0); /* Job already done */ } pooldat.jobtab[0].domnorg = mappptr->domnorg; /* Build first job */ pooldat.jobtab[0].grafdat = *grafptr; /* Clone induced graph as first job graph */ pooldat.jobtab[0].grafdat.flagval &= ~GRAPHFREETABS; /* Do not free its arrays on exit */ pooldat.jobtab[0].vflonbr = vflonbr; /* Record initial list of fixed load slots */ pooldat.jobtab[0].vflotab = vflotab; kgraphMapRbMapPoolFrst (&pooldat, &pooldat.jobtab[0]); /* Add initial job */ comploadmin = (1.0 - dataptr->paraptr->kbalval) * dataptr->comploadrat; /* Ratio can have been tilted when working on subgraph */ comploadmax = (1.0 + dataptr->paraptr->kbalval) * dataptr->comploadrat; while (! kgraphMapRbMapPoolEmpty (&pooldat)) { /* For all non-empty pools */ KgraphMapRbMapJob * joborgptr; /* Pointer to current job */ while ((joborgptr = kgraphMapRbMapPoolGet (&pooldat)) != NULL) { /* For all jobs in pool */ Gnum vflonbrtab[2]; Gnum vflowgttab[2]; int partval; jobsubnum[0] = joborgptr - pooldat.jobtab; /* Get current (and first son) job slot number before possible move of pointers */ joborgdat = *joborgptr; /* Save current job data (clone graph) */ if (archDomBipart (mappptr->archptr, &joborgdat.domnorg, &domnsubtab[0], &domnsubtab[1]) != 0) { errorPrint ("kgraphMapRbMap: cannot bipartition domain"); kgraphMapRbMapPoolExit (&pooldat); /* Copied graph will be freed as not yet removed */ return (1); } kgraphMapRbVfloSplit (mappptr->archptr, domnsubtab, /* Split fixed vertex load slots, if any */ joborgdat.vflonbr, joborgdat.vflotab, vflonbrtab, vflowgttab); if (kgraphMapRbBgraph (dataptr, &actgrafdat, &joborgdat.grafdat, pooldat.mappptr, domnsubtab, vflowgttab) != 0) { /* Create bipartition graph */ errorPrint ("kgraphMapRbMap: cannot create bipartition graph"); kgraphMapRbMapPoolExit (&pooldat); /* Copied graph will be freed as not yet removed */ return (1); } actgrafdat.s.flagval |= (joborgdat.grafdat.flagval & GRAPHFREETABS); /* Bipartition graph is responsible for freeing the cloned graph data fields */ joborgptr->poolflag = 0; /* Original slot is now considered unused so that cloned graph data will not be freed twice */ if ((pooldat.flagval & KGRAPHMAPRBMAPARCHVAR) == 0) { /* If not variable-sized, impose constraints on bipartition */ double comploadavg; comploadavg = (double) actgrafdat.s.velosum / (double) archDomWght (mappptr->archptr, &joborgdat.domnorg); actgrafdat.compload0min = actgrafdat.compload0avg - (Gnum) MIN ((comploadmax - comploadavg) * (double) actgrafdat.domnwght[0], (comploadavg - comploadmin) * (double) actgrafdat.domnwght[1]); actgrafdat.compload0max = actgrafdat.compload0avg + (Gnum) MIN ((comploadavg - comploadmin) * (double) actgrafdat.domnwght[0], (comploadmax - comploadavg) * (double) actgrafdat.domnwght[1]); } if (bgraphBipartSt (&actgrafdat, dataptr->paraptr->strat) != 0) { /* Perform bipartitioning */ errorPrint ("kgraphMapRbMap: cannot bipartition job"); bgraphExit (&actgrafdat); kgraphMapRbMapPoolExit (&pooldat); return (1); } if ((partval = 1, actgrafdat.compsize0 == 0) || /* If no bipartition found */ (partval = 0, actgrafdat.compsize0 == actgrafdat.s.vertnbr)) { if (((pooldat.flagval & KGRAPHMAPRBMAPARCHVAR) != 0) || /* If architecture is variable-sized */ (archDomSize (mappptr->archptr, &domnsubtab[partval]) <= 1)) { /* Or if domain is terminal */ pooldat.domntab[0][jobsubnum[0]] = joborgdat.domnorg; /* Update domain in next pool */ kgraphMapRbMapPoolRemv (&pooldat, &joborgdat); /* Remove job from pool as long as graph exists */ bgraphExit (&actgrafdat); /* Free bipartitioning data as well as current graph */ continue; /* Process next job in current pool */ } else { /* Re-use job slot and graph for further bipartitioning */ pooldat.domntab[0][jobsubnum[0]] = /* Update domain in next pool */ joborgptr->domnorg = domnsubtab[partval]; /* New job takes same graph and non-empty subdomain */ joborgptr->vflonbr = vflonbrtab[partval]; joborgptr->vflotab = joborgdat.vflotab + (partval * vflonbrtab[0]); /* Point to proper sub-array */ kgraphMapRbMapPoolUpdt1 (&pooldat, &joborgdat, actgrafdat.parttax, joborgptr, partval); /* Add job to pool */ actgrafdat.s.flagval &= ~GRAPHFREETABS; /* Since graph will be re-used, never free its internal arrays */ bgraphExit (&actgrafdat); /* Free bipartitioning data */ continue; /* Process next job in current pool */ } } if ((pooldat.mappptr->domnnbr == pooldat.mappptr->domnmax) && /* If all job slots busy and if cannot resize */ (kgraphMapRbMapPoolResize (&pooldat) != 0)) { errorPrint ("kgraphMapRbMap: cannot resize structures"); kgraphMapRbMapPoolExit (&pooldat); return (1); } jobsubnum[1] = pooldat.mappptr->domnnbr ++; /* Get slot number of new subdomain */ jobsubsiz[1] = actgrafdat.s.vertnbr - actgrafdat.compsize0; jobsubsiz[0] = actgrafdat.compsize0; pooldat.jobtab[jobsubnum[1]].poolflag = 0; /* Assume that new job is inactive in case of premature freeing */ pooldat.domntab[1][jobsubnum[1]] = joborgdat.domnorg; /* Copy original domain to new subdomain as old mapping shares parttax with new */ pooldat.domntab[0][jobsubnum[0]] = domnsubtab[0]; /* Set subdomains of second mapping before relinking subjobs in pool */ pooldat.domntab[0][jobsubnum[1]] = domnsubtab[1]; if ((pooldat.flagval & KGRAPHMAPRBMAPPARTHALF) != 0) /* If can only update second half */ kgraphMapRbMapPartOne (&pooldat, &actgrafdat, jobsubnum[1]); else kgraphMapRbMapPartBoth (&pooldat, &actgrafdat, jobsubnum); for (i = 1; i >= 0; i --) { /* For both subdomains */ KgraphMapRbMapJob * jobsubptr; jobsubptr = &pooldat.jobtab[jobsubnum[i]]; /* Point to subdomain job slot */ jobsubptr->poollink.prev = /* Prevent Valgrind from yelling in kgraphMapRbMapPoolResize() */ jobsubptr->poollink.next = NULL; jobsubptr->prioval = /* Prevent Valgrind from yelling in kgraphMapRbMapPoolRemv()/Updt1()/Updt2() */ jobsubptr->priolvl = 0; if ((((pooldat.flagval & KGRAPHMAPRBMAPARCHVAR) == 0) && (archDomSize (mappptr->archptr, &domnsubtab[i]) <= 1)) || /* If single-vertex domain */ (((pooldat.flagval & KGRAPHMAPRBMAPARCHVAR) != 0) && (jobsubsiz[i] <= 1))) { /* Or if variable-sized architecture with single vertex graph */ jobsubsiz[i] = 0; /* Cancel subjob */ continue; } partval = i; /* At least this subjob works */ if (graphInducePart (&actgrafdat.s, actgrafdat.parttax, jobsubsiz[i], (GraphPart) i, &jobsubptr->grafdat) != 0) { errorPrint ("kgraphMapRbMap: cannot create induced subgraph"); bgraphExit (&actgrafdat); kgraphMapRbMapPoolExit (&pooldat); return (1); } jobsubptr->poolflag = 1; /* So that graph is freed in case of error on other part */ jobsubptr->domnorg = domnsubtab[i]; jobsubptr->vflonbr = vflonbrtab[i]; jobsubptr->vflotab = joborgdat.vflotab + (i * vflonbrtab[0]); /* Point to proper sub-array */ } if ((jobsubsiz[0] | jobsubsiz[1]) == 0) /* If both subjobs do not need further processing */ kgraphMapRbMapPoolRemv (&pooldat, &joborgdat); else if (jobsubsiz[1 - partval] == 0) /* If one of the subjobs only needs further processing */ kgraphMapRbMapPoolUpdt1 (&pooldat, &joborgdat, actgrafdat.parttax, &pooldat.jobtab[jobsubnum[partval]], (GraphPart) partval); else kgraphMapRbMapPoolUpdt2 (&pooldat, &joborgdat, actgrafdat.parttax, &pooldat.jobtab[jobsubnum[0]], &pooldat.jobtab[jobsubnum[1]]); bgraphExit (&actgrafdat); /* Free bipartition graph data */ } kgraphMapRbMapPoolSwap (&pooldat); /* Swap current and next levels */ } kgraphMapRbMapPoolExit (&pooldat); /* Free internal structures and propagate back new partition */ return (0); } scotch-6.0.4.dfsg/src/libscotch/vmesh_separate_gg.h0000644002563400244210000001137211631447170025476 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vmesh_separate_gg.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the the greedy mesh growing node **/ /** separation method. **/ /** **/ /** DATES : # Version 4.0 : from : 16 sep 2002 **/ /** to 07 apr 2004 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ System-defined constants. +*/ #define VMESHSEPAGGSUBBITS 4 #define VMESHSEPAGGSTATEPART0 ((GainLink *) 0) /*+ Element vertex in part 0 (initial state) +*/ #define VMESHSEPAGGSTATEPART1 ((GainLink *) 1) /*+ Element vertex in part 1 +*/ #define VMESHSEPAGGSTATEPART2 ((GainLink *) 2) /*+ Element vertex in part 2, chained +*/ #define VMESHSEPAGGSTATELINK ((GainLink *) 3) /*+ Currently in gain table if higher +*/ /* ** The type and structure definitions. */ /*+ Method parameters. +*/ typedef struct VmeshSeparateGgParam_ { INT passnbr; /*+ Number of passes to perform +*/ } VmeshSeparateGgParam; /*+ The complementary element vertex structure. For trick reasons, the gain table data structure must be the first field of the structure. +*/ typedef struct VmeshSeparateGgElem_ { GainLink gainlink; /*+ Gain link: FIRST +*/ Gnum ncmpgain2; /*+ Computation gain in separator: (0->2) - (2->1) +*/ Gnum ncmpgaindlt; /*+ Overall computation delta: - (0->2) - (2->1) +*/ } VmeshSeparateGgElem; /*+ The complementary vertex structure. Only partval is always valid. Other fields are valid only when vertex belongs to separator. +*/ typedef struct VmeshSeparateGgNode_ { int partval; /*+ Part to which node vertex belongs +*/ Gnum commsize0; /*+ Number of neighbors in part 0 +*/ Gnum velmisum0; /*+ Sum of all element indices in part 0; the last one is the right one +*/ } VmeshSeparateGgNode; /* ** The function prototypes. */ #ifndef VMESH_SEPARATE_GG #define static #endif int vmeshSeparateGg (Vmesh * restrict const, const VmeshSeparateGgParam * restrict const); #ifdef SCOTCH_DEBUG_VMESH3 static int vmeshSeparateGgCheck (Vmesh * restrict const, const Gnum, const Gnum, const VmeshSeparateGgElem * restrict const, const VmeshSeparateGgNode * restrict const vnoxtax); #endif /* SCOTCH_DEBUG_VMESH3 */ #undef static scotch-6.0.4.dfsg/src/libscotch/library_graph_io_chac_f.c0000644002563400244210000001633711631447170026613 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_io_chac_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the Fortran API for the **/ /** graph i/o routines of the libSCOTCH **/ /** library. **/ /** **/ /** DATES : # Version 4.0 : from : 23 nov 2005 **/ /** to 23 nov 2005 **/ /** # Version 5.1 : from : 27 mar 2010 **/ /** to 27 mar 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the mapping routines. */ /* */ /**************************************/ /* String lengths are passed at the very ** end of the argument list. */ FORTRAN ( \ SCOTCHFGRAPHGEOMLOADCHAC, scotchfgraphgeomloadchac, ( \ SCOTCH_Graph * const grafptr, \ SCOTCH_Geom * const geomptr, \ const int * const filegrfptr, \ const int * const filegeoptr, \ const char * const dataptr, /* No use */ \ int * const revaptr, \ const int datanbr), \ (grafptr, geomptr, filegrfptr, filegeoptr, dataptr, revaptr, datanbr)) { FILE * filegrfstream; /* Streams to build from handles */ FILE * filegeostream; int filegrfnum; /* Duplicated handle */ int filegeonum; int o; if ((filegrfnum = dup (*filegrfptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFGRAPHGEOMLOADCHAC: cannot duplicate handle (1)"); *revaptr = 1; /* Indicate error */ return; } if ((filegeonum = dup (*filegeoptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFGRAPHGEOMLOADCHAC: cannot duplicate handle (2)"); close (filegrfnum); *revaptr = 1; /* Indicate error */ return; } if ((filegrfstream = fdopen (filegrfnum, "r")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFGRAPHGEOMLOADCHAC: cannot open input stream (1)"); close (filegrfnum); close (filegeonum); *revaptr = 1; return; } if ((filegeostream = fdopen (filegeonum, "r")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFGRAPHGEOMLOADCHAC: cannot open input stream (2)"); fclose (filegrfstream); close (filegeonum); *revaptr = 1; return; } o = SCOTCH_graphGeomLoadChac (grafptr, geomptr, filegrfstream, filegeostream, NULL); fclose (filegrfstream); /* This closes file descriptors too */ fclose (filegeostream); *revaptr = o; } /* String lengths are passed at the very ** end of the argument list. */ FORTRAN ( \ SCOTCHFGRAPHGEOMSAVECHAC, scotchfgraphgeomsavechac, ( \ const SCOTCH_Graph * const grafptr, \ const SCOTCH_Geom * const geomptr, \ const int * const filegrfptr, \ const int * const filegeoptr, \ const char * const dataptr, /* No use */ \ int * const revaptr, \ const int datanbr), \ (grafptr, geomptr, filegrfptr, filegeoptr, dataptr, revaptr, datanbr)) { FILE * filegrfstream; /* Streams to build from handles */ FILE * filegeostream; int filegrfnum; /* Duplicated handle */ int filegeonum; int o; if ((filegrfnum = dup (*filegrfptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFGRAPHGEOMSAVECHAC: cannot duplicate handle (1)"); *revaptr = 1; /* Indicate error */ return; } if ((filegeonum = dup (*filegeoptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFGRAPHGEOMSAVECHAC: cannot duplicate handle (2)"); close (filegrfnum); *revaptr = 1; /* Indicate error */ return; } if ((filegrfstream = fdopen (filegrfnum, "w")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFGRAPHGEOMSAVECHAC: cannot open output stream (1)"); close (filegrfnum); close (filegeonum); *revaptr = 1; return; } if ((filegeostream = fdopen (filegeonum, "w")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFGRAPHGEOMSAVECHAC: cannot open output stream (2)"); fclose (filegrfstream); close (filegeonum); *revaptr = 1; return; } o = SCOTCH_graphGeomSaveChac (grafptr, geomptr, filegrfstream, filegeostream, NULL); fclose (filegrfstream); /* This closes file descriptors too */ fclose (filegeostream); *revaptr = o; } scotch-6.0.4.dfsg/src/libscotch/graph_io_habo.h0000644002563400244210000001005311631447170024567 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : graph_io_habo.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the Harwell-Boeing matrix **/ /** format I/O module. **/ /** **/ /** DATES : # Version 3.2 : from : 06 nov 1997 **/ /** to 06 nov 1997 **/ /** # Version 3.3 : from : 13 dec 1998 **/ /** to 15 dec 1998 **/ /** # Version 4.0 : from : 18 dec 2001 **/ /** to 19 jan 2004 **/ /** # Version 5.0 : from : 06 jun 2007 **/ /** to 06 jun 2007 **/ /** # Version 5.1 : from : 09 nov 2008 **/ /** to 09 nov 2008 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ Prime number for hashing vertex numbers. +*/ #define GRAPHGEOMHABOHASHPRIME 7 /*+ Prime number +*/ /* ** The type and structure definitions. */ /*+ This structure holds neighbor vertex hashing data. +*/ typedef struct GraphGeomHaboHash_ { Gnum vertnum; /*+ Origin vertex (i.e. pass) number +*/ Gnum vertend; /*+ Adjacent end vertex number +*/ } GraphGeomHaboHash; /*+ This structure holds line formats for reading input data +*/ typedef struct GraphGeomHaboLine_ { int strtnbr; /*+ Number of starting blank characters +*/ int datanbr; /*+ Number of integers par line +*/ int datalen; /*+ Number of characters per integer +*/ } GraphGeomHaboLine; /* ** The function prototypes. */ #ifndef GRAPH_IO_HABO #define static #endif static int graphGeomLoadHaboFormat (GraphGeomHaboLine * restrict const, const char * const); #undef static scotch-6.0.4.dfsg/src/libscotch/library_dgraph_io_save_f.c0000644002563400244210000001022412055776644027020 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_io_save_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API for **/ /** the distributed source graph handling **/ /** routines of the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 16 may 2007 **/ /** to 16 may 2007 **/ /** # Version 5.1 : from : 27 mar 2010 **/ /** to 27 mar 2010 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "ptscotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the graph handling routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFDGRAPHSAVE, scotchfdgraphsave, ( \ SCOTCH_Dgraph * const grafptr, \ int * const fileptr, \ int * const revaptr), \ (grafptr, fileptr, revaptr)) { FILE * stream; /* Stream to build from handle */ int filenum; /* Duplicated handle */ int o; if ((filenum = dup (*fileptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFDGRAPHSAVE: cannot duplicate handle"); *revaptr = 1; /* Indicate error */ return; } if ((stream = fdopen (filenum, "w")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFDGRAPHSAVE: cannot open output stream"); close (filenum); *revaptr = 1; return; } o = SCOTCH_dgraphSave (grafptr, stream); fclose (stream); /* This closes filenum too */ *revaptr = o; } scotch-6.0.4.dfsg/src/libscotch/dorder_gather.c0000644002563400244210000005547112225622435024626 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2013 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dorder_gather.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles distributed **/ /** orderings. **/ /** **/ /** DATES : # Version 5.0 : from : 19 jul 2007 **/ /** to 10 sep 2007 **/ /** # Version 5.1 : from : 28 sep 2008 **/ /** to 28 sep 2008 **/ /** # Version 6.0 : from : 10 oct 2013 **/ /** to 10 oct 2013 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DORDER #include "module.h" #include "common.h" #include "dgraph.h" #include "dgraph_allreduce.h" #include "order.h" #include "dorder.h" #include "dorder_gather.h" /************************************/ /* */ /* These routines handle orderings. */ /* */ /************************************/ /* This function gathers the pieces of ** a distributed ordering to build a ** centralized ordering. ** It returns: ** - 0 : if ordering data are consistent. ** - !0 : on error. */ DGRAPHALLREDUCEMAXSUMOP (1, 1) int dorderGather ( const Dorder * restrict const dordptr, Order * restrict const cordptr) { Gnum leaflocnbr; int leafrcvnbr; DorderGatherLeaf * restrict leafrcvtab; int leafsndnbr; /* "int" since used as count in MPI_Gatherv */ DorderGatherLeaf * restrict leafsndtab; Gnum * restrict perircvtab; int perisndnbr; /* "int" since used as count in MPI_Gatherv */ Gnum * restrict perisndtab; int * restrict recvcnttab; int * restrict recvdsptab; const DorderLink * restrict linklocptr; Gnum vnodlocnbr; int procglbnbr; int protnum; Gnum reduloctab[2]; Gnum reduglbtab[2]; int cheklocval; int chekglbval; #ifdef SCOTCH_DEBUG_DORDER2 if ((DORDERCBLKNEDI == 0) || (DORDERCBLKNEDI != ORDERCBLKNEDI)) { errorPrint ("dorderGather: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_DORDER2 */ for (linklocptr = dordptr->linkdat.nextptr, leaflocnbr = vnodlocnbr = 0; /* For all nodes in local ordering structure */ linklocptr != &dordptr->linkdat; linklocptr = linklocptr->nextptr) { const DorderCblk * restrict cblklocptr; cblklocptr = (DorderCblk *) linklocptr; /* TRICK: FIRST */ if ((cblklocptr->typeval & DORDERCBLKLEAF) != 0) { /* If node is leaf */ leaflocnbr ++; /* One more leaf fragment */ vnodlocnbr += cblklocptr->data.leaf.vnodlocnbr; /* And more node vertices */ } #ifdef SCOTCH_DEBUG_DORDER2 else if (cblklocptr->typeval != DORDERCBLKNEDI) { errorPrint ("dorderGather: invalid parameters"); return (1); } #endif /* SCOTCH_DEBUG_DORDER2 */ } MPI_Comm_size (dordptr->proccomm, &procglbnbr); if (cordptr != NULL) { Gnum vnodglbnbr; reduloctab[0] = (Gnum) dordptr->proclocnum; reduloctab[1] = 1; vnodglbnbr = 2 * procglbnbr; /* TRICK: use perircvtab array as gather array */ if (vnodglbnbr < (dordptr->vnodglbnbr - vnodlocnbr)) /* But should receive permutation indices too! */ vnodglbnbr = dordptr->vnodglbnbr - vnodlocnbr; /* TRICK: root will not receive from itself */ if (memAllocGroup ((void **) (void *) &recvcnttab, (size_t) (procglbnbr * sizeof (int)), &recvdsptab, (size_t) (procglbnbr * sizeof (int)), &perircvtab, (size_t) (vnodglbnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("dorderGather: out of memory (1)"); reduloctab[0] = (Gnum) procglbnbr; /* Indicate memory error */ } } else { recvcnttab = NULL; /* Prepare possible freeing on error */ reduloctab[0] = reduloctab[1] = 0; } if (dgraphAllreduceMaxSum (reduloctab, reduglbtab, 1, 1, dordptr->proccomm) != 0) { errorPrint ("dorderGather: communication error (1)"); return (1); } if (reduglbtab[1] != 1) { errorPrint ("dorderGather: should have only one root"); reduglbtab[0] = (Gnum) procglbnbr; } if (reduglbtab[0] >= (Gnum) procglbnbr) { if (recvcnttab != NULL) memFree (recvcnttab); return (1); } protnum = (int) reduglbtab[0]; reduloctab[0] = leaflocnbr; reduloctab[1] = vnodlocnbr; if (MPI_Gather (reduloctab, 2, GNUM_MPI, perircvtab, 2, GNUM_MPI, protnum, dordptr->proccomm) != MPI_SUCCESS) { errorPrint ("dorderGather: communication error (2)"); return (1); } if (dordptr->proclocnum == protnum) { int procnum; perircvtab[2 * protnum] = 0; /* TRICK: root will not send to nor receive from itself to avoid unnecessary memory copy */ for (procnum = 0, leafrcvnbr = 0; procnum < procglbnbr; procnum ++) { recvdsptab[procnum] = leafrcvnbr; recvcnttab[procnum] = (int) (perircvtab[2 * procnum] * 2); /* TRICK: DorderGatherLeaf structures are made of 2 GNUM_MPI fields */ leafrcvnbr += recvcnttab[procnum]; } leafrcvnbr /= 2; /* TRICK: restore real number of leaf structures to be received */ leafsndnbr = 0; perisndnbr = 0; } else { leafrcvnbr = 0; leafsndnbr = (int) leaflocnbr; perisndnbr = (int) vnodlocnbr; } cheklocval = 0; if (memAllocGroup ((void **) (void *) &leafrcvtab, (size_t) (leafrcvnbr * sizeof (DorderGatherLeaf)), &leafsndtab, (size_t) (leafsndnbr * sizeof (DorderGatherLeaf)), &perisndtab, (size_t) (perisndnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("dorderGather: out of memory (2)"); cheklocval = 1; } #ifdef SCOTCH_DEBUG_DORDER1 /* Communication cannot be merged with a useful one */ if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, dordptr->proccomm) != MPI_SUCCESS) { errorPrint ("dorderGather: communication error (3)"); return (1); } #else /* SCOTCH_DEBUG_DORDER1 */ chekglbval = cheklocval; #endif /* SCOTCH_DEBUG_DORDER1 */ if (chekglbval != 0) { if (recvcnttab != NULL) memFree (recvcnttab); return (1); } if (dordptr->proclocnum == protnum) { /* If root process */ #ifdef SCOTCH_DEBUG_DORDER2 memSet (cordptr->peritab, ~0, dordptr->vnodglbnbr * sizeof (Gnum)); #endif /* SCOTCH_DEBUG_DORDER2 */ for (linklocptr = dordptr->linkdat.nextptr; linklocptr != &dordptr->linkdat; linklocptr = linklocptr->nextptr) { /* For all nodes */ const DorderCblk * restrict cblklocptr; cblklocptr = (DorderCblk *) linklocptr; /* TRICK: FIRST */ if ((cblklocptr->typeval & DORDERCBLKLEAF) != 0) /* If tree node is leaf, copy fragment */ memCpy (cordptr->peritab + cblklocptr->data.leaf.ordelocval, cblklocptr->data.leaf.periloctab, cblklocptr->data.leaf.vnodlocnbr * sizeof (Gnum)); } } else { Gnum leaflocnum; Gnum vnodlocnum; for (linklocptr = dordptr->linkdat.nextptr, leaflocnum = vnodlocnum = 0; linklocptr != &dordptr->linkdat; linklocptr = linklocptr->nextptr) { /* For all nodes */ const DorderCblk * restrict cblklocptr; cblklocptr = (DorderCblk *) linklocptr; /* TRICK: FIRST */ if ((cblklocptr->typeval & DORDERCBLKLEAF) != 0) { /* If node is leaf */ leafsndtab[leaflocnum].ordelocval = cblklocptr->data.leaf.ordelocval; /* Fill send structures with permutation data */ leafsndtab[leaflocnum].vnodlocnbr = cblklocptr->data.leaf.vnodlocnbr; memCpy (perisndtab + vnodlocnum, cblklocptr->data.leaf.periloctab, cblklocptr->data.leaf.vnodlocnbr * sizeof (Gnum)); vnodlocnum += cblklocptr->data.leaf.vnodlocnbr; leaflocnum ++; } } leafsndnbr *= 2; /* TRICK: DorderGatherLeaf structures are made of 2 GNUM_MPI fields */ } if (MPI_Gatherv (leafsndtab, leafsndnbr, GNUM_MPI, leafrcvtab, recvcnttab, recvdsptab, GNUM_MPI, protnum, dordptr->proccomm) != MPI_SUCCESS) { errorPrint ("dorderGather: communication error (4)"); return (1); } if (dordptr->proclocnum == protnum) { int vnodglbnbr; int procnum; perircvtab[2 * protnum + 1] = 0; /* TRICK: root will not send to nor receive from itself to avoid unnecessary memory copy */ for (procnum = 0, vnodglbnbr = 0; procnum < procglbnbr; procnum ++) { recvdsptab[procnum] = vnodglbnbr; recvcnttab[procnum] = (int) perircvtab[2 * procnum + 1]; vnodglbnbr += recvcnttab[procnum]; } #ifdef SCOTCH_DEBUG_DORDER2 if (((Gnum) vnodglbnbr + vnodlocnbr) != dordptr->vnodglbnbr) { errorPrint ("dorderGather: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_DORDER2 */ } if (MPI_Gatherv (perisndtab, perisndnbr, GNUM_MPI, perircvtab, recvcnttab, recvdsptab, GNUM_MPI, protnum, dordptr->proccomm) != MPI_SUCCESS) { errorPrint ("dorderGather: communication error (5)"); return (1); } if (dordptr->proclocnum == protnum) { /* If root process */ int leafglbnum; int vnodglbnum; for (leafglbnum = vnodglbnum = 0; leafglbnum < leafrcvnbr; leafglbnum ++) { memCpy (cordptr->peritab + leafrcvtab[leafglbnum].ordelocval, perircvtab + vnodglbnum, leafrcvtab[leafglbnum].vnodlocnbr * sizeof (Gnum)); vnodglbnum += leafrcvtab[leafglbnum].vnodlocnbr; } memFree (recvcnttab); /* Free group leader */ } memFree (leafrcvtab); /* Free group leader */ if (dorderGatherTree (dordptr, cordptr, protnum) != 0) /* Gather ordering tree */ return (1); #ifdef SCOTCH_DEBUG_DORDER2 if (dordptr->proclocnum == protnum) { if (orderCheck (cordptr) != 0) { errorPrint ("dorderGather: invalid centralized ordering"); return (1); } } #endif /* SCOTCH_DEBUG_DORDER2 */ return (0); } /* This function gathers the pieces of ** a distributed ordering tree to build a ** centralized ordering tree. ** It returns: ** - 0 : if ordering data are consistent. ** - !0 : on error. */ int dorderGatherTree ( const Dorder * restrict const dordptr, Order * restrict const cordptr, const int protnum) { int treelocnbr; /* "int" since used as way to fill count array in MPI_Allgather */ Gnum treeglbnbr; DorderGatherNode * restrict treercvtab; int treesndnbr; /* "int" since used as count in MPI_Gatherv */ DorderGatherNode * treesndtab; DorderGatherNode * restrict treesndptr; int * restrict treecnttab; int * restrict treedsptab; DorderGatherCblk * restrict cblkglbtab; const DorderLink * restrict linklocptr; int procglbnbr; int procnum; int cheklocval; int chekglbval; for (linklocptr = dordptr->linkdat.nextptr, treelocnbr = 0; /* Count only purely local nodes */ linklocptr != &dordptr->linkdat; linklocptr = linklocptr->nextptr) { const DorderCblk * restrict cblklocptr; cblklocptr = (DorderCblk *) linklocptr; /* TRICK: FIRST */ #ifdef SCOTCH_DEBUG_DORDER2 if ((cblklocptr->cblknum.proclocnum != dordptr->proclocnum) && /* Local sub-nodes of non-locally rooted node not implemented */ ((cblklocptr->typeval & DORDERCBLKLEAF) != 0) && (cblklocptr->data.leaf.nodelocnbr != 0)) { errorPrint ("dorderGatherTree: not implemented"); return (1); } #endif /* SCOTCH_DEBUG_DORDER2 */ if (cblklocptr->cblknum.proclocnum == dordptr->proclocnum) { treelocnbr ++; if ((cblklocptr->typeval & DORDERCBLKLEAF) != 0) treelocnbr += (int) cblklocptr->data.leaf.nodelocnbr; } } MPI_Comm_size (dordptr->proccomm, &procglbnbr); treesndnbr = (dordptr->proclocnum == protnum) ? 0 : treelocnbr; /* TRICK: root will not send nor receive */ cheklocval = 0; if (memAllocGroup ((void **) (void *) &treecnttab, (size_t) (procglbnbr * sizeof (int)), &treedsptab, (size_t) (procglbnbr * sizeof (int)), &treesndtab, (size_t) (treesndnbr * sizeof (DorderGatherNode)), NULL) == NULL) { errorPrint ("dorderGatherTree: out of memory (1)"); cheklocval = 1; } #ifdef SCOTCH_DEBUG_DORDER1 /* Communication cannot be merged with a useful one */ if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, dordptr->proccomm) != MPI_SUCCESS) { errorPrint ("dorderGatherTree: communication error (1)"); return (1); } #else /* SCOTCH_DEBUG_DORDER1 */ chekglbval = cheklocval; #endif /* SCOTCH_DEBUG_DORDER1 */ if (chekglbval != 0) { if (treecnttab != NULL) memFree (treecnttab); return (1); } if (MPI_Allgather (&treelocnbr, 1, MPI_INT, treecnttab, 1, MPI_INT, dordptr->proccomm) != MPI_SUCCESS) { errorPrint ("dorderGatherTree: communication error (2)"); return (1); } for (procnum = 0, treeglbnbr = 0; procnum < procglbnbr; procnum ++) { /* Compute prefix sum of local numbers for global numbering */ treedsptab[procnum] = treeglbnbr; treeglbnbr += treecnttab[procnum]; } if (dordptr->proclocnum == protnum) { treecnttab[protnum] = 0; /* TRICK: root will not send to nor receive from itself to avoid unnecessary memory copy */ cordptr->treenbr = treeglbnbr; if (memAllocGroup ((void **) (void *) &treercvtab, (size_t) (treeglbnbr * sizeof (DorderGatherNode)), &cblkglbtab, (size_t) (treeglbnbr * sizeof (DorderGatherCblk)), NULL) == NULL) { errorPrint ("dorderGatherTree: out of memory (2)"); cheklocval = 1; } treesndptr = treercvtab + treedsptab[protnum]; /* TRICK: root process will build its column blocks in place as if received */ } else treesndptr = treesndtab; #ifdef SCOTCH_DEBUG_DORDER1 /* Communication cannot be merged with a useful one */ if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, dordptr->proccomm) != MPI_SUCCESS) { errorPrint ("dorderGather: communication error (3)"); return (1); } #else /* SCOTCH_DEBUG_DORDER1 */ chekglbval = cheklocval; #endif /* SCOTCH_DEBUG_DORDER1 */ if (chekglbval != 0) { memFree (treecnttab); return (1); } for (linklocptr = dordptr->linkdat.nextptr; linklocptr != &dordptr->linkdat; linklocptr = linklocptr->nextptr) { /* For all nodes */ const DorderCblk * restrict cblklocptr; cblklocptr = (DorderCblk *) linklocptr; /* TRICK: FIRST */ if (cblklocptr->cblknum.proclocnum != dordptr->proclocnum) /* Skip non-local nodes */ continue; treesndptr->fathnum = treedsptab[cblklocptr->fathnum.proclocnum] + cblklocptr->fathnum.cblklocnum; /* If node is (part of) the root node */ treesndptr->typeval = (Gnum) (((cblklocptr->typeval & DORDERCBLKNEDI) != 0) ? ORDERCBLKNEDI : ORDERCBLKOTHR); treesndptr->vnodnbr = cblklocptr->vnodglbnbr; treesndptr->cblknum = cblklocptr->cblkfthnum; treesndptr ++; if ((cblklocptr->typeval & DORDERCBLKLEAF) != 0) { /* If node is a distributed leaf */ Gnum cblkglbnum; Gnum cblkglbadj; const DorderNode * restrict nodelocptr; const DorderNode * restrict nodeloctnd; cblkglbnum = treedsptab[cblklocptr->cblknum.proclocnum] + cblklocptr->cblknum.cblklocnum; cblkglbadj = treedsptab[cblklocptr->cblknum.proclocnum] + cblklocptr->data.leaf.cblklocnum; for (nodelocptr = cblklocptr->data.leaf.nodeloctab, nodeloctnd = nodelocptr + cblklocptr->data.leaf.nodelocnbr; nodelocptr < nodeloctnd; nodelocptr ++) { /* Build nodes for all local nodes */ treesndptr->fathnum = (nodelocptr->fathnum == -1) ? cblkglbnum : (nodelocptr->fathnum + cblkglbadj); treesndptr->typeval = (Gnum) nodelocptr->typeval; treesndptr->vnodnbr = nodelocptr->vnodnbr; treesndptr->cblknum = nodelocptr->cblknum; treesndptr ++; } } #ifdef SCOTCH_DEBUG_DORDER2 else if (cblklocptr->typeval != DORDERCBLKNEDI) { errorPrint ("dorderGatherTree: invalid column block type"); return (1); } #endif /* SCOTCH_DEBUG_DORDER2 */ } #ifdef SCOTCH_DEBUG_DORDER2 if (treesndptr != ((dordptr->proclocnum == protnum) ? (treercvtab + treedsptab[protnum]) : treesndtab) + treelocnbr) { errorPrint ("dorderGatherTree: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_DORDER2 */ if (dordptr->proclocnum == protnum) { /* If node is root, adjust displacements in terms of Gnum and not DorderGatherNode */ for (procnum = 0; procnum < procglbnbr; procnum ++) { treecnttab[procnum] *= DORDERGATHERNODESIZE; treedsptab[procnum] *= DORDERGATHERNODESIZE; } } if (MPI_Gatherv (treesndtab, treesndnbr * DORDERGATHERNODESIZE, GNUM_MPI, treercvtab, treecnttab, treedsptab, GNUM_MPI, protnum, dordptr->proccomm) != MPI_SUCCESS) { errorPrint ("dorderGatherTree: communication error (4)"); return (1); } if (dordptr->proclocnum == protnum) { Gnum treeglbnum; Gnum cblkglbnbr; memSet (cblkglbtab, 0, treeglbnbr * sizeof (DorderGatherCblk)); /* Set all son counters to zero and all array pointers to NULL */ for (treeglbnum = 1; treeglbnum < treeglbnbr; treeglbnum ++) { /* For all local and received tree nodes except root node */ Gnum cblkfthnum; cblkfthnum = treercvtab[treeglbnum].fathnum; #ifdef SCOTCH_DEBUG_DORDER2 if ((cblkfthnum < 0) || /* Father of non-root node cannot be -1 */ (cblkfthnum >= treeglbnum)) { /* Father should always have smaller global node number */ errorPrint ("dorderGatherTree: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_DORDER2 */ cblkglbtab[cblkfthnum].cblknbr ++; /* Add a son to its father */ } for (treeglbnum = 0, cblkglbnbr = treeglbnbr; treeglbnum < treeglbnbr; treeglbnum ++) { /* For all local and received tree nodes */ if (cblkglbtab[treeglbnum].cblknbr > 0) { #ifdef SCOTCH_DEBUG_DORDER2 if (cblkglbtab[treeglbnum].cblknbr < 2) { /* Descendent nodes should comprise at least two column block slots */ errorPrint ("dorderGatherTree: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_DORDER2 */ cblkglbnbr --; /* One new subblock means one more shared frontier, so one less column block than nodes */ if ((cblkglbtab[treeglbnum].cblktab = memAlloc (cblkglbtab[treeglbnum].cblknbr * sizeof (OrderCblk))) == NULL) { errorPrint ("dorderGather: out of memory (3)"); while (-- treeglbnum >= 0) { if (cblkglbtab[treeglbnum].cblktab != NULL) memFree (cblkglbtab[treeglbnum].cblktab); } memFree (treercvtab); memFree (treecnttab); return (1); } } } cordptr->cblknbr = cblkglbnbr; cordptr->cblktre.typeval = (int) treercvtab[0].typeval; /* Process root node of separator tree */ cordptr->cblktre.vnodnbr = treercvtab[0].vnodnbr; cordptr->cblktre.cblknbr = cblkglbtab[0].cblknbr; cordptr->cblktre.cblktab = cblkglbtab[0].cblktab; /* Link its sons array */ for (treeglbnum = 1; treeglbnum < treeglbnbr; treeglbnum ++) { /* For all nodes except the root */ Gnum cblkfthnum; OrderCblk * restrict cblksonptr; cblkfthnum = treercvtab[treeglbnum].cblknum; #ifdef SCOTCH_DEBUG_DORDER2 if ((cblkfthnum < 0) || (cblkfthnum >= cblkglbtab[treercvtab[treeglbnum].fathnum].cblknbr)) { errorPrint ("dorderGatherTree: internal error (4)"); return (1); } #endif /* SCOTCH_DEBUG_DORDER2 */ cblksonptr = &cblkglbtab[treercvtab[treeglbnum].fathnum].cblktab[cblkfthnum]; /* Point to son's slot in father array */ cblksonptr->typeval = (int) treercvtab[treeglbnum].typeval; cblksonptr->vnodnbr = treercvtab[treeglbnum].vnodnbr; cblksonptr->cblknbr = cblkglbtab[treeglbnum].cblknbr; /* Link son column block array to column block structure */ cblksonptr->cblktab = cblkglbtab[treeglbnum].cblktab; } memFree (treercvtab); } memFree (treecnttab); return (0); } scotch-6.0.4.dfsg/src/libscotch/vdgraph_separate_ml.h0000644002563400244210000001111712412035044026006 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2009, 2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vdgraph_separate_ml.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Cedric CHEVALIER (v5.0) **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the sequential vertex separation **/ /** routine for distributed graphs. **/ /** **/ /** DATES : # Version 5.0 : from : 07 feb 2006 **/ /** to : 03 aug 2007 **/ /** # Version 5.1 : from : 14 dec 2008 **/ /** to : 29 may 2009 **/ /** # Version 6.0 : from : 28 sep 2014 **/ /** to : 28 sep 2014 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct VdgraphSeparateMlParam_ { INT passnbr; /*+ Number of coarsening passes to go +*/ INT foldmax; /*+ Maximum number of vertices per processor to do folding +*/ int foldval; /*+ Type of folding +*/ INT coarnbr; /*+ Minimum number of vertices +*/ double coarrat; /*+ Coarsening ratio +*/ Strat * stratlow; /*+ Strategy at lowest level +*/ Strat * stratasc; /*+ Strategy at ascending levels +*/ Strat * stratseq; /*+ Strategy when running on a single processor +*/ } VdgraphSeparateMlParam; /* ** The function prototypes. */ #ifndef VDGRAPH_SEPARATE_ML #define static #endif static int vdgraphSeparateMlCoarsen (Vdgraph * const, Vdgraph * const, DgraphCoarsenMulti * restrict * const, const VdgraphSeparateMlParam * const); static int vdgraphSeparateMlUncoarsen (Vdgraph *, const Vdgraph * const, const DgraphCoarsenMulti * restrict const); static void vdgraphSeparateMlOpBest (const Gnum * const, Gnum * const, const int * const, const MPI_Datatype * const); int vdgraphSeparateMl (Vdgraph * const, const VdgraphSeparateMlParam * const); static int vdgraphSeparateMl2 (Vdgraph * const, const VdgraphSeparateMlParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/kgraph_map_ex.c0000644002563400244210000004420212375455630024617 0ustar trophimeutilisateurs du domaine/* Copyright 2011,2013,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph_map_ex.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module tries to balance the **/ /** subgraphs of the partition as best as **/ /** it can. **/ /** **/ /** DATES : # Version 6.0 : from : 27 may 2011 **/ /** to 21 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define KGRAPH_MAP_EX #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "arch.h" #include "mapping.h" #include "kgraph.h" #include "kgraph_map_ex.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the balanced mapping. ** It returns: ** - 0 : if mapping could be computed. ** - 1 : on error. */ int kgraphMapEx ( Kgraph * const grafptr, /*+ Graph to map +*/ const KgraphMapExParam * const paraptr) /*+ Method parameters +*/ { KgraphMapExDom * restrict doextab; KgraphMapExSort * restrict sorttab; KgraphMapExTerm * restrict termtab; KgraphMapExTree * restrict treetab; Anum * restrict parttax; Anum treenbr; /* Number of nodes in tree structure */ const Arch * restrict archptr; ArchDom domndat; /* Root domain */ Anum domnnbr; Anum domnnum; Gnum sortnbr; /* Number of non-fixed vertices */ Gnum sortnum; Anum termnbr; /* Number of terminal domains in mapping */ Gnum vertnum; Gnum vertnnd; double velosum; /* Sum of vertex weights */ double wghtsum; /* Sum of architecture weights */ Anum wghttmp; /* Sum of architecture weights for archVar */ int flagval; /* Flag unset if load imbalance to fix */ const Gnum * restrict const velotax = grafptr->s.velotax; const Anum * restrict const pfixtax = grafptr->pfixtax; grafptr->kbalval = paraptr->kbalval; /* Store last k-way imbalance ratio */ domnnbr = grafptr->m.domnnbr; sortnbr = grafptr->s.vertnbr - grafptr->vfixnbr; /* Only sort non-fixed vertices */ if (memAllocGroup ((void **) (void *) &doextab, (size_t) (domnnbr * sizeof (KgraphMapExDom)), &sorttab, (size_t) (sortnbr * sizeof (KgraphMapExSort)), &termtab, (size_t) (domnnbr * sizeof (KgraphMapExTerm)), &treetab, (size_t) (domnnbr * sizeof (KgraphMapExTree) * 2), NULL) == NULL) { errorPrint ("kgraphMapEx: out of memory"); return (1); } archptr = grafptr->m.archptr; archDomFrst (archptr, &domndat); wghtsum = (double) archDomWght (archptr, &domndat); velosum = (double) grafptr->s.velosum; for (domnnum = 0, termnbr = 0, wghttmp = 0, flagval = 1; domnnum < domnnbr; domnnum ++) { const ArchDom * restrict domnptr; domnptr = &grafptr->m.domntab[domnnum]; if (archDomSize (archptr, domnptr) <= 1) { /* If domain is a terminal (even variable-sized) */ Anum termnum; wghttmp += /* Accumulate subdomain loads in case of variable-sized architectures */ doextab[domnnum].domnwght = archDomWght (archptr, domnptr); doextab[domnnum].compload = 0; doextab[domnnum].comploadmax = ((double) doextab[domnnum].domnwght * velosum * (1.0 + paraptr->kbalval)) / wghtsum; termnum = archDomNum (archptr, domnptr); termtab[termnbr].termnum = termnum; /* Record domain in terminal domain array */ termtab[termnbr].domnnum = domnnum; termnbr ++; /* One more terminal domain */ if ((grafptr->comploadavg[domnnum] + grafptr->comploaddlt[domnnum]) > doextab[domnnum].comploadmax) flagval = 0; /* Set flag if at least one domain is imbalanced */ } } if (archVar (archptr)) { /* If architecture is variable-sized */ Anum termnum; wghtsum = (double) wghttmp / wghtsum; /* Recompute real load sum */ for (termnum = 0; termnum < termnbr; termnum ++) { Anum domnnum; domnnum = termtab[termnum].domnnum; doextab[domnnum].comploadmax = ((double) doextab[domnnum].domnwght * velosum * (1.0 + paraptr->kbalval)) / wghtsum; if ((grafptr->comploadavg[domnnum] + grafptr->comploaddlt[domnnum]) > doextab[domnnum].comploadmax) flagval = 0; /* Set flag if at least one domain is imbalanced */ } } if (flagval != 0) { /* If nothing to do */ memFree (doextab); /* Free group leader */ return (0); } intSort2asc1 (termtab, termnbr); /* Sort terminal domains to allow for dichotomy */ treenbr = 0; /* Prepare to fill tree array; next slot to fill */ kgraphMapExTree (archptr, termtab, termnbr, doextab, treetab, &treenbr, &domndat); /* Recursively fill tree array */ parttax = grafptr->m.parttax; for (vertnum = grafptr->s.baseval, vertnnd = grafptr->s.vertnnd, sortnbr = 0; /* Get vertex weights */ vertnum < vertnnd; vertnum ++) { Gnum veloval; veloval = (velotax != NULL) ? velotax[vertnum] : 1; if ((pfixtax == NULL) || (pfixtax[vertnum] < 0)) { /* If vertex is not fixed */ sorttab[sortnbr].veloval = veloval; /* Record it for sorting */ sorttab[sortnbr].vertnum = vertnum; sortnbr ++; } else doextab[parttax[vertnum]].comploadmax -= veloval; /* Reduce available room in domain for non-fixed vertices */ } #ifdef SCOTCH_DEBUG_KGRAPH2 if (sortnbr != (grafptr->s.vertnbr - grafptr->vfixnbr)) { errorPrint ("kgraphMapEx: internal error"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ if (velotax != NULL) /* If vertices are weighted, sort them in ascending order */ intSort2asc1 (sorttab, sortnbr); for (sortnum = sortnbr - 1; sortnum >= 0; sortnum --) { /* For all sorted vertex indices, by descending weights */ Gnum vertnum; Gnum veloval; Anum domnnum; vertnum = sorttab[sortnum].vertnum; veloval = sorttab[sortnum].veloval; domnnum = parttax[vertnum]; if ((doextab[domnnum].compload + veloval) > doextab[domnnum].comploadmax) { /* If leaving vertex in place would cause imbalance */ domnnum = kgraphMapExFind (archptr, treetab, doextab, domnnum, veloval); /* Try to find better location for vertex load */ if (parttax[vertnum] != domnnum) { /* If vertex moved to another part */ parttax[vertnum] = domnnum; /* Set vertex to new part */ flagval = 0; /* Record change */ } } doextab[domnnum].compload += veloval; } memFree (doextab); /* Free group leader */ if (flagval == 0) { /* If something changed */ kgraphFron (grafptr); /* Recompute frontier */ kgraphCost (grafptr); } #ifdef SCOTCH_DEBUG_KGRAPH2 if (kgraphCheck (grafptr) != 0) { errorPrint ("kgraphMapEx: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ return (0); } /* This routine fills the tree structure ** with the relevant node information. ** It returns: ** - void : in all cases. */ static Anum kgraphMapExTree ( const Arch * restrict const archptr, const KgraphMapExTerm * restrict const termtab, const Anum termnbr, KgraphMapExDom * restrict const doextab, /*+ Extended domain array, for adding link to tree +*/ KgraphMapExTree * restrict const treetab, Anum * restrict const treeptr, const ArchDom * restrict const domnptr) /*+ Pointer to subdomain to consider for this node +*/ { Anum treenum; int o; if (archDomSize (archptr, domnptr) > 1) { /* If not variable-sized architecture and can bipartition */ ArchDom domntab[2]; /* Temporary area to store subdomains */ Anum sonstab[2]; int i, j; o = archDomBipart (archptr, domnptr, &domntab[0], &domntab[1]); #ifdef SCOTCH_DEBUG_KGRAPH2 if (o != 0) { errorPrint ("kgraphMapExTree: internal error"); return (-1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ sonstab[0] = kgraphMapExTree (archptr, termtab, termnbr, doextab, treetab, treeptr, &domntab[0]); sonstab[1] = kgraphMapExTree (archptr, termtab, termnbr, doextab, treetab, treeptr, &domntab[1]); if (sonstab[0] + sonstab[1] < -1) /* If both sub-branches do not exist */ return (-1); /* Return that this branch does not exist */ treenum = (*treeptr) ++; /* Reserve slot for node */ treetab[treenum].fathnum = /* Assume node has no father (yet) */ treetab[treenum].sonstab[1] = -1; /* Assume second node does not exist */ for (i = j = 0; i < 2; i ++) { /* For both prospective sons */ Anum sonsnum; sonsnum = sonstab[i]; if (sonsnum == -1) /* If this son does not exist, skip it */ continue; treetab[treenum].sonstab[j] = sonsnum; /* Link son to current node */ treetab[sonsnum].fathnum = treenum; j ++; /* One more son created */ } treetab[treenum].domndat = *domnptr; } else { /* If domain is terminal */ Anum termmin; Anum termmax; Anum termnum; Anum domnnum; #ifdef SCOTCH_DEBUG_KGRAPH2 if (archVar (archptr)) { errorPrint ("kgraphMapExTree: not implemented"); return (-1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ termnum = archDomNum (archptr, domnptr); /* Get number of terminal domain */ for (termmin = 0, termmax = termnbr; (termmax - termmin) > 1; ) { Anum termmed; termmed = (termmax + termmin) / 2; if (termtab[termmed].termnum <= termnum) termmin = termmed; else termmax = termmed; } if (termtab[termmin].termnum != termnum) /* If terminal not found */ return (-1); /* This branch is dead */ treenum = (*treeptr) ++; /* Reserve slot for terminal */ domnnum = termtab[termmin].domnnum; /* Get domain location */ treetab[treenum].sonstab[0] = -1; /* Slot is terminal */ treetab[treenum].sonstab[1] = domnnum; /* Record domain number of tree node */ treetab[treenum].domndat = *domnptr; /* Record domain data */ doextab[domnnum].treenum = treenum; /* Record entry point in tree structure */ } return (treenum); } /* This routine tries to find a destination ** target vertex that creates the least imbalance. ** It returns: ** - 0 : if a suitable terminal vertex has been found. ** - 1 : if process has to be continued.. */ static Anum kgraphMapExFind ( const Arch * restrict const archptr, /*+ Target architecture +*/ const KgraphMapExTree * restrict const treetab, /*+ Subdomain tree structure +*/ const KgraphMapExDom * restrict const doextab, /*+ Extended domain array +*/ const Anum domnnum, /*+ Initial domain number +*/ const Gnum veloval) /*+ Weight of vertex to map +*/ { KgraphMapExFind bestdat; Anum treenum; int o; bestdat.comploaddlt = (doextab[domnnum].compload + veloval - doextab[domnnum].comploadmax) / doextab[domnnum].domnwght; /* Compute weighted imbalance */ bestdat.domnnum = domnnum; treenum = doextab[domnnum].treenum; /* Start from leaf of subdomain tree */ do { /* Traverse nodes up to the root */ Anum nodenum; /* Number of the son we come from */ Anum othrnum; /* Number of the other son */ nodenum = treenum; /* Record position of current node */ treenum = treetab[treenum].fathnum; /* Get father node */ if (treenum == -1) /* If already reached root of tree */ break; othrnum = treetab[treenum].sonstab[(treetab[treenum].sonstab[0] == nodenum) ? 1 : 0]; /* Don't consider the branch we come from */ if (othrnum == -1) /* If parent node has only one son */ continue; /* Skip to upper level */ o = kgraphMapExFind2 (archptr, treetab, doextab, &bestdat, treenum, othrnum, veloval); } while (o != 0); /* As long as proper candidate not found */ return (bestdat.domnnum); /* Return best candidate found */ } /* This routine tries to find a destination ** target vertex that creates the least imbalance. ** It returns: ** - 0 : if a suitable terminal vertex has been found. ** - 1 : if process has to be continued. */ static int kgraphMapExFind2 ( const Arch * restrict const archptr, const KgraphMapExTree * restrict const treetab, const KgraphMapExDom * restrict const doextab, KgraphMapExFind * restrict const bestptr, /*+ Pointer to structure that keeps best terminal found */ const Anum treenum, const Anum nodenum, const Gnum veloval) { Anum son0num; Anum son1num; son0num = treetab[nodenum].sonstab[0]; son1num = treetab[nodenum].sonstab[1]; if (son0num != -1) { /* If node is not a terminal */ int i; int o; if (son1num == -1) /* If node has only one son */ return (kgraphMapExFind2 (archptr, treetab, doextab, bestptr, treenum, son0num, veloval)); /* Process it directly */ i = (archDomDist (archptr, &treetab[treenum].domndat, &treetab[son0num].domndat) <= /* Get closest subdomain */ archDomDist (archptr, &treetab[treenum].domndat, &treetab[son1num].domndat)) ? 0 : 1; o = kgraphMapExFind2 (archptr, treetab, doextab, bestptr, treenum, treetab[nodenum].sonstab[i], veloval); /* Process closest branch */ if (o != 0) /* If didn't find suitable terminal in closest branch */ o = kgraphMapExFind2 (archptr, treetab, doextab, bestptr, treenum, treetab[nodenum].sonstab[i ^ 1], veloval); /* Process farthest one */ return (o); } else { /* If current node is terminal */ Anum domnnum; Gnum comploaddlt; domnnum = son1num; /* Second son records domain number */ comploaddlt = (doextab[domnnum].compload + veloval - doextab[domnnum].comploadmax) / doextab[domnnum].domnwght; /* Compute weighted imbalance */ if (comploaddlt < bestptr->comploaddlt) { /* If found vertex that potentially improves balance */ bestptr->comploaddlt = comploaddlt; bestptr->domnnum = domnnum; } return ((comploaddlt <= 0) ? 0 : 1); /* Return immediatly or go on whether found proper terminal to host vertex or not */ } } scotch-6.0.4.dfsg/src/libscotch/library_dorder.c0000644002563400244210000000645612056000516025007 0ustar trophimeutilisateurs du domaine/* Copyright 2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dorder.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains miscellaneous **/ /** routines for handling distributed **/ /** graph orderings. **/ /** **/ /** DATES : # Version 5.1 : from : 17 nov 2010 **/ /** to 17 nov 2010 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "ptscotch.h" /*****************************************/ /* */ /* These routines are the C API for */ /* ordering structure handling routines. */ /* */ /*****************************************/ /*+ This routine reserves a memory area *** of a size sufficient to store a *** distributed ordering structure. *** It returns: *** - !NULL : if the initialization succeeded. *** - NULL : on error. +*/ SCOTCH_Dordering * SCOTCH_dorderAlloc () { return ((SCOTCH_Dordering *) memAlloc (sizeof (SCOTCH_Dordering))); } scotch-6.0.4.dfsg/src/libscotch/kgraph_map_bd.c0000644002563400244210000003472712342557325024601 0ustar trophimeutilisateurs du domaine/* Copyright 2010,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph_map_bd.c **/ /** **/ /** AUTHOR : Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module computes a partition of **/ /** the given k-way mapping graph by **/ /** creating a band graph of given **/ /** width around the current frontier, **/ /** computing an improved partition of the **/ /** band graph, and projecting back the **/ /** obtained frontier to the original **/ /** graph. **/ /** **/ /** DATES : # Version 6.0 : from : 05 jan 2010 **/ /** to : 03 mar 2011 **/ /** **/ /** NOTES : # Since only edges from local vertices **/ /** to local anchors are created in **/ /** kdgraphBand(), the communication cost **/ /** might be wrong if a local vertex of **/ /** the last layer is linked to a remote **/ /** vertex of different part which was **/ /** not in the band graph. Hence, commun- **/ /** ication costs have to be recomputed **/ /** from scratch. **/ /** **/ /** # This code derives from the code of **/ /** bdgraph_bipart_bd.c in version 5.1 **/ /** for direct k-way partitioning. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define KGRAPH_MAP_BD #include "module.h" #include "common.h" #include "parser.h" #include "arch.h" #include "graph.h" #include "mapping.h" #include "kgraph.h" #include "kgraph_map_bd.h" #include "kgraph_map_st.h" /* ** The static variables. */ /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine computes a band graph of given ** width around the current frontier and applies ** partitioning routines to it. ** The graph is not guaranteed to be balanced ** at all. ** It returns: ** - 0 : if the band graph could be computed. ** - !0 : on error. */ int kgraphMapBd ( Kgraph * const orggrafptr, /*+ Graph +*/ const KgraphMapBdParam * const paraptr) /*+ Method parameters +*/ { Kgraph bndgrafdat; /* Partitioning band graph structure */ Gnum bndvertancnnd; /* End of local vertex array, without anchors */ Gnum bndvertnum; Gnum bndvertlvlnum; /* Based number of first band vertex in last layer */ Gnum orgfronnum; int * restrict orgflagtab; Gnum commload; Gnum commload2; /* Twice twice (4 times) the internal communication load of last layer */ Anum domnnum; Gnum * restrict bandvnumtax; /* Orignal numbers of vertices in band graph */ Gnum * vertnbrtab; Gnum vertnum; const Arch * restrict const archptr = orggrafptr->m.archptr; const Anum domnnbr = orggrafptr->m.domnnbr; Gnum * restrict const orgfrontab = orggrafptr->frontab; Gnum * restrict const orgparttax = orggrafptr->m.parttax; if ((vertnbrtab = memAlloc (domnnbr * sizeof(Gnum))) == NULL) { errorPrint ("kgraphMapBd: out of memory (1)"); return (1); } memSet (vertnbrtab, 0, domnnbr * sizeof(Gnum)); for (vertnum = orggrafptr->s.baseval; vertnum < orggrafptr->s.vertnnd; vertnum ++) vertnbrtab[orgparttax[vertnum]] ++; /* TODO check optimize? */ if (orggrafptr->fronnbr == 0) /* If no separator vertices, apply strategy to full (original) graph */ return (kgraphMapSt (orggrafptr, paraptr->stratorg)); if (kgraphBand (orggrafptr, paraptr->distmax, &bndgrafdat, &bndvertlvlnum, &bandvnumtax) != 0) { errorPrint ("kgraphMapBd: cannot create band graph"); return (1); } bndvertancnnd = bndgrafdat.s.vertnnd - domnnbr; for (domnnum = 0; domnnum < domnnbr; domnnum ++) { /* For all anchor domains */ Gnum vertnum; vertnum = bndvertancnnd + domnnum; if (((bndgrafdat.s.verttax[vertnum + 1] - bndgrafdat.s.verttax[vertnum]) == 0) && (vertnbrtab[domnnum] != 0)) break; } memFree (vertnbrtab); if (domnnum != domnnbr) { /* If graph is too small to have any usable anchors, apply org strategy */ memFree (bandvnumtax + bndgrafdat.s.baseval); memFree (bndgrafdat.m.parttax + bndgrafdat.s.baseval); kgraphExit (&bndgrafdat); return (kgraphMapSt (orggrafptr, paraptr->stratorg)); } if (kgraphMapSt (&bndgrafdat, paraptr->stratbnd) != 0) { /* Partition band graph */ errorPrint ("kgraphMapBd: cannot partition band graph"); kgraphExit (&bndgrafdat); return (1); } if (bndgrafdat.m.domnnbr != orggrafptr->m.domnnbr) { errorPrint ("kgraphMapBd: change in band graph number of parts not supported"); kgraphExit (&bndgrafdat); return (1); } memCpy (orggrafptr->comploaddlt, bndgrafdat.comploaddlt, domnnbr * sizeof (Gnum)); /* Propagate back imbalance information */ for (bndvertnum = bndgrafdat.s.baseval; bndvertnum < bndvertancnnd; bndvertnum ++) /* Update part array of all vertices except anchors */ orgparttax[bandvnumtax[bndvertnum]] = bndgrafdat.m.parttax[bndvertnum]; commload = 0; for (bndvertnum = bndgrafdat.s.baseval; bndvertnum < bndvertlvlnum; bndvertnum ++) { /* For all vertices of band graph save for last layer */ Gnum bndedgenum; Gnum bndedgennd; Anum bndpartval; Anum bndpartlst; /* Part of last vertex for which a distance was computed */ Anum bnddistlst; /* Last distance computed */ int bndflagval; bndpartval = bndgrafdat.m.parttax[bndvertnum]; bndpartlst = -1; /* Invalid part to recompute distance */ bnddistlst = -1; /* To prevent compiler from yielding */ bndflagval = 0; for (bndedgenum = bndgrafdat.s.verttax[bndvertnum], bndedgennd = bndgrafdat.s.vendtax[bndvertnum]; bndedgenum < bndedgennd; bndedgenum ++) { Gnum bndpartend; bndpartend = bndgrafdat.m.parttax[bndgrafdat.s.edgetax[bndedgenum]]; if (bndpartval != bndpartend) { /* TODO maybe can be optimized */ Anum bnddistval; bndflagval |= 1; bnddistval = (bndpartend != bndpartlst) ? archDomDist (archptr, &bndgrafdat.m.domntab[bndpartval], &bndgrafdat.m.domntab[bndpartend]) : bnddistlst; bndpartlst = bndpartend; bnddistlst = bnddistval; commload += (Gnum) bnddistval * ((bndgrafdat.s.edlotax != NULL) ? bndgrafdat.s.edlotax[bndedgenum] : 1); } } } for ( ; bndvertnum < bndvertancnnd; bndvertnum ++) { /* For all vertices of last layer, remove communication loads to band vertices once */ Gnum bndedgenum; Gnum bndedgennd; Anum bndpartval; Anum bndpartlst; /* Part of last vertex for which a distance was computed */ Anum bnddistlst; /* Last distance computed */ int bndflagval; bndpartval = bndgrafdat.m.parttax[bndvertnum]; bndpartlst = -1; /* Invalid part to recompute distance */ bnddistlst = -1; /* To prevent compiler from yielding */ bndflagval = 0; for (bndedgenum = bndgrafdat.s.verttax[bndvertnum], bndedgennd = bndgrafdat.s.vendtax[bndvertnum] - 1; /* "-1" to avoid anchor edges */ bndedgenum < bndedgennd; bndedgenum ++) { Gnum bndpartend; bndpartend = bndgrafdat.m.parttax[bndgrafdat.s.edgetax[bndedgenum]]; if (bndpartval != bndpartend) { Anum bnddistval; bndflagval |= 1; bnddistval = (bndpartend != bndpartlst) ? archDomDist (archptr, &bndgrafdat.m.domntab[bndpartval], &bndgrafdat.m.domntab[bndpartend]) : bnddistlst; bndpartlst = bndpartend; bnddistlst = bnddistval; commload -= (Gnum) bnddistval * ((bndgrafdat.s.edlotax != NULL) ? bndgrafdat.s.edlotax[bndedgenum] : 1); /* Remove communication loads to band graph vertices once because afterwards they will be accounted for twice */ } } } if ((orgflagtab = memAlloc (kgraphMapBdFlagSize (orggrafptr->s.vertnnd) * sizeof (int))) == NULL) { errorPrint ("kgraphMapBd: out of memory (2)"); return (1); } memSet (orgflagtab, 0, kgraphMapBdFlagSize (orggrafptr->s.vertnnd) * sizeof (int)); /* Set vertices as not already considered */ orgfronnum = 0; commload2 = 0; for (bndvertnum = bndgrafdat.s.baseval; bndvertnum < bndvertancnnd; bndvertnum ++) { /* For all vertices */ Gnum orgedgenum; Gnum orgedgennd; Gnum orgvertnum; Anum orgpartval; int orgflagval; orgvertnum = bandvnumtax[bndvertnum]; orgpartval = bndgrafdat.m.parttax[bndvertnum]; orgflagval = 0; /* Assume vertex does not belong to the frontier */ for (orgedgenum = orggrafptr->s.verttax[orgvertnum], orgedgennd = orggrafptr->s.vendtax[orgvertnum]; orgedgenum < orgedgennd; orgedgenum ++) { Gnum orgvertend; Gnum orgpartend; Anum orgdistval; orgvertend = orggrafptr->s.edgetax[orgedgenum]; orgpartend = orgparttax[orgvertend]; orgdistval = archDomDist (orggrafptr->m.archptr, &orggrafptr->m.domntab[orgpartval], &orggrafptr->m.domntab[orgpartend]); if (orgpartval != orgpartend) { orgflagval = 1; commload2 += ((orggrafptr->s.edlotax != NULL) ? orggrafptr->s.edlotax[orgedgenum] : 1) * orgdistval; /* Internal load to band and original graph vertices are accounted for twice */ if ((orgvertend < orggrafptr->s.vertnnd) && (kgraphMapBdFlagVal (orgflagtab, orgvertend) == 0)) { orgfrontab[orgfronnum ++] = orgvertend; kgraphMapBdFlagSet (orgflagtab, orgvertend); } } } if ((orgflagval != 0) && (kgraphMapBdFlagVal (orgflagtab, orgvertnum) == 0)) orgfrontab[orgfronnum ++] = orgvertnum; kgraphMapBdFlagSet (orgflagtab, orgvertnum); /* Set vertex as processed anyway */ } commload += 2 * commload2; /* Add twice the communication load of original graph edges and once the one of band edges (one removed before) */ if (orggrafptr->pfixtax != NULL) { /* Add fixed vertices with fixed neighbours only in the frontier array */ Gnum vertnum; for (vertnum = orggrafptr->s.baseval; vertnum < orggrafptr->s.vertnnd; vertnum ++) { Gnum partval; Gnum edgenum; if ((orggrafptr->pfixtax[vertnum] == -1) || /* If it is not a fixed vertex */ (kgraphMapBdFlagVal (orgflagtab, vertnum) != 0)) /* Or has already been processed */ continue; /* Skip it */ partval = orggrafptr->m.parttax[vertnum]; for (edgenum = orggrafptr->s.verttax[vertnum]; edgenum < orggrafptr->s.vendtax[vertnum]; edgenum ++) { if (orggrafptr->m.parttax[orggrafptr->s.edgetax[edgenum]] != partval) { /* If first vertex belongs to frontier */ orggrafptr->frontab[orgfronnum] = vertnum; orgfronnum ++; break; } } } } orggrafptr->fronnbr = orgfronnum; orggrafptr->commload = commload / 2; memFree (orgflagtab); memFree (bandvnumtax + bndgrafdat.s.baseval); memFree (bndgrafdat.m.parttax + bndgrafdat.s.baseval); kgraphCost (orggrafptr); #ifdef SCOTCH_DEBUG_KGRAPH2 if (kgraphCheck (orggrafptr) != 0) { errorPrint ("kgraphMapBd: internal error"); kgraphExit (&bndgrafdat); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ kgraphExit (&bndgrafdat); return (0); } scotch-6.0.4.dfsg/src/libscotch/vgraph_separate_gg.h0000644002563400244210000000777311631447171025656 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vgraph_separate_gg.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the greedy graph growing vertex **/ /** separation method. **/ /** **/ /** DATES : # Version 3.2 : from : 14 nov 1997 **/ /** to 15 jul 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 4.0 : from : 19 dec 2001 **/ /** to 09 jan 2004 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ System-defined constants. +*/ #define VGRAPHSEPAGGSUBBITS 4 #define VGRAPHSEPAGGSTATEPART0 ((GainLink *) 0) /*+ Vertex in part 0 (initial state) +*/ #define VGRAPHSEPAGGSTATEPART1 ((GainLink *) 1) /*+ Vertex in part 1 +*/ #define VGRAPHSEPAGGSTATEPART2 ((GainLink *) 2) /*+ Vertex in part 2, chained +*/ #define VGRAPHSEPAGGSTATELINK ((GainLink *) 3) /*+ Currently in gain table if higher +*/ /* ** The type and structure definitions. */ /*+ Method parameters. +*/ typedef struct VgraphSeparateGgParam_ { INT passnbr; /*+ Number of passes to do +*/ } VgraphSeparateGgParam; /*+ The complementary vertex structure. For trick reasons, the gain table data structure must be the first field of the structure. +*/ typedef struct VgraphSeparateGgVertex_ { GainLink gainlink; /*+ Gain link: FIRST +*/ Gnum compgain2; /*+ Computation gain in separator +*/ } VgraphSeparateGgVertex; /* ** The function prototypes. */ #ifndef VGRAPH_SEPARATE_GG #define static #endif int vgraphSeparateGg (Vgraph * restrict const, const VgraphSeparateGgParam * restrict const); #undef static scotch-6.0.4.dfsg/src/libscotch/arch_vhcub.c0000644002563400244210000002066212377070515024117 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : arch_vhcub.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module handles the variable-sized **/ /** hypercube target architecture. **/ /** **/ /** DATES : # Version 3.4 : from : 08 nov 2001 **/ /** to 08 nov 2001 **/ /** # Version 4.0 : from : 04 nov 2003 **/ /** to 04 nov 2003 **/ /** # Version 5.1 : from : 21 jan 2008 **/ /** to 27 feb 2008 **/ /** # Version 6.0 : from : 14 fev 2011 **/ /** to 26 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define ARCH_VHCUB #include "module.h" #include "common.h" #include "arch.h" #include "arch_vhcub.h" /********************************/ /* */ /* These are the variable-sized */ /* hypercube handling routines. */ /* */ /********************************/ /* This function returns the smallest number ** of terminal domain included in the given ** domain. */ ArchDomNum archVhcubDomNum ( const ArchVhcub * const archptr, const ArchVhcubDom * const domptr) { return (domptr->termnum); /* Return terminal number */ } /* This function returns the terminal domain associated ** with the given terminal number in the architecture. ** It returns: ** - 0 : if label is valid and domain has been updated. ** - 1 : if label is invalid. ** - 2 : on error. */ int archVhcubDomTerm ( const ArchVhcub * const archptr, ArchVhcubDom * const domptr, const ArchDomNum domnum) { Anum termnum; Anum termlvl; if (domnum != ARCHDOMNOTTERM) { /* If valid label */ if (domnum == 0) /* Not a legal domain */ return (2); domptr->termnum = domnum; /* Set the domain */ for (termnum = domnum, termlvl = 0; termnum > 1; termnum >>= 1, termlvl ++) ; /* Compute level */ domptr->termlvl = termlvl; /* Set level */ return (0); } return (1); /* Cannot set domain */ } /* This function returns the number of ** elements in the domain. */ Anum archVhcubDomSize ( const ArchVhcub * const archptr, const ArchVhcubDom * const domptr) { return (1); /* All domains have same size for bipartitioning */ } /* This function returns the average ** distance between two subdomains. */ Anum archVhcubDomDist ( const ArchVhcub * const archptr, const ArchVhcubDom * const dom0ptr, const ArchVhcubDom * const dom1ptr) { Anum dom0num; Anum dom1num; Anum distval; if (dom0ptr->termlvl > dom1ptr->termlvl) { dom0num = dom0ptr->termnum >> (dom0ptr->termlvl - dom1ptr->termlvl); dom1num = dom1ptr->termnum; distval = (dom0ptr->termlvl - dom1ptr->termlvl) >> 1; /* One half of unknown bits */ } else { dom0num = dom0ptr->termnum; dom1num = dom1ptr->termnum >> (dom1ptr->termlvl - dom0ptr->termlvl); distval = (dom1ptr->termlvl - dom0ptr->termlvl) >> 1; /* One half of unknown bits */ } for (dom0num ^= dom1num; dom0num != 0; /* Compute Hamming distance */ distval += (dom0num & 1), dom0num >>= 1) ; return (distval); } /* This function sets the biggest ** domain available for this ** architecture. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archVhcubDomFrst ( const ArchVhcub * const archptr, ArchVhcubDom * restrict const domptr) { domptr->termlvl = 0; /* First terminal number */ domptr->termnum = 1; return (0); } /* This routine reads domain information ** from the given stream. ** It returns: ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archVhcubDomLoad ( const ArchVhcub * const archptr, ArchVhcubDom * restrict const domptr, FILE * const stream) { Anum termnum; Anum termlvl; if (intLoad (stream, &domptr->termnum) != 1) { errorPrint ("archVhcubDomLoad: bad input"); return (1); } for (termnum = domptr->termnum, termlvl = 0; termnum > 1; termnum >>= 1, termlvl ++) ; /* Compute level */ domptr->termlvl = termlvl; return (0); } /* This routine saves domain information ** to the given stream. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archVhcubDomSave ( const ArchVhcub * const archptr, const ArchVhcubDom * const domptr, FILE * const stream) { if (fprintf (stream, ANUMSTRING " ", (Anum) domptr->termnum) == EOF) { errorPrint ("archVhcubDomSave: bad output"); return (1); } return (0); } /* This function splits a domain ** into two subdomains. ** It returns: ** - 0 : if bipartitioning succeeded. ** - 2 : on error. */ int archVhcubDomBipart ( const ArchVhcub * const archptr, const ArchVhcubDom * const domptr, ArchVhcubDom * restrict const dom0ptr, ArchVhcubDom * restrict const dom1ptr) { dom0ptr->termlvl = /* Bipartition the domain */ dom1ptr->termlvl = domptr->termlvl + 1; dom0ptr->termnum = domptr->termnum << 1; dom1ptr->termnum = dom0ptr->termnum + 1; return ((dom1ptr->termnum < domptr->termnum) ? 2 : 0); /* Return error on overflow */ } /* This function checks if dom1 is ** included in dom0. ** It returns: ** - 0 : if dom1 is not included in dom0. ** - 1 : if dom1 is included in dom0. ** - 2 : on error. */ int archVhcubDomIncl ( const ArchVhcub * const archptr, const ArchVhcubDom * const dom0ptr, const ArchVhcubDom * const dom1ptr) { if ((dom1ptr->termlvl >= dom0ptr->termlvl) && ((dom1ptr->termnum >> (dom1ptr->termlvl - dom0ptr->termlvl)) == dom0ptr->termnum)) return (1); return (0); } /* This function creates the MPI_Datatype for ** variable-sized hypercube domains. ** It returns: ** - 0 : if type could be created. ** - 1 : on error. */ #ifdef SCOTCH_PTSCOTCH int archVhcubDomMpiType ( const ArchVhcub * const archptr, MPI_Datatype * const typeptr) { MPI_Type_contiguous (2, ANUM_MPI, typeptr); return (0); } #endif /* SCOTCH_PTSCOTCH */ scotch-6.0.4.dfsg/src/libscotch/bdgraph_bipart_sq.h0000644002563400244210000000605511631447170025470 0ustar trophimeutilisateurs du domaine/* Copyright 2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bdgraph_bipart_sq.h **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the sequential bipartitioning **/ /** routine for distributed graphs. **/ /** **/ /** DATES : # Version 5.1 : from : 19 nov 2007 **/ /** to : 20 nov 2007 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct BdgraphBipartSqParam_ { Strat * strat; /*+ Sequential bipartitioning strategy used +*/ } BdgraphBipartSqParam; /* ** The function prototypes. */ #ifndef BDGRAPH_BIPART_SQ #define static #endif int bdgraphBipartSq (Bdgraph * const, const BdgraphBipartSqParam * const); static void bdgraphBipartSqOpBest (const Gnum * const, Gnum * const, const int * const, const MPI_Datatype * const); #undef static scotch-6.0.4.dfsg/src/libscotch/library_dgraph_order_gather.c0000644002563400244210000001546412055777275027547 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_order_gather.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the distri- **/ /** buted ordering gathering routines of **/ /** the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 21 jul 2007 **/ /** to 04 aug 2007 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "dgraph.h" #include "order.h" #include "dorder.h" #include "library_order.h" #include "ptscotch.h" /************************************/ /* */ /* These routines are the C API for */ /* the distributed ordering */ /* handling routines. */ /* */ /************************************/ /*+ This routine initializes an API centralized *** ordering with respect to the given distributed *** source graph and the locations of output parameters. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_dgraphCorderInit ( const SCOTCH_Dgraph * const grafptr, /*+ Distributed graph to order +*/ SCOTCH_Ordering * const cordptr, /*+ Ordering structure to initialize +*/ SCOTCH_Num * const permtab, /*+ Direct permutation array +*/ SCOTCH_Num * const peritab, /*+ Inverse permutation array +*/ SCOTCH_Num * const cblkptr, /*+ Pointer to number of column blocks +*/ SCOTCH_Num * const rangtab, /*+ Column block range array +*/ SCOTCH_Num * const treetab) /*+ Separator tree array +*/ { Dgraph * srcgrafptr; LibOrder * libcordptr; #ifdef SCOTCH_DEBUG_LIBRARY1 if (sizeof (SCOTCH_Ordering) < sizeof (LibOrder)) { errorPrint ("SCOTCH_dgraphCorderInit: internal error"); return (1); } #endif /* SCOTCH_DEBUG_LIBRARY1 */ srcgrafptr = (Dgraph *) grafptr; /* Use structure as distributed source graph */ libcordptr = (LibOrder *) cordptr; libcordptr->permtab = ((permtab == NULL) || ((void *) permtab == (void *) grafptr)) ? NULL : (Gnum *) permtab; libcordptr->peritab = ((peritab == NULL) || ((void *) peritab == (void *) grafptr)) ? NULL : (Gnum *) peritab; libcordptr->cblkptr = ((cblkptr == NULL) || ((void *) cblkptr == (void *) grafptr)) ? NULL : (Gnum *) cblkptr; libcordptr->rangtab = ((rangtab == NULL) || ((void *) rangtab == (void *) grafptr)) ? NULL : (Gnum *) rangtab; libcordptr->treetab = ((treetab == NULL) || ((void *) treetab == (void *) grafptr)) ? NULL : (Gnum *) treetab; return (orderInit (&libcordptr->o, srcgrafptr->baseval, srcgrafptr->vertglbnbr, libcordptr->peritab)); } /*+ This routine frees an API centralized ordering. *** It returns: *** - VOID : in all cases. +*/ void SCOTCH_dgraphCorderExit ( const SCOTCH_Dgraph * const grafptr, SCOTCH_Ordering * const cordptr) { orderExit (&((LibOrder *) cordptr)->o); } /*+ This routine gathers the contents of *** the given distributed ordering into the *** given centralized ordering. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_dgraphOrderGather ( const SCOTCH_Dgraph * const grafptr, /*+ Not used +*/ const SCOTCH_Dordering * const dordptr, /*+ Distributed ordering +*/ SCOTCH_Ordering * const cordptr) /*+ Centralized ordering +*/ { LibOrder * libcordptr; /* Pointer to ordering */ if ((cordptr != NULL) && ((void *) cordptr != (void *) dordptr)) { /* If potential root process */ libcordptr = (LibOrder *) cordptr; /* Get centralized ordering */ if (dorderGather ((Dorder *) dordptr, &libcordptr->o) != 0) return (1); if (libcordptr->permtab != NULL) /* Build direct permutation if wanted */ orderPeri (libcordptr->o.peritab, libcordptr->o.baseval, libcordptr->o.vnodnbr, libcordptr->permtab, libcordptr->o.baseval); if (libcordptr->rangtab != NULL) /* Build range array if column block data wanted */ orderRang (&libcordptr->o, libcordptr->rangtab); if (libcordptr->treetab != NULL) /* Build separator tree array if wanted */ orderTree (&libcordptr->o, libcordptr->treetab); if (libcordptr->cblkptr != NULL) /* Set number of column blocks if wanted */ *(libcordptr->cblkptr) = libcordptr->o.cblknbr; return (0); } else return (dorderGather ((Dorder *) dordptr, NULL)); } scotch-6.0.4.dfsg/src/libscotch/kgraph_band.h0000644002563400244210000000600212405517777024260 0ustar trophimeutilisateurs du domaine/* Copyright 2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph_band.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the k-way band graph extraction **/ /** routine. **/ /** **/ /** DATES : # Version 6.0 : from : 15 sep 2014 **/ /** to 15 sep 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ Prime number for hashing terminal domain numbers. +*/ #define KGRAPHBANDHASHPRIME 17 /*+ Prime number for hashing +*/ /* ** The type and structure definitions. */ /*+ Hash structure for linking fixed vertex domains with non-fixed vertex domains. +*/ typedef struct KgraphBandHash_ { Anum termnum; /*+ Terminal domain number +*/ Anum domnnum; /*+ Domain number in domain array +*/ } KgraphBandHash; scotch-6.0.4.dfsg/src/libscotch/graph_io_mmkt.h0000644002563400244210000000523311631447170024632 0ustar trophimeutilisateurs du domaine/* Copyright 2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : graph_io_mmkt.h **/ /** **/ /** AUTHORS : Cedric CHEVALIER (v5.0) **/ /** Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the Input routines **/ /** for handling the Matrix Market format. **/ /** **/ /** DATES : # Version 5.0 : from : 17 jan 2008 **/ /** to : 14 mar 2008 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /* Structure representing edges to symmetrize. */ typedef struct GraphGeomMmktEdge_ { Gnum vertnum[2]; } GraphGeomMmktEdge; scotch-6.0.4.dfsg/src/libscotch/arch_tleaf.h0000644002563400244210000001777512354533106024116 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : arch_tleaf.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the tree-leaf pseudo-graph target **/ /** architecture functions. **/ /** **/ /** DATES : # Version 0.0 : from : 01 dec 1992 **/ /** to : 24 mar 1993 **/ /** # Version 1.2 : from : 04 feb 1994 **/ /** to : 11 feb 1994 **/ /** # Version 1.3 : from : 20 apr 1994 **/ /** to : 20 apr 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to : 12 nov 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to : 30 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 16 aug 1995 **/ /** # Version 3.1 : from : 20 jul 1996 **/ /** to 23 jul 1996 **/ /** # Version 3.2 : from : 10 oct 1996 **/ /** to 14 may 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 4.0 : from : 10 dec 2003 **/ /** to 10 dec 2003 **/ /** # Version 5.1 : from : 21 jan 2008 **/ /** to 24 jun 2010 **/ /** # Version 6.0 : from : 14 fev 2011 **/ /** to 03 jul 2014 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ #ifndef ARCH_TLEAF_H_STRUCT #define ARCH_TLEAF_H_STRUCT /** The Tree-Leaf graph definitions. **/ typedef struct ArchTleaf_ { Anum termnbr; /*+ Number of terminal domains in architecture +*/ Anum levlnbr; /*+ Number of levels +*/ Anum * sizetab; /*+ Array of cluster sizes, per descending level +*/ Anum * linktab; /*+ Value of extra-cluster link costs +*/ Anum permnbr; /*+ Number of label permutation indices +*/ Anum * permtab; /*+ Label permutation array +*/ Anum * peritab; /*+ Invertse label permutation array +*/ } ArchTleaf; typedef struct ArchTleafDom_ { Anum levlnum; /*+ Current block level +*/ Anum indxmin; /*+ Minimum index in level +*/ Anum indxnbr; /*+ Number of indices in domain +*/ } ArchTleafDom; #endif /* ARCH_TLEAF_H_STRUCT */ /* ** The function prototypes. */ #ifndef ARCH_NOPROTO #ifndef ARCH_TLEAF_H_PROTO #define ARCH_TLEAF_H_PROTO #ifndef ARCH_TLEAF #define static #endif int archTleafArchLoad (ArchTleaf * restrict const, FILE * restrict const); int archTleafArchFree (ArchTleaf * restrict const); int archTleafArchSave (const ArchTleaf * const, FILE * restrict const); ArchDomNum archTleafDomNum (const ArchTleaf * const, const ArchTleafDom * const); int archTleafDomTerm (const ArchTleaf * const, ArchTleafDom * restrict const, const ArchDomNum); Anum archTleafDomSize (const ArchTleaf * const, const ArchTleafDom * const); #define archTleafDomWght archTleafDomSize Anum archTleafDomDist (const ArchTleaf * const, const ArchTleafDom * const, const ArchTleafDom * const); int archTleafDomFrst (const ArchTleaf * const, ArchTleafDom * restrict const); int archTleafDomLoad (const ArchTleaf * const, ArchTleafDom * restrict const, FILE * restrict const); int archTleafDomSave (const ArchTleaf * const, const ArchTleafDom * const, FILE * restrict const); int archTleafDomBipart (const ArchTleaf * const, const ArchTleafDom * const, ArchTleafDom * restrict const, ArchTleafDom * restrict const); int archTleafDomIncl (const ArchTleaf * const, const ArchTleafDom * const, const ArchTleafDom * const); #ifdef SCOTCH_PTSCOTCH int archTleafDomMpiType (const ArchTleaf * const, MPI_Datatype * const); #endif /* SCOTCH_PTSCOTCH */ int archLtleafArchLoad (ArchTleaf * restrict const, FILE * restrict const); int archLtleafArchSave (const ArchTleaf * const, FILE * restrict const); ArchDomNum archLtleafDomNum (const ArchTleaf * const, const ArchTleafDom * const); int archLtleafDomTerm (const ArchTleaf * const, ArchTleafDom * restrict const, const ArchDomNum); #define archLtleafDomWght archLtleafDomSize #undef static /* ** The macro definitions. */ #define ArchLtleaf ArchTleaf #define ArchLtleafDom ArchTleafDom #define archLtleafArchFree archTleafArchFree #define archLtleafDomSize archTleafDomSize #define archLtleafDomDist archTleafDomDist #define archLtleafDomFrst archTleafDomFrst #define archLtleafDomLoad archTleafDomLoad #define archLtleafDomSave archTleafDomSave #define archLtleafDomBipart archTleafDomBipart #define archLtleafDomIncl archTleafDomIncl #define archLtleafDomMpiType archTleafDomMpiType #endif /* ARCH_TLEAF_H_PROTO */ #endif /* ARCH_NOPROTO */ scotch-6.0.4.dfsg/src/libscotch/hdgraph_fold.c0000644002563400244210000012345711631447171024440 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hdgraph_fold.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles the halo distribu- **/ /** ted graph folding function. **/ /** **/ /** DATES : # Version 5.0 : from : 23 apr 2006 **/ /** to : 10 sep 2007 **/ /** # Version 5.1 : from : 27 jun 2008 **/ /** to : 04 jan 2011 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HDGRAPH #include "module.h" #include "common.h" #include "dgraph.h" #include "dgraph_fold_comm.h" #include "hdgraph.h" #include "hdgraph_fold.h" /******************************/ /* */ /* These routines handle halo */ /* distributed source graphs. */ /* */ /******************************/ /* This routine builds a folded graph by ** merging graph data to the processes of ** the first half or to the second half ** of the communicator. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int hdgraphFold ( const Hdgraph * restrict const orggrafptr, const int partval, /* 0 for first half, 1 for second half */ Hdgraph * restrict const fldgrafptr) { int fldprocglbnbr; int fldproclocnum; /* Index of local process in folded communicator */ int fldproccol; /* Color of receiver or not wanted in communicator */ MPI_Comm fldproccomm; /* Communicator of folded part */ fldprocglbnbr = (orggrafptr->s.procglbnbr + 1) / 2; if (partval == 1) { fldproclocnum = orggrafptr->s.proclocnum - fldprocglbnbr; fldprocglbnbr = orggrafptr->s.procglbnbr - fldprocglbnbr; } else fldproclocnum = orggrafptr->s.proclocnum; fldproccol = ((fldproclocnum >= 0) && (fldproclocnum < fldprocglbnbr)) ? 0 : MPI_UNDEFINED; if (MPI_Comm_split (orggrafptr->s.proccomm, fldproccol, fldproclocnum, &fldproccomm) != MPI_SUCCESS) { errorPrint ("hdgraphFold: communication error"); return (1); } return (hdgraphFold2 (orggrafptr, partval, fldgrafptr, fldproccomm)); } int hdgraphFold2 ( const Hdgraph * restrict const orggrafptr, const int partval, /* 0 for first half, 1 for second half */ Hdgraph * restrict const fldgrafptr, MPI_Comm fldproccomm) /* Pre-computed communicator */ { int fldcommtypval; /* Type of communication for this process */ DgraphFoldCommData * restrict fldcommdattab; /* Array of two communication data */ Gnum * restrict fldcommvrttab; /* Starting global send indices of communications */ Gnum * restrict fldvertidxtab; /* Start indices of vertex arrays */ Gnum * restrict fldvendidxtab; /* Adjustment value for end vertex arrays */ Gnum * restrict fldedgeidxtab; /* Start indices of edge arrays */ Gnum * restrict fldedgecnttab; /* Number of edges exchanged during each communication */ Gnum fldvertlocnbr; /* Number of vertices in local folded part */ Gnum fldedgelocsiz; /* (Upper bound of) number of edges in folded graph */ int fldprocglbnbr; int fldproclocnum; /* Index of local process in folded communicator */ int fldvertadjnbr; Gnum * restrict fldvertadjtab; /* Array of index adjustments for original vertices */ Gnum * restrict fldvertdlttab; /* Array of index adjustments for original vertices */ Gnum * restrict fldvhalloctax; /* Index array for remote halo vertex renumbering */ int cheklocval; int chekglbval; int commmax; int commnbr; int requnbr; MPI_Request * restrict requtab; #ifdef SCOTCH_DEBUG_HDGRAPH2 if (orggrafptr->vhndloctax != (orggrafptr->s.vertloctax + 1)) { errorPrint ("hdgraphFold2: halo graph must be compact"); return (1); } if (orggrafptr->s.vendloctax < (orggrafptr->s.vertloctax + orggrafptr->s.vertlocnbr)) { /* MPI_Isend calls should not overlap */ errorPrint ("hdgraphFold2: halo graph must have distinct arrays"); return (1); } #endif /* SCOTCH_DEBUG_HDGRAPH2 */ fldprocglbnbr = (orggrafptr->s.procglbnbr + 1) / 2; if (partval == 1) { fldproclocnum = orggrafptr->s.proclocnum - fldprocglbnbr; fldprocglbnbr = orggrafptr->s.procglbnbr - fldprocglbnbr; } else fldproclocnum = orggrafptr->s.proclocnum; fldcommtypval = ((fldproclocnum >= 0) && (fldproclocnum < fldprocglbnbr)) ? DGRAPHFOLDCOMMRECV : DGRAPHFOLDCOMMSEND; cheklocval = 0; fldvertidxtab = NULL; fldcommdattab = NULL; if (fldcommtypval == DGRAPHFOLDCOMMRECV) { /* If we are going to receive */ #ifdef SCOTCH_DEBUG_HDGRAPH2 if (fldgrafptr == NULL) { errorPrint ("hdgraphFold2: invalid parameters (1)"); return (1); } if (fldproccomm == MPI_COMM_NULL) { errorPrint ("hdgraphFold2: invalid parameters (2)"); return (1); } #endif /* SCOTCH_DEBUG_HDGRAPH2 */ memSet (fldgrafptr, 0, sizeof (Hdgraph)); /* Pre-initialize graph fields */ fldgrafptr->s.proccomm = fldproccomm; fldgrafptr->s.procglbnbr = fldprocglbnbr; fldgrafptr->s.proclocnum = fldproclocnum; fldgrafptr->s.flagval = DGRAPHFREEALL | DGRAPHVERTGROUP | DGRAPHEDGEGROUP; /* For premature freeing on error; do not free vhndloctab as it is grouped with vertloctab */ if (memAllocGroup ((void **) (void *) /* Allocate distributed graph private data */ &fldgrafptr->s.procdsptab, (size_t) ((fldprocglbnbr + 1) * sizeof (Gnum)), &fldgrafptr->s.proccnttab, (size_t) (fldprocglbnbr * sizeof (Gnum)), &fldgrafptr->s.procngbtab, (size_t) (fldprocglbnbr * sizeof (int)), &fldgrafptr->s.procrcvtab, (size_t) (fldprocglbnbr * sizeof (int)), &fldgrafptr->s.procsndtab, (size_t) (fldprocglbnbr * sizeof (int)), NULL) == NULL) { errorPrint ("hdgraphFold2: out of memory (1)"); cheklocval = 1; } else if (dgraphFoldComm (&orggrafptr->s, partval, &commmax, &fldcommtypval, &fldcommdattab, &fldcommvrttab, /* Process can become a sender receiver */ fldgrafptr->s.proccnttab, &fldvertadjnbr, &fldvertadjtab, &fldvertdlttab) != 0) { errorPrint ("hdgraphFold2: cannot compute folding communications (1)"); cheklocval = 1; } else { Gnum fldvelolocnbr; if ((fldcommtypval & DGRAPHFOLDCOMMSEND) == 0) { /* If process is a normal receiver */ int i; for (i = 0, fldvertlocnbr = orggrafptr->s.vertlocnbr; (i < commmax) && (fldcommdattab[i].procnum != -1); i ++) fldvertlocnbr += fldcommdattab[i].vertnbr; commnbr = i; fldedgelocsiz = orggrafptr->s.edgelocsiz + orggrafptr->s.edgeglbsmx * i; /* Upper bound on local edges (degree useless since only for non-halo vertices) */ } else { /* Process is a sender receiver */ fldvertlocnbr = fldcommvrttab[0] - orggrafptr->s.procvrttab[orggrafptr->s.proclocnum]; /* Communications will remove vertices */ fldedgelocsiz = orggrafptr->s.vertloctax[fldvertlocnbr + orggrafptr->s.baseval] - orggrafptr->s.baseval; /* Exact number of edges */ fldgrafptr->s.edgelocsiz = fldedgelocsiz; } fldvelolocnbr = (orggrafptr->s.veloloctax != NULL) ? fldvertlocnbr : 0; if (memAllocGroup ((void **) (void *) /* Allocate distributed graph public data */ &fldgrafptr->s.vertloctax, (size_t) ((fldvertlocnbr + 1) * sizeof (Gnum)), &fldgrafptr->s.vendloctax, (size_t) ( fldvertlocnbr * sizeof (Gnum)), /* Vertex end array for non-halo vertices */ &fldgrafptr->s.vnumloctax, (size_t) ( fldvertlocnbr * sizeof (Gnum)), &fldgrafptr->s.veloloctax, (size_t) ( fldvelolocnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("hdgraphFold2: out of memory (2)"); cheklocval = 1; } else if (fldgrafptr->s.vertloctax -= orggrafptr->s.baseval, fldgrafptr->s.vendloctax -= orggrafptr->s.baseval, fldgrafptr->s.vnumloctax -= orggrafptr->s.baseval, fldgrafptr->s.veloloctax = ((orggrafptr->s.veloloctax != NULL) ? fldgrafptr->s.veloloctax - orggrafptr->s.baseval : NULL), memAllocGroup ((void **) (void *) &fldgrafptr->s.edgeloctax, (size_t) (fldedgelocsiz * sizeof (Gnum)), &fldvhalloctax, (size_t) (orggrafptr->s.edgeglbsmx * sizeof (Gnum)), NULL) == NULL) { errorPrint ("hdgraphFold2: out of memory (3)"); cheklocval = 1; } else { fldgrafptr->s.edgeloctax -= orggrafptr->s.baseval; fldvhalloctax -= orggrafptr->s.baseval; } } } else { /* Process is a sender */ #ifdef SCOTCH_DEBUG_HDGRAPH2 if (fldproccomm != MPI_COMM_NULL) { errorPrint ("hdgraphFold2: invalid parameters (3)"); return (1); } #endif /* SCOTCH_DEBUG_HDGRAPH2 */ if (dgraphFoldComm (&orggrafptr->s, partval, &commmax, &fldcommtypval, &fldcommdattab, &fldcommvrttab, NULL, NULL, NULL, NULL) != 0) { errorPrint ("hdgraphFold2: cannot compute folding communications (2)"); cheklocval = 1; } } if ((cheklocval == 0) && (memAllocGroup ((void **) (void *) /* Allocate folding data */ &fldvertidxtab, (size_t) (commmax * sizeof (Gnum)), &fldvendidxtab, (size_t) (commmax * sizeof (Gnum)), &fldedgeidxtab, (size_t) (commmax * sizeof (Gnum)), &fldedgecnttab, (size_t) (commmax * sizeof (Gnum)), &requtab, (size_t) (commmax * HDGRAPHFOLDTAGNBR * sizeof (MPI_Request)), NULL) == NULL)) { errorPrint ("hdgraphFold2: out of memory (4)"); cheklocval = 1; } #ifdef SCOTCH_DEBUG_HDGRAPH1 /* Communication cannot be merged with a useful one */ if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, orggrafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("hdgraphFold2: communication error (1)"); chekglbval = 1; } #else /* SCOTCH_DEBUG_HDGRAPH1 */ chekglbval = cheklocval; #endif /* SCOTCH_DEBUG_HDGRAPH1 */ if (chekglbval != 0) { if ((fldcommtypval & DGRAPHFOLDCOMMRECV) != 0) { hdgraphExit (fldgrafptr); if (fldvertidxtab != NULL) memFree (fldvertidxtab); /* Free group leaders */ if (fldcommdattab != NULL) memFree (fldcommdattab); } return (1); } requnbr = 0; /* Communications without further processing are placed at beginning of array */ if ((fldcommtypval & DGRAPHFOLDCOMMSEND) != 0) { /* If process is (also) a sender */ Gnum vertsndbas; Gnum vertsndnbr; int i; vertsndnbr = ((fldcommtypval & DGRAPHFOLDCOMMRECV) != 0) ? (fldcommvrttab[0] - orggrafptr->s.procvrttab[orggrafptr->s.proclocnum]) : 0; /* If process is also a receiver, start sending after kept vertices */ for (i = 0, requnbr = 0, vertsndbas = orggrafptr->s.baseval; /* For all send communications to perform */ (i < commmax) && (fldcommdattab[i].procnum != -1); i ++) { Gnum edgelocsiz; vertsndbas += vertsndnbr; vertsndnbr = fldcommdattab[i].vertnbr; edgelocsiz = orggrafptr->s.vertloctax[vertsndbas + vertsndnbr] - orggrafptr->s.vertloctax[vertsndbas]; /* Graph is compact */ fldvertidxtab[i] = vertsndbas; fldedgeidxtab[i] = orggrafptr->s.vertloctax[vertsndbas]; fldedgecnttab[i] = edgelocsiz; if (MPI_Isend (&edgelocsiz, 1, GNUM_MPI, fldcommdattab[i].procnum, TAGFOLD + TAGVLBLLOCTAB, orggrafptr->s.proccomm, &requtab[requnbr ++]) != MPI_SUCCESS) { errorPrint ("hdgraphFold2: communication error (2)"); cheklocval = 1; } } commnbr = i; for (i = 0; (i < commnbr) && (cheklocval == 0); i ++) { if (MPI_Isend (orggrafptr->s.vertloctax + fldvertidxtab[i], fldcommdattab[i].vertnbr, GNUM_MPI, fldcommdattab[i].procnum, TAGFOLD + TAGVERTLOCTAB, orggrafptr->s.proccomm, &requtab[requnbr ++]) != MPI_SUCCESS) { errorPrint ("hdgraphFold2: communication error (3)"); cheklocval = 1; } } for (i = 0; (i < commnbr) && (cheklocval == 0); i ++) { if (MPI_Isend (orggrafptr->s.vendloctax + fldvertidxtab[i], fldcommdattab[i].vertnbr, GNUM_MPI, fldcommdattab[i].procnum, TAGFOLD + TAGVENDLOCTAB, orggrafptr->s.proccomm, &requtab[requnbr ++]) != MPI_SUCCESS) { errorPrint ("hdgraphFold2: communication error (4)"); cheklocval = 1; } } for (i = 0; (i < commnbr) && (cheklocval == 0); i ++) { if (MPI_Isend (orggrafptr->s.edgeloctax + fldedgeidxtab[i], fldedgecnttab[i], GNUM_MPI, fldcommdattab[i].procnum, TAGFOLD + TAGEDGELOCTAB, orggrafptr->s.proccomm, &requtab[requnbr ++]) != MPI_SUCCESS) { errorPrint ("hdgraphFold2: communication error (5)"); cheklocval = 1; } } for (i = 0; (i < commnbr) && (cheklocval == 0); i ++) { Gnum vertsndbas; int vertsndnbr; int procsndnum; /* Rank of process to send to */ vertsndbas = fldvertidxtab[i]; vertsndnbr = (int) fldcommdattab[i].vertnbr; procsndnum = (int) fldcommdattab[i].procnum; if ((orggrafptr->s.veloloctax != NULL) && (MPI_Isend (orggrafptr->s.veloloctax + vertsndbas, vertsndnbr, GNUM_MPI, procsndnum, TAGFOLD + TAGVELOLOCTAB, orggrafptr->s.proccomm, &requtab[requnbr ++]) != MPI_SUCCESS)) { errorPrint ("hdgraphFold2: communication error (6)"); cheklocval = 1; } else if ((orggrafptr->s.vnumloctax != NULL) && (MPI_Isend (orggrafptr->s.vnumloctax + vertsndbas, vertsndnbr, GNUM_MPI, procsndnum, TAGFOLD + TAGVNUMLOCTAB, orggrafptr->s.proccomm, &requtab[requnbr ++]) != MPI_SUCCESS)) { errorPrint ("hdgraphFold2: communication error (7)"); cheklocval = 1; } } /* Communications of sender-receivers will be completed in the receiving phase */ } if ((fldcommtypval & DGRAPHFOLDCOMMRECV) != 0) { /* If process is (also) a receiver */ Gnum orgvertlocnbr; Gnum orgvertlocnnd; Gnum fldvertlocadj; Gnum fldvelolocsum; Gnum fldedgelocnum; Gnum fldvhallocnum; Gnum fldehallocnbr; int fldprocnum; int i; const Gnum * restrict const orgvertloctax = orggrafptr->s.vertloctax; const Gnum * restrict const orgvendloctax = orggrafptr->s.vendloctax; const Gnum * restrict const orgedgeloctax = orggrafptr->s.edgeloctax; fldgrafptr->s.procvrttab = fldgrafptr->s.procdsptab; /* Graph does not have holes */ fldgrafptr->s.procdsptab[0] = orggrafptr->s.baseval; /* Build private data of folded graph and array */ for (fldprocnum = 0; fldprocnum < fldprocglbnbr; fldprocnum ++) /* New subdomain indices start from baseval */ fldgrafptr->s.procdsptab[fldprocnum + 1] = fldgrafptr->s.procdsptab[fldprocnum] + fldgrafptr->s.proccnttab[fldprocnum]; if ((fldcommtypval & DGRAPHFOLDCOMMSEND) == 0) { /* If process is a normal receiver */ Gnum orgvertlocmin; Gnum orgvertlocmax; Gnum fldvertlocnum; Gnum fldedgelocbas; Gnum fldvertrcvbas; Gnum fldvertrcvnbr; int procngbmin; int procngbmax; Gnum * restrict const fldedgeloctax = fldgrafptr->s.edgeloctax; for (i = 0, fldvertrcvbas = orggrafptr->s.vertlocnnd, fldvertrcvnbr = 0; /* For all receive communications to perform */ (i < commnbr) && (cheklocval == 0); i ++) { fldvertrcvbas += fldvertrcvnbr; fldvertrcvnbr = fldcommdattab[i].vertnbr; fldvertidxtab[i] = fldvertrcvbas; if (MPI_Irecv (&fldedgecnttab[i], 1, GNUM_MPI, fldcommdattab[i].procnum, TAGFOLD + TAGVLBLLOCTAB, orggrafptr->s.proccomm, &requtab[HDGRAPHFOLDTAGENBR * commmax + i]) != MPI_SUCCESS) { errorPrint ("hdgraphFold2: communication error (8)"); cheklocval = 1; } } for (i = 0; (i < commnbr) && (cheklocval == 0); i ++) { /* Let these communications progress while we process the edge size messages */ if (MPI_Irecv (fldgrafptr->s.vertloctax + fldvertidxtab[i], fldcommdattab[i].vertnbr, GNUM_MPI, fldcommdattab[i].procnum, TAGFOLD + TAGVERTLOCTAB, orggrafptr->s.proccomm, &requtab[HDGRAPHFOLDTAGVERT * commmax + i]) != MPI_SUCCESS) { errorPrint ("hdgraphFold2: communication error (9)"); cheklocval = 1; } } for (i = 0; (i < commnbr) && (cheklocval == 0); i ++) { if (MPI_Irecv (fldgrafptr->s.vendloctax + fldvertidxtab[i], fldcommdattab[i].vertnbr, GNUM_MPI, fldcommdattab[i].procnum, TAGFOLD + TAGVENDLOCTAB, orggrafptr->s.proccomm, &requtab[HDGRAPHFOLDTAGVEND * commmax + i]) != MPI_SUCCESS) { errorPrint ("hdgraphFold2: communication error (10)"); cheklocval = 1; } } MPI_Waitall (commnbr, &requtab[HDGRAPHFOLDTAGENBR * commmax], MPI_STATUSES_IGNORE); for (i = 0, fldedgelocbas = orggrafptr->s.vertloctax[orggrafptr->s.vertlocnnd]; (i < commnbr) && (cheklocval == 0); i ++) { fldedgeidxtab[i] = fldedgelocbas; fldedgelocbas += fldedgecnttab[i]; if (MPI_Irecv (fldedgeloctax + fldedgeidxtab[i], fldedgecnttab[i], GNUM_MPI, fldcommdattab[i].procnum, TAGFOLD + TAGEDGELOCTAB, orggrafptr->s.proccomm, &requtab[HDGRAPHFOLDTAGEDGE * commmax + i]) != MPI_SUCCESS) { errorPrint ("hdgraphFold2: communication error (11)"); cheklocval = 1; } } fldgrafptr->s.edgelocsiz = fldedgelocbas - orggrafptr->s.baseval; /* Get number of local and halo edges */ if (orggrafptr->s.veloloctax != NULL) { for (i = 0; (i < commnbr) && (cheklocval == 0); i ++) { if (MPI_Irecv (fldgrafptr->s.veloloctax + fldvertidxtab[i], fldcommdattab[i].vertnbr, GNUM_MPI, fldcommdattab[i].procnum, TAGFOLD + TAGVELOLOCTAB, orggrafptr->s.proccomm, &requtab[HDGRAPHFOLDTAGVELO * commmax + i]) != MPI_SUCCESS) { errorPrint ("hdgraphFold2: communication error (12)"); cheklocval = 1; } } } if (orggrafptr->s.vnumloctax != NULL) { for (i = 0; (i < commnbr) && (cheklocval == 0); i ++) { if (MPI_Irecv (fldgrafptr->s.vnumloctax + fldvertidxtab[i], fldcommdattab[i].vertnbr, GNUM_MPI, fldcommdattab[i].procnum, TAGFOLD + TAGVNUMLOCTAB, orggrafptr->s.proccomm, &requtab[requnbr ++]) != MPI_SUCCESS) { errorPrint ("hdgraphFold2: communication error (13)"); cheklocval = 1; } } } orgvertlocnbr = orggrafptr->s.vertlocnbr; /* Process all local vertices */ orgvertlocnnd = orggrafptr->s.vertlocnnd; if (orggrafptr->s.vnumloctax == NULL) { /* If original graph does not have vertex numbers, create remote parts of vertex number array */ Gnum fldvertlocnum; Gnum fldvertlocadj; int i; Gnum * restrict const fldvnumloctax = fldgrafptr->s.vnumloctax; for (i = 0, fldvertlocnum = orgvertlocnnd; i < commnbr; i ++) { Gnum fldvertlocnnd; for (fldvertlocnnd = fldvertlocnum + fldcommdattab[i].vertnbr, fldvertlocadj = fldcommvrttab[i]; fldvertlocnum < fldvertlocnnd; fldvertlocnum ++) fldvnumloctax[fldvertlocnum] = fldvertlocadj ++; } } for (procngbmin = 0, procngbmax = fldvertadjnbr; /* Initialize search accelerator */ procngbmax - procngbmin > 1; ) { int procngbmed; procngbmed = (procngbmax + procngbmin) / 2; if (fldvertadjtab[procngbmed] <= orggrafptr->s.procvrttab[orggrafptr->s.proclocnum]) procngbmin = procngbmed; else procngbmax = procngbmed; } orgvertlocmin = fldvertadjtab[procngbmin]; orgvertlocmax = fldvertadjtab[procngbmax]; fldvertlocadj = fldvertdlttab[procngbmin]; for (fldvertlocnum = fldedgelocnum = orggrafptr->s.baseval; /* Adjust local part of edge array */ fldvertlocnum < orgvertlocnnd; ) { for ( ; fldedgelocnum < orgvendloctax[fldvertlocnum]; fldedgelocnum ++) { /* Reorder end vertices */ Gnum orgvertlocend; #ifdef SCOTCH_DEBUG_HDGRAPH2 if (fldedgelocnum >= (fldgrafptr->s.edgelocsiz + orggrafptr->s.baseval)) { errorPrint ("hdgraphFold2: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_HDGRAPH2 */ orgvertlocend = orgedgeloctax[fldedgelocnum]; if ((orgvertlocend >= orgvertlocmin) && /* If end vertex is local */ (orgvertlocend < orgvertlocmax)) fldedgeloctax[fldedgelocnum] = orgvertlocend + fldvertlocadj; else { /* End vertex is not local */ int procngbmin; int procngbmax; for (procngbmin = 0, procngbmax = fldvertadjnbr; procngbmax - procngbmin > 1; ) { int procngbnum; procngbnum = (procngbmax + procngbmin) / 2; if (fldvertadjtab[procngbnum] <= orgvertlocend) procngbmin = procngbnum; else procngbmax = procngbnum; } fldedgeloctax[fldedgelocnum] = orgvertlocend + fldvertdlttab[procngbmin]; } } fldvertlocnum ++; for ( ; fldedgelocnum < orgvertloctax[fldvertlocnum]; fldedgelocnum ++) { /* Copy halo part as is */ #ifdef SCOTCH_DEBUG_HDGRAPH2 if ((orgedgeloctax[fldedgelocnum] < orggrafptr->s.baseval) || (orgedgeloctax[fldedgelocnum] >= (orggrafptr->vhallocnbr + orggrafptr->s.baseval))) { errorPrint ("hdgraphFold2: internal error (2)"); return (1); } if (fldedgelocnum >= (fldgrafptr->s.edgelocsiz + orggrafptr->s.baseval)) { errorPrint ("hdgraphFold2: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_HDGRAPH2 */ fldedgeloctax[fldedgelocnum] = orgedgeloctax[fldedgelocnum]; } } fldvelolocsum = orggrafptr->s.velolocsum; /* In case there are vertex loads, we keep all of existing load */ fldehallocnbr = orggrafptr->ehallocnbr; /* Normal receivers have at least all of their local halo vertices */ fldvhallocnum = orggrafptr->vhallocnbr + orggrafptr->s.baseval; /* Index of next halo vertex number to assign */ } else { /* Receiver process is also a sender */ Gnum orgvertlocmin; Gnum orgvertlocmax; Gnum fldvertlocnum; Gnum fldvertlocadj; Gnum fldvhallocmax; /* Maximum current size of halo vertex array */ int procngbmin; int procngbmax; Gnum * restrict const fldedgeloctax = fldgrafptr->s.edgeloctax; orgvertlocnbr = fldvertlocnbr; /* Process only remaining local vertices */ orgvertlocnnd = fldvertlocnbr + orggrafptr->s.baseval; for (procngbmin = 0, procngbmax = fldvertadjnbr; /* Initialize search accelerator */ procngbmax - procngbmin > 1; ) { int procngbmed; procngbmed = (procngbmax + procngbmin) / 2; if (fldvertadjtab[procngbmed] <= orggrafptr->s.procvrttab[orggrafptr->s.proclocnum]) procngbmin = procngbmed; else procngbmax = procngbmed; } orgvertlocmin = fldvertadjtab[procngbmin]; orgvertlocmax = fldvertadjtab[procngbmax]; fldvertlocadj = fldvertdlttab[procngbmin]; fldvhallocmax = orggrafptr->s.baseval - 1; /* Reset halo vertex array for local part as halo vertices may have disappeared */ fldehallocnbr = 0; /* Recount all remaining halo vertices and edges */ fldvhallocnum = orggrafptr->s.baseval; for (fldvertlocnum = fldedgelocnum = orggrafptr->s.baseval; /* Copy remaining local part of edge array */ fldvertlocnum < orgvertlocnnd; ) { for ( ; fldedgelocnum < orgvendloctax[fldvertlocnum]; fldedgelocnum ++) { /* Reorder end vertices */ Gnum orgvertlocend; #ifdef SCOTCH_DEBUG_HDGRAPH2 if (fldedgelocnum >= (fldgrafptr->s.edgelocsiz + orggrafptr->s.baseval)) { errorPrint ("hdgraphFold2: internal error (4)"); return (1); } #endif /* SCOTCH_DEBUG_HDGRAPH2 */ orgvertlocend = orgedgeloctax[fldedgelocnum]; if ((orgvertlocend >= orgvertlocmin) && /* If end vertex is local */ (orgvertlocend < orgvertlocmax)) fldedgeloctax[fldedgelocnum] = orgvertlocend + fldvertlocadj; else { /* End vertex is not local */ int procngbnum; int procngbmax; for (procngbnum = 0, procngbmax = fldvertadjnbr; procngbmax - procngbnum > 1; ) { int procngbmed; procngbmed = (procngbmax + procngbnum) / 2; if (fldvertadjtab[procngbmed] <= orgvertlocend) procngbnum = procngbmed; else procngbmax = procngbmed; } fldedgeloctax[fldedgelocnum] = orgvertlocend + fldvertdlttab[procngbnum]; } } fldvertlocnum ++; fldehallocnbr += orgvertloctax[fldvertlocnum] - fldedgelocnum; for ( ; fldedgelocnum < orgvertloctax[fldvertlocnum]; fldedgelocnum ++) { /* Renumber halo part */ Gnum orgverthalend; Gnum fldvhallocend; orgverthalend = orgedgeloctax[fldedgelocnum]; #ifdef SCOTCH_DEBUG_HDGRAPH2 if ((orgverthalend < orggrafptr->s.baseval) || (orgverthalend >= (orggrafptr->vhallocnbr + orggrafptr->s.baseval)) || (fldedgelocnum >= (fldgrafptr->s.edgelocsiz + orggrafptr->s.baseval))) { errorPrint ("hdgraphFold2: internal error (5)"); return (1); } #endif /* SCOTCH_DEBUG_HDGRAPH2 */ while (fldvhallocmax < orgverthalend) /* Expand halo vertex index array whenever necessary */ fldvhalloctax[++ fldvhallocmax] = ~0; fldvhallocend = fldvhalloctax[orgverthalend]; /* Get renumbered halo vertex */ if (fldvhallocend < 0) { /* If new halo vertex not yet given */ fldvhallocend = /* Allocate it */ fldvhalloctax[orgverthalend] = fldvhallocnum ++; } fldedgeloctax[fldedgelocnum] = fldvhallocend; } } if (orggrafptr->s.veloloctax != NULL) { /* If original graph has vertex loads */ Gnum fldvertlocnum; for (fldvertlocnum = orggrafptr->s.baseval, fldvelolocsum = 0; /* Accumulate load sum of remaining part */ fldvertlocnum < orgvertlocnnd; fldvertlocnum ++) fldvelolocsum += orggrafptr->s.veloloctax[fldvertlocnum]; } commnbr = 0; /* Turn sender-receiver into normal receiver without any communications to perform */ } if (orggrafptr->s.veloloctax != NULL) /* If original graph has vertex loads */ memCpy (fldgrafptr->s.veloloctax + orggrafptr->s.baseval, /* Copy local part of vertex load array */ orggrafptr->s.veloloctax + orggrafptr->s.baseval, orgvertlocnbr * sizeof (Gnum)); if (orggrafptr->s.vnumloctax != NULL) /* If original graph has vertex numbers */ memCpy (fldgrafptr->s.vnumloctax + orggrafptr->s.baseval, /* Copy local part of vertex number array */ orggrafptr->s.vnumloctax + orggrafptr->s.baseval, orgvertlocnbr * sizeof (Gnum)); else { /* Build local part of vertex number array */ Gnum fldvertlocnum; Gnum fldvertlocadj; for (fldvertlocnum = orggrafptr->s.baseval, fldvertlocadj = orggrafptr->s.procvrttab[orggrafptr->s.proclocnum]; fldvertlocnum < orgvertlocnnd; fldvertlocnum ++) fldgrafptr->s.vnumloctax[fldvertlocnum] = fldvertlocadj ++; } memCpy (fldgrafptr->s.vertloctax + orggrafptr->s.baseval, /* Copy local part of vertex arrays, since they are compact */ orggrafptr->s.vertloctax + orggrafptr->s.baseval, orgvertlocnbr * sizeof (Gnum)); /* Last value not copied */ fldgrafptr->s.vertloctax[fldvertlocnbr + orggrafptr->s.baseval] = fldgrafptr->s.edgelocsiz + orggrafptr->s.baseval; memCpy (fldgrafptr->s.vendloctax + orggrafptr->s.baseval, orggrafptr->s.vendloctax + orggrafptr->s.baseval, orgvertlocnbr * sizeof (Gnum)); for (i = 0; i < commnbr; i ++) { int j; if (MPI_Waitany (commnbr, &requtab[HDGRAPHFOLDTAGVERT * commmax], &j, MPI_STATUS_IGNORE) != MPI_SUCCESS) { errorPrint ("hdgraphFold2: communication error (14)"); cheklocval = 1; } else { /* Adjust first remote part of vertex array */ Gnum fldvertlocnum; Gnum fldvertlocnnd; Gnum fldvertlocadj; Gnum * restrict const fldvertloctax = fldgrafptr->s.vertloctax; fldvertlocnum = fldvertidxtab[j]; fldvertlocadj = fldedgeidxtab[j] - fldgrafptr->s.vertloctax[fldvertlocnum]; fldvendidxtab[j] = fldvertlocadj; /* Record updated adjust value for vendloctab pass */ for (fldvertlocnnd = fldvertlocnum + fldcommdattab[j].vertnbr; fldvertlocnum < fldvertlocnnd; fldvertlocnum ++) fldvertloctax[fldvertlocnum] += fldvertlocadj; } } for (i = 0; i < commnbr; i ++) { int j; if (MPI_Waitany (commnbr, &requtab[HDGRAPHFOLDTAGVEND * commmax], &j, MPI_STATUS_IGNORE) != MPI_SUCCESS) { errorPrint ("hdgraphFold2: communication error (15)"); cheklocval = 1; } else { /* Adjust first remote part of vertex array */ Gnum fldvendlocnum; Gnum fldvendlocnnd; Gnum fldvendlocadj; Gnum * restrict const fldvendloctax = fldgrafptr->s.vendloctax; fldvendlocnum = fldvertidxtab[j]; fldvendlocadj = fldvendidxtab[j]; /* Get updated adjust from above vertloctab pass */ for (fldvendlocnnd = fldvendlocnum + fldcommdattab[j].vertnbr; fldvendlocnum < fldvendlocnnd; fldvendlocnum ++) fldvendloctax[fldvendlocnum] += fldvendlocadj; } } for (i = 0; i < commnbr; i ++) { MPI_Status statdat; int j; if (MPI_Waitany (commnbr, &requtab[HDGRAPHFOLDTAGEDGE * commmax], &j, &statdat) != MPI_SUCCESS) { errorPrint ("hdgraphFold2: communication error (16)"); cheklocval = 1; } else if (cheklocval == 0) { /* Adjust remote part(s) of edge array */ Gnum orgvertlocmin; Gnum orgvertlocmax; Gnum fldvertlocnum; Gnum fldvertlocnnd; Gnum fldvertlocadj; Gnum fldvhallocmax; /* Maximum current size of halo vertex array */ int procngbmin; int procngbmax; Gnum * restrict const fldvertloctax = fldgrafptr->s.vertloctax; Gnum * restrict const fldvendloctax = fldgrafptr->s.vendloctax; Gnum * restrict const fldedgeloctax = fldgrafptr->s.edgeloctax; #ifdef SCOTCH_DEBUG_HDGRAPH2 int fldedgercvnbr; MPI_Get_count (&statdat, GNUM_MPI, &fldedgercvnbr); if (fldedgercvnbr != fldedgecnttab[j]) { errorPrint ("hdgraphFold2: internal error (6)"); return (1); } #endif /* SCOTCH_DEBUG_HDGRAPH2 */ for (procngbmin = 0, procngbmax = fldvertadjnbr; /* Initialize search accelerator */ procngbmax - procngbmin > 1; ) { int procngbmed; procngbmed = (procngbmax + procngbmin) / 2; if (fldvertadjtab[procngbmed] <= fldcommvrttab[j]) procngbmin = procngbmed; else procngbmax = procngbmed; } orgvertlocmin = fldvertadjtab[procngbmin]; orgvertlocmax = fldvertadjtab[procngbmax]; fldvertlocadj = fldvertdlttab[procngbmin]; fldvhallocmax = orggrafptr->s.baseval - 1; /* Reset halo vertex array for each remote part */ for (fldvertlocnum = fldvertidxtab[j], fldedgelocnum = fldedgeidxtab[j], /* Update received part of edge array */ fldvertlocnnd = fldvertlocnum + fldcommdattab[j].vertnbr; fldvertlocnum < fldvertlocnnd; ) { for ( ; fldedgelocnum < fldvendloctax[fldvertlocnum]; fldedgelocnum ++) { /* Reorder end vertices */ Gnum orgvertlocend; #ifdef SCOTCH_DEBUG_HDGRAPH2 if (fldedgelocnum >= (fldgrafptr->s.edgelocsiz + orggrafptr->s.baseval)) { errorPrint ("hdgraphFold2: internal error (7)"); return (1); } #endif /* SCOTCH_DEBUG_HDGRAPH2 */ orgvertlocend = fldedgeloctax[fldedgelocnum]; if ((orgvertlocend >= orgvertlocmin) && /* If end vertex is local */ (orgvertlocend < orgvertlocmax)) fldedgeloctax[fldedgelocnum] = orgvertlocend + fldvertlocadj; else { int procngbnum; int procngbmax; for (procngbnum = 0, procngbmax = fldvertadjnbr; procngbmax - procngbnum > 1; ) { int procngbmed; procngbmed = (procngbmax + procngbnum) / 2; if (fldvertadjtab[procngbmed] <= orgvertlocend) procngbnum = procngbmed; else procngbmax = procngbmed; } fldedgeloctax[fldedgelocnum] = orgvertlocend + fldvertdlttab[procngbnum]; } } fldvertlocnum ++; fldehallocnbr += fldvertloctax[fldvertlocnum] - fldedgelocnum; for ( ; fldedgelocnum < fldvertloctax[fldvertlocnum]; fldedgelocnum ++) { /* Renumber halo part */ Gnum orgverthalend; Gnum fldvhallocend; orgverthalend = fldedgeloctax[fldedgelocnum]; #ifdef SCOTCH_DEBUG_HDGRAPH2 if ((orgverthalend < orggrafptr->s.baseval) || (orgverthalend >= (orggrafptr->s.edgeglbsmx + orggrafptr->s.baseval)) || (fldedgelocnum >= (fldgrafptr->s.edgelocsiz + orggrafptr->s.baseval))) { errorPrint ("hdgraphFold2: internal error (8)"); return (1); } #endif /* SCOTCH_DEBUG_HDGRAPH2 */ while (fldvhallocmax < orgverthalend) /* Expand halo vertex index array whenever necessary */ fldvhalloctax[++ fldvhallocmax] = ~0; fldvhallocend = fldvhalloctax[orgverthalend]; /* Get renumbered halo vertex */ if (fldvhallocend < 0) { /* If new halo vertex not yet given */ fldvhallocend = /* Allocate it */ fldvhalloctax[orgverthalend] = fldvhallocnum ++; } fldedgeloctax[fldedgelocnum] = fldvhallocend; } } } } if ((fldcommtypval & DGRAPHFOLDCOMMSEND) == 0) { /* If process is a normal receiver, edge arrays may have been oversized */ fldgrafptr->s.edgeloctax = memRealloc (fldgrafptr->s.edgeloctax + orggrafptr->s.baseval, fldgrafptr->s.edgelocsiz * sizeof (Gnum)); fldgrafptr->s.edgeloctax -= orggrafptr->s.baseval; } fldgrafptr->vhallocnbr = fldvhallocnum - orggrafptr->s.baseval; fldgrafptr->vhndloctax = fldgrafptr->s.vertloctax + 1; /* Compact edge array with halo vertices */ fldgrafptr->ehallocnbr = fldehallocnbr; fldgrafptr->levlnum = orggrafptr->levlnum; /* Folded graph is of same level */ if (orggrafptr->s.veloloctax == NULL) /* If no vertex loads, reset graph vertex load to number of vertices */ fldvelolocsum = fldvertlocnbr; else { /* Graph has vertex loads and load of local part has already been computed */ for (i = 0; i < commnbr; i ++) { int j; if (MPI_Waitany (commnbr, &requtab[HDGRAPHFOLDTAGVELO * commmax], &j, MPI_STATUS_IGNORE) != MPI_SUCCESS) { errorPrint ("hdgraphFold2: communication error (17)"); cheklocval = 1; } else if (cheklocval == 0) { /* Accumulate vertex loads for received vertex load array */ Gnum fldvertlocnum; Gnum fldvertlocnnd; for (fldvertlocnum = fldvertidxtab[j], fldvertlocnnd = fldvertlocnum + fldcommdattab[j].vertnbr; fldvertlocnum < fldvertlocnnd; fldvertlocnum ++) fldvelolocsum += fldgrafptr->s.veloloctax[fldvertlocnum]; } } } fldgrafptr->s.baseval = orggrafptr->s.baseval; fldgrafptr->s.vertlocnbr = fldvertlocnbr; fldgrafptr->s.vertlocnnd = fldvertlocnbr + orggrafptr->s.baseval; fldgrafptr->s.velolocsum = fldvelolocsum; fldgrafptr->s.edgelocnbr = fldgrafptr->s.edgelocsiz - fldehallocnbr; fldgrafptr->s.degrglbmax = orggrafptr->s.degrglbmax; if (dgraphBuild4 (&fldgrafptr->s) != 0) { errorPrint ("hdgraphFold2: cannot build folded graph"); hdgraphExit (fldgrafptr); return (1); } #ifdef SCOTCH_DEBUG_HDGRAPH2 if (hdgraphCheck (fldgrafptr) != 0) { /* Check graph consistency; vnumloctab is not checked so no need to wait for it */ errorPrint ("hdgraphFold2: internal error (9)"); hdgraphExit (fldgrafptr); return (1); } #endif /* SCOTCH_DEBUG_HDGRAPH2 */ } memFree (fldcommdattab); /* Free group leader */ if (MPI_Waitall (requnbr, requtab, MPI_STATUSES_IGNORE) != MPI_SUCCESS) { /* Wait for all graph data to arrive because graph could be freed afterwards */ errorPrint ("hdgraphFold2: communication error (18)"); cheklocval = 1; } memFree (fldvertidxtab); /* Free group leader including request array */ #ifdef SCOTCH_DEBUG_HDGRAPH1 /* Communication cannot be merged with a useful one */ if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, orggrafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("hdgraphFold2: communication error (19)"); chekglbval = 1; } #else /* SCOTCH_DEBUG_HDGRAPH1 */ chekglbval = cheklocval; #endif /* SCOTCH_DEBUG_HDGRAPH1 */ return (chekglbval); } scotch-6.0.4.dfsg/src/libscotch/library_dgraph_stat.h0000644002563400244210000000556611631447170026047 0ustar trophimeutilisateurs du domaine/* Copyright 2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /**********************************************************/ /* */ /* NAME : library_dgraph_stat.h */ /* */ /* AUTHOR : Francois PELLEGRINI */ /* */ /* FUNCTION : These lines are the data declarations */ /* for the distributed source graph */ /* analyzing routine. */ /* */ /* # Version 5.0 : from : 23 jun 2007 */ /* to 23 jun 2007 */ /* */ /**********************************************************/ /* ** The type and structure definitions. */ /* Communication structure for distributed graph statistics. */ typedef struct DgraphStatData_ { Gnum velomin; Gnum velomax; Gnum degrmin; Gnum degrmax; Gnum edlomin; Gnum edlomax; Gnum edlosum; double velodlt; double degrdlt; double edlodlt; } DgraphStatData; scotch-6.0.4.dfsg/src/libscotch/common_file_compress.h0000644002563400244210000001124412262355406026214 0ustar trophimeutilisateurs du domaine/* Copyright 2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : common_file_compress.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the file (de)compression routines. **/ /** **/ /** DATES : # Version 5.0 : from : 12 mar 2008 **/ /** to 17 mar 2008 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /* Buffer size. */ #define FILECOMPRESSDATASIZE (128 * 1024) /* Size of (un)compressing buffers */ /* Available types of (un)compression. */ typedef enum FileCompressType_ { FILECOMPRESSTYPENOTIMPL = -1, /* Error code */ FILECOMPRESSTYPENONE, /* No compression */ FILECOMPRESSTYPEBZ2, FILECOMPRESSTYPEGZ, FILECOMPRESSTYPELZMA } FileCompressType; /* (Un)compression type slot. */ typedef struct FileCompressTab_ { char * name; /* File extension name */ FileCompressType type; /* (Un)compression type */ } FileCompressTab; /* ** The type and structure definitions. */ typedef struct FileCompressData_ { int typeval; /*+ Type of (un)compression +*/ int innerfd; /*+ Inner file handle (pipe end) +*/ FILE * outerstream; /*+ Outer stream +*/ double datatab; /*+ Start of data buffer +*/ } FileCompressData; /* ** The function prototypes. */ #ifdef COMMON_FILE_COMPRESS_BZ2 #ifdef COMMON_FILE_COMPRESS static void fileCompressBz2 (FileCompressData * const dataptr); #endif /* COMMON_FILE_COMPRESS */ #ifdef COMMON_FILE_UNCOMPRESS static void fileUncompressBz2 (FileCompressData * const dataptr); #endif /* COMMON_FILE_UNCOMPRESS */ #endif /* COMMON_FILE_COMPRESS_Bz2 */ #ifdef COMMON_FILE_COMPRESS_GZ #ifdef COMMON_FILE_COMPRESS static void fileCompressGz (FileCompressData * const dataptr); #endif /* COMMON_FILE_COMPRESS */ #ifdef COMMON_FILE_UNCOMPRESS static void fileUncompressGz (FileCompressData * const dataptr); #endif /* COMMON_FILE_UNCOMPRESS */ #endif /* COMMON_FILE_COMPRESS_GZ */ #ifdef COMMON_FILE_COMPRESS_LZMA /* #ifdef COMMON_FILE_COMPRESS */ /* static void fileCompressLzma (FileCompressData * const dataptr); */ /* #endif /\* COMMON_FILE_COMPRESS *\/ */ #ifdef COMMON_FILE_UNCOMPRESS static void fileUncompressLzma (FileCompressData * const dataptr); #endif /* COMMON_FILE_UNCOMPRESS */ #endif /* COMMON_FILE_COMPRESS_LZMA */ scotch-6.0.4.dfsg/src/libscotch/hgraph_check.c0000644002563400244210000001205611631447170024414 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hgraph.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles the source graph **/ /** functions. **/ /** **/ /** DATES : # Version 4.0 : from : 17 jan 2002 **/ /** to 01 dec 2003 **/ /** # Version 5.0 : from : 19 dec 2006 **/ /** to 19 dec 2006 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HGRAPH #include "module.h" #include "common.h" #include "graph.h" #include "hgraph.h" /****************************************/ /* */ /* These routines handle source graphs. */ /* */ /****************************************/ /* This routine checks the consistency ** of the given halo graph. ** It returns: ** - 0 : if graph data are consistent. ** - !0 : on error. */ int hgraphCheck ( const Hgraph * restrict const grafptr) { Gnum vertnum; /* Number of current vertex */ Gnum edgenum; /* Number of current edge */ Gnum enohsum; if (graphCheck (&grafptr->s) != 0) { errorPrint ("hgraphCheck: invalid graph structure in halo graph"); return (1); } if ((grafptr->vnohnbr < 0) || (grafptr->vnohnbr > grafptr->s.vertnbr) || (grafptr->vnohnnd != (grafptr->vnohnbr + grafptr->s.baseval)) || (grafptr->vnlosum > grafptr->s.velosum) || (grafptr->enohnbr > grafptr->s.edgenbr) || (grafptr->enohsum < grafptr->enohnbr)) { errorPrint ("hgraphCheck: invalid halo graph parameters"); return (1); } enohsum = (grafptr->s.edlotax == NULL) ? grafptr->enohnbr : 0; for (vertnum = grafptr->s.baseval; vertnum < grafptr->vnohnnd; vertnum ++) { /* For all non-halo vertices */ if ((grafptr->vnhdtax[vertnum] < grafptr->s.verttax[vertnum]) || (grafptr->vnhdtax[vertnum] > grafptr->s.vendtax[vertnum])) { errorPrint ("hgraphCheck: invalid non-halo end vertex array"); return (1); } if (grafptr->s.edlotax != NULL) { Gnum edgenum; for (edgenum = grafptr->s.verttax[vertnum]; edgenum < grafptr->vnhdtax[vertnum]; edgenum ++) enohsum += grafptr->s.edlotax[edgenum]; } } if (grafptr->enohsum != enohsum) { errorPrint ("hgraphCheck: invalid non-halo edge load sum"); return (1); } for ( ; vertnum < grafptr->s.vertnnd; vertnum ++) { /* For all halo vertices */ for (edgenum = grafptr->s.verttax[vertnum]; edgenum < grafptr->s.vendtax[vertnum]; edgenum ++) { if (grafptr->s.edgetax[edgenum] >= grafptr->vnohnnd) { /* If two halo vertices connected together */ errorPrint ("hgraphCheck: halo vertices should not be connected together"); return (1); } } } return (0); } scotch-6.0.4.dfsg/src/libscotch/vdgraph_store.c0000644002563400244210000001465111631447170024660 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vdgraph_store.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the save data **/ /** structure handling routines for **/ /** distributed separation graphs. **/ /** **/ /** DATES : # Version 4.0 : from : 08 mar 2006 **/ /** to : 01 mar 2008 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VDGRAPH_STORE #include "module.h" #include "common.h" #include "dgraph.h" #include "vdgraph.h" /**********************************/ /* */ /* Store graph handling routines. */ /* */ /**********************************/ /* This routine builds a save structure ** for the given active graph. ** It returns: ** - 0 : if allocation succeeded. ** - !0 : on error. */ int vdgraphStoreInit ( const Vdgraph * restrict const grafptr, VdgraphStore * restrict const storptr) { Gnum savsize; savsize = grafptr->s.vertlocnbr * (sizeof (GraphPart) + sizeof (Gnum)); /* Compute size for frontier and part arrays */ if ((storptr->datatab = (byte *) memAlloc (savsize)) == NULL) { /* Allocate save structure */ errorPrint ("vdgraphStoreInit: out of memory"); return (1); } return (0); } /* This routine frees a save structure. ** It returns: ** - VOID : in all cases. */ void vdgraphStoreExit ( VdgraphStore * const storptr) { memFree (storptr->datatab); #ifdef SCOTCH_DEBUG_VDGRAPH2 storptr->datatab = NULL; #endif /* SCOTCH_DEBUG_VDGRAPH2 */ } /* This routine saves partition data from the ** given active graph to the given save structure. ** It returns: ** - VOID : in all cases. */ void vdgraphStoreSave ( const Vdgraph * const grafptr, VdgraphStore * const storptr) { byte * partloctab; /* Pointer to part data save area */ byte * fronloctab; /* Pointer to frontier data save area */ storptr->fronglbnbr = grafptr->compglbsize[2]; /* Save partition parameters */ storptr->compglbloaddlt = grafptr->compglbloaddlt; storptr->compglbload[0] = grafptr->compglbload[0]; storptr->compglbload[1] = grafptr->compglbload[1]; storptr->compglbsize0 = grafptr->compglbsize[0]; storptr->complocsize0 = grafptr->complocsize[0]; storptr->fronlocnbr = grafptr->complocsize[2]; fronloctab = storptr->datatab; /* Compute data offsets within save structure */ partloctab = fronloctab + grafptr->complocsize[2] * sizeof (Gnum); memCpy (fronloctab, grafptr->fronloctab, grafptr->complocsize[2] * sizeof (Gnum)); memCpy (partloctab, grafptr->partgsttax + grafptr->s.baseval, grafptr->s.vertlocnbr * sizeof (GraphPart)); } /* This routine updates partition data of the ** given active graph, using the given save graph. ** It returns: ** - VOID : in all cases. */ void vdgraphStoreUpdt ( Vdgraph * const grafptr, const VdgraphStore * const storptr) { byte * fronloctab; /* Pointer to frontier data save area */ byte * partloctab; /* Pointer to part data save area */ grafptr->compglbload[0] = storptr->compglbload[0]; /* Load partition parameters */ grafptr->compglbload[1] = storptr->compglbload[1]; grafptr->compglbload[2] = grafptr->s.veloglbsum - (storptr->compglbload[0] + storptr->compglbload[1]); grafptr->compglbloaddlt = storptr->compglbloaddlt; grafptr->compglbsize[0] = storptr->compglbsize0; grafptr->compglbsize[1] = grafptr->s.vertglbnbr - (storptr->compglbsize0 + storptr->fronglbnbr); grafptr->compglbsize[2] = storptr->fronglbnbr; grafptr->complocsize[0] = storptr->complocsize0; grafptr->complocsize[1] = grafptr->s.vertlocnbr - (storptr->complocsize0 + storptr->fronlocnbr); grafptr->complocsize[2] = storptr->fronlocnbr; fronloctab = storptr->datatab; /* Compute data offsets within save structure */ partloctab = fronloctab + grafptr->complocsize[2] * sizeof (Gnum); memCpy (grafptr->fronloctab, fronloctab, grafptr->complocsize[2] * sizeof (Gnum)); memCpy (grafptr->partgsttax + grafptr->s.baseval, partloctab, grafptr->s.vertlocnbr * sizeof (GraphPart)); #ifdef SCOTCH_DEBUG_VDGRAPH2 if (vdgraphCheck (grafptr) != 0) errorPrint ("vdgraphStoreUpdt: inconsistent graph data"); #endif /* SCOTCH_DEBUG_VDGRAPH2 */ } scotch-6.0.4.dfsg/src/libscotch/dgraph_match_sync_ptop.c0000644002563400244210000006146611736616757026555 0ustar trophimeutilisateurs du domaine/* Copyright 2008,2009,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_match_sync_ptop.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Cedric CHEVALIER (v5.0) **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the distributed graph matching **/ /** routines. **/ /** **/ /** DATES : # Version 5.1 : from : 01 dec 2008 **/ /** to : 22 apr 2009 **/ /** # Version 6.0 : from : 03 apr 2012 **/ /** to : 03 apr 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DGRAPH_MATCH #include "module.h" #include "common.h" #include "dgraph.h" #include "dgraph_coarsen.h" #include "dgraph_match.h" /*************************************/ /* */ /* These routines handle distributed */ /* source graphs. */ /* */ /*************************************/ /* This routine performs a round of point-to-point ** communication to synchronize enqueued matching ** requests across processors. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int dgraphMatchSyncPtop ( DgraphMatchData * restrict const mateptr) { Gnum queulocnbr; Gnum queulocnum; Gnum matelocnbr; Gnum multlocnbr; Gnum vertlocadj; Gnum edgekptnbr; int procngbnbr; int procngbidx; int procngbnum; int vrcvreqnbr; Dgraph * restrict const grafptr = mateptr->c.finegrafptr; const int * restrict const procngbtab = grafptr->procngbtab; int * restrict const procgsttax = mateptr->c.procgsttax; const Gnum * restrict const procvgbtab = mateptr->procvgbtab; const Gnum * restrict const vertloctax = grafptr->vertloctax; const Gnum * restrict const vendloctax = grafptr->vendloctax; const Gnum * restrict const edgeloctax = grafptr->edgeloctax; const Gnum * restrict const edgegsttax = grafptr->edgegsttax; Gnum * restrict const queuloctab = mateptr->queuloctab; Gnum * restrict const mategsttax = mateptr->mategsttax; DgraphCoarsenMulti * restrict const multloctab = mateptr->c.multloctab; int * restrict const nsndidxtab = mateptr->c.nsndidxtab; DgraphCoarsenVert * const vsnddattab = mateptr->c.vsnddattab; /* [norestrict:async] */ procngbnbr = grafptr->procngbnbr; #ifdef SCOTCH_DEBUG_DGRAPH2 if (edgeloctax == NULL) { errorPrint ("dgraphMatchSyncPtop: not implemented"); return (1); } if (MPI_Barrier (grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphMatchSyncPtop: communication error (1)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ for (procngbnum = 0; procngbnum < procngbnbr; procngbnum ++) /* Reset indices for sending messages */ nsndidxtab[procngbnum] = mateptr->c.vsnddsptab[procngbtab[procngbnum]]; vertlocadj = grafptr->procvrttab[grafptr->proclocnum] - grafptr->baseval; for (queulocnum = 0, queulocnbr = mateptr->queulocnbr; queulocnum < queulocnbr; queulocnum ++) { Gnum vertlocnum; Gnum vertgstnum; Gnum edgelocnum; Gnum mategstnum; Gnum mateglbnum; int procngbnum; int vsndidxnum; vertlocnum = queuloctab[queulocnum]; /* Get local vertex index */ mategstnum = mategsttax[vertlocnum]; /* Get mate (edge ?) index */ if (mategstnum >= -1) /* If vertex not willing to mate or matched locally after being considered during matching phase */ continue; edgelocnum = -2 - mategstnum; /* Get local edge to mate ghost vertex */ #ifdef SCOTCH_DEBUG_DGRAPH2 if ((edgelocnum < grafptr->baseval) || (edgelocnum >= (grafptr->edgelocsiz + grafptr->baseval)) || (mategsttax[edgegsttax[edgelocnum]] != -1)) { errorPrint ("dgraphMatchSyncPtop: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ mateglbnum = edgeloctax[edgelocnum]; vertgstnum = edgegsttax[edgelocnum]; procngbnum = procgsttax[vertgstnum]; /* Find neighbor owner process */ if (procngbnum < 0) { /* If neighbor not yet computed */ int procngbmax; procngbnum = 0; procngbmax = procngbnbr; while ((procngbmax - procngbnum) > 1) { /* Find owner process by dichotomy on procvgbtab */ int procngbmed; procngbmed = (procngbmax + procngbnum) / 2; if (procvgbtab[procngbmed] > mateglbnum) procngbmax = procngbmed; else procngbnum = procngbmed; } procgsttax[vertgstnum] = procngbnum; } #ifdef SCOTCH_DEBUG_DGRAPH2 if ((grafptr->procvrttab[procngbtab[procngbnum]] > mateglbnum) || (grafptr->procvrttab[procngbtab[procngbnum] + 1] <= mateglbnum)) { errorPrint ("dgraphMatchSyncPtop: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ vsndidxnum = nsndidxtab[procngbnum] ++; /* Get position of message in send array */ #ifdef SCOTCH_DEBUG_DGRAPH2 if (vsndidxnum >= mateptr->c.vsnddsptab[procngbtab[procngbnum] + 1]) { errorPrint ("dgraphMatchSyncPtop: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ vsnddattab[vsndidxnum].datatab[0] = vertlocnum + vertlocadj; vsnddattab[vsndidxnum].datatab[1] = mateglbnum; } for (procngbidx = 0; procngbidx < procngbnbr; procngbidx ++) { /* Post receives of mating requests in descending order */ int procngbnum; int procglbnum; procngbnum = (mateptr->c.procngbnxt + (procngbnbr - 1) - procngbidx) % procngbnbr; procglbnum = procngbtab[procngbnum]; if (MPI_Irecv (mateptr->c.vrcvdattab + mateptr->c.vrcvdsptab[procglbnum], 2 * (mateptr->c.vrcvdsptab[procglbnum + 1] - mateptr->c.vrcvdsptab[procglbnum]), GNUM_MPI, procglbnum, TAGMATCH, grafptr->proccomm, &mateptr->c.nrcvreqtab[procngbnum]) != MPI_SUCCESS) { errorPrint ("dgraphMatchSyncPtop: communication error (2)"); return (1); } } for (procngbidx = 0; procngbidx < procngbnbr; procngbidx ++) { /* Post sends of mating requests in ascending order */ int procngbnum; int procglbnum; procngbnum = (procngbidx + mateptr->c.procngbnxt) % procngbnbr; procglbnum = procngbtab[procngbnum]; if (MPI_Isend (vsnddattab + mateptr->c.vsnddsptab[procglbnum], 2 * (nsndidxtab[procngbnum] - mateptr->c.vsnddsptab[procglbnum]), GNUM_MPI, procglbnum, TAGMATCH, grafptr->proccomm, &mateptr->c.nsndreqtab[procngbnum]) != MPI_SUCCESS) { errorPrint ("dgraphMatchSyncPtop: communication error (3)"); return (1); } } matelocnbr = mateptr->matelocnbr; multlocnbr = mateptr->c.multlocnbr; edgekptnbr = mateptr->c.edgekptnbr; for (vrcvreqnbr = procngbnbr; vrcvreqnbr > 0; vrcvreqnbr --) { /* For all pending receive requests */ int procglbnum; int procngbnum; int vrcvidxnnd; int requrcvnum; int requnxtnum; /* Index of location where to pack requests to process when all messages arrive */ MPI_Status statdat; int statsiz; int o; #ifdef SCOTCH_DETERMINISTIC procngbnum = vrcvreqnbr - 1; o = MPI_Wait (&mateptr->c.nrcvreqtab[procngbnum], &statdat); #else /* SCOTCH_DETERMINISTIC */ o = MPI_Waitany (procngbnbr, mateptr->c.nrcvreqtab, &procngbnum, &statdat); #endif /* SCOTCH_DETERMINISTIC */ if ((o != MPI_SUCCESS) || (MPI_Get_count (&statdat, GNUM_MPI, &statsiz) != MPI_SUCCESS)) { errorPrint ("dgraphMatchSyncPtop: communication error (4)"); return (1); } #ifdef SCOTCH_DEBUG_DGRAPH2 if (statdat.MPI_SOURCE != procngbtab[procngbnum]) { errorPrint ("dgraphMatchSyncPtop: internal error (4)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ procglbnum = procngbtab[procngbnum]; vrcvidxnnd = mateptr->c.vrcvdsptab[procglbnum]; if (statsiz <= 0) { /* If query message is empty */ mateptr->c.nrcvidxtab[procngbnum] = -1; /* No need to send a reply */ continue; /* Skip message processing */ } else { Gnum vertsndnbr; /* Number of vertices to be sent to requesting neighbor */ Gnum edgesndnbr; /* Number of edges to be sent to requesting neighbor */ DgraphCoarsenVert * restrict const vrcvdattab = mateptr->c.vrcvdattab; /* Local restrict pointer only when data available (has been received) */ vertsndnbr = edgesndnbr = 0; for (requrcvnum = requnxtnum = vrcvidxnnd, vrcvidxnnd += (statsiz / 2); /* TRICK: each message item costs 2 Gnum's */ requrcvnum < vrcvidxnnd; requrcvnum ++) { Gnum vertglbnum; /* Our global number (the one seen as mate by sender) */ Gnum vertlocnum; /* Our local number (the one seen as mate by sender) */ Gnum vmatglbnum; /* Global number of requesting mate (sender of message) */ Gnum mategstnum; /* The mate we wanted to ask for */ vmatglbnum = vrcvdattab[requrcvnum].datatab[0]; /* Names are opposite because receiving side */ vertglbnum = vrcvdattab[requrcvnum].datatab[1]; vertlocnum = vertglbnum - vertlocadj; #ifdef SCOTCH_DEBUG_DGRAPH2 if ((vertlocnum < grafptr->baseval) || /* If matching request is not directed towards our process */ (vertlocnum >= grafptr->vertlocnnd)) { errorPrint ("dgraphMatchSyncPtop: internal error (5)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ mategstnum = mategsttax[vertlocnum]; /* Get our local mating decision data */ if (mategstnum == -1) { /* If local vertex wanted for mating is free */ Gnum edgelocnum; for (edgelocnum = vertloctax[vertlocnum]; edgeloctax[edgelocnum] != vmatglbnum; edgelocnum ++) { #ifdef SCOTCH_DEBUG_DGRAPH2 if (edgelocnum >= vendloctax[vertlocnum]) { errorPrint ("dgraphMatchSyncPtop: internal error (6)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ } mategsttax[edgegsttax[edgelocnum]] = vertglbnum; /* We are no longer free */ mategsttax[vertlocnum] = vmatglbnum; /* Leave message as is to acknowledge it */ matelocnbr ++; vertsndnbr ++; edgesndnbr += vendloctax[vertlocnum] - vertloctax[vertlocnum]; } else if (mategstnum < -1) { /* If local vertex is also asking for mating */ Gnum edgelocnum; Gnum mateglbnum; edgelocnum = -2 - mategstnum; mateglbnum = edgeloctax[edgelocnum]; /* Get global number of our remote mate */ if (mateglbnum == vmatglbnum) { /* If it is with the sender */ Gnum flagval; /* Flag for choosing side to create multinode */ mategsttax[vertlocnum] = mateglbnum; /* Say we are mated to inform future requesting processes in same pass */ mategsttax[edgegsttax[edgelocnum]] = vertglbnum; flagval = (mateglbnum > vertglbnum) ? 1 : 0; /* Compute pseudo-random flag always opposite for both ends */ flagval = ((mateglbnum + (mateglbnum - vertglbnum) * flagval) & 1) ^ flagval; if (flagval == 0) { /* If flag is even, create multinode */ multloctab[multlocnbr].vertglbnum[0] = vertglbnum; multloctab[multlocnbr].vertglbnum[1] = mategstnum; /* Remote mate: negative value */ multlocnbr ++; /* One more coarse vertex created */ edgekptnbr += vendloctax[vertlocnum] - vertloctax[vertlocnum]; } else { /* If flag is odd, prepare to send vertex data at build time */ vertsndnbr ++; edgesndnbr += vendloctax[vertlocnum] - vertloctax[vertlocnum]; } /* Go on by destroying message in all cases since both ends know what it is about */ vrcvdattab[requrcvnum --] = vrcvdattab[-- vrcvidxnnd]; /* Replace current message with another one and process it */ matelocnbr ++; /* One more local vertex mated on each side; no messages will tell it */ } else { /* If willing to mate but not with the sender, tell later with whom */ DgraphCoarsenVert vertdat; /* Temporary storage data for swapping vertices */ vertdat = vrcvdattab[requnxtnum]; /* Pack requests to process later at beginning of message */ vrcvdattab[requnxtnum].datatab[0] = vmatglbnum; vrcvdattab[requnxtnum].datatab[1] = -2 - vertlocnum; /* Build appropriate answer to mating request later, when all messages arrived */ if (requnxtnum ++ != requrcvnum) vrcvdattab[requrcvnum] = vertdat; /* Swap vertices if not already at the right place */ } } else /* If already matched, inform sender */ vrcvdattab[requrcvnum].datatab[1] = mategstnum; } mateptr->c.dcntloctab[procglbnum].vertsndnbr += vertsndnbr; mateptr->c.dcntloctab[procglbnum].edgesndnbr += edgesndnbr; } mateptr->c.nrcvidxtab[procngbnum] = vrcvidxnnd; } if (MPI_Waitall (procngbnbr, mateptr->c.nsndreqtab, MPI_STATUSES_IGNORE) != MPI_SUCCESS) { /* Wait for send requests of mating requests to complete */ errorPrint ("dgraphMatchSyncPtop: communication error (5)"); return (1); } #ifdef SCOTCH_DEBUG_DGRAPH2 if (MPI_Barrier (grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphMatchSyncPtop: communication error (6)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ vrcvreqnbr = procngbnbr; /* Count number of receive requests we will have to consider */ for (procngbidx = 0; procngbidx < procngbnbr; procngbidx ++) { /* Post receives of mating replies in descending order */ int procngbnum; int procglbnum; procngbnum = (mateptr->c.procngbnxt + (procngbnbr - 1) - procngbidx) % procngbnbr; procglbnum = procngbtab[procngbnum]; if (nsndidxtab[procngbnum] <= mateptr->c.vsnddsptab[procglbnum]) { /* If we had sent an empty query message, do not expect any reply */ mateptr->c.nrcvreqtab[procngbnum] = MPI_REQUEST_NULL; vrcvreqnbr --; /* One less receive request to wait for */ continue; } if (MPI_Irecv (vsnddattab + mateptr->c.vsnddsptab[procglbnum], 2 * (mateptr->c.vsnddsptab[procglbnum + 1] - mateptr->c.vsnddsptab[procglbnum]), GNUM_MPI, procglbnum, TAGMATCH + 1, grafptr->proccomm, &mateptr->c.nrcvreqtab[procngbnum]) != MPI_SUCCESS) { errorPrint ("dgraphMatchSyncPtop: communication error (7)"); return (1); } } for (procngbidx = 0; procngbidx < procngbnbr; procngbidx ++) { /* Post sends of mating requests in ascending order */ int procngbnum; int procglbnum; int vsndidxnnd; procngbnum = (procngbidx + mateptr->c.procngbnxt) % procngbnbr; procglbnum = procngbtab[procngbnum]; vsndidxnnd = mateptr->c.nrcvidxtab[procngbnum]; /* Re-send (or not) the messages we have received to acknowledge */ if (vsndidxnnd >= 0) { /* If we had received a non-empty message (but reply might be empty) */ int vsndidxnum; DgraphCoarsenVert * restrict const vrcvdattab = mateptr->c.vrcvdattab; /* Local restrict pointer only when data available */ for (vsndidxnum = mateptr->c.vrcvdsptab[procglbnum]; /* Finalize unfinished messages */ vsndidxnum < vsndidxnnd; vsndidxnum ++) { Gnum vertlocnum; Gnum mateglbnum; vertlocnum = vrcvdattab[vsndidxnum].datatab[1]; if (vertlocnum >= 0) /* If no more unfinished messages to process, quit scanning */ break; vertlocnum = -2 - vertlocnum; mateglbnum = mategsttax[vertlocnum]; if (mateglbnum >= 0) /* If vertex we wanted to mate with has been mated in this round */ vrcvdattab[vsndidxnum].datatab[1] = mateglbnum; /* Propagate this information back to the requester */ else { /* Vertex mating data not yet available (maybe in answer) */ vrcvdattab[vsndidxnum] = vrcvdattab[-- vsndidxnnd]; /* Remove message as no reply means not willing */ if (vrcvdattab[vsndidxnum].datatab[1] < 0) /* If replacing message is also to be processed */ vsndidxnum --; /* Do not skip replaced message in next iteration */ } } if (MPI_Isend (vrcvdattab + mateptr->c.vrcvdsptab[procglbnum], 2 * (vsndidxnnd - mateptr->c.vrcvdsptab[procglbnum]), GNUM_MPI, procglbnum, TAGMATCH + 1, grafptr->proccomm, &mateptr->c.nsndreqtab[procngbnum]) != MPI_SUCCESS) { errorPrint ("dgraphMatchSyncPtop: communication error (8)"); return (1); } } #ifdef SCOTCH_DEBUG_DGRAPH2 else { if (mateptr->c.nsndreqtab[procngbnum] != MPI_REQUEST_NULL) { /* Should have been set by previous MPI_Waitall() */ errorPrint ("dgraphMatchSyncPtop: internal error (7)"); return (1); } } #endif /* SCOTCH_DEBUG_DGRAPH2 */ } #ifdef SCOTCH_DETERMINISTIC vrcvreqnbr = procngbnbr; /* For deterministic behavior, consider all neighbors in order, whether communicating or not */ #endif /* SCOTCH_DETERMINISTIC */ for ( ; vrcvreqnbr > 0; vrcvreqnbr --) { /* For all pending receive requests */ int vrcvidxnnd; int vrcvidxnum; int procngbnum; MPI_Status statdat; int statsiz; int o; #ifdef SCOTCH_DETERMINISTIC procngbnum = vrcvreqnbr - 1; if (mateptr->c.nrcvreqtab[procngbnum] == MPI_REQUEST_NULL) /* If we do not expect this message, skip it */ continue; o = MPI_Wait (&mateptr->c.nrcvreqtab[procngbnum], &statdat); #else /* SCOTCH_DETERMINISTIC */ o = MPI_Waitany (procngbnbr, mateptr->c.nrcvreqtab, &procngbnum, &statdat); #endif /* SCOTCH_DETERMINISTIC */ if ((o != MPI_SUCCESS) || (MPI_Get_count (&statdat, GNUM_MPI, &statsiz) != MPI_SUCCESS)) { errorPrint ("dgraphMatchSyncPtop: communication error (9)"); return (1); } for (vrcvidxnum = mateptr->c.vsnddsptab[procngbtab[procngbnum]], vrcvidxnnd = vrcvidxnum + (statsiz / 2); /* TRICK: each message item costs 2 Gnum's */ vrcvidxnum < vrcvidxnnd; vrcvidxnum ++) { Gnum edgelocnum; Gnum vertglbnum; /* Our global number (the one seen as mate by sender) */ Gnum vertlocnum; /* Our local number (the one seen as mate by sender) */ Gnum vmatglbnum; /* Global number of vertex to which the mate is mated */ Gnum mategstnum; /* The mate we wanted to ask for */ vertglbnum = vsnddattab[vrcvidxnum].datatab[0]; vmatglbnum = vsnddattab[vrcvidxnum].datatab[1]; vertlocnum = vertglbnum - vertlocadj; #ifdef SCOTCH_DEBUG_DGRAPH2 if ((vertlocnum < grafptr->baseval) || /* If matching reply is not directed towards our process */ (vertlocnum >= grafptr->vertlocnnd)) { errorPrint ("dgraphMatchSyncPtop: internal error (8)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ mategstnum = mategsttax[vertlocnum]; /* Get our local mating decision data */ edgelocnum = -2 - mategstnum; #ifdef SCOTCH_DEBUG_DGRAPH2 if ((mategstnum >= -1) || /* If we did not ask anything or if we were already matched, no reply message should come to us */ ((mategsttax[edgegsttax[edgelocnum]] >= 0) && /* Also, if our prospective mate was itself already set as matched by a previous reply */ (mategsttax[edgegsttax[edgelocnum]] != vertglbnum) && /* And this message is not the positive reply which acknowledges this mating */ (mategsttax[edgegsttax[edgelocnum]] != vmatglbnum))) { /* Or an informative negative reply which gives again the mate of the ghost */ errorPrint ("dgraphMatchSyncPtop: internal error (9)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ if (edgeloctax[edgelocnum] == vmatglbnum) { /* If positive answer from the mate we wanted */ mategsttax[vertlocnum] = vmatglbnum; /* Set local vertex as matched with the mate */ mategsttax[edgegsttax[edgelocnum]] = vertglbnum; /* Update state of ghost mate */ multloctab[multlocnbr].vertglbnum[0] = vertglbnum; multloctab[multlocnbr].vertglbnum[1] = mategstnum; /* Remote mate: negative value */ multlocnbr ++; /* One more coarse vertex created */ matelocnbr ++; edgekptnbr += vendloctax[vertlocnum] - vertloctax[vertlocnum]; } else { /* If negative answer from the mate we wanted */ mategsttax[vertlocnum] = -1; /* Reset local vertex as free for mating */ mategsttax[edgegsttax[edgelocnum]] = vmatglbnum; /* Update state of unwilling ghost mate */ } } } mateptr->matelocnbr = matelocnbr; mateptr->c.multlocnbr = multlocnbr; mateptr->c.edgekptnbr = edgekptnbr; if (MPI_Waitall (procngbnbr, mateptr->c.nsndreqtab, MPI_STATUSES_IGNORE) != MPI_SUCCESS) { /* Wait for send requests of mating requests to complete */ errorPrint ("dgraphMatchSyncPtop: communication error (10)"); return (1); } #ifdef SCOTCH_DEBUG_DGRAPH2 if (MPI_Barrier (grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphMatchSyncPtop: communication error (11)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/library_dgraph_stat_f.c0000644002563400244210000001061212056000215026316 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_stat_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API for **/ /** the distributed source graph analyzing **/ /** routine of the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 24 jun 2007 **/ /** to 24 jun 2007 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "ptscotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the graph handling routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFDGRAPHSTAT, scotchfdgraphstat, ( \ const SCOTCH_Dgraph * const grafptr, \ SCOTCH_Num * const velominptr, \ SCOTCH_Num * const velomaxptr, \ SCOTCH_Num * const velosumptr, \ double * veloavgptr, \ double * velodltptr, \ SCOTCH_Num * const degrminptr, \ SCOTCH_Num * const degrmaxptr, \ double * degravgptr, \ double * degrdltptr, \ SCOTCH_Num * const edlominptr, \ SCOTCH_Num * const edlomaxptr, \ SCOTCH_Num * const edlosumptr, \ double * edloavgptr, \ double * edlodltptr, \ int * const revaptr), \ (grafptr, velominptr, velomaxptr, velosumptr, \ veloavgptr, velodltptr, degrminptr, \ degrmaxptr, degravgptr, degrdltptr, \ edlominptr, edlomaxptr, edlosumptr, \ edloavgptr, edlodltptr, revaptr)) { *revaptr = SCOTCH_dgraphStat (grafptr, velominptr, velomaxptr, velosumptr, veloavgptr, velodltptr, degrminptr, degrmaxptr, degravgptr, degrdltptr, edlominptr, edlomaxptr, edlosumptr, edloavgptr, edlodltptr); } scotch-6.0.4.dfsg/src/libscotch/mesh.h0000644002563400244210000002063511631447171022752 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mesh.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the source mesh functions. **/ /** **/ /** DATES : # Version 4.0 : from : 29 dec 2001 **/ /** to 11 may 2004 **/ /** # Version 5.1 : from : 04 nov 2010 **/ /** to 04 nov 2010 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ Mesh option flags. +*/ #define MESHNONE 0x0000 /* No options set */ #define MESHFREEEDGE 0x0001 /* Free edgetab array */ #define MESHFREEVERT 0x0002 /* Free verttab array */ #define MESHFREEVEND 0x0004 /* Free verttab array */ #define MESHFREEVNUM 0x0008 /* Free vnumtab array */ #define MESHFREEOTHR 0x0010 /* Free all other arrays */ #define MESHFREETABS 0x001F /* Free all mesh arrays */ #define MESHVERTGROUP 0x0010 /* All vertex arrays grouped */ /*+ The Mesh flag type. +*/ typedef int MeshFlag; /*+ Mesh property flags +*/ /*+ Mesh structure. It is basically a graph structure. It is a bipartite graph in the sense that node vertices are adjacent to element vertices only, and that element vertices are adjacent to node vertices only. Node vertices can all be put before or after element vertices, but node and element vertices cannot be mixed. In most algorithms, elements are put at the beginning because critical algorithms, such as the mesh induction and mesh coarsening routines, start by scanning element edges, such that elements can then be built on the fly before nodes are processed. Furthermore, as halo meshes comprise halo nodes but not halo elements, all halo nodes will be put at the end of the node array, making un-haloing much easier and inexpensive. Vertex global indices are also different, as vnumtab is only valid for (non-halo) node vertices. The base of the vnumtax array is thus vnodbas, and not s.baseval . Moreover, the contents of vnumtab is based with respect to baseval, and not to vnodbas, so that building the inverse permutation does not require to know vnodbas to trim node indices. When vertex loads are available, node loads represent the number of degrees of freedom per node, and element loads should be set as the sum of the vertex loads of all of their adjacent nodes (used by routines such as vmeshSeparateGg). +*/ typedef struct Mesh_ { MeshFlag flagval; /*+ Graph properties +*/ Gnum baseval; /*+ Base index for edge/vertex arrays +*/ Gnum velmnbr; /*+ Number of element vertices +*/ Gnum velmbas; /*+ Based number of first element +*/ Gnum velmnnd; /*+ Based number of first non-element vertex +*/ Gnum veisnbr; /*+ Number of isolated element vertices +*/ Gnum vnodnbr; /*+ Number of node vertices in mesh +*/ Gnum vnodbas; /*+ Based number of first node +*/ Gnum vnodnnd; /*+ Based number of first non-node vertex +*/ Gnum * verttax; /*+ Vertex array [based] +*/ Gnum * vendtax; /*+ End vertex array [based] +*/ Gnum * velotax; /*+ Element vertex load array (if present) +*/ Gnum * vnlotax; /*+ Node vertex load array (if present) +*/ Gnum velosum; /*+ Sum of element vertex weights +*/ Gnum vnlosum; /*+ Sum of node vertex weights +*/ Gnum * vnumtax; /*+ Vertex number in ancestor graph +*/ Gnum * vlbltax; /*+ Vertex label (from file) +*/ Gnum edgenbr; /*+ Number of edges (arcs) in graph +*/ Gnum * edgetax; /*+ Edge array [based] +*/ Gnum degrmax; /*+ Maximum degree +*/ } Mesh; /* ** The function prototypes. */ #ifndef MESH #define static #endif int meshInit (Mesh * const); void meshExit (Mesh * const); void meshFree (Mesh * const); int meshLoad (Mesh * restrict const, FILE * restrict const, const Gnum); int meshSave (const Mesh * restrict const, FILE * restrict const); Gnum meshBase (Mesh * const, const Gnum); int meshGraph (const Mesh * restrict const, Graph * restrict const); int meshInduceList (const Mesh *, Mesh *, const VertList *); int meshInducePart (const Mesh *, Mesh *, const Gnum, const GraphPart *, const GraphPart); int meshInduceSepa (const Mesh * restrict const, const GraphPart * restrict const, const Gnum, const Gnum * restrict const, Mesh * restrict const); int meshCheck (const Mesh * const); int meshReorder (const Mesh * restrict const, Mesh * restrict const); #ifdef GEOM_H int meshGeomLoadHabo (Mesh * restrict const, Geom * restrict const, FILE * const, FILE * const, const char * const); int meshGeomLoadScot (Mesh * restrict const, Geom * restrict const, FILE * const, FILE * const, const char * const); int meshGeomSaveScot (const Mesh * restrict const, const Geom * restrict const, FILE * const, FILE * const, const char * const); #endif /* GEOM_H */ #undef static scotch-6.0.4.dfsg/src/libscotch/hgraph_induce_edge.c0000644002563400244210000002747612473174437025616 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010,2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hgraph_induce_edge.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This commodity file contains the edge **/ /** arrays building subroutine which is **/ /** duplicated, with minor modifications, **/ /** into hgraph_induce.c **/ /** **/ /** DATES : # Version 4.0 : from : 10 jan 2002 **/ /** to 17 jan 2003 **/ /** # Version 5.0 : from : 19 dec 2006 **/ /** to 19 dec 2006 **/ /** # Version 5.1 : from : 24 oct 2010 **/ /** to 24 oct 2010 **/ /** # Version 6.0 : from : 22 mar 2012 **/ /** to 07 nov 2014 **/ /** **/ /************************************************************/ static void HGRAPHINDUCE2NAME ( const Hgraph * restrict const orggrafptr, /* Pointer to original halo graph */ Gnum * restrict const orgindxtax, /* Array of numbers of selected vertices */ Hgraph * restrict const indgrafptr) /* Pointer to induced halo graph */ { Gnum indvertnum; /* Number of current induced vertex */ Gnum indvertnnd; /* Number of after-last induced (halo) vertex */ Gnum indvelosum; /* Overall induced vertex load */ Gnum indedgenum; /* Number of current edge in induced halo subgraph */ Gnum indenohnbr; /* Number of non-halo edges in halo subgraph */ Gnum inddegrmax; /* Maximum degree */ #ifdef SCOTCH_DEBUG_HGRAPH2 Gnum indedgenbs; /* Revised number of edges in halo subgraph */ #endif /* SCOTCH_DEBUG_HGRAPH2 */ #ifdef HGRAPHINDUCE2L /* If edge loads present */ Gnum indedlosum; Gnum indenohsum; #endif /* HGRAPHINDUCE2L */ const Gnum * restrict const orgverttax = orggrafptr->s.verttax; const Gnum * restrict const orgvendtax = orggrafptr->s.vendtax; const Gnum * restrict const orgvelotax = orggrafptr->s.velotax; const Gnum * restrict const orgvnumtax = orggrafptr->s.vnumtax; const Gnum * restrict const orgedgetax = orggrafptr->s.edgetax; Gnum * restrict const indvnhdtax = indgrafptr->vnhdtax; Gnum * restrict const indverttax = indgrafptr->s.verttax; Gnum * restrict const indvelotax = indgrafptr->s.velotax; Gnum * restrict const indvnumtax = indgrafptr->s.vnumtax; Gnum * restrict const indedgetax = indgrafptr->s.edgetax; #ifdef HGRAPHINDUCE2L /* If edge loads present */ const Gnum * restrict const orgedlotax = orggrafptr->s.edlotax; Gnum * restrict indedlotax = indgrafptr->s.edlotax; /* Not const because location will change */ indedlosum = indenohsum = 0; #endif /* HGRAPHINDUCE2L */ inddegrmax = 0; for (indvertnum = indedgenum = indgrafptr->s.baseval, indvelosum = indenohnbr = 0, indvertnnd = indgrafptr->vnohnnd; /* For all non-halo vertices */ indvertnum < indgrafptr->vnohnnd; indvertnum ++) { Gnum orgvertnum; /* Number of current vertex in original halo graph */ Gnum orgedgenum; /* Number of current edge in original halo graph */ Gnum indedgennd; /* Index of after-last edge position in edge array */ Gnum indedhdnum; /* Index of after-last edge linking to non-halo vertices */ Gnum inddegrval; orgvertnum = indvnumtax[indvertnum]; indverttax[indvertnum] = indedgenum; indenohnbr -= indedgenum; /* Subtract base of non-halo edges */ if (indvelotax != NULL) { /* If graph has vertex weights */ indvelosum += /* Accumulate vertex loads */ indvelotax[indvertnum] = orgvelotax[orgvertnum]; } inddegrval = orgvendtax[orgvertnum] - orgverttax[orgvertnum]; /* Get degree of non-halo node */ if (inddegrmax < inddegrval) /* Keep maximum degree */ inddegrmax = inddegrval; for (orgedgenum = orgverttax[orgvertnum], indedhdnum = indedgennd = indedgenum + inddegrval; orgedgenum < orgvendtax[orgvertnum]; orgedgenum ++) { Gnum orgvertend; /* Number of current end vertex in original halo graph */ Gnum indvertend; /* Number of current end vertex in induced halo subgraph */ orgvertend = orgedgetax[orgedgenum]; indvertend = orgindxtax[orgvertend]; if (indvertend == ~0) { /* If neighbor is yet undeclared halo vertex */ indvnumtax[indvertnnd] = orgvertend; /* Add number of halo vertex to array */ indvertend = orgindxtax[orgvertend] = indvertnnd ++; /* Get induced number of vertex */ } if (indvertend >= indgrafptr->vnohnnd) { /* If neighbor is halo vertex */ indedhdnum --; /* Add neighbor at end of edge sub-array */ indedgetax[indedhdnum] = indvertend; HGRAPHINDUCE2EDLOINIT (indedhdnum); } else { /* If heighbor is non-halo vertex */ indedgetax[indedgenum] = indvertend; /* Add neighbor at beginning of edge sub-array */ HGRAPHINDUCE2EDLOINIT (indedgenum); HGRAPHINDUCE2ENOHINIT; indedgenum ++; } } #ifdef SCOTCH_DEBUG_HGRAPH2 if (indedgenum != indedhdnum) { errorPrint (STRINGIFY (HGRAPHINDUCE2NAME) ": internal error (1)"); return; } #endif /* SCOTCH_DEBUG_HGRAPH2 */ indenohnbr += indedhdnum; /* Add position to number of non-halo edges */ indvnhdtax[indvertnum] = indedhdnum; /* Set end of non-halo sub-array */ indedgenum = indedgennd; /* Point to next free space in edge array */ } indgrafptr->vnlosum = (indvelotax != NULL) ? indvelosum : indgrafptr->vnohnbr; indgrafptr->enohnbr = indenohnbr; #ifdef SCOTCH_DEBUG_HGRAPH2 indedgenbs = 2 * (indedgenum - indgrafptr->s.baseval) - indenohnbr; /* Compute total number of edges */ #endif /* SCOTCH_DEBUG_HGRAPH2 */ #ifdef HGRAPHINDUCE2L /* If edge loads present */ { Gnum * indedgetab; /* Dummy area to recieve un-based edgetab */ Gnum * indedlotab; /* Save of old position of edgetab array */ #ifndef SCOTCH_DEBUG_HGRAPH2 Gnum indedgenbs; /* Revised number of edges in halo subgraph */ indedgenbs = 2 * (indedgenum - indgrafptr->s.baseval) - indenohnbr; /* Compute total number of edges */ #endif /* SCOTCH_DEBUG_HGRAPH2 */ indedlotab = indedlotax + indgrafptr->s.baseval; /* Save old offset of move area */ memOffset (indedgetax + indgrafptr->s.baseval, /* Compute new offsets */ &indedgetab, (size_t) (indedgenbs * sizeof (Gnum)), &indedlotax, (size_t) (indedgenbs * sizeof (Gnum)), NULL); memMov (indedlotax, indedlotab, (indedgenum - indgrafptr->s.baseval) * sizeof (Gnum)); /* Move already existing edge load array */ indgrafptr->s.edlotax = /* Record new position of edge load array */ indedlotax -= indgrafptr->s.baseval; } #endif /* HGRAPHINDUCE2L */ for ( ; indvertnum < indvertnnd; indvertnum ++) { /* For all halo vertices found during first pass */ Gnum orgvertnum; /* Number of current vertex in original halo graph */ Gnum orgedgenum; /* Number of current edge in original halo graph */ orgvertnum = indvnumtax[indvertnum]; indverttax[indvertnum] = indedgenum; if (indvelotax != NULL) { /* If graph has vertex weights */ indvelosum += /* Accumulate vertex loads */ indvelotax[indvertnum] = orgvelotax[orgvertnum]; } for (orgedgenum = orgverttax[orgvertnum]; orgedgenum < orgvendtax[orgvertnum]; orgedgenum ++) { Gnum orgvertend; /* Number of current end vertex in original halo graph */ Gnum indvertend; /* Number of current end vertex in induced halo subgraph */ orgvertend = orgedgetax[orgedgenum]; indvertend = orgindxtax[orgvertend]; if ((indvertend != ~0) && /* If end vertex in induced halo subgraph */ (indvertend < indgrafptr->vnohnnd)) { /* And in its non-halo part only */ indedgetax[indedgenum] = indvertend; HGRAPHINDUCE2EDLOINIT (indedgenum); indedgenum ++; } } if (inddegrmax < (indedgenum - indverttax[indvertnum])) inddegrmax = (indedgenum - indverttax[indvertnum]); } #ifdef SCOTCH_DEBUG_HGRAPH2 if ((indedgenum - indgrafptr->s.baseval) != indedgenbs) { errorPrint (STRINGIFY (HGRAPHINDUCE2NAME) ": internal error (2)"); return; } #endif /* SCOTCH_DEBUG_HGRAPH2 */ indverttax[indvertnnd] = indedgenum; /* Set end of compact vertex array */ indgrafptr->s.vertnbr = indvertnnd - indgrafptr->s.baseval; indgrafptr->s.vertnnd = indvertnnd; indgrafptr->s.velosum = (indvelotax != NULL) ? indvelosum : indgrafptr->s.vertnbr; indgrafptr->s.edgenbr = indedgenum - indgrafptr->s.baseval; /* Set actual number of edges */ indgrafptr->s.edlosum = HGRAPHINDUCE2EDLOSUM; indgrafptr->s.degrmax = inddegrmax; indgrafptr->enohsum = HGRAPHINDUCE2ENOHSUM; } scotch-6.0.4.dfsg/src/libscotch/dgraph_halo.h0000644002563400244210000001021611631447170024257 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_halo.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the data declara- **/ /** tions for the asynchronous halo **/ /** exchange routine. **/ /** **/ /** DATES : # Version 5.0 : from : 28 dec 2007 **/ /** to : 05 feb 2008 **/ /** # Version 5.1 : from : 28 aug 2008 **/ /** to : 04 nov 2010 **/ /** **/ /************************************************************/ /* ** The defines. */ /* procsidtab-related values. */ #define DGRAPHGHSTSIDMAX ((int) ((unsigned int) (1 << (sizeof (int) * 8 - 1)) - 2U)) /* Maximum leap value for procsidtab entries */ /* ** The type and structure definitions. */ /* Sort structure for ghost edges. */ typedef struct DgraphHaloRequest_ { int flagval; #ifdef SCOTCH_PTHREAD Dgraph * grafptr; /* Pointer to graph data */ void * attrgsttab; /* Attribute array to share */ MPI_Datatype attrglbtype; /* Attribute datatype */ pthread_t thrdval; /* Data of asynchronous thread */ #else /* SCOTCH_PTHREAD */ #ifdef SCOTCH_MPI_ASYNC_COLL byte * attrsndtab; /* Group leader for memory freeing */ MPI_Request requval; /* MPI asynchronous communication request */ #endif /* SCOTCH_MPI_ASYNC_COLL */ #endif /* SCOTCH_PTHREAD */ } DgraphHaloRequest; /* ** The function prototypes. */ #ifndef DGRAPH_HALO #define static #endif #ifdef SCOTCH_PTHREAD static void * dgraphHaloAsync2 (DgraphHaloRequest * restrict); #endif /* SCOTCH_PTHREAD */ void dgraphHaloAsync (Dgraph * restrict const, void * restrict const, const MPI_Datatype, DgraphHaloRequest * restrict); int dgraphHaloWait (DgraphHaloRequest * restrict); int dgraphHaloCheck (const Dgraph * restrict const); #undef static scotch-6.0.4.dfsg/src/libscotch/library_graph_check.c0000644002563400244210000000650511631447170025772 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_check.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the source **/ /** graph handling routines of the **/ /** libSCOTCH library. **/ /** **/ /** DATES : # Version 3.2 : from : 18 aug 1998 **/ /** to 18 aug 1998 **/ /** # Version 3.3 : from : 02 oct 1998 **/ /** to 01 nov 2001 **/ /** # Version 4.0 : from : 11 dec 2001 **/ /** to 22 apr 2004 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "graph.h" #include "scotch.h" /************************************/ /* */ /* These routines are the C API for */ /* the graph handling routines. */ /* */ /************************************/ /*+ This routine checks the consistency *** of the given graph. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphCheck ( const SCOTCH_Graph * const grafptr) { return (graphCheck ((const Graph * const) grafptr)); } scotch-6.0.4.dfsg/src/libscotch/arch_tleaf.c0000644002563400244210000005057311774051527024111 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : arch_tleaf.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module handles the tree-leaf **/ /** target architecture. **/ /** **/ /** DATES : # Version 0.0 : from : 01 dec 1992 **/ /** to : 24 mar 1993 **/ /** # Version 1.2 : from : 04 feb 1994 **/ /** to : 11 feb 1994 **/ /** # Version 1.3 : from : 20 apr 1994 **/ /** to : 20 apr 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to : 23 dec 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to : 29 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 08 sep 1995 **/ /** # Version 3.1 : from : 20 jul 1996 **/ /** to 20 jul 1996 **/ /** # Version 3.2 : from : 10 oct 1996 **/ /** to 14 may 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 3.4 : from : 07 jun 2001 **/ /** to 07 jun 2001 **/ /** # Version 4.0 : from : 10 dec 2003 **/ /** to 10 mar 2005 **/ /** # Version 5.1 : from : 21 jan 2008 **/ /** to 11 aug 2010 **/ /** # Version 6.0 : from : 14 fev 2011 **/ /** to 01 jul 2012 **/ /** **/ /** NOTES : # The ltleaf architecture was proposed **/ /** by Emmanuel Jeannot and Francois **/ /** Tessier. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define ARCH_TLEAF #include "module.h" #include "common.h" #include "arch.h" #include "arch_tleaf.h" /*******************************************/ /* */ /* These are the tree-leaf graph routines. */ /* */ /*******************************************/ /* This routine loads the ** tree leaf architecture. ** It returns: ** - 0 : if the architecture has been successfully read. ** - !0 : on error. */ int archTleafArchLoad ( ArchTleaf * restrict const archptr, FILE * restrict const stream) { Anum sizeval; Anum levlnum; #ifdef SCOTCH_DEBUG_ARCH1 if ((sizeof (ArchTleaf) > sizeof (ArchDummy)) || (sizeof (ArchTleafDom) > sizeof (ArchDomDummy))) { errorPrint ("archTleafArchLoad: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ if (intLoad (stream, &archptr->levlnbr) != 1) { errorPrint ("archTleafArchLoad: bad input (1)"); return (1); } if ((archptr->sizetab = memAlloc ((archptr->levlnbr * 2 + 1) * sizeof (Anum))) == NULL) { /* TRICK: One more slot for linktab[-1] */ errorPrint ("archTleafArchLoad: out of memory"); return (1); } archptr->linktab = archptr->sizetab + archptr->levlnbr + 1; /* TRICK: One more slot */ archptr->linktab[-1] = 0; /* Dummy slot for for level-0 communication */ archptr->permtab = NULL; /* Assume no permutation array */ for (levlnum = 0, sizeval = 1; levlnum < archptr->levlnbr; levlnum ++) { if ((intLoad (stream, &archptr->sizetab[levlnum]) != 1) || (intLoad (stream, &archptr->linktab[levlnum]) != 1) || (archptr->sizetab[levlnum] < 2) || (archptr->linktab[levlnum] < 1)) { errorPrint ("archTleafArchLoad: bad input (2)"); return (1); } sizeval *= archptr->sizetab[levlnum]; } archptr->termnbr = sizeval; return (0); } /* This routine frees the tree ** leaf architecture structures. ** It returns: ** - 0 : if the architecture has been successfully freed. ** - !0 : on error. */ int archTleafArchFree ( ArchTleaf * const archptr) { #ifdef SCOTCH_DEBUG_ARCH1 if ((sizeof (ArchTleaf) > sizeof (ArchDummy)) || (sizeof (ArchTleafDom) > sizeof (ArchDomDummy))) { errorPrint ("archTleafArchFree: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ memFree (archptr->sizetab); /* Free group leader */ if (archptr->permtab != NULL) memFree (archptr->permtab); /* Free group leader */ #ifdef SCOTCH_DEBUG_ARCH2 archptr->sizetab = archptr->linktab = archptr->permtab = NULL; #endif /* SCOTCH_DEBUG_ARCH2 */ return (0); } /* This routine saves the ** tree leaf architecture. ** It returns: ** - 0 : if the architecture has been successfully written. ** - !0 : on error. */ int archTleafArchSave ( const ArchTleaf * const archptr, FILE * restrict const stream) { Anum levlnum; #ifdef SCOTCH_DEBUG_ARCH1 if ((sizeof (ArchTleaf) > sizeof (ArchDummy)) || (sizeof (ArchTleafDom) > sizeof (ArchDomDummy))) { errorPrint ("archTleafArchSave: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ if (fprintf (stream, ANUMSTRING, (Anum) archptr->levlnbr) == EOF) { errorPrint ("archTleafArchSave: bad output (1)"); return (1); } for (levlnum = 0; levlnum < archptr->levlnbr; levlnum ++) { if (fprintf (stream, " " ANUMSTRING " " ANUMSTRING, (Anum) archptr->sizetab[levlnum], (Anum) archptr->linktab[levlnum]) == EOF) { errorPrint ("archTleafArchSave: bad output (2)"); return (1); } } return (0); } /* This function returns the smallest number ** of terminal domain included in the given ** domain. */ ArchDomNum archTleafDomNum ( const ArchTleaf * const archptr, const ArchTleafDom * const domnptr) { Anum levlnum; Anum sizeval; sizeval = 1; /* Compute size of blocks below */ for (levlnum = domnptr->levlnum; levlnum < archptr->levlnbr; levlnum ++) sizeval *= archptr->sizetab[levlnum]; return (domnptr->indxmin * sizeval); } /* This function returns the terminal domain associated ** with the given terminal number in the architecture. ** It returns: ** - 0 : if label is valid and domain has been updated. ** - 1 : if label is invalid. ** - 2 : on error. */ int archTleafDomTerm ( const ArchTleaf * const archptr, ArchTleafDom * const domnptr, const ArchDomNum domnnum) { #ifdef SCOTCH_DEBUG_ARCH2 if (domnnum < 0) { errorPrint ("archTleafDomTerm: invalid parameter"); return (1); } #endif /* SCOTCH_DEBUG_ARCH2 */ if (domnnum < archptr->termnbr) { /* If valid label */ domnptr->levlnum = archptr->levlnbr; /* Set the domain */ domnptr->indxmin = domnnum; domnptr->indxnbr = 1; return (0); } return (1); /* Cannot set domain */ } /* This function returns the number of ** elements in the subtree domain. */ Anum archTleafDomSize ( const ArchTleaf * const archptr, const ArchTleafDom * const domnptr) { Anum levlnum; Anum sizeval; sizeval = 1; /* Compute size of blocks below */ for (levlnum = domnptr->levlnum; levlnum < archptr->levlnbr; levlnum ++) sizeval *= archptr->sizetab[levlnum]; return (sizeval * domnptr->indxnbr); } /* This function returns the average ** distance between two tree leaf ** subdomains. */ Anum archTleafDomDist ( const ArchTleaf * const archptr, const ArchTleafDom * const dom0ptr, const ArchTleafDom * const dom1ptr) { Anum lev0num; Anum lev1num; Anum idx0min; Anum idx1min; Anum idx0nbr; Anum idx1nbr; Anum distval; const Anum * const sizetab = archptr->sizetab; lev0num = dom0ptr->levlnum; lev1num = dom1ptr->levlnum; idx0min = dom0ptr->indxmin; idx1min = dom1ptr->indxmin; idx0nbr = dom0ptr->indxnbr; idx1nbr = dom1ptr->indxnbr; if (lev0num != lev1num) { if (lev0num > lev1num) { idx0nbr = 1; do { lev0num --; idx0min /= sizetab[lev0num]; } while (lev0num > lev1num); } else { idx1nbr = 1; do { lev1num --; idx1min /= sizetab[lev1num]; } while (lev1num > lev0num); } } distval = archptr->linktab[lev0num - 1]; /* Get cost at this level */ return (((idx0min >= (idx1min + idx1nbr)) || /* If inclusion, only half of the distance */ (idx1min >= (idx0min + idx0nbr))) ? distval : ((idx0nbr == idx1nbr) ? 0 : (distval >> 1))); } /* This function sets the biggest ** domain available for this ** architecture. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archTleafDomFrst ( const ArchTleaf * const archptr, ArchTleafDom * restrict const domnptr) { domnptr->levlnum = 0; domnptr->indxmin = 0; domnptr->indxnbr = 1; /* The root vertex is unique */ return (0); } /* This routine reads domain information ** from the given stream. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archTleafDomLoad ( const ArchTleaf * const archptr, ArchTleafDom * restrict const domnptr, FILE * const stream) { if ((intLoad (stream, &domnptr->levlnum) != 1) || (intLoad (stream, &domnptr->indxmin) != 1) || (intLoad (stream, &domnptr->indxnbr) != 1) || (domnptr->levlnum < 0) || (domnptr->levlnum > archptr->levlnbr)) { errorPrint ("archTleafDomLoad: bad input"); return (1); } return (0); } /* This routine saves domain information ** to the given stream. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archTleafDomSave ( const ArchTleaf * const archptr, const ArchTleafDom * const domnptr, FILE * const stream) { if (fprintf (stream, ANUMSTRING " " ANUMSTRING " " ANUMSTRING " ", (Anum) domnptr->levlnum, (Anum) domnptr->indxmin, (Anum) domnptr->indxnbr) == EOF) { errorPrint ("archTleafDomSave: bad output"); return (1); } return (0); } /* This function tries to split a tree leaf ** domain into two subdomains. ** It returns: ** - 0 : if bipartitioning succeeded. ** - 1 : if bipartitioning could not be performed. ** - 2 : on error. */ int archTleafDomBipart ( const ArchTleaf * const archptr, const ArchTleafDom * const domnptr, ArchTleafDom * restrict const dom0ptr, ArchTleafDom * restrict const dom1ptr) { Anum sizeval; if (domnptr->indxnbr <= 1) { /* If dubdomain has only one node at this level */ if (domnptr->levlnum >= archptr->levlnbr) /* Return if cannot bipartition more */ return (1); sizeval = archptr->sizetab[domnptr->levlnum]; /* Partition all the vertices of a new level */ dom0ptr->levlnum = dom1ptr->levlnum = domnptr->levlnum + 1; dom0ptr->indxmin = domnptr->indxmin * sizeval; } else { /* Subdomain has several indices */ sizeval = domnptr->indxnbr; /* Base on existing block size */ dom0ptr->levlnum = /* Stay at same level */ dom1ptr->levlnum = domnptr->levlnum; dom0ptr->indxmin = domnptr->indxmin; /* Start from the existing start index */ } dom0ptr->indxnbr = (sizeval + 1) >> 1; /* Subdomain 0 is always the largest one */ dom1ptr->indxmin = dom0ptr->indxmin + dom0ptr->indxnbr; dom1ptr->indxnbr = sizeval - dom0ptr->indxnbr; return (0); } /* This function checks if dom1 is ** included in dom0. ** It returns: ** - 0 : if dom1 is not included in dom0. ** - 1 : if dom1 is included in dom0. ** - 2 : on error. */ int archTleafDomIncl ( const ArchTleaf * const archptr, const ArchTleafDom * const dom0ptr, const ArchTleafDom * const dom1ptr) { Anum lev0num; Anum lev1num; Anum idx0min; Anum idx1min; Anum idx0nbr; Anum idx1nbr; const Anum * const sizetab = archptr->sizetab; lev0num = dom0ptr->levlnum; lev1num = dom1ptr->levlnum; idx0min = dom0ptr->indxmin; idx1min = dom1ptr->indxmin; idx0nbr = dom0ptr->indxnbr; idx1nbr = dom1ptr->indxnbr; if (lev0num != lev1num) { if (lev1num > lev0num) { idx1nbr = 1; do { lev1num --; idx1min /= sizetab[lev1num]; } while (lev1num > lev0num); } else return (0); } return (((idx0min >= (idx1min + idx1nbr)) || (idx1min >= (idx0min + idx0nbr))) ? 0 : 1); } /* This function creates the MPI_Datatype for ** tree-leaf domains. ** It returns: ** - 0 : if type could be created. ** - 1 : on error. */ #ifdef SCOTCH_PTSCOTCH int archTleafDomMpiType ( const ArchTleaf * const archptr, MPI_Datatype * const typeptr) { MPI_Type_contiguous (3, ANUM_MPI, typeptr); return (0); } #endif /* SCOTCH_PTSCOTCH */ /***********************************/ /* */ /* These are the labeled tree-leaf */ /* graph routines. */ /* */ /***********************************/ /* This routine loads the labeled ** tree leaf architecture. ** It returns: ** - 0 : if the architecture has been successfully read. ** - !0 : on error. */ int archLtleafArchLoad ( ArchTleaf * restrict const archptr, FILE * restrict const stream) { Anum sizeval; Anum levlnum; Anum permnum; if (archTleafArchLoad (archptr, stream) != 0) /* Read tree part */ return (1); if ((intLoad (stream, &archptr->permnbr) != 1) || (archptr->permnbr <= 0)) { errorPrint ("archLtleafArchLoad: bad input (1)"); return (1); } #ifdef SCOTCH_DEBUG_ARCH2 if (archptr->permnbr != 1) { /* Valid empty permutation is of size 1 */ for (levlnum = archptr->levlnbr - 1, sizeval = archptr->sizetab[levlnum]; sizeval != archptr->permnbr; levlnum --, sizeval *= archptr->sizetab[levlnum]) { if (levlnum < 0) { errorPrint ("archLtleafArchLoad: permutation size does not match level boundaries"); return (1); } } } #endif /* SCOTCH_DEBUG_ARCH2 */ if ((archptr->permtab = memAlloc (archptr->permnbr * 2 * sizeof (Anum))) == NULL) { /* TRICK: space for peritab too */ errorPrint ("archLtleafArchLoad: out of memory"); return (1); } for (permnum = 0; permnum < archptr->permnbr; permnum ++) { #ifdef SCOTCH_DEBUG_ARCH2 Anum permtmp; #endif /* SCOTCH_DEBUG_ARCH2 */ if ((intLoad (stream, &archptr->permtab[permnum]) != 1) || (archptr->permtab[permnum] < 0) || (archptr->permtab[permnum] >= archptr->permnbr)) { errorPrint ("archLtleafArchLoad: bad input (2)"); return (1); } #ifdef SCOTCH_DEBUG_ARCH2 for (permtmp = 0; permtmp < permnum; permtmp ++) { if (archptr->permtab[permtmp] == archptr->permtab[permnum]) { errorPrint ("archLtleafArchLoad: duplicate permutation index"); return (1); } } #endif /* SCOTCH_DEBUG_ARCH2 */ } archptr->peritab = archptr->permtab + archptr->permnbr; for (permnum = 0; permnum < archptr->permnbr; permnum ++) /* Build inverse permutation */ archptr->peritab[archptr->permtab[permnum]] = permnum; return (0); } /* This routine saves the labeled ** tree leaf architecture. ** It returns: ** - 0 : if the architecture has been successfully written. ** - !0 : on error. */ int archLtleafArchSave ( const ArchTleaf * const archptr, FILE * restrict const stream) { Anum permnum; if (archTleafArchSave (archptr, stream) != 0) /* Save tree part */ return (1); if (fprintf (stream, ANUMSTRING, (Anum) archptr->permnbr) == EOF) { errorPrint ("archLtleafArchSave: bad output (1)"); return (1); } for (permnum = 0; permnum < archptr->permnbr; permnum ++) { if (fprintf (stream, " " ANUMSTRING, (Anum) archptr->permtab[permnum]) == EOF) { errorPrint ("archLtleafArchSave: bad output (2)"); return (1); } } return (0); } /* This function returns the smallest number ** of terminal domain included in the given ** domain. */ ArchDomNum archLtleafDomNum ( const ArchTleaf * const archptr, const ArchTleafDom * const domnptr) { Anum levlnum; Anum sizeval; Anum domnnum; Anum permnum; sizeval = 1; /* Compute size of blocks below */ for (levlnum = domnptr->levlnum; levlnum < archptr->levlnbr; levlnum ++) sizeval *= archptr->sizetab[levlnum]; domnnum = domnptr->indxmin * sizeval; permnum = domnnum % archptr->permnbr; /* Get non permuted index as terminal domain */ return (domnnum - permnum + archptr->permtab[permnum]); /* Return permuted index */ } /* This function returns the terminal domain associated ** with the given terminal number in the architecture. ** It returns: ** - 0 : if label is valid and domain has been updated. ** - 1 : if label is invalid. ** - 2 : on error. */ int archLtleafDomTerm ( const ArchTleaf * const archptr, ArchTleafDom * const domnptr, const ArchDomNum domnnum) { #ifdef SCOTCH_DEBUG_ARCH2 if (domnnum < 0) { errorPrint ("archLtleafDomTerm: invalid parameter"); return (1); } #endif /* SCOTCH_DEBUG_ARCH2 */ if (domnnum < archptr->termnbr) { /* If valid label */ Anum permnum; permnum = domnnum % archptr->permnbr; /* Get permuted index as terminal domain */ domnptr->levlnum = archptr->levlnbr; /* Set the domain */ domnptr->indxmin = domnnum - permnum + archptr->peritab[permnum]; domnptr->indxnbr = 1; return (0); } return (1); /* Cannot set domain */ } scotch-6.0.4.dfsg/src/libscotch/hdgraph_check.c0000644002563400244210000001462011631447170024557 0ustar trophimeutilisateurs du domaine/* Copyright 2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hdgraph_check.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a parallel static mapper. **/ /** This module contains the distributed **/ /** graph consistency checking routine. **/ /** **/ /** # Version 5.0 : from : 21 apr 2006 **/ /** to : 29 apr 2006 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HDGRAPH_CHECK #include "module.h" #include "common.h" #include "dgraph.h" #include "hdgraph.h" /******************************/ /* */ /* These routines handle halo */ /* distributed source graphs. */ /* */ /******************************/ /* This function checks the consistency ** of the given halo distributed graph. ** It returns: ** - 0 : if graph data are consistent. ** - !0 : on error. */ int hdgraphCheck ( const Hdgraph * restrict const grafptr) { Gnum vertlocnum; int * restrict vhalloctax; /* Flag array for halo vertices */ Gnum vhallocnnd; Gnum vhallocnum; Gnum ehallocnbr; int cheklocval; /* Local consistency flag */ int chekglbval; /* Global consistency flag */ cheklocval = 0; for (vertlocnum = grafptr->s.baseval, ehallocnbr = 0; vertlocnum < grafptr->s.vertlocnnd; vertlocnum ++) { if ((grafptr->vhndloctax[vertlocnum] < grafptr->s.vendloctax[vertlocnum]) || (grafptr->vhndloctax[vertlocnum] > (grafptr->s.edgelocsiz + grafptr->s.baseval))) { errorPrint ("hdgraphCheck: inconsistent local vertex arrays"); cheklocval = 1; } ehallocnbr += grafptr->vhndloctax[vertlocnum] - grafptr->s.vendloctax[vertlocnum]; } if (ehallocnbr != grafptr->ehallocnbr) { errorPrint ("hdgraphCheck: invalid local number of halo edges"); cheklocval = 1; } if ((grafptr->vhallocnbr < 0) || (grafptr->vhallocnbr > grafptr->s.edgelocsiz)) { errorPrint ("hdgraphCheck: invalid local number of halo vertices"); cheklocval = 1; } vhalloctax = NULL; if ((cheklocval == 0) && ((vhalloctax = (int *) memAlloc (grafptr->vhallocnbr * sizeof (int))) == NULL)) { errorPrint ("hdgraphCheck: out of memory"); cheklocval = 1; } if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, grafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("hdgraphCheck: communication error (1)"); return (1); } if (chekglbval != 0) { if (vhalloctax != NULL) memFree (vhalloctax); return (1); } memSet (vhalloctax, ~0, grafptr->vhallocnbr * sizeof (int)); vhalloctax -= grafptr->s.baseval; vhallocnnd = grafptr->vhallocnbr + grafptr->s.baseval; for (vertlocnum = grafptr->s.baseval; vertlocnum < grafptr->s.vertlocnnd; vertlocnum ++) { Gnum edgelocnum; for (edgelocnum = grafptr->s.vendloctax[vertlocnum]; edgelocnum < grafptr->vhndloctax[vertlocnum]; edgelocnum ++) { Gnum vhallocend; vhallocend = grafptr->s.edgeloctax[edgelocnum]; if ((vhallocend < grafptr->s.baseval) || (vhallocend >= vhallocnnd)) { errorPrint ("hdgraphCheck: invalid halo vertex number"); vertlocnum = grafptr->s.vertlocnnd; /* Avoid unwanted cascaded error messages */ cheklocval = 1; break; } vhalloctax[vhallocend] = 0; /* Flag halo vertex as used */ } } if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, grafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("hdgraphCheck: communication error (2)"); return (1); } if (chekglbval != 0) { memFree (vhalloctax + grafptr->s.baseval); return (1); } for (vhallocnum = grafptr->s.baseval; vhallocnum < vhallocnnd; vhallocnum ++) { if (vhalloctax[vhallocnum] != 0) { /* If halo vertex index not used in graph */ errorPrint ("hdgraphCheck: unused halo vertex number"); cheklocval = 1; break; } } memFree (vhalloctax + grafptr->s.baseval); if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, grafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("hdgraphCheck: communication error (3)"); return (1); } if (chekglbval != 0) return (1); return (dgraphCheck (&grafptr->s)); } scotch-6.0.4.dfsg/src/libscotch/library_mesh_io_scot_f.c0000644002563400244210000001626111631447170026514 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_mesh_io_scot_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the Fortran API for the **/ /** mesh i/o routines of the libSCOTCH **/ /** library. **/ /** **/ /** DATES : # Version 4.0 : from : 24 nov 2005 **/ /** to 24 nov 2005 **/ /** # Version 5.1 : from : 27 mar 2010 **/ /** to 27 mar 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the mapping routines. */ /* */ /**************************************/ /* String lengths are passed at the very ** end of the argument list. */ FORTRAN ( \ SCOTCHFMESHGEOMLOADSCOT, scotchfmeshgeomloadscot, ( \ SCOTCH_Mesh * const meshptr, \ SCOTCH_Geom * const geomptr, \ const int * const filegrfptr, \ const int * const filegeoptr, \ const char * const dataptr, /* No use */ \ int * const revaptr, \ const int datanbr), \ (meshptr, geomptr, filegrfptr, filegeoptr, dataptr, revaptr, datanbr)) { FILE * filegrfstream; /* Streams to build from handles */ FILE * filegeostream; int filegrfnum; /* Duplicated handle */ int filegeonum; int o; if ((filegrfnum = dup (*filegrfptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFMESHGEOMLOADSCOT: cannot duplicate handle (1)"); *revaptr = 1; /* Indicate error */ return; } if ((filegeonum = dup (*filegeoptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFMESHGEOMLOADSCOT: cannot duplicate handle (2)"); close (filegrfnum); *revaptr = 1; /* Indicate error */ return; } if ((filegrfstream = fdopen (filegrfnum, "r")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFMESHGEOMLOADSCOT: cannot open input stream (1)"); close (filegrfnum); close (filegeonum); *revaptr = 1; return; } if ((filegeostream = fdopen (filegeonum, "r")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFMESHGEOMLOADSCOT: cannot open input stream (2)"); fclose (filegrfstream); close (filegeonum); *revaptr = 1; return; } o = SCOTCH_meshGeomLoadScot (meshptr, geomptr, filegrfstream, filegeostream, NULL); fclose (filegrfstream); /* This closes file descriptors too */ fclose (filegeostream); *revaptr = o; } /* String lengths are passed at the very ** end of the argument list. */ FORTRAN ( \ SCOTCHFMESHGEOMSAVESCOT, scotchfmeshgeomsavescot, ( \ const SCOTCH_Mesh * const meshptr, \ const SCOTCH_Geom * const geomptr, \ const int * const filegrfptr, \ const int * const filegeoptr, \ const char * const dataptr, /* No use */ \ int * const revaptr, \ const int datanbr), \ (meshptr, geomptr, filegrfptr, filegeoptr, dataptr, revaptr, datanbr)) { FILE * filegrfstream; /* Streams to build from handles */ FILE * filegeostream; int filegrfnum; /* Duplicated handle */ int filegeonum; int o; if ((filegrfnum = dup (*filegrfptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFMESHGEOMSAVESCOT: cannot duplicate handle (1)"); *revaptr = 1; /* Indicate error */ return; } if ((filegeonum = dup (*filegeoptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFMESHGEOMSAVESCOT: cannot duplicate handle (2)"); close (filegrfnum); *revaptr = 1; /* Indicate error */ return; } if ((filegrfstream = fdopen (filegrfnum, "w")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFMESHGEOMSAVESCOT: cannot open output stream (1)"); close (filegrfnum); close (filegeonum); *revaptr = 1; return; } if ((filegeostream = fdopen (filegeonum, "w")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFMESHGEOMSAVESCOT: cannot open output stream (2)"); fclose (filegrfstream); close (filegeonum); *revaptr = 1; return; } o = SCOTCH_meshGeomSaveScot (meshptr, geomptr, filegrfstream, filegeostream, NULL); fclose (filegrfstream); /* This closes file descriptors too */ fclose (filegeostream); *revaptr = o; } scotch-6.0.4.dfsg/src/libscotch/wgraph_part_ml.c0000644002563400244210000003211612474554132025016 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2011,2014,2015 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : wgraph_part_ml.c **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Francois PELLEGRINI **/ /** Charles-Edmond BICHOT (v5.1b) **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module conducts multilevel framew- **/ /** ork for the vertex overlapped graph pa- **/ /** rtitioning. **/ /** **/ /** DATES : # Version 5.1 : from : 01 dec 2007 **/ /** to : 01 jul 2008 **/ /** # Version 6.0 : from : 05 nov 2009 **/ /** to 27 feb 2015 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define WGRAPH_PART_ML #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "arch.h" #include "mapping.h" #include "graph_coarsen.h" #include "wgraph.h" #include "wgraph_part_ml.h" #include "wgraph_part_st.h" /* ** The static variables. */ static const Gnum wgraphpartmlloadone = 1; /*********************************************/ /* */ /* The coarsening and uncoarsening routines. */ /* */ /*********************************************/ /* This routine builds a coarser graph from the ** graph that is given on input. The coarser ** graphs differ at this stage from classical ** active graphs as their internal gains are not ** yet computed. ** It returns: ** - 0 : if the coarse graph has been built. ** - 1 : if threshold achieved or on error. */ static int wgraphPartMlCoarsen ( const Wgraph * restrict const finegrafptr, /*+ Finer graph +*/ Wgraph * restrict const coargrafptr, /*+ Coarser graph to build +*/ GraphCoarsenMulti * restrict * const coarmultptr, /*+ Pointer to un-based multinode table to build +*/ const WgraphPartMlParam * const paraptr) /*+ Method parameters +*/ { *coarmultptr = NULL; /* Allocate coarmulttab along with coarse graph */ if (graphCoarsen (&finegrafptr->s, &coargrafptr->s, coarmultptr, (paraptr->coarnbr * finegrafptr->partnbr), paraptr->coarval, NULL, NULL, 0, NULL) != 0) return (1); /* Return if coarsening failed */ coargrafptr->parttax = NULL; /* Do not allocate partition data yet */ coargrafptr->compload = NULL; coargrafptr->partnbr = finegrafptr->partnbr; coargrafptr->levlnum = finegrafptr->levlnum + 1; /* Graph level is coarsening level */ return (0); } /* This routine propagates the separation of the ** coarser graph back to the finer graph, according ** to the multinode table of collapsed vertices. ** After the separation is propagated, it finishes ** to compute the parameters of the finer graph that ** were not computed at the coarsening stage. ** It returns: ** - 0 : if coarse graph data has been propagated to fine graph. ** - !0 : on error. */ static int wgraphPartMlUncoarsen ( Wgraph * restrict const finegrafptr, /*+ Finer graph +*/ const Wgraph * restrict const coargrafptr, /*+ Coarser graph +*/ const GraphCoarsenMulti * restrict const coarmulttab) /*+ Un-based multinode array +*/ { Gnum coarvertnbr; Gnum coarvertnum; /* Number of current coarse vertex */ const Anum * restrict coarparttab; Anum * restrict fineparttax; Gnum * restrict finefrontab; Gnum finefronnbr; /* Number of frontier vertices in fine graph */ Gnum finevertnum; WgraphPartList * restrict finelisttab; Gnum finevelomsk; const Gnum * restrict finevelobax; /* Data for handling of optional arrays */ Gnum * restrict finecompload; Gnum * restrict finecompsize; const Gnum * restrict const fineverttax = finegrafptr->s.verttax; const Gnum * restrict const finevendtax = finegrafptr->s.vendtax; const Gnum * restrict const fineedgetax = finegrafptr->s.edgetax; if ((finegrafptr->levlnum > 0) && /* If partition data not yet allocated */ (wgraphAlloc (finegrafptr) != 0)) { /* Allocate tables before processing */ errorPrint ("wgraphPartMlUncoarsen: out of memory (1)"); return (1); } if (coargrafptr == NULL) { /* If no coarse graph provided */ wgraphZero (finegrafptr); return (0); } finecompload = finegrafptr->compload; finecompsize = finegrafptr->compsize; if ((finelisttab = (WgraphPartList *) memAlloc ((finegrafptr->partnbr + 1) * sizeof (WgraphPartList))) == NULL) { /* TRICK: "+1" to create slot for a "-1" index */ errorPrint ("wgraphPartMlUncoarsen: out of memory (2)"); return (1); } finelisttab ++; /* TRICK: Trim array so that finelisttab[-1] is valid */ memSet (finelisttab, ~0, finegrafptr->partnbr * sizeof (WgraphPartList)); /* Set vertex indices to ~0 */ memSet (finecompload, 0, finegrafptr->partnbr * sizeof (Gnum)); /* Reset load arrays to 0 */ memSet (finecompsize, 0, finegrafptr->partnbr * sizeof (Gnum)); if (finegrafptr->s.velotax == NULL) { /* Set accesses to optional arrays */ finevelobax = &wgraphpartmlloadone; /* In case vertices not weighted */ finevelomsk = 0; } else { finevelobax = finegrafptr->s.velotax; finevelomsk = ~((Gnum) 0); } finefronnbr = 0; finefrontab = finegrafptr->frontab; fineparttax = finegrafptr->parttax; coarparttab = coargrafptr->parttax + coargrafptr->s.baseval; for (coarvertnum = 0, coarvertnbr = coargrafptr->s.vertnbr; coarvertnum < coarvertnbr; coarvertnum ++) { Anum coarpartval; /* Value of current multinode part */ Gnum finevertnum0; Gnum finevertnum1; coarpartval = coarparttab[coarvertnum]; finevertnum0 = coarmulttab[coarvertnum].vertnum[0]; finevertnum1 = coarmulttab[coarvertnum].vertnum[1]; fineparttax[finevertnum0] = coarpartval; if (coarpartval >= 0) { /* If vertex is not in separator */ if (finevertnum0 != finevertnum1) fineparttax[finevertnum1] = coarpartval; } else { /* Vertex is in separator */ finefrontab[finefronnbr ++] = finevertnum0; if (finevertnum0 != finevertnum1) { fineparttax[finevertnum1] = coarpartval; finefrontab[finefronnbr ++] = finevertnum1; /* One extra vertex in separator */ } } } finegrafptr->fronnbr = finefronnbr; finegrafptr->fronload = coargrafptr->fronload; for (finevertnum = finegrafptr->s.baseval; finevertnum < finegrafptr->s.vertnnd; finevertnum ++) { Anum finepartval; finepartval = fineparttax[finevertnum]; if (finepartval >= 0) { finecompload[finepartval] += finevelobax[finevertnum & finevelomsk]; finecompsize[finepartval] ++; } else { /* Fine vertex is in separator */ Gnum finelistidx; /* Index of first neighbor part */ Gnum fineedgenum; Gnum fineveloval; finelistidx = -1; /* No neighboring parts recorded yet */ finelisttab[-1].vertnum = finevertnum; /* Separator neighbors will not be considered */ for (fineedgenum = fineverttax[finevertnum]; fineedgenum < finevendtax[finevertnum]; fineedgenum ++) { /* Compute gain */ Gnum finevertend; Anum finepartend; finevertend = fineedgetax[fineedgenum]; finepartend = fineparttax[finevertend]; if (finelisttab[finepartend].vertnum != finevertnum) { /* If part not yet considered */ finelisttab[finepartend].vertnum = finevertnum; /* Link it in list of neighbors */ finelisttab[finepartend].nextidx = finelistidx; finelistidx = finepartend; } } fineveloval = finevelobax[finevertnum & finevelomsk]; while (finelistidx != -1) { /* For all neighboring parts found */ finecompload[finelistidx] += fineveloval; /* Add load of separator vertex to part */ finecompsize[finelistidx] ++; finelistidx = finelisttab[finelistidx].nextidx; } } } memFree (finelisttab - 1); /* TRICK: free array using its real beginning */ #ifdef SCOTCH_DEBUG_WGRAPH2 if (wgraphCheck (finegrafptr) != 0) { errorPrint ("wgraphPartMlUncoarsen: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_WGRAPH2 */ return (0); } /* This routine recursively performs the partitioning. ** It returns: ** - 0 : if separator could be computed. ** - !0 : on error. */ static int wgraphPartMl2 ( Wgraph * restrict const grafptr, const WgraphPartMlParam * const paraptr) { Wgraph coargrafdat; GraphCoarsenMulti * restrict coarmulttab; int o; if (wgraphPartMlCoarsen (grafptr, &coargrafdat, &coarmulttab, paraptr) == 0) { if (((o = wgraphPartMl2 (&coargrafdat, paraptr)) == 0) && ((o = wgraphPartMlUncoarsen (grafptr, &coargrafdat, coarmulttab)) == 0) && ((o = wgraphPartSt (grafptr, paraptr->stratasc)) != 0)) /* Apply ascending strategy */ errorPrint ("wgraphPartMl2: cannot apply ascending strategy"); wgraphExit (&coargrafdat); } else { /* Cannot coarsen due to lack of memory or error */ if (((o = wgraphPartMlUncoarsen (grafptr, NULL, NULL)) == 0) && /* Finalize graph */ ((o = wgraphPartSt (grafptr, paraptr->stratlow)) != 0)) /* Apply low strategy */ errorPrint ("wgraphPartMl2: cannot apply low strategy"); } return (o); } /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the muti-level separation. ** It returns: ** - 0 : if separator could be computed. ** - 1 : on error. */ int wgraphPartMl ( Wgraph * const wgrafptr, /*+ Vertex-separation graph +*/ const WgraphPartMlParam * const paraptr) /*+ Method parameters +*/ { Gnum levlnum; /* Save value for graph level */ int o; levlnum = wgrafptr->levlnum; /* Save graph level */ wgrafptr->levlnum = 0; /* Initialize coarsening level */ o = wgraphPartMl2 (wgrafptr, paraptr); /* Perform multi-level separation */ wgrafptr->levlnum = levlnum; /* Restore graph level */ return (o); } scotch-6.0.4.dfsg/src/libscotch/dgraph.h0000644002563400244210000004002412030514770023247 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Francois CHATENET (P0.0) **/ /** Sebastien FOUCAULT (P0.0) **/ /** Nicolas GICQUEL (P0.1) **/ /** Jerome LACOSTE (P0.1) **/ /** Cedric CHEVALIER (v5.0) **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the distributed source graph **/ /** structure. **/ /** **/ /** DATES : # Version P0.0 : from : 01 apr 1997 **/ /** to : 20 jun 1997 **/ /** # Version P0.1 : from : 07 apr 1998 **/ /** to : 20 jun 1998 **/ /** # Version P0.2 : from : 11 may 1999 **/ /** to : 02 feb 2000 **/ /** # Version P0.3 : from : 16 jun 2005 **/ /** to : 16 jun 2005 **/ /** # Version 5.0 : from : 22 jul 2005 **/ /** to : 03 aug 2007 **/ /** # Version 5.1 : from : 11 nov 2007 **/ /** to : 20 feb 2011 **/ /** # Version 6.0 : from : 30 aug 2012 **/ /** to : 26 sep 2012 **/ /** **/ /************************************************************/ #define DGRAPH_H #define PTSCOTCH_FOLD_DUP /* Activate folding on coarsening */ #ifndef SCOTCH_COMM_PTOP_RAT #define SCOTCH_COMM_PTOP_RAT 0.25 /* Percentage under which point-to-point is allowed */ #endif /* SCOTCH_COMM_PTOP_RAT */ /* ** The defines. */ /* Graph flags. */ #define DGRAPHNONE 0x0000 /* No options set */ #define DGRAPHFREEPRIV 0x0001 /* Set if private arrays freed on exit */ #define DGRAPHFREECOMM 0x0002 /* MPI communicator has to be freed */ #define DGRAPHFREETABS 0x0004 /* Set if local arrays freed on exit */ #define DGRAPHFREEPSID 0x0008 /* Set if procsidtab freed on exit */ #define DGRAPHFREEEDGEGST 0x0010 /* Set if edgegsttab freed on exit */ #define DGRAPHHASEDGEGST 0x0020 /* Edge ghost array computed */ #define DGRAPHVERTGROUP 0x0040 /* All vertex arrays grouped */ #define DGRAPHEDGEGROUP 0x0080 /* All edge arrays grouped */ #define DGRAPHFREEALL (DGRAPHFREEPRIV | DGRAPHFREECOMM | DGRAPHFREETABS | DGRAPHFREEPSID | DGRAPHFREEEDGEGST) #define DGRAPHCOMMPTOP 0x0100 /* Use point-to-point collective communication */ #define DGRAPHBITSUSED 0x01FF /* Significant bits for plain distributed graph routines */ #define DGRAPHBITSNOTUSED 0x0200 /* Value above which bits not used by plain distributed graph routines */ /* Used in algorithms */ #define COARPERTPRIME 31 /* Prime number */ #define COARHASHPRIME 179 /* Prime number */ /* ** The type and structure definitions. */ /* The graph basic types, which must be signed. */ #ifndef GNUMMAX /* If graph.h not included */ typedef INT Gnum; /* Vertex or edge number */ #define GNUMMAX (INTVALMAX) /* Maximum Gnum value */ #define GNUMSTRING INTSTRING /* String to printf a Gnum */ #endif /* GNUMMAX */ #define GNUM_MPI COMM_INT /* MPI type for Gnum is MPI type for INT */ #define GRAPHPART_MPI COMM_BYTE /* Raw byte type for graph parts */ /* Tags used for point-to-point communications. */ typedef enum DgraphTag_ { TAGPROCVRTTAB = 0, /*+ procvrttab message +*/ TAGVERTLOCTAB, /*+ vertloctab message +*/ TAGVENDLOCTAB, /*+ vendloctab message +*/ TAGVELOLOCTAB, /*+ veloloctab message +*/ TAGVNUMLOCTAB, /*+ vnumloctab message +*/ TAGVLBLLOCTAB, /*+ vlblloctab message +*/ TAGEDGELOCTAB, /*+ edgeloctab message +*/ TAGEDLOLOCTAB, /*+ edloloctab message +*/ TAGDATALOCTAB, /*+ Generic data message +*/ TAGOK, /*+ Positive answer +*/ TAGBAD, /*+ Negative answer +*/ TAGHALO = 100, /*+ Tag class for halo +*/ TAGCOARSEN = 200, /*+ Tag class for coarsening +*/ TAGMATCH = 300, /*+ Tag class for matching +*/ TAGFOLD = 400, /*+ Tag class for folding +*/ TAGBAND = 500 /*+ Tag class for band graph +*/ } DgraphTag; /*+ The graph flag type. +*/ typedef int DgraphFlag; /*+ Graph property flags +*/ /*+ The vertex part type, in compressed form. From graph.h +*/ #ifndef GRAPH_H typedef byte GraphPart; #endif /* GRAPH_H */ /* The distributed graph structure. */ typedef struct Dgraph_ { DgraphFlag flagval; /*+ Graph properties +*/ Gnum baseval; /*+ Base index for edge/vertex arrays +*/ Gnum vertglbnbr; /*+ Global number of vertices +*/ Gnum vertglbmax; /*+ Maximum number of local vertices over all processes +*/ Gnum vertgstnbr; /*+ Number of local + ghost vertices +*/ Gnum vertgstnnd; /*+ vertgstnbr + baseval +*/ Gnum vertlocnbr; /*+ Local number of vertices +*/ Gnum vertlocnnd; /*+ Local number of vertices + baseval +*/ Gnum * vertloctax; /*+ Local vertex beginning index array [based] +*/ Gnum * vendloctax; /*+ Local vertex end index array [based] +*/ Gnum * veloloctax; /*+ Local vertex load array if present +*/ Gnum velolocsum; /*+ Local sum of all vertex loads +*/ Gnum veloglbsum; /*+ Global sum of all vertex loads +*/ Gnum * vnumloctax; /*+ Arrays of global vertex numbers in original graph +*/ Gnum * vlblloctax; /*+ Arrays of vertex labels (when read from file) +*/ Gnum edgeglbnbr; /*+ Global number of arcs +*/ Gnum edgeglbmax; /*+ Maximum number of local edges over all processes +*/ Gnum edgelocnbr; /*+ Number of local edges +*/ Gnum edgelocsiz; /*+ Size of local edge array (= edgelocnbr when compact) +*/ Gnum edgeglbsmx; /*+ Maximum size of local edge arrays over all processes +*/ Gnum * edgegsttax; /*+ Edge array holding local indices of neighbors [based] +*/ Gnum * edgeloctax; /*+ Edge array holding global neighbor numbers [based] +*/ Gnum * edloloctax; /*+ Edge load array +*/ Gnum degrglbmax; /*+ Maximum degree over all processes +*/ MPI_Comm proccomm; /*+ Graph communicator +*/ int prockeyval; /*+ Communicator key value: folded communicators are distinct +*/ int procglbnbr; /*+ Number of processes sharing graph data +*/ int proclocnum; /*+ Number of this process +*/ Gnum * procvrttab; /*+ Global array of vertex number ranges [+1,based] +*/ Gnum * proccnttab; /*+ Count array for local number of vertices +*/ Gnum * procdsptab; /*+ Displacement array with respect to proccnttab [+1,based] +*/ int procngbnbr; /*+ Number of neighboring processes +*/ int procngbmax; /*+ Maximum number of neighboring processes +*/ int * procngbtab; /*+ Array of neighbor process numbers [sorted] +*/ int * procrcvtab; /*+ Number of vertices to receive in ghost vertex sub-arrays +*/ int procsndnbr; /*+ Overall size of local send array +*/ int * procsndtab; /*+ Number of vertices to send in ghost vertex sub-arrays +*/ int * procsidtab; /*+ Array of indices to build communication vectors (send) +*/ int procsidnbr; /*+ Size of the send index array +*/ } Dgraph; /* ** The function prototypes. */ int dgraphInit (Dgraph * const, MPI_Comm); void dgraphExit (Dgraph * const); void dgraphFree (Dgraph * const); int dgraphLoad (Dgraph * const, FILE * const, const Gnum, const DgraphFlag); int dgraphSave (Dgraph * const, FILE * const); int dgraphBuild (Dgraph * const, const Gnum, const Gnum, const Gnum, Gnum * const, Gnum * const, Gnum * const, Gnum * const, Gnum * const, const Gnum, const Gnum, Gnum * const, Gnum * const, Gnum * const); int dgraphBuild2 (Dgraph * const, const Gnum, const Gnum, const Gnum, Gnum * const, Gnum * const, Gnum * const, const Gnum, Gnum * const, Gnum * const, const Gnum, const Gnum, Gnum * const, Gnum * const, Gnum * const, const Gnum); int dgraphBuild3 (Dgraph * const, const Gnum, const Gnum, Gnum * const, Gnum * const, Gnum * const, const Gnum, Gnum * const, Gnum * const, const Gnum, const Gnum, Gnum * const, Gnum * const, Gnum * const, const Gnum); int dgraphBuild4 (Dgraph * const); int dgraphBuildHcub (Dgraph * const, const Gnum, const Gnum, const Gnum); int dgraphBuildGrid3D (Dgraph * const, const Gnum, const Gnum, const Gnum, const Gnum, const Gnum, const int); int dgraphCheck (const Dgraph * const); int dgraphView (const Dgraph * const, FILE * const); int dgraphGhst2 (Dgraph * const, const int); int dgraphBand (Dgraph * restrict const, const Gnum, Gnum * restrict const, const GraphPart * restrict const, const Gnum, const Gnum, Gnum, Dgraph * restrict const, Gnum * restrict * const, GraphPart * restrict * const, Gnum * const, Gnum * const, Gnum * const); int dgraphFold (const Dgraph * restrict const, const int, Dgraph * restrict const, const void * restrict const, void ** restrict const, MPI_Datatype); int dgraphFold2 (const Dgraph * restrict const, const int, Dgraph * restrict const, MPI_Comm, const void * restrict const, void ** restrict const, MPI_Datatype); int dgraphFoldDup (const Dgraph * restrict const, Dgraph * restrict const, void * restrict const, void ** restrict const, MPI_Datatype); int dgraphInduce2 (Dgraph * restrict const, Gnum (*) (Dgraph * restrict const, Dgraph * restrict const, const void * restrict const, Gnum * restrict const), const void * const, const Gnum, Gnum *, Dgraph * restrict const); int dgraphInduceList (Dgraph * const, const Gnum, const Gnum * const, Dgraph * const); int dgraphInducePart (Dgraph * const, const GraphPart * restrict const, const Gnum, const GraphPart, Dgraph * const); #ifdef GRAPH_H int dgraphGather (const Dgraph * restrict const, Graph * restrict); int dgraphGather2 (const Dgraph * restrict const, Graph * restrict, const int, const Gnum); int dgraphGatherAll (const Dgraph * restrict const, Graph * restrict); int dgraphGatherAll2 (const Dgraph * restrict const, Graph * restrict, const Gnum, const int); int dgraphScatter (Dgraph * const, const Graph * const); #endif /* GRAPH_H */ int dgraphHaloSync (Dgraph * const, void * const, MPI_Datatype); /* ** The macro definitions. */ #define dgraphGhst(grafptr) dgraphGhst2 (grafptr, 0) /* Build ghost edge array in addition to local edge array */ #define dgraphGhstReplace(grafptr) dgraphGhst2 (grafptr, 1) /* Replace local edge array by ghost edge array */ #define dgraphHasGhst(grafptr) (((grafptr)->flagval & DGRAPHHASEDGEGST) != 0) /* If graph has a ghost edge array */ scotch-6.0.4.dfsg/src/libscotch/library_dgraph_band.c0000644002563400244210000004044212055775415025772 0ustar trophimeutilisateurs du domaine/* Copyright 2011,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_band.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the distri- **/ /** buted band graph building routine of **/ /** the libScotch library. **/ /** **/ /** DATES : # Version 6.0 : from : 28 oct 2011 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "dgraph.h" #include "dgraph_halo.h" #include "ptscotch.h" #define DGRAPHBANDGROWNAME dgraphBand #include "dgraph_band_grow.h" /************************************/ /* */ /* These routines are the C API for */ /* the mapping routines. */ /* */ /************************************/ /*+ This routine builds a distributed *** band graph, without anchors, from the *** given distributed graph. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_dgraphBand ( SCOTCH_Dgraph * const orggrafptr, const SCOTCH_Num fronlocnbr, SCOTCH_Num * const fronloctab, const SCOTCH_Num distval, SCOTCH_Dgraph * const bndgrafptr) { MPI_Comm bandproccomm; Gnum bandvertlocnnd; /* End of local band vertex array */ Gnum bandvertlocnbr; /* Number of local band vertices */ Gnum bandvertlvlnum; /* Index of first band vertex belonging to last level */ Gnum * restrict bandvertloctax; Gnum bandvertlocadj; /* Ajust value for local-to-global band vertex indices */ Gnum bandvertlocnum; Gnum * restrict bandveloloctax; Gnum bandvelolocnbr; Gnum bandvelolocsum; Gnum * restrict bandedgeloctax; Gnum bandedgelocnum; Gnum bandedgelocsiz; /* Number of local edges in band graph */ Gnum * restrict bandedloloctax; Gnum bandedlolocsiz; /* Size of local band edge load array */ Gnum bandvnumgstsiz; Gnum * restrict bandvnumgsttax; /* Indices of selected band vertices in band graph */ Gnum * restrict bandvlblloctax; Gnum banddegrlocmax; Gnum degrval; Gnum veloval; Gnum vertlocadj; const Gnum * restrict edgegsttax; SCOTCH_Num * fronloctax; Gnum fronlocnum; int cheklocval; int chekglbval; int procngbnum; Dgraph * restrict const grafptr = (Dgraph *) orggrafptr; Dgraph * restrict const bandgrafptr = (Dgraph *) bndgrafptr; const Gnum * restrict const vertloctax = grafptr->vertloctax; const Gnum * restrict const vendloctax = grafptr->vendloctax; const Gnum * restrict const vlblloctax = grafptr->vlblloctax; const Gnum * restrict const veloloctax = grafptr->veloloctax; const Gnum * restrict const edloloctax = grafptr->edloloctax; #ifdef SCOTCH_DEBUG_LIBRARY1 int o; MPI_Comm_compare (((Dgraph * restrict const) orggrafptr)->proccomm, ((Dgraph * restrict const) bndgrafptr)->proccomm, &o); if ((o != MPI_IDENT) && (o != MPI_CONGRUENT)) { errorPrint ("SCOTCH_dgraphBand: communicators are not congruent"); return (1); } #endif /* SCOTCH_DEBUG_LIBRARY1 */ if (dgraphGhst (grafptr) != 0) { /* Compute ghost edge array if not already present */ errorPrint ("SCOTCH_dgraphBand: cannot compute ghost edge array"); return (1); } cheklocval = 0; bandvnumgstsiz = MAX ((grafptr->vertgstnbr * sizeof (Gnum)), (grafptr->procglbnbr * sizeof (int))); /* TRICK: re-use array for further error collective communications */ if ((bandvnumgsttax = memAlloc (bandvnumgstsiz)) == NULL) { errorPrint ("SCOTCH_dgraphBand: out of memory (1)"); cheklocval = 1; } #ifdef SCOTCH_DEBUG_DGRAPH1 /* This communication cannot be covered by a useful one */ if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("SCOTCH_dgraphBand: communication error (1)"); return (1); } #else /* SCOTCH_DEBUG_DGRAPH1 */ chekglbval = cheklocval; #endif /* SCOTCH_DEBUG_DGRAPH1 */ if (chekglbval != 0) return (1); memSet (bandvnumgsttax, ~0, grafptr->vertgstnbr * sizeof (Gnum)); /* Reset part array */ bandvnumgsttax -= grafptr->baseval; if ((((grafptr->flagval & DGRAPHCOMMPTOP) != 0) ? dgraphBandPtop : dgraphBandColl) (grafptr, fronlocnbr, fronloctab, distval, bandvnumgsttax, &bandvertlvlnum, &bandvertlocnbr, &bandedgelocsiz) != 0) return (1); bandvelolocnbr = (veloloctax != NULL) ? bandvertlocnbr : 0; bandedlolocsiz = (edloloctax != NULL) ? bandedgelocsiz : 0; bandgrafptr->flagval |= (DGRAPHFREEALL ^ DGRAPHFREECOMM) | DGRAPHVERTGROUP | DGRAPHEDGEGROUP; /* Arrays created by the routine itself */ bandgrafptr->baseval = grafptr->baseval; cheklocval = 0; if (memAllocGroup ((void **) (void *) /* Allocate distributed graph private data */ &bandgrafptr->procdsptab, (size_t) ((grafptr->procglbnbr + 1) * sizeof (Gnum)), &bandgrafptr->proccnttab, (size_t) (grafptr->procglbnbr * sizeof (Gnum)), &bandgrafptr->procngbtab, (size_t) (grafptr->procglbnbr * sizeof (int)), &bandgrafptr->procrcvtab, (size_t) (grafptr->procglbnbr * sizeof (int)), &bandgrafptr->procsndtab, (size_t) (grafptr->procglbnbr * sizeof (int)), NULL) == NULL) { errorPrint ("SCOTCH_dgraphBand: out of memory (2)"); cheklocval = 1; } else if (memAllocGroup ((void **) (void *) /* Allocate distributed graph public data */ &bandgrafptr->vertloctax, (size_t) ((bandvertlocnbr + 1) * sizeof (Gnum)), /* Compact vertex array */ &bandvlblloctax, (size_t) (bandvertlocnbr * sizeof (Gnum)), &bandveloloctax, (size_t) (bandvelolocnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("SCOTCH_dgraphBand: out of memory (3)"); cheklocval = 1; } else if (bandgrafptr->vertloctax -= bandgrafptr->baseval, bandvlblloctax -= bandgrafptr->baseval, bandveloloctax = (veloloctax != NULL) ? (bandveloloctax - bandgrafptr->baseval) : NULL, (memAllocGroup ((void **) (void *) &bandedgeloctax, (size_t) (bandedgelocsiz * sizeof (Gnum)), &bandedloloctax, (size_t) (bandedlolocsiz * sizeof (Gnum)), NULL) == NULL)) { errorPrint ("SCOTCH_dgraphBand: out of memory (4)"); cheklocval = 1; } else { bandedgeloctax -= bandgrafptr->baseval; bandedloloctax = (edloloctax != NULL) ? (bandedloloctax - bandgrafptr->baseval) : NULL; } if (cheklocval != 0) { /* In case of memory error */ bandgrafptr->procdsptab[0] = -1; if (MPI_Allgather (&bandgrafptr->procdsptab[0], 1, GNUM_MPI, /* Send received data to dummy array */ bandvnumgsttax + bandgrafptr->baseval, 1, GNUM_MPI, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("SCOTCH_dgraphBand: communication error (2)"); return (1); } dgraphExit (bandgrafptr); memFree (bandvnumgsttax + bandgrafptr->baseval); return (1); } else { bandgrafptr->procdsptab[0] = bandvertlocnbr; if (MPI_Allgather (&bandgrafptr->procdsptab[0], 1, GNUM_MPI, &bandgrafptr->procdsptab[1], 1, GNUM_MPI, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("SCOTCH_dgraphBand: communication error (3)"); return (1); } } bandgrafptr->procdsptab[0] = bandgrafptr->baseval; /* Build vertex-to-process array */ #ifdef SCOTCH_DEBUG_DGRAPH2 memSet (bandvlblloctax + bandgrafptr->baseval, ~0, (bandvertlocnbr * sizeof (Gnum))); #endif /* SCOTCH_DEBUG_DGRAPH2 */ for (procngbnum = 1; procngbnum <= grafptr->procglbnbr; procngbnum ++) { /* Process potential error flags from other processes */ if (bandgrafptr->procdsptab[procngbnum] < 0) { /* If error notified by another process */ dgraphExit (bandgrafptr); memFree (bandvnumgsttax + bandgrafptr->baseval); return (1); } bandgrafptr->procdsptab[procngbnum] += bandgrafptr->procdsptab[procngbnum - 1]; bandgrafptr->proccnttab[procngbnum - 1] = bandgrafptr->procdsptab[procngbnum] - bandgrafptr->procdsptab[procngbnum - 1]; } fronloctax = fronloctab - bandgrafptr->baseval; for (vertlocadj = grafptr->procvrttab[grafptr->proclocnum] - grafptr->baseval, bandvertlocnum = bandgrafptr->baseval, bandvertlocnnd = bandvertlocnbr + bandgrafptr->baseval, bandvertlocadj = bandgrafptr->procdsptab[grafptr->proclocnum] - bandgrafptr->baseval; bandvertlocnum < bandvertlocnnd; bandvertlocnum ++) { /* Turn all kept graph vertices into band graph vertices */ Gnum vertlocnum; vertlocnum = fronloctax[bandvertlocnum]; bandvlblloctax[bandvertlocnum] = (vlblloctax == NULL) ? (vertlocnum + vertlocadj) : vlblloctax[vertlocnum]; bandvnumgsttax[vertlocnum] += bandvertlocadj; /* Turn local indices in band graph into global indices */ } if (dgraphHaloSync (grafptr, (byte *) (bandvnumgsttax + bandgrafptr->baseval), GNUM_MPI) != 0) { /* Share global indexing of halo vertices */ errorPrint ("SCOTCH_dgraphBand: cannot perform halo exchange"); return (1); } edgegsttax = grafptr->edgegsttax; veloval = 1; bandvertloctax = bandgrafptr->vertloctax; bandvelolocsum = 0; banddegrlocmax = 0; for (bandvertlocnum = bandedgelocnum = bandgrafptr->baseval; /* Build global vertex array of band graph */ bandvertlocnum < bandvertlvlnum; bandvertlocnum ++) { /* For all vertices save for the last level */ Gnum vertlocnum; Gnum edgelocnum; Gnum degrval; vertlocnum = bandvlblloctax[bandvertlocnum] - vertlocadj; bandvertloctax[bandvertlocnum] = bandedgelocnum; if (veloloctax != NULL) { veloval = veloloctax[vertlocnum]; bandvelolocsum += veloval; bandveloloctax[bandvertlocnum] = veloval; } degrval = vendloctax[vertlocnum] - vertloctax[vertlocnum]; if (banddegrlocmax < degrval) banddegrlocmax = degrval; for (edgelocnum = vertloctax[vertlocnum]; /* For all original edges */ edgelocnum < vendloctax[vertlocnum]; edgelocnum ++) { #ifdef SCOTCH_DEBUG_DGRAPH2 if (bandvnumgsttax[edgegsttax[edgelocnum]] == ~0) { /* All ends should belong to the band graph too */ errorPrint ("SCOTCH_dgraphBand: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ bandedgeloctax[bandedgelocnum ++] = bandvnumgsttax[edgegsttax[edgelocnum]]; } } for ( ; bandvertlocnum < bandvertlocnnd; bandvertlocnum ++) { /* For all vertices that belong to the last level */ Gnum vertlocnum; Gnum edgelocnum; Gnum degrval; vertlocnum = bandvlblloctax[bandvertlocnum] - vertlocadj; bandvertloctax[bandvertlocnum] = bandedgelocnum; if (veloloctax != NULL) { veloval = veloloctax[vertlocnum]; bandvelolocsum += veloval; bandveloloctax[bandvertlocnum] = veloval; } for (edgelocnum = vertloctax[vertlocnum]; /* For all original edges */ edgelocnum < vendloctax[vertlocnum]; edgelocnum ++) { Gnum bandvertlocend; bandvertlocend = bandvnumgsttax[edgegsttax[edgelocnum]]; if (bandvertlocend != ~0) { /* If end vertex belongs to band graph */ if (bandedloloctax != NULL) /* If graph has edge weights, copy load */ bandedloloctax[bandedgelocnum] = edloloctax[edgelocnum]; bandedgeloctax[bandedgelocnum ++] = bandvertlocend; } } degrval = bandedgelocnum - bandvertloctax[bandvertlocnum]; if (banddegrlocmax < degrval) banddegrlocmax = degrval; } bandvertloctax[bandvertlocnnd] = bandedgelocnum; /* Set end of vertex array */ memFree (bandvnumgsttax + bandgrafptr->baseval); /* Free useless space */ if (bandedloloctax != NULL) { /* If graph has edge weights */ Gnum edgelocnum; Gnum edgelocnnd; for (bandvertlocnum = bandgrafptr->baseval; /* For all vertices that do not belong to the last level */ bandvertlocnum < bandvertlvlnum; bandvertlocnum ++) { Gnum vertlocnum; Gnum bandedgelocnum; vertlocnum = bandvlblloctax[bandvertlocnum] - vertlocadj; bandedgelocnum = bandvertloctax[bandvertlocnum]; memCpy (bandedloloctax + bandedgelocnum, /* Copy edge load array */ &edloloctax[vertloctax[vertlocnum]], (bandvertloctax[bandvertlocnum + 1] - bandedgelocnum) * sizeof (Gnum)); } /* Vertices of last level have been processed before */ } bandgrafptr->procvrttab = bandgrafptr->procdsptab; /* Graph does not have holes */ bandgrafptr->vertlocnbr = bandvertlocnbr; bandgrafptr->vertlocnnd = bandvertlocnbr + bandgrafptr->baseval; bandgrafptr->vendloctax = bandvertloctax + 1; /* Band graph is compact */ bandgrafptr->veloloctax = bandveloloctax; bandgrafptr->velolocsum = bandvelolocsum; bandgrafptr->vlblloctax = bandvlblloctax; bandgrafptr->edgeloctax = bandedgeloctax; bandgrafptr->edloloctax = bandedloloctax; bandgrafptr->edgelocnbr = bandedgelocnum - bandgrafptr->baseval; bandgrafptr->edgelocsiz = bandedgelocsiz; bandgrafptr->degrglbmax = banddegrlocmax; /* Local maximum degree will be turned into global maximum degree */ if (dgraphBuild4 (bandgrafptr) != 0) { errorPrint ("SCOTCH_dgraphBand: cannot build band graph"); return (1); } #ifdef SCOTCH_DEBUG_DGRAPH2 if (dgraphCheck (bandgrafptr) != 0) { errorPrint ("SCOTCH_dgraphBand: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/comm.h0000644002563400244210000000737311631447170022754 0ustar trophimeutilisateurs du domaine/* Copyright 2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : comm.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for communication functions. **/ /** **/ /** DATES : # Version 5.1 : from : 30 jul 2010 **/ /** to 11 aug 2010 **/ /** **/ /************************************************************/ #define COMM_H /* ** The type and structure definitions. */ #ifndef GNUMMAX /* If dgraph.h not included */ typedef INT Gnum; /* Vertex and edge numbers */ typedef UINT Gunum; /* Unsigned type of same width */ #define GNUMMAX (INTVALMAX) /* Maximum signed Gnum value */ #define GNUMSTRING INTSTRING /* String to printf a Gnum */ #endif /* GNUMMAX */ /* ** The function prototypes. */ #ifndef COMM #define static #endif int commAllgatherv (void * const, const Gnum, MPI_Datatype, void * const, const Gnum * const, const Gnum * const, MPI_Datatype, MPI_Comm); int commGatherv (void * const, const Gnum, MPI_Datatype, void * const, const Gnum * const, const Gnum * const, MPI_Datatype, const int, MPI_Comm); int commScatterv (void * const, const Gnum * const, const Gnum * const, MPI_Datatype, void * const, const Gnum, MPI_Datatype, const int, MPI_Comm); #undef static /* ** The macro definitions. */ #ifndef COMM #ifndef INTSIZE64 #define commAllgatherv MPI_Allgatherv #define commGatherv MPI_Gatherv #define commScatterv MPI_Scatterv #endif /* INTSIZE64 */ #endif /* COMM */ scotch-6.0.4.dfsg/src/libscotch/mesh_io_habo.c0000644002563400244210000003065511631447170024427 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mesh_io_habo.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the I/O routines **/ /** for handling the Harwell-Boeing **/ /** elemental matrix format. **/ /** **/ /** DATES : # Version 4.0 : from : 19 jan 2004 **/ /** to 20 jan 2004 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define MESH_IO_HABO #include "module.h" #include "common.h" #include "geom.h" #include "graph.h" #include "mesh.h" /* This routine loads the geometrical mesh ** in the Harwell-Boeing matrix format, and ** allocates the proper structures. ** - 0 : on success. ** - !0 : on error. */ int meshGeomLoadHabo ( Mesh * restrict const meshptr, /* Mesh to load */ Geom * restrict const geomptr, /* Geometry to load */ FILE * const filesrcptr, /* Topological data */ FILE * const filegeoptr, /* No use */ const char * const dataptr) /* No use */ { long habmattag; /* Matrix tag number in file */ long habmatnum; /* Current matrix number */ char habmatbuf[4][84]; /* Matrix header line buffers */ char habmattype[4]; /* Matrix type */ long habcrdnbr; /* Total number of data lines */ long habrhsnbr; /* Number of right hand side lines */ int habcolsiz; /* Size of column type */ int habnzrsiz; /* Size of non-zero type */ Gnum habevlnbr; /* Number of element matrix values (not uesd) */ Gnum habvixnbr; /* Number of element matrix variable indices */ Gnum habeltnbr; /* Number of elements */ Gnum habvarnbr; /* Number of variables, that is, nodes */ Gnum velmnum; /* Number of current element vertex */ Gnum vnodnum; /* Number of current node vertex */ Gnum edgenum; /* Number of current edge (arc) */ Gnum edgesum; /* Accumulated number of edges in node part */ Gnum degrmax; /* Maximum degree */ int c; if (((habmattag = atol (dataptr)) == 0) && /* Get tag value */ (dataptr[0] != '0') && (dataptr[0] != '\0')) { errorPrint ("meshGeomLoadHabo: bad input (1)"); return (1); } for (habmatnum = 0; habmatnum <= habmattag; habmatnum ++) { /* Read headers and skip if necessary */ memSet (habmatbuf[0], ' ', &habmatbuf[3][83] - &habmatbuf[0][0]); /* Initialize header buffers */ if ((fgets (habmatbuf[0], 83, filesrcptr) == NULL) || /* Read mesh header */ (fgets (habmatbuf[1], 83, filesrcptr) == NULL) || (fgets (habmatbuf[2], 83, filesrcptr) == NULL) || (fgets (habmatbuf[3], 83, filesrcptr) == NULL)) { errorPrint ("meshGeomLoadHabo: bad input (2)"); return (1); } habmatbuf[1][70] = '\0'; /* Extract header values */ habrhsnbr = atol (&habmatbuf[1][56]); habmatbuf[1][14] = '\0'; habcrdnbr = atol (&habmatbuf[1][00]); habmattype[0] = toupper (habmatbuf[2][0]); habmattype[1] = toupper (habmatbuf[2][1]); habmattype[2] = toupper (habmatbuf[2][2]); habmatbuf[2][70] = '\0'; habevlnbr = (Gnum) atol (&habmatbuf[2][57]); /* NELTVL */ habmatbuf[2][56] = '\0'; habvixnbr = (Gnum) atol (&habmatbuf[2][43]); /* VARIX */ habmatbuf[2][42] = '\0'; habeltnbr = (Gnum) atol (&habmatbuf[2][29]); /* NELT */ habmatbuf[2][28] = '\0'; habvarnbr = (Gnum) atol (&habmatbuf[2][14]); /* NVAR */ habmatbuf[2][14] = '\0'; if ((c = sscanf (habmatbuf[3], "(%*d%*[Ii]%d) (%*d%*[Ii]%d)", &habcolsiz, &habnzrsiz)) != 2) { errorPrint ("meshGeomLoadHabo: bad input (3, %d)", c); return (1); } if (habrhsnbr != 0) { while ((c = getc (filesrcptr)) != '\n'){ /* Skip RHS format line */ if (c == EOF) { errorPrint ("meshGeomLoadHabo: bad input (4)"); return (1); } } } if (habmatnum < habmattag) { /* If we have to skip file */ while (habcrdnbr -- > 0) { /* Skip all of file lines */ while ((c = getc (filesrcptr)) != '\n') { /* Skip line */ if (c == EOF) { errorPrint ("meshGeomLoadHabo: bad input (5)"); return (1); } } } } } if (habmattype[2] != 'E') { errorPrint ("meshGeomLoadHabo: only elemental matrices supported"); return (1); } if (habmattype[1] == 'R') { errorPrint ("meshGeomLoadHabo: rectangular matrices not supported"); return (1); } if (((meshptr->verttax = (Gnum *) memAlloc ((habeltnbr + habvarnbr + 1) * sizeof (Gnum))) == NULL) || ((meshptr->edgetax = (Gnum *) memAlloc (habvixnbr * 2 * sizeof (Gnum))) == NULL)) { errorPrint ("meshGeomLoadHabo: out of memory (1)"); if (meshptr->verttax != NULL) { memFree (meshptr->verttax); meshptr->verttax = NULL; } return (1); } meshptr->flagval = MESHFREETABS; /* Totally new mesh structure */ meshptr->baseval = 1; /* Harwell-Boeing meshs have base 1 */ meshptr->vendtax = meshptr->verttax; meshptr->verttax --; meshptr->edgenbr = habvixnbr * 2; meshptr->edgetax --; meshptr->velmnbr = habeltnbr; meshptr->velmbas = habvarnbr + 1; meshptr->velmnnd = habeltnbr + habvarnbr + 1; meshptr->vnodnbr = habvarnbr; meshptr->vnodbas = 1; meshptr->vnodnnd = meshptr->velmbas; meshptr->vnlosum = habvarnbr; for (velmnum = meshptr->velmbas; velmnum <= meshptr->velmnnd; velmnum ++) { /* Read ELTPTR as second part of vertex array */ Gnum habcolval; /* Current column value */ int habcolidx; /* Current index in column value */ while (((c = getc (filesrcptr)) == '\n') || (c == '\r')) ; habcolval = (c == ' ') ? 0 : (c - '0'); for (habcolidx = 1; habcolidx < habcolsiz; habcolidx ++) { if ((c = getc (filesrcptr)) != ' ') habcolval = habcolval * 10 + c - '0'; } if (c == EOF) { errorPrint ("meshGeomLoadHabo: bad input (6)"); meshFree (meshptr); return (1); } #ifdef SCOTCH_DEBUG_MESH2 if ((habcolval < 1) || (habcolval > (habvixnbr + 1))) { errorPrint ("meshGeomLoadHabo: bad input (7)"); return (1); } #endif /* SCOTCH_DEBUG_MESH2 */ meshptr->verttax[velmnum] = habcolval + habvixnbr; } if (meshptr->verttax[velmnum - 1] != (habvixnbr + habvixnbr + 1)) { errorPrint ("meshGeomLoadHabo: bad input (8)"); meshFree (meshptr); return (1); } memSet (meshptr->verttax + 1, 0, habvarnbr * sizeof (Gnum)); /* Pre-set node adjacency array */ for (edgenum = habvixnbr + 1; edgenum <= meshptr->edgenbr; edgenum ++) { /* Read VARIND as second part of edge array */ Gnum habnodval; /* Current non-zero value */ int habnzridx; /* Current index in non-zero value */ while (((c = getc (filesrcptr)) == '\n') || (c == '\r')) ; habnodval = (c == ' ') ? 0 : (c - '0'); for (habnzridx = 1; habnzridx < habnzrsiz; habnzridx ++) { if ((c = getc (filesrcptr)) != ' ') habnodval = habnodval * 10 + c - '0'; } if (c == EOF) { errorPrint ("meshGeomLoadHabo: bad input (9)"); meshFree (meshptr); return (1); } #ifdef SCOTCH_DEBUG_MESH2 if ((habnodval < 1) || (habnodval > habvarnbr)) { errorPrint ("meshGeomLoadHabo: bad input (10)"); return (1); } #endif /* SCOTCH_DEBUG_MESH2 */ meshptr->edgetax[edgenum] = habnodval; meshptr->verttax[habnodval] ++; } degrmax = 1; for (vnodnum = edgesum = 1; vnodnum < meshptr->vnodnnd; vnodnum ++) { /* Accumulate start indices for node part of vertex array */ Gnum degrval; degrval = meshptr->verttax[vnodnum]; if (degrval > degrmax) degrmax = degrval; meshptr->verttax[vnodnum] = edgesum; edgesum += degrval; } #ifdef SCOTCH_DEBUG_MESH2 if (edgesum != meshptr->verttax[meshptr->velmbas]) { errorPrint ("meshGeomLoadHabo: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_MESH2 */ for (velmnum = meshptr->velmbas, edgenum = habvixnbr + 1; /* Re-scan element part of edge array to build node part of edge array */ velmnum < meshptr->velmnnd; velmnum ++) { if ((meshptr->vendtax[velmnum] - edgenum) > degrmax) degrmax = (meshptr->vendtax[velmnum] - edgenum); for ( ; edgenum < meshptr->vendtax[velmnum]; edgenum ++) { Gnum vnodnum; vnodnum = meshptr->edgetax[edgenum]; #ifdef SCOTCH_DEBUG_MESH2 if ((vnodnum < 1) || (vnodnum > habvarnbr)) { errorPrint ("meshGeomLoadHabo: internal error (2)"); return (1); } if (meshptr->verttax[vnodnum] > habvixnbr) { errorPrint ("meshGeomLoadHabo: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_MESH2 */ meshptr->edgetax[meshptr->verttax[vnodnum] ++] = velmnum; } } meshptr->degrmax = degrmax; for (vnodnum = edgesum = 1; vnodnum < meshptr->vnodnnd; vnodnum ++) { /* Restore start indices for node part of vertex array */ Gnum edgenum; edgenum = meshptr->verttax[vnodnum]; meshptr->verttax[vnodnum] = edgesum; edgesum = edgenum; } #ifdef SCOTCH_DEBUG_MESH2 if (meshCheck (meshptr) != 0) { errorPrint ("meshGeomLoadHabo: inconsistent mesh data"); return (1); } #endif /* SCOTCH_DEBUG_MESH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/common_file_compress.c0000644002563400244210000002556512262355406026222 0ustar trophimeutilisateurs du domaine/* Copyright 2008,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : common_file_compress.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles compressed streams **/ /** for compression. **/ /** **/ /** DATES : # Version 5.0 : from : 13 mar 2008 **/ /** to : 15 may 2008 **/ /** # Version 5.1 : from : 27 jun 2010 **/ /** to 27 jun 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define COMMON_FILE #define COMMON_FILE_COMPRESS #ifndef COMMON_NOMODULE #include "module.h" #endif /* COMMON_NOMODULE */ #include "common.h" #include "common_file.h" #include "common_file_compress.h" #ifdef COMMON_FILE_COMPRESS_BZ2 #include "bzlib.h" #endif /* COMMON_FILE_COMPRESS_BZ2 */ #ifdef COMMON_FILE_COMPRESS_GZ #include "zlib.h" #endif /* COMMON_FILE_COMPRESS_GZ */ /* ** The static definitions. */ static FileCompressTab filetab[] = { #ifdef COMMON_FILE_COMPRESS_BZ2 { ".bz2", FILECOMPRESSTYPEBZ2, }, #else /* COMMON_FILE_COMPRESS_BZ2 */ { ".bz2", FILECOMPRESSTYPENOTIMPL }, #endif /* COMMON_FILE_COMPRESS_BZ */ #ifdef COMMON_FILE_COMPRESS_GZ { ".gz", FILECOMPRESSTYPEGZ, }, #else /* COMMON_FILE_COMPRESS_GZ */ { ".gz", FILECOMPRESSTYPENOTIMPL }, #endif /* COMMON_FILE_COMPRESS_GZ */ /* #ifdef COMMON_FILE_COMPRESS_LZMA */ /* TODO: Current lzmadec library does not offer compression to date */ /* { ".lzma", FILECOMPRESSTYPELZMA }, */ /* #else COMMON_FILE_COMPRESS_LZMA */ { ".lzma", FILECOMPRESSTYPENOTIMPL }, /* #endif /\* COMMON_FILE_COMPRESS_LZMA *\/ */ { NULL, FILECOMPRESSTYPENOTIMPL } }; /*********************************/ /* */ /* Basic routines for filenames. */ /* */ /*********************************/ /* This routine searches the given file name ** for relevant extensions and returns the ** corresponding code if it is the case. ** It returns: ** - FILECOMPRESSTYPENONE : no recognized file extension. ** - FILECOMPRESSTYPENOTIMPL : compression algorithm not implemented. ** - FILECOMPRESSTYPExxxx : implemented compression algorithm. */ int fileCompressType ( const char * const nameptr) /*+ Name string +*/ { int namelen; int i; namelen = strlen (nameptr); for (i = 0; filetab[i].name != NULL; i ++) { int extnlen; /* Name of extension string */ extnlen = strlen (filetab[i].name); if ((namelen >= extnlen) && (strncmp (filetab[i].name, nameptr + (namelen - extnlen), extnlen) == 0)) return (filetab[i].type); } return (FILECOMPRESSTYPENONE); } /* This routine creates a thread to compress the ** given stream according to the given compression ** algorithm. ** If threads are available, compression will be ** performed by an auxiliary thread. Else, a child process ** will be fork()'ed, and after completion this process ** will remain a zombie until the main process terminates. ** It returns: ** - !NULL : stream holding compressed data. ** - NULL : on error. */ static void * /* (void *) to comply to the Posix pthread API */ fileCompress2 ( FileCompressData * const dataptr) { switch (dataptr->typeval) { #ifdef COMMON_FILE_COMPRESS_BZ2 case FILECOMPRESSTYPEBZ2 : fileCompressBz2 (dataptr); break; #endif /* COMMON_FILE_COMPRESS_BZ2 */ #ifdef COMMON_FILE_COMPRESS_GZ case FILECOMPRESSTYPEGZ : fileCompressGz (dataptr); break; #endif /* COMMON_FILE_COMPRESS_GZ */ /* #ifdef COMMON_FILE_COMPRESS_LZMA /\* TODO: Current lzmadec library does not offer compression to date *\/ */ /* case FILECOMPRESSTYPELZMA : */ /* fileCompressLzma (dataptr); */ /* break; */ /* #endif /\* COMMON_FILE_COMPRESS_LZMA *\/ */ default : errorPrint ("fileCompress2: method not implemented"); } close (dataptr->innerfd); /* Close writer's end */ memFree (dataptr); /* Free buffers */ return ((void *) 0); /* Don't care anyway */ } FILE * fileCompress ( FILE * const stream, /*+ Uncompressed stream +*/ const int typeval) /*+ (Un)compression algorithm +*/ { int filetab[2]; FILE * writptr; FileCompressData * dataptr; #ifdef COMMON_PTHREAD pthread_t thrdval; #endif /* COMMON_PTHREAD */ if (typeval <= FILECOMPRESSTYPENONE) /* If uncompressed stream, return original stream pointer */ return (stream); if (pipe (filetab) != 0) { errorPrint ("fileCompress: cannot create pipe"); return (NULL); } if ((writptr = fdopen (filetab[1], "w")) == NULL) { errorPrint ("fileCompress: cannot create stream"); close (filetab[0]); close (filetab[1]); return (NULL); } if ((dataptr = memAlloc (sizeof (FileCompressData) + FILECOMPRESSDATASIZE)) == NULL) { errorPrint ("fileCompress: out of memory"); close (filetab[0]); fclose (writptr); return (NULL); } dataptr->typeval = typeval; /* Fill structure to be passed to compression thread/process */ dataptr->innerfd = filetab[0]; dataptr->outerstream = stream; /* Stream to write to */ #ifdef COMMON_PTHREAD if (pthread_create (&thrdval, NULL, (void * (*) (void *)) fileCompress2, (void *) dataptr) != 0) { /* If could not create thread */ errorPrint ("fileCompress: cannot create thread"); memFree (dataptr); close (filetab[0]); fclose (writptr); return (NULL); } #else /* COMMON_PTHREAD */ switch (fork ()) { case -1 : /* Error */ errorPrint ("fileCompress: cannot create child process"); memFree (dataptr); close (filetab[0]); fclose (writptr); return (NULL); case 0 : /* We are the son process */ fclose (writptr); /* Close writer pipe stream */ fileCompress2 (dataptr); /* Perform compression */ exit (0); /* Exit gracefully */ default : /* We are the father process */ close (filetab[0]); /* Close the reader pipe end */ } #endif /* COMMON_PTHREAD */ return (writptr); } /* This routine compresses a stream compressed in the ** gzip format. ** It returns: ** - void : in all cases. Compression stops immediately ** in case of error. */ #ifdef COMMON_FILE_COMPRESS_BZ2 static void fileCompressBz2 ( FileCompressData * const dataptr) { BZFILE * bzfile; int bzsize; int bzerror; if ((bzfile = BZ2_bzWriteOpen (&bzerror, dataptr->outerstream, 9, 0, 0)) == NULL) { errorPrint ("fileCompressBz2: cannot start compression"); BZ2_bzWriteClose (&bzerror, bzfile, 1, NULL, NULL); return; } while ((bzsize = read (dataptr->innerfd, &dataptr->datatab, FILECOMPRESSDATASIZE)) > 0) { /* Read from pipe */ BZ2_bzWrite (&bzerror, bzfile, &dataptr->datatab, bzsize); if (bzerror != BZ_OK) { errorPrint ("fileCompressBz2: cannot write"); break; } } if (bzsize < 0) { errorPrint ("fileCompressBz2: cannot read"); bzerror = BZ_STREAM_END; /* Will set abandon flag to 1 in BZ2_bzWriteClose */ } BZ2_bzWriteClose (&bzerror, bzfile, (bzerror != BZ_OK) ? 1 : 0, NULL, NULL); fclose (dataptr->outerstream); /* Do as zlib does */ } #endif /* COMMON_FILE_COMPRESS_BZ2 */ /* This routine compresses a stream compressed in the ** gzip format. ** It returns: ** - void : in all cases. Compression stops immediately ** in case of error. */ #ifdef COMMON_FILE_COMPRESS_GZ static void fileCompressGz ( FileCompressData * const dataptr) { gzFile gzfile; int gzsize; if ((gzfile = gzdopen (fileno (dataptr->outerstream), "wb")) == NULL) { errorPrint ("fileCompressGz: cannot start compression"); return; } gzsetparams (gzfile, 9, Z_DEFAULT_STRATEGY); /* Maximum compression */ while ((gzsize = read (dataptr->innerfd, &dataptr->datatab, FILECOMPRESSDATASIZE)) > 0) { /* Read from pipe */ if (gzwrite (gzfile, &dataptr->datatab, gzsize) != gzsize) { errorPrint ("fileCompressGz: cannot write"); break; } } if (gzsize < 0) errorPrint ("fileCompressGz: cannot read"); gzclose (gzfile); } #endif /* COMMON_FILE_COMPRESS_GZ */ scotch-6.0.4.dfsg/src/libscotch/hall_order_hd.h0000644002563400244210000000621211726071103024570 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hall_order_hd.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the block-oriented Halo **/ /** Approximate (Multiple) Minimum Degree **/ /** ordering routine. **/ /** **/ /** DATES : # Version 3.4 : from : 15 may 2001 **/ /** to : 15 may 2001 **/ /** # Version 4.0 : from : 10 jan 2003 **/ /** to : 10 dec 2003 **/ /** # Version 6.0 : from : 08 mar 2012 **/ /** to : 08 mar 2012 **/ /** **/ /************************************************************/ /* ** The function prototypes. */ #ifndef HALL_ORDER_HD #define static #endif void hallOrderHdHalmd (const Gnum n, const Gnum nbelts, const Gnum iwlen, Gnum pe[], Gnum pfree, Gnum len[], Gnum iw[], Gnum nv[], Gnum elen[], Gnum last[], Gnum * ncmpa, Gnum degree[], Gnum head[], Gnum next[], Gnum w[]); #undef static scotch-6.0.4.dfsg/src/libscotch/kgraph_map_st.h0000644002563400244210000001026111705731136024626 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010-2012 IPB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph_map_st.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the strategy and method **/ /** tables and the generic entry point for **/ /** the graph multipartitioning methods. **/ /** **/ /** DATES : # Version 3.2 : from : 15 oct 1996 **/ /** to 29 sep 1997 **/ /** # Version 3.3 : from : 19 oct 1998 **/ /** to 09 dec 1998 **/ /** # Version 4.0 : from : 12 jan 2004 **/ /** to 12 jan 2004 **/ /** # Version 5.1 : from : 13 jul 2010 **/ /** to 13 jul 2010 **/ /** # Version 6.0 : from : 08 jun 2011 **/ /** to 16 jan 2012 **/ /** **/ /************************************************************/ /* ** The type definitions. */ /*+ Method types. +*/ typedef enum KgraphMapStMethodType_ { KGRAPHMAPSTMETHBD = 0, /*+ Band (strategy) +*/ KGRAPHMAPSTMETHCP, /*+ Old mapping copy +*/ KGRAPHMAPSTMETHDF, /*+ Diffusion +*/ KGRAPHMAPSTMETHEX, /*+ Exactifier +*/ KGRAPHMAPSTMETHFM, /*+ Fiduccia-Mattheyses +*/ KGRAPHMAPSTMETHML, /*+ Multi-level (strategy) +*/ KGRAPHMAPSTMETHRB, /*+ Dual Recursive Bipartitioning +*/ KGRAPHMAPSTMETHNBR /*+ Number of methods +*/ } KgraphMapStMethodType; /* ** The external declarations. */ extern StratTab kgraphmapststratab; /* ** The function prototypes. */ #ifndef KGRAPH_MAP_ST #define static #endif int kgraphMapSt (Kgraph * restrict const, const Strat * restrict const); #undef static scotch-6.0.4.dfsg/src/libscotch/dgraph_band_grow.c0000644002563400244210000007122312030701422025261 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_band_grow.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module flags vertices according **/ /** to a breadth-first search traversal of **/ /** the distributed graph. It is used both **/ /** by dgraphBand() and dgraphGrow(). **/ /** **/ /** DATES : # Version 5.1 : from : 11 nov 2007 **/ /** to : 20 feb 2011 **/ /** # Version 6.0 : from : 03 apr 2012 **/ /** to : 26 sep 2012 **/ /** **/ /** NOTES : # This code derives from the code of **/ /** vdgraph_separate_bd.c in version **/ /** 5.0. It was first moved to **/ /** dgraph_band.c, then to here to be **/ /** mutualized between dgraphBand and **/ /** dgraphGrow. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DGRAPHBANDGROWNSTR STRINGIFY (DGRAPHBANDGROWNAME) /**********************************/ /* */ /* Distance computation routines. */ /* */ /**********************************/ /* This routine computes a distributed index array ** of given width around the current separator, ** using collective communication. ** It returns: ** - 0 : if the index array could be computed. ** - !0 : on error. */ int DGRAPHBANDGROWNAMECOLL ( Dgraph * restrict const grafptr, /*+ Distributed graph +*/ const Gnum queulocnbr, /*+ Number of frontier vertices, start size for vertex queue +*/ Gnum * restrict const queuloctab, /*+ Array of frontier vertices, re-used as queue array +*/ const Gnum distmax, /*+ Maximum distance from separator vertices +*/ Gnum * restrict const vnumgsttax, /*+ Flag or index array to fill +*/ Gnum * restrict const bandvertlvlptr, /*+ Pointer to based start index of last level +*/ Gnum * restrict const bandvertlocptr, /*+ Pointer to bandvertlocnnd +*/ Gnum * restrict const bandedgelocptr) /*+ Pointer to bandedgelocnbr +*/ { Gnum queulocnum; Gnum vertlocnnd; Gnum vnumgstsiz; /* Size of vnumgsttax; TRICK: re-use */ Gnum vrcvdatsiz; /* Sizes of data send and receive arrays */ Gnum vsnddatsiz; Gnum * vrcvdattab; /* Data arrays [norestrict:async] */ Gnum * restrict vsnddattab; Gnum * restrict procvgbtab; /* Array of neighbor bounds [+1] */ int procngbnbr; int procngbnum; int * restrict vrcvcnttab; int * restrict vsndcnttab; int * restrict vrcvdsptab; int * restrict vsnddsptab; int * restrict nsndidxtab; int vrcvdspnum; int vsnddspnum; Gnum queuheadidx; /* Index of head of queue */ Gnum queutailidx; /* Index of tail of queue */ Gnum bandvertlvlnum; Gnum bandvertlocnnd; Gnum bandedgelocnbr; Gnum distval; #ifdef SCOTCH_DEBUG_DGRAPH1 Gnum reduloctab[3]; Gnum reduglbtab[3]; #else /* SCOTCH_DEBUG_DGRAPH1 */ Gnum reduglbtab[1]; #endif /* SCOTCH_DEBUG_DGRAPH1 */ const Gnum * restrict const vertloctax = grafptr->vertloctax; const Gnum * restrict const vendloctax = grafptr->vendloctax; const Gnum * restrict const edgegsttax = grafptr->edgegsttax; const Gnum * restrict const edgeloctax = grafptr->edgeloctax; procngbnbr = grafptr->procngbnbr; reduglbtab[0] = 0; /* Assume everything is all right */ vrcvdatsiz = DGRAPHBANDGROWSMUL (grafptr->procsndnbr); /* Senders and receivers inverted because we send local, not halo vertices */ vsnddatsiz = DGRAPHBANDGROWSMUL (grafptr->vertgstnbr - grafptr->vertlocnbr); if (memAllocGroup ((void **) (void *) &procvgbtab, (size_t) ((procngbnbr + 1) * sizeof (Gnum)), &nsndidxtab, (size_t) (procngbnbr * sizeof (int)), &vrcvcnttab, (size_t) (grafptr->procglbnbr * sizeof (int)), &vsndcnttab, (size_t) (grafptr->procglbnbr * sizeof (int)), /* TRICK: vsndcnttab, vrcvdsptab, vrcvdattab, vrcvdattab joined */ &vrcvdsptab, (size_t) (grafptr->procglbnbr * sizeof (int)), &vsnddsptab, (size_t) (grafptr->procglbnbr * sizeof (int)), &vrcvdattab, (size_t) (vrcvdatsiz * sizeof (Gnum)), &vsnddattab, (size_t) (vsnddatsiz * sizeof (Gnum)), NULL) == NULL) { errorPrint (DGRAPHBANDGROWNSTR "Coll: out of memory (1)"); reduglbtab[0] = 1; } #ifdef SCOTCH_DEBUG_DGRAPH1 /* Communication not needed and not absorbable by the algorithm */ reduloctab[0] = reduglbtab[0]; reduloctab[1] = distmax; reduloctab[2] = - distmax; if (MPI_Allreduce (reduloctab, reduglbtab, 3, GNUM_MPI, MPI_MAX, grafptr->proccomm) != MPI_SUCCESS) { errorPrint (DGRAPHBANDGROWNSTR "Coll: communication error (1)"); return (1); } if (reduglbtab[1] != - reduglbtab[2]) { errorPrint (DGRAPHBANDGROWNSTR "Coll: invalid parameters"); reduglbtab[0] = 1; } #endif /* SCOTCH_DEBUG_DGRAPH1 */ if (reduglbtab[0] != 0) { if (vnumgsttax != NULL) { if (procvgbtab != NULL) memFree (procvgbtab); /* Free group leader */ memFree (vnumgsttax); } return (1); } memSet (vsndcnttab, 0, (((int *) vrcvdattab) - vsndcnttab) * sizeof (int)); /* TRICK: vsndcnttab, vrcvdsptab, vrcvdattab, vrcvdattab joined */ for (procngbnum = 0, vrcvdspnum = vsnddspnum = 0; /* Build communication index arrays */ procngbnum < procngbnbr; procngbnum ++) { int procglbnum; procglbnum = grafptr->procngbtab[procngbnum]; procvgbtab[procngbnum] = grafptr->procvrttab[procglbnum]; vrcvdsptab[procglbnum] = vrcvdspnum; vsnddsptab[procglbnum] = vsnddspnum; vrcvdspnum += DGRAPHBANDGROWSMUL (grafptr->procsndtab[procglbnum]); /* Senders and receivers are reversed */ vsnddspnum += DGRAPHBANDGROWSMUL (grafptr->procrcvtab[procglbnum]); } procvgbtab[procngbnum] = grafptr->procvrttab[grafptr->procglbnbr]; bandvertlvlnum = /* Start index of last level is start index */ bandvertlocnnd = grafptr->baseval; /* Reset number of band vertices, plus base */ bandedgelocnbr = 0; /* No edges accounted for yet */ DGRAPHBANDGROWENQ1; /* Record queued vertices in index array and account for their edges */ vertlocnnd = grafptr->vertlocnnd; queuheadidx = 0; /* No queued vertex read yet */ queutailidx = queulocnbr; /* All frontier vertices are already in queue */ for (distval = 0; ++ distval <= distmax; ) { Gnum queunextidx; /* Tail index for enqueuing vertices of next band */ int procngbnum; bandvertlvlnum = bandvertlocnnd; /* Save start index of current level, based */ *bandvertlvlptr = bandvertlvlnum; for (procngbnum = 0; procngbnum < procngbnbr; procngbnum ++) /* Build communication index arrays */ nsndidxtab[procngbnum] = vsnddsptab[grafptr->procngbtab[procngbnum]]; for (queunextidx = queutailidx; queuheadidx < queutailidx; ) { /* For all vertices in queue */ Gnum vertlocnum; Gnum edgelocnum; vertlocnum = queuloctab[queuheadidx ++]; /* Dequeue vertex */ for (edgelocnum = vertloctax[vertlocnum]; edgelocnum < vendloctax[vertlocnum]; edgelocnum ++) { Gnum vertlocend; vertlocend = edgegsttax[edgelocnum]; if (vnumgsttax[vertlocend] != ~0) /* If end vertex has already been processed */ continue; /* Skip to next vertex */ if (vertlocend < vertlocnnd) { /* If end vertex is local */ vnumgsttax[vertlocend] = DGRAPHBANDGROWENQ2; /* Label vertex as enqueued */ queuloctab[queunextidx ++] = vertlocend; /* Enqueue vertex for next pass */ DGRAPHBANDGROWEDGE (vertlocend); /* Account for its edges */ } else { /* End vertex is a ghost */ Gnum vertglbend; int procngbnum; int procngbmax; int nsndidxnum; vnumgsttax[vertlocend] = 0; /* Label ghost vertex as enqueued */ vertglbend = edgeloctax[edgelocnum]; /* Get global number of end vertex */ procngbnum = 0; procngbmax = procngbnbr; while ((procngbmax - procngbnum) > 1) { /* Find owner process by dichotomy on procvgbtab */ int procngbmed; procngbmed = (procngbmax + procngbnum) / 2; if (procvgbtab[procngbmed] > vertglbend) procngbmax = procngbmed; else procngbnum = procngbmed; } #ifdef SCOTCH_DEBUG_DGRAPH2 if ((grafptr->procvrttab[grafptr->procngbtab[procngbnum]] > vertglbend) || (grafptr->procvrttab[grafptr->procngbtab[procngbnum] + 1] <= vertglbend) || (nsndidxtab[procngbnum] >= (vsnddsptab[grafptr->procngbtab[procngbnum]] + grafptr->procrcvtab[grafptr->procngbtab[procngbnum]]))) { errorPrint (DGRAPHBANDGROWNSTR "Coll: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ nsndidxnum = nsndidxtab[procngbnum]; vsnddattab[nsndidxnum ++] = vertglbend - procvgbtab[procngbnum] + grafptr->baseval; /* Buffer local value on neighbor processor */ DGRAPHBANDGROWENQ3; /* Send additional data if needed */ nsndidxtab[procngbnum] = nsndidxnum; } } } for (procngbnum = 0; procngbnum < procngbnbr; procngbnum ++) { int procglbnum; procglbnum = grafptr->procngbtab[procngbnum]; vsndcnttab[procglbnum] = nsndidxtab[procngbnum] - vsnddsptab[procglbnum]; } if (MPI_Alltoall (vsndcnttab, 1, MPI_INT, vrcvcnttab, 1, MPI_INT, grafptr->proccomm) != MPI_SUCCESS) { errorPrint (DGRAPHBANDGROWNSTR "Coll: communication error (2)"); return (1); } if (MPI_Alltoallv (vsnddattab, vsndcnttab, vsnddsptab, GNUM_MPI, vrcvdattab, vrcvcnttab, vrcvdsptab, GNUM_MPI, grafptr->proccomm) != MPI_SUCCESS) { errorPrint (DGRAPHBANDGROWNSTR "Coll: communication error (3)"); return (1); } for (procngbnum = 0; procngbnum < procngbnbr; procngbnum ++) { /* For all receive buffers */ Gnum * restrict vrcvdatptr; int vertrcvnum; int procglbnum; int statsiz; procglbnum = grafptr->procngbtab[procngbnum]; vrcvdatptr = vrcvdattab + vrcvdsptab[procglbnum]; statsiz = vrcvcnttab[procglbnum]; for (vertrcvnum = 0; vertrcvnum < statsiz; vertrcvnum += DGRAPHBANDGROWSMUL (1)) { Gnum vertlocend; vertlocend = vrcvdatptr[vertrcvnum]; /* Get local vertex from message */ #ifdef SCOTCH_DEBUG_DGRAPH2 if ((vertlocend < grafptr->baseval) || (vertlocend >= vertlocnnd)) { errorPrint (DGRAPHBANDGROWNSTR "Coll: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ if (vnumgsttax[vertlocend] != ~0) /* If end vertex has already been processed */ continue; /* Skip to next vertex */ vnumgsttax[vertlocend] = DGRAPHBANDGROWENQ4; /* Label vertex as enqueued */ queuloctab[queunextidx ++] = vertlocend; /* Enqueue vertex for next pass */ DGRAPHBANDGROWEDGE (vertlocend); /* Account for its edges */ } } queutailidx = queunextidx; /* Prepare queue for next sweep */ } memFree (procvgbtab); /* Free group leader */ *bandvertlocptr = bandvertlocnnd - grafptr->baseval; *bandedgelocptr = bandedgelocnbr; return (0); } /* This routine computes a distributed index array ** of given width around the current separator, ** using point-to-point communication. ** It returns: ** - 0 : if the index array could be computed. ** - !0 : on error. */ int DGRAPHBANDGROWNAMEPTOP ( Dgraph * restrict const grafptr, /*+ Distributed graph +*/ const Gnum queulocnbr, /*+ Number of frontier vertices, start size for vertex queue +*/ Gnum * restrict const queuloctab, /*+ Array of frontier vertices, re-used as queue array +*/ const Gnum distmax, /*+ Maximum distance from separator vertices +*/ Gnum * restrict const vnumgsttax, /*+ Flag or index array to fill +*/ Gnum * restrict const bandvertlvlptr, /*+ Pointer to based start index of last level +*/ Gnum * restrict const bandvertlocptr, /*+ Pointer to bandvertlocnnd +*/ Gnum * restrict const bandedgelocptr) /*+ Pointer to bandedgelocnbr +*/ { Gnum queulocnum; Gnum vertlocnnd; Gnum vnumgstsiz; /* Size of vnumgsttax; TRICK: re-use */ Gnum vrcvdatsiz; /* Sizes of data send and receive arrays */ Gnum vsnddatsiz; Gnum * vrcvdattab; /* Data arrays [norestrict:async] */ Gnum * vsnddattab; Gnum * restrict procvgbtab; /* Array of neighbor bounds [+1] */ int procngbnbr; int procngbnum; int procngbnxt; Gnum * restrict nrcvdsptab; Gnum * restrict nsnddsptab; Gnum nrcvdspnum; Gnum nsnddspnum; Gnum * restrict nsndidxtab; Gnum queuheadidx; /* Index of head of queue */ Gnum queutailidx; /* Index of tail of queue */ MPI_Request * nrcvreqtab; /* Array of receive requests */ MPI_Request * nsndreqtab; /* Array of receive requests */ Gnum bandvertlvlnum; Gnum bandvertlocnnd; Gnum bandedgelocnbr; Gnum distval; #ifdef SCOTCH_DEBUG_DGRAPH1 Gnum reduloctab[3]; Gnum reduglbtab[3]; #else /* SCOTCH_DEBUG_DGRAPH1 */ Gnum reduglbtab[1]; #endif /* SCOTCH_DEBUG_DGRAPH1 */ const Gnum * restrict const vertloctax = grafptr->vertloctax; const Gnum * restrict const vendloctax = grafptr->vendloctax; const Gnum * restrict const edgegsttax = grafptr->edgegsttax; const Gnum * restrict const edgeloctax = grafptr->edgeloctax; procngbnbr = grafptr->procngbnbr; reduglbtab[0] = 0; /* Assume everything is all right */ vrcvdatsiz = DGRAPHBANDGROWSMUL (grafptr->procsndnbr); /* Senders and receivers inverted because we send local, not halo vertices */ vsnddatsiz = DGRAPHBANDGROWSMUL (grafptr->vertgstnbr - grafptr->vertlocnbr); if (memAllocGroup ((void **) (void *) &procvgbtab, (size_t) ((procngbnbr + 1) * sizeof (Gnum)), &nrcvdsptab, (size_t) ((procngbnbr + 1) * sizeof (Gnum)), /* +1 to check against end of array */ &nsnddsptab, (size_t) ((procngbnbr + 1) * sizeof (Gnum)), /* +1 to check against end of array */ &nsndidxtab, (size_t) (procngbnbr * sizeof (Gnum)), /* Here Gnum's since point-to-point */ &nrcvreqtab, (size_t) (procngbnbr * sizeof (MPI_Request)), &nsndreqtab, (size_t) (procngbnbr * sizeof (MPI_Request)), &vrcvdattab, (size_t) (vrcvdatsiz * sizeof (Gnum)), &vsnddattab, (size_t) (vsnddatsiz * sizeof (Gnum)), NULL) == NULL) { errorPrint (DGRAPHBANDGROWNSTR "Ptop: out of memory (1)"); reduglbtab[0] = 1; } #ifdef SCOTCH_DEBUG_DGRAPH1 /* Communication not needed and not absorbable by the algorithm */ reduloctab[0] = reduglbtab[0]; reduloctab[1] = distmax; reduloctab[2] = - distmax; if (MPI_Allreduce (reduloctab, reduglbtab, 3, GNUM_MPI, MPI_MAX, grafptr->proccomm) != MPI_SUCCESS) { errorPrint (DGRAPHBANDGROWNSTR "Ptop: communication error (1)"); return (1); } if (reduglbtab[1] != - reduglbtab[2]) { errorPrint (DGRAPHBANDGROWNSTR "Ptop: invalid parameters"); reduglbtab[0] = 1; } #endif /* SCOTCH_DEBUG_DGRAPH1 */ if (reduglbtab[0] != 0) { if (vnumgsttax != NULL) { if (procvgbtab != NULL) memFree (procvgbtab); /* Free group leader */ memFree (vnumgsttax); } return (1); } for (procngbnum = 0, nrcvdspnum = nsnddspnum = procngbnxt = 0; /* Build communication index arrays */ procngbnum < procngbnbr; procngbnum ++) { int procglbnum; procglbnum = grafptr->procngbtab[procngbnum]; if ((procngbnxt == 0) && (procglbnum > grafptr->proclocnum)) /* Find index of first neighbor of higher rank */ procngbnxt = procngbnum; procvgbtab[procngbnum] = grafptr->procvrttab[procglbnum]; nrcvdsptab[procngbnum] = nrcvdspnum; /* Arrays are indexed per neighbor since we are doing point-to-point communication */ nsnddsptab[procngbnum] = nsnddspnum; nrcvdspnum += DGRAPHBANDGROWSMUL (grafptr->procsndtab[procglbnum]); /* Senders and receivers are reversed */ nsnddspnum += DGRAPHBANDGROWSMUL (grafptr->procrcvtab[procglbnum]); } procvgbtab[procngbnum] = grafptr->procvrttab[grafptr->procglbnbr]; nrcvdsptab[procngbnum] = nrcvdspnum; /* Mark end of communication index arrays */ nsnddsptab[procngbnum] = nsnddspnum; procngbnum = procngbnxt; /* Create receive requests in descending order */ if (procngbnbr != 0) { do { procngbnum = (procngbnum + (procngbnbr - 1)) % procngbnbr; /* Pre-decrement neighbor rank */ if (MPI_Recv_init (vrcvdattab + nrcvdsptab[procngbnum], (int) (nrcvdsptab[procngbnum + 1] - nrcvdsptab[procngbnum]), GNUM_MPI, grafptr->procngbtab[procngbnum], TAGBAND, grafptr->proccomm, nrcvreqtab + procngbnum) != MPI_SUCCESS) { errorPrint (DGRAPHBANDGROWNSTR "Ptop: communication error (2)"); return (1); } } while (procngbnum != procngbnxt); } bandvertlvlnum = /* Start index of last level is start index */ bandvertlocnnd = grafptr->baseval; /* Reset number of band vertices, plus base */ bandedgelocnbr = 0; /* No edges accounted for yet */ DGRAPHBANDGROWENQ1; /* Record queued vertices in index array and account for their edges */ vertlocnnd = grafptr->vertlocnnd; queuheadidx = 0; /* No queued vertex read yet */ queutailidx = queulocnbr; /* All frontier vertices are already in queue */ for (distval = 0; ++ distval <= distmax; ) { Gnum queunextidx; /* Tail index for enqueuing vertices of next band */ int vrcvreqnbr; if (MPI_Startall (procngbnbr, nrcvreqtab) != MPI_SUCCESS) { /* Start all receive operations from neighbors */ errorPrint (DGRAPHBANDGROWNSTR "Ptop: communication error (3)"); return (1); } bandvertlvlnum = bandvertlocnnd; /* Save start index of current level, based */ *bandvertlvlptr = bandvertlvlnum; memCpy (nsndidxtab, nsnddsptab, procngbnbr * sizeof (Gnum)); /* Reset send buffer indices */ for (queunextidx = queutailidx; queuheadidx < queutailidx; ) { /* For all vertices in queue */ Gnum vertlocnum; Gnum edgelocnum; vertlocnum = queuloctab[queuheadidx ++]; /* Dequeue vertex */ for (edgelocnum = vertloctax[vertlocnum]; edgelocnum < vendloctax[vertlocnum]; edgelocnum ++) { Gnum vertlocend; vertlocend = edgegsttax[edgelocnum]; if (vnumgsttax[vertlocend] != ~0) /* If end vertex has already been processed */ continue; /* Skip to next vertex */ if (vertlocend < vertlocnnd) { /* If end vertex is local */ vnumgsttax[vertlocend] = DGRAPHBANDGROWENQ2; /* Label vertex as enqueued */ queuloctab[queunextidx ++] = vertlocend; /* Enqueue vertex for next pass */ DGRAPHBANDGROWEDGE (vertlocend); /* Account for its edges */ } else { /* End vertex is a ghost */ Gnum vertglbend; int procngbnum; int procngbmax; int nsndidxnum; vnumgsttax[vertlocend] = 0; /* Label ghost vertex as enqueued */ vertglbend = edgeloctax[edgelocnum]; /* Get global number of end vertex */ procngbnum = 0; procngbmax = procngbnbr; while ((procngbmax - procngbnum) > 1) { /* Find owner process by dichotomy on procvgbtab */ int procngbmed; procngbmed = (procngbmax + procngbnum) / 2; if (procvgbtab[procngbmed] > vertglbend) procngbmax = procngbmed; else procngbnum = procngbmed; } #ifdef SCOTCH_DEBUG_DGRAPH2 if ((grafptr->procvrttab[grafptr->procngbtab[procngbnum]] > vertglbend) || (grafptr->procvrttab[grafptr->procngbtab[procngbnum] + 1] <= vertglbend) || (nsndidxtab[procngbnum] >= nsnddsptab[procngbnum + 1])) { errorPrint (DGRAPHBANDGROWNSTR "Ptop: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ nsndidxnum = nsndidxtab[procngbnum]; vsnddattab[nsndidxnum ++] = vertglbend - procvgbtab[procngbnum] + grafptr->baseval; /* Buffer local value on neighbor processor */ DGRAPHBANDGROWENQ3; /* Send additional data if needed */ nsndidxtab[procngbnum] = nsndidxnum; } } } procngbnum = procngbnxt; /* Send all buffers to neighbors */ if (procngbnbr != 0) { do { int procglbnum; procglbnum = grafptr->procngbtab[procngbnum]; if (MPI_Isend (vsnddattab + nsnddsptab[procngbnum], nsndidxtab[procngbnum] - nsnddsptab[procngbnum], GNUM_MPI, grafptr->procngbtab[procngbnum], TAGBAND, grafptr->proccomm, nsndreqtab + procngbnum) != MPI_SUCCESS) { errorPrint (DGRAPHBANDGROWNSTR "Ptop: communication error (4)"); return (1); } procngbnum = (procngbnum + 1) % procngbnbr; /* Post-increment neighbor rank */ } while (procngbnum != procngbnxt); } for (vrcvreqnbr = procngbnbr; vrcvreqnbr > 0; vrcvreqnbr --) { /* For all pending receive requests */ Gnum * restrict vrcvdatptr; int vertrcvnum; MPI_Status statdat; int statsiz; int o; #ifdef SCOTCH_DETERMINISTIC procngbnum = vrcvreqnbr - 1; o = MPI_Wait (&nrcvreqtab[procngbnum], &statdat); #else /* SCOTCH_DETERMINISTIC */ o = MPI_Waitany (procngbnbr, nrcvreqtab, &procngbnum, &statdat); #endif /* SCOTCH_DETERMINISTIC */ if ((o != MPI_SUCCESS) || (MPI_Get_count (&statdat, GNUM_MPI, &statsiz) != MPI_SUCCESS)) { errorPrint (DGRAPHBANDGROWNSTR "Ptop: communication error (5)"); return (1); } #ifdef SCOTCH_DEBUG_DGRAPH2 if (statdat.MPI_SOURCE != grafptr->procngbtab[procngbnum]) { errorPrint (DGRAPHBANDGROWNSTR "Ptop: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ vrcvdatptr = vrcvdattab + nrcvdsptab[procngbnum]; for (vertrcvnum = 0; vertrcvnum < statsiz; vertrcvnum += DGRAPHBANDGROWSMUL (1)) { Gnum vertlocend; vertlocend = vrcvdatptr[vertrcvnum]; /* Get local vertex from message */ #ifdef SCOTCH_DEBUG_DGRAPH2 if ((vertlocend < grafptr->baseval) || (vertlocend >= vertlocnnd)) { errorPrint (DGRAPHBANDGROWNSTR "dgraphBandPtop: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ if (vnumgsttax[vertlocend] != ~0) /* If end vertex has already been processed */ continue; /* Skip to next vertex */ vnumgsttax[vertlocend] = DGRAPHBANDGROWENQ4; /* Label vertex as enqueued */ queuloctab[queunextidx ++] = vertlocend; /* Enqueue vertex for next pass */ DGRAPHBANDGROWEDGE (vertlocend); /* Account for its edges */ } } queutailidx = queunextidx; /* Prepare queue for next sweep */ if (MPI_Waitall (procngbnbr, nsndreqtab, MPI_STATUSES_IGNORE) != MPI_SUCCESS) { /* Wait until all send operations completed */ errorPrint (DGRAPHBANDGROWNSTR "Ptop: communication error (6)"); return (1); } } for (procngbnum = 0; procngbnum < procngbnbr; procngbnum ++) { /* Free persistent receive requests */ if (MPI_Request_free (nrcvreqtab + procngbnum) != MPI_SUCCESS) { errorPrint (DGRAPHBANDGROWNSTR "Ptop: communication error (7)"); return (1); } } memFree (procvgbtab); /* Free group leader */ *bandvertlocptr = bandvertlocnnd - grafptr->baseval; *bandedgelocptr = bandedgelocnbr; return (0); } scotch-6.0.4.dfsg/src/libscotch/library_arch_build.c0000644002563400244210000001314511631447171025627 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_arch_build.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the target **/ /** architecture building routine of the **/ /** libSCOTCH library. **/ /** **/ /** DATES : # Version 3.3 : from : 02 oct 1998 **/ /** to 29 mar 1999 **/ /** # Version 3.4 : from : 01 nov 2001 **/ /** to 01 nov 2001 **/ /** # Version 4.0 : from : 08 mar 2005 **/ /** to 17 mar 2005 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "arch.h" #include "arch_build.h" #include "mapping.h" #include "bgraph.h" #include "bgraph_bipart_st.h" #include "scotch.h" /**************************************/ /* */ /* These routines are the C API for */ /* the architecture building routine. */ /* */ /**************************************/ /*+ This routine parses the given *** bipartitioning strategy. *** It returns: *** - 0 : if string successfully scanned. *** - !0 : on error. +*/ int SCOTCH_stratGraphBipart ( SCOTCH_Strat * const stratptr, const char * const string) { if (*((Strat **) stratptr) != NULL) stratExit (*((Strat **) stratptr)); if ((*((Strat **) stratptr) = stratInit (&bgraphbipartststratab, string)) == NULL) { errorPrint ("SCOTCH_stratBipart: error in bipartitioning strategy"); return (1); } return (0); } /*+ This routine fills the contents of the given *** opaque target structure with the data provided *** by the user. The source graph provided on input *** is turned into a decomposition-defined target *** architecture. *** It returns: *** - 0 : if the computation succeeded. *** - !0 : on error. +*/ int SCOTCH_archBuild ( SCOTCH_Arch * const archptr, /*+ Target architecture to build +*/ const SCOTCH_Graph * const grafptr, /*+ Graph to turn into architecture +*/ const SCOTCH_Num listnbr, /*+ Number of elements in sublist +*/ const SCOTCH_Num * const listptr, /*+ Pointer to sublist +*/ const SCOTCH_Strat * const stratptr) /*+ Bipartitoning strategy +*/ { Strat * bipstratptr; VertList graflistdat; VertList * graflistptr; int o; if ((sizeof (SCOTCH_Num) != sizeof (Gnum)) || (sizeof (SCOTCH_Num) != sizeof (Anum))) { errorPrint ("SCOTCH_archBuild: internal error (1)"); return (1); } if (*((Strat **) stratptr) == NULL) /* Set default mapping strategy if necessary */ *((Strat **) stratptr) = stratInit (&bgraphbipartststratab, "(m{vert=50,low=h{pass=10},asc=f{move=100,bal=0.1}}f{move=100,bal=0.05})(/((load0=load)|(load0=0))?x;)"); bipstratptr = *((Strat **) stratptr); if (bipstratptr->tabl != &bgraphbipartststratab) { errorPrint ("SCOTCH_archBuild: not a bipartitioning strategy"); return (1); } if ((listnbr == ((Graph *) grafptr)->vertnbr) || (listnbr == 0) || (listptr == NULL)) graflistptr = NULL; else { graflistptr = &graflistdat; graflistdat.vnumnbr = (Gnum) listnbr; graflistdat.vnumtab = (Gnum *) listptr; } o = archBuild ((Arch * const) archptr, (const Graph * const) grafptr, graflistptr, bipstratptr); return (o); } scotch-6.0.4.dfsg/src/libscotch/vdgraph.c0000644002563400244210000001215211631447170023436 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vdgraph.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the distributed **/ /** separator handling routines. **/ /** **/ /** DATES : # Version 5.0 : from : 07 feb 2006 **/ /** to 13 mar 2006 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VDGRAPH #include "module.h" #include "common.h" #include "dgraph.h" #include "vdgraph.h" /*************************************/ /* */ /* These routines handle distributed */ /* separator graphs. */ /* */ /*************************************/ /* This routine initializes a distributed ** separator graph structure. As for the Dgraph ** structure, in order to avoid collective ** communication whenever possible, the allocation ** of send and receive index arrays is not performed ** in the routine itself, but rather delegated to ** subsequent routines such as dgraphBuild. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int vdgraphInit ( Vdgraph * restrict const grafptr, /* Distributed separator graph structure */ MPI_Comm proccomm) /* Communicator to be used for all communications */ { memSet (grafptr, 0, sizeof (Vdgraph)); /* Clear public and private graph fields */ grafptr->s.proccomm = proccomm; /* Set private fields */ MPI_Comm_size (proccomm, &grafptr->s.procglbnbr); /* Get communicator data */ MPI_Comm_rank (proccomm, &grafptr->s.proclocnum); return (0); } /* This routine frees the contents ** of the given distributed active graph. ** It returns: ** - VOID : in all cases. */ void vdgraphExit ( Vdgraph * const grafptr) { if (grafptr->partgsttax != NULL) memFree (grafptr->partgsttax + grafptr->s.baseval); if (grafptr->fronloctab != NULL) memFree (grafptr->fronloctab); dgraphExit (&grafptr->s); /* Free distributed source graph and its private data (flagval may be corrupted afterwards) */ #ifdef SCOTCH_DEBUG_VDGRAPH2 memSet (grafptr, ~0, sizeof (Vdgraph)); #endif /* SCOTCH_DEBUG_VDGRAPH2 */ } /* This routine moves all of the graph ** vertices to the first part. ** It returns: ** - VOID : in all cases. */ void vdgraphZero ( Vdgraph * const grafptr) { memSet (grafptr->partgsttax + grafptr->s.baseval, 0, grafptr->s.vertgstnbr * sizeof (GraphPart)); /* Set all local and ghost vertices to part 0 */ grafptr->compglbloaddlt = grafptr->s.veloglbsum; grafptr->compglbload[0] = grafptr->s.veloglbsum; /* No frontier vertices */ grafptr->compglbload[1] = grafptr->compglbload[2] = 0; grafptr->compglbsize[0] = grafptr->s.vertglbnbr; grafptr->compglbsize[1] = grafptr->compglbsize[2] = 0; grafptr->complocload[0] = grafptr->s.velolocsum; grafptr->complocload[1] = grafptr->complocload[2] = 0; grafptr->complocsize[0] = grafptr->s.vertlocnbr; grafptr->complocsize[1] = grafptr->complocsize[2] = 0; } scotch-6.0.4.dfsg/src/libscotch/hmesh_order_hd.h0000644002563400244210000000666011631447170024771 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2009 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh_order_hd.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the block-oriented Halo **/ /** Approximate (Multiple) Minimum Degree **/ /** mesh ordering routine. **/ /** **/ /** DATES : # Version 4.0 : from : 09 dec 2003 **/ /** to 10 dec 2003 **/ /** # Version 5.1 : from : 01 oct 2009 **/ /** to : 01 oct 2009 **/ /** **/ /************************************************************/ /* ** The defines. */ #define HMESHORDERHDCOMPRAT 1.2L /*+ Compression ratio +*/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct HmeshOrderHdParam_ { INT colmin; /*+ Minimum number of columns +*/ INT colmax; /*+ Maximum number of columns +*/ double fillrat; /*+ Fill-in ratio +*/ } HmeshOrderHdParam; /* ** The function prototypes. */ #ifndef HMESH_ORDER_HD #define static #endif int hmeshOrderHd (const Hmesh * restrict const, Order * restrict const, const Gnum, OrderCblk * restrict const, const HmeshOrderHdParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/vgraph_separate_vw.c0000644002563400244210000001061112225617616025674 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010,2013 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vgraph_separate_vw.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module outputs the state of the **/ /** current partition on the form of a **/ /** Scotch mapping file. **/ /** **/ /** DATES : # Version 4.0 : from : 18 may 2004 **/ /** to 18 may 2004 **/ /** # Version 5.1 : from : 11 aug 2010 **/ /** to 11 aug 2010 **/ /** # Version 6.0 : from : 10 oct 2013 **/ /** to 10 oct 2013 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VGRAPH_SEPARATE_VW #include "module.h" #include "common.h" #include "gain.h" #include "graph.h" #include "vgraph.h" #include "vgraph_separate_vw.h" /* ** The static variables. */ static int vgraphseparatevwfilenum = 0; /* Number of file to output */ /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine outputs the mapping file. ** It returns: ** - 0 : if the file could be produced. ** - !0 : on error. */ int vgraphSeparateVw ( Vgraph * restrict const grafptr) /*+ Separation graph +*/ { char nametab[64]; /* File name */ FILE * restrict fileptr; Gnum vertnum; /* Vertex number */ sprintf (nametab, "vgraphseparatevw_output_%08d.map", vgraphseparatevwfilenum ++); if ((fileptr = fopen (nametab, "w+")) == NULL) { errorPrint ("vgraphSeparateVw: cannot open partition file"); return (1); } fprintf (fileptr, GNUMSTRING "\n", /* Output size of mapping; test if failure later, in main loop */ (Gnum) grafptr->s.vertnbr); for (vertnum = grafptr->s.baseval; vertnum < grafptr->s.vertnnd; vertnum ++) { if (fprintf (fileptr, GNUMSTRING "\t%d\n", (Gnum) ((grafptr->s.vnumtax != NULL) ? grafptr->s.vnumtax[vertnum] : vertnum), (int) grafptr->parttax[vertnum]) <= 0) { errorPrint ("vgraphSeparateVw: bad output"); fclose (fileptr); return (1); } } fclose (fileptr); return (0); } scotch-6.0.4.dfsg/src/libscotch/mesh_io.h0000644002563400244210000000532711631447170023441 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mesh_io.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the source graph input/output **/ /** functions. **/ /** **/ /** DATES : # Version 4.0 : from : 14 nov 2002 **/ /** to 14 nov 2002 **/ /** **/ /************************************************************/ /* ** The function prototypes. */ #ifndef MESH_IO #define static #endif int meshLoad2 (const Gnum, const Gnum, const Gnum * const, const Gnum * const, Gnum * const, const Gnum, const Gnum * const); #undef static scotch-6.0.4.dfsg/src/libscotch/dgraph_band.c0000644002563400244210000006030612030553506024233 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_band.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module computes a distributed band **/ /** graph from the given frontier array. **/ /** **/ /** DATES : # Version 5.1 : from : 11 nov 2007 **/ /** to : 20 feb 2011 **/ /** # Version 6.0 : from : 03 apr 2012 **/ /** to : 26 sep 2012 **/ /** **/ /** NOTES : # This code derives from the code of **/ /** vdgraph_separate_bd.c in version 5.0. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DGRAPH_BAND #include "module.h" #include "common.h" #include "dgraph.h" /**********************************/ /* */ /* Distance computation routines. */ /* */ /**********************************/ #define DGRAPHBANDGROWNAME dgraphBand #define DGRAPHBANDGROWEDGE(n) bandedgelocnbr += vendloctax[n] - vertloctax[n] #define DGRAPHBANDGROWENQ1 for (queulocnum = 0; queulocnum < queulocnbr; queulocnum ++) { \ Gnum vertlocnum; \ \ vertlocnum = queuloctab[queulocnum]; \ vnumgsttax[vertlocnum] = bandvertlocnnd ++; \ DGRAPHBANDGROWEDGE (vertlocnum); \ } #define DGRAPHBANDGROWENQ2 bandvertlocnnd ++ #define DGRAPHBANDGROWENQ3 /* Nothing more to send */ #define DGRAPHBANDGROWENQ4 bandvertlocnnd ++ #define DGRAPHBANDGROWSMUL(n) (n) #include "dgraph_band_grow.h" #include "dgraph_band_grow.c" #undef DGRAPHBANDGROWNAME #undef DGRAPHBANDGROWEDGE #undef DGRAPHBANDGROWENQU #undef DGRAPHBANDGROWSMUL /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine computes a distributed index array ** of given width around the current separator. ** It returns: ** - 0 : if the index array could be computed. ** - !0 : on error. */ int dgraphBand ( Dgraph * restrict const grafptr, /*+ Distributed graph +*/ const Gnum fronlocnbr, /*+ Number of frontier vertices +*/ Gnum * restrict const fronloctab, /*+ Array of frontier vertices, re-used as queue array +*/ const GraphPart * restrict const partgsttax, /*+ Part array for original graph ({0,1} or {0,1,2}) +*/ const Gnum complocload0, /*+ Load in part 0 or {0,2} +*/ const Gnum complocload1, /*+ Load in part 1 +*/ Gnum distmax, /*+ Maximum distance from separator vertices +*/ Dgraph * restrict const bandgrafptr, /*+ Pointer to band graph structure to fill +*/ Gnum * restrict * const bandfronlocptr, /*+ Pointer to bandfronloctab +*/ GraphPart * restrict * const bandpartgstptr, /*+ Pointer to bandpartgsttax +*/ Gnum * const bandvertlvlptr, /*+ Pointer to based start index of last level +*/ Gnum * const bandvertlocptr1, /*+ Pointer to number of band vertices in part 1 +*/ Gnum * const bandvertlocancptr) /*+ Pointer to flag set if anchor vertices overloaded +*/ { Gnum bandvertlocnnd; /* End of local band vertex array, (without anchor vertices) */ Gnum bandvertlocnbr; /* Number of local band vertices (including anchor vertices) */ Gnum bandvertlocnbr1; /* Number of band graph vertices in part 1 except anchor 1 */ Gnum bandvertlvlnum; /* Index of first band vertex belonging to last level */ Gnum * restrict bandvertloctax; Gnum bandvertlocadj; /* Ajust value for local-to-global band vertex indices */ Gnum bandvertlocancadj; /* Flag set when anchor(s) represent unexistent vertices */ Gnum bandvertlocnum; Gnum bandvelolocsum; Gnum bandvelolocsum1; Gnum * restrict bandedgeloctax; Gnum bandedgelocnum; Gnum bandedgeloctmp; Gnum bandedgelocnbr; /* Number of local edges in band graph */ Gnum * restrict bandedloloctax; Gnum bandedlolocnbr; /* Size of local band edge load array */ Gnum * restrict bandfronloctab; GraphPart * restrict bandpartgsttax; Gnum bandvnumgstsiz; Gnum * restrict bandvnumgsttax; /* Indices of selected band vertices in band graph */ Gnum banddegrlocmax; Gnum degrval; Gnum veloval; const Gnum * restrict edgegsttax; Gnum fronlocnum; int cheklocval; int chekglbval; int procngbnum; if (dgraphGhst (grafptr) != 0) { /* Compute ghost edge array if not already present */ errorPrint ("dgraphBand: cannot compute ghost edge array"); return (1); } cheklocval = 0; bandvnumgstsiz = MAX ((grafptr->vertgstnbr * sizeof (Gnum)), (grafptr->procglbnbr * sizeof (int))); /* TRICK: re-use array for further error collective communications */ if ((bandvnumgsttax = memAlloc (bandvnumgstsiz)) == NULL) { errorPrint ("dgraphBand: out of memory (1)"); cheklocval = 1; } #ifdef SCOTCH_DEBUG_DGRAPH1 /* This communication cannot be covered by a useful one */ if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphBand: communication error (1)"); return (1); } #else /* SCOTCH_DEBUG_DGRAPH1 */ chekglbval = cheklocval; #endif /* SCOTCH_DEBUG_DGRAPH1 */ if (chekglbval != 0) return (1); memSet (bandvnumgsttax, ~0, grafptr->vertgstnbr * sizeof (Gnum)); /* Reset part array */ bandvnumgsttax -= grafptr->baseval; if ((((grafptr->flagval & DGRAPHCOMMPTOP) != 0) ? dgraphBandPtop : dgraphBandColl) (grafptr, fronlocnbr, fronloctab, distmax, bandvnumgsttax, &bandvertlvlnum, &bandvertlocnbr, &bandedgelocnbr) != 0) return (1); if (bandvertlvlptr != NULL) *bandvertlvlptr = bandvertlvlnum; bandedgelocnbr += 2 * ((bandvertlocnbr + grafptr->baseval - bandvertlvlnum) + (grafptr->procglbnbr - 1)); /* Add edges to and from anchors */ bandvertlocnbr += 2; /* Add anchor vertices */ bandedlolocnbr = (grafptr->edloloctax != NULL) ? bandedgelocnbr : 0; dgraphInit (bandgrafptr, grafptr->proccomm); bandgrafptr->flagval = (DGRAPHFREEALL ^ DGRAPHFREECOMM) | DGRAPHVERTGROUP | DGRAPHEDGEGROUP; /* Arrays created by the routine itself */ bandgrafptr->baseval = grafptr->baseval; if (memAllocGroup ((void **) (void *) /* Allocate distributed graph private data */ &bandgrafptr->procdsptab, (size_t) ((grafptr->procglbnbr + 1) * sizeof (Gnum)), &bandgrafptr->proccnttab, (size_t) (grafptr->procglbnbr * sizeof (Gnum)), &bandgrafptr->procngbtab, (size_t) (grafptr->procglbnbr * sizeof (int)), &bandgrafptr->procrcvtab, (size_t) (grafptr->procglbnbr * sizeof (int)), &bandgrafptr->procsndtab, (size_t) (grafptr->procglbnbr * sizeof (int)), NULL) == NULL) { errorPrint ("dgraphBand: out of memory (2)"); cheklocval = 1; } else if (memAllocGroup ((void **) (void *) /* Allocate distributed graph public data */ &bandgrafptr->vertloctax, (size_t) ((bandvertlocnbr + 1) * sizeof (Gnum)), /* Compact vertex array */ &bandgrafptr->vnumloctax, (size_t) (bandvertlocnbr * sizeof (Gnum)), &bandgrafptr->veloloctax, (size_t) (bandvertlocnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("dgraphBand: out of memory (3)"); cheklocval = 1; } else if (bandgrafptr->vertloctax -= bandgrafptr->baseval, bandgrafptr->veloloctax -= bandgrafptr->baseval, bandgrafptr->vnumloctax -= bandgrafptr->baseval, (memAllocGroup ((void **) (void *) &bandedgeloctax, (size_t) (bandedgelocnbr * sizeof (Gnum)), &bandedloloctax, (size_t) (bandedlolocnbr * sizeof (Gnum)), NULL) == NULL)) { errorPrint ("dgraphBand: out of memory (4)"); cheklocval = 1; } else { bandedgeloctax -= bandgrafptr->baseval; bandedloloctax = (grafptr->edloloctax != NULL) ? (bandedloloctax - bandgrafptr->baseval) : NULL; if ((bandfronloctab = memAlloc (bandvertlocnbr * sizeof (Gnum))) == NULL) { errorPrint ("dgraphBand: out of memory (5)"); cheklocval = 1; } else if ((bandpartgsttax = memAlloc ((bandvertlocnbr + bandedgelocnbr) * sizeof (GraphPart))) == NULL) { /* Upper bound on number of ghost vertices */ errorPrint ("dgraphBand: out of memory (6)"); cheklocval = 1; } else bandpartgsttax -= bandgrafptr->baseval; } if (cheklocval != 0) { /* In case of memory error */ bandgrafptr->procdsptab[0] = -1; if (MPI_Allgather (&bandgrafptr->procdsptab[0], 1, GNUM_MPI, /* Send received data to dummy array */ bandvnumgsttax + bandgrafptr->baseval, 1, GNUM_MPI, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphBand: communication error (2)"); return (1); } if (bandfronloctab != NULL) memFree (bandfronloctab); dgraphFree (bandgrafptr); memFree (bandvnumgsttax + bandgrafptr->baseval); return (1); } else { bandgrafptr->procdsptab[0] = bandvertlocnbr; if (MPI_Allgather (&bandgrafptr->procdsptab[0], 1, GNUM_MPI, &bandgrafptr->procdsptab[1], 1, GNUM_MPI, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphBand: communication error (3)"); return (1); } } bandgrafptr->procdsptab[0] = bandgrafptr->baseval; /* Build vertex-to-process array */ #ifdef SCOTCH_DEBUG_DGRAPH2 memSet (bandgrafptr->vnumloctax + bandgrafptr->baseval, ~0, (bandvertlocnbr * sizeof (Gnum))); #endif /* SCOTCH_DEBUG_DGRAPH2 */ for (procngbnum = 1; procngbnum <= grafptr->procglbnbr; procngbnum ++) { /* Process potential error flags from other processes */ if (bandgrafptr->procdsptab[procngbnum] < 0) { /* If error notified by another process */ if (bandpartgsttax != NULL) memFree (bandpartgsttax + bandgrafptr->baseval); if (bandfronloctab != NULL) memFree (bandfronloctab); dgraphFree (bandgrafptr); memFree (bandvnumgsttax + bandgrafptr->baseval); return (1); } bandgrafptr->procdsptab[procngbnum] += bandgrafptr->procdsptab[procngbnum - 1]; bandgrafptr->proccnttab[procngbnum - 1] = bandgrafptr->procdsptab[procngbnum] - bandgrafptr->procdsptab[procngbnum - 1]; } for (fronlocnum = 0, bandvertlocnum = bandgrafptr->baseval, bandvertlocadj = bandgrafptr->procdsptab[grafptr->proclocnum] - bandgrafptr->baseval; fronlocnum < fronlocnbr; fronlocnum ++, bandvertlocnum ++) { /* Turn all graph frontier vertices into band frontier vertices */ Gnum vertlocnum; bandfronloctab[fronlocnum] = bandvertlocnum; /* All frontier vertices are first vertices of band graph */ vertlocnum = fronloctab[fronlocnum]; bandgrafptr->vnumloctax[bandvertlocnum] = vertlocnum; bandvnumgsttax[vertlocnum] += bandvertlocadj; /* Turn local indices in band graph into global indices */ } for (bandvertlocnnd = bandvertlocnbr + bandgrafptr->baseval - 2; /* Pick selected band vertices from rest of frontier array without anchors */ bandvertlocnum < bandvertlocnnd; fronlocnum ++, bandvertlocnum ++) { Gnum vertlocnum; vertlocnum = fronloctab[fronlocnum]; bandgrafptr->vnumloctax[bandvertlocnum] = vertlocnum; bandvnumgsttax[vertlocnum] += bandvertlocadj; /* Turn local indices in band graph into global indices */ } bandgrafptr->vnumloctax[bandvertlocnnd] = /* Prevent Valgrind from yelling when centralizing band graphs */ bandgrafptr->vnumloctax[bandvertlocnnd + 1] = -1; if (dgraphHaloSync (grafptr, (byte *) (bandvnumgsttax + bandgrafptr->baseval), GNUM_MPI) != 0) { /* Share global indexing of halo vertices */ errorPrint ("dgraphBand: cannot perform halo exchange"); return (1); } edgegsttax = grafptr->edgegsttax; veloval = 1; bandvertloctax = bandgrafptr->vertloctax; bandvertlocnbr1 = 0; bandvelolocsum = 0; bandvelolocsum1 = 0; banddegrlocmax = 0; for (bandvertlocnum = bandedgelocnum = bandgrafptr->baseval; /* Build global vertex array of band graph */ bandvertlocnum < bandvertlvlnum; bandvertlocnum ++) { /* For all vertices that do not belong to the last level */ Gnum vertlocnum; Gnum edgelocnum; Gnum degrval; GraphPart partval; Gnum partval1; vertlocnum = bandgrafptr->vnumloctax[bandvertlocnum]; partval = partgsttax[vertlocnum]; #ifdef SCOTCH_DEBUG_DGRAPH2 if (partval > 2) { errorPrint ("dgraphBand: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ partval1 = partval & 1; bandvertlocnbr1 += partval1; /* Count vertices in part 1 */ bandpartgsttax[bandvertlocnum] = partval; bandvertloctax[bandvertlocnum] = bandedgelocnum; if (grafptr->veloloctax != NULL) { veloval = grafptr->veloloctax[vertlocnum]; bandvelolocsum += veloval; bandvelolocsum1 += veloval & (- partval1); /* Sum vertex load if (partval == 1) */ } bandgrafptr->veloloctax[bandvertlocnum] = veloval; degrval = grafptr->vendloctax[vertlocnum] - grafptr->vertloctax[vertlocnum]; if (banddegrlocmax < degrval) banddegrlocmax = degrval; for (edgelocnum = grafptr->vertloctax[vertlocnum]; /* For all original edges */ edgelocnum < grafptr->vendloctax[vertlocnum]; edgelocnum ++) { #ifdef SCOTCH_DEBUG_DGRAPH2 if (bandvnumgsttax[edgegsttax[edgelocnum]] == ~0) { /* All ends should belong to the band graph too */ errorPrint ("dgraphBand: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ bandedgeloctax[bandedgelocnum ++] = bandvnumgsttax[edgegsttax[edgelocnum]]; } } for ( ; bandvertlocnum < bandvertlocnnd; bandvertlocnum ++) { /* For all vertices that belong to the last level except anchors */ Gnum vertlocnum; Gnum edgelocnum; Gnum degrval; GraphPart partval; Gnum partval1; vertlocnum = bandgrafptr->vnumloctax[bandvertlocnum]; partval = partgsttax[vertlocnum]; #ifdef SCOTCH_DEBUG_DGRAPH2 if (partval > 2) { errorPrint ("dgraphBand: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ partval1 = partval & 1; bandvertlocnbr1 += partval1; /* Count vertices in part 1 */ bandpartgsttax[bandvertlocnum] = partval; bandvertloctax[bandvertlocnum] = bandedgelocnum; if (grafptr->veloloctax != NULL) { veloval = grafptr->veloloctax[vertlocnum]; bandvelolocsum += veloval; bandvelolocsum1 += veloval & (- partval1); /* Sum vertex load if (partval == 1) */ } bandgrafptr->veloloctax[bandvertlocnum] = veloval; for (edgelocnum = grafptr->vertloctax[vertlocnum]; /* For all original edges */ edgelocnum < grafptr->vendloctax[vertlocnum]; edgelocnum ++) { Gnum bandvertlocend; bandvertlocend = bandvnumgsttax[edgegsttax[edgelocnum]]; if (bandvertlocend != ~0) { /* If end vertex belongs to band graph */ if (bandedloloctax != NULL) /* If graph has edge weights, copy load */ bandedloloctax[bandedgelocnum] = grafptr->edloloctax[edgelocnum]; bandedgeloctax[bandedgelocnum ++] = bandvertlocend; } } if (bandedloloctax != NULL) /* If graph has edge weights */ bandedloloctax[bandedgelocnum] = 1; /* Edge to anchor has load 1 */ bandedgeloctax[bandedgelocnum ++] = bandvertlocnnd + bandvertlocadj + partval1; /* Add edge to anchor of proper part */ degrval = bandedgelocnum - bandvertloctax[bandvertlocnum]; if (banddegrlocmax < degrval) banddegrlocmax = degrval; } memFree (bandvnumgsttax + bandgrafptr->baseval); /* Free useless space */ bandpartgsttax[bandvertlocnnd] = 0; /* Set parts of anchor vertices */ bandpartgsttax[bandvertlocnnd + 1] = 1; bandvertloctax[bandvertlocnum] = bandedgelocnum; /* Process anchor vertex in part 0 */ for (procngbnum = 0; procngbnum < grafptr->proclocnum; procngbnum ++) /* Build clique with anchors of part 0 */ bandedgeloctax[bandedgelocnum ++] = bandgrafptr->procdsptab[procngbnum + 1] - 2; for (procngbnum ++; procngbnum < grafptr->procglbnbr; procngbnum ++) /* Build clique with anchors of part 0 */ bandedgeloctax[bandedgelocnum ++] = bandgrafptr->procdsptab[procngbnum + 1] - 2; bandedgeloctmp = bandedgelocnum + (bandvertlocnnd - bandvertlvlnum); for (procngbnum = 0; procngbnum < grafptr->proclocnum; procngbnum ++) /* Build clique with anchors of part 1 */ bandedgeloctax[bandedgeloctmp ++] = bandgrafptr->procdsptab[procngbnum + 1] - 1; for (procngbnum ++; procngbnum < grafptr->procglbnbr; procngbnum ++) /* Build clique with anchors of part 1 */ bandedgeloctax[bandedgeloctmp ++] = bandgrafptr->procdsptab[procngbnum + 1] - 1; bandvertloctax[bandvertlocnnd + 2] = bandedgeloctmp; bandedgelocnbr = bandedgeloctmp - bandgrafptr->baseval; /* Set real number of edges */ for (bandvertlocnum = bandvertlvlnum, bandedgeloctmp = bandedgelocnum + (bandvertlocnnd - bandvertlvlnum); /* Link vertices of last level to anchors */ bandvertlocnum < bandvertlocnnd; bandvertlocnum ++) { if (bandpartgsttax[bandvertlocnum] == 0) bandedgeloctax[bandedgelocnum ++] = bandvertlocnum + bandvertlocadj; else bandedgeloctax[-- bandedgeloctmp] = bandvertlocnum + bandvertlocadj; } bandvertloctax[bandvertlocnnd + 1] = bandedgeloctmp; degrval = bandvertloctax[bandvertlocnnd + 1] - bandvertloctax[bandvertlocnnd]; if (banddegrlocmax < degrval) banddegrlocmax = degrval; degrval = bandvertloctax[bandvertlocnnd + 2] - bandvertloctax[bandvertlocnnd + 1]; if (banddegrlocmax < degrval) banddegrlocmax = degrval; if (bandedloloctax != NULL) { /* If graph has edge weights */ Gnum edgelocnum; Gnum edgelocnnd; for (bandvertlocnum = bandgrafptr->baseval; /* For all vertices that do not belong to the last level */ bandvertlocnum < bandvertlvlnum; bandvertlocnum ++) { Gnum vertlocnum; Gnum bandedgelocnum; vertlocnum = bandgrafptr->vnumloctax[bandvertlocnum]; bandedgelocnum = bandvertloctax[bandvertlocnum]; memCpy (bandedloloctax + bandedgelocnum, /* Copy edge load array */ &grafptr->edloloctax[grafptr->vertloctax[vertlocnum]], (bandvertloctax[bandvertlocnum + 1] - bandedgelocnum) * sizeof (Gnum)); } /* Vertices of last level have been processed before */ for (edgelocnum = bandvertloctax[bandvertlocnnd], /* Loads of anchor edges are all 1's too */ edgelocnnd = bandvertloctax[bandvertlocnnd + 2]; edgelocnum < edgelocnnd; edgelocnum ++) bandedloloctax[edgelocnum] = 1; } if (grafptr->veloloctax == NULL) { /* If original graph is not weighted */ bandgrafptr->veloloctax[bandvertlocnnd] = complocload0 + bandvertlocnbr1 - bandvertlocnbr + 2; /* Plus 2 for anchors */ bandgrafptr->veloloctax[bandvertlocnnd + 1] = complocload1 - bandvertlocnbr1; } else { bandgrafptr->veloloctax[bandvertlocnnd] = complocload0 + bandvelolocsum1 - bandvelolocsum; bandgrafptr->veloloctax[bandvertlocnnd + 1] = complocload1 - bandvelolocsum1; } bandvertlocancadj = 0; if ((bandgrafptr->veloloctax[bandvertlocnnd] == 0) || /* If at least one anchor is empty */ (bandgrafptr->veloloctax[bandvertlocnnd + 1] == 0)) { bandvertlocancadj = 1; bandgrafptr->veloloctax[bandvertlocnnd] ++; /* Increase weight of both anchors to keep balance */ bandgrafptr->veloloctax[bandvertlocnnd + 1] ++; } bandgrafptr->procvrttab = bandgrafptr->procdsptab; /* Graph does not have holes */ bandgrafptr->vertlocnbr = bandvertlocnbr; bandgrafptr->vertlocnnd = bandvertlocnbr + bandgrafptr->baseval; bandgrafptr->vendloctax = bandvertloctax + 1; /* Band graph is compact */ bandgrafptr->velolocsum = grafptr->velolocsum + 2 * bandvertlocancadj; bandgrafptr->edgeloctax = bandedgeloctax; bandgrafptr->edloloctax = bandedloloctax; bandgrafptr->edgelocnbr = bandedgelocnbr; bandgrafptr->edgelocsiz = bandedgelocnbr; bandgrafptr->degrglbmax = banddegrlocmax; /* Local maximum degree will be turned into global maximum degree */ if (dgraphBuild4 (bandgrafptr) != 0) { errorPrint ("dgraphBand: cannot build band graph"); return (1); } #ifdef SCOTCH_DEBUG_DGRAPH2 if (dgraphCheck (bandgrafptr) != 0) { errorPrint ("dgraphBand: internal error (4)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ *bandfronlocptr = bandfronloctab; *bandpartgstptr = bandpartgsttax; *bandvertlocptr1 = bandvertlocnbr1; *bandvertlocancptr = bandvertlocancadj; return (0); } scotch-6.0.4.dfsg/src/libscotch/hgraph_order_si.h0000644002563400244210000000566111774101270025152 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hgraph_order_si.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the simple halo graph **/ /** ordering routine. **/ /** **/ /** DATES : # Version 3.2 : from : 01 nov 1996 **/ /** to : 18 aug 1998 **/ /** # Version 3.3 : from : 02 oct 1998 **/ /** to 02 oct 1998 **/ /** # Version 4.0 : from : 19 dec 2001 **/ /** to 11 dec 2002 **/ /** **/ /************************************************************/ /* ** The function prototypes. */ #ifndef HGRAPH_ORDER_SI #define static #endif int hgraphOrderSi (const Hgraph * const, Order * const, const Gnum, OrderCblk * const); #undef static scotch-6.0.4.dfsg/src/libscotch/hdgraph.h0000644002563400244210000001233411631447170023427 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hdgraph.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the source halo distributed graph **/ /** structure. **/ /** **/ /** DATES : # Version 5.0 : from : 15 apr 2006 **/ /** to 16 jun 2007 **/ /** # Version 5.1 : from : 04 nov 2010 **/ /** to 04 nov 2010 **/ /** **/ /************************************************************/ #define HDGRAPH_H /* ** The defines. */ /*+ Graph option flags. +*/ #define HDGRAPHFREEVHND 0x0400 /* Free vnhdtab array */ #define HDGRAPHFREETABS (DGRAPHFREETABS | HGRAPHFREEVHND) /* ** The type and structure definitions. */ /*+ Halo distributed graph structure. In order to keep efficiency, distributed halo graphs are not considered as regular graphs as sequential halo graphs were. Halo distributed graphs have a compact vertex array, with halo edges added at the end of each vertex sub-array. They are not visible when considering the vertlocnbr, vertloctax (which is in fact most often of size vhallocnbr + 1 when the graph is compact, as in this case we have vnhdloctax = vertloctax + 1) and vendloctax (which is of size vertlocnbr) of the embedded distributed graph, but can be accessed through vendloctax and vnhdloctax. Halo vertex ends are stored only in edgeloctax, not in edgegsttax, except when graph has only an edgegsttax and no edgeloctax. Since halo vertices have no real existence in distributed graphs, they are simply numbered from baseval. They are converted into real vertices when a distributed halo graph is turned into a sequential halo graph. */ typedef struct Hdgraph_ { Dgraph s; /*+ Source distributed graph +*/ Gnum vhallocnbr; /*+ Local number of halo end vertices +*/ Gnum * vhndloctax; /*+ End vertex array including halo vertex indices +*/ Gnum ehallocnbr; /*+ Local number of halo edges +*/ Gnum levlnum; /*+ Nested dissection level +*/ } Hdgraph; /* ** The function prototypes. */ #ifndef HDGRAPH #define static #endif int hdgraphInit (Hdgraph * const); void hdgraphExit (Hdgraph * const); void hdgraphFree (Hdgraph * const); int hdgraphFold (const Hdgraph *, const int, Hdgraph * const); int hdgraphFold2 (const Hdgraph *, const int, Hdgraph * const, MPI_Comm); int hdgraphCheck (const Hdgraph *); #ifdef HGRAPH_H int hdgraphGather (Hdgraph *, Hgraph *); #endif /* HGRAPH_H */ int hdgraphInduceList (Hdgraph * restrict const, const Gnum, const Gnum * restrict const, Hdgraph * restrict const); #undef static scotch-6.0.4.dfsg/src/libscotch/library_dgraph_coarsen_f.c0000644002563400244210000000713712055776164027033 0ustar trophimeutilisateurs du domaine/* Copyright 2011,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_coarsen_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the Fortran API for the **/ /** distributed graph coarsening routine of **/ /** the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.1 : from : 07 aug 2011 **/ /** to 07 aug 2011 **/ /** # Version 6.0 : from : 12 sep 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "ptscotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the mapping routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFDGRAPHCOARSEN, scotchfdgraphcoarsen, ( \ SCOTCH_Dgraph * const finegrafptr, \ const SCOTCH_Num * const coarnbrptr, \ double * const coarratptr, \ const SCOTCH_Num * const flagvalptr, \ SCOTCH_Dgraph * const coargrafptr, \ SCOTCH_Num * const multloctab, \ int * const revaptr), \ (finegrafptr, coarnbrptr, coarratptr, flagvalptr, coargrafptr, multloctab, revaptr)) { *revaptr = SCOTCH_dgraphCoarsen (finegrafptr, *coarnbrptr, *coarratptr, *flagvalptr, coargrafptr, multloctab); } scotch-6.0.4.dfsg/src/libscotch/mesh.c0000644002563400244210000001701511631447170022742 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mesh.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles the source mesh **/ /** functions. **/ /** **/ /** DATES : # Version 4.0 : from : 29 dec 2001 **/ /** to 05 may 2004 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define MESH #include "module.h" #include "common.h" #include "graph.h" #include "mesh.h" /****************************************/ /* */ /* These routines handle source meshes. */ /* */ /****************************************/ /* This routine initializes a source mesh ** structure. ** It returns: ** - 0 : in all cases. */ int meshInit ( Mesh * const meshptr) { memSet (meshptr, 0, sizeof (Mesh)); /* Initialize mesh fields */ meshptr->flagval = MESHFREETABS; /* By default, free all arrays */ return (0); } /* This routine frees a source mesh structure. ** It returns: ** - VOID : in all cases. */ void meshExit ( Mesh * const meshptr) { meshFree (meshptr); /* Exit mesh data */ #ifdef SCOTCH_DEBUG_MESH2 memSet (meshptr, ~0, sizeof (Mesh)); /* Purge mesh fields */ #endif /* SCOTCH_DEBUG_MESH2 */ } /* This routine frees the mesh data. Because ** vertex load arrays are either passed by ** the user, or grouped with other arrays, ** they are not considered for explicit ** freeing. This is also much simpler, as ** load arrays can be grouped or not. ** It returns: ** - VOID : in all cases. */ void meshFree ( Mesh * const meshptr) { if (((meshptr->flagval & MESHFREEEDGE) != 0) && /* If edgetab must be freed */ (meshptr->edgetax != NULL)) /* And if it exists */ memFree (meshptr->edgetax + meshptr->baseval); /* Free it */ if ((meshptr->flagval & MESHFREEVEND) != 0) { /* If vendtab must be freed */ if ((meshptr->vendtax != NULL) && /* If vendtab is distinct from verttab */ (meshptr->vendtax != meshptr->verttax + 1) && /* (if vertex arrays grouped, vendtab not distinct anyway) */ ((meshptr->flagval & MESHVERTGROUP) == 0)) memFree (meshptr->vendtax + meshptr->baseval); /* Then free vendtab */ } if ((meshptr->flagval & MESHFREEVERT) != 0) { /* If verttab must be freed */ if (meshptr->verttax != NULL) /* Free verttab anyway, as it is the array group leader */ memFree (meshptr->verttax + meshptr->baseval); } #ifdef SCOTCH_DEBUG_MESH2 if ((meshptr->flagval & MESHFREEVNUM) != 0) { /* If vnumtab must be freed */ if ((meshptr->vnumtax != NULL) && /* And is not in vertex array group */ ((meshptr->flagval & MESHVERTGROUP) == 0)) errorPrint ("meshFree: vnumtab should never be freed as its base may vary according to creation routines"); } #endif /* SCOTCH_DEBUG_MESH2 */ if ((meshptr->flagval & MESHFREEOTHR) != 0) { /* If other arrays must be freed */ if (meshptr->vlbltax != NULL) memFree (meshptr->vlbltax + meshptr->baseval); } #ifdef SCOTCH_DEBUG_MESH2 memSet (meshptr, ~0, sizeof (Mesh)); /* Purge mesh fields */ #endif /* SCOTCH_DEBUG_MESH2 */ } /* This routine sets the base of the given ** mesh to the given base value, and returns ** the old base value. ** It returns: ** - old base value : in all cases. */ Gnum meshBase ( Mesh * const meshptr, const Gnum baseval) { Gnum baseold; /* Old base value */ Gnum baseadj; /* Base adjustment */ Gnum vertnum; Gnum edgenum; if (meshptr->baseval == baseval) /* If nothing to do */ return (baseval); baseold = meshptr->baseval; /* Record old base value */ baseadj = baseval - baseold; /* Compute adjustment */ for (vertnum = meshptr->baseval; vertnum < (meshptr->velmnbr + meshptr->vnodnbr + meshptr->baseval); vertnum ++) { for (edgenum = meshptr->verttax[vertnum]; edgenum < meshptr->vendtax[vertnum]; edgenum ++) meshptr->edgetax[edgenum] += baseadj; meshptr->verttax[vertnum] += baseadj; } if (meshptr->vendtax != meshptr->verttax + 1) { /* If distinct vertex end array */ for (vertnum = meshptr->baseval; vertnum < (meshptr->velmnbr + meshptr->vnodnbr + meshptr->baseval); vertnum ++) meshptr->vendtax[vertnum] += baseadj; } else /* If same vertex end array (of size +1) */ meshptr->verttax[meshptr->velmnbr + meshptr->vnodnbr + meshptr->baseval] += baseadj; /* Adjust last entry of verttab */ meshptr->verttax -= baseadj; /* Adjust array accesses */ meshptr->vendtax -= baseadj; meshptr->edgetax -= baseadj; if (meshptr->vnumtax != NULL) meshptr->vnumtax -= baseadj; if (meshptr->vlbltax != NULL) meshptr->vlbltax -= baseadj; meshptr->baseval = baseval; /* Set new base value */ meshptr->velmbas += baseadj; /* Adjust mesh parameter */ meshptr->velmnnd += baseadj; meshptr->vnodbas += baseadj; meshptr->vnodnnd += baseadj; return (baseold); /* Return old base value */ } scotch-6.0.4.dfsg/src/libscotch/arch.h0000644002563400244210000003766512405305077022744 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007-2011,2013,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : arch.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the generic target architecture **/ /** functions. **/ /** **/ /** DATES : # Version 0.0 : from : 01 dec 1992 **/ /** to : 24 mar 1993 **/ /** # Version 1.2 : from : 04 feb 1994 **/ /** to : 11 feb 1994 **/ /** # Version 1.3 : from : 20 apr 1994 **/ /** to : 20 apr 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to : 12 nov 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to : 30 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 08 sep 1995 **/ /** # Version 3.1 : from : 02 may 1996 **/ /** to 20 jul 1996 **/ /** # Version 3.2 : from : 07 sep 1996 **/ /** to 13 may 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 07 oct 1998 **/ /** # Version 3.4 : from : 08 nov 2001 **/ /** to 08 nov 2001 **/ /** # Version 4.0 : from : 01 jan 2002 **/ /** to 07 dec 2004 **/ /** # Version 5.1 : from : 11 dec 2007 **/ /** to 11 aug 2010 **/ /** # Version 6.0 : from : 14 fev 2011 **/ /** to 01 aug 2014 **/ /** **/ /************************************************************/ #define ARCH_H /* ** The defines. */ /*+ Architecture flags. +*/ #define ARCHNONE 0x0000 /*+ No options set +*/ #define ARCHPART 0x0001 /*+ Architecture without external gains +*/ #define ARCHVAR 0x0002 /*+ Variable-sized architecture +*/ /* ** The type and structure definitions. */ typedef INT Anum; /*+ Generic integer +*/ #define ANUMMAX INTVALMAX #define ANUMSTRING INTSTRING #define ANUM_MPI COMM_INT /*+ MPI type for Gnum is MPI type for INT +*/ /*+ The domain number type. +*/ typedef Anum ArchDomNum; /*+ Domain number +*/ #define ARCHDOMNOTTERM ((ArchDomNum) ~0) /*+ Not-terminal number +*/ /*+ The sub-includes for structure size computations. +*/ #define ARCH_NOPROTO #include "arch_cmplt.h" #include "arch_cmpltw.h" #include "arch_deco.h" #include "arch_dist.h" #include "arch_hcub.h" #include "arch_tleaf.h" #include "arch_mesh.h" #include "arch_torus.h" #include "arch_vcmplt.h" #include "arch_vhcub.h" #undef ARCH_NOPROTO /*+ The architecture class type. +*/ typedef struct ArchClass_ { char * archname; /*+ Architecture name +*/ int flagval; /*+ Architecture flags of the class +*/ int (* archLoad) (); /*+ Architecture loading function +*/ int (* archSave) (); /*+ Architecture saving function +*/ int (* archFree) (); /*+ Architecture freeing function +*/ ArchDomNum (* domNum) (); /*+ Domain labeling function +*/ int (* domTerm) (); /*+ Terminal domain building function +*/ Anum (* domSize) (); /*+ Domain size function +*/ Anum (* domWght) (); /*+ Domain weight function +*/ Anum (* domDist) (); /*+ Distance computation function +*/ int (* domFrst) (); /*+ Compute biggest domain +*/ int (* domLoad) (); /*+ Domain loading routine +*/ int (* domSave) (); /*+ Domain saving routine +*/ int (* domBipart) (); /*+ Domain bipartitioning routine +*/ int (* domIncl) (); /*+ Domain inclusion routine +*/ #ifdef SCOTCH_PTSCOTCH int (* domMpiType) (); /*+ Domain MPI type building routine +*/ #endif /* SCOTCH_PTSCOTCH */ int domsizeof; /*+ Size in bytes of domain data +*/ } ArchClass; /*+ The architecture union type. +*/ typedef union { /*+ Architecture data +*/ ArchCmplt cmplt; /*+ Complete graph architecture +*/ ArchCmpltw cmpltw; /*+ Weighted complete graph architecture +*/ ArchDeco deco; /*+ Decomposition-described architecture +*/ ArchDist dist; /*+ Distance multiplicator pseudo-architecture +*/ ArchHcub hcub; /*+ Hypercube architecture +*/ ArchMesh2 mesh2; /*+ 2D-mesh architecture +*/ ArchMesh3 mesh3; /*+ 3D-mesh architecture +*/ ArchTleaf tleaf; /*+ Tree-leaf architecture +*/ ArchTorusX torusx; /*+ xD-torus architecture (includes 2D and 3D) +*/ ArchVcmplt vcmplt; /*+ Variable-sized complete graph architecture +*/ ArchVhcub vhcub; /*+ Variable-sized hypercube architecture +*/ } ArchDummy; /*+ The architecture type. +*/ typedef struct Arch_ { const ArchClass * class; /*+ Pointer to architecture class +*/ int flagval; /*+ (Possibly updated) architecture flags +*/ ArchDummy data; /*+ Architecture data +*/ } Arch; /*+ The architecture domain union type. +*/ typedef union { /*+ The domain data +*/ ArchCmpltDom cmplt; /*+ Complete graph domain type +*/ ArchCmpltwDom cmpltw; /*+ Weighted complete graph domain type +*/ ArchDecoDom deco; /*+ Decomposition-descripted domain type +*/ /*+ ArchDistDom dist; *+ Distance multiplicator domain is ArchDom +*/ ArchHcubDom hcub; /*+ Hypercube domain type +*/ ArchMesh2Dom mesh2; /*+ 2D-mesh domain type +*/ ArchMesh3Dom mesh3; /*+ 3D-mesh domain type +*/ ArchTleafDom tleaf; /*+ Tree-leaf domain type +*/ ArchTorusXDom torusx; /*+ xD-torus domain type (includes 2D and 3D) +*/ ArchVcmpltDom vcmplt; /*+ Variable-sized complete graph domain type +*/ ArchVhcubDom vhcub; /*+ Variable-sized hypercube domain type +*/ } ArchDomDummy; /*+ The domain structure type. +*/ typedef struct ArchDom_ { ArchDomDummy data; /*+ The domain data +*/ } ArchDom; /* ** The function prototypes. */ #ifndef ARCH #define static #endif int archInit (Arch * restrict const); int archExit (Arch * restrict const); int archFree (Arch * restrict const); int archLoad (Arch * restrict const, FILE * const); int archSave (const Arch * const, FILE * const); char * archName (const Arch * const); const ArchClass * archClass (const char * const); ArchDomNum archDomNum (const Arch * const, const ArchDom * const); int archDomTerm (const Arch * const, ArchDom * const, const ArchDomNum); Anum archDomSize (const Arch * const, const ArchDom * const); Anum archDomWght (const Arch * const, const ArchDom * const); Anum archDomDist (const Arch * const, const ArchDom * const, const ArchDom * const); int archDomFrst (const Arch * const, ArchDom * const); int archDomLoad (const Arch * const, ArchDom * const, FILE * const); int archDomSave (const Arch * const, const ArchDom * const, FILE * const); int archDomBipart (const Arch * const, const ArchDom * const, ArchDom * const, ArchDom * const); int archDomIncl (const Arch * const, const ArchDom * const, const ArchDom * const); #ifdef SCOTCH_PTSCOTCH int archDomMpiType (const Arch * const, MPI_Datatype * const); #endif /* SCOTCH_PTSCOTCH */ #undef static /* ** The macro definitions. */ #define archDomSizeof(a) ((a)->class->domsizeof) #define archName(a) (((a)->class == NULL) ? "" : (a)->class->archname) #define archPart(a) ((((a)->flagval) & ARCHPART) != 0) #define archVar(a) ((((a)->flagval) & ARCHVAR) != 0) #if ((! defined SCOTCH_DEBUG_ARCH2) || (defined ARCH)) #define archDomNum2(arch,dom) (((ArchDomNum (*) (const void * const, const void * const)) (arch)->class->domNum) ((const void * const) &(arch)->data, (const void * const) &(dom)->data)) #define archDomTerm2(arch,dom,num) (((int (*) (const void * const, void * const, const ArchDomNum)) (arch)->class->domTerm) ((void *) &(arch)->data, (void *) &(dom)->data, (num))) #define archDomSize2(arch,dom) (((Anum (*) (const void * const, const void * const)) (arch)->class->domSize) ((void *) &(arch)->data, (void *) &(dom)->data)) #define archDomWght2(arch,dom) (((Anum (*) (const void * const, const void * const)) (arch)->class->domWght) ((void *) &(arch)->data, (void *) &(dom)->data)) #define archDomDist2(arch,dom0,dom1) (((Anum (*) (const void * const, const void * const, const void * const)) (arch)->class->domDist) ((const void *) &(arch)->data, (const void *) &(dom0)->data, (const void *) &(dom1)->data)) #define archDomFrst2(arch,dom) (((int (*) (const void * const, void * const)) (arch)->class->domFrst) ((const void * const) &(arch)->data, (void * const) &(dom)->data)) #define archDomBipart2(arch,dom,dom0,dom1) (((int (*) (const void * const, const void * const, void * const, void * const)) (arch)->class->domBipart) ((const void * const) &(arch)->data, (const void * const) &(dom)->data, (void * const) &(dom0)->data, (void * const) &(dom1)->data)) #define archDomIncl2(arch,dom0,dom1) (((int (*) (const void * const, const void * const, void * const)) (arch)->class->domIncl) ((const void * const) &(arch)->data, (void * const) &(dom0)->data, (void * const) &(dom1)->data)) #endif #ifndef SCOTCH_DEBUG_ARCH2 #define archDomNum archDomNum2 #define archDomTerm archDomTerm2 #define archDomSize archDomSize2 #define archDomWght archDomWght2 #define archDomDist archDomDist2 #define archDomFrst archDomFrst2 #define archDomBipart archDomBipart2 #define archDomIncl archDomIncl2 #endif /* SCOTCH_DEBUG_ARCH2 */ #ifdef SCOTCH_PTSCOTCH #define ARCHCLASSBLOCK(s,n,f) { s, f, \ arch##n##ArchLoad, \ arch##n##ArchSave, \ arch##n##ArchFree, \ arch##n##DomNum, \ arch##n##DomTerm, \ arch##n##DomSize, \ arch##n##DomWght, \ arch##n##DomDist, \ arch##n##DomFrst, \ arch##n##DomLoad, \ arch##n##DomSave, \ arch##n##DomBipart, \ arch##n##DomIncl, \ arch##n##DomMpiType, \ sizeof (Arch##n##Dom) } #else /* SCOTCH_PTSCOTCH */ #define ARCHCLASSBLOCK(s,n,f) { s, f, \ arch##n##ArchLoad, \ arch##n##ArchSave, \ arch##n##ArchFree, \ arch##n##DomNum, \ arch##n##DomTerm, \ arch##n##DomSize, \ arch##n##DomWght, \ arch##n##DomDist, \ arch##n##DomFrst, \ arch##n##DomLoad, \ arch##n##DomSave, \ arch##n##DomBipart, \ arch##n##DomIncl, \ sizeof (Arch##n##Dom) } #endif /* SCOTCH_PTSCOTCH */ #define ARCHCLASSBLOCKNULL { NULL, ARCHNONE } #define ARCH_H_END scotch-6.0.4.dfsg/src/libscotch/fibo.c0000644002563400244210000002716311650650640022731 0ustar trophimeutilisateurs du domaine/* Copyright 2010,2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : fibo.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles Fibonacci trees. **/ /** **/ /** DATES : # Version 5.1 : from : 01 may 2010 **/ /** to 12 may 2010 **/ /** # Version 6.0 : from : 22 oct 2011 **/ /** to 22 oct 2011 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define FIBO #include "module.h" #include "common.h" #include "fibo.h" /*********************************************/ /* */ /* These routines deal with Fibonacci trees. */ /* */ /*********************************************/ /* This routine initializes a Fibonacci ** tree structure. ** It returns: ** - 0 : in case of success. ** - !0 : on error. */ int fiboTreeInit ( FiboTree * const treeptr, int (* cmpfptr) (const FiboNode * const, const FiboNode * const)) { if ((treeptr->degrtab = (FiboNode **) memAlloc ((sizeof (INT) << 3) * sizeof (FiboNode *))) == NULL) /* As many cells as there are bits in an INT */ return (1); memSet (treeptr->degrtab, 0, (sizeof (INT) << 3) * sizeof (FiboNode *)); /* Make degree array ready for consolidation: all cells set to NULL */ treeptr->rootdat.linkdat.prevptr = /* Link root node to itself */ treeptr->rootdat.linkdat.nextptr = &treeptr->rootdat; treeptr->cmpfptr = cmpfptr; return (0); } /* This routine flushes the contents of ** the given Fibonacci tree. ** It returns: ** - VOID : in all cases. */ void fiboTreeExit ( FiboTree * const treeptr) { if (treeptr->degrtab != NULL) memFree (treeptr->degrtab); } /* This routine flushes the contents of ** the given Fibonacci tree. ** It returns: ** - VOID : in all cases. */ void fiboTreeFree ( FiboTree * const treeptr) { treeptr->rootdat.linkdat.prevptr = /* Link root node to itself */ treeptr->rootdat.linkdat.nextptr = &treeptr->rootdat; } /* This routine perform the consolidation ** of roots per degree. It returns the best ** element found because this element is not ** recorded in the data structure itself. ** It returns: ** - !NULL : pointer to best element found. ** - NULL : Fibonacci tree is empty. */ FiboNode * fiboTreeConsolidate ( FiboTree * const treeptr) { FiboNode ** restrict degrtab; int degrmax; int degrval; FiboNode * rootptr; FiboNode * nextptr; FiboNode * bestptr; degrtab = treeptr->degrtab; for (rootptr = treeptr->rootdat.linkdat.nextptr, nextptr = rootptr->linkdat.nextptr, degrmax = 0; /* For all roots in root list */ rootptr != &treeptr->rootdat; ) { degrval = rootptr->deflval >> 1; /* Get degree, getting rid of flag part */ #ifdef SCOTCH_DEBUG_FIBO2 if (degrval >= (sizeof (INT) << 3)) errorPrint ("fiboTreeConsolidate: invalid node degree"); #endif /* SCOTCH_DEBUG_FIBO2 */ if (degrtab[degrval] == NULL) { /* If no tree with same degree already found */ if (degrval > degrmax) /* Record highest degree found */ degrmax = degrval; degrtab[degrval] = rootptr; /* Record tree as first tree with this degree */ rootptr = nextptr; /* Process next root in list during next iteration */ nextptr = rootptr->linkdat.nextptr; } else { FiboNode * oldrptr; /* Root which will no longer be a root */ FiboNode * chldptr; oldrptr = degrtab[degrval]; /* Assume old root is worse */ if (treeptr->cmpfptr (oldrptr, rootptr) <= 0) { /* If old root is still better */ oldrptr = rootptr; /* This root will be be linked to it */ rootptr = degrtab[degrval]; /* We will go on processing this root */ } degrtab[degrval] = NULL; /* Remaining root changes degree so leaves this cell */ fiboTreeUnlink (oldrptr); /* Old root is no longer a root */ oldrptr->deflval &= ~1; /* Whatever old root flag was, it is reset to 0 */ oldrptr->pareptr = rootptr; /* Remaining root is now father of old root */ chldptr = rootptr->chldptr; /* Get first child of remaining root */ if (chldptr != NULL) { /* If remaining root had already some children, link old root with them */ rootptr->deflval += 2; /* Increase degree by 1, that is, by 2 with left shift in deflval */ fiboTreeLinkAfter (chldptr, oldrptr); } else { /* Old root becomes first child of remaining root */ rootptr->deflval = 2; /* Real degree set to 1, and flag set to 0 */ rootptr->chldptr = oldrptr; oldrptr->linkdat.prevptr = /* Chain old root to oneself as only child */ oldrptr->linkdat.nextptr = oldrptr; } } /* Process again remaining root as its degree has changed */ } bestptr = NULL; for (degrval = 0; degrval <= degrmax; degrval ++) { if (degrtab[degrval] != NULL) { /* If some tree is found */ bestptr = degrtab[degrval]; /* Record it as potential best */ degrtab[degrval] = NULL; /* Clean-up used part of array */ degrval ++; /* Go on at next cell in next loop */ break; } } for ( ; degrval <= degrmax; degrval ++) { /* For remaining roots once a potential best root has been found */ if (degrtab[degrval] != NULL) { if (treeptr->cmpfptr (degrtab[degrval], bestptr) < 0) /* If new root is better */ bestptr = degrtab[degrval]; /* Record new root as best root */ degrtab[degrval] = NULL; /* Clean-up used part of array */ } } return (bestptr); } /* This routine returns the node of minimum ** key in the given tree. The node is searched ** for each time this routine is called, so this ** information should be recorded if needed. ** This is the non-macro version, for testing ** and setting up breakpoints. ** It returns: ** - !NULL : pointer to best element found. ** - NULL : Fibonacci tree is empty. */ #ifndef fiboTreeMinIsMacro FiboNode * fiboTreeMin ( FiboTree * const treeptr) { FiboNode * bestptr; bestptr = fiboTreeMinMacro (treeptr); #ifdef SCOTCH_DEBUG_FIBO3 fiboTreeCheck (treeptr); #endif /* SCOTCH_DEBUG_FIBO3 */ return (bestptr); } #endif /* fiboTreeMinIsMacro */ /* This routine adds the given node to the ** given tree. This is the non-macro version, ** for testing and setting up breakpoints. ** It returns: ** - void : in all cases. */ #ifndef fiboTreeAddIsMacro void fiboTreeAdd ( FiboTree * const treeptr, FiboNode * const nodeptr) { fiboTreeAddMacro (treeptr, nodeptr); #ifdef SCOTCH_DEBUG_FIBO3 fiboTreeCheck (treeptr); #endif /* SCOTCH_DEBUG_FIBO3 */ } #endif /* fiboTreeAddIsMacro */ /* This routine deletes the given node from ** the given tree, whatever ths node is (root ** or non root). This is the non-macro version, ** for testing and setting up breakpoints. ** It returns: ** - void : in all cases. */ #ifndef fiboTreeDelIsMacro void fiboTreeDel ( FiboTree * const treeptr, FiboNode * const nodeptr) { fiboTreeDelMacro (treeptr, nodeptr); #ifdef SCOTCH_DEBUG_FIBO3 nodeptr->pareptr = nodeptr->chldptr = nodeptr->linkdat.prevptr = nodeptr->linkdat.nextptr = NULL; fiboTreeCheck (treeptr); #endif /* SCOTCH_DEBUG_FIBO3 */ } #endif /* fiboTreeDelIsMacro */ /* This routine checks the consistency of the ** given linked list. ** It returns: ** - !NULL : pointer to the vertex. ** - NULL : if no such vertex available. */ #ifdef SCOTCH_DEBUG_FIBO3 static int fiboTreeCheck2 ( const FiboNode * const nodeptr) { FiboNode * chldptr; int degrval; degrval = 0; chldptr = nodeptr->chldptr; if (chldptr != NULL) { do { if (chldptr->linkdat.nextptr->linkdat.prevptr != chldptr) { errorPrint ("fiboTreeCheck: bad child linked list"); return (1); } if (chldptr->pareptr != nodeptr) { errorPrint ("fiboTreeCheck: bad child parent"); return (1); } if (fiboTreeCheck2 (chldptr) != 0) return (1); degrval ++; chldptr = chldptr->linkdat.nextptr; } while (chldptr != nodeptr->chldptr); } if (degrval != (nodeptr->deflval >> 1)) { /* Real node degree is obtained by discarding lowest bit */ errorPrint ("fiboTreeCheck2: invalid child information"); return (1); } return (0); } int fiboTreeCheck ( const FiboTree * const treeptr) { FiboNode * nodeptr; for (nodeptr = treeptr->rootdat.linkdat.nextptr; nodeptr != &treeptr->rootdat; nodeptr = nodeptr->linkdat.nextptr) { if (nodeptr->linkdat.nextptr->linkdat.prevptr != nodeptr) { errorPrint ("fiboTreeCheck: bad root linked list"); return (1); } if (nodeptr->pareptr != NULL) { errorPrint ("fiboTreeCheck: bad root parent"); return (1); } if (fiboTreeCheck2 (nodeptr) != 0) return (1); } return (0); } #endif /* SCOTCH_DEBUG_FIBO3 */ scotch-6.0.4.dfsg/src/libscotch/dgraph_halo.c0000644002563400244210000004411512473137664024270 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2009,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_halo.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Francois CHATENET (P0.0) **/ /** Sebastien FOUCAULT (P0.0) **/ /** Nicolas GICQUEL (P0.1) **/ /** Jerome LACOSTE (P0.1) **/ /** **/ /** FUNCTION : Part of a parallel static mapper. **/ /** This module contains the halo update **/ /** routines. **/ /** **/ /** # Version P0.0 : from : 01 apr 1997 **/ /** to 20 jun 1997 **/ /** # Version P0.1 : from : 14 apr 1998 **/ /** to 20 jun 1998 **/ /** # Version 5.0 : from : 28 feb 2006 **/ /** to 05 feb 2008 **/ /** # Version 5.1 : from : 28 aug 2008 **/ /** to 22 feb 2011 **/ /** # Version 6.0 : from : 29 oct 2014 **/ /** to 29 oct 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DGRAPH_HALO #include "module.h" #include "common.h" #include "dgraph.h" #include "dgraph_halo.h" /* These routines fill the send arrays used by ** all of the halo routines. ** They return: ** - void : in all cases. */ #define DGRAPHHALOFILLNAME dgraphHaloFillGeneric #define DGRAPHHALOFILLSIZE attrglbsiz #define DGRAPHHALOFILLCOPY(d,s,n) memCpy ((d), (s), (n)) #include "dgraph_halo_fill.c" #undef DGRAPHHALOFILLNAME #undef DGRAPHHALOFILLSIZE #undef DGRAPHHALOFILLCOPY #define DGRAPHHALOFILLNAME dgraphHaloFillGnum #define DGRAPHHALOFILLSIZE sizeof (Gnum) #define DGRAPHHALOFILLCOPY(d,s,n) *((Gnum *) (d)) = *((Gnum *) (s)) #include "dgraph_halo_fill.c" #undef DGRAPHHALOFILLNAME #undef DGRAPHHALOFILLSIZE #undef DGRAPHHALOFILLCOPY #define DGRAPHHALOFILLNAME dgraphHaloFillGraphPart #define DGRAPHHALOFILLSIZE sizeof (GraphPart) #define DGRAPHHALOFILLCOPY(d,s,n) *((GraphPart *) (d)) = *((GraphPart *) (s)) #include "dgraph_halo_fill.c" #undef DGRAPHHALOFILLNAME #undef DGRAPHHALOFILLSIZE #undef DGRAPHHALOFILLCOPY #define DGRAPHHALOFILLNAME dgraphHaloFillInt /* In case Gnum is not int */ #define DGRAPHHALOFILLSIZE sizeof (int) #define DGRAPHHALOFILLCOPY(d,s,n) *((int *) (d)) = *((int *) (s)) #include "dgraph_halo_fill.c" #undef DGRAPHHALOFILLNAME #undef DGRAPHHALOFILLSIZE #undef DGRAPHHALOFILLCOPY static void dgraphHaloFill ( const Dgraph * restrict const grafptr, const void * restrict const attrgsttab, /* Attribute array to diffuse */ int attrglbsiz, /* Type extent of attribute */ byte * restrict const attrsndtab, /* Array for packing data to send */ int * const senddsptab, /* Temporary displacement array */ const int * restrict const sendcnttab) /* Count array */ { int procnum; byte ** attrdsptab; attrdsptab = (byte **) senddsptab; /* TRICK: use senddsptab (int *) as attrdsptab (byte **) */ attrdsptab[0] = attrsndtab; /* Pre-set send arrays for send buffer filling routines */ for (procnum = 1; procnum < grafptr->procglbnbr; procnum ++) attrdsptab[procnum] = attrdsptab[procnum - 1] + sendcnttab[procnum - 1] * attrglbsiz; if (attrglbsiz == sizeof (Gnum)) dgraphHaloFillGnum (grafptr, attrgsttab, attrglbsiz, attrdsptab); else if (attrglbsiz == sizeof (GraphPart)) dgraphHaloFillGraphPart (grafptr, attrgsttab, attrglbsiz, attrdsptab); else if (attrglbsiz == sizeof (int)) /* In case Gnum is not int (suitable for float's too) */ dgraphHaloFillInt (grafptr, attrgsttab, attrglbsiz, attrdsptab); else /* Generic but slower fallback routine */ dgraphHaloFillGeneric (grafptr, attrgsttab, attrglbsiz, attrdsptab); senddsptab[0] = 0; /* Pre-set send arrays for data sending routines */ for (procnum = 1; procnum < grafptr->procglbnbr; procnum ++) senddsptab[procnum] = senddsptab[procnum - 1] + sendcnttab[procnum - 1]; } /* This function checks that the data of proc{snd,rcv}tab ** are consistent. */ #ifdef SCOTCH_DEBUG_DGRAPH2 int dgraphHaloCheck ( const Dgraph * restrict const grafptr) { int * proctab; /* Array to collect data */ int procnum; int o; if ((proctab = memAlloc (grafptr->procglbnbr * sizeof (int))) == NULL) { errorPrint ("dgraphHaloCheck: out of memory"); return (1); } if (MPI_Alltoall (grafptr->procsndtab, 1, MPI_INT, proctab, 1, MPI_INT, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphHaloCheck: communication error"); memFree (proctab); /* Free group leader */ return (1); } o = 0; for (procnum = 0; procnum < grafptr->procglbnbr; procnum ++) { if (proctab[procnum] != grafptr->procrcvtab[procnum]) { errorPrint ("dgraphHaloCheck: data error"); o = 1; break; } } memFree (proctab); /* Free group leader */ return (o); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ /* These functions perform a synchronous collective ** halo diffusion operation on the ghost array given ** on input. ** It returns: ** - 0 : if the halo has been successfully propagated. ** - !0 : on error. */ static int dgraphHaloSync2 ( Dgraph * restrict const grafptr, void * restrict const attrgsttab, /* Attribute array to share */ const MPI_Datatype attrglbtype, /* Attribute datatype */ byte ** const attrsndptr, /* Pointer to array for packing data to send */ int ** const senddspptr, /* Pointers to communication displacement arrays */ int ** const recvdspptr, MPI_Request ** const requptr) /* Pointer to local request array for point-to-point */ { #if ! ((defined COMMON_MPI_VERSION) && (COMMON_MPI_VERSION <= 100)) MPI_Aint attrglbtmp; /* Lower bound of attribute datatype (not used) */ #endif /* ((defined COMMON_MPI_VERSION) && (COMMON_MPI_VERSION <= 100)) */ MPI_Aint attrglbsiz; /* Extent of attribute datatype */ int procngbsiz; /* Size of request array for point-to-point communications */ int procngbnum; int * restrict recvdsptab; const int * restrict procrcvtab; if (dgraphGhst (grafptr) != 0) { /* Compute ghost edge array if not already present */ errorPrint ("dgraphHaloSync2: cannot compute ghost edge array"); return (1); } procngbsiz = ((grafptr->flagval & DGRAPHCOMMPTOP) != 0) ? grafptr->procngbnbr : 0; #if ((defined COMMON_MPI_VERSION) && (COMMON_MPI_VERSION <= 100)) MPI_Type_extent (attrglbtype, &attrglbsiz); /* Get type extent */ #else /* ((defined COMMON_MPI_VERSION) && (COMMON_MPI_VERSION <= 100)) */ MPI_Type_get_extent (attrglbtype, &attrglbtmp, &attrglbsiz); /* Get type extent */ #endif /* ((defined COMMON_MPI_VERSION) && (COMMON_MPI_VERSION <= 100)) */ if (memAllocGroup ((void **) (void *) attrsndptr, (size_t) (grafptr->procsndnbr * attrglbsiz), senddspptr, (size_t) (grafptr->procglbnbr * MAX (sizeof (int), sizeof (byte *))), /* TRICK: use senddsptab (int *) as attrdsptab (byte **) */ recvdspptr, (size_t) (grafptr->procglbnbr * sizeof (int)), requptr, (size_t) (procngbsiz * 2 * sizeof (MPI_Request)), NULL) == NULL) { errorPrint ("dgraphHaloSync2: out of memory"); return (1); } dgraphHaloFill (grafptr, attrgsttab, attrglbsiz, *attrsndptr, *senddspptr, grafptr->procsndtab); /* Fill data arrays */ recvdsptab = *recvdspptr; procrcvtab = grafptr->procrcvtab; recvdsptab[0] = grafptr->vertlocnbr; for (procngbnum = 1; procngbnum < grafptr->procglbnbr; procngbnum ++) recvdsptab[procngbnum] = recvdsptab[procngbnum - 1] + procrcvtab[procngbnum - 1]; #ifdef SCOTCH_DEBUG_DGRAPH2 if (dgraphHaloCheck (grafptr) != 0) { errorPrint ("dgraphHaloSync2: invalid communication data"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ return (0); } int dgraphHaloSync ( Dgraph * restrict const grafptr, void * restrict const attrgsttab, /* Attribute array to share */ const MPI_Datatype attrglbtype) /* Attribute datatype */ { byte * attrsndtab; /* Array for packing data to send */ int * senddsptab; int * recvdsptab; MPI_Request * requtab; int o; if (dgraphHaloSync2 (grafptr, attrgsttab, attrglbtype, &attrsndtab, &senddsptab, &recvdsptab, &requtab) != 0) /* Prepare communication arrays */ return (1); o = 0; /* Assume success */ if ((grafptr->flagval & DGRAPHCOMMPTOP) != 0) { /* If point-to-point exchange */ #if ! ((defined COMMON_MPI_VERSION) && (COMMON_MPI_VERSION <= 100)) MPI_Aint attrglbtmp; /* Lower bound of attribute datatype (not used) */ #endif /* ((defined COMMON_MPI_VERSION) && (COMMON_MPI_VERSION <= 100)) */ MPI_Aint attrglbsiz; /* Extent of attribute datatype */ const int * restrict procrcvtab; const int * restrict procsndtab; const int * restrict procngbtab; int procngbnbr; int procngbnum; MPI_Comm proccomm; int requnbr; proccomm = grafptr->proccomm; procngbtab = grafptr->procngbtab; procngbnbr = grafptr->procngbnbr; procrcvtab = grafptr->procrcvtab; #if ((defined COMMON_MPI_VERSION) && (COMMON_MPI_VERSION <= 100)) MPI_Type_extent (attrglbtype, &attrglbsiz); /* Get type extent */ #else /* ((defined COMMON_MPI_VERSION) && (COMMON_MPI_VERSION <= 100)) */ MPI_Type_get_extent (attrglbtype, &attrglbtmp, &attrglbsiz); /* Get type extent */ #endif /* ((defined COMMON_MPI_VERSION) && (COMMON_MPI_VERSION <= 100)) */ for (procngbnum = procngbnbr - 1, requnbr = 0; procngbnum >= 0; procngbnum --, requnbr ++) { /* Post receives first */ int procglbnum; procglbnum = procngbtab[procngbnum]; if (MPI_Irecv ((byte *) attrgsttab + recvdsptab[procglbnum] * attrglbsiz, procrcvtab[procglbnum], attrglbtype, procglbnum, TAGHALO, proccomm, requtab + requnbr) != MPI_SUCCESS) { errorPrint ("dgraphHaloSync: communication error (1)"); o = 1; break; } } procsndtab = grafptr->procsndtab; for (procngbnum = 0; procngbnum < procngbnbr; procngbnum ++, requnbr ++) { /* Post sends afterwards */ int procglbnum; procglbnum = procngbtab[procngbnum]; if (MPI_Isend (attrsndtab + senddsptab[procglbnum] * attrglbsiz, procsndtab[procglbnum], attrglbtype, procglbnum, TAGHALO, proccomm, requtab + requnbr) != MPI_SUCCESS) { errorPrint ("dgraphHaloSync: communication error (2)"); o = 1; break; } } if (MPI_Waitall (requnbr, requtab, MPI_STATUSES_IGNORE) != MPI_SUCCESS) { errorPrint ("dgraphHaloSync: communication error (3)"); o = 1; } } else { /* Collective communication */ if (MPI_Alltoallv (attrsndtab, grafptr->procsndtab, senddsptab, attrglbtype, /* Perform diffusion */ attrgsttab, grafptr->procrcvtab, recvdsptab, attrglbtype, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphHaloSync: communication error (4)"); o = 1; } } memFree (attrsndtab); /* Free group leader */ return (o); } /* This function performs an asynchronous collective ** halo diffusion operation on the ghost array given ** on input. It fills the given request structure with ** the relevant data. ** It returns: ** - 0 : if the halo has been successfully propagated. ** - !0 : on error. */ #ifdef SCOTCH_PTHREAD static void * dgraphHaloAsync2 ( DgraphHaloRequest * restrict requptr) { return ((void *) (intptr_t) dgraphHaloSync (requptr->grafptr, requptr->attrgsttab, requptr->attrglbtype)); } #endif /* SCOTCH_PTHREAD */ void dgraphHaloAsync ( Dgraph * restrict const grafptr, void * restrict const attrgsttab, /* Attribute array to share */ const MPI_Datatype attrglbtype, /* Attribute datatype */ DgraphHaloRequest * restrict requptr) { #ifndef SCOTCH_PTHREAD #ifdef SCOTCH_MPI_ASYNC_COLL int * senddsptab; int * recvdsptab; #endif /* SCOTCH_MPI_ASYNC_COLL */ #endif /* SCOTCH_PTHREAD */ #ifdef SCOTCH_PTHREAD requptr->flagval = -1; /* Assume thread will be successfully launched */ requptr->grafptr = grafptr; requptr->attrgsttab = attrgsttab; requptr->attrglbtype = attrglbtype; if (pthread_create (&requptr->thrdval, NULL, (void * (*) (void *)) dgraphHaloAsync2, (void *) requptr) != 0) /* If could not create thread */ requptr->flagval = (int) (intptr_t) dgraphHaloAsync2 (requptr); /* Call function synchronously */ #else /* SCOTCH_PTHREAD */ #ifdef SCOTCH_MPI_ASYNC_COLL requptr->flagval = 1; /* Assume error */ requptr->attrsndtab = NULL; /* No memory */ if (dgraphHaloSync2 (grafptr, attrgsttab, attrglbtype, &requptr->attrsndtab, &senddsptab, &recvdsptab) != 0) /* Prepare communication arrays */ return; if (MPE_Ialltoallv (requptr->attrsndtab, grafptr->procsndtab, senddsptab, attrglbtype, /* Perform asynchronous collective communication */ attrgsttab, grafptr->procrcvtab, recvdsptab, attrglbtype, grafptr->proccomm, &requptr->requval) != MPI_SUCCESS) { errorPrint ("dgraphHaloAsync: communication error"); /* Group leader will be freed on wait routine */ return; } requptr->flagval = -1; /* Communication successfully launched */ #else /* SCOTCH_MPI_ASYNC_COLL */ requptr->flagval = dgraphHaloSync (grafptr, attrgsttab, attrglbtype); /* Last resort is synchronous communication */ #endif /* SCOTCH_MPI_ASYNC_COLL */ #endif /* SCOTCH_PTHREAD */ } /* This function performs an asynchronous collective ** halo diffusion operation on the ghost array given ** on input. It fills the given request structure with ** the relevant data. ** It returns: ** - 0 : if the halo has been successfully propagated. ** - !0 : on error. */ int dgraphHaloWait ( DgraphHaloRequest * restrict requptr) { #ifdef SCOTCH_PTHREAD void * o; if (requptr->flagval == -1) { /* If thread launched */ pthread_join (requptr->thrdval, &o); /* Wait for its completion */ requptr->flagval = (int) (intptr_t) o; /* Get thread return value */ } /* Else return value already known */ #else /* SCOTCH_PTHREAD */ #ifdef SCOTCH_MPI_ASYNC_COLL MPI_Status statval; if (requptr->flagval == -1) { /* If communication launched */ MPI_Wait (&requptr->requval, &statval); /* Wait for completion of asynchronous collective communication */ requptr->flagval = (statval.MPI_ERROR == MPI_SUCCESS) ? 0 : 1; /* Set return value accordingly */ } if (requptr->attrsndtab != NULL) /* Free group leader if it was successfully allocated before */ memFree (requptr->attrsndtab); #endif /* SCOTCH_MPI_ASYNC_COLL */ #endif /* SCOTCH_PTHREAD */ return (requptr->flagval); /* Return asynchronous or synchronous error code */ } scotch-6.0.4.dfsg/src/libscotch/mesh_io_scot.c0000644002563400244210000002772611631447170024473 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mesh_io_scot.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the I/O routines **/ /** for handling the Scotch mesh format. **/ /** **/ /** DATES : # Version 4.0 : from : 19 jan 2004 **/ /** to 19 jan 2004 **/ /** # Version 5.0 : from : 13 sep 2006 **/ /** to 27 feb 2008 **/ /** # Version 5.1 : from : 11 aug 2010 **/ /** to 11 aug 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define MESH_IO_SCOT #include "module.h" #include "common.h" #include "geom.h" #include "graph.h" #include "mesh.h" /* This routine loads the geometrical mesh ** in the Scotch graph format, and allocates ** the proper structures. ** - 0 : on success. ** - !0 : on error. */ int meshGeomLoadScot ( Mesh * restrict const meshptr, /* Graph to load */ Geom * restrict const geomptr, /* Geometry to load */ FILE * const filesrcptr, /* Topological data */ FILE * const filegeoptr, /* No use */ const char * const dataptr) /* No use */ { #ifdef DEAD_CODE /* TODO */ double * restrict coorfiletab; /* Pointer to geometric data read from file */ MeshGeomScotSort * restrict coorsorttab; /* Pointer to geometric data sorting array */ int coorsortflag; /* Flag set if geometric data sorted by label */ Gnum coornbr; /* Number of geometric coordinates in file */ Gnum coornum; /* Number of current coordinate */ MeshGeomScotSort * restrict vertsorttab; /* Pointer to graph sorting array */ int vertsortflag; /* Flag set if graph data sorted by label */ Gnum vertnum; /* Current graph vertex */ Gnum dimnnbr; /* Dimension of geometry file */ int o; if (filesrcptr != NULL) { if (graphLoad (meshptr, filesrcptr, -1, 0) != 0) return (1); } if (filegeoptr == NULL) return (0); if ((intLoad (filegeoptr, &dimnnbr) != 1) || /* Read type and number of geometry items */ (intLoad (filegeoptr, &coornbr) != 1) || (dimnnbr < 1) || (dimnnbr > 3) || (dimnnbr < 1)) { errorPrint ("meshGeomLoadScot: bad input (1)"); return (1); } if ((filesrcptr != NULL) && (meshptr->vertnbr != coornbr)) { errorPrint ("meshGeomLoadScot: inconsistent number of vertices"); return (1); } if (meshptr->vertnbr == 0) return (0); if ((geomptr->geomtab == NULL) && /* Allocate geometry if necessary */ ((geomptr->geomtab = (double *) memAlloc (meshptr->vertnbr * dimnnbr * sizeof (double))) == NULL)) { errorPrint ("meshGeomLoadScot: out of memory (1)"); return (1); } if (memAllocGroup ((void **) &coorfiletab, (size_t) (coornbr * dimnnbr * sizeof (double)), &coorsorttab, (size_t) (coornbr * sizeof (MeshGeomScotSort)), &vertsorttab, (size_t) (meshptr->vertnbr * sizeof (MeshGeomScotSort)), NULL) == NULL) { errorPrint ("meshGeomLoadScot: out of memory (2)"); return (1); } o = 0; coorsortflag = 1; /* Assume geometry data sorted */ for (coornum = 0; (o == 0) && (coornum < coornbr); coornum ++) { Gnum vlblnum; o = 1 - intLoad (filegeoptr, &vlblnum); coorsorttab[coornum].labl = vlblnum; coorsorttab[coornum].num = coornum; if ((coornum > 0) && /* Check if geometry data sorted */ (coorsorttab[coornum].labl < coorsorttab[coornum - 1].labl)) coorsortflag = 0; /* Geometry data not sorted */ o |= 1 - fscanf (filegeoptr, "%lf", /* Read X coordinate */ &coorfiletab[coornum * dimnnbr]); if (dimnnbr > 1) { o |= 1 - fscanf (filegeoptr, "%lf", /* Read Y coordinate */ &coorfiletab[(coornum * dimnnbr) + 1]); if (dimnnbr > 2) o |= 1 - fscanf (filegeoptr, "%lf", /* Read Z coordinate */ &coorfiletab[(coornum * dimnnbr) + 2]); } } if (o != 0) { errorPrint ("meshGeomLoadScot: bad input (2)"); memFree (coorfiletab); /* Free group leader */ return (1); } if (coorsortflag != 1) /* If geometry data not sorted */ intSort2asc1 (coorsorttab, coornbr); /* Sort sort area by ascending labels */ for (coornum = 1; coornum < coornbr; coornum ++) { /* Check geometric data integrity */ if (coorsorttab[coornum].labl == coorsorttab[coornum - 1].labl) { errorPrint ("meshGeomLoadScot: duplicate vertex label"); memFree (coorfiletab); /* Free group leader */ return (1); } } if (meshptr->vlbltax != NULL) { /* If graph has vertex labels */ vertsortflag = 1; /* Assume graph data sorted */ for (vertnum = 0; vertnum < meshptr->vertnbr; vertnum ++) { vertsorttab[vertnum].labl = meshptr->vlbltax[vertnum + meshptr->baseval]; vertsorttab[vertnum].num = vertnum; if ((vertnum > 0) && /* Check if graph data sorted */ (vertsorttab[vertnum].labl < vertsorttab[vertnum - 1].labl)) vertsortflag = 0; /* Graph data not sorted */ } if (vertsortflag != 1) /* If graph data not sorted */ intSort2asc1 (vertsorttab, meshptr->vertnbr); /* Sort sort area by ascending labels */ } else { /* Graph does not have vertex labels */ for (vertnum = 0; vertnum < meshptr->vertnbr; vertnum ++) vertsorttab[vertnum].labl = vertsorttab[vertnum].num = vertnum; } for (coornum = vertnum = 0; vertnum < meshptr->vertnbr; vertnum ++) { /* For all vertices in graph */ while ((coornum < coornbr) && (coorsorttab[coornum].labl < vertsorttab[vertnum].labl)) coornum ++; /* Search geometry vertex with same label */ if ((coornum >= coornbr) || (coorsorttab[coornum].labl > vertsorttab[vertnum].labl)) { /* If label does not exist */ errorPrint ("meshGeomLoadScot: vertex geometry data not found (%d)", vertsorttab[vertnum].labl); memFree (coorfiletab); /* Free group leader */ return (1); } memCpy (&geomptr->geomtab[vertsorttab[vertnum].num * dimnnbr], &coorfiletab[coorsorttab[coornum ++].num * dimnnbr], dimnnbr * sizeof (double)); } memFree (coorfiletab); /* Free group leader */ #endif /* DEAD_CODE */ return (0); } /* This routine saves the source mesh ** in the Scotch mesh and geometry formats. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int meshGeomSaveScot ( const Mesh * restrict const meshptr, /* Mesh to save */ const Geom * restrict const geomptr, /* Geometry to save */ FILE * const filesrcptr, /* Topological data */ FILE * const filegeoptr, /* No use */ const char * const dataptr) /* No use */ { Gnum vnodnum; int dimnnbr; int o; if (filesrcptr != NULL) { if (meshSave (meshptr, filesrcptr) != 0) /* Save mesh structural data */ return (1); } dimnnbr = geomptr->dimnnbr; o = 0; if (geomptr->geomtab != NULL) { /* If geometrical data present */ o = (fprintf (filegeoptr, GNUMSTRING "\n" GNUMSTRING "\n", /* Output file header */ (Gnum) geomptr->dimnnbr, (Gnum) meshptr->vnodnbr) == EOF); switch (dimnnbr) { /* Output geometry data */ case 1 : for (vnodnum = meshptr->vnodbas; (o == 0) && (vnodnum < meshptr->vnodnnd); vnodnum ++) o |= (fprintf (filegeoptr, GNUMSTRING "\t%lf\n", (Gnum) ((meshptr->vlbltax != NULL) ? meshptr->vlbltax[vnodnum] : vnodnum), (double) geomptr->geomtab[(vnodnum - meshptr->vnodbas) * dimnnbr]) == EOF); break; case 2 : for (vnodnum = meshptr->vnodbas; (o == 0) && (vnodnum < meshptr->vnodnnd); vnodnum ++) o |= (fprintf (filegeoptr, GNUMSTRING "\t%lf\t%lf\n", (Gnum) ((meshptr->vlbltax != NULL) ? meshptr->vlbltax[vnodnum] : vnodnum), (double) geomptr->geomtab[(vnodnum - meshptr->vnodbas) * dimnnbr], (double) geomptr->geomtab[(vnodnum - meshptr->vnodbas) * dimnnbr + 1]) == EOF); break; case 3 : for (vnodnum = meshptr->vnodbas; (o == 0) && (vnodnum < meshptr->vnodnnd); vnodnum ++) o |= (fprintf (filegeoptr, GNUMSTRING "\t%lf\t%lf\t%lf\n", (Gnum) ((meshptr->vlbltax != NULL) ? meshptr->vlbltax[vnodnum] : vnodnum), (double) geomptr->geomtab[(vnodnum - meshptr->vnodbas) * dimnnbr], (double) geomptr->geomtab[(vnodnum - meshptr->vnodbas) * dimnnbr + 1], (double) geomptr->geomtab[(vnodnum - meshptr->vnodbas) * dimnnbr + 2]) == EOF); break; #ifdef SCOTCH_DEBUG_MESH2 default : errorPrint ("meshGeomSaveScot: invalid geometry type"); return (1); #endif /* SCOTCH_DEBUG_MESH2 */ } if (o != 0) { errorPrint ("meshGeomSaveScot: bad output"); } } return (o); } scotch-6.0.4.dfsg/src/libscotch/hgraph_order_hf.c0000644002563400244210000001606211631447170025130 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hgraph_order_hf.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module orders a subgraph using **/ /** the block-oriented Halo Approximate **/ /** (Multiple) Minimum Fill algorithm, **/ /** with super-variable accounting **/ /** R2HAMDf4 v2.0). **/ /** **/ /** DATES : # Version 3.4 : from : 15 may 2001 **/ /** to : 23 nov 2001 **/ /** # Version 4.0 : from : 10 jan 2003 **/ /** to : 24 jan 2004 **/ /** # Version 5.0 : from : 10 sep 2007 **/ /** to : 10 sep 2007 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HGRAPH_ORDER_HF #include "module.h" #include "common.h" #include "graph.h" #include "order.h" #include "hgraph.h" #include "hall_order_hf.h" #include "hall_order_hx.h" #include "hgraph_order_hf.h" #include "hgraph_order_hx.h" #include "hgraph_order_si.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the ordering. ** It returns: ** - 0 : if the ordering could be computed. ** - !0 : on error. */ int hgraphOrderHf ( const Hgraph * restrict const grafptr, Order * restrict const ordeptr, const Gnum ordenum, /*+ Zero-based ordering number +*/ OrderCblk * restrict const cblkptr, /*+ Multiple column-block +*/ const HgraphOrderHfParam * restrict const paraptr) { Gnum nbbuck; Gnum * restrict petab; Gnum pfree; Gnum iwlen; Gnum * restrict iwtab; Gnum * restrict lentab; Gnum * restrict nvartab; Gnum * restrict elentab; Gnum * restrict lasttab; Gnum * restrict leaftab; Gnum * restrict secntab; /* Array of index to first secondary variable */ Gnum * restrict nexttab; /* Array of index of next principal variable */ Gnum * restrict frsttab; Gnum * restrict headtab; /* Head array : nbbuck = 2 * n */ Gnum ncmpa; Gnum n; /* Number of nodes to order (with halo or not) */ int o; if (grafptr->s.vertnbr < paraptr->colmin) /* If graph is too small, order simply */ return (hgraphOrderSi (grafptr, ordeptr, ordenum, cblkptr)); n = grafptr->s.vertnbr; nbbuck = n * 2; iwlen = (Gnum) ((double) grafptr->s.edgenbr * HGRAPHORDERHFCOMPRAT) + 32; if (iwlen < n) /* Prepare to re-use array */ iwlen = n; if (memAllocGroup ((void **) (void *) &petab, (size_t) (n * sizeof (Gnum)), &iwtab, (size_t) (iwlen * sizeof (Gnum)), &lentab, (size_t) (n * sizeof (Gnum)), &nvartab, (size_t) (n * sizeof (Gnum)), &elentab, (size_t) (n * sizeof (Gnum)), &lasttab, (size_t) (n * sizeof (Gnum)), &leaftab, (size_t) (n * sizeof (Gnum)), &frsttab, (size_t) (n * sizeof (Gnum)), &secntab, (size_t) (n * sizeof (Gnum)), &nexttab, (size_t) (n * sizeof (Gnum)), &headtab, (size_t) ((nbbuck + 2) * sizeof (Gnum)), NULL) == NULL) { errorPrint ("hgraphOrderHf: out of memory"); return (1); } hgraphOrderHxFill (grafptr, petab, lentab, iwtab, elentab, &pfree); hallOrderHfR2hamdf4 (n, 0, nbbuck, iwlen, petab, pfree, /* No elements here */ lentab, iwtab, nvartab, elentab, lasttab, &ncmpa, leaftab, secntab, nexttab, frsttab, headtab); if (ncmpa < 0) { errorPrint ("hgraphOrderHf: internal error"); memFree (petab); /* Free group leader */ return (1); } o = hallOrderHxBuild (grafptr->s.baseval, n, grafptr->vnohnbr, grafptr->s.vnumtax, ordeptr, cblkptr, nvartab - grafptr->s.baseval, lentab - grafptr->s.baseval, petab - grafptr->s.baseval, frsttab - grafptr->s.baseval, nexttab - grafptr->s.baseval, secntab - grafptr->s.baseval, iwtab - grafptr->s.baseval, elentab - grafptr->s.baseval, ordeptr->peritab + ordenum, /* Use given inverse permutation as inverse permutation space, never based */ leaftab, paraptr->colmin, paraptr->colmax, (float) paraptr->fillrat); memFree (petab); /* Free group leader */ return (o); } scotch-6.0.4.dfsg/src/libscotch/wgraph_part_gp.c0000644002563400244210000003317412473175616025026 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2010,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : wgraph_part_gp.c **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Charles-Edmond BICHOT (v5.1b) **/ /** **/ /** FUNCTION : This module is the vertex overlapped **/ /** graph partitioning rountine based on **/ /** a vertex-oriented version of the Gibbs- **/ /** Poole-Stockmeyer algorithm. **/ /** **/ /** DATES : # Version 5.1 : from : 01 dec 2007 **/ /** to : 01 jul 2008 **/ /** # Version 6.0 : from : 05 nov 2009 **/ /** to : 29 oct 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define WGRAPH_PART_GP #include "module.h" #include "common.h" #include "graph.h" #include "wgraph.h" #include "wgraph_part_gp.h" /* ** The static variables. */ static const Gnum wgraphpartgploadone = 1; /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the bipartitioning. ** It returns: ** - 0 : if the bipartitioning could be computed. ** - !0 : on error. */ int wgraphPartGp ( Wgraph * restrict const wgrafptr, /*+ Separation graph +*/ const WgraphPartGpParam * const paraptr) /*+ Method parameters +*/ { Gnum i; Gnum head; Gnum tail; Gnum fronnum; Gnum fronnbr; /* number of frontier vertices */ Gnum fronload; /* load of frontier vertices */ Gnum frlobst; /* best frontier load found */ Gnum partval; Gnum vertnum; Gnum vertnum2; Gnum edgenum; Gnum palooth; /* load of vertices in the remained unassigned part */ Gnum paloexc; /* load of vertices in the current part excepting the frontier */ Gnum frloprt; /* load of vertices in the frontier of the current part */ Gnum passnum; Gnum velomsk; const Gnum * restrict velobax; /* Data for handling of optional arrays */ Gnum * restrict compload; /* array of part load */ Gnum * restrict compsize; /* array of part vertices number */ Gnum * restrict permtab; /* permutation table */ Gnum * restrict stack; /* Pointer to stack */ Gnum * restrict parttax; WgraphPartGpVertex * vexxtax; /* Complementary vertex array */ WgraphPartGpVertex * restrict vertlist; /* list of vertices */ if (memAllocGroup((void **) (void *) &vexxtax, (size_t) (wgrafptr->s.vertnbr * sizeof (WgraphPartGpVertex)), &compload, (size_t) (wgrafptr->partnbr * sizeof (Gnum)), &compsize, (size_t) (wgrafptr->partnbr * sizeof (Gnum)), &stack , (size_t) (wgrafptr->s.vertnbr * sizeof (Gnum)), &parttax, (size_t) (wgrafptr->s.vertnbr * sizeof (Gnum)), &permtab, (size_t) (wgrafptr->s.vertnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("wgraphPartGp: out of memory (1)"); return (1); } vexxtax -= wgrafptr->s.baseval; /* Base access to vexxtax */ parttax -= wgrafptr->s.baseval; /* Base access to parttax */ for (vertnum = 0; vertnum < wgrafptr->s.vertnbr; vertnum ++) { /* Initialization of the permutation table */ i = intRandVal (vertnum + 1); permtab[vertnum] = permtab[i]; permtab[i] = vertnum; } if (wgrafptr->s.velotax == NULL) { /* Set accesses to optional arrays */ velobax = &wgraphpartgploadone; /* In case vertices not weighted (least often) */ velomsk = 0; } else { velobax = wgrafptr->s.velotax; velomsk = ~((Gnum) 0); } frlobst = wgrafptr->s.velosum + 1; /* The first solution that will be found will be better than frlobst */ for (passnum = 0; passnum < paraptr->passnbr; passnum ++) { fronnbr = /* Begin with empty separators */ fronload = 0; vertnum = -1; palooth = wgrafptr->s.velosum; memSet (compload, 0, wgrafptr->partnbr * sizeof (Gnum)); memSet (compsize, 0, wgrafptr->partnbr * sizeof (Gnum)); memSet (parttax + wgrafptr->s.baseval, 0, wgrafptr->s.vertnbr * sizeof (Gnum)); memSet (vexxtax + wgrafptr->s.baseval, 0, wgrafptr->s.vertnbr * sizeof (WgraphPartGpVertex)); head = tail = 0; for (partval = 0; partval < wgrafptr->partnbr; partval ++) { frloprt = paloexc = 0; if (tail > head) /* try to take a vertex from the frontier of the last part */ vertnum = stack[tail % wgrafptr->s.vertnbr]; else vertnum = -1; head = tail = 0; if (vertnum != -1) { /* if the stack was not empty */ for (edgenum = wgrafptr->s.verttax[vertnum]; /* search a neighbor vertex that is in the part 0 */ edgenum < wgrafptr->s.vendtax[vertnum]; edgenum ++) { vertnum2 = wgrafptr->s.edgetax[edgenum]; if (parttax[vertnum2] == 0) { fronnbr ++; compsize[partval] ++; parttax[vertnum2] = -1; /* move it in the seperator */ fronload += velobax[vertnum2 & velomsk]; /* update load and size of parts */ compload[partval] += velobax[vertnum2 & velomsk]; vexxtax[vertnum2].isinstack = 0; stack[(head ++) % (wgrafptr->s.vertnbr)] = vertnum2; break; } } } do { /* while the part is not big enought */ if (head > tail) /* select a vertex */ vertnum = stack[tail % wgrafptr->s.vertnbr]; else vertnum = -1; if (vertnum != -1) { tail ++; } else /* if the stack was empty */ { if ((2 * (paloexc + frloprt / 2)) * (wgrafptr->partnbr - partval + 1) <= palooth) { /* if the part load is not big enought */ for (i = 0; i < wgrafptr->s.vertnbr; i ++) { /* select a random vertex in the part 0 */ Gnum pos = i + intRandVal (wgrafptr->s.vertnbr - i); vertnum = permtab[pos]; permtab[pos] = permtab[i]; permtab[i] = vertnum; vertnum += wgrafptr->s.baseval; if (parttax[vertnum] == 0) { for (edgenum = wgrafptr->s.verttax[vertnum]; edgenum < wgrafptr->s.vendtax[vertnum]; edgenum ++) { vertnum2 = wgrafptr->s.edgetax[edgenum]; if (parttax[vertnum2] > 0) { break; } } break; } } fronnbr ++; parttax[vertnum] = -1; frloprt += velobax[vertnum & velomsk]; fronload += velobax[vertnum & velomsk]; compload[partval] += velobax[vertnum & velomsk]; compsize[partval] ++; } else break; } fronnbr --; vertlist = NULL; parttax[vertnum] = partval; /* Move selected vertex in the current part */ paloexc += velobax[vertnum & velomsk]; frloprt -= velobax[vertnum & velomsk]; fronload -= velobax[vertnum & velomsk]; for (edgenum = wgrafptr->s.verttax[vertnum]; edgenum < wgrafptr->s.vendtax[vertnum]; edgenum ++) { vertnum2 = wgrafptr->s.edgetax[edgenum]; /* for each neighbor vertex */ if (parttax[vertnum2] != -1 && parttax[vertnum2] != partval) { parttax[vertnum2] = -1; /* Move the part in the separator */ fronnbr ++; fronload += velobax[vertnum2 & velomsk]; frloprt += velobax[vertnum2 & velomsk]; compload[partval] += velobax[vertnum2 & velomsk]; compsize[partval] ++; vexxtax[vertnum2].partlvl = partval; /* Label the vertex for this part */ vexxtax[vertnum2].prev = vertlist; /* Add the vertex in the list */ vertlist = vexxtax + vertnum2; } else if (parttax[vertnum2] == -1) { /* If the vertex is in the separator */ if (vexxtax[vertnum2].partlvl == partval) { if (vexxtax[vertnum2].isinstack != 1) { /* If the vertex is in the stack */ } } else { /* If the vertex is not labeled for the current part */ frloprt += velobax[vertnum2 & velomsk]; compload[partval] += velobax[vertnum2 & velomsk]; compsize[partval] ++; vexxtax[vertnum2].partlvl = partval; /* Label it for the part */ vexxtax[vertnum2].isinstack = 1; } } } while (vertlist != NULL) { /* For eack linked vertices */ vertnum2 = vertlist - vexxtax; stack[head ++ % wgrafptr->s.vertnbr] = vertnum2; vexxtax[vertnum2].isinstack = 0; vertlist = vertlist->prev; } } while ((paloexc + frloprt / 2) * (wgrafptr->partnbr - partval + 1) <= palooth); /* While the part is not big enought */ palooth -= (paloexc + frloprt / 2); } compload[0] = compsize[0] = 0; for (vertnum = wgrafptr->s.baseval; vertnum < wgrafptr->s.vertnnd; vertnum ++) { /* Recompute load and size of part 0 */ if (parttax[vertnum] == 0) { compload[0] += velobax[vertnum & velomsk]; compsize[0] ++; } else if (parttax[vertnum] == -1) { for (edgenum = wgrafptr->s.verttax[vertnum]; edgenum < wgrafptr->s.vendtax[vertnum]; edgenum ++) { vertnum2 = wgrafptr->s.edgetax[edgenum]; if (parttax[vertnum2] == 0) { compload[0] += velobax[vertnum & velomsk]; compsize[0] ++; break; } } } } if (frlobst > fronload) { /* If the pass frontier load is better than the better one */ wgrafptr->fronnbr = fronnbr; wgrafptr->fronload = fronload; memCpy (wgrafptr->compload, compload, sizeof (Gnum) * wgrafptr->partnbr); memCpy (wgrafptr->compsize, compsize, sizeof (Gnum) * wgrafptr->partnbr); memCpy (wgrafptr->parttax + wgrafptr->s.baseval, parttax + wgrafptr->s.baseval, sizeof (Gnum) * wgrafptr->s.vertnbr); for (vertnum = wgrafptr->s.baseval, fronnum = 0; vertnum < wgrafptr->s.vertnnd; vertnum ++) { /* Recompute frontab */ if (parttax[vertnum] == -1) wgrafptr->frontab[fronnum ++] = vertnum; } frlobst = fronload; } } for (partval = 0; partval < wgrafptr->partnbr; partval ++) /* for each part */ printf("\033[0;33mcompload[" GNUMSTRING "] " GNUMSTRING " " GNUMSTRING "\033[0m\n", partval, wgrafptr->compload[partval], wgrafptr->compsize[partval]); printf("\033[0;33mfronload " GNUMSTRING " " GNUMSTRING "\033[0m\n", wgrafptr->fronload, wgrafptr->fronnbr); memFree(vexxtax + wgrafptr->s.baseval); /* Free work arrays */ return (0); } scotch-6.0.4.dfsg/src/libscotch/dgraph_induce.c0000644002563400244210000005006512024357614024604 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_induce.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Jun-Ho HER (v6.0) **/ /** **/ /** FUNCTION : This module handles the source graph **/ /** subgraph-making functions. **/ /** **/ /** DATES : # Version 5.0 : from : 08 apr 2006 **/ /** to : 10 sep 2007 **/ /** # Version 5.1 : from : 31 mar 2008 **/ /** to : 30 jul 2010 **/ /** # Version 6.0 : from : 29 aug 2012 **/ /** to : 13 sep 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DGRAPH #define DGRAPH_INDUCE #include "module.h" #include "common.h" #include "dgraph.h" /****************************************/ /* */ /* These routines handle source graphs. */ /* */ /****************************************/ int dgraphInduce2 ( Dgraph * restrict const orggrafptr, Gnum (* orgfuncptr) (Dgraph * restrict const, Dgraph * restrict const, const void * restrict const, Gnum * restrict const), const void * const orgdataptr, /* Pointer to routine-specific data */ const Gnum indvertlocnbr, /* Number of vertices in induced subgraph */ Gnum * indvnumloctmp, /* Pointer to temporary index array; TRICK: [alias] */ Dgraph * restrict const indgrafptr) { Gnum * restrict orgindxgsttax; /* Based access to vertex translation array */ Gnum indvertlocnnd; /* Based index of end of local vertex array */ Gnum indvertlocnum; /* Number of current vertex in induced graph */ Gnum indvertglbnum; /* Number of current vertex in global ordering */ Gnum indvelolocnbr; /* Size of local vertex load array */ Gnum indvelolocsum; /* Sum of vertex loads */ Gnum * indvnumloctax; /* TRICK: maybe alias of indvnumloctmp */ Gnum indvlbllocnbr; /* Size of local vertex label array */ Gnum indedgelocmax; /* (Approximate) number of edges in induced graph */ Gnum indedgelocnbr; /* Real number of edges in induced graph */ Gnum indedgelocnum; Gnum * restrict indedloloctax; Gnum inddegrlocmax; /* Local maximum degree */ const Gnum * restrict indlisttax; Gnum baseval; int cheklocval; int chekglbval; const Gnum * restrict const orgvertloctax = orggrafptr->vertloctax; const Gnum * restrict const orgvendloctax = orggrafptr->vendloctax; const Gnum * restrict const orgvnumloctax = orggrafptr->vnumloctax; const Gnum * restrict const orgvlblloctax = orggrafptr->vlblloctax; const Gnum * restrict const orgveloloctax = orggrafptr->veloloctax; const Gnum * restrict const orgedloloctax = orggrafptr->edloloctax; if (dgraphGhst (orggrafptr) != 0) { /* Compute ghost edge array if not already present */ errorPrint ("dgraphInduce2: cannot compute ghost edge array"); return (1); } baseval = orggrafptr->baseval; indgrafptr->flagval |= (DGRAPHFREEALL ^ DGRAPHFREECOMM) | DGRAPHVERTGROUP | DGRAPHEDGEGROUP; indgrafptr->baseval = baseval; indgrafptr->vertlocnbr = indvertlocnbr; /* Must be set before orgfuncptr() is called */ indgrafptr->vertlocnnd = indvertlocnbr + baseval; if (orgveloloctax != NULL) { indvelolocnbr = indvertlocnbr; indvelolocsum = 0; } else { indvelolocnbr = 0; indvelolocsum = indvertlocnbr; } indvlbllocnbr = (orgvlblloctax != NULL) ? indvertlocnbr : 0; indedgelocmax = orggrafptr->edgelocnbr; /* Choose best upper bound on number of edges (avoid multiply overflow) */ if ((orggrafptr->degrglbmax > 0) && (indvertlocnbr < (indedgelocmax / orggrafptr->degrglbmax))) indedgelocmax = indvertlocnbr * orggrafptr->degrglbmax; if (orggrafptr->edloloctax != NULL) /* If graph has edge weights */ indedgelocmax *= 2; /* Account for edge weights */ cheklocval = chekglbval = 0; if (memAllocGroup ((void **) (void *) /* Allocate distributed graph private data */ &indgrafptr->procdsptab, (size_t) ((orggrafptr->procglbnbr + 1) * sizeof (Gnum)), &indgrafptr->proccnttab, (size_t) (orggrafptr->procglbnbr * sizeof (Gnum)), &indgrafptr->procngbtab, (size_t) (orggrafptr->procglbnbr * sizeof (int)), &indgrafptr->procrcvtab, (size_t) (orggrafptr->procglbnbr * sizeof (int)), &indgrafptr->procsndtab, (size_t) (orggrafptr->procglbnbr * sizeof (int)), NULL) == NULL) { errorPrint ("dgraphInduce2: out of memory (1)"); cheklocval = 1; } else if (memAllocGroup ((void **) (void *) /* Allocate distributed graph public data */ &indgrafptr->vertloctax, (size_t) ((indvertlocnbr + 1) * sizeof (Gnum)), /* Compact vertex array */ &indgrafptr->vnumloctax, (size_t) (indvertlocnbr * sizeof (Gnum)), &indgrafptr->veloloctax, (size_t) (indvelolocnbr * sizeof (Gnum)), &indgrafptr->vlblloctax, (size_t) (indvlbllocnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("dgraphInduce2: out of memory (2)"); cheklocval = 1; } else if (indgrafptr->vertloctax -= baseval, indgrafptr->vnumloctax -= baseval, indgrafptr->veloloctax = (orgveloloctax != NULL) ? indgrafptr->veloloctax - baseval : NULL, indgrafptr->vlblloctax = indgrafptr->vlblloctax - baseval, /* If no vertex labels, vlblloctax will point to vnumloctax afterward */ memAllocGroup ((void **) (void *) &indgrafptr->edgeloctax, (size_t) (indedgelocmax * sizeof (Gnum)), /* Pre-allocate space for edgetab (and edlotab) */ &orgindxgsttax, (size_t) (orggrafptr->vertgstnbr * sizeof (Gnum)), NULL) == NULL) { /* orgindxgsttab is at the end */ errorPrint ("dgraphInduce2: out of memory (3)"); cheklocval = 1; } else indgrafptr->edgeloctax -= baseval; if (cheklocval != 0) { /* In case of memory error */ Gnum procngbnum; Gnum dummyval; dummyval = -1; chekglbval = 1; if (MPI_Allgather (&dummyval, 1, GNUM_MPI, /* Use proccnttab of orggraf as dummy receive array (will be regenerated) */ orggrafptr->proccnttab, 1, GNUM_MPI, indgrafptr->proccomm) != MPI_SUCCESS) errorPrint ("dgraphInduce2: communication error (1)"); for (procngbnum = 1; procngbnum <= orggrafptr->procglbnbr; procngbnum ++) /* Rebuild proccnttab of orggraf */ orggrafptr->proccnttab[procngbnum - 1] = orggrafptr->procdsptab[procngbnum] - orggrafptr->procdsptab[procngbnum - 1]; } else { indgrafptr->procdsptab[0] = indvertlocnbr; if (MPI_Allgather (&indgrafptr->procdsptab[0], 1, GNUM_MPI, &indgrafptr->proccnttab[0], 1, GNUM_MPI, indgrafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphInduce2: communication error (2)"); chekglbval = 1; } else { Gnum procngbnum; indgrafptr->procdsptab[0] = baseval; /* Build vertex-to-process array */ for (procngbnum = 0; procngbnum < indgrafptr->procglbnbr; procngbnum ++) { /* Process potential error flags from other processes */ if (indgrafptr->procdsptab[procngbnum] < 0) { /* If error notified by another process */ chekglbval = 1; break; } indgrafptr->procdsptab[procngbnum + 1] = indgrafptr->procdsptab[procngbnum] + indgrafptr->proccnttab[procngbnum]; } } indgrafptr->procvrttab = indgrafptr->procdsptab; /* Graph does not have holes */ } if (chekglbval != 0) { /* If something went wrong in all of the above */ dgraphFree (indgrafptr); return (1); } memSet (orgindxgsttax, ~0, orggrafptr->vertlocnbr * sizeof (Gnum)); /* Preset index array */ orgindxgsttax -= baseval; indedgelocmax = orgfuncptr (indgrafptr, orggrafptr, orgdataptr, orgindxgsttax); /* Call flagging subroutine */ if (dgraphHaloSync (orggrafptr, (byte *) (orgindxgsttax + baseval), GNUM_MPI) != 0) { /* Share global indexing of subgraph vertices */ errorPrint ("dgraphInduce2: cannot perform halo exchange"); dgraphFree (indgrafptr); return (1); } if (indvnumloctmp == NULL) /* indgrafptr->vnumloctax did not exist when function was called */ indvnumloctmp = indgrafptr->vnumloctax; indedloloctax = (orggrafptr->edloloctax != NULL) ? indgrafptr->edgeloctax + indedgelocmax : NULL; inddegrlocmax = 0; for (indvertlocnum = indedgelocnum = baseval, indvertlocnnd = indvertlocnbr + baseval; indvertlocnum < indvertlocnnd; indvertlocnum ++) { Gnum orgvertlocnum; Gnum orgedgelocnum; orgvertlocnum = indvnumloctmp[indvertlocnum]; indgrafptr->vertloctax[indvertlocnum] = indedgelocnum; if (orgveloloctax != NULL) { /* If graph has vertex weights */ indvelolocsum += /* Accumulate vertex loads */ indgrafptr->veloloctax[indvertlocnum] = orgveloloctax[orgvertlocnum]; } if (orgvlblloctax != NULL) /* If graph has vertex labels */ indgrafptr->vlblloctax[indvertlocnum] = orgvlblloctax[orgvertlocnum]; for (orgedgelocnum = orgvertloctax[orgvertlocnum]; orgedgelocnum < orgvendloctax[orgvertlocnum]; orgedgelocnum ++) { Gnum indvertgstend; indvertgstend = orgindxgsttax[orggrafptr->edgegsttax[orgedgelocnum]]; if (indvertgstend != ~0) { /* If edge should be kept */ indgrafptr->edgeloctax[indedgelocnum] = indvertgstend; if (indedloloctax != NULL) indedloloctax[indedgelocnum] = orgedloloctax[orgedgelocnum]; indedgelocnum ++; } } if (inddegrlocmax < (indedgelocnum - indgrafptr->vertloctax[indvertlocnum])) inddegrlocmax = (indedgelocnum - indgrafptr->vertloctax[indvertlocnum]); } indedgelocnbr = indedgelocnum - baseval; indgrafptr->vertloctax[indvertlocnum] = indedgelocnum; /* Mark end of edge array */ indgrafptr->vendloctax = indgrafptr->vertloctax + 1; /* Induced graph is compact */ indgrafptr->velolocsum = indvelolocsum; indgrafptr->edgelocnbr = indedgelocnbr; indgrafptr->edgelocsiz = indedgelocnbr; if (orgvlblloctax == NULL) /* If we didn't have vertex labels, use vertex index array as vertex label array */ indgrafptr->vlblloctax = indgrafptr->vnumloctax; if (indedloloctax != NULL) { /* Re-allocate arrays and delete orgindxtab */ size_t indedlooftval; /* Offset of edge load array with respect to edge array */ indedlooftval = indedloloctax - indgrafptr->edgeloctax; indgrafptr->edgeloctax = memRealloc (indgrafptr->edgeloctax + baseval, (indedlooftval + indedgelocnbr) * sizeof (Gnum)); indgrafptr->edgeloctax -= baseval; indedloloctax = indgrafptr->edgeloctax + indedlooftval; /* Use old index into old array as new index to avoid alignment problems */ } else { indgrafptr->edgeloctax = memRealloc (indgrafptr->edgeloctax + baseval, indedgelocnbr * sizeof (Gnum)); indgrafptr->edgeloctax -= baseval; } indvertlocnum = baseval; indvnumloctax = indgrafptr->vnumloctax; /* TRICK: maybe alias */ if (orgvnumloctax != NULL) { /* Adjust vnumloctax */ for ( ; indvertlocnum < indvertlocnnd; indvertlocnum ++) indvnumloctax[indvertlocnum] = orgvnumloctax[indvnumloctmp[indvertlocnum]]; /* TRICK: indvnumloctmp and indgrafptr->vnumloctax may be aliases */ } else { Gnum orgvertglbadj; orgvertglbadj = orggrafptr->procvrttab[orggrafptr->proclocnum] - baseval; /* Set adjustement for global indexing */ for ( ; indvertlocnum < indvertlocnnd; indvertlocnum ++) indvnumloctax[indvertlocnum] = indvnumloctmp[indvertlocnum] + orgvertglbadj; /* TRICK: indvnumloctmp and indgrafptr->vnumloctax may be aliases */ } indgrafptr->edloloctax = indedloloctax; indgrafptr->degrglbmax = inddegrlocmax; /* Local maximum degree will be turned into global maximum degree */ if (dgraphBuild4 (indgrafptr) != 0) { errorPrint ("dgraphInduce2: cannot build induced graph"); return (1); } #ifdef SCOTCH_DEBUG_DGRAPH2 if (dgraphCheck (indgrafptr) != 0) { /* Check graph consistency */ errorPrint ("dgraphInduce2: inconsistent graph data"); dgraphFree (indgrafptr); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ return (0); } /* This routine builds the graph induced ** by the original graph and the list of ** selected vertices. ** The induced vnumtab array is the global ** translation of the list array if the ** original graph does not have a vnumtab, ** or the proper subset of the original ** vnumtab else. ** It returns: ** - 0 : on success. ** - !0 : on error. */ static Gnum dgraphInduceList2 ( Dgraph * restrict const indgrafptr, Dgraph * restrict const orggrafptr, const void * restrict const orgdataptr, /* Data pointer is list array pointer */ Gnum * restrict const orgindxgsttax) { Gnum orglistnbr; Gnum orglistnum; Gnum indvertglbnum; Gnum indedgelocmax; const Gnum * restrict const orgvertloctax = orggrafptr->vertloctax; const Gnum * restrict const orgvendloctax = orggrafptr->vendloctax; const Gnum * restrict const orglisttab = (const Gnum * restrict) orgdataptr; for (orglistnum = 0, indvertglbnum = indgrafptr->procvrttab[indgrafptr->proclocnum], /* Fill index array while recomputing tighter upper bound on arcs */ orglistnbr = indgrafptr->vertlocnbr, indedgelocmax = 0; orglistnum < orglistnbr; orglistnum ++, indvertglbnum ++) { Gnum orgvertlocnum; orgvertlocnum = orglisttab[orglistnum]; orgindxgsttax[orgvertlocnum] = indvertglbnum; /* Mark selected vertices */ indedgelocmax += orgvendloctax[orgvertlocnum] - orgvertloctax[orgvertlocnum]; } return (indedgelocmax); } int dgraphInduceList ( Dgraph * restrict const orggrafptr, const Gnum orglistnbr, const Gnum * const orglisttab, /* Local list of kept vertices */ Dgraph * restrict const indgrafptr) { return (dgraphInduce2 (orggrafptr, dgraphInduceList2, (const void * const) orglisttab, orglistnbr, (Gnum * const) (orglisttab - orggrafptr->baseval), indgrafptr)); } /* This routine builds the graph induced ** by the original graph and the vector of ** selected vertices. ** The induced vnumtab array is the global ** translation of the list array if the ** original graph does not have a vnumtab, ** or the proper subset of the original ** vnumtab else. ** It returns: ** - 0 : on success. ** - !0 : on error. */ typedef struct DgraphInducePartData_ { const GraphPart * orgpartloctax; GraphPart indpartval; } DgraphInducePartData; static Gnum dgraphInducePart2 ( Dgraph * restrict const indgrafptr, Dgraph * restrict const orggrafptr, const void * restrict const orgdataptr, Gnum * restrict const orgindxgsttax) { Gnum orgvertlocnnd; Gnum orgvertlocnum; Gnum indvertlocnum; Gnum indvertglbnum; Gnum indedgelocmax; const Gnum * restrict const orgvertloctax = orggrafptr->vertloctax; const Gnum * restrict const orgvendloctax = orggrafptr->vendloctax; const GraphPart * restrict const orgpartloctax = ((const DgraphInducePartData * restrict const) orgdataptr)->orgpartloctax; const GraphPart indpartval = ((const DgraphInducePartData * restrict const) orgdataptr)->indpartval; Gnum * restrict const indvnumloctax = indgrafptr->vnumloctax; for (orgvertlocnum = indvertlocnum = orggrafptr->baseval, indvertglbnum = indgrafptr->procvrttab[indgrafptr->proclocnum], /* Fill index array while recomputing tighter upper bound on arcs */ orgvertlocnnd = orggrafptr->vertlocnnd, indedgelocmax = 0; orgvertlocnum < orgvertlocnnd; orgvertlocnum ++) { if (orgpartloctax[orgvertlocnum] == indpartval) { orgindxgsttax[orgvertlocnum] = indvertglbnum; /* Mark selected vertices */ indvnumloctax[indvertlocnum] = orgvertlocnum; indedgelocmax += orgvendloctax[orgvertlocnum] - orgvertloctax[orgvertlocnum]; indvertlocnum ++, indvertglbnum ++; } else orgindxgsttax[orgvertlocnum] = ~0; } #ifdef SCOTCH_DEBUG_DGRAPH2 if ((indvertlocnum - orggrafptr->baseval) != indgrafptr->vertlocnbr) { errorPrint ("dgraphInducePart2: inconsistent data"); dgraphFree (indgrafptr); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ return (indedgelocmax); } int dgraphInducePart ( Dgraph * restrict const orggrafptr, /* Pointer to original distributed graph */ const GraphPart * restrict const orgpartloctax, /* Based array of local vertex partition flags */ const Gnum indvertlocnbr, /* Number of local vertices in selected part */ const GraphPart indpartval, Dgraph * restrict const indgrafptr) { DgraphInducePartData orgdatadat; orgdatadat.orgpartloctax = orgpartloctax; orgdatadat.indpartval = indpartval; return (dgraphInduce2 (orggrafptr, dgraphInducePart2, &orgdatadat, indvertlocnbr, NULL, indgrafptr)); } scotch-6.0.4.dfsg/src/libscotch/dgraph_redist.c0000644002563400244210000005744112024357466024641 0ustar trophimeutilisateurs du domaine/* Copyright 2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_redist.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file implements the distributed **/ /** graph redistribution method. **/ /** **/ /** DATES : # Version 6.0 : from : 10 may 2010 **/ /** to : 13 sep 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DGRAPH_REDIST #include "module.h" #include "common.h" #include "dgraph.h" #include "dgraph_redist.h" /**********************************/ /* */ /* Graph redistribution routines. */ /* */ /**********************************/ /* This routine creates a redistributed ** destination graph by redistributing ** the contents of the given source graph ** according to the provided information. ** It returns: ** - 0 : if the redistributed graph has been created. ** - !0 : on error. */ int dgraphRedist ( Dgraph * restrict const srcgrafptr, /* Source distributed graph */ const Gnum * restrict const srcpartloctax, /* Array of process destinations */ const Gnum * restrict const srcpermgsttax, /* Redistribution permutation array */ const Gnum dstvertlocdlt, /* Extra size of local vertex array */ const Gnum dstedgelocdlt, /* Extra size of local edge array */ Dgraph * restrict const dstgrafptr) /* Destination distributed graph */ { Gnum * restrict permgsttax; const Gnum * restrict permgsttmp; Gnum permgstnbr; Gnum * restrict procdsptab; Gnum * restrict procvrttab; Gnum * restrict vadjloctab; Gnum * restrict vadjglbtab; Gnum vadjglbnbr; Gnum vertlocnum; int cheklocval; int chekglbval; Gnum procdspval; Gnum procvrtval; int procglbnbr; int procnum; int o; if (srcpartloctax == NULL) { errorPrint ("dgraphRedist: part array must be provided"); return (1); } cheklocval = 0; procglbnbr = srcgrafptr->procglbnbr; if (srcpermgsttax != NULL) { /* Do not allocate permutation array if already provided */ permgstnbr = vadjglbnbr = 0; } else { if (dgraphGhst (srcgrafptr) != 0) { /* Compute ghost edge array if not already present */ errorPrint ("dgraphRedist: cannot compute ghost edge array"); return (1); } permgstnbr = srcgrafptr->vertgstnbr; vadjglbnbr = procglbnbr; } if (memAllocGroup ((void **) (void *) &procvrttab, (size_t) ((procglbnbr + 1) * sizeof (Gnum)), &procdsptab, (size_t) ((procglbnbr + 1) * sizeof (Gnum)), &vadjloctab, (size_t) (procglbnbr * sizeof (Gnum)), &vadjglbtab, (size_t) (vadjglbnbr * sizeof (Gnum)), &permgsttax, (size_t) (permgstnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("dgraphRedist: out of memory"); cheklocval = 1; } #ifdef SCOTCH_DEBUG_DGRAPH2 if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, srcgrafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphRedist: communication error (1)"); return (1); } #else /* SCOTCH_DEBUG_DGRAPH2 */ chekglbval = cheklocval; #endif /* SCOTCH_DEBUG_DGRAPH2 */ if (chekglbval != 0) { if (procvrttab != NULL) memFree (procvrttab); return (1); } memSet (vadjloctab, 0, procglbnbr * sizeof (Gnum)); for (vertlocnum = srcgrafptr->baseval; vertlocnum < srcgrafptr->vertlocnnd; vertlocnum ++) /* Count number of vertices for each processor */ vadjloctab[srcpartloctax[vertlocnum]] ++; if (MPI_Allreduce (vadjloctab, procdsptab, procglbnbr, GNUM_MPI, MPI_SUM, srcgrafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphRedist: communication error (2)"); return (1); } for (procnum = 0, procdspval = procvrtval = srcgrafptr->baseval; procnum < procglbnbr; procnum ++) { /* Create vertex range arrays */ Gnum procglbval; procglbval = procdsptab[procnum]; procdsptab[procnum] = procdspval; /* Build displacement array */ procdspval += procglbval; procvrttab[procnum] = procvrtval; /* Build vertex index array by adding vertlocdlt */ procvrtval += procglbval + dstvertlocdlt; } procdsptab[procnum] = procdspval; /* Set end of vertex range arrays */ procvrttab[procnum] = procvrtval; if (srcpermgsttax == NULL) { permgsttax -= srcgrafptr->baseval; if (MPI_Scan (vadjloctab, vadjglbtab, procglbnbr, GNUM_MPI, MPI_SUM, srcgrafptr->proccomm) != MPI_SUCCESS) { /* Compute permutation start indices */ errorPrint ("dgraphRedist: communication error (3)"); return (1); } for (procnum = 0; procnum < procglbnbr; procnum ++) /* Finalize permutation start indices */ vadjglbtab[procnum] -= vadjloctab[procnum] - procvrttab[procnum]; for (vertlocnum = srcgrafptr->baseval; vertlocnum < srcgrafptr->vertlocnnd; vertlocnum ++) /* Renumber local vertices */ permgsttax[vertlocnum] = vadjglbtab[srcpartloctax[vertlocnum]] ++; if (dgraphHaloSync (srcgrafptr, permgsttax + srcgrafptr->baseval, GNUM_MPI) != 0) { errorPrint ("dgraphRedist: cannot compute halo"); memFree (procvrttab); /* Free group leader */ return (1); } permgsttmp = permgsttax; } else permgsttmp = srcpermgsttax; o = dgraphRedist2 (srcgrafptr, srcpartloctax, permgsttmp, procdsptab, procvrttab, 0, dstedgelocdlt, dstgrafptr); memFree (procvrttab); /* Free group leader */ return (o); } static int dgraphRedist2 ( Dgraph * restrict const srcgrafptr, /* Source distributed graph */ const Gnum * restrict const srcpartloctax, /* Array of process destinations */ const Gnum * restrict const srcpermgsttax, /* Redistribution permutation array */ const Gnum * const dstprocdsptab, /* New distribution of graph vertices */ const Gnum * const dstprocvrttab, /* New distribution of graph vertices */ const Gnum dstvertlocdlt, /* Extra size of local vertex array */ const Gnum dstedgelocdlt, /* Extra size of local edge array */ Dgraph * restrict const dstgrafptr) /* Destination distributed graph */ { Gnum baseval; int flveval; /* Number of data to send per vertex */ int fledval; /* Number of data to send per edge */ Gnum * drcvdattab; /* Receive array for vertex and edge data [norestrict] */ Gnum * dsnddattab; /* Send array for vertex and edge data [norestrict] */ int * restrict drcvcnttab; /* Count array for received data */ int * restrict dsndcnttab; /* Count array for sent data */ int * restrict drcvdsptab; /* Displacement array for received data */ int * restrict dsnddsptab; /* Displacement array for sent data */ int drcvdatnbr; /* Amount of data to allocate */ int dsnddatnbr; int drcvdatidx; int dsnddatidx; Gnum srcvertlocnum; Gnum srcvertlocnnd; Gnum srcvertlocadj; Gnum * restrict dstvertloctax; Gnum dstvertlocadj; Gnum dstvertlocnbr; Gnum dstvertlocnnd; Gnum dstvertlocnum; Gnum * restrict dstveloloctax; Gnum dstvelolocsiz; Gnum dstvelolocsum; Gnum * restrict dstvlblloctax; Gnum * dstedgeloctax; /* Pointer to destination edge array [norestrict] */ Gnum dstedgelocnbr; Gnum dstedgelocsiz; Gnum dstedgelocnum; Gnum * dstedloloctax; /* Pointer to destination edge load array [norestrict] */ Gnum dstedlolocsiz; int dstvertloctmp; /* Vertex and edge numbers, as (int)s */ int dstedgeloctmp; Gnum procdspval; int procglbnbr; int cheklocval; int chekglbval; int procnum; const Gnum * restrict const srcvertloctax = srcgrafptr->vertloctax; const Gnum * restrict const srcvendloctax = srcgrafptr->vendloctax; const Gnum * restrict const srcveloloctax = srcgrafptr->veloloctax; const Gnum * restrict const srcvlblloctax = srcgrafptr->vlblloctax; const Gnum * restrict const srcedgegsttax = srcgrafptr->edgegsttax; const Gnum * restrict const srcedloloctax = srcgrafptr->edloloctax; dstgrafptr->flagval |= (DGRAPHFREEALL ^ DGRAPHFREECOMM) | DGRAPHVERTGROUP | DGRAPHEDGEGROUP; cheklocval = 0; procglbnbr = srcgrafptr->procglbnbr; if (memAllocGroup ((void **) (void *) /* Allocate distributed graph private data */ &dstgrafptr->procdsptab, (size_t) ((procglbnbr + 1) * sizeof (Gnum)), &dstgrafptr->procvrttab, (size_t) ((procglbnbr + 1) * sizeof (Gnum)), &dstgrafptr->proccnttab, (size_t) (procglbnbr * sizeof (Gnum)), &dstgrafptr->procngbtab, (size_t) (procglbnbr * sizeof (int)), &dstgrafptr->procrcvtab, (size_t) (procglbnbr * sizeof (int)), &dstgrafptr->procsndtab, (size_t) (procglbnbr * sizeof (int)), NULL) == NULL) { errorPrint ("dgraphRedist2: out of memory (1)"); cheklocval = 1; } #ifdef SCOTCH_DEBUG_DGRAPH2 if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, srcgrafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphRedist2: communication error (1)"); return (1); } #else /* SCOTCH_DEBUG_DGRAPH2 */ chekglbval = cheklocval; #endif /* SCOTCH_DEBUG_DGRAPH2 */ if (chekglbval != 0) { dgraphFree (dstgrafptr); return (1); } dsndcnttab = (int *) dstgrafptr->procdsptab; /* TRICK: use procdsptab and procvrttab as paired send count arrays */ drcvcnttab = (int *) dstgrafptr->proccnttab; /* TRICK: use proccnttab and procngbtab as paired receive arrays */ dsnddsptab = (int *) dstgrafptr->procrcvtab; drcvdsptab = (int *) dstgrafptr->procsndtab; memSet (dsndcnttab, 0, procglbnbr * 2 * sizeof (int)); /* TRICK: Pairs of vertex and edge counts will be exchanged */ baseval = srcgrafptr->baseval; for (srcvertlocnum = baseval, srcvertlocnnd = srcgrafptr->vertlocnnd; srcvertlocnum < srcvertlocnnd; srcvertlocnum ++) { Gnum procngbnum; procngbnum = srcpartloctax[srcvertlocnum]; dsndcnttab[2 * procngbnum] ++; /* One more vertex */ dsndcnttab[2 * procngbnum + 1] += (int) (srcvendloctax[srcvertlocnum] - srcvertloctax[srcvertlocnum]); /* More edges */ } if (MPI_Alltoall (dsndcnttab, 2, MPI_INT, /* Get amounts of vertex and edge data to receive */ drcvcnttab, 2, MPI_INT, srcgrafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphRedist2: communication error (2)"); return (1); } fledval = ((srcgrafptr->edloloctax != NULL) ? 1 : 0) + 1; /* Amount of data to exchange per edge */ flveval = ((srcgrafptr->veloloctax != NULL) ? 1 : 0) + 3; /* Number, degree and label count for 3 */ for (procnum = 0, drcvdatidx = dsnddatidx = 0, dstvertloctmp = dstedgeloctmp = 0; procnum < procglbnbr; procnum ++) { /* Compute start indices for data send and receive arrays */ int dsndcntval; int drcvcntval; dsndcntval = dsndcnttab[2 * procnum] * flveval + dsndcnttab[2 * procnum + 1] * fledval; drcvcntval = drcvcnttab[2 * procnum] * flveval + drcvcnttab[2 * procnum + 1] * fledval; dstvertloctmp += drcvcnttab[2 * procnum]; /* Accumulate number of vertices and edges */ dstedgeloctmp += drcvcnttab[2 * procnum + 1]; dsnddsptab[procnum] = dsnddatidx; dsnddatidx += dsndcntval; drcvdsptab[procnum] = drcvdatidx; drcvdatidx += drcvcntval; } dsnddatnbr = dsnddatidx; /* Preserve amount of data to allocate for sending and receiving */ drcvdatnbr = drcvdatidx; for (procnum = procglbnbr - 1; procnum >= 0; procnum --) { /* Compute count arrays for data send and receive arrays */ int dsnddspval; int drcvdspval; dsnddspval = dsnddsptab[procnum]; dsndcnttab[procnum] = dsnddatidx - dsnddspval; dsnddatidx = dsnddspval; drcvdspval = drcvdsptab[procnum]; drcvcnttab[procnum] = drcvdatidx - drcvdspval; drcvdatidx = drcvdspval; } dstvertlocnbr = (Gnum) dstvertloctmp; dstedgelocnbr = (Gnum) dstedgeloctmp; dstedgelocsiz = dstedgelocnbr + dstedgelocdlt; dstvelolocsiz = (srcgrafptr->veloloctax != NULL) ? dstvertlocnbr + dstvertlocdlt : 0; dstedlolocsiz = (srcgrafptr->edloloctax != NULL) ? dstedgelocsiz : 0; if (memAllocGroup ((void **) (void *) &dstvertloctax, (size_t) ((dstvertlocnbr + dstvertlocdlt + 1) * sizeof (Gnum)), /* Create compact array */ &dstveloloctax, (size_t) ( dstvelolocsiz * sizeof (Gnum)), &dstvlblloctax, (size_t) ((dstvertlocnbr + dstvertlocdlt) * sizeof (Gnum)), NULL) == NULL) { /* Vertex labels always present */ errorPrint ("dgraphRedist2: out of memory (2)"); cheklocval = 1; } else if (dstvertloctax -= baseval, dstveloloctax = ((srcgrafptr->veloloctax != NULL) ? dstveloloctax - baseval : NULL), dstvlblloctax -= baseval, memAllocGroup ((void **) (void *) &dstedgeloctax, (size_t) ((dstedlolocsiz + /* TRICK: extra space required only if edge loads */ MAX (dstedgelocdlt, srcgrafptr->degrglbmax)) * sizeof (Gnum)), /* TRICK: degrmax to avoid overlap */ &dsnddattab, (size_t) (dsnddatnbr * sizeof (Gnum)), /* TRICK: send space will be edgeloctab or edloloctab */ &drcvdattab, (size_t) (drcvdatnbr * sizeof (Gnum)), NULL) == NULL) { /* TRICK: Remaining space will be freed */ errorPrint ("dgraphRedist2: out of memory (3)"); cheklocval = 1; } else { dstedgeloctax -= baseval; dstedloloctax = (srcgrafptr->edloloctax != NULL) ? (dstedgeloctax + dstedgelocsiz) : NULL; } #ifdef SCOTCH_DEBUG_DGRAPH2 if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, srcgrafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphRedist2: communication error (3)"); return (1); } #else /* SCOTCH_DEBUG_DGRAPH2 */ chekglbval = cheklocval; #endif /* SCOTCH_DEBUG_DGRAPH2 */ if (chekglbval != 0) { dgraphFree (dstgrafptr); return (1); } srcvertlocadj = srcgrafptr->procvrttab[srcgrafptr->proclocnum] - baseval; for (srcvertlocnum = baseval; srcvertlocnum < srcvertlocnnd; srcvertlocnum ++) { /* Record data to send */ Gnum procngbnum; int dsnddatidx; Gnum srcedgelocnum; Gnum srcedgelocnnd; Gnum srcdegrval; procngbnum = srcpartloctax[srcvertlocnum]; /* Retrieve destination process number */ dsnddatidx = dsnddsptab[procngbnum]; srcedgelocnum = srcvertloctax[srcvertlocnum]; srcedgelocnnd = srcvendloctax[srcvertlocnum]; srcdegrval = srcedgelocnnd - srcedgelocnum; dsnddattab[dsnddatidx ++] = srcpermgsttax[srcvertlocnum]; /* Record destination vertex global number */ dsnddattab[dsnddatidx ++] = srcdegrval; /* Record number of edges */ dsnddattab[dsnddatidx ++] = (srcvlblloctax != NULL) /* Record source vertex global number or label */ ? srcvlblloctax[srcvertlocnum] : srcvertlocnum + srcvertlocadj; if (srcveloloctax != NULL) dsnddattab[dsnddatidx ++] = srcveloloctax[srcvertlocnum]; /* Record vertex load if needed */ if (srcedloloctax != NULL) { /* If edge loads have to be sent too */ memCpy (dsnddattab + dsnddatidx, srcedloloctax + srcedgelocnum, srcdegrval * sizeof (Gnum)); /* Copy edge loads */ dsnddatidx += srcdegrval; } for ( ; srcedgelocnum < srcedgelocnnd; srcedgelocnum ++) /* Record translated edge array */ dsnddattab[dsnddatidx ++] = srcpermgsttax[srcedgegsttax[srcedgelocnum]]; dsnddsptab[procngbnum] = dsnddatidx; } for (procnum = 0, dsnddatidx = 0; /* Recompute dsnddsptab */ procnum < procglbnbr; procnum ++) { dsnddsptab[procnum] = dsnddatidx; dsnddatidx += dsndcnttab[procnum]; } if (MPI_Alltoallv (dsnddattab, dsndcnttab, dsnddsptab, GNUM_MPI, /* Exchange graph data */ drcvdattab, drcvcnttab, drcvdsptab, GNUM_MPI, srcgrafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphRedist2: communication error (4)"); return (1); } dstvertlocadj = dstprocvrttab[srcgrafptr->proclocnum] - baseval; for (drcvdatidx = 0; drcvdatidx < drcvdatnbr; ) { Gnum dstvertlocnum; Gnum dstdegrval; dstvertlocnum = drcvdattab[drcvdatidx ++] - dstvertlocadj; /* Get vertex index */ dstdegrval = drcvdattab[drcvdatidx ++]; /* Get number of edges */ dstvertloctax[dstvertlocnum] = dstdegrval; /* Record vertex degree to compute index array */ dstvlblloctax[dstvertlocnum] = drcvdatidx; /* TRICK: record data position in label array */ drcvdatidx += dstdegrval * fledval + (flveval - 2); /* Increase index by proper value */ } dstvelolocsum = (dstveloloctax != NULL) ? 0 : dstvertlocnbr; /* Set local vertex load sum if no vertex loads present */ for (dstvertlocnum = dstedgelocnum = baseval, dstvertlocnnd = dstvertlocnbr + baseval; /* Copy edge information in due place */ dstvertlocnum < dstvertlocnnd; dstvertlocnum ++) { int drcvdatidx; Gnum dstdegrval; drcvdatidx = dstvlblloctax[dstvertlocnum]; dstdegrval = dstvertloctax[dstvertlocnum]; dstvertloctax[dstvertlocnum] = dstedgelocnum; dstvlblloctax[dstvertlocnum] = drcvdattab[drcvdatidx ++]; /* Set vertex label */ if (dstveloloctax != NULL) { dstvelolocsum += dstveloloctax[dstvertlocnum] = drcvdattab[drcvdatidx ++]; /* Set vertex load */ } if (dstedloloctax != NULL) { #ifdef SCOTCH_DEBUG_DGRAPH2 if (abs ((dstedloloctax + dstedgelocnum) - (drcvdattab + drcvdatidx)) < dstdegrval) { /* Memory areas should never overlap */ errorPrint ("dgraphRedist2: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ memCpy (dstedloloctax + dstedgelocnum, drcvdattab + drcvdatidx, dstdegrval * sizeof (Gnum)); drcvdatidx += dstdegrval; } #ifdef SCOTCH_DEBUG_DGRAPH2 if (abs ((dstedgeloctax + dstedgelocnum) - (drcvdattab + drcvdatidx)) < dstdegrval) { /* TRICK: memory areas should never overlap because of degrmax */ errorPrint ("dgraphRedist2: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ memCpy (dstedgeloctax + dstedgelocnum, drcvdattab + drcvdatidx, dstdegrval * sizeof (Gnum)); /* TRICK: will never overlap */ dstedgelocnum += dstdegrval; } dstvertloctax[dstvertlocnum] = dstedgelocnum; /* Set end of compact vertex array */ dstedgeloctax = memRealloc (dstedgeloctax + baseval, dstedgelocsiz * fledval * sizeof (Gnum)); #ifdef SCOTCH_DEBUG_DGRAPH2 if (dstedgeloctax == NULL) { /* Shrinking should never fail */ errorPrint ("dgraphRedist2: out of memory (4)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ dstedgeloctax -= baseval; if (dstedloloctax != NULL) dstedloloctax = dstedgeloctax + dstedgelocsiz; dstgrafptr->procglbnbr = procglbnbr; dstgrafptr->proclocnum = srcgrafptr->proclocnum; memCpy (dstgrafptr->procvrttab, dstprocvrttab, (procglbnbr + 1) * sizeof (Gnum)); /* Set vertex range array (possibly with holes) */ memCpy (dstgrafptr->procdsptab, dstprocdsptab, (procglbnbr + 1) * sizeof (Gnum)); /* Set vertex displacement array */ for (procnum = procglbnbr - 1, procdspval = dstprocdsptab[procglbnbr]; /* Set vertex count array */ procnum >= 0; procnum --) { Gnum procdsptmp; procdsptmp = dstprocdsptab[procnum]; dstgrafptr->proccnttab[procnum] = procdspval - procdsptmp; procdspval = procdsptmp; } if (dgraphBuild3 (dstgrafptr, baseval, dstvertlocnbr, dstvertloctax, dstvertloctax + 1, dstveloloctax, dstvelolocsum, NULL, NULL, dstedgelocnbr, dstedgelocsiz, dstedgeloctax, NULL, dstedloloctax, srcgrafptr->degrglbmax) != 0) { errorPrint ("dgraphRedist2: cannot build redistributed graph"); dgraphFree (dstgrafptr); return (1); } dstgrafptr->vlblloctax = dstvlblloctax; /* Set label array after building so that labels not taken into account at build time */ #ifdef SCOTCH_DEBUG_DGRAPH2 if (dgraphCheck (dstgrafptr) != 0) { /* Check graph consistency */ errorPrint ("dgraphRedist2: inconsistent graph data"); dgraphFree (dstgrafptr); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/library_dgraph_io_save.c0000644002563400244210000000655712055776612026524 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_io_save.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the distri- **/ /** buted source graph saving routine of **/ /** the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 16 may 2007 **/ /** to 16 may 2007 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "graph.h" #include "dgraph.h" #include "ptscotch.h" /****************************************/ /* */ /* These routines are the C API for the */ /* distributed graph handling routines. */ /* */ /****************************************/ /*+ This routine saves the contents of the given *** opaque distributed graph structure to the *** given streams. *** It returns: *** - 0 : if the saving succeeded. *** - !0 : on error. +*/ int SCOTCH_dgraphSave ( SCOTCH_Dgraph * const grafptr, FILE * const stream) { return (dgraphSave ((Dgraph * const) grafptr, stream)); } scotch-6.0.4.dfsg/src/libscotch/graph_match_scan.c0000644002563400244210000004150012343665150025264 0ustar trophimeutilisateurs du domaine/* Copyright 2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : graph_match_scan.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module contains the stub of the **/ /** threaded and un-threaded centralized **/ /** graph matching functions. **/ /** **/ /** DATES : # Version 6.0 : from : 01 oct 2012 **/ /** to 04 jun 2014 **/ /** **/ /** NOTES : # This code partly derives from the **/ /** code of graph_match.c partly updated **/ /** in the early stages of release 6.0 **/ /** so as to account for fixed vertices **/ /** and an old partition. **/ /** **/ /************************************************************/ /***************************/ /* */ /* The matching subroutine */ /* pattern. */ /* */ /***************************/ /* This routine matches the vertices of the given ** centralized graph according to various constraints. ** It returns: ** - void : in all cases */ static void GRAPHMATCHSCANNAME ( GraphCoarsenThread * restrict thrdptr) /* Thread-dependent data */ { GraphCoarsenData * restrict const coarptr = (GraphCoarsenData *) (thrdptr->thrddat.grouptr); const Graph * restrict const finegrafptr = coarptr->finegrafptr; Gnum finevertnum; /* Current vertex index */ Gnum finevertnnd; /* Current end of vertex array */ #ifdef GRAPHMATCHSCANVELOTAB Gnum finevelomin = (1 * finegrafptr->velosum) / (4 * finegrafptr->vertnbr); /* Minimum load of neighbor */ Gnum coarvelomax = (4 * finegrafptr->velosum) / (1 * (coarptr->coarvertmax - coarptr->finevfixnbr)) + 1; #endif /* GRAPHMATCHSCANVELOTAB */ Gnum coarvertnbr = thrdptr->coarvertnbr; /* Current number of multinode vertices */ #if ((defined GRAPHMATCHSCANP1INPERT) || defined (GRAPHMATCHSCANP2INPERT)) const Gnum degrmax = finegrafptr->degrmax; Gnum pertbas; Gnum pertnnd; Gnum pertnbr; Gunum randval = thrdptr->randval; /* Unsigned to avoid negative random numbers */ #endif /* ((defined GRAPHMATCHSCANP1INPERT) || defined (GRAPHMATCHSCANP2INPERT)) */ #if ((defined GRAPHMATCHSCANP1INQUEUE) || defined (GRAPHMATCHSCANP2INQUEUE) || defined (GRAPHMATCHSCANP2OUTQUEUE)) Gnum * const queutab = coarptr->finequeutab; volatile int * const locktax = coarptr->finelocktax; #endif /* ((defined GRAPHMATCHSCANP1INQUEUE) || defined (GRAPHMATCHSCANP2INQUEUE) || defined (GRAPHMATCHSCANP2OUTQUEUE)) */ #if ((defined GRAPHMATCHSCANP1INQUEUE) || defined (GRAPHMATCHSCANP2INQUEUE)) Gnum queunnd; Gnum queunum; #endif /* ((defined GRAPHMATCHSCANP1INQUEUE) || defined (GRAPHMATCHSCANP2INQUEUE)) */ #if ((defined GRAPHMATCHSCANP1OUTQUEUE) || defined (GRAPHMATCHSCANP2OUTQUEUE)) Gnum queunew; #endif /* ((defined GRAPHMATCHSCANP1OUTQUEUE) || defined (GRAPHMATCHSCANP2OUTQUEUE)) */ const Gnum * restrict const fineverttax = finegrafptr->verttax; const Gnum * restrict const finevendtax = finegrafptr->vendtax; #ifdef GRAPHMATCHSCANVELOTAB const Gnum * restrict const finevelotax = finegrafptr->velotax; #endif /* GRAPHMATCHSCANVELOTAB */ const Gnum * restrict const fineedgetax = finegrafptr->edgetax; #ifdef GRAPHMATCHSCANEDLOTAB const Gnum * restrict const fineedlotax = finegrafptr->edlotax; #endif /* GRAPHMATCHSCANEDLOTAB */ volatile Gnum * restrict const finematetax = coarptr->finematetax; #ifdef GRAPHMATCHSCANPFIXTAB const Gnum * restrict const fineparotax = coarptr->fineparotax; const Gnum * restrict const finepfixtax = coarptr->finepfixtax; #endif /* GRAPHMATCHSCANPFIXTAB */ #ifdef GRAPHMATCHSCANP1INPERT /* First pass is only for start or sequential routines */ #ifdef GRAPHMATCHSCANVELOTAB #ifdef GRAPHMATCHSCANP1OUTQUEUE queunew = thrdptr->queubas; #endif /* GRAPHMATCHSCANP1OUTQUEUE */ #ifdef GRAPHMATCHSCANP1INQUEUE for (queunum = thrdptr->queubas, queunnd = thrdptr->queunnd; queunum < queunnd; queunum ++) { finevertnum = queutab[queunum]; #endif /* GRAPHMATCHSCANP1INQUEUE */ #ifdef GRAPHMATCHSCANP1INPERT for (pertbas = thrdptr->finequeubas, pertnnd = thrdptr->finequeunnd; pertbas < pertnnd; pertbas += pertnbr) { /* Run cache-friendly perturbation */ Gnum pertval; /* Current index in perturbation area */ pertnbr = degrmax * 2 + randval % (degrmax + 1) + 1; /* Compute perturbation area size (avoid DIV0 in random) */ if (pertnbr >= GRAPHMATCHSCANPERTPRIME) pertnbr = 32 + randval % (GRAPHMATCHSCANPERTPRIME - 34); if (pertbas + pertnbr > pertnnd) pertnbr = pertnnd - pertbas; pertval = 0; /* Start from first perturbation vertex */ do { /* Loop on perturbation vertices */ finevertnum = pertbas + pertval; /* Compute corresponding vertex number */ #endif /* GRAPHMATCHSCANP1INPERT */ { Gnum fineedgenum; Gnum finevertbst; #ifdef GRAPHMATCHSCANEDLOTAB Gnum fineedlobst = -1; /* Edge load of current best neighbor */ #endif /* GRAPHMATCHSCANEDLOTAB */ if (finematetax[finevertnum] >= 0) /* If vertex already mated, skip it without remembering it */ goto loop1; finevertbst = finevertnum; /* Assume we match with ourselves */ if ((finevelotax[finevertnum] >= finevelomin) || /* If vertex is not too light, skip it and record it */ (fineverttax[finevertnum] == finevendtax[finevertnum])) /* Same for isolated vertex: process later */ #ifdef GRAPHMATCHSCANP1OUTQUEUE goto record1; #else /* GRAPHMATCHSCANP1OUTQUEUE */ goto loop1; #endif /* GRAPHMATCHSCANP1OUTQUEUE */ for (fineedgenum = fineverttax[finevertnum]; fineedgenum < finevendtax[finevertnum]; fineedgenum ++) { Gnum finevertend; finevertend = fineedgetax[fineedgenum]; if ((finematetax[finevertend] < 0) /* If unmatched vertex */ #ifdef GRAPHMATCHSCANPFIXTAB && ((finepfixtax == NULL) || (finepfixtax[finevertend] == finepfixtax[finevertnum])) /* We can only mate if potential mate has same value */ && ((fineparotax == NULL) || (fineparotax[finevertend] == fineparotax[finevertnum])) /* And is in the same old part */ #endif /* GRAPHMATCHSCANPFIXTAB */ #ifdef GRAPHMATCHSCANEDLOTAB && (fineedlotax[fineedgenum] > fineedlobst) /* And is better candidate */ #endif /* GRAPHMATCHSCANEDLOTAB */ ) { finevertbst = finevertend; #ifdef GRAPHMATCHSCANEDLOTAB fineedlobst = fineedlotax[fineedgenum]; #else /* GRAPHMATCHSCANEDLOTAB */ break; #endif /* GRAPHMATCHSCANEDLOTAB */ } } #ifdef GRAPHMATCHSCANP2OUTQUEUE if (__sync_lock_test_and_set (&locktax[finevertnum], 1)) /* If could not acquire local vertex */ goto loop1; /* Do not remember it as some other vertex has already acquired both */ if (finevertbst != finevertnum) { /* If we mated with another vertex */ if (__sync_lock_test_and_set (&locktax[finevertbst], 1)) { /* If could not acquire mate vertex */ __sync_lock_release (&locktax[finevertnum]); /* Release lock on local vertex */ #ifdef GRAPHMATCHSCANP1OUTQUEUE record1: queutab[queunew ++] = finevertnum; /* Postpone processing to next pass */ #endif /* GRAPHMATCHSCANP1OUTQUEUE */ goto loop1; } finematetax[finevertbst] = finevertnum; } #else /* GRAPHMATCHSCANP2OUTQUEUE */ finematetax[finevertbst] = finevertnum; /* If last (sequential) pass, always record */ #endif /* GRAPHMATCHSCANP2OUTQUEUE */ finematetax[finevertnum] = finevertbst; /* At this point or if last pass, record */ coarvertnbr ++; /* One more coarse vertex created */ loop1: ; } #ifdef GRAPHMATCHSCANP1INPERT pertval = (pertval + GRAPHMATCHSCANPERTPRIME) % pertnbr; /* Compute next perturbation index */ } while (pertval != 0); randval += finevertnum; /* Perturbation for thread-dependent pseudo-random number */ } #endif /* GRAPHMATCHSCANP1INPERT */ #ifdef GRAPHMATCHSCANP1INQUEUE } #endif /* GRAPHMATCHSCANP1INQUEUE */ #ifdef GRAPHMATCHSCANP1OUTQUEUE thrdptr->queunnd = queunew; /* Record queue index for next pass */ #endif /* GRAPHMATCHSCANP1OUTQUEUE */ #endif /* GRAPHMATCHSCANVELOTAB */ #endif /* GRAPHMATCHSCANP1INPERT */ #ifdef GRAPHMATCHSCANP2OUTQUEUE queunew = thrdptr->finequeubas; #endif /* GRAPHMATCHSCANP2OUTQUEUE */ #ifdef GRAPHMATCHSCANP2INQUEUE for (queunum = thrdptr->finequeubas, queunnd = thrdptr->finequeunnd; queunum < queunnd; queunum ++) { finevertnum = queutab[queunum]; #endif /* GRAPHMATCHSCANP2INQUEUE */ #ifdef GRAPHMATCHSCANP2INPERT for (pertbas = thrdptr->finequeubas, pertnnd = thrdptr->finequeunnd; pertbas < pertnnd; pertbas += pertnbr) { /* Run cache-friendly perturbation */ Gnum pertval; /* Current index in perturbation area */ pertnbr = degrmax * 2 + randval % (degrmax + 1) + 1; /* Compute perturbation area size (avoid DIV0 in random) */ if (pertnbr >= GRAPHMATCHSCANPERTPRIME) pertnbr = 32 + randval % (GRAPHMATCHSCANPERTPRIME - 34); if (pertbas + pertnbr > pertnnd) pertnbr = pertnnd - pertbas; pertval = 0; /* Start from first perturbation vertex */ do { /* Loop on perturbation vertices */ finevertnum = pertbas + pertval; /* Compute corresponding vertex number */ #endif /* GRAPHMATCHSCANP2INPERT */ { Gnum fineedgenum; Gnum finevertbst; if (finematetax[finevertnum] >= 0) /* If vertex already mated, skip it without remembering it */ goto loop2; if (fineverttax[finevertnum] == finevendtax[finevertnum]) { /* If isolated vertex */ #ifdef GRAPHMATCHSCANP2INPERT Gnum perttmp = pertnnd; do finevertbst = -- perttmp; #endif /* GRAPHMATCHSCANP2INPERT */ #ifdef GRAPHMATCHSCANP2INQUEUE Gnum queutmp = queunnd; do finevertbst = queutab[-- queutmp]; #endif /* GRAPHMATCHSCANP2INQUEUE */ while ((finematetax[finevertbst] >= 0) /* No test for overflow; we will always mate ourselves as we are isolated */ #ifdef GRAPHMATCHSCANPFIXTAB || ((finepfixtax != NULL) && (finepfixtax[finevertbst] != fineparotax[finevertnum])) || ((fineparotax != NULL) && (fineparotax[finevertbst] != fineparotax[finevertnum]))); #else /* GRAPHMATCHSCANPFIXTAB */ ); #ifdef GRAPHMATCHSCANP2INPERT pertnnd = perttmp; /* If no extra conditions on mating, no longer consider traversed array */ #endif /* GRAPHMATCHSCANP2INPERT */ #ifdef GRAPHMATCHSCANP2INQUEUE queunnd = queutmp; #endif /* GRAPHMATCHSCANP2INQUEUE */ #endif /* GRAPHMATCHSCANPFIXTAB */ } else { Gnum fineedgenum; #ifdef GRAPHMATCHSCANVELOTAB Gnum finevelodlt = coarvelomax - finevelotax[finevertnum]; #endif /* GRAPHMATCHSCANVELOTAB */ #ifdef GRAPHMATCHSCANEDLOTAB Gnum fineedlobst = -1; #endif /* GRAPHMATCHSCANEDLOTAB */ finevertbst = finevertnum; /* No matching neighbor found yet */ for (fineedgenum = fineverttax[finevertnum]; /* For all adjacent vertices */ fineedgenum < finevendtax[finevertnum]; fineedgenum ++) { Gnum finevertend; finevertend = fineedgetax[fineedgenum]; if ((finematetax[finevertend] < 0) /* If unmatched vertex */ #ifdef GRAPHMATCHSCANPFIXTAB && ((finepfixtax == NULL) || (finepfixtax[finevertend] == finepfixtax[finevertnum])) /* And is in the same part */ && ((fineparotax == NULL) || (fineparotax[finevertend] == fineparotax[finevertnum])) #endif /* GRAPHMATCHSCANPFIXTAB */ #ifdef GRAPHMATCHSCANVELOTAB && (finevelodlt >= finevelotax[finevertend]) /* And does not create overloads */ #endif /* GRAPHMATCHSCANVELOTAB */ #ifdef GRAPHMATCHSCANEDLOTAB && (fineedlotax[fineedgenum] > fineedlobst) #endif /* GRAPHMATCHSCANEDLOTAB */ ) { /* And is better candidate */ finevertbst = finevertend; #ifdef GRAPHMATCHSCANEDLOTAB fineedlobst = fineedlotax[fineedgenum]; #else /* GRAPHMATCHSCANEDLOTAB */ break; /* First match will do if no edge loads */ #endif /* GRAPHMATCHSCANEDLOTAB */ } } } #ifdef GRAPHMATCHSCANP2OUTQUEUE if (__sync_lock_test_and_set (&locktax[finevertnum], 1)) /* If could not acquire local vertex */ goto loop2; /* Do not remember it as some other vertex has already acquired both */ if (finevertbst != finevertnum) { /* If we mated with another vertex */ if (__sync_lock_test_and_set (&locktax[finevertbst], 1)) { /* If could not acquire mate vertex */ __sync_lock_release (&locktax[finevertnum]); /* Release lock on local vertex */ queutab[queunew ++] = finevertnum; /* Postpone processing to next pass */ goto loop2; } finematetax[finevertbst] = finevertnum; } #else /* GRAPHMATCHSCANP2OUTQUEUE */ finematetax[finevertbst] = finevertnum; /* If last (sequential) pass, always record */ #endif /* GRAPHMATCHSCANP2OUTQUEUE */ finematetax[finevertnum] = finevertbst; /* At this point or if last pass, record */ coarvertnbr ++; /* One more coarse vertex created */ loop2: ; /* We may do something before looping */ } #ifdef GRAPHMATCHSCANP2INPERT pertval = (pertval + GRAPHMATCHSCANPERTPRIME) % pertnbr; /* Compute next perturbation index */ } while (pertval != 0); randval += finevertnum; /* Perturbation for thread-dependent pseudo-random number */ } #endif /* GRAPHMATCHSCANP2INPERT */ #ifdef GRAPHMATCHSCANP2INQUEUE } #endif /* GRAPHMATCHSCANP2INQUEUE */ #ifdef GRAPHMATCHSCANP2OUTQUEUE thrdptr->finequeunnd = queunew; /* Record queue index for next pass */ #endif /* GRAPHMATCHSCANP2OUTQUEUE */ thrdptr->coarvertnbr = coarvertnbr; /* Record subsequent number of multinode vertices */ } scotch-6.0.4.dfsg/src/libscotch/graph_coarsen.c0000644002563400244210000006604112474554215024631 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2009,2011-2015 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : graph_coarsen.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the source graph **/ /** coarsening functions. **/ /** **/ /** DATES : # Version 0.0 : from : 01 dec 1992 **/ /** to 18 may 1993 **/ /** # Version 1.3 : from : 30 apr 1994 **/ /** to 18 may 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to 31 oct 1994 **/ /** # Version 3.0 : from : 07 jul 1995 **/ /** to 28 sep 1995 **/ /** # Version 3.1 : from : 28 nov 1995 **/ /** to 08 jun 1996 **/ /** # Version 3.2 : from : 07 sep 1996 **/ /** to 17 sep 1998 **/ /** # Version 4.0 : from : 13 dec 2001 **/ /** to 31 aug 2005 **/ /** # Version 5.0 : from : 13 dec 2006 **/ /** to 24 mar 2008 **/ /** # Version 5.1 : from : 30 oct 2009 **/ /** to 30 oct 2009 **/ /** # Version 6.0 : from : 09 mar 2011 **/ /** to 28 feb 2015 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GRAPH_COARSEN #include "module.h" #include "common.h" #include "arch.h" #include "graph.h" #include "graph_coarsen.h" #include "graph_match.h" /***************************/ /* */ /* The coarsening routine. */ /* */ /***************************/ #ifdef GRAPHCOARSENTHREAD /* This routine aggregates a sum and max ** reduction of partial coarse graph ** parameters computed by multiple ** threads. */ static void graphCoarsenReduce ( GraphCoarsenThread * restrict const tlocptr, /* Pointer to local thread */ void * restrict const vlocptr, /* Pointer to local value */ void * restrict const vremptr) /* Pointer to remote value */ { GraphCoarsenThread * restrict const tremptr = (GraphCoarsenThread *) vremptr; tlocptr->coaredloadj += tremptr->coaredloadj; /* Sum edge load sum adjustments */ if (tremptr->coardegrmax > tlocptr->coardegrmax) /* Take maximum of degrees */ tlocptr->coardegrmax = tremptr->coardegrmax; } /* This routine performs a perfix scan ** sum operation on a single Gnum value. */ static void graphCoarsenScan ( GraphCoarsenThread * restrict const tlocptr, /* Pointer to local thread */ Gnum * restrict const vlocptr, /* Pointer to local value */ Gnum * restrict const vremptr, /* Pointer to remote value */ const int phasval) /* Phase index */ { vlocptr[1 - phasval] = vlocptr[phasval] + ((vremptr == NULL) ? 0 : vremptr[phasval]); } #endif /* GRAPHCOARSENTHREAD */ /* This routine is the threaded core of the building ** of the coarse graph from the fine graph. ** It returns: ** - 0 : if the graph has been coarsened. ** - 1 : if the graph could not be coarsened. ** - 2 : on error. */ static int graphCoarsen2 ( void * dataptr) { Gnum baseval; Gnum finevertbas; Gnum finevertnnd; Gnum finevertnbr; Gnum finevertnum; Gnum coarvertnbr; Gnum coarvertnum; Gnum coarhashnbr; /* Size of neighbor vertex hash table */ GraphCoarsenMulti * restrict coarmulttax; Gnum coarmultsiz; /* Size of embedded multinode array */ #ifdef GRAPHCOARSENTHREAD int thrdnbr; int thrdnum; #endif /* GRAPHCOARSENTHREAD */ GraphCoarsenThread * restrict const thrdptr = (GraphCoarsenThread *) dataptr; volatile GraphCoarsenData * restrict const coarptr = (GraphCoarsenData *) (thrdptr->thrddat.grouptr); const Graph * restrict const finegrafptr = coarptr->finegrafptr; volatile Gnum * restrict const finecoartax = coarptr->finematetax; volatile Graph * restrict const coargrafptr = coarptr->coargrafptr; graphMatch (thrdptr); /* Perform (threaded) matching */ coarvertnbr = coarptr->coarvertnbr; /* Get number of vertices actually created */ if (coarvertnbr >= coarptr->coarvertmax) /* If matching failed or if coarsened graph too large */ return (1); /* Do not proceed any further */ coarmultsiz = (coarptr->coarmulttab == NULL) ? coarvertnbr : 0; /* Determine whether coarmulttab is iser-provided */ baseval = finegrafptr->baseval; #ifdef GRAPHCOARSENTHREAD thrdnbr = coarptr->thrddat.thrdnbr; thrdnum = thrdptr->thrddat.thrdnum; if (thrdnum == 0) /* Thread 0 populates the graph data structure */ #endif /* GRAPHCOARSENTHREAD */ { memSet (coargrafptr, 0, sizeof (Graph)); /* Initialize coarse graph on thread 0 */ coargrafptr->flagval = GRAPHFREEVERT | GRAPHVERTGROUP | GRAPHEDGEGROUP; coargrafptr->baseval = baseval; coargrafptr->vertnbr = coarvertnbr; coargrafptr->vertnnd = coarvertnbr + baseval; coargrafptr->velosum = finegrafptr->velosum; /* Keep load of finer graph */ if (memAllocGroup ((void **) (void *) &coargrafptr->verttax, (size_t) ((coarvertnbr + 1) * sizeof (Gnum)), &coargrafptr->velotax, (size_t) (coarvertnbr * sizeof (Gnum)), &coarmulttax, (size_t) (coarmultsiz * sizeof (GraphCoarsenMulti)), &coargrafptr->edgetax, (size_t) (finegrafptr->edgenbr * sizeof (Gnum)), /* Pre-allocate space for edge arrays */ &coargrafptr->edlotax, (size_t) (finegrafptr->edgenbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("graphCoarsen2: out of memory (1)"); /* Allocate coarser graph structure */ return (2); } if (coarmultsiz > 0) /* If array created internally, record its location */ coarptr->coarmulttab = coarmulttax; /* Record un-based array location */ coarmulttax = coarptr->coarmulttab - baseval; /* Only thread 0 knows coarptr->coarmulttab */ coargrafptr->verttax -= baseval; /* Base coarse graph arrays */ coargrafptr->velotax -= baseval; coargrafptr->edgetax -= baseval; coargrafptr->edlotax -= baseval; } finevertnnd = thrdptr->finevertnnd; /* Will be used by many loops */ #ifdef GRAPHCOARSENTHREAD if (thrdnbr > 1) { /* If more than one thread */ Gnum coarvertnnd; for (finevertnum = thrdptr->finevertbas, coarvertnum = 0; finevertnum < finevertnnd; finevertnum ++) { Gnum finematenum; /* Number of current mate vertex */ finematenum = finecoartax[finevertnum]; /* Get mate number */ if (finematenum >= finevertnum) /* If mate has larger number */ coarvertnum ++; /* One more local multinode created */ } thrdptr->coarvertbas = (thrdnum == 0) ? (coarvertnum + baseval) : coarvertnum; threadScan (thrdptr, &thrdptr->coarvertbas, (ThreadScanFunc) graphCoarsenScan); /* Compute start indices for multinodes; barrier for coarptr->coarmulttab */ coarvertnum = thrdptr->coarvertbas - coarvertnum; coarmulttax = coarptr->coarmulttab - baseval; /* All threads know coarptr->coarmulttab */ for (finevertnum = thrdptr->finevertbas; finevertnum < finevertnnd; finevertnum ++) { Gnum finematenum; /* Number of current mate vertex */ finematenum = finecoartax[finevertnum]; /* Get mate number */ if (finematenum >= finevertnum) { /* If mate has larger number */ coarmulttax[coarvertnum].vertnum[0] = finevertnum; /* Build new multinode */ coarmulttax[coarvertnum].vertnum[1] = finematenum; /* Second index always biggest */ coarvertnum ++; /* One more local multinode created */ } } thrdptr->coarvertbas = DATASCAN (coargrafptr->vertnbr, thrdnbr, thrdnum) + baseval; /* Set bounds for coarse vertex processing */ thrdptr->coarvertnnd = DATASIZE (coargrafptr->vertnbr, thrdnbr, thrdnum) + thrdptr->coarvertbas; threadBarrier (thrdptr); /* Ensure all of coarmulttax has been written */ for (coarvertnum = thrdptr->coarvertbas, coarvertnnd = thrdptr->coarvertnnd; coarvertnum < coarvertnnd; coarvertnum ++) { finecoartax[coarmulttax[coarvertnum].vertnum[0]] = /* Build fine-to-coarse array */ finecoartax[coarmulttax[coarvertnum].vertnum[1]] = coarvertnum; } } else #endif /* GRAPHCOARSENTHREAD */ { for (finevertnum = thrdptr->finevertbas, coarvertnum = baseval; /* Finalize finecoartab array */ finevertnum < finevertnnd; finevertnum ++) { Gnum finematenum; /* Number of current mate vertex */ finematenum = finecoartax[finevertnum]; /* Get mate number */ if (finematenum >= finevertnum) { /* If mate has larger number */ coarmulttax[coarvertnum].vertnum[0] = finevertnum; /* Build new multinode */ coarmulttax[coarvertnum].vertnum[1] = finematenum; /* Second index always biggest */ finecoartax[finematenum] = /* Point to coarse vertex */ finecoartax[finevertnum] = coarvertnum; /* Always valid since coarvertnum <= finevertnum */ coarvertnum ++; /* One more multinode created */ } } thrdptr->coarvertbas = baseval; /* Set bounds for coarse vertex processing */ thrdptr->coarvertnnd = coarvertnbr + baseval; } coarhashnbr = coarptr->coarhashmsk + 1; if ((thrdptr->coarhashtab = memAlloc (coarhashnbr * sizeof (GraphCoarsenHash))) == NULL) { /* Allocate local thread memory */ errorPrint ("graphCoarsen2: out of memory (2)"); return (2); } memSet (thrdptr->coarhashtab, ~0, coarhashnbr * sizeof (GraphCoarsenHash)); /* Initialize (local) hash table */ #ifdef GRAPHCOARSENTHREAD if (thrdnbr > 1) { /* If more than one thread */ Gnum coaredgenbr; threadBarrier (thrdptr); /* Ensure all of finecoartax has been written */ thrdptr->coaredgebas = 0; /* No coarse edges accounted for yet */ graphCoarsenEdgeCt (thrdptr); /* Count number of coarse edges for each thread */ coaredgenbr = thrdptr->coaredgebas; /* Save number of local coarse edges */ if (thrdnum == 0) /* Prepare start index for edge index scan */ thrdptr->coaredgebas = coaredgenbr + baseval; threadScan (thrdptr, &thrdptr->coaredgebas, (ThreadScanFunc) graphCoarsenScan); /* Compute scan on coarse edge indices */ thrdptr->coaredgebas -= coaredgenbr; /* Adjust value to have real edge start index */ memSet (thrdptr->coarhashtab, ~0, coarhashnbr * sizeof (GraphCoarsenHash)); /* Re-initialize (local) hash table */ } else #endif /* GRAPHCOARSENTHREAD */ thrdptr->coaredgebas = baseval; /* We start from the beginning */ ((finegrafptr->edlotax != NULL) ? graphCoarsenEdgeLl : graphCoarsenEdgeLu) (thrdptr); /* Build coarse graph edge array */ memFree (thrdptr->coarhashtab); /* Free used (local) hash table */ #ifdef GRAPHCOARSENTHREAD if (thrdnbr > 1) threadReduce (thrdptr, thrdptr, (ThreadReduceFunc) graphCoarsenReduce, 0); /* Sum edloadj and get maximum of degrmax */ if (thrdnum == 0) #endif /* GRAPHCOARSENTHREAD */ { coargrafptr->edlosum = thrdptr->coaredloadj + finegrafptr->edlosum; coargrafptr->degrmax = thrdptr->coardegrmax; } #ifdef GRAPHCOARSENTHREAD if (thrdnum == (thrdnbr - 1)) #endif /* GRAPHCOARSENTHREAD */ coargrafptr->verttax[coargrafptr->vertnnd] = thrdptr->coaredgebas; /* Mark end of edge array */ return (0); /* Joining all treads will serve as synchronization for coarse graph data */ } /* This routine is the sequential core of the ** matching and coarse graph building process. ** It returns: ** - 0 : if the graph has been coarsened. ** - 1 : if the graph could not be coarsened. ** - 2 : on error. */ static int graphCoarsen3 ( GraphCoarsenData * restrict const coarptr, GraphCoarsenMulti * restrict * const coarmultptr) /*+ Pointer to un-based multinode table to build +*/ { Gnum coarvertnbr; /* Number of coarse vertices */ Gnum coarvertnum; /* Number of current multinode vertex */ Gnum coarvfixnbr; /* Coarse number of fixed vertices */ GraphCoarsenMulti * restrict coarmulttax; /* Multinode array */ Gnum coarmultsiz; /* Size of embedded multinode array */ Gnum * finecoartab; /* Fine vertex mating / indexing array */ Gnum finevertnum; /* Number of currently selected fine vertex */ Gnum coarhashmsk; /* Mask for access to hash table */ size_t coarmultoftval; size_t coarvelooftval; size_t coaredgeoftval; size_t coaredlooftval; #ifdef GRAPHCOARSENTHREAD int thrdnbr; #endif /* GRAPHCOARSENTHREAD */ int o; Graph * restrict const coargrafptr = coarptr->coargrafptr; const Graph * restrict const finegrafptr = coarptr->finegrafptr; const Gnum finevertnbr = finegrafptr->vertnbr; const Gnum baseval = finegrafptr->baseval; for (coarhashmsk = 31; coarhashmsk < finegrafptr->degrmax; coarhashmsk = coarhashmsk * 2 + 1) ; /* Compute size of hash table */ coarptr->coarhashmsk = coarhashmsk * 4 + 3; /* Record it for (local) hash table allocation */ #ifdef GRAPHCOARSENTHREAD thrdnbr = coarptr->thrddat.thrdnbr = SCOTCH_PTHREAD_NUMBER; /* Required by graphMatchInit */ #else /* GRAPHCOARSENTHREAD */ coarptr->thrddat.thrdnbr = 1; #endif /* GRAPHCOARSENTHREAD */ if (coarptr->finematetax == NULL) { /* If no user-provided mating array */ if (graphMatchInit (coarptr) != 0) /* Initialize global data needed for matching */ return (1); if ((finecoartab = (Gnum *) memAlloc (finevertnbr * sizeof (Gnum))) == NULL) { errorPrint ("graphCoarsen3: out of memory (1)"); /* Allocate coarse graph mating and indexing array */ return (2); } coarptr->finematetax = finecoartab - baseval; /* Set based access to finematetab / finecoartab */ } else { graphMatchNone (coarptr); /* Initialize global data to avoid matching */ finecoartab = NULL; /* No need to allocate local mating array */ } coarptr->coarmulttab = *coarmultptr; #ifdef GRAPHCOARSENTHREAD if (thrdnbr > 1) { GraphCoarsenThread * restrict thrdtab; int thrdnum; Gnum finevertbas; if ((thrdtab = memAlloc (thrdnbr * sizeof (GraphCoarsenThread))) == NULL) { errorPrint ("graphCoarsen3: out of memory (2)"); memFree (finecoartab); return (2); } for (thrdnum = 0, finevertbas = baseval; thrdnum < thrdnbr; thrdnum ++) { thrdtab[thrdnum].randval = intRandVal (INT_MAX); thrdtab[thrdnum].finevertbas = finevertbas; thrdtab[thrdnum].finevertnnd = finevertbas += DATASIZE (finevertnbr, thrdnbr, thrdnum); thrdtab[thrdnum].coarvertnbr = 0; /* No coarse vertices yet */ } o = threadLaunch (coarptr, thrdtab, sizeof (GraphCoarsenThread), (ThreadLaunchStartFunc) graphCoarsen2, (ThreadLaunchJoinFunc) NULL, thrdnbr, THREADCANBARRIER | THREADCANREDUCE); memFree (thrdtab); /* Free group leader */ } else #endif /* GRAPHCOARSENTHREAD */ { GraphCoarsenThread thrddat; #ifdef GRAPHCOARSENTHREAD thrddat.thrddat.thrdnum = 0; /* Thread 0 of 1 */ #endif /* GRAPHCOARSENTHREAD */ thrddat.thrddat.grouptr = (void *) coarptr; thrddat.randval = intRandVal (INT_MAX); thrddat.finevertbas = baseval; thrddat.finevertnnd = baseval + finevertnbr; o = graphCoarsen2 (&thrddat); } if (finecoartab != NULL) memFree (finecoartab); if (o != 0) /* If coarsened graph is too small, abort here */ return (1); coargrafptr->edgenbr = coargrafptr->verttax[coargrafptr->vertnnd] - baseval; /* Set exact number of edges */ coarvertnbr = coargrafptr->vertnbr; coarmultsiz = (*coarmultptr == NULL) ? coarvertnbr : 0; /* Tell whether we have to resize multloctab within coarse graph vertex group */ coarvelooftval = coargrafptr->velotax - coargrafptr->verttax; coaredgeoftval = coargrafptr->edgetax - coargrafptr->verttax; coaredlooftval = coargrafptr->edlotax - coargrafptr->verttax; coarmultoftval = (Gnum *) coarptr->coarmulttab - coargrafptr->verttax; if (memReallocGroup ((void *) (coargrafptr->verttax + baseval), /* Re-allocate data, wiping temporary arrays */ &coargrafptr->verttax, (size_t) ((coarvertnbr + 1) * sizeof (Gnum)), &coargrafptr->velotax, (size_t) (coarvertnbr * sizeof (Gnum)), &coarptr->coarmulttab, (size_t) (coarmultsiz * sizeof (GraphCoarsenMulti)), &coargrafptr->edgetax, (size_t) (finegrafptr->edgenbr * sizeof (Gnum)), &coargrafptr->edlotax, (size_t) (coargrafptr->edgenbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("graphCoarsen3: cannot reallocate memory"); /* Allocate coarser graph structure */ return (2); } coargrafptr->verttax -= baseval; coargrafptr->vendtax = coargrafptr->verttax + 1; /* Use compact representation of arrays */ coargrafptr->velotax = coargrafptr->verttax + coarvelooftval; coargrafptr->edgetax = coargrafptr->verttax + coaredgeoftval; coargrafptr->edlotax = coargrafptr->verttax + coaredlooftval; if (coarmultsiz > 0) /* If multinode array not user-provided */ *coarmultptr = ((GraphCoarsenMulti *) (coargrafptr->verttax + coarmultoftval)); /* Return pointer to un-based multinode array */ if (coarptr->coarvfixptr != NULL) *coarptr->coarvfixptr = coarvfixnbr = coarptr->finevfixnbr; /* TODO: compute real number ! */ #ifdef SCOTCH_DEBUG_GRAPH2 if (graphCheck (coargrafptr) != 0) { /* Check graph consistency */ errorPrint ("graphCoarsen3: inconsistent graph data"); graphFree (coargrafptr); return (2); } #endif /* SCOTCH_DEBUG_GRAPH2 */ return (0); } /* This routine coarsens the given "finegraph" into ** "coargraph", as long as the coarsening ratio remains ** below some threshold value and the coarsened graph ** is not too small. ** It returns: ** - 0 : if the graph has been coarsened. ** - 1 : if the graph could not be coarsened. ** - 2 : on error. */ int graphCoarsen ( const Graph * restrict const finegrafptr, /*+ Graph to coarsen +*/ Graph * restrict const coargrafptr, /*+ Coarse graph to build +*/ GraphCoarsenMulti * restrict * const coarmultptr, /*+ Pointer to un-based multinode table to build +*/ const Gnum coarvertnbr, /*+ Minimum number of coarse vertices +*/ const double coarval, /*+ Maximum contraction ratio +*/ const Anum * restrict const fineparotax, const Anum * restrict const finepfixtax, const Gnum finevfixnbr, Gnum * restrict const coarvfixptr) { GraphCoarsenData coardat; /* Graph coarsening global data */ #ifdef SCOTCH_DEBUG_GRAPH1 if (coarval < 0.5L) /* If impossible coarsening ratio wanted */ return (1); /* We will never succeed */ #endif /* SCOTCH_DEBUG_GRAPH1 */ coardat.coarvertmax = (Gnum) ((double) (finegrafptr->vertnbr - finevfixnbr) * coarval) + finevfixnbr; /* Maximum number of coarse vertices */ if (coardat.coarvertmax < coarvertnbr) /* If there will be too few vertices in graph */ return (1); /* It is useless to go any further */ coardat.finegrafptr = finegrafptr; /* Fill caller part of matching data structure */ coardat.fineparotax = fineparotax; coardat.finepfixtax = finepfixtax; coardat.finevfixnbr = finevfixnbr; coardat.finematetax = NULL; /* No user-provided mating array */ coardat.coargrafptr = coargrafptr; coardat.coarvfixptr = coarvfixptr; return (graphCoarsen3 (&coardat, coarmultptr)); } /* This routine coarsens the given "finegraph" into ** "coargraph", as long as the coarsening ratio remains ** below some threshold value and the coarsened graph ** is not too small. ** It returns: ** - 0 : if the graph has been coarsened. ** - 1 : if the graph could not be coarsened. ** - 2 : on error. */ int graphCoarsenBuild ( const Graph * restrict const finegrafptr, /*+ Graph to coarsen +*/ Graph * restrict const coargrafptr, /*+ Coarse graph to build +*/ GraphCoarsenMulti * restrict * const coarmultptr, /*+ Pointer to un-based multinode table to build +*/ const Gnum coarvertnbr, /*+ User-provided number of coarse vertices +*/ Gnum * restrict const finematetab) /*+ Pointer to un-based user-provided mating array +*/ { GraphCoarsenData coardat; /* Graph coarsening global data */ coardat.finegrafptr = finegrafptr; /* Fill caller part of matching data structure */ coardat.fineparotax = NULL; /* TODO: arrays not handled yet */ coardat.finepfixtax = NULL; coardat.finevfixnbr = 0; coardat.finematetax = finematetab - finegrafptr->baseval; /* User-provided mating array */ coardat.coargrafptr = coargrafptr; coardat.coarvertmax = finegrafptr->vertnbr + 1; /* Value that always succeeds */ coardat.coarvertnbr = coarvertnbr; /* Set number of coarse vertices */ coardat.coarvfixptr = NULL; /* TODO: arrays not handled yet */ return (graphCoarsen3 (&coardat, coarmultptr)); } /****************************************/ /* */ /* The edge array building subroutines. */ /* */ /****************************************/ #define GRAPHCOARSENEDGENAME graphCoarsenEdgeLl #define GRAPHCOARSENEDGEINIT const Gnum * restrict const fineedlotax = finegrafptr->edlotax #define GRAPHCOARSENEDGEEDLOINIT coaredlotax[coaredgenum] = fineedlotax[fineedgenum] #define GRAPHCOARSENEDGEEDLOADD coaredlotax[coarhashtab[h].edgenum] += fineedlotax[fineedgenum] #define GRAPHCOARSENEDGEEDLOSUB coaredloadj -= fineedlotax[fineedgenum] #include "graph_coarsen_edge.c" #undef GRAPHCOARSENEDGENAME #undef GRAPHCOARSENEDGEINIT #undef GRAPHCOARSENEDGEEDLOINIT #undef GRAPHCOARSENEDGEEDLOADD #undef GRAPHCOARSENEDGEEDLOSUB #define GRAPHCOARSENEDGENAME graphCoarsenEdgeLu #define GRAPHCOARSENEDGEINIT #define GRAPHCOARSENEDGEEDLOINIT coaredlotax[coaredgenum] = 1 #define GRAPHCOARSENEDGEEDLOADD coaredlotax[coarhashtab[h].edgenum] ++ #define GRAPHCOARSENEDGEEDLOSUB coaredloadj -- #include "graph_coarsen_edge.c" #undef GRAPHCOARSENEDGENAME #undef GRAPHCOARSENEDGEINIT #undef GRAPHCOARSENEDGEEDLOINIT #undef GRAPHCOARSENEDGEEDLOADD #undef GRAPHCOARSENEDGEEDLOSUB #ifdef GRAPHCOARSENTHREAD #define GRAPHCOARSENEDGECOUNT /* Local coarse edge count routine */ #define GRAPHCOARSENEDGENAME graphCoarsenEdgeCt #define GRAPHCOARSENEDGEINIT #define GRAPHCOARSENEDGEEDLOINIT #define GRAPHCOARSENEDGEEDLOADD #define GRAPHCOARSENEDGEEDLOSUB #include "graph_coarsen_edge.c" #undef GRAPHCOARSENEDGENAME #undef GRAPHCOARSENEDGEINIT #undef GRAPHCOARSENEDGEEDLOINIT #undef GRAPHCOARSENEDGEEDLOADD #undef GRAPHCOARSENEDGEEDLOSUB #undef GRAPHCOARSENEDGECOUNT #endif /* GRAPHCOARSENTHREAD */ scotch-6.0.4.dfsg/src/libscotch/library_memory_f.c0000644002563400244210000000614612410344531025343 0ustar trophimeutilisateurs du domaine/* Copyright 2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_memory_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API for **/ /** the some miscellaneous routines **/ /** provided by the common files of the **/ /** libSCOTCH library. **/ /** **/ /** DATES : # Version 6.0 : from : 23 sep 2014 **/ /** to 23 sep 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for some miscellaneous routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFNUMSIZEOF, scotchfnumsizeof, ( \ int * const sizeptr), \ (sizeptr)) { *sizeptr = SCOTCH_numSizeof (); } scotch-6.0.4.dfsg/src/libscotch/hmesh_order_st.c0000644002563400244210000003604011631447170025012 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh_order_st.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the generic call to the **/ /** halo mesh ordering module, using a **/ /** given strategy. **/ /** **/ /** DATES : # Version 4.0 : from : 28 sep 2002 **/ /** to 05 jan 2005 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HMESH_ORDER_ST #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "hgraph.h" #include "mesh.h" #include "hmesh.h" #include "order.h" #include "hgraph_order_st.h" #include "hmesh_order_bl.h" #include "hmesh_order_cp.h" #include "hmesh_order_gp.h" #include "hmesh_order_gr.h" #include "hmesh_order_hd.h" #include "hmesh_order_hf.h" #include "hmesh_order_nd.h" #include "hmesh_order_si.h" #include "hmesh_order_st.h" #include "vmesh.h" #include "vmesh_separate_st.h" /* ** The static and global variables. */ static Hmesh hmeshorderstmeshdummy; /* Dummy mesh for offset computations */ static union { /* Default parameters for block splitting method */ HmeshOrderBlParam param; /* Parameter zone */ StratNodeMethodData padding; /* To avoid reading out of structure */ } hmeshorderstdefaultbl = { { &stratdummy, 8 } }; static union { HmeshOrderCpParam param; StratNodeMethodData padding; } hmeshorderstdefaultcp = { { 0.70L, &stratdummy, &stratdummy } }; static union { /* Default parameters for nested dissection method */ HmeshOrderGpParam param; StratNodeMethodData padding; } hmeshorderstdefaultgp = { { 3 } }; static union { /* Default parameters for nested dissection method */ HmeshOrderGrParam param; StratNodeMethodData padding; } hmeshorderstdefaultgr = { { &stratdummy } }; static union { HmeshOrderHdParam param; StratNodeMethodData padding; } hmeshorderstdefaulthd = { { 1, 1000000, 0.08L } }; static union { HmeshOrderHfParam param; StratNodeMethodData padding; } hmeshorderstdefaulthf = { { 1, 1000000, 0.08L } }; static union { /* Default parameters for nested dissection method */ HmeshOrderNdParam param; StratNodeMethodData padding; } hmeshorderstdefaultnd = { { &stratdummy, &stratdummy, &stratdummy } }; static StratMethodTab hmeshorderstmethtab[] = { /* Mesh ordering methods array */ { HMESHORDERSTMETHBL, "b", hmeshOrderBl, &hmeshorderstdefaultbl }, { HMESHORDERSTMETHCP, "c", hmeshOrderCp, &hmeshorderstdefaultcp }, { HMESHORDERSTMETHGP, "g", hmeshOrderGp, &hmeshorderstdefaultgp }, { HMESHORDERSTMETHGR, "v", hmeshOrderGr, &hmeshorderstdefaultgr }, { HMESHORDERSTMETHHD, "d", hmeshOrderHd, &hmeshorderstdefaulthd }, { HMESHORDERSTMETHHF, "f", hmeshOrderHf, &hmeshorderstdefaulthf }, { HMESHORDERSTMETHND, "n", hmeshOrderNd, &hmeshorderstdefaultnd }, { HMESHORDERSTMETHSI, "s", hmeshOrderSi, NULL }, { -1, NULL, NULL, NULL } }; static StratParamTab hmeshorderstparatab[] = { /* The method parameter list */ { HMESHORDERSTMETHBL, STRATPARAMSTRAT, "strat", (byte *) &hmeshorderstdefaultbl.param, (byte *) &hmeshorderstdefaultbl.param.strat, (void *) &hmeshorderststratab }, { HMESHORDERSTMETHBL, STRATPARAMINT, "cmin", (byte *) &hmeshorderstdefaultbl.param, (byte *) &hmeshorderstdefaultbl.param.cblkmin, NULL }, { HMESHORDERSTMETHCP, STRATPARAMDOUBLE, "rat", (byte *) &hmeshorderstdefaultcp.param, (byte *) &hmeshorderstdefaultcp.param.comprat, NULL }, { HMESHORDERSTMETHCP, STRATPARAMSTRAT, "cpr", (byte *) &hmeshorderstdefaultcp.param, (byte *) &hmeshorderstdefaultcp.param.stratcpr, (void *) &hmeshorderststratab }, { HMESHORDERSTMETHCP, STRATPARAMSTRAT, "unc", (byte *) &hmeshorderstdefaultcp.param, (byte *) &hmeshorderstdefaultcp.param.stratunc, (void *) &hmeshorderststratab }, { HMESHORDERSTMETHGP, STRATPARAMINT, "pass", (byte *) &hmeshorderstdefaultgp.param, (byte *) &hmeshorderstdefaultgp.param.passnbr, NULL }, { HMESHORDERSTMETHGR, STRATPARAMSTRAT, "strat", (byte *) &hmeshorderstdefaultgr.param, (byte *) &hmeshorderstdefaultgr.param.stratptr, (void *) &hgraphorderststratab }, { HMESHORDERSTMETHHD, STRATPARAMINT, "cmin", (byte *) &hmeshorderstdefaulthd.param, (byte *) &hmeshorderstdefaulthd.param.colmin, NULL }, { HMESHORDERSTMETHHD, STRATPARAMINT, "cmax", (byte *) &hmeshorderstdefaulthd.param, (byte *) &hmeshorderstdefaulthd.param.colmax, NULL }, { HMESHORDERSTMETHHD, STRATPARAMDOUBLE, "frat", (byte *) &hmeshorderstdefaulthd.param, (byte *) &hmeshorderstdefaulthd.param.fillrat, NULL }, { HMESHORDERSTMETHHF, STRATPARAMINT, "cmin", (byte *) &hmeshorderstdefaulthf.param, (byte *) &hmeshorderstdefaulthf.param.colmin, NULL }, { HMESHORDERSTMETHHF, STRATPARAMINT, "cmax", (byte *) &hmeshorderstdefaulthf.param, (byte *) &hmeshorderstdefaulthf.param.colmax, NULL }, { HMESHORDERSTMETHHF, STRATPARAMDOUBLE, "frat", (byte *) &hmeshorderstdefaulthf.param, (byte *) &hmeshorderstdefaulthf.param.fillrat, NULL }, { HMESHORDERSTMETHND, STRATPARAMSTRAT, "sep", (byte *) &hmeshorderstdefaultnd.param, (byte *) &hmeshorderstdefaultnd.param.sepstrat, (void *) &vmeshseparateststratab }, { HMESHORDERSTMETHND, STRATPARAMSTRAT, "ole", (byte *) &hmeshorderstdefaultnd.param, (byte *) &hmeshorderstdefaultnd.param.ordstratlea, (void *) &hmeshorderststratab }, { HMESHORDERSTMETHND, STRATPARAMSTRAT, "ose", (byte *) &hmeshorderstdefaultnd.param, (byte *) &hmeshorderstdefaultnd.param.ordstratsep, (void *) &hmeshorderststratab }, { HMESHORDERSTMETHNBR, STRATPARAMINT, NULL, NULL, NULL, NULL } }; static StratParamTab hmeshorderstcondtab[] = { /* Mesh condition parameter table */ { STRATNODECOND, STRATPARAMINT, "edge", (byte *) &hmeshorderstmeshdummy, (byte *) &hmeshorderstmeshdummy.m.edgenbr, NULL }, { STRATNODECOND, STRATPARAMINT, "levl", (byte *) &hmeshorderstmeshdummy, (byte *) &hmeshorderstmeshdummy.levlnum, NULL }, { STRATNODECOND, STRATPARAMINT, "load", (byte *) &hmeshorderstmeshdummy, (byte *) &hmeshorderstmeshdummy.vnhlsum, NULL }, { STRATNODECOND, STRATPARAMDOUBLE, "mdeg", (byte *) &hmeshorderstmeshdummy, (byte *) &hmeshorderstmeshdummy.m.degrmax, NULL }, { STRATNODECOND, STRATPARAMINT, "vnod", (byte *) &hmeshorderstmeshdummy, (byte *) &hmeshorderstmeshdummy.vnohnbr, NULL }, { STRATNODECOND, STRATPARAMINT, "velm", (byte *) &hmeshorderstmeshdummy, (byte *) &hmeshorderstmeshdummy.m.velmnbr, NULL }, { STRATNODENBR, STRATPARAMINT, NULL, NULL, NULL, NULL } }; StratTab hmeshorderststratab = { /* Strategy tables for mesh ordering methods */ hmeshorderstmethtab, hmeshorderstparatab, hmeshorderstcondtab }; /***********************************/ /* */ /* This routine is the entry point */ /* for the mesh ordering routines. */ /* */ /***********************************/ /* This routine computes an ordering ** with respect to a given strategy. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int hmeshOrderSt ( const Hmesh * restrict const meshptr, /*+ Submesh to which list apply +*/ Order * restrict const ordeptr, /*+ Ordering to complete +*/ const Gnum ordenum, /*+ Index to start ordering at +*/ OrderCblk * restrict const cblkptr, /*+ Current column block +*/ const Strat * restrict const strat) /*+ Mesh ordering strategy +*/ { StratTest val; int o; if (meshptr->vnohnbr == 0) /* Return immediately if nothing to do */ return (0); o = 0; switch (strat->type) { case STRATNODECONCAT : errorPrint ("hmeshOrderSt: concatenation operator not implemented for ordering strategies"); return (1); case STRATNODECOND : o = stratTestEval (strat->data.cond.test, &val, (void *) meshptr); /* Evaluate expression */ if (o == 0) { /* If evaluation was correct */ #ifdef SCOTCH_DEBUG_HMESH2 if ((val.typetest != STRATTESTVAL) && (val.typenode != STRATPARAMLOG)) { errorPrint ("hmeshOrderSt: invalid test result"); o = 1; break; } #endif /* SCOTCH_DEBUG_HMESH2 */ if (val.data.val.vallog == 1) /* If expression is true */ o = hmeshOrderSt (meshptr, ordeptr, ordenum, cblkptr, strat->data.cond.strat[0]); /* Apply first strategy */ else { /* Else if expression is false */ if (strat->data.cond.strat[1] != NULL) /* And if there is an else statement */ o = hmeshOrderSt (meshptr, ordeptr, ordenum, cblkptr, strat->data.cond.strat[1]); /* Apply second strategy */ } } break; case STRATNODEEMPTY : hmeshOrderSi (meshptr, ordeptr, ordenum, cblkptr); /* Always maintain a coherent ordering */ break; case STRATNODESELECT : errorPrint ("hmeshOrderSt: selection operator not available for mesh ordering strategies"); return (1); #ifdef SCOTCH_DEBUG_HMESH2 case STRATNODEMETHOD : #else /* SCOTCH_DEBUG_HMESH2 */ default : #endif /* SCOTCH_DEBUG_HMESH2 */ return (strat->tabl->methtab[strat->data.method.meth].func (meshptr, ordeptr, ordenum, cblkptr, (void *) &strat->data.method.data)); #ifdef SCOTCH_DEBUG_HMESH2 default : errorPrint ("hmeshOrderSt: invalid parameter"); return (1); #endif /* SCOTCH_DEBUG_HMESH2 */ } return (o); } scotch-6.0.4.dfsg/src/libscotch/order.h0000644002563400244210000001530111631447170023122 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : order.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data **/ /** declarations for the generic ordering **/ /** structure. **/ /** **/ /** DATES : # Version 3.2 : from : 19 oct 1996 **/ /** to : 21 aug 1998 **/ /** # Version 4.0 : from : 19 dec 2001 **/ /** to 28 dec 2004 **/ /** # Version 5.0 : from : 25 jul 2007 **/ /** to 25 jul 2007 **/ /** # Version 5.1 : from : 04 nov 2010 **/ /** to 04 nov 2010 **/ /** **/ /************************************************************/ #define ORDER_H /* ** The defines. */ /*+ Ordering option flags. +*/ #define ORDERNONE 0x0000 /* No options set */ #define ORDERFREEPERI 0x0001 /* Free inverse permutation array */ /*+ Column block separation tree cell flags. The ORDERCBLKNEDI value must correspond to a single bit and be equal to the DORDERCBLKNEDI value. +*/ #define ORDERCBLKOTHR 0x0000 /*+ Other ordering node +*/ #define ORDERCBLKNEDI 0x0001 /*+ Nested dissection separator node +*/ /* ** The type and structure definitions. */ /*+ Column-block tree node. Each node defines a column block, which is either a separator or a leaf built by nested dissection, or a super-variable built by minimum-degree algorithms. Column blocks are given in ascending order within sub-arrays, for proper infix traversal. +*/ typedef struct OrderCblk_ { int typeval; /*+ Type of tree node +*/ Gnum vnodnbr; /*+ Number of node vertices in subtree +*/ Gnum cblknbr; /*+ Number of descendent column blocks +*/ struct OrderCblk_ * cblktab; /*+ Sub-array of column-blocks +*/ } OrderCblk; /*+ Ordering structure. A block ordering is defined by its inverse permutation peritab and by the tree of permuted ordering blocks, which, once flattened, defines the blocks of the ordering. For the sake of consistency between orderings that have been produced either from graphs or meshes, all ordering values are based from baseval. +*/ typedef struct Order_ { int flagval; /*+ Flag value +*/ Gnum baseval; /*+ Base value for structures +*/ Gnum vnodnbr; /*+ Number of node vertices +*/ Gnum treenbr; /*+ Number of column block tree nodes +*/ Gnum cblknbr; /*+ Number of column blocks +*/ OrderCblk cblktre; /*+ Root of column block tree +*/ Gnum * peritab; /*+ Inverse permutation array [vnodnbr] +*/ } Order; /* ** The function prototypes. */ #ifndef ORDER #define static #endif int orderInit (Order * const, const Gnum, const Gnum, Gnum * const); void orderExit (Order * const); static void orderExit2 (OrderCblk * const, const Gnum); int orderLoad (Order * restrict const, const Gnum * restrict const, FILE * restrict const); int orderSave (const Order * restrict const, const Gnum * restrict const, FILE * restrict const); int orderSaveMap (const Order * const, const Gnum * restrict const, FILE * restrict const); int orderSaveTree (const Order * const, const Gnum * restrict const, FILE * restrict const); void orderPeri (const Gnum * const, const Gnum, const Gnum, Gnum * const, const Gnum); void orderRang (const Order * const, Gnum * const); static void orderRang2 (Gnum ** const, Gnum * const, const OrderCblk * const); void orderTree (const Order * restrict const, Gnum * restrict const); static void orderTree2 (Gnum * restrict const, Gnum * restrict const, const OrderCblk * restrict const, Gnum); int orderCheck (const Order * const); #undef static scotch-6.0.4.dfsg/src/libscotch/library_dgraph_io_load_f.c0000644002563400244210000001161112055776560026777 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_io_load_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API for **/ /** the distributed source graph handling **/ /** routines of the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 13 may 2007 **/ /** to 13 may 2007 **/ /** # Version 5.1 : from : 27 mar 2010 **/ /** to 27 mar 2010 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "ptscotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the graph handling routines. */ /* */ /**************************************/ /* When an input stream is built from the given ** file handle, it is set as unbuffered, so as to ** allow for multiple stream reads from the same ** file handle. If it were buffered, too many ** input characters would be read on the first ** block read. */ FORTRAN ( \ SCOTCHFDGRAPHLOAD, scotchfdgraphload, ( \ SCOTCH_Dgraph * const grafptr, \ int * const fileptr, \ const SCOTCH_Num * const baseptr, \ const SCOTCH_Num * const flagptr, \ int * const revaptr), \ (grafptr, fileptr, baseptr, flagptr, revaptr)) { FILE * stream; /* Stream to build from handle */ int filenum; /* Duplicated handle */ int o; if (*fileptr == -1) /* If process does not want to open a stream */ stream = NULL; else { if ((filenum = dup (*fileptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFDGRAPHLOAD: cannot duplicate handle"); *revaptr = 1; /* Indicate error */ return; } if ((stream = fdopen (filenum, "r")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFDGRAPHLOAD: cannot open input stream"); close (filenum); *revaptr = 1; return; } setbuf (stream, NULL); /* Do not buffer on input */ } errorPrint ("SCOTCHFDGRAPHLOAD: not implemented"); o = SCOTCH_dgraphLoad (grafptr, stream, *baseptr, *flagptr); if (stream != NULL) /* If process has an open stream */ fclose (stream); /* This closes filenum too */ *revaptr = o; } scotch-6.0.4.dfsg/src/libscotch/mapping_io.c0000644002563400244210000002505612376056112024133 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mapping_io.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module handles (partial) mappings. **/ /** **/ /** DATES : # Version 0.0 : from : 31 mar 1993 **/ /** to 31 mar 1993 **/ /** # Version 1.0 : from : 04 oct 1993 **/ /** to 06 oct 1993 **/ /** # Version 1.1 : from : 15 oct 1993 **/ /** to 15 oct 1993 **/ /** # Version 1.3 : from : 09 apr 1994 **/ /** to 11 may 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to 17 nov 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to 18 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 19 oct 1995 **/ /** # Version 3.1 : from : 30 oct 1995 **/ /** to 14 jun 1996 **/ /** # Version 3.2 : from : 23 aug 1996 **/ /** to 07 sep 1998 **/ /** # Version 3.3 : from : 19 oct 1998 **/ /** to 30 mar 1999 **/ /** # Version 3.4 : from : 11 sep 2001 **/ /** to 08 nov 2001 **/ /** # Version 4.0 : from : 16 jan 2004 **/ /** to 14 nov 2005 **/ /** # Version 5.0 : from : 13 sep 2006 **/ /** to 27 feb 2008 **/ /** # Version 5.1 : from : 11 aug 2010 **/ /** to 11 aug 2010 **/ /** # Version 6.0 : from : 03 mar 2011 **/ /** to 22 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define MAPPING_IO #include "module.h" #include "common.h" #include "graph.h" #include "arch.h" #include "mapping.h" #include "mapping_io.h" /***********************************/ /* */ /* These routines handle mappings. */ /* */ /***********************************/ /* This routine reads the contents of the given mapping ** file to the given mapping, reordering vertices ** according to the given vertex label table if necessary. ** It returns: ** - 0 : if mapping successfully written. ** - 1 : on error. ** - 2 : variable-sized architectures cannot be loaded. */ /* TODO remove it */ int /* TODO copy the one from gout? */ mapLoad ( Mapping * restrict const mappptr, const Gnum * restrict const vlbltab, FILE * restrict const stream) { Gnum vertnum; Gnum mappnum; Gnum mappnbr; MappingLoadMap * mapptab; /* Mapping array */ MappingLoadPerm * permtab; /* Array of sorted label/index pairs */ Anum archnbr; /* Size of the target architecture */ ArchDom fdomdat; /* First domain of architecture */ if (strcmp (archName (mappptr->archptr), "term") == 0) /* If target architecture is variable-sized */ return (2); archDomFrst (mappptr->archptr, &fdomdat); /* Get architecture size */ archnbr = archDomSize (mappptr->archptr, &fdomdat); if (mappptr->domnmax < (archnbr + 1)) { /* If mapping array too small to store mapping data */ ArchDom * restrict domntab; if ((domntab = (ArchDom *) memRealloc (mappptr->domntab, (archnbr + 1) * sizeof (ArchDom))) == NULL) { /* If cannot resize domain array */ errorPrint ("mapLoad: out of memory (1)"); return (1); } mappptr->domnmax = archnbr + 1; /* Point to new array */ mappptr->domntab = domntab; } mappptr->domnnbr = archnbr + 1; /* One more for first domain, for unmapped vertices */ archDomFrst (mappptr->archptr, &mappptr->domntab[0]); /* Set first domain with root domain data */ for (mappnum = 0; mappnum < archnbr; mappnum ++) /* For all terminal domain numbers */ archDomTerm (mappptr->archptr, &mappptr->domntab[mappnum + 1], mappnum); /* Set domain with terminal domain data */ if ((intLoad (stream, &mappnbr) != 1) || /* Read number of mapping entries */ (mappnbr < 1)) { errorPrint ("mapLoad: bad input (1)"); return (1); } if (memAllocGroup ((void **) (void *) &mapptab, (size_t) (mappnbr * sizeof (MappingLoadMap)), &permtab, (size_t) (mappptr->grafptr->vertnbr * sizeof (MappingLoadPerm)), NULL) == NULL) { errorPrint ("mapLoad: out of memory (2)"); return (1); } for (mappnum = 0; mappnum < mappnbr; mappnum ++) { /* Load mapping array */ if ((intLoad (stream, &mapptab[mappnum].slblnum) != 1) || (intLoad (stream, &mapptab[mappnum].tlblnum) != 1)) { errorPrint ("mapLoad: bad input (2)"); return (1); } } intSort2asc1 (mapptab, mappnbr); /* Sort mapping array by increasing source labels */ if (vlbltab != NULL) { /* If graph has vertex labels */ Gnum vertnum; for (vertnum = 0; vertnum < mappptr->grafptr->vertnbr; vertnum ++) { /* Build inverse permutation */ permtab[vertnum].vertnum = vertnum + mappptr->grafptr->baseval; permtab[vertnum].vlblnum = vlbltab[vertnum]; } intSort2asc1 (permtab, mappptr->grafptr->vertnbr); /* Sort vertex array by increasing labels */ } else { Gnum vertnum; for (vertnum = 0; vertnum < mappptr->grafptr->vertnbr; vertnum ++) { /* Build identity permutation */ permtab[vertnum].vertnum = vertnum + mappptr->grafptr->baseval; permtab[vertnum].vlblnum = vertnum + mappptr->grafptr->baseval; } } for (vertnum = 0, mappnum = 0; /* For all graph vertices */ vertnum < mappptr->grafptr->vertnbr; vertnum ++) { while ((mappnum < mappnbr) && /* Skip useless mapping data (if graph is subgraph of originally mapped graph) */ (permtab[vertnum].vlblnum > mapptab[mappnum].slblnum)) mappnum ++; if (mappnum >= mappnbr) /* If all mapping data exhausted */ break; /* Exit the matching loop */ if (permtab[vertnum].vlblnum == mapptab[mappnum].slblnum) { /* If matching mapping data found */ if ((mapptab[mappnum].tlblnum >= 0) && /* If mapping valid */ (mapptab[mappnum].tlblnum < archnbr)) mappptr->parttax[permtab[vertnum].vertnum] = mapptab[mappnum].tlblnum + 1; /* Set mapping to terminal domain */ mappnum ++; /* Mapping pair has been used */ } } memFree (mapptab); /* Free group leader */ return (0); } /* This routine writes the contents of the ** given mapping to the given string. ** It returns: ** - 0 : if mapping successfully written. ** - !0 : on error. */ int mapSave ( const Mapping * restrict const mappptr, FILE * restrict const stream) { Gnum vertnnd; Gnum vertnum; const Arch * restrict const archptr = mappptr->archptr; const ArchDom * restrict const domntab = mappptr->domntab; const Anum * restrict const parttax = mappptr->parttax; const Gnum * restrict const vlbltax = mappptr->grafptr->vlbltax; vertnum = mappptr->grafptr->baseval; vertnnd = mappptr->grafptr->vertnbr; /* Un-based number at first */ if (fprintf (stream, GNUMSTRING "\n", (Gnum) vertnnd) == EOF) { errorPrint ("mapSave: bad output (1)"); return (1); } for (vertnnd += vertnum; vertnum < vertnnd; vertnum ++) { if (fprintf (stream, GNUMSTRING "\t" ANUMSTRING "\n", (Gnum) ((vlbltax != NULL) ? vlbltax[vertnum] : vertnum), (Anum) (parttax != NULL) ? archDomNum (archptr, &domntab[parttax[vertnum]]) : -1) == EOF) { errorPrint ("mapSave: bad output (2)"); return (1); } } return (0); } scotch-6.0.4.dfsg/src/libscotch/kgraph_map_cp.c0000644002563400244210000001007612376151352024602 0ustar trophimeutilisateurs du domaine/* Copyright 2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph_map_cp.c **/ /** **/ /** AUTHOR : Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This method copies a given old mapping **/ /** as a mapping result. **/ /** **/ /** DATES : # Version 6.0 : from : 16 jan 2012 **/ /** to 23 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define KGRAPH_MAP_CP #include "module.h" #include "common.h" #include "graph.h" #include "arch.h" #include "mapping.h" #include "parser.h" #include "kgraph.h" #include "kgraph_map_cp.h" #include "kgraph_map_st.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the k-way partitioning. ** It returns: ** - 0 : if k-partition could be computed. ** - 1 : on error. */ /* TODO handle the case when the old and the new architectures are differents. */ int kgraphMapCp ( Kgraph * restrict const grafptr) /*+ Graph +*/ { Gnum baseval; Anum domnnbr; const Anum * restrict const pfixtax = grafptr->pfixtax; if (grafptr->r.m.parttax == NULL) { /* If we do not have an old partition */ errorPrint ("kgraphMapCp: inconsistent old mapping data"); return (1); } baseval = grafptr->s.baseval; if (mapCopy (&grafptr->m, &grafptr->r.m) != 0) { errorPrint ("kgraphMapCp: cannot copy old mapping"); return (1); } if (pfixtax != NULL) { /* If we have fixed vertices */ if (mapMerge (&grafptr->m, pfixtax) != 0) { errorPrint ("kgraphMapCp: cannot merge with fixed vertices"); return (1); } } kgraphFron (grafptr); kgraphCost (grafptr); #ifdef SCOTCH_DEBUG_KGRAPH2 if (kgraphCheck (grafptr) != 0) { errorPrint ("kgraphMapCp: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/vmesh_separate_zr.c0000644002563400244210000000620611631447171025530 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vgraph_separate_zr.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module moves all of the vertices **/ /** to the first subdomain. **/ /** **/ /** DATES : # Version 4.0 : from : 10 sep 2002 **/ /** to 29 may 2004 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VMESH_SEPARATE_ZR #include "module.h" #include "common.h" #include "graph.h" #include "mesh.h" #include "vmesh.h" #include "vmesh_separate_zr.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine moves all of the mesh nodes ** and elements to the first part of the ** partition. ** It returns: ** - 0 : if the bipartitioning could be computed. ** - !0 : on error. */ int vmeshSeparateZr ( Vmesh * restrict const meshptr) { if (meshptr->ncmpload[0] != meshptr->m.vnlosum) /* If not all vertices already in part zero */ vmeshZero (meshptr); return (0); } scotch-6.0.4.dfsg/src/libscotch/library_mesh_graph.c0000644002563400244210000000623411631447171025651 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_mesh_graph.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the Scotch **/ /** mesh-to-graph converter. **/ /** **/ /** DATES : # Version 4.0 : from : 21 jan 2004 **/ /** to 21 jan 2004 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "graph.h" #include "mesh.h" #include "scotch.h" /*************************************/ /* */ /* These routines are the C API for */ /* the Scotch graph and geometry */ /* handling routines. */ /* */ /*************************************/ /*+ This routine loads the given opaque graph *** structure with the data of the given stream. *** - 0 : if loading succeeded. *** - !0 : on error. +*/ int SCOTCH_meshGraph ( const SCOTCH_Mesh * restrict const meshptr, SCOTCH_Graph * restrict const grafptr) { return (meshGraph ((Mesh *) meshptr, (Graph *) grafptr)); } scotch-6.0.4.dfsg/src/libscotch/vdgraph_separate_sq.h0000644002563400244210000000606511631447170026040 0ustar trophimeutilisateurs du domaine/* Copyright 2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vdgraph_separate_sq.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the sequential vertex separation **/ /** routine for distributed graphs. **/ /** **/ /** DATES : # Version 5.0 : from : 15 feb 2006 **/ /** to : 01 mar 2006 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct VdgraphSeparateSqParam_ { Strat * strat; /*+ Sequential separation strategy used +*/ } VdgraphSeparateSqParam; /* ** The function prototypes. */ #ifndef VDGRAPH_SEPARATE_SQ #define static #endif int vdgraphSeparateSq (Vdgraph * const, const VdgraphSeparateSqParam * const); static void vdgraphSeparateSqOpBest (const Gnum * const, Gnum * const, const int * const, const MPI_Datatype * const); #undef static scotch-6.0.4.dfsg/src/libscotch/wgraph_part_st.c0000644002563400244210000003125211631447170025031 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : wgraph_part_st.c **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Charles-Edmond BICHOT (v5.1b) **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module contains the global **/ /** vertex overlapped graph partitioning **/ /** strategy and method tables. **/ /** **/ /** DATES : # Version 5.1 : from : 01 dec 2007 **/ /** to : 01 jul 2008 **/ /** # Version 6.0 : from : 05 nov 2009 **/ /** to 16 apr 2011 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define WGRAPH_PART_ST #include "module.h" #include "common.h" #include "gain.h" #include "parser.h" #include "graph.h" #include "arch.h" #include "mapping.h" #include "graph_coarsen.h" #include "vgraph.h" #include "vgraph_separate_st.h" #include "wgraph.h" #include "wgraph_part_fm.h" #include "wgraph_part_gg.h" #include "wgraph_part_gp.h" #include "wgraph_part_ml.h" #include "wgraph_part_rb.h" #include "wgraph_part_st.h" #include "wgraph_part_zr.h" /* ** The static and global variables. */ static Wgraph wgraphdummy; /* Dummy overlap graph for offset computations */ static union { WgraphPartFmParam param; StratNodeMethodData padding; } wgraphpartdefaultfm = { { 10, 40, 0.1L } }; static union { WgraphPartGgParam param; StratNodeMethodData padding; } wgraphpartdefaultgg = { { 10 } }; static union { WgraphPartGpParam param; StratNodeMethodData padding; } wgraphpartdefaultgp = { { 5 } }; static union { WgraphPartMlParam param; StratNodeMethodData padding; } wgraphpartdefaultml = { { 20, 0.8L, &stratdummy, &stratdummy } }; static union { WgraphPartRbParam param; StratNodeMethodData padding; } wgraphpartdefaultrb = { { &stratdummy } }; static StratMethodTab wgraphpartstmethtab[] = { /* Graph overlap partitioning methods array */ { WGRAPHSEPASTMETHGG, "h", wgraphPartGg, &wgraphpartdefaultgg }, { WGRAPHSEPASTMETHGP, "g", wgraphPartGp, &wgraphpartdefaultgp }, { WGRAPHSEPASTMETHFM, "f", wgraphPartFm, &wgraphpartdefaultfm }, { WGRAPHSEPASTMETHML, "m", wgraphPartMl, &wgraphpartdefaultml }, { WGRAPHSEPASTMETHRB, "r", wgraphPartRb, &wgraphpartdefaultrb }, { WGRAPHSEPASTMETHZR, "z", wgraphPartZr, NULL }, { -1, NULL, NULL, NULL } }; static StratParamTab wgraphpartstparatab[] = { /* Method parameter list */ { WGRAPHSEPASTMETHFM, STRATPARAMINT, "pass", (byte *) &wgraphpartdefaultfm.param, (byte *) &wgraphpartdefaultfm.param.passnbr, NULL }, { WGRAPHSEPASTMETHFM, STRATPARAMINT, "move", (byte *) &wgraphpartdefaultfm.param, (byte *) &wgraphpartdefaultfm.param.movenbr, NULL }, { WGRAPHSEPASTMETHFM, STRATPARAMDOUBLE, "bal", (byte *) &wgraphpartdefaultfm.param, (byte *) &wgraphpartdefaultfm.param.deltrat, NULL }, { WGRAPHSEPASTMETHGG, STRATPARAMINT, "pass", (byte *) &wgraphpartdefaultgg.param, (byte *) &wgraphpartdefaultgg.param.passnbr, NULL }, { WGRAPHSEPASTMETHGP, STRATPARAMINT, "pass", (byte *) &wgraphpartdefaultgp.param, (byte *) &wgraphpartdefaultgp.param.passnbr, NULL }, { WGRAPHSEPASTMETHML, STRATPARAMSTRAT, "asc", (byte *) &wgraphpartdefaultml.param, (byte *) &wgraphpartdefaultml.param.stratasc, (void *) &wgraphpartststratab }, { WGRAPHSEPASTMETHML, STRATPARAMSTRAT, "low", (byte *) &wgraphpartdefaultml.param, (byte *) &wgraphpartdefaultml.param.stratlow, (void *) &wgraphpartststratab }, { WGRAPHSEPASTMETHML, STRATPARAMINT, "vert", (byte *) &wgraphpartdefaultml.param, (byte *) &wgraphpartdefaultml.param.coarnbr, NULL }, { WGRAPHSEPASTMETHML, STRATPARAMDOUBLE, "rat", (byte *) &wgraphpartdefaultml.param, (byte *) &wgraphpartdefaultml.param.coarval, NULL }, { WGRAPHSEPASTMETHRB, STRATPARAMSTRAT, "sep", (byte *) &wgraphpartdefaultrb.param, (byte *) &wgraphpartdefaultrb.param.stratptr, (void *) &vgraphseparateststratab }, { WGRAPHSEPASTMETHNBR, STRATPARAMINT, NULL, NULL, NULL, NULL } }; static StratParamTab wgraphpartstcondtab[] = { /* Overlap graph condition parameter table*/ { STRATNODENBR, STRATPARAMINT, NULL, NULL, NULL, NULL } }; StratTab wgraphpartststratab = { /* Strategy tables for overlap partitioning methods */ wgraphpartstmethtab, wgraphpartstparatab, wgraphpartstcondtab }; /*********************************************/ /* */ /* This is the generic partitioning routine. */ /* */ /*********************************************/ /* This routine computes the separation of ** the given graph according to the given ** strategy. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int wgraphPartSt ( Wgraph * restrict const grafptr, /*+ Overlap partitioning graph +*/ const Strat * restrict const strat) /*+ Overlap partitioning strategy +*/ { StratTest val; /* Result of condition evaluation */ WgraphStore savetab[2]; /* Results of the two strategies */ int o; int o2; #ifdef SCOTCH_DEBUG_WGRAPH2 if (sizeof (Gnum) != sizeof (INT)) { errorPrint ("wgraphPartSt: invalid type specification for parser variables"); return (1); } if ((sizeof (WgraphPartFmParam) > sizeof (StratNodeMethodData)) || (sizeof (WgraphPartGgParam) > sizeof (StratNodeMethodData)) || (sizeof (WgraphPartGpParam) > sizeof (StratNodeMethodData)) || (sizeof (WgraphPartMlParam) > sizeof (StratNodeMethodData)) || (sizeof (WgraphPartRbParam) > sizeof (StratNodeMethodData))) { errorPrint ("wgraphPartSt: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_WGRAPH2 */ #ifdef SCOTCH_DEBUG_WGRAPH1 if ((strat->tabl != &wgraphpartststratab) && (strat != &stratdummy)) { errorPrint ("wgraphPartSt: invalid parameter (1)"); return (1); } #endif /* SCOTCH_DEBUG_WGRAPH1 */ o = 0; switch (strat->type) { case STRATNODECONCAT : o = wgraphPartSt (grafptr, strat->data.concat.strat[0]); /* Apply the first strategy */ if (o == 0) /* If it worked all right */ o |= wgraphPartSt (grafptr, strat->data.concat.strat[1]); /* Then apply second strategy */ break; case STRATNODECOND : o = stratTestEval (strat->data.cond.test, &val, (void *) grafptr); /* Evaluate expression */ if (o == 0) { /* If evaluation was correct */ #ifdef SCOTCH_DEBUG_WGRAPH2 if ((val.typetest != STRATTESTVAL) || (val.typenode != STRATPARAMLOG)) { errorPrint ("wgraphPartSt: invalid test result"); o = 1; break; } #endif /* SCOTCH_DEBUG_WGRAPH2 */ if (val.data.val.vallog == 1) /* If expression is true */ o = wgraphPartSt (grafptr, strat->data.cond.strat[0]); /* Apply first strategy */ else { /* Else if expression is false */ if (strat->data.cond.strat[1] != NULL) /* And if there is an else statement */ o = wgraphPartSt (grafptr, strat->data.cond.strat[1]); /* Apply second strategy */ } } break; case STRATNODEEMPTY : break; case STRATNODESELECT : if (((wgraphStoreInit (grafptr, &savetab[0])) != 0) || /* Allocate save areas */ ((wgraphStoreInit (grafptr, &savetab[1])) != 0)) { errorPrint ("wgraphPartSt: out of memory"); wgraphStoreExit (&savetab[0]); return (1); } wgraphStoreSave (grafptr, &savetab[1]); /* Save initial partition */ o = wgraphPartSt (grafptr, strat->data.select.strat[0]); /* Apply first strategy */ wgraphStoreSave (grafptr, &savetab[0]); /* Save its result */ wgraphStoreUpdt (grafptr, &savetab[1]); /* Restore initial partition */ o2 = wgraphPartSt (grafptr, strat->data.select.strat[1]); /* Apply second strategy */ if ((o == 0) || (o2 == 0)) { /* If at least one method make a k-partition */ if (savetab[0].fronload < grafptr->fronload) /* If first strategy is better */ wgraphStoreUpdt (grafptr, &savetab[0]); /* Restore its result */ } wgraphStoreExit (&savetab[0]); /* Free both save areas */ wgraphStoreExit (&savetab[1]); break; #ifdef SCOTCH_DEBUG_WGRAPH2 case STRATNODEMETHOD : #else /* SCOTCH_DEBUG_WGRAPH2 */ default : #endif /* SCOTCH_DEBUG_WGRAPH2 */ return (strat->tabl->methtab[strat->data.method.meth].func (grafptr, (void *) &strat->data.method.data)); #ifdef SCOTCH_DEBUG_WGRAPH2 default : errorPrint ("wgraphPartSt: invalid parameter (2)"); return (1); #endif /* SCOTCH_DEBUG_WGRAPH2 */ } return (o); } scotch-6.0.4.dfsg/src/libscotch/library_dgraph_check.c0000644002563400244210000000641112056000332026115 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_check.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the source **/ /** graph handling routines of the **/ /** libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 26 aug 2006 **/ /** to 26 aug 2006 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "dgraph.h" #include "ptscotch.h" /************************************/ /* */ /* These routines are the C API for */ /* the distributed graph handling */ /* routines. */ /* */ /************************************/ /*+ This routine checks the consistency *** of the given graph. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_dgraphCheck ( const SCOTCH_Dgraph * const grafptr) { return (dgraphCheck ((const Dgraph * const) grafptr)); } scotch-6.0.4.dfsg/src/libscotch/arch_vcmplt.c0000644002563400244210000002205612377071670024317 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : arch_vcmplt.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module handles the variable-sized **/ /** complete graph target architecture. **/ /** **/ /** DATES : # Version 0.0 : from : 01 dec 1992 **/ /** to : 24 mar 1993 **/ /** # Version 1.2 : from : 04 feb 1994 **/ /** to : 11 feb 1994 **/ /** # Version 1.3 : from : 20 apr 1994 **/ /** to : 20 apr 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to : 23 dec 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to : 29 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 16 aug 1995 **/ /** # Version 3.1 : from : 20 jul 1996 **/ /** to 20 jul 1996 **/ /** # Version 3.2 : from : 15 oct 1996 **/ /** to 14 may 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 3.4 : from : 14 sep 2001 **/ /** to 08 nov 2001 **/ /** # Version 4.0 : from : 05 nov 2003 **/ /** to 05 nov 2003 **/ /** # Version 5.1 : from : 21 jan 2008 **/ /** to 11 aug 2010 **/ /** # Version 6.0 : from : 14 fev 2011 **/ /** to 26 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define ARCH_VCMPLT #include "module.h" #include "common.h" #include "arch.h" #include "arch_vcmplt.h" /*****************************************/ /* */ /* These are the variable-sized complete */ /* graph handling routines. */ /* */ /*****************************************/ /* This function returns the smallest number ** of terminal domain included in the given ** domain. */ ArchDomNum archVcmpltDomNum ( const ArchVcmplt * const archptr, const ArchVcmpltDom * const domptr) { return (domptr->termnum); /* Return terminal number */ } /* This function returns the terminal domain associated ** with the given terminal number in the architecture. ** It returns: ** - 0 : if label is valid and domain has been updated. ** - 1 : if label is invalid. ** - 2 : on error. */ int archVcmpltDomTerm ( const ArchVcmplt * const archptr, ArchVcmpltDom * const domptr, const ArchDomNum domnum) { Anum termnum; Anum termlvl; if (domnum != ARCHDOMNOTTERM) { /* If valid label */ if (domnum == 0) /* Not a legal domain */ return (2); domptr->termnum = domnum; /* Set the domain */ for (termnum = domnum, termlvl = 0; termnum > 1; termnum >>= 1, termlvl ++) ; /* Compute level */ domptr->termlvl = termlvl; /* Set level */ return (0); } return (1); /* Cannot set domain */ } /* This function returns the number of ** elements in the domain. */ Anum archVcmpltDomSize ( const ArchVcmplt * const archptr, const ArchVcmpltDom * const domptr) { return (1); /* All domains have same size for bipartitioning */ } /* This function returns the average ** distance between two subdomains. */ Anum archVcmpltDomDist ( const ArchVcmplt * const archptr, const ArchVcmpltDom * const dom0ptr, const ArchVcmpltDom * const dom1ptr) { return ((dom0ptr->termnum == dom1ptr->termnum) ? 0 : 1); /* All distinct terminals are at distance 1 */ } /* This function sets the biggest ** domain available for this ** architecture. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archVcmpltDomFrst ( const ArchVcmplt * const archptr, ArchVcmpltDom * restrict const domptr) { domptr->termlvl = 0; /* First terminal number */ domptr->termnum = 1; return (0); } /* This routine reads domain information ** from the given stream. ** It returns: ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archVcmpltDomLoad ( const ArchVcmplt * const archptr, ArchVcmpltDom * restrict const domptr, FILE * const stream) { Anum termnum; Anum termlvl; if (intLoad (stream, &domptr->termnum) != 1) { errorPrint ("archVcmpltDomLoad: bad input"); return (1); } for (termnum = domptr->termnum, termlvl = 0; termnum > 1; termnum >>= 1, termlvl ++) ; /* Compute level */ domptr->termlvl = termlvl; return (0); } /* This routine saves domain information ** to the given stream. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archVcmpltDomSave ( const ArchVcmplt * const archptr, const ArchVcmpltDom * const domptr, FILE * const stream) { if (fprintf (stream, ANUMSTRING " ", (Anum) domptr->termnum) == EOF) { errorPrint ("archVcmpltDomSave: bad output"); return (1); } return (0); } /* This function splits a domain ** into two subdomains. ** It returns: ** - 0 : if bipartitioning succeeded. ** - 2 : on error. */ int archVcmpltDomBipart ( const ArchVcmplt * const archptr, const ArchVcmpltDom * const domptr, ArchVcmpltDom * restrict const dom0ptr, ArchVcmpltDom * restrict const dom1ptr) { dom0ptr->termlvl = /* Bipartition the domain */ dom1ptr->termlvl = domptr->termlvl + 1; dom0ptr->termnum = domptr->termnum << 1; dom1ptr->termnum = dom0ptr->termnum + 1; return ((dom1ptr->termnum < domptr->termnum) ? 2 : 0); /* Return error on overflow */ } /* This function checks if dom1 is ** included in dom0. ** It returns: ** - 0 : if dom1 is not included in dom0. ** - 1 : if dom1 is included in dom0. ** - 2 : on error. */ int archVcmpltDomIncl ( const ArchVcmplt * const archptr, const ArchVcmpltDom * const dom0ptr, const ArchVcmpltDom * const dom1ptr) { if ((dom1ptr->termlvl >= dom0ptr->termlvl) && ((dom1ptr->termnum >> (dom1ptr->termlvl - dom0ptr->termlvl)) == dom0ptr->termnum)) return (1); return (0); } /* This function creates the MPI_Datatype for ** variable-sized complete graph domains. ** It returns: ** - 0 : if type could be created. ** - 1 : on error. */ #ifdef SCOTCH_PTSCOTCH int archVcmpltDomMpiType ( const ArchVcmplt * const archptr, MPI_Datatype * const typeptr) { MPI_Type_contiguous (2, ANUM_MPI, typeptr); return (0); } #endif /* SCOTCH_PTSCOTCH */ scotch-6.0.4.dfsg/src/libscotch/dorder.h0000644002563400244210000002427011631447170023273 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dorder.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data **/ /** declarations for the generic **/ /** distributed ordering structure. **/ /** **/ /** DATES : # Version 5.0 : from : 15 apr 2006 **/ /** to 14 oct 2007 **/ /** # Version 5.1 : from : 28 nov 2007 **/ /** to 04 nov 2010 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ Tag for MPI communications. +*/ #define DORDERTAGPERI 0 /*+ Column block separation tree cell flags. The DORDERCBLKNEDI value must correspond to a single bit and be equal to the ORDERCBLKNEDI value. +*/ #define DORDERCBLKNONE 0x0000 /*+ Not yet assigned +*/ #define DORDERCBLKNEDI 0x0001 /*+ Nested dissection separator node +*/ #define DORDERCBLKLEAF 0x0002 /*+ Distributed leaf +*/ /* ** The type and structure definitions. */ /*+ Distributed index of column block tree cell. +*/ typedef struct DorderIndex_ { int proclocnum; /*+ Number of this process +*/ Gnum cblklocnum; /*+ Local index of column block +*/ } DorderIndex; /*+ Link structure to double-chain all column blocks into the distributed ordering structure. Nodes are inserted at end of list such that a simple traversal gives nodes in ascending creation order, which is essential for locally-rooted nodes when gathering them on a centralized ordering. +*/ typedef struct DorderLink_ { struct DorderLink_ * nextptr; /*+ Pointer to previous column block +*/ struct DorderLink_ * prevptr; /*+ Pointer to next column block +*/ } DorderLink; /*+ Centralized column block node. +*/ typedef struct DorderNode_ { Gnum fathnum; /*+ Number of father in centralized node array +*/ int typeval; /*+ Centralized type of tree node +*/ Gnum vnodnbr; /*+ Number of nodes in this column block +*/ Gnum cblknum; /*+ Rank of column block in father column block array +*/ } DorderNode; /*+ Distributed column-block tree cell. Each cell defines a distributed column block, which is either a nested dissection node, with its two subgraphs and its separator, or a leaf. Leaves which are located on a single process can be nested dissection sequential nodes, with the sequential tree folded as a node array. Column blocks are given in ascending order within all sub-arrays, for proper infix traversal. +*/ typedef struct DorderCblk_ { DorderLink linkdat; /*+ Link to other blocks. TRICK: FIRST +*/ struct Dorder_ * ordelocptr; /*+ Pointer to local distributed ordering +*/ int typeval; /*+ Distributed type of tree node +*/ DorderIndex fathnum; /*+ Master index of parent column block +*/ DorderIndex cblknum; /*+ Master index of this column block +*/ Gnum ordeglbval; /*+ Un-based starting index of inverse permutation +*/ Gnum vnodglbnbr; /*+ Number of node vertices in subtree +*/ Gnum cblkfthnum; /*+ Rank of node in father column block array +*/ union { struct { /*+ Fragment of inverse permutation +*/ Gnum ordelocval; /*+ Starting index of inverse permutation +*/ Gnum vnodlocnbr; /*+ Number of node vertices in fragment +*/ Gnum * periloctab; /*+ Pointer to inverse permutation fragment +*/ Gnum nodelocnbr; /*+ Number of local column blocks +*/ DorderNode * nodeloctab; /*+ Array of local column blocks +*/ Gnum cblklocnum; /*+ Local number of first local column block +*/ } leaf; struct { /*+ Fragment of inverse permutation +*/ Gnum cblkglbnbr; /*+ Number of descendent nodes (2 or 3) +*/ } nedi; } data; } DorderCblk; /*+ Distributed ordering structure. A distributed block ordering is defined by fragments of its inverse permutation, distributed across all of the participating processes. For the sake of consistency between orderings that have been produced either from graphs or meshes, whether centralized or distributed, all ordering values are based from baseval. +*/ typedef struct Dorder_ { Gnum baseval; /*+ Base value for structures +*/ Gnum vnodglbnbr; /*+ Global number of node vertices +*/ Gnum cblklocnbr; /*+ Local number of unique locally-rooted distributed and sequential column blocks +*/ DorderLink linkdat; /*+ Link to column blocks +*/ MPI_Comm proccomm; /*+ Ordering global communicator +*/ int proclocnum; /*+ Rank of this process in the communicator +*/ #ifdef SCOTCH_PTHREAD pthread_mutex_t mutelocdat; /*+ Local mutex for counter and link updates +*/ #endif /* SCOTCH_PTHREAD */ } Dorder; /* ** The function prototypes. */ #ifndef DORDER #define static #endif int dorderInit (Dorder * const, const Gnum, const Gnum, MPI_Comm); void dorderExit (Dorder * const); void dorderFree (Dorder * const); #ifdef DGRAPH_H int dorderPerm (const Dorder * const, const Dgraph * const, Gnum * const); int dorderSave (const Dorder * const, const Dgraph * const, FILE * const); int dorderSaveBlock (const Dorder * const, const Dgraph * const, FILE * const); int dorderSaveMap (const Dorder * const, const Dgraph * const, FILE * const); int dorderSaveTree (const Dorder * const, const Dgraph * const, FILE * const); #ifdef ORDER_H int dorderSaveTree2 (const Dorder * restrict const, const Dgraph * restrict const, FILE * restrict const, int (*) (const Order * const, const Gnum * const, FILE * const)); #endif /* ORDER_H */ #endif /* DGRAPH_H */ Gnum dorderCblkDist (const Dorder * restrict const); int dorderTreeDist (const Dorder * restrict const, const Dgraph * restrict const, Gnum * restrict const, Gnum * restrict const); #ifdef ORDER_H int dorderGather (const Dorder * const, Order * const); int dorderGatherTree (const Dorder * const, Order * const, const int); #endif /* ORDER_H */ DorderCblk * dorderFrst (Dorder * const); DorderCblk * dorderNew (DorderCblk * const, MPI_Comm); DorderCblk * dorderNewSequ (DorderCblk * const); Gnum dorderNewSequIndex (DorderCblk * const, const Gnum); void dorderDispose (DorderCblk * const); #undef static scotch-6.0.4.dfsg/src/libscotch/arch_hcub.c0000644002563400244210000002417212354555656023742 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : arch_hcub.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module handles the hypercube **/ /** target architecture. **/ /** **/ /** DATES : # Version 0.0 : from : 01 dec 1992 **/ /** to : 24 mar 1993 **/ /** # Version 1.2 : from : 04 feb 1994 **/ /** to : 11 feb 1994 **/ /** # Version 1.3 : from : 20 apr 1994 **/ /** to : 20 apr 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to : 23 dec 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to : 29 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 08 sep 1995 **/ /** # Version 3.1 : from : 11 jun 1996 **/ /** to 11 jun 1996 **/ /** # Version 3.2 : from : 21 sep 1996 **/ /** to 14 may 1998 **/ /** # Version 4.0 : from : 11 nov 2003 **/ /** to 10 mar 2005 **/ /** # Version 5.1 : from : 21 jan 2008 **/ /** to 11 aug 2010 **/ /** # Version 6.0 : from : 14 fev 2011 **/ /** to 14 fev 2011 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define ARCH_HCUB #include "module.h" #include "common.h" #include "arch.h" #include "arch_hcub.h" /********************************************/ /* */ /* These are the binary hypercube routines. */ /* */ /********************************************/ /* This routine loads the binary ** hypercube architecture. ** It returns: ** - 0 : if the architecture has been successfully read. ** - !0 : on error. */ int archHcubArchLoad ( ArchHcub * restrict const archptr, FILE * restrict const stream) { #ifdef SCOTCH_DEBUG_ARCH1 if ((sizeof (ArchHcub) > sizeof (ArchDummy)) || (sizeof (ArchHcubDom) > sizeof (ArchDomDummy))) { errorPrint ("archHcubArchLoad: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ if ((intLoad (stream, &archptr->dimmax) != 1) || (archptr->dimmax < 1) || (archptr->dimmax > (sizeof (archptr->dimmax) << 3))) { errorPrint ("archHcubArchLoad: bad input"); return (1); } return (0); } /* This routine saves the ** binary hypercube architecture. ** It returns: ** - 0 : if the architecture has been successfully written. ** - !0 : on error. */ int archHcubArchSave ( const ArchHcub * const archptr, FILE * restrict const stream) { #ifdef SCOTCH_DEBUG_ARCH1 if ((sizeof (ArchHcub) > sizeof (ArchDummy)) || (sizeof (ArchHcubDom) > sizeof (ArchDomDummy))) { errorPrint ("archHcubArchSave: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ if (fprintf (stream, ANUMSTRING " ", (Anum) archptr->dimmax) == EOF) { errorPrint ("archHcubArchSave: bad output"); return (1); } return (0); } /* This function returns the smallest number ** of terminal domain included in the given ** domain. */ ArchDomNum archHcubDomNum ( const ArchHcub * const archptr, const ArchHcubDom * const domptr) { return (domptr->bitset); /* Return vertex number */ } /* This function returns the terminal domain associated ** with the given terminal number in the architecture. ** It returns: ** - 0 : if label is valid and domain has been updated. ** - 1 : if label is invalid. ** - 2 : on error. */ int archHcubDomTerm ( const ArchHcub * const archptr, ArchHcubDom * const domptr, const ArchDomNum domnum) { if (domnum < (1 << archptr->dimmax)) { /* If valid label */ domptr->dimcur = 0; /* Set the domain */ domptr->bitset = domnum; return (0); } return (1); /* Cannot set domain */ } /* This function returns the number of ** elements in the hypercube domain. */ Anum archHcubDomSize ( const ArchHcub * const archptr, const ArchHcubDom * const domptr) { return (1 << domptr->dimcur); } /* This function returns the average distance ** between two sub-hypercubes. */ Anum archHcubDomDist ( const ArchHcub * const archptr, const ArchHcubDom * const dom0ptr, const ArchHcubDom * const dom1ptr) { Anum i, j, k; if (dom0ptr->dimcur > dom1ptr->dimcur) { /* Get smallest set dimension value */ i = dom0ptr->dimcur; j = i - dom1ptr->dimcur; } else { i = dom1ptr->dimcur; j = i - dom0ptr->dimcur; } j /= 2; /* For set/unset bits, assume 1/2 difference */ for (k = (dom0ptr->bitset ^ dom1ptr->bitset) >> i, i = archptr->dimmax - i; i > 0; k >>= 1, i --) j += (k & 1); /* Add Hamming difference on set dimensions */ return (j); } /* This function sets the biggest ** domain available for this ** architecture. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archHcubDomFrst ( const ArchHcub * const archptr, ArchHcubDom * restrict const domptr) { domptr->dimcur = archptr->dimmax; domptr->bitset = 0; return (0); } /* This routine reads domain information ** from the given stream. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archHcubDomLoad ( const ArchHcub * const archptr, ArchHcubDom * restrict const domptr, FILE * restrict const stream) { if ((intLoad (stream, &domptr->dimcur) != 1) || (intLoad (stream, &domptr->bitset) != 1) || (domptr->dimcur > archptr->dimmax)) { errorPrint ("archHcubDomLoad: bad input"); return (1); } return (0); } /* This routine saves domain information ** to the given stream. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archHcubDomSave ( const ArchHcub * const archptr, const ArchHcubDom * const domptr, FILE * restrict const stream) { if (fprintf (stream, ANUMSTRING " " ANUMSTRING " ", (Anum) domptr->dimcur, (Anum) domptr->bitset) == EOF) { errorPrint ("archHcubDomSave: bad output"); return (1); } return (0); } /* This function tries to split a hypercube ** domain into two subdomains. ** It returns: ** - 0 : if bipartitioning succeeded. ** - 1 : if bipartitioning could not be performed. ** - 2 : on error. */ int archHcubDomBipart ( const ArchHcub * const archptr, const ArchHcubDom * const domptr, ArchHcubDom * restrict const dom0ptr, ArchHcubDom * restrict const dom1ptr) { if (domptr->dimcur <= 0) /* Return if cannot bipartition more */ return (1); dom0ptr->dimcur = dom1ptr->dimcur = domptr->dimcur - 1; dom0ptr->bitset = domptr->bitset; dom1ptr->bitset = domptr->bitset | (1 << dom1ptr->dimcur); return (0); } /* This function checks if dom1 is ** included in dom0. ** It returns: ** - 0 : if dom1 is not included in dom0. ** - 1 : if dom1 is included in dom0. ** - 2 : on error. */ int archHcubDomIncl ( const ArchHcub * const archptr, const ArchHcubDom * const dom0ptr, const ArchHcubDom * const dom1ptr) { if ((dom0ptr->dimcur >= dom1ptr->dimcur) && (((dom0ptr->bitset ^ dom1ptr->bitset) >> dom0ptr->dimcur) == 0)) return (1); return (0); } /* This function creates the MPI_Datatype for ** hypercube domains. ** It returns: ** - 0 : if type could be created. ** - 1 : on error. */ #ifdef SCOTCH_PTSCOTCH int archHcubDomMpiType ( const ArchHcub * const archptr, MPI_Datatype * const typeptr) { MPI_Type_contiguous (2, ANUM_MPI, typeptr); return (0); } #endif /* SCOTCH_PTSCOTCH */ scotch-6.0.4.dfsg/src/libscotch/kgraph_check.c0000644002563400244210000002264012405305024024406 0ustar trophimeutilisateurs du domaine/* Copyright 2010,2011,2013,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph_check.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module contains the mapping graph **/ /** consistency checking routine. **/ /** **/ /** DATES : # Version 5.1 : from : 13 jul 2010 **/ /** to 13 jul 2010 **/ /** # Version 6.0 : from : 03 mar 2011 **/ /** to 14 sep 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define KGRAPH #include "module.h" #include "common.h" #include "graph.h" #include "arch.h" #include "mapping.h" #include "kgraph.h" /*************************/ /* */ /* These routines handle */ /* mapping graphs. */ /* */ /*************************/ /* This routine checks the consistency ** of the given mapping graph. ** It returns: ** - 0 : if graph data are consistent. ** - !0 : on error. */ int kgraphCheck ( const Kgraph * restrict const grafptr) { int * restrict flagtax; /* Frontier flag array */ Gnum vertnum; /* Number of current vertex */ Gnum fronnum; /* Number of frontier vertex */ Gnum vfixnbr; /* Number of fixed vertices */ Gnum * restrict comploadtab; Gnum commload; Gnum edloval; Anum domnnum; int o; const Gnum baseval = grafptr->s.baseval; const Gnum vertnnd = grafptr->s.vertnnd; const Gnum * restrict const verttax = grafptr->s.verttax; const Gnum * restrict const vendtax = grafptr->s.vendtax; const Gnum * restrict const velotax = grafptr->s.velotax; const Gnum * restrict const edgetax = grafptr->s.edgetax; const Gnum * restrict const edlotax = grafptr->s.edlotax; const Anum * restrict const parttax = grafptr->m.parttax; const ArchDom * restrict const domntab = grafptr->m.domntab; const Arch * const archptr = grafptr->m.archptr; const Anum * restrict const pfixtax = grafptr->pfixtax; const Gnum * restrict const frontab = grafptr->frontab; if (&grafptr->s != grafptr->m.grafptr) { errorPrint ("kgraphCheck: invalid mapping graph"); return (1); } if ((grafptr->m.domnmax <= 0) || (grafptr->m.domnnbr > grafptr->m.domnmax) || (grafptr->m.domnnbr > grafptr->s.vertnbr)) { errorPrint ("kgraphCheck: invalid number of domains"); return (1); } if (memAllocGroup ((void **) (void *) &comploadtab, (size_t) (grafptr->m.domnnbr * sizeof (Gnum)), &flagtax, (size_t) (grafptr->s.vertnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("kgraphCheck: out of memory"); return (1); } memSet (comploadtab, 0, grafptr->m.domnnbr * sizeof (Gnum)); memSet (flagtax, ~0, grafptr->s.vertnbr * sizeof (Gnum)); flagtax -= baseval; o = 1; /* Assume failure when checking */ for (vertnum = baseval, vfixnbr = 0; vertnum < vertnnd; vertnum ++) { Anum partval; partval = parttax[vertnum]; if ((partval < 0) || (partval >= grafptr->m.domnnbr)) { errorPrint ("kgraphCheck: invalid part array"); goto fail; } if (pfixtax != NULL) { Anum pfixval; pfixval = pfixtax[vertnum]; if (pfixval != ~0) { if (pfixval < 0) { errorPrint ("kgraphCheck: invalid fixed part value"); goto fail; } if (pfixval != archDomNum (archptr, &grafptr->m.domntab[partval])) { errorPrint ("kgraphCheck: part index does not match fixed array"); goto fail; } vfixnbr ++; } } } if (vfixnbr != grafptr->vfixnbr) { errorPrint ("kgraphCheck: invalid number of fixed vertices"); goto fail; } if ((grafptr->fronnbr < 0) || (grafptr->fronnbr > grafptr->s.vertnbr)) { errorPrint ("kgraphCheck: invalid number of frontier vertices"); goto fail; } for (fronnum = 0; fronnum < grafptr->fronnbr; fronnum ++) { Gnum vertnum; Gnum edgenum; Anum partval; Anum flagval; vertnum = frontab[fronnum]; if ((vertnum < baseval) || (vertnum >= vertnnd)) { errorPrint ("kgraphCheck: invalid vertex index in frontier array"); goto fail; } if (flagtax[vertnum] != ~0) { errorPrint ("kgraphCheck: duplicate vertex in frontier array"); goto fail; } flagtax[vertnum] = 0; partval = parttax[vertnum]; for (edgenum = verttax[vertnum], flagval = 0; edgenum < vendtax[vertnum]; edgenum ++) flagval |= parttax[edgetax[edgenum]] ^ partval; /* Flag set if neighbor part differs from vertex part */ if (flagval == 0) { errorPrint ("kgraphCheck: invalid vertex in frontier array"); goto fail; } } commload = 0; edloval = 1; /* Assume edges are not weighted */ for (vertnum = baseval; vertnum < vertnnd; vertnum ++) { Anum partval; /* Part of current vertex */ Anum tdomnum; /* Terminal domain number of current vertex */ Anum tdfinum; /* Terminal domain number of current fixed vertex */ Gnum edgenum; /* Number of current edge */ Gnum commcut; partval = parttax[vertnum]; tdomnum = archDomNum (&grafptr->a, &grafptr->m.domntab[partval]); tdfinum = (grafptr->pfixtax != NULL) ? grafptr->pfixtax[vertnum] : -1; if ((tdfinum != -1) && /* If it is a fixed vertex */ (tdfinum != tdomnum)) { errorPrint ("kgraphCheck: invalid fixed vertex part"); goto fail; } comploadtab[partval] += (velotax == NULL) ? 1 : velotax[vertnum]; commcut = 0; for (edgenum = verttax[vertnum]; edgenum < vendtax[vertnum]; edgenum ++) { Anum partend; if (edlotax != NULL) edloval = edlotax[edgenum]; partend = parttax[edgetax[edgenum]]; if (partend == partval) /* If same part, no communication load */ continue; commcut += edloval * archDomDist (archptr, &domntab[partval], &domntab[partend]); /* Loads are accounted for twice */ } if ((commcut != 0) && (flagtax[vertnum] != 0)) { /* If vertex should be in frontier array */ errorPrint ("kgraphCheck: vertex should be in frontier array"); goto fail; } commload += commcut; } commload /= 2; if (commload != grafptr->commload) { errorPrint ("kgraphCheck: invalid communication load"); goto fail; } for (domnnum = 0; domnnum < grafptr->m.domnnbr; domnnum ++) { if (comploadtab[domnnum] != (grafptr->comploadavg[domnnum] + grafptr->comploaddlt[domnnum])) { errorPrint ("kgraphCheck: invalid computation load"); goto fail; } } o = 0; /* Everything turned well */ fail : memFree (comploadtab); /* Free group leader */ return (o); } scotch-6.0.4.dfsg/src/libscotch/vdgraph_check.c0000644002563400244210000002455511631447170024605 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vdgraph_check.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the distributed **/ /** separator graph consistency checking **/ /** routine. **/ /** **/ /** DATES : # Version 5.0 : from : 07 feb 2006 **/ /** to 01 mar 2008 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VDGRAPH #include "module.h" #include "common.h" #include "dgraph.h" #include "vdgraph.h" /*************************/ /* */ /* These routines handle */ /* separator graphs. */ /* */ /*************************/ /* This routine checks the consistency ** of the given distributed separator graph. ** It returns: ** - 0 : if graph data are consistent. ** - !0 : on error. */ int vdgraphCheck ( const Vdgraph * const grafptr) { Dgraph grafdat; /* Dummy graph for ghost edge array */ MPI_Comm proccomm; /* Graph communicator */ Gnum vertnum; /* Number of current vertex */ Gnum fronnum; /* Number of frontier vertex */ Gnum complocload[3]; Gnum complocsize[3]; Gnum commcut[3]; GraphPart * restrict partgsttax; Gnum reduloctab[11]; /* Arrays for reductions */ Gnum reduglbtab[11]; int cheklocval; /* Local consistency flag */ int chekglbval; /* Global consistency flag */ proccomm = grafptr->s.proccomm; if (MPI_Barrier (proccomm) != MPI_SUCCESS) { /* Synchronize */ errorPrint ("vdgraphCheck: communication error (1)"); return (1); } cheklocval = 0; /* Assume everything is all right */ if ((grafptr->compglbload[0] + grafptr->compglbload[1] + grafptr->compglbload[2]) != grafptr->s.veloglbsum) { errorPrint ("vdgraphCheck: invalid global load sum"); cheklocval = 1; } if (grafptr->compglbloaddlt != (grafptr->compglbload[0] - grafptr->compglbload[1])) { errorPrint ("vdgraphCheck: invalid global balance"); cheklocval |= 2; } if ((grafptr->compglbsize[0] + grafptr->compglbsize[1] + grafptr->compglbsize[2]) != grafptr->s.vertglbnbr) { errorPrint ("vdgraphCheck: invalid global size sum"); cheklocval |= 4; } if ((grafptr->complocsize[0] + grafptr->complocsize[1] + grafptr->complocsize[2]) != grafptr->s.vertlocnbr) { errorPrint ("vdgraphCheck: invalid local size sum"); cheklocval |= 8; } if ((grafptr->complocsize[2] < 0) || (grafptr->complocsize[2] > grafptr->s.vertlocnbr)) { errorPrint ("vdgraphCheck: invalid number of local frontier vertices"); cheklocval |= 16; } for (vertnum = grafptr->s.baseval; vertnum < grafptr->s.vertlocnnd; vertnum ++) { if (grafptr->partgsttax[vertnum] > 2) { errorPrint ("vdgraphCheck: invalid local part array"); cheklocval |= 32; break; } } for (fronnum = 0; fronnum < grafptr->complocsize[2]; fronnum ++) { Gnum vertnum; vertnum = grafptr->fronloctab[fronnum]; if ((vertnum < grafptr->s.baseval) || (vertnum >= grafptr->s.vertlocnnd)) { errorPrint ("vdgraphCheck: invalid vertex index in frontier array"); cheklocval |= 64; break; } if (grafptr->partgsttax[vertnum] != 2) { errorPrint ("vdgraphCheck: invalid vertex in frontier array"); cheklocval |= 64; break; } } grafdat = grafptr->s; /* Copy minimal distributed graph data */ if (dgraphGhst (&grafdat) != 0) { /* Create ghost edge array if did not exist */ errorPrint ("vdgraphCheck: cannot compute ghost edge array"); cheklocval |= 128; } if ((partgsttax = memAlloc (grafdat.vertgstnbr * sizeof (byte))) == NULL) { errorPrint ("vdgraphCheck: out of memory"); cheklocval |= 256; } reduloctab[0] = grafptr->compglbload[0]; reduloctab[1] = - grafptr->compglbload[0]; reduloctab[2] = grafptr->compglbload[1]; reduloctab[3] = - grafptr->compglbload[1]; reduloctab[4] = grafptr->compglbload[2]; reduloctab[5] = - grafptr->compglbload[2]; reduloctab[6] = grafptr->compglbsize[2]; reduloctab[7] = - grafptr->compglbsize[2]; reduloctab[8] = grafptr->levlnum; reduloctab[9] = - grafptr->levlnum; reduloctab[10] = cheklocval; if (MPI_Allreduce (reduloctab, reduglbtab, 11, GNUM_MPI, MPI_MAX, proccomm) != MPI_SUCCESS) { errorPrint ("vdgraphCheck: communication error (2)"); return (1); } if (reduglbtab[10] != 0) { /* Return from previous errors */ if (partgsttax != NULL) memFree (partgsttax); return (1); } if ((reduglbtab[1] != - reduglbtab[0]) || (reduglbtab[3] != - reduglbtab[2]) || (reduglbtab[5] != - reduglbtab[4]) || (reduglbtab[7] != - reduglbtab[6]) || (reduglbtab[9] != - reduglbtab[8])) { errorPrint ("vdgraphCheck: inconsistent global graph data"); return (1); } memCpy (partgsttax, grafptr->partgsttax + grafptr->s.baseval, grafptr->s.vertlocnbr); /* Copy local part data */ dgraphHaloSync (&grafdat, partgsttax, GRAPHPART_MPI); /* Spread yet unbased halo part data across neighboring processes */ partgsttax -= grafptr->s.baseval; complocload[0] = complocload[1] = complocload[2] = 0; complocsize[0] = complocsize[1] = complocsize[2] = 0; for (vertnum = grafptr->s.baseval; vertnum < grafptr->s.vertlocnnd; vertnum ++) { int partnum; /* Part of current vertex */ Gnum edgenum; /* Number of current edge */ partnum = (int) partgsttax[vertnum]; complocload[partnum] += (grafptr->s.veloloctax == NULL) ? 1 : grafptr->s.veloloctax[vertnum]; complocsize[partnum] ++; commcut[0] = commcut[1] = commcut[2] = 0; for (edgenum = grafptr->s.vertloctax[vertnum]; edgenum < grafptr->s.vendloctax[vertnum]; edgenum ++) { if (grafdat.edgegsttax[edgenum] < grafptr->s.vertlocnnd) /* Check only for local ends, as ghost part might be inaccurate */ commcut[partgsttax[grafdat.edgegsttax[edgenum]]] ++; } if (partnum != 2) { if (commcut[1 - partnum] != 0) { errorPrint ("vdgraphCheck: vertex should be in separator (%ld)", (long) vertnum); cheklocval = 1; break; } } } if (grafptr->s.edgegsttax != grafdat.edgegsttax) /* If ghost edge array was allocated here, free it manually */ memFree (grafdat.edgegsttax + grafptr->s.baseval); if (grafptr->s.procsidtab != grafdat.procsidtab) /* The same for procsidtab */ memFree (grafdat.procsidtab); memFree (partgsttax + grafptr->s.baseval); if ((cheklocval == 0) && ((complocsize[0] != grafptr->complocsize[0]) || (complocsize[1] != grafptr->complocsize[1]) || (complocsize[2] != grafptr->complocsize[2]))) { errorPrint ("vgraphCheck: invalid local part sizes"); cheklocval = 1; } reduloctab[0] = complocload[0]; reduloctab[1] = complocload[1]; reduloctab[2] = complocload[2]; reduloctab[3] = complocsize[0]; reduloctab[4] = complocsize[1]; reduloctab[5] = complocsize[2]; reduloctab[6] = cheklocval; if (MPI_Allreduce (reduloctab, reduglbtab, 7, GNUM_MPI, MPI_SUM, proccomm) != MPI_SUCCESS) { errorPrint ("vdgraphCheck: communication error (3)"); return (1); } if (reduglbtab[6] != 0) /* Return from previous errors */ return (1); if ((grafptr->compglbload[0] != reduglbtab[0]) || (grafptr->compglbload[1] != reduglbtab[1]) || (grafptr->compglbload[2] != reduglbtab[2])) { errorPrint ("vdgraphCheck: invalid global part loads"); cheklocval = 1; } if ((grafptr->compglbsize[0] != reduglbtab[3]) || (grafptr->compglbsize[1] != reduglbtab[4]) || (grafptr->compglbsize[2] != reduglbtab[5])) { errorPrint ("vgraphCheck: invalid global part sizes"); cheklocval = 1; } if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, proccomm) != MPI_SUCCESS) { errorPrint ("vdgraphCheck: communication error (4)"); return (1); } return (chekglbval); } scotch-6.0.4.dfsg/src/libscotch/hmesh_order_st.h0000644002563400244210000000742411631447170025023 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh_order_st.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data **/ /** declarations for the main halo mesh **/ /** ordering routine. **/ /** **/ /** DATES : # Version 4.0 : from : 28 sep 2002 **/ /** to : 08 feb 2004 **/ /** **/ /************************************************************/ /* ** The type definitions. */ /*+ Method types. +*/ typedef enum HmeshOrderStMethodType_ { HMESHORDERSTMETHBL = 0, /*+ Block splitting post-processing +*/ HMESHORDERSTMETHCP, /*+ Mesh compression +*/ HMESHORDERSTMETHGP, /*+ Gibbs-Poole-Stockmeyer +*/ HMESHORDERSTMETHGR, /*+ Graph-based ordering +*/ HMESHORDERSTMETHHD, /*+ Block Halo Approximate Minimum Degree +*/ HMESHORDERSTMETHHF, /*+ Block Halo Approximate Minimum Fill +*/ HMESHORDERSTMETHND, /*+ Nested Dissection +*/ HMESHORDERSTMETHSI, /*+ Simple +*/ HMESHORDERSTMETHNBR /*+ Number of methods +*/ } HmeshOrderStMethodType; /* ** The external declarations. */ extern StratTab hmeshorderststratab; /* ** The function prototypes. */ #ifndef HMESH_ORDER_ST #define static #endif int hmeshOrderSt (const Hmesh * restrict const, Order * restrict const, const Gnum, OrderCblk * restrict const, const Strat * const); #undef static scotch-6.0.4.dfsg/src/libscotch/bgraph_bipart_df.c0000644002563400244210000002767712371155772025310 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2011-2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bgraph_bipart_df.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module computes a bipartition of **/ /** a bipartition graph by using a **/ /** diffusion scheme. **/ /** **/ /** NOTES : # This algorithm has been designed to **/ /** work on band graphs only, for which **/ /** the two anchor vertices are the two **/ /** last vertices, the before-last as **/ /** anchor of part 0, and the last as **/ /** anchor of part 1. **/ /** **/ /** DATES : # Version 5.0 : from : 09 jan 2007 **/ /** to 10 sep 2007 **/ /** # Version 5.1 : from : 29 oct 2007 **/ /** to 27 mar 2011 **/ /** # Version 6.0 : from : 07 nov 2011 **/ /** to 08 aug 2013 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define BGRAPH_BIPART_DF #ifdef SCOTCH_PTHREAD #define BGRAPHBIPARTDFTHREAD #endif /* SCOTCH_PTHREAD */ #include "module.h" #include "common.h" #include "graph.h" #include "arch.h" #include "bgraph.h" #include "bgraph_bipart_df.h" /************************************/ /* */ /* The threaded reduction routines. */ /* */ /************************************/ #ifdef BGRAPHBIPARTDFTHREAD static void bgraphBipartDfReduceVanc ( BgraphBipartDfThread * restrict const tlocptr, /* Pointer to local thread */ void * restrict const vlocptr, /* Pointer to local value */ void * restrict const vremptr) /* Pointer to remote value */ { BgraphBipartDfThread * restrict const tremptr = (BgraphBipartDfThread *) vremptr; tlocptr->vanctab[0] += tremptr->vanctab[0]; /* Accumulate external gains */ tlocptr->vanctab[1] += tremptr->vanctab[1]; } static void bgraphBipartDfReduceVeex ( BgraphBipartDfThread * restrict const tlocptr, /* Pointer to local thread */ void * restrict const vlocptr, /* Pointer to local value */ void * restrict const vremptr) /* Pointer to remote value */ { BgraphBipartDfThread * restrict const tremptr = (BgraphBipartDfThread *) vremptr; tlocptr->veexsum += tremptr->veexsum; /* Accumulate external gains */ tlocptr->veexsum1 += tremptr->veexsum1; } #endif /* BGRAPHBIPARTDFTHREAD */ /********************************/ /* */ /* The sequential loop routine. */ /* */ /********************************/ #define BGRAPHBIPARTDFLOOPNAME bgraphBipartDfSeq #include "bgraph_bipart_df_loop.c" #undef BGRAPHBIPARTDFLOOPNAME /******************************/ /* */ /* The threaded loop routine. */ /* */ /******************************/ #ifdef BGRAPHBIPARTDFTHREAD #define BGRAPHBIPARTDFLOOPTHREAD #define BGRAPHBIPARTDFLOOPNAME bgraphBipartDfThr #include "bgraph_bipart_df_loop.c" #undef BGRAPHBIPARTDFLOOPNAME #undef BGRAPHMAPARTDFLOOPTHREAD #endif /* BGRAPHBIPARTDFTHREAD */ /******************************/ /* */ /* The threaded join routine. */ /* */ /******************************/ #ifdef BGRAPHBIPARTDFTHREAD int bgraphBipartDfJoin ( BgraphBipartDfThread * tlocptr, BgraphBipartDfThread * tremptr) { BgraphBipartDfData * restrict const loopptr = (BgraphBipartDfData *) tlocptr->thrddat.grouptr; Bgraph * restrict const grafptr = loopptr->grafptr; Gnum * restrict const frontab = grafptr->frontab; Gnum fronnbr; fronnbr = tremptr->fronnnd - (tremptr->vertbas - grafptr->s.baseval); memMov (frontab + tlocptr->fronnnd, /* Aggregate frontier array; TODO: we should do differently for large number of threads */ frontab + (tremptr->vertbas - grafptr->s.baseval), fronnbr * sizeof (Gnum)); tlocptr->fronnnd += fronnbr; /* Accumulate frontier vertices */ tlocptr->compload1 += tremptr->compload1; /* Accumulate graph properties */ tlocptr->compsize1 += tremptr->compsize1; tlocptr->commloadextn += tremptr->commloadextn; tlocptr->commloadintn += tremptr->commloadintn; tlocptr->commgainextn += tremptr->commgainextn; return (0); } #endif /* BGRAPHBIPARTDFTHREAD */ /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the bipartitioning. ** It returns: ** - 0 : if bipartitioning could be computed. ** - 1 : on error. */ int bgraphBipartDf ( Bgraph * restrict const grafptr, /*+ Active graph +*/ const BgraphBipartDfParam * const paraptr) /*+ Method parameters +*/ { BgraphBipartDfData loopdat; Gnum compload0; Gnum compload1; Gnum compsize1; Gnum commloadintn; Gnum commloadextn; Gnum commgainextn; #ifdef BGRAPHBIPARTDFTHREAD /* Threads can be accepted even when SCOTCH_DETERMINISTIC set */ int thrdnbr; #endif /* BGRAPHBIPARTDFTHREAD */ Gnum fronnbr; #ifdef SCOTCH_DEBUG_BGRAPH1 if ((grafptr->s.flagval & BGRAPHHASANCHORS) == 0) { /* Method valid only if graph has anchors */ errorPrint ("bgraphBipartDf: graph does not have anchors"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH1 */ if (memAllocGroup ((void **) (void *) &loopdat.difotax, (size_t) (grafptr->s.vertnbr * sizeof (float)), &loopdat.difntax, (size_t) (grafptr->s.vertnbr * sizeof (float)), NULL) == NULL) { errorPrint ("bgraphBipartDf: out of memory (1)"); return (1); } loopdat.grafptr = grafptr; loopdat.difotax -= grafptr->s.baseval; loopdat.difntax -= grafptr->s.baseval; loopdat.passnbr = paraptr->passnbr; compload0 = (paraptr->typeval == BGRAPHBIPARTDFTYPEBAL) /* If balanced parts wanted */ ? grafptr->compload0avg /* Target is average */ : ( (grafptr->compload0 < grafptr->compload0min) ? grafptr->compload0min : /* Else keep load if not off balance */ ((grafptr->compload0 > grafptr->compload0max) ? grafptr->compload0max : grafptr->compload0)); loopdat.vanctab[0] = (float) - compload0; /* Values to be injected to anchor vertices at every iteration */ loopdat.vanctab[1] = (float) (grafptr->s.velosum - compload0)- BGRAPHBIPARTDFEPSILON; /* Slightly tilt value to add to part 1 */ #ifdef BGRAPHBIPARTDFTHREAD /* Threads can be accepted even when SCOTCH_DETERMINISTIC set */ thrdnbr = SCOTCH_PTHREAD_NUMBER; loopdat.abrtval = 0; /* No one wants to abort yet */ if (thrdnbr > 1) { BgraphBipartDfThread * restrict thrdtab; int thrdnum; Gnum vertbas; if ((thrdtab = memAlloc (thrdnbr * sizeof (BgraphBipartDfThread))) == NULL) { errorPrint ("bgraphBipartDf: out of memory (2)"); memFree (loopdat.difotax + grafptr->s.baseval); return (1); } for (thrdnum = 0, vertbas = grafptr->s.baseval; /* For all threads except the last one */ thrdnum < (thrdnbr - 1); thrdnum ++) { thrdtab[thrdnum].vertbas = vertbas; thrdtab[thrdnum].vertnnd = vertbas += DATASIZE ((grafptr->s.vertnbr - 2), thrdnbr, thrdnum); /* Do not count anchors in distribution */ } thrdtab[thrdnum].vertbas = vertbas; thrdtab[thrdnum].vertnnd = grafptr->s.vertnnd; /* Both anchors will always be on the same thread */ threadLaunch (&loopdat, thrdtab, sizeof (BgraphBipartDfThread), (ThreadLaunchStartFunc) bgraphBipartDfThr, (ThreadLaunchJoinFunc) bgraphBipartDfJoin, thrdnbr, THREADCANBARRIER | THREADCANREDUCE); fronnbr = thrdtab[0].fronnnd; compload1 = thrdtab[0].compload1; compsize1 = thrdtab[0].compsize1; commloadextn = thrdtab[0].commloadextn; commloadintn = thrdtab[0].commloadintn; commgainextn = thrdtab[0].commgainextn; memFree (thrdtab); /* Free group leader */ } else #endif /* BGRAPHBIPARTDFTHREAD */ { BgraphBipartDfThread thrddat; thrddat.thrddat.grouptr = &loopdat; thrddat.vertbas = grafptr->s.baseval; /* Process all vertices, including both anchors */ thrddat.vertnnd = grafptr->s.vertnnd; #ifdef BGRAPHBIPARTDFTHREAD loopdat.thrddat.thrdnbr = 1; /* Thread is thread 0 of 1 */ thrddat.thrddat.thrdnum = 0; #endif /* BGRAPHBIPARTDFTHREAD */ bgraphBipartDfSeq (&thrddat); fronnbr = thrddat.fronnnd; compload1 = thrddat.compload1; compsize1 = thrddat.compsize1; commloadextn = thrddat.commloadextn; commloadintn = thrddat.commloadintn; commgainextn = thrddat.commgainextn; } memFree (loopdat.difotax + grafptr->s.baseval); /* Free group leader */ grafptr->fronnbr = fronnbr; grafptr->compload0 = grafptr->s.velosum - compload1; grafptr->compload0dlt = grafptr->compload0 - grafptr->compload0avg; grafptr->compsize0 = grafptr->s.vertnbr - compsize1; grafptr->commload = commloadextn + (commloadintn / 2) * grafptr->domndist; grafptr->commgainextn = commgainextn; grafptr->bbalval = (double) ((grafptr->compload0dlt < 0) ? (- grafptr->compload0dlt) : grafptr->compload0dlt) / (double) grafptr->compload0avg; #ifdef SCOTCH_DEBUG_BGRAPH2 if (bgraphCheck (grafptr) != 0) { errorPrint ("bgraphBipartDf: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/vgraph_separate_es.c0000644002563400244210000010353212216555743025656 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2013 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vgraph_separate_es.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a matrix ordering software. **/ /** This module computes the node separator **/ /** of a graph based on the edge-separation **/ /** module of "bgraph_bipart_st.c". **/ /** **/ /** DATES : # Version 3.2 : from : 17 oct 1996 **/ /** to : 07 sep 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 4.0 : from : 18 aug 2004 **/ /** to 20 aug 2004 **/ /** # Version 5.0 : from : 24 jan 2007 **/ /** to 12 sep 2007 **/ /** # Version 5.1 : from : 09 nov 2008 **/ /** to 09 nov 2008 **/ /** **/ /** NOTES : # This algorithm comes from: **/ /** "Computing the Block Triangular form **/ /** of a Sparse Matrix", A. Pothen and **/ /** C.-J. Fan, ACM Trans. on Mathematical **/ /** Software, 16 (4), pp 303-324, 1990. **/ /** and from: **/ /** "Implementations of $O(n^{1/2}\tau)$ **/ /** assignment algorithms", I. Duff and **/ /** T. Wieberg, ACM Trans. on Math. **/ /** Software, 4, pp 267-287, 1988. **/ /** **/ /** # The choice of the separator to take, **/ /** either HR u SC u VC or HR u SR u VC, **/ /** is made regarding the size of the **/ /** separator only, irrespective of its **/ /** balance. This choice is made because **/ /** else an imbalance ratio should be **/ /** provided for this method, and because **/ /** it is assumed that the edge biparti- **/ /** tioning method is assumed to have **/ /** reached suitable balance. When they **/ /** are equal, the choice is biased **/ /** towards SR, because the xC block is **/ /** the one which has less vertices so **/ /** removing more separator vertices from **/ /** it would mean increasing imbalance. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VGRAPH_SEPARATE_ES #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "arch.h" #include "mapping.h" #include "bgraph.h" #include "bgraph_bipart_st.h" #include "vgraph.h" #include "vgraph_separate_es.h" /*********************************************/ /* */ /* These routines compute a vertex separator */ /* from an edge separator represented as a */ /* bipartite graph, by minimum covering. */ /* */ /*********************************************/ /* This routine computes a vertex separator ** from an edge separator represented as a ** bipartite graph, by minimum covering. ** It returns: ** - 0 : if a separator could be computed. ** - !0 : on error. */ static int vgraphSeparateEsCover ( const Graph * restrict const grafptr, /* Bipartite graph to cover */ const Gnum partnbr, /* Number of vertices in first part */ Gnum * const sepatab, /* Array of covering vertices */ Gnum * const sepaptr) /* Pointer to size of the array */ { Gnum * restrict levltax; /* Array of vertex level values */ Gnum levlmax; /* Maximum level searched */ Gnum * restrict listtab; /* List of reachable augmenting rows */ Gnum listnbr; /* Number of items in list */ Gnum * restrict matetax; /* Matching array */ Gnum * queutab; /* Queue of (free) column nodes */ Gnum * restrict queuhead; /* Head of queue */ Gnum * restrict queutail; /* Tail of queue */ VgraphSeparateEsTrav * restrict travtax; /* Array of traversal flag values */ VgraphSeparateEsType * restrict typetax; /* Vertex type in the graph */ Gnum loadcval; /* Load of subset (HR u SC u VC) */ Gnum loadrval; /* Load of subset (HR u SR u VC) */ Gnum sizecval; /* Load of subset (HR u SC u VC) */ Gnum sizerval; /* Load of subset (HR u SR u VC) */ Gnum vertnum; #ifdef SCOTCH_DEBUG_VGRAPH2 if (sizeof (VgraphSeparateEsType) > sizeof (VgraphSeparateEsTrav)) { /* Assert next trick will work */ errorPrint ("vgraphSeparateEsCover: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ if (memAllocGroup ((void **) (void *) &travtax, (size_t) (grafptr->vertnbr * sizeof (VgraphSeparateEsTrav)), /* TRICK: VgraphSeparateEsType should also fit */ &matetax, (size_t) (grafptr->vertnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("vgraphSeparateEsCover: out of memory (1)"); return (1); } if (memAllocGroup ((void **) (void *) &queutab, (size_t) (partnbr * sizeof (Gnum)), &levltax, (size_t) (grafptr->vertnbr * sizeof (Gnum)), &listtab, (size_t) (grafptr->vertnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("vgraphSeparateEsCover: out of memory (2)"); memFree (travtax); /* Not based yet */ return (1); } travtax -= grafptr->baseval; matetax -= grafptr->baseval; levltax -= grafptr->baseval; memSet (matetax + (partnbr + grafptr->baseval), ~0, (grafptr->vertnbr - partnbr) * sizeof (Gnum)); for (vertnum = grafptr->baseval; /* Compute a cheap matching */ vertnum < (partnbr + grafptr->baseval); vertnum ++) { Gnum edgenum; Gnum matenum; for (edgenum = grafptr->verttax[vertnum], matenum = ~0; /* Search a matching end vertex */ edgenum < grafptr->vendtax[vertnum]; edgenum ++) { Gnum vertend; vertend = grafptr->edgetax[edgenum]; if (matetax[vertend] == ~0) { /* If an unmatched end vertex is found */ matenum = vertend; matetax[vertend] = vertnum; break; } } matetax[vertnum] = matenum; } do { /* Matching augmentation loop */ queuhead = /* Flush the data structures */ queutail = queutab; listnbr = 0; memSet (levltax + grafptr->baseval, 0, grafptr->vertnbr * sizeof (Gnum)); memSet (travtax + grafptr->baseval, 0, grafptr->vertnbr * sizeof (VgraphSeparateEsTrav)); levlmax = ~0; for (vertnum = grafptr->baseval; /* Enqueue unmatched column nodes */ vertnum < (partnbr + grafptr->baseval); vertnum ++) { if (matetax[vertnum] == ~0) { *queuhead ++ = vertnum; levltax[vertnum] = 1; } } while (queuhead > queutail) { /* As long as there are free columns */ Gnum vertcol; vertcol = *queutail ++; /* Get the free column vertex */ if (levltax[vertcol] < levlmax) { Gnum edgenum; travtax[vertcol] = VGRAPHSEPAESTRAVUSED; /* Column has been reached */ for (edgenum = grafptr->verttax[vertcol]; /* For all neighboring rows */ edgenum < grafptr->vendtax[vertcol]; edgenum ++) { Gnum vertrow; vertrow = grafptr->edgetax[edgenum]; if (travtax[vertrow] == VGRAPHSEPAESTRAVFREE) { /* If row not yet reached yet */ travtax[vertrow] = VGRAPHSEPAESTRAVUSED; /* Now it is */ if (matetax[vertrow] == ~0) { /* If row is unmatched */ listtab[listnbr ++] = vertrow; /* Put it in list */ levlmax = levltax[vertcol]; /* Do not go any further */ } else { /* Row is matched */ *queuhead ++ = matetax[vertrow]; /* Enqueue its matching column */ levltax[matetax[vertrow]] = levltax[vertcol] + 1; } } } } } if (listnbr <= 0) /* If no free rows could be reached */ break; /* Then the matching is maximal */ while (-- listnbr >= 0) /* For all rows in list, try to augment the matching */ vgraphSeparateEsCoverAugment (levltax, levlmax, matetax, travtax, grafptr->verttax, grafptr->vendtax, grafptr->edgetax, listtab[listnbr]); } while (1); memFree (queutab); /* Free group leader of arrays no longer in use */ typetax = (VgraphSeparateEsType *) travtax; /* TRICK: re-use traversal table as type table */ for (vertnum = grafptr->baseval; vertnum < (partnbr + grafptr->baseval); vertnum ++) /* Pre-set vertex types */ typetax[vertnum] = VGRAPHSEPAESTYPESC; for ( ; vertnum < grafptr->vertnnd; vertnum ++) typetax[vertnum] = VGRAPHSEPAESTYPESR; for (vertnum = grafptr->baseval; vertnum < (partnbr + grafptr->baseval); vertnum ++) /* For all column vertices */ if (matetax[vertnum] == ~0) /* If vertex is unmatched */ vgraphSeparateEsCoverCol (matetax, typetax, grafptr->verttax, grafptr->vendtax, grafptr->edgetax, vertnum); /* Find HC and HR */ for ( ; vertnum < grafptr->vertnnd; vertnum ++) /* For all row vertices */ if (matetax[vertnum] == ~0) /* If vertex is unmatched */ vgraphSeparateEsCoverRow (matetax, typetax, grafptr->verttax, grafptr->vendtax, grafptr->edgetax, vertnum); /* Find VC and VR */ sizecval = /* Reset sizes */ sizerval = 0; if (grafptr->velotax != NULL) { /* If graph vertices are weighted */ Gnum vertnum; loadcval = /* Reset loads */ loadrval = 0; for (vertnum = 0; vertnum < grafptr->vertnbr; vertnum ++) { /* Accumulate loads */ VgraphSeparateEsType typeval; Gnum veloval; Gnum bitcval; Gnum bitrval; typeval = typetax[vertnum]; veloval = grafptr->velotax[vertnum]; bitcval = (typeval >> VGRAPHSEPAESTYPEBITC) & 1; bitrval = typeval >> VGRAPHSEPAESTYPEBITR; /* TRICK: highest bit so does not need mask */ loadcval += bitcval * veloval; /* Superscalar update */ loadrval += bitrval * veloval; sizecval += bitcval; sizerval += bitrval; } } else { /* Graph vertices are not weighted */ Gnum vertnum; for (vertnum = grafptr->baseval; vertnum < grafptr->vertnnd; vertnum ++) { /* Accumulate vertex sizes */ sizecval += (typetax[vertnum] >> VGRAPHSEPAESTYPEBITC) & 1; /* Superscalar update */ sizerval += typetax[vertnum] >> VGRAPHSEPAESTYPEBITR; /* TRICK: highest bit so does not need mask */ } loadcval = sizecval; /* Loads equal sizes */ loadrval = sizerval; } if (loadcval < loadrval) { /* If separator with SC is smaller */ Gnum vertnum; Gnum sepanum; *sepaptr = sizecval; for (vertnum = grafptr->baseval, sepanum = 0; vertnum < grafptr->vertnnd; vertnum ++) { if ((typetax[vertnum] & VGRAPHSEPAESTYPEHRSCVC) != 0) { #ifdef SCOTCH_DEBUG_VGRAPH2 if ((sepanum >= sizecval) || ((typetax[vertnum] != VGRAPHSEPAESTYPEHR) && (typetax[vertnum] != VGRAPHSEPAESTYPESC) && (typetax[vertnum] != VGRAPHSEPAESTYPEVC))) { errorPrint ("vgraphSeparateEsCover: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ sepatab[sepanum ++] = vertnum; } } #ifdef SCOTCH_DEBUG_VGRAPH2 if (sepanum != sizecval) { errorPrint ("vgraphSeparateEsCover: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ } else { /* If separator with SR is smaller */ Gnum vertnum; Gnum sepanum; *sepaptr = sizerval; for (vertnum = grafptr->baseval, sepanum = 0; vertnum < grafptr->vertnnd; vertnum ++) { if ((typetax[vertnum] & VGRAPHSEPAESTYPEHRSRVC) != 0) { #ifdef SCOTCH_DEBUG_VGRAPH2 if ((sepanum >= sizerval) || ((typetax[vertnum] != VGRAPHSEPAESTYPEHR) && (typetax[vertnum] != VGRAPHSEPAESTYPESR) && (typetax[vertnum] != VGRAPHSEPAESTYPEVC))) { errorPrint ("vgraphSeparateEsCover: internal error (4)"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ sepatab[sepanum ++] = vertnum; } } #ifdef SCOTCH_DEBUG_VGRAPH2 if (sepanum != sizerval) { errorPrint ("vgraphSeparateEsCover: internal error (5)"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ } memFree (travtax + grafptr->baseval); /* Free group leader of remaining arrays */ return (0); } /* This routine augments the current matching ** by performing a backtracking depth-first ** search from a free row vertex to a free ** column vertex, guided by the level values. ** It returns: ** - 0 : backtracking succeeded. ** - !0 : could not find a valid return path. */ static int vgraphSeparateEsCoverAugment ( const Gnum * restrict const levltax, const Gnum levlcur, /* Current backtracking level */ Gnum * restrict const matetax, VgraphSeparateEsTrav * restrict const travtax, const Gnum * restrict const verttax, const Gnum * restrict const vendtax, const Gnum * restrict const edgetax, const Gnum vertrow) /* Row vertex to backtrack from */ { Gnum edgenum; travtax[vertrow] = VGRAPHSEPAESTRAVDRTY; /* Never re-use this row */ for (edgenum = verttax[vertrow]; edgenum < vendtax[vertrow]; edgenum ++) { Gnum vertcol; vertcol = edgetax[edgenum]; /* Get column vertex */ if ((travtax[vertcol] == VGRAPHSEPAESTRAVUSED) && /* If this column may be a backtracking path */ (levltax[vertcol] == levlcur)) { /* At the proper distance from a free column */ travtax[vertcol] = VGRAPHSEPAESTRAVDRTY; /* Never re-use this column */ if ((levlcur == 1) || /* If we have (recursively) reached a free column vertex */ (vgraphSeparateEsCoverAugment (levltax, levlcur - 1, matetax, travtax, verttax, vendtax, edgetax, matetax[vertcol]) == 0)) { matetax[vertcol] = vertrow; /* Switch the edges of the augmenting path */ matetax[vertrow] = vertcol; return (0); /* Backtracking process is under way */ } } } return (1); /* No improvement could be done */ } /* Starting from unmatched column and row vertices, ** these routines perform depth-first traversals of ** the bipartite graph, following alternating paths. ** It is assumed that the matchings are sufficently ** large, so that the depth of the trees is small ** and the stack will not overflow. ** They return: ** - VOID : in all cases. */ static void vgraphSeparateEsCoverCol ( const Gnum * restrict const matetax, VgraphSeparateEsType * restrict const typetax, const Gnum * restrict const verttax, const Gnum * restrict const vendtax, const Gnum * restrict const edgetax, const Gnum vertcol) /* Column vertex index */ { Gnum edgenum; if (typetax[vertcol] == VGRAPHSEPAESTYPEHC) /* If vertex already traversed */ return; typetax[vertcol] = VGRAPHSEPAESTYPEHC; for (edgenum = verttax[vertcol]; edgenum < vendtax[vertcol]; edgenum ++) { Gnum vertrow; vertrow = edgetax[edgenum]; if (typetax[vertrow] == VGRAPHSEPAESTYPEHR) /* If end vertex already traversed */ continue; /* Skip to next vertex */ typetax[vertrow] = VGRAPHSEPAESTYPEHR; if (matetax[vertrow] != ~0) /* If end vertex matched */ vgraphSeparateEsCoverCol (matetax, typetax, verttax, vendtax, edgetax, matetax[vertrow]); } } static void vgraphSeparateEsCoverRow ( const Gnum * restrict const matetax, VgraphSeparateEsType * restrict const typetax, const Gnum * restrict const verttax, const Gnum * restrict const vendtax, const Gnum * restrict const edgetax, const Gnum vertrow) /* Row vertex index */ { Gnum edgenum; if (typetax[vertrow] == VGRAPHSEPAESTYPEVR) /* If vertex already traversed */ return; typetax[vertrow] = VGRAPHSEPAESTYPEVR; for (edgenum = verttax[vertrow]; edgenum < vendtax[vertrow]; edgenum ++) { Gnum vertcol; vertcol = edgetax[edgenum]; if (typetax[vertcol] == VGRAPHSEPAESTYPEVC) /* If end vertex already traversed */ continue; /* Skip to next vertex */ typetax[vertcol] = VGRAPHSEPAESTYPEVC; if (matetax[vertcol] != ~0) /* If end vertex matched */ vgraphSeparateEsCoverRow (matetax, typetax, verttax, vendtax, edgetax, matetax[vertcol]); } } /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine separates the given graph by first ** computing an edge separator, according to the ** given bipartitioning strategy, and then turning ** it into a vertex separator. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int vgraphSeparateEs ( Vgraph * restrict const grafptr, /*+ Active graph +*/ const VgraphSeparateEsParam * const paraptr) /*+ Method parameters +*/ { Bgraph actgrafdat; /* Active graph structure */ Graph bipgrafdat; /* Bipartite graph structure */ actgrafdat.s = grafptr->s; /* Initialize active graph */ actgrafdat.s.flagval = grafptr->s.flagval & ~(GRAPHFREETABS | BGRAPHFREEPART | BGRAPHFREEFRON); actgrafdat.s.vnumtax = NULL; actgrafdat.s.vlbltax = NULL; actgrafdat.veextax = NULL; /* No external gains */ actgrafdat.parttax = grafptr->parttax; /* Inherit arrays from vertex separation graph */ actgrafdat.frontab = grafptr->frontab; bgraphInit2 (&actgrafdat, 1, 1, 1, 0, 0); /* Complete initialization and set all vertices to part 0 */ if (bgraphBipartSt (&actgrafdat, paraptr->strat) != 0) { /* Bipartition active subgraph */ errorPrint ("vgraphSeparateEs: cannot bipartition active graph"); return (1); } grafptr->compload[0] = actgrafdat.compload0; /* Reset vertex counts */ grafptr->compload[1] = actgrafdat.s.velosum - actgrafdat.compload0; grafptr->compsize[0] = actgrafdat.compsize0; grafptr->compsize[1] = actgrafdat.s.vertnbr - actgrafdat.compsize0; if (actgrafdat.fronnbr > 0) { /* If edge separator is not empty */ if (paraptr->widtval == VGRAPHSEPAESWIDTHTHIN) { /* If thin vertex separator wanted */ Gnum * restrict actvnumtax; Gnum actfronnum; Gnum bipvelosum; Gnum bipedgenbr; /* Number of edges in bipartite graph (i.e. arcs) */ Gnum bipedgenbr0; /* Number of edges adjacent to part 0 */ Gnum bipedgenbr1; /* Number of edges adjacent to part 1 */ Gnum bipvertnbr0; /* Number of vertices in part 0 */ Gnum bipvertnbr1; /* Number of vertices in part 1 */ Gnum bipvertnbrp; /* Number of vertices in part put in first place */ Gnum bippartval; /* Part of bipartite graph to be put in first place */ Gnum compsizep; /* Number of vertices to be removed from part p */ Gnum compload01; /* Load of vertices to be removed from both parts */ Gnum comploadp; /* Load of vertices to be removed from part p */ if ((actvnumtax = (Gnum *) memAlloc (actgrafdat.s.vertnbr * sizeof (Gnum))) == NULL) { errorPrint ("vgraphSeparateEs: out of memory (1)"); return (1); } #ifdef SCOTCH_DEBUG_VGRAPH2 memSet (actvnumtax, ~0, actgrafdat.s.vertnbr * sizeof (Gnum)); #endif /* SCOTCH_DEBUG_VGRAPH2 */ actvnumtax -= actgrafdat.s.baseval; bipedgenbr = 0; /* Initialize bipartite graph counts */ bipvertnbr0 = bipvertnbr1 = 0; for (actfronnum = 0; actfronnum < actgrafdat.fronnbr; actfronnum ++) { /* For all frontier vertices */ Gnum actvertnum; int actpartval; Gnum actedgenum; actvertnum = grafptr->frontab[actfronnum]; actpartval = grafptr->parttax[actvertnum]; if (actpartval == 0) { /* Count separator edges only for nodes of one side and multply by 2 */ for (actedgenum = actgrafdat.s.verttax[actvertnum]; actedgenum < actgrafdat.s.vendtax[actvertnum]; actedgenum ++) bipedgenbr += (actpartval ^ grafptr->parttax[actgrafdat.s.edgetax[actedgenum]]); } actvnumtax[actvertnum] = actpartval * (bipvertnbr1 - bipvertnbr0) + bipvertnbr0; /* Count and number separator vertices on each side */ bipvertnbr0 += actpartval ^ 1; /* Superscalar update */ bipvertnbr1 += actpartval; } bipedgenbr *= 2; /* Count both sides of arcs */ bipgrafdat.flagval = GRAPHFREEVERT | GRAPHVERTGROUP; /* Initialize bipartite graph structure */ bipgrafdat.baseval = 0; /* Base bipartite graph from 0 */ bipgrafdat.vertnbr = bipgrafdat.vertnnd = bipvertnbr0 + bipvertnbr1; if (memAllocGroup ((void **) (void *) &bipgrafdat.verttax, (size_t) ((bipgrafdat.vertnbr + 1) * sizeof (Gnum)), &bipgrafdat.velotax, (size_t) ((actgrafdat.s.velotax != NULL) ? (bipgrafdat.vertnbr * sizeof (Gnum)) : 0), &bipgrafdat.vnumtax, (size_t) (bipgrafdat.vertnbr * sizeof (Gnum)), &bipgrafdat.edgetax, (size_t) (bipedgenbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("vgraphSeparateEs: out of memory (2)"); memFree (actvnumtax + actgrafdat.s.baseval); return (1); } bipgrafdat.vendtax = bipgrafdat.verttax + 1; if (actgrafdat.s.velotax == NULL) bipgrafdat.velotax = NULL; bipgrafdat.vlbltax = NULL; bipgrafdat.edgenbr = bipedgenbr; bipgrafdat.edlotax = NULL; bipgrafdat.edlosum = bipedgenbr; bipgrafdat.degrmax = grafptr->s.degrmax; bippartval = (bipvertnbr0 <= bipvertnbr1) ? 0 : 1; /* Select smallest part to be placed first */ if (bippartval == 0) { bipvertnbrp = bipvertnbr0; bipedgenbr0 = 0; bipedgenbr1 = bipedgenbr / 2; } else { bipvertnbrp = bipvertnbr1; bipedgenbr0 = bipedgenbr / 2; bipedgenbr1 = 0; } bipvelosum = 0; for (actfronnum = 0; actfronnum < actgrafdat.fronnbr; actfronnum ++) { /* For all frontier vertices */ Gnum actvertnum; int actpartval; Gnum bipvertnum; Gnum actedgenum; actvertnum = grafptr->frontab[actfronnum]; actpartval = grafptr->parttax[actvertnum]; bipvertnum = (actpartval ^ bippartval) * bipvertnbrp + actvnumtax[actvertnum]; if (bipgrafdat.velotax != NULL) { Gnum actveloval; actveloval = actgrafdat.s.velotax[actvertnum]; bipvelosum += actveloval; bipgrafdat.velotax[bipvertnum] = actveloval; } bipgrafdat.vnumtax[bipvertnum] = actvertnum; bipgrafdat.verttax[bipvertnum] = actpartval * (bipedgenbr1 - bipedgenbr0) + bipedgenbr0; for (actedgenum = actgrafdat.s.verttax[actvertnum]; /* Count separator edges */ actedgenum < actgrafdat.s.vendtax[actvertnum]; actedgenum ++) { Gnum actvertend; int actpartend; actvertend = actgrafdat.s.edgetax[actedgenum]; actpartend = grafptr->parttax[actvertend]; if (actpartend != actpartval) { Gnum bipedgenum; #ifdef SCOTCH_DEBUG_VGRAPH2 if (actvnumtax[actvertend] == ~0) { errorPrint ("vgraphSeparateEs: internal error (1)"); graphExit (&bipgrafdat); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ bipedgenum = actpartval * (bipedgenbr1 - bipedgenbr0) + bipedgenbr0; bipedgenbr0 += actpartval ^ 1; /* Superscalar update */ bipedgenbr1 += actpartval; bipgrafdat.edgetax[bipedgenum] = actvnumtax[actvertend] + (actpartend ^ bippartval) * bipvertnbrp; } } } bipgrafdat.verttax[bipgrafdat.vertnbr] = bipgrafdat.edgenbr; bipgrafdat.velosum = (bipgrafdat.velotax != NULL) ? bipvelosum : bipgrafdat.vertnbr; memFree (actvnumtax + actgrafdat.s.baseval); #ifdef SCOTCH_DEBUG_VGRAPH2 if (((bipedgenbr0 - bipedgenbr1) * bippartval + bipedgenbr1) != bipgrafdat.edgenbr) { errorPrint ("vgraphSeparateEs: internal error (2)"); graphExit (&bipgrafdat); return (1); } if (graphCheck (&bipgrafdat) != 0) { errorPrint ("vgraphSeparateEs: internal error (3)"); graphExit (&bipgrafdat); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ if (vgraphSeparateEsCover (&bipgrafdat, bipvertnbrp, grafptr->frontab, &grafptr->fronnbr) != 0) { errorPrint ("vgraphSeparateEs: cannot compute cover"); graphExit (&bipgrafdat); return (1); } compsizep = 0; if (actgrafdat.s.velotax != NULL) { /* If vertices are weighted */ Gnum fronnum; compload01 = comploadp = 0; for (fronnum = 0; fronnum < grafptr->fronnbr; fronnum ++) { Gnum bipvertnum; Gnum actvertnum; Gnum actveloval; bipvertnum = grafptr->frontab[fronnum]; actvertnum = bipgrafdat.vnumtax[bipvertnum]; actveloval = actgrafdat.s.velotax[actvertnum]; grafptr->frontab[fronnum] = actvertnum; /* Express vertices with respect to original graph */ grafptr->parttax[actvertnum] = 2; /* Write separator part for global renumbering */ compload01 += actveloval; if (bipvertnum < bipvertnbrp) { /* Update separator vertices */ compsizep ++; /* Superscalar update */ comploadp += actveloval; } } } else { /* Vertices are not weighted */ Gnum fronnum; for (fronnum = 0; fronnum < grafptr->fronnbr; fronnum ++) { Gnum bipvertnum; Gnum actvertnum; bipvertnum = grafptr->frontab[fronnum]; actvertnum = bipgrafdat.vnumtax[bipvertnum]; grafptr->frontab[fronnum] = actvertnum; /* Express vertices with respect to original graph */ grafptr->parttax[actvertnum] = 2; /* Write separator part for global renumbering */ if (bipvertnum < bipvertnbrp) /* Update separator vertices */ compsizep ++; /* Superscalar update */ } compload01 = grafptr->fronnbr; /* Loads are equivalent to sizes */ comploadp = compsizep; } grafptr->compsize[bippartval] -= compsizep; grafptr->compsize[bippartval ^ 1] -= grafptr->fronnbr - compsizep; grafptr->compload[bippartval] -= comploadp; grafptr->compload[bippartval ^ 1] -= compload01 - comploadp; graphExit (&bipgrafdat); } else { /* Fat separator wanted */ Gnum compsize1; /* Number of vertices to be removed from part 1 */ Gnum compload01; /* Load of vertices to be removed from both parts */ Gnum compload1; /* Load of vertices to be removed from part 1 */ compsize1 = 0; grafptr->fronnbr = actgrafdat.fronnbr; /* Keep separator as is */ if (actgrafdat.s.velotax != NULL) { /* If vertices are weighted */ Gnum fronnum; compload01 = compload1 = 0; for (fronnum = 0; fronnum < actgrafdat.fronnbr; fronnum ++) { Gnum vertnum; Gnum veloval; int partval; vertnum = grafptr->frontab[fronnum]; partval = grafptr->parttax[vertnum]; veloval = grafptr->s.velotax[vertnum]; compsize1 += partval; /* Superscalar update */ compload01 += veloval; compload1 += partval * veloval; grafptr->parttax[vertnum] = 2; /* Write separator part for global renumbering */ } } else { /* Vertices are not weighted */ Gnum fronnum; for (fronnum = 0; fronnum < actgrafdat.fronnbr; fronnum ++) { Gnum vertnum; int partval; vertnum = grafptr->frontab[fronnum]; partval = grafptr->parttax[vertnum]; compsize1 += partval; grafptr->parttax[vertnum] = 2; /* Write separator part for global renumbering */ } compload01 = actgrafdat.fronnbr; /* Loads are equivalent to sizes */ compload1 = compsize1; } grafptr->compsize[0] -= actgrafdat.fronnbr - compsize1; /* Update graph properties */ grafptr->compsize[1] -= compsize1; grafptr->compload[0] -= compload01 - compload1; grafptr->compload[1] -= compload1; } } grafptr->comploaddlt = grafptr->compload[0] - grafptr->compload[1]; grafptr->compload[2] = grafptr->s.velosum - grafptr->compload[0] - grafptr->compload[1]; grafptr->fronnbr = grafptr->s.vertnbr - grafptr->compsize[0] - grafptr->compsize[1]; #ifdef SCOTCH_DEBUG_VGRAPH2 if (vgraphCheck (grafptr) != 0) { errorPrint ("vgraphSeparateEs: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/bgraph_bipart_ml.h0000644002563400244210000001042511631447170025305 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010,2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bgraph_bipart_ml.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Luca SCARANO (v3.1) **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the multi-level graph bipartitio- **/ /** ning routines. **/ /** **/ /** DATES : # Version 3.1 : from : 24 oct 1995 **/ /** to 03 jul 1996 **/ /** # Version 3.2 : from : 20 sep 1996 **/ /** to 13 sep 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 4.0 : from : 12 dec 2003 **/ /** to 20 mar 2005 **/ /** # Version 5.1 : from : 13 jul 2010 **/ /** to 13 jul 2010 **/ /** # Version 6.0 : from : 16 apr 2011 **/ /** to 03 sep 2011 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct BgraphBipartMlParam_ { INT coarnbr; /*+ Minimum number of vertices +*/ double coarrat; /*+ Coarsening ratio +*/ Strat * stratlow; /*+ Strategy at lowest level +*/ Strat * stratasc; /*+ Strategy at ascending levels +*/ } BgraphBipartMlParam; /* ** The function prototypes. */ #ifndef BGRAPH_BIPART_ML #define static #endif static int bgraphBipartMlCoarsen (const Bgraph * const, Bgraph * restrict const, GraphCoarsenMulti * restrict * const, const BgraphBipartMlParam * const); static int bgraphBipartMlUncoarsen (Bgraph * restrict const, const Bgraph * restrict const, const GraphCoarsenMulti * const); int bgraphBipartMl (Bgraph * restrict const, const BgraphBipartMlParam * const); static int bgraphBipartMl2 (Bgraph * restrict const, const BgraphBipartMlParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/hgraph_induce.h0000644002563400244210000000575111631447170024617 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hgraph_induce.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the halo graph subgraph making **/ /** functions. **/ /** **/ /** DATES : # Version 4.0 : from : 10 jan 2002 **/ /** to 22 dec 2002 **/ /** **/ /************************************************************/ /* ** The function prototypes. */ #ifndef HGRAPH_INDUCE #define static #endif static int hgraphInduce2 (const Hgraph * const, Gnum * const, Hgraph * const, const Gnum, Gnum * const); static void hgraphInduce2L (const Hgraph * const, Gnum * const, Hgraph * const); static void hgraphInduce2U (const Hgraph * const, Gnum * const, Hgraph * const); static Gnum hgraphInduce3 (const Hgraph * const, const VertList * const); #undef static scotch-6.0.4.dfsg/src/libscotch/hmesh_order_si.h0000644002563400244210000000526311631447171025010 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh_order_si.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the simple halo mesh ordering **/ /** routine. **/ /** **/ /** DATES : # Version 4.0 : from : 01 jan 2002 **/ /** to 28 sep 2002 **/ /** **/ /************************************************************/ /* ** The function prototypes. */ #ifndef HMESH_ORDER_SI #define static #endif int hmeshOrderSi (const Hmesh * const, Order * const, const Gnum, OrderCblk * const); #undef static scotch-6.0.4.dfsg/src/libscotch/graph_io_scot.h0000644002563400244210000000633411631447170024635 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : graph_io_scot.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the Scotch graph format **/ /** module. **/ /** **/ /** DATES : # Version 3.2 : from : 06 nov 1997 **/ /** to 06 nov 1997 **/ /** # Version 3.3 : from : 13 dec 1998 **/ /** to 21 dec 1998 **/ /** # Version 4.0 : from : 18 dec 2001 **/ /** to 19 jan 2004 **/ /** # Version 5.0 : from : 13 sep 2006 **/ /** to 13 sep 2006 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ The sort structure, used to sort graph vertices by label. Field labl is first because of intSort2asc1. +*/ typedef struct GraphGeomScotSort_ { Gnum labl; /*+ Vertex label: FIRST +*/ Gnum num; /*+ Vertex number +*/ } GraphGeomScotSort; scotch-6.0.4.dfsg/src/libscotch/hmesh_order_nd.h0000644002563400244210000000621711631447171024776 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh_order_nd.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the halo mesh nested dissection **/ /** ordering algorithm. **/ /** **/ /** DATES : # Version 4.0 : from : 06 jan 2002 **/ /** to 23 jan 2004 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct HmeshOrderNdParam_ { Strat * sepstrat; /*+ Separation strategy +*/ Strat * ordstratlea; /*+ Leaf ordering strategy +*/ Strat * ordstratsep; /*+ Separator ordering strategy +*/ } HmeshOrderNdParam; /* ** The function prototypes. */ #ifndef HMESH_ORDER_ND #define static #endif int hmeshOrderNd (const Hmesh * restrict const, Order * restrict const, const Gnum, OrderCblk * restrict const, const HmeshOrderNdParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/Makefile0000644002563400244210000020431612410344734023302 0ustar trophimeutilisateurs du domaine## Copyright 2004,2007-2013 IPB, Universite de Bordeaux, INRIA & CNRS ## ## This file is part of the Scotch software package for static mapping, ## graph partitioning and sparse matrix ordering. ## ## This software is governed by the CeCILL-C license under French law ## and abiding by the rules of distribution of free software. You can ## use, modify and/or redistribute the software under the terms of the ## CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ## URL: "http://www.cecill.info". ## ## As a counterpart to the access to the source code and rights to copy, ## modify and redistribute granted by the license, users are provided ## only with a limited warranty and the software's author, the holder of ## the economic rights, and the successive licensors have only limited ## liability. ## ## In this respect, the user's attention is drawn to the risks associated ## with loading, using, modifying and/or developing or reproducing the ## software by the user in light of its specific status of free software, ## that may mean that it is complicated to manipulate, and that also ## therefore means that it is reserved for developers and experienced ## professionals having in-depth computer knowledge. Users are therefore ## encouraged to load and test the software's suitability as regards ## their requirements in conditions enabling the security of their ## systems and/or data to be ensured and, more generally, to use and ## operate it in the same conditions as regards security. ## ## The fact that you are presently reading this means that you have had ## knowledge of the CeCILL-C license and that you accept its terms. ## includedir = ../../include libdir = ../../lib ## ## General inference rules. ## include ../Makefile.inc %$(OBJ) : %.c $(CC) $(CFLAGS) $(CLIBFLAGS) -c $(<) -o $(@) %$(EXE) : %.c $(CC) $(CFLAGS) -DSCOTCH_VERSION=$(VERSION) -DSCOTCH_RELEASE=$(RELEASE) -DSCOTCH_PATCHLEVEL=$(PATCHLEVEL) $(<) -o $(@) $(LDFLAGS) ## ## Project rules. ## .PHONY : ptscotch scotch ptinstall install clean realclean scotch : $(MAKE) CC="$(CCS)" CCD="$(CCS)" \ scotch.h \ scotchf.h \ libscotch$(LIB) \ libscotcherr$(LIB) \ libscotcherrexit$(LIB) ptscotch : scotch $(MAKE) CFLAGS="$(CFLAGS) -DSCOTCH_PTSCOTCH" CC="$(CCP)" \ ptscotch.h \ ptscotchf.h \ libptscotch$(LIB) \ libptscotcherr$(LIB) \ libptscotcherrexit$(LIB) install : $(includedir)/scotch.h \ $(includedir)/scotchf.h \ $(libdir)/libscotch$(LIB) ptinstall : install \ $(includedir)/ptscotch.h \ $(includedir)/ptscotchf.h \ $(libdir)/libptscotch$(LIB) clean : -$(RM) *~ *$(OBJ) lib*$(LIB) parser_yy.c parser_ly.h parser_ll.c *scotch.h *scotchf.h y.output *dummysizes$(EXE) realclean : clean ## ## Installation dependencies ## $(includedir)/scotch.h : scotch.h -$(CP) scotch.h $(includedir) $(includedir)/scotchf.h : scotchf.h -$(CP) scotchf.h $(includedir) $(includedir)/ptscotch.h : ptscotch.h -$(CP) ptscotch.h $(includedir) $(includedir)/ptscotchf.h : ptscotchf.h -$(CP) ptscotchf.h $(includedir) $(libdir)/libscotch$(LIB) : libscotch$(LIB) -$(CP) libscotch$(LIB) libscotcherr*$(LIB) $(libdir) $(libdir)/libptscotch$(LIB) : libptscotch$(LIB) -$(CP) libptscotch$(LIB) libptscotcherr*$(LIB) $(libdir) ## ## Library dependencies. ## LIBPTSCOTCHDEPS = bdgraph$(OBJ) \ bdgraph_bipart_bd$(OBJ) \ bdgraph_bipart_df$(OBJ) \ bdgraph_bipart_ex$(OBJ) \ bdgraph_bipart_ml$(OBJ) \ bdgraph_bipart_sq$(OBJ) \ bdgraph_bipart_st$(OBJ) \ bdgraph_bipart_zr$(OBJ) \ bdgraph_check$(OBJ) \ bdgraph_gather_all$(OBJ) \ bdgraph_store$(OBJ) \ comm$(OBJ) \ dgraph$(OBJ) \ dgraph_allreduce$(OBJ) \ dgraph_band$(OBJ) \ dgraph_build$(OBJ) \ dgraph_build_grid3d$(OBJ) \ dgraph_build_hcub$(OBJ) \ dgraph_check$(OBJ) \ dgraph_coarsen$(OBJ) \ dgraph_fold$(OBJ) \ dgraph_fold_comm$(OBJ) \ dgraph_fold_dup$(OBJ) \ dgraph_gather$(OBJ) \ dgraph_gather_all$(OBJ) \ dgraph_ghst$(OBJ) \ dgraph_halo$(OBJ) \ dgraph_induce$(OBJ) \ dgraph_io_load$(OBJ) \ dgraph_io_save$(OBJ) \ dgraph_match$(OBJ) \ dgraph_match_sync_coll$(OBJ) \ dgraph_match_sync_ptop$(OBJ) \ dgraph_match_check$(OBJ) \ dgraph_redist$(OBJ) \ dgraph_scatter$(OBJ) \ dgraph_view$(OBJ) \ dmapping$(OBJ) \ dmapping_io$(OBJ) \ dorder$(OBJ) \ dorder_gather$(OBJ) \ dorder_io$(OBJ) \ dorder_io_block$(OBJ) \ dorder_io_tree$(OBJ) \ dorder_perm$(OBJ) \ dorder_tree_dist$(OBJ) \ hdgraph$(OBJ) \ hdgraph_check$(OBJ) \ hdgraph_fold$(OBJ) \ hdgraph_gather$(OBJ) \ hdgraph_induce$(OBJ) \ hdgraph_order_nd$(OBJ) \ hdgraph_order_si$(OBJ) \ hdgraph_order_sq$(OBJ) \ hdgraph_order_st$(OBJ) \ kdgraph$(OBJ) \ kdgraph_gather$(OBJ) \ kdgraph_map_rb$(OBJ) \ kdgraph_map_rb_map$(OBJ) \ kdgraph_map_rb_part$(OBJ) \ kdgraph_map_st$(OBJ) \ library_dgraph$(OBJ) \ library_dgraph_f$(OBJ) \ library_dgraph_band$(OBJ) \ library_dgraph_band_f$(OBJ) \ library_dgraph_build$(OBJ) \ library_dgraph_build_f$(OBJ) \ library_dgraph_build_grid3d$(OBJ) \ library_dgraph_build_grid3d_f$(OBJ) \ library_dgraph_check$(OBJ) \ library_dgraph_check_f$(OBJ) \ library_dgraph_coarsen$(OBJ) \ library_dgraph_coarsen_f$(OBJ) \ library_dgraph_gather$(OBJ) \ library_dgraph_gather_f$(OBJ) \ library_dgraph_grow$(OBJ) \ library_dgraph_halo$(OBJ) \ library_dgraph_halo_f$(OBJ) \ library_dgraph_induce$(OBJ) \ library_dgraph_induce_f$(OBJ) \ library_dgraph_io_load$(OBJ) \ library_dgraph_io_load_f$(OBJ) \ library_dgraph_io_save$(OBJ) \ library_dgraph_io_save_f$(OBJ) \ library_dgraph_map$(OBJ) \ library_dgraph_map_f$(OBJ) \ library_dgraph_map_view$(OBJ) \ library_dgraph_map_view_f$(OBJ) \ library_dgraph_order$(OBJ) \ library_dgraph_order_f$(OBJ) \ library_dgraph_order_gather$(OBJ) \ library_dgraph_order_gather_f$(OBJ) \ library_dgraph_order_io$(OBJ) \ library_dgraph_order_io_f$(OBJ) \ library_dgraph_order_io_block$(OBJ) \ library_dgraph_order_io_block_f$(OBJ) \ library_dgraph_order_perm$(OBJ) \ library_dgraph_order_perm_f$(OBJ) \ library_dgraph_order_tree_dist$(OBJ) \ library_dgraph_order_tree_dist_f$(OBJ) \ library_dgraph_redist$(OBJ) \ library_dgraph_redist_f$(OBJ) \ library_dgraph_scatter$(OBJ) \ library_dgraph_scatter_f$(OBJ) \ library_dgraph_stat$(OBJ) \ library_dgraph_stat_f$(OBJ) \ library_dmapping$(OBJ) \ library_dorder$(OBJ) \ vdgraph$(OBJ) \ vdgraph_check$(OBJ) \ vdgraph_gather_all$(OBJ) \ vdgraph_separate_bd$(OBJ) \ vdgraph_separate_df$(OBJ) \ vdgraph_separate_ml$(OBJ) \ vdgraph_separate_sq$(OBJ) \ vdgraph_separate_st$(OBJ) \ vdgraph_separate_zr$(OBJ) \ vdgraph_store$(OBJ) LIBSCOTCHDEPS = arch$(OBJ) \ arch_build$(OBJ) \ arch_cmplt$(OBJ) \ arch_cmpltw$(OBJ) \ arch_deco$(OBJ) \ arch_dist$(OBJ) \ arch_hcub$(OBJ) \ arch_mesh$(OBJ) \ arch_tleaf$(OBJ) \ arch_torus$(OBJ) \ arch_vcmplt$(OBJ) \ arch_vhcub$(OBJ) \ bgraph$(OBJ) \ bgraph_bipart_bd$(OBJ) \ bgraph_bipart_df$(OBJ) \ bgraph_bipart_ex$(OBJ) \ bgraph_bipart_fm$(OBJ) \ bgraph_bipart_gg$(OBJ) \ bgraph_bipart_gp$(OBJ) \ bgraph_bipart_ml$(OBJ) \ bgraph_bipart_st$(OBJ) \ bgraph_bipart_zr$(OBJ) \ bgraph_check$(OBJ) \ bgraph_store$(OBJ) \ common$(OBJ) \ common_file$(OBJ) \ common_file_compress$(OBJ) \ common_file_uncompress$(OBJ) \ common_integer$(OBJ) \ common_memory$(OBJ) \ common_string$(OBJ) \ common_stub$(OBJ) \ common_thread$(OBJ) \ fibo$(OBJ) \ gain$(OBJ) \ geom$(OBJ) \ graph$(OBJ) \ graph_base$(OBJ) \ graph_band$(OBJ) \ graph_check$(OBJ) \ graph_coarsen$(OBJ) \ graph_induce$(OBJ) \ graph_io$(OBJ) \ graph_io_chac$(OBJ) \ graph_io_habo$(OBJ) \ graph_io_mmkt$(OBJ) \ graph_io_scot$(OBJ) \ graph_list$(OBJ) \ graph_match$(OBJ) \ hall_order_hd$(OBJ) \ hall_order_hf$(OBJ) \ hall_order_hx$(OBJ) \ hgraph$(OBJ) \ hgraph_check$(OBJ) \ hgraph_induce$(OBJ) \ hgraph_order_bl$(OBJ) \ hgraph_order_cp$(OBJ) \ hgraph_order_gp$(OBJ) \ hgraph_order_hd$(OBJ) \ hgraph_order_hf$(OBJ) \ hgraph_order_hx$(OBJ) \ hgraph_order_kp$(OBJ) \ hgraph_order_nd$(OBJ) \ hgraph_order_si$(OBJ) \ hgraph_order_st$(OBJ) \ hmesh$(OBJ) \ hmesh_check$(OBJ) \ hmesh_hgraph$(OBJ) \ hmesh_induce$(OBJ) \ hmesh_mesh$(OBJ) \ hmesh_order_bl$(OBJ) \ hmesh_order_cp$(OBJ) \ hmesh_order_gr$(OBJ) \ hmesh_order_gp$(OBJ) \ hmesh_order_hd$(OBJ) \ hmesh_order_hf$(OBJ) \ hmesh_order_hx$(OBJ) \ hmesh_order_nd$(OBJ) \ hmesh_order_si$(OBJ) \ hmesh_order_st$(OBJ) \ kgraph$(OBJ) \ kgraph_band$(OBJ) \ kgraph_check$(OBJ) \ kgraph_map_bd$(OBJ) \ kgraph_map_cp$(OBJ) \ kgraph_map_df$(OBJ) \ kgraph_map_ex$(OBJ) \ kgraph_map_fm$(OBJ) \ kgraph_map_ml$(OBJ) \ kgraph_map_rb$(OBJ) \ kgraph_map_rb_map$(OBJ) \ kgraph_map_rb_part$(OBJ) \ kgraph_map_st$(OBJ) \ kgraph_store$(OBJ) \ library_arch$(OBJ) \ library_arch_f$(OBJ) \ library_arch_build$(OBJ) \ library_arch_build_f$(OBJ) \ library_common_f$(OBJ) \ library_geom$(OBJ) \ library_geom_f$(OBJ) \ library_graph$(OBJ) \ library_graph_f$(OBJ) \ library_graph_base$(OBJ) \ library_graph_base_f$(OBJ) \ library_graph_check$(OBJ) \ library_graph_check_f$(OBJ) \ library_graph_coarsen$(OBJ) \ library_graph_coarsen_f$(OBJ) \ library_graph_color$(OBJ) \ library_graph_color_f$(OBJ) \ library_graph_io_chac$(OBJ) \ library_graph_io_chac_f$(OBJ) \ library_graph_io_habo$(OBJ) \ library_graph_io_habo_f$(OBJ) \ library_graph_io_mmkt$(OBJ) \ library_graph_io_mmkt_f$(OBJ) \ library_graph_io_scot$(OBJ) \ library_graph_io_scot_f$(OBJ) \ library_graph_map$(OBJ) \ library_graph_map_f$(OBJ) \ library_graph_map_io$(OBJ) \ library_graph_map_io_f$(OBJ) \ library_graph_map_view$(OBJ) \ library_graph_map_view_f$(OBJ) \ library_graph_order$(OBJ) \ library_graph_order_f$(OBJ) \ library_graph_part_ovl$(OBJ) \ library_graph_part_ovl_f$(OBJ) \ library_mapping$(OBJ) \ library_memory$(OBJ) \ library_memory_f$(OBJ) \ library_mesh$(OBJ) \ library_mesh_f$(OBJ) \ library_mesh_graph$(OBJ) \ library_mesh_graph_f$(OBJ) \ library_mesh_io_habo$(OBJ) \ library_mesh_io_habo_f$(OBJ) \ library_mesh_io_scot$(OBJ) \ library_mesh_io_scot_f$(OBJ) \ library_mesh_order$(OBJ) \ library_mesh_order_f$(OBJ) \ library_order$(OBJ) \ library_parser$(OBJ) \ library_parser_f$(OBJ) \ library_random$(OBJ) \ library_random_f$(OBJ) \ library_strat$(OBJ) \ library_version$(OBJ) \ library_version_f$(OBJ) \ mapping$(OBJ) \ mapping_io$(OBJ) \ mesh$(OBJ) \ mesh_check$(OBJ) \ mesh_coarsen$(OBJ) \ mesh_graph$(OBJ) \ mesh_induce_sepa$(OBJ) \ mesh_io$(OBJ) \ mesh_io_habo$(OBJ) \ mesh_io_scot$(OBJ) \ order$(OBJ) \ order_check$(OBJ) \ order_io$(OBJ) \ parser$(OBJ) \ parser_ll$(OBJ) \ parser_yy$(OBJ) \ vgraph$(OBJ) \ vgraph_check$(OBJ) \ vgraph_separate_bd$(OBJ) \ vgraph_separate_df$(OBJ) \ vgraph_separate_es$(OBJ) \ vgraph_separate_fm$(OBJ) \ vgraph_separate_gg$(OBJ) \ vgraph_separate_gp$(OBJ) \ vgraph_separate_ml$(OBJ) \ vgraph_separate_st$(OBJ) \ vgraph_separate_th$(OBJ) \ vgraph_separate_vw$(OBJ) \ vgraph_separate_zr$(OBJ) \ vgraph_store$(OBJ) \ vmesh$(OBJ) \ vmesh_check$(OBJ) \ vmesh_separate_fm$(OBJ) \ vmesh_separate_gg$(OBJ) \ vmesh_separate_gr$(OBJ) \ vmesh_separate_ml$(OBJ) \ vmesh_separate_zr$(OBJ) \ vmesh_separate_st$(OBJ) \ vmesh_store$(OBJ) \ wgraph$(OBJ) \ wgraph_check$(OBJ) \ wgraph_part_fm$(OBJ) \ wgraph_part_gg$(OBJ) \ wgraph_part_gp$(OBJ) \ wgraph_part_ml$(OBJ) \ wgraph_part_rb$(OBJ) \ wgraph_part_st$(OBJ) \ wgraph_part_zr$(OBJ) \ wgraph_store$(OBJ) ## ## Todo list. ## common$(OBJ) : common.c \ module.h \ common.h $(CC) $(CFLAGS) $(CLIBFLAGS) -c $(<) -DSCOTCH_COMMON_RENAME -o $(@) common_file$(OBJ) : common_file.c \ module.h \ common.h \ common_file.h $(CC) $(CFLAGS) $(CLIBFLAGS) -c $(<) -DSCOTCH_COMMON_RENAME -o $(@) common_file_compress$(OBJ) : common_file_compress.c \ module.h \ common.h \ common_file.h \ common_file_compress.h $(CC) $(CFLAGS) $(CLIBFLAGS) -c $(<) -DSCOTCH_COMMON_RENAME -o $(@) common_file_uncompress$(OBJ) : common_file_uncompress.c \ module.h \ common.h \ common_file.h \ common_file_compress.h $(CC) $(CFLAGS) $(CLIBFLAGS) -c $(<) -DSCOTCH_COMMON_RENAME -o $(@) common_integer$(OBJ) : common_integer.c \ module.h \ common.h \ common_sort.c $(CC) $(CFLAGS) $(CLIBFLAGS) -c $(<) -DSCOTCH_COMMON_RENAME -o $(@) common_memory$(OBJ) : common_memory.c \ module.h \ common.h $(CC) $(CFLAGS) $(CLIBFLAGS) -c $(<) -DSCOTCH_COMMON_RENAME -o $(@) common_string$(OBJ) : common_string.c \ module.h \ common.h $(CC) $(CFLAGS) $(CLIBFLAGS) -c $(<) -DSCOTCH_COMMON_RENAME -o $(@) common_stub$(OBJ) : common_stub.c \ module.h \ common.h $(CC) $(CFLAGS) $(CLIBFLAGS) -c $(<) -DSCOTCH_COMMON_RENAME -o $(@) common_thread$(OBJ) : common_thread.c \ module.h \ common.h $(CC) $(CFLAGS) $(CLIBFLAGS) -c $(<) -DSCOTCH_COMMON_RENAME -o $(@) arch$(OBJ) : arch.c \ module.h \ common.h \ arch.h \ arch_cmplt.h \ arch_cmpltw.h \ arch_deco.h \ arch_dist.h \ arch_hcub.h \ arch_mesh.h \ arch_tleaf.h \ arch_torus.h \ arch_vcmplt.h \ arch_vhcub.h arch_build$(OBJ) : arch_build.c \ module.h \ common.h \ parser.h \ graph.h \ arch$(OBJ) \ arch_deco.h \ arch_vcmplt.h \ mapping.h \ bgraph.h \ bgraph_bipart_st.h \ arch_build.h arch_cmplt$(OBJ) : arch_cmplt.c \ module.h \ common.h \ arch.h \ arch_cmplt.h arch_cmpltw$(OBJ) : arch_cmpltw.c \ module.h \ common.h \ arch.h \ arch_cmpltw.h arch_deco$(OBJ) : arch_deco.c \ module.h \ common.h \ arch.h \ arch_deco.h arch_dist$(OBJ) : arch_dist.c \ module.h \ common.h \ arch.h \ arch_dist.h arch_hcub$(OBJ) : arch_hcub.c \ module.h \ common.h \ arch.h \ arch_hcub.h arch_mesh$(OBJ) : arch_mesh.c \ module.h \ common.h \ arch.h \ arch_mesh.h arch_tleaf$(OBJ) : arch_tleaf.c \ module.h \ common.h \ arch.h \ arch_tleaf.h arch_torus$(OBJ) : arch_torus.c \ module.h \ common.h \ arch.h \ arch_torus.h arch_vcpmlt$(OBJ) : arch_vcmplt.c \ module.h \ common.h \ arch.h \ arch_vcmplt.h arch_vhcub$(OBJ) : arch_vhcub.c \ module.h \ common.h \ arch.h \ arch_vhcub.h bdgraph$(OBJ) : bdgraph.c \ module.h \ common.h \ arch$(OBJ) \ dgraph.h \ dmapping.h \ bdgraph.h bdgraph_bipart_bd$(OBJ) : bdgraph_bipart_bd.c \ module.h \ common.h \ parser.h \ arch$(OBJ) \ dgraph.h \ dgraph_halo.h \ bdgraph.h \ bdgraph_bipart_bd.h \ bdgraph_bipart_st.h bdgraph_bipart_df$(OBJ) : bdgraph_bipart_df.c \ module.h \ common.h \ arch$(OBJ) \ dgraph.h \ bdgraph.h \ bdgraph_bipart_df.h bdgraph_bipart_ex$(OBJ) : bdgraph_bipart_ex.c \ module.h \ common.h \ arch$(OBJ) \ dgraph.h \ bdgraph.h \ bdgraph_bipart_ex.h bdgraph_bipart_ml$(OBJ) : bdgraph_bipart_ml.c \ module.h \ common.h \ parser.h \ arch$(OBJ) \ dgraph.h \ dgraph_coarsen.h \ bdgraph.h \ bdgraph_bipart_ml.h \ bdgraph_bipart_st.h bdgraph_bipart_sq$(OBJ) : bdgraph_bipart_sq.c \ module.h \ common.h \ comm.h \ parser.h \ arch$(OBJ) \ graph.h \ bgraph.h \ bgraph_bipart_st.h \ dgraph.h \ bdgraph.h \ bdgraph_bipart_sq.h bdgraph_bipart_st$(OBJ) : bdgraph_bipart_st.c \ module.h \ common.h \ gain.h \ parser.h \ graph.h \ arch$(OBJ) \ bgraph.h \ bgraph_bipart_st.h \ dgraph.h \ dgraph_coarsen.h \ bdgraph.h \ bdgraph_bipart_bd.h \ bdgraph_bipart_df.h \ bdgraph_bipart_ex.h \ bdgraph_bipart_ml.h \ bdgraph_bipart_sq.h \ bdgraph_bipart_st.h \ bdgraph_bipart_zr.h bdgraph_bipart_zr$(OBJ) : bdgraph_bipart_zr.c \ module.h \ common.h \ arch$(OBJ) \ dgraph.h \ bdgraph.h \ bdgraph_bipart_zr.h bdgraph_check$(OBJ) : bdgraph_check.c \ module.h \ common.h \ arch$(OBJ) \ dgraph.h \ bdgraph.h bdgraph_gather_all$(OBJ) : bdgraph_gather_all.c \ module.h \ common.h \ comm.h \ arch$(OBJ) \ graph.h \ bgraph.h \ dgraph.h \ bdgraph.h bdgraph_store$(OBJ) : bdgraph_store.c \ module.h \ common.h \ arch$(OBJ) \ dgraph.h \ bdgraph.h bgraph$(OBJ) : bgraph.c \ module.h \ common.h \ graph.h \ arch$(OBJ) \ mapping.h \ bgraph.h bgraph_bipart_bd$(OBJ) : bgraph_bipart_bd.c \ module.h \ common.h \ parser.h \ graph.h \ arch$(OBJ) \ bgraph.h \ bgraph_bipart_bd.h \ bgraph_bipart_st.h bgraph_bipart_df$(OBJ) : bgraph_bipart_df.c \ bgraph_bipart_df_loop.c \ module.h \ common.h \ graph.h \ arch$(OBJ) \ bgraph.h \ bgraph_bipart_df.h bgraph_bipart_ex$(OBJ) : bgraph_bipart_ex.c \ module.h \ common.h \ gain.h \ graph.h \ arch$(OBJ) \ bgraph.h \ bgraph_bipart_ex.h \ bgraph_bipart_fm.h \ bgraph_bipart_gg.h bgraph_bipart_fm$(OBJ) : bgraph_bipart_fm.c \ gain.h \ fibo.h \ module.h \ common.h \ graph.h \ arch$(OBJ) \ bgraph.h \ bgraph_bipart_fm.h bgraph_bipart_gg$(OBJ) : bgraph_bipart_gg.c \ gain.h \ fibo.h \ module.h \ common.h \ graph.h \ arch$(OBJ) \ bgraph.h \ bgraph_bipart_gg.h bgraph_bipart_gp$(OBJ) : bgraph_bipart_gp.c \ module.h \ common.h \ graph.h \ arch$(OBJ) \ bgraph.h \ bgraph_bipart_gp.h bgraph_bipart_ml$(OBJ) : bgraph_bipart_ml.c \ module.h \ common.h \ parser.h \ graph.h \ graph_coarsen.h \ arch$(OBJ) \ bgraph.h \ bgraph_bipart_ml.h \ bgraph_bipart_st.h bgraph_bipart_st$(OBJ) : bgraph_bipart_st.c \ gain.h \ fibo.h \ module.h \ common.h \ parser.h \ graph.h \ arch$(OBJ) \ bgraph.h \ bgraph_bipart_bd.h \ bgraph_bipart_df.h \ bgraph_bipart_ex.h \ bgraph_bipart_fm.h \ bgraph_bipart_gg.h \ bgraph_bipart_gp.h \ bgraph_bipart_ml.h \ bgraph_bipart_st.h \ bgraph_bipart_zr.h bgraph_bipart_zr$(OBJ) : bgraph_bipart_zr.c \ module.h \ common.h \ graph.h \ arch$(OBJ) \ bgraph.h \ bgraph_bipart_zr.h bgraph_check$(OBJ) : bgraph_check.c \ module.h \ common.h \ graph.h \ arch$(OBJ) \ bgraph.h bgraph_store$(OBJ) : bgraph_store.c \ module.h \ common.h \ graph.h \ arch$(OBJ) \ bgraph.h comm$(OBJ) : comm.c \ module.h \ common.h \ comm.h dgraph$(OBJ) : dgraph.c \ module.h \ common.h \ dgraph.h dgraph_allreduce$(OBJ) : dgraph_allreduce.c \ module.h \ common.h \ dgraph.h \ dgraph_allreduce.h dgraph_band$(OBJ) : dgraph_band.c \ module.h \ common.h \ dgraph.h dgraph_build$(OBJ) : dgraph_build.c \ module.h \ common.h \ dgraph.h \ dgraph_allreduce.h \ dgraph_build.h dgraph_build_grid3d$(OBJ) : dgraph_build_grid3d.c \ module.h \ common.h \ dgraph.h \ dgraph_build_grid3d.h dgraph_build_hcub$(OBJ) : dgraph_build_hcub.c \ module.h \ common.h \ dgraph.h dgraph_check$(OBJ) : dgraph_check.c \ module.h \ common.h \ dgraph.h dgraph_coarsen$(OBJ) : dgraph_coarsen.c \ module.h \ common.h \ dgraph.h \ dgraph_allreduce.h \ dgraph_coarsen.h \ dgraph_match.h dgraph_fold$(OBJ) : dgraph_fold.c \ module.h \ common.h \ comm.h \ dgraph.h \ dgraph_fold.h \ dgraph_fold_comm.h dgraph_fold_comm$(OBJ) : dgraph_fold_comm.c \ module.h \ common.h \ comm.h \ dgraph.h \ dgraph_fold_comm.h dgraph_fold_dup$(OBJ) : dgraph_fold_dup.c \ module.h \ common.h \ dgraph.h \ dgraph_fold_dup.h dgraph_gather$(OBJ) : dgraph_gather.c \ module.h \ common.h \ graph.h \ dgraph.h dgraph_gather_all$(OBJ) : dgraph_gather_all.c \ module.h \ common.h \ comm.h \ graph.h \ dgraph.h dgraph_ghst$(OBJ) : dgraph_ghst.c \ module.h \ common.h \ dgraph.h \ dgraph_ghst.h dgraph_halo$(OBJ) : dgraph_halo.c \ dgraph_halo_fill.c \ module.h \ common.h \ dgraph.h \ dgraph_halo.h dgraph_induce$(OBJ) : dgraph_induce.c \ module.h \ common.h \ dgraph.h dgraph_io_load$(OBJ) : dgraph_io_load.c \ module.h \ common.h \ dgraph.h \ dgraph_io_load.h dgraph_io_save$(OBJ) : dgraph_io_save.c \ module.h \ common.h \ dgraph.h dgraph_match$(OBJ) : dgraph_match.c \ dgraph_match_scan.c \ module.h \ common.h \ dgraph.h \ dgraph_coarsen.h \ dgraph_match.h dgraph_match_check$(OBJ) : dgraph_match_check.c \ module.h \ common.h \ dgraph.h \ dgraph_coarsen.h \ dgraph_match.h dgraph_match_sync_coll$(OBJ) : dgraph_match_sync_coll.c \ module.h \ common.h \ dgraph.h \ dgraph_coarsen.h \ dgraph_match.h \ graph.h dgraph_match_sync_ptop$(OBJ) : dgraph_match_sync_ptop.c \ module.h \ common.h \ dgraph.h \ dgraph_coarsen.h \ dgraph_match.h \ graph.h dgraph_redist$(OBJ) : dgraph_redist.c \ module.h \ common.h \ graph.h \ dgraph.h dgraph_scatter$(OBJ) : dgraph_scatter.c \ module.h \ common.h \ graph.h \ dgraph.h dgraph_view$(OBJ) : dgraph_view.c \ module.h \ common.h \ dgraph.h dmapping$(OBJ) : dmapping.c \ module.h \ common.h \ arch$(OBJ) \ dgraph.h \ dmapping.h dmapping_io$(OBJ) : dmapping_io.c \ module.h \ common.h \ comm.h \ arch$(OBJ) \ dgraph.h \ dgraph_allreduce.h \ dmapping.h dorder$(OBJ) : dorder.c \ module.h \ common.h \ dgraph.h \ dorder.h dorder_gather$(OBJ) : dorder_gather.c \ module.h \ common.h \ dgraph.h \ dgraph_allreduce.h \ dorder.h \ dorder_gather.h \ order.h dorder_io$(OBJ) : dorder_io.c \ module.h \ common.h \ comm.h \ dgraph.h \ dorder.h \ order.h dorder_io_block$(OBJ) : dorder_io_block.c \ module.h \ common.h \ dgraph.h \ dorder.h \ order.h dorder_io_tree$(OBJ) : dorder_io_tree.c \ module.h \ common.h \ comm.h \ dgraph.h \ dorder.h \ order.h dorder_perm$(OBJ) : dorder_perm.c \ module.h \ common.h \ dgraph.h \ dorder.h \ dorder_perm.h dorder_tree_dist$(OBJ) : dorder_tree_dist.c \ module.h \ common.h \ dgraph.h \ dorder.h fibo$(OBJ) : fibo.c \ module.h \ common.h \ fibo.h gain$(OBJ) : gain.c \ module.h \ common.h \ gain.h geom$(OBJ) : geom.c \ module.h \ common.h \ geom.h graph$(OBJ) : graph.c \ module.h \ common.h \ graph.h graph_band$(OBJ) : graph_band.c \ module.h \ common.h \ graph.h graph_base$(OBJ) : graph_base.c \ module.h \ common.h \ graph.h graph_check$(OBJ) : graph_check.c \ module.h \ common.h \ graph.h graph_coarsen$(OBJ) : graph_coarsen.c \ graph_coarsen_edge.c \ module.h \ common.h \ graph.h \ graph_coarsen.h graph_induce$(OBJ) : graph_induce.c \ module.h \ common.h \ graph.h \ graph_induce.h graph_io$(OBJ) : graph_io.c \ module.h \ common.h \ graph.h \ graph_io.h graph_io_chac$(OBJ) : graph_io_chac.c \ module.h \ common.h \ geom.h \ graph.h graph_io_habo$(OBJ) : graph_io_habo.c \ module.h \ common.h \ geom.h \ graph.h \ graph_io_habo.h graph_io_mmkt$(OBJ) : graph_io_mmkt.c \ module.h \ common.h \ geom.h \ graph.h \ graph_io_mmkt.h graph_io_scot$(OBJ) : graph_io_scot.c \ module.h \ common.h \ geom.h \ graph.h \ graph_io_scot.h graph_list$(OBJ) : graph_list.c \ module.h \ common.h \ graph.h graph_match$(OBJ) : graph_match.c \ graph_match_scan.c \ module.h \ common.h \ graph.h \ graph_coarsen.h \ graph_match.h hall_order_hd$(OBJ) : hall_order_hd.c \ module.h \ common.h \ graph.h \ hall_order_hd.h hall_order_hf$(OBJ) : hall_order_hf.c \ module.h \ common.h \ graph.h \ hall_order_hf.h hall_order_hx$(OBJ) : hall_order_hx.c \ module.h \ common.h \ graph.h \ order.h \ hall_order_hx.h hdgraph$(OBJ) : hdgraph.c \ module.h \ common.h \ dgraph.h \ hdgraph.h hdgraph_check$(OBJ) : hdgraph_check.c \ module.h \ common.h \ dgraph.h \ hdgraph.h hdgraph_fold$(OBJ) : hdgraph_fold.c \ module.h \ common.h \ comm.h \ dgraph.h \ dgraph_fold_comm.h \ hdgraph.h \ hdgraph_fold.h hdgraph_gather$(OBJ) : hdgraph_gather.c \ module.h \ common.h \ comm.h \ graph.h \ hgraph.h \ dgraph.h \ hdgraph.h hdgraph_induce$(OBJ) : hdgraph_induce.c \ module.h \ common.h \ dgraph.h \ hdgraph.h hdgraph_order_nd$(OBJ) : hdgraph_order_nd.c \ module.h \ common.h \ parser.h \ graph.h \ order.h \ hgraph.h \ hgraph_order_st.h \ dgraph.h \ dorder.h \ hdgraph.h \ hdgraph_order_nd.h \ hdgraph_order_sq.h \ hdgraph_order_st.h \ vdgraph.h \ vdgraph_separate_st.h hdgraph_order_si$(OBJ) : hdgraph_order_si.c \ module.h \ common.h \ dgraph.h \ dorder.h \ hdgraph.h \ hdgraph_order_si.h hdgraph_order_sq$(OBJ) : hdgraph_order_sq.c \ module.h \ common.h \ parser.h \ graph.h \ order.h \ hgraph.h \ hgraph_order_st.h \ dgraph.h \ dorder.h \ hdgraph.h \ hdgraph_order_sq.h hdgraph_order_st$(OBJ) : hdgraph_order_st.c \ module.h \ common.h \ parser.h \ dgraph.h \ dgraph_coarsen.h \ dorder.h \ hdgraph.h \ vdgraph.h \ vdgraph_separate_st.h \ hdgraph_order_nd.h \ hdgraph_order_si.h \ hdgraph_order_sq.h \ hdgraph_order_st.h hgraph$(OBJ) : hgraph.c \ module.h \ common.h \ graph.h \ hgraph.h hgraph_check$(OBJ) : hgraph_check.c \ module.h \ common.h \ graph.h \ hgraph.h hgraph_induce$(OBJ) : hgraph_induce.c \ hgraph_induce_edge.c \ module.h \ common.h \ graph.h \ hgraph.h \ hgraph_induce.h hgraph_order_bl$(OBJ) : hgraph_order_bl.c \ module.h \ common.h \ parser.h \ graph.h \ order.h \ hgraph.h \ hgraph_order_bl.h hgraph_order_cp$(OBJ) : hgraph_order_cp.c \ module.h \ common.h \ parser.h \ graph.h \ order.h \ hgraph.h \ hgraph_order_cp.h \ hgraph_order_st.h hgraph_order_gp$(OBJ) : hgraph_order_gp.c \ module.h \ common.h \ graph.h \ order.h \ hgraph.h \ hgraph_order_gp.h hgraph_order_hd$(OBJ) : hgraph_order_hd.c \ module.h \ common.h \ graph.h \ order.h \ hgraph.h \ hall_order_hd.h \ hall_order_hx.h \ hgraph_order_hd.h \ hgraph_order_hx.h \ hgraph_order_si.h hgraph_order_hf$(OBJ) : hgraph_order_hf.c \ module.h \ common.h \ graph.h \ order.h \ hgraph.h \ hall_order_hf.h \ hall_order_hx.h \ hgraph_order_hf.h \ hgraph_order_hx.h \ hgraph_order_si.h hgraph_order_hx$(OBJ) : hgraph_order_hx.c \ module.h \ common.h \ graph.h \ hgraph.h \ hgraph_order_hx.h hgraph_order_kp$(OBJ) : hgraph_order_kp.c \ module.h \ common.h \ parser.h \ graph.h \ arch.h \ mapping.h \ order.h \ hgraph.h \ hgraph_order_kp.h \ hgraph_order_si.h \ hgraph_order_st.h \ kgraph.h \ kgraph_map_st.h \ scotch.h hgraph_order_nd$(OBJ) : hgraph_order_nd.c \ module.h \ common.h \ parser.h \ graph.h \ order.h \ hgraph.h \ hgraph_order_nd.h \ hgraph_order_st.h \ vgraph.h \ vgraph_separate_st.h hgraph_order_si$(OBJ) : hgraph_order_si.c \ module.h \ common.h \ graph.h \ order.h \ hgraph.h \ hgraph_order_si.h hgraph_order_st$(OBJ) : hgraph_order_st.c \ module.h \ common.h \ parser.h \ graph.h \ arch$(OBJ) \ mapping.h \ order.h \ hgraph.h \ hgraph_order_bl.h \ hgraph_order_cp.h \ hgraph_order_gp.h \ hgraph_order_hd.h \ hgraph_order_hf.h \ hgraph_order_kp.h \ hgraph_order_nd.h \ hgraph_order_si.h \ hgraph_order_st.h \ kgraph.h \ kgraph_map_st.h \ vgraph.h \ vgraph_separate_st.h hmesh$(OBJ) : hmesh.c \ module.h \ common.h \ graph.h \ mesh.h \ hmesh.h hmesh_check$(OBJ) : hmesh_check.c \ module.h \ common.h \ graph.h \ mesh.h \ hmesh.h hmesh_hgraph$(OBJ) : hmesh_hgraph.c \ module.h \ common.h \ graph.h \ hgraph.h \ mesh.h \ hmesh.h \ hmesh_hgraph.h hmesh_induce$(OBJ) : hmesh_induce.c \ module.h \ common.h \ graph.h \ mesh.h \ hmesh.h hmesh_mesh$(OBJ) : hmesh_mesh.c \ module.h \ common.h \ graph.h \ mesh.h \ hmesh.h hmesh_order_bl$(OBJ) : hmesh_order_bl.c \ module.h \ common.h \ parser.h \ graph.h \ order.h \ mesh.h \ hmesh.h \ hmesh_order_bl.h \ hmesh_order_st.h hmesh_order_cp$(OBJ) : hmesh_order_cp.c \ module.h \ common.h \ parser.h \ graph.h \ order.h \ mesh.h \ hmesh.h \ hmesh_order_cp.h \ hmesh_order_st.h hmesh_order_gp$(OBJ) : hmesh_order_gp.c \ module.h \ common.h \ graph.h \ order.h \ mesh.h \ hmesh.h \ hmesh_order_gp.h hmesh_order_gp$(OBJ) : hmesh_order_gp.c \ module.h \ common.h \ graph.h \ order.h \ mesh.h \ hmesh.h \ hmesh_order_gp.h hmesh_order_hd$(OBJ) : hmesh_order_hd.c \ module.h \ common.h \ graph.h \ order.h \ mesh.h \ hmesh.h \ hall_order_hd.h \ hall_order_hx.h \ hmesh_order_hd.h \ hmesh_order_si.h hmesh_order_hf$(OBJ) : hmesh_order_hf.c \ module.h \ common.h \ graph.h \ order.h \ mesh.h \ hmesh.h \ hall_order_hf.h \ hall_order_hx.h \ hmesh_order_hf.h \ hmesh_order_si.h hmesh_order_hx$(OBJ) : hmesh_order_hx.c \ module.h \ common.h \ graph.h \ mesh.h \ hmesh.h \ hmesh_order_hx.h hmesh_order_nd$(OBJ) : hmesh_order_nd.c \ module.h \ common.h \ parser.h \ graph.h \ order.h \ mesh.h \ hmesh.h \ hmesh_order_nd.h \ hmesh_order_st.h \ vmesh.h \ vmesh_separate_st.h hmesh_order_si$(OBJ) : hmesh_order_si.c \ module.h \ common.h \ graph.h \ order.h \ mesh.h \ hmesh.h \ hmesh_order_si.h hmesh_order_st$(OBJ) : hmesh_order_st.c \ module.h \ common.h \ parser.h \ graph.h \ hgraph.h \ hgraph_order_st.h \ mesh.h \ hmesh.h \ order.h \ vmesh_separate_st.h \ hmesh_order_bl.h \ hmesh_order_gp.h \ hmesh_order_gr.h \ hmesh_order_hd.h \ hmesh_order_hf.h \ hmesh_order_nd.h \ hmesh_order_si.h \ hmesh_order_st.h kdgraph$(OBJ) : kdgraph.c \ module.h \ common.h \ arch$(OBJ) \ dgraph.h \ dmapping.h \ kdgraph.h kdgraph_gather$(OBJ) : kdgraph_gather.c \ module.h \ common.h \ arch$(OBJ) \ graph.h \ mapping.h \ kgraph.h \ dgraph.h \ kdgraph.h kdgraph_map_rb$(OBJ) : kdgraph_map_rb.c \ module.h \ common.h \ parser.h \ arch$(OBJ) \ graph.h \ dgraph.h \ dmapping.h \ kdgraph.h \ kdgraph_map_rb.h \ kdgraph_map_rb_map.h \ kdgraph_map_rb_part.h kdgraph_map_rb_map$(OBJ) : kdgraph_map_rb_map.c \ module.h \ common.h \ parser.h \ arch$(OBJ) \ graph.h \ bgraph.h \ bgraph_bipart_st.h \ mapping.h \ kgraph.h \ kgraph_map_st.h \ dgraph.h \ dmapping.h \ bdgraph.h \ bdgraph_bipart_st.h \ kdgraph.h \ kdgraph_map_rb.h \ kdgraph_map_rb_map.h \ kdgraph_map_st.h kdgraph_map_rb_part$(OBJ) : kdgraph_map_rb_part.c \ module.h \ common.h \ parser.h \ arch$(OBJ) \ graph.h \ bgraph.h \ bgraph_bipart_st.h \ mapping.h \ kgraph.h \ kgraph_map_st.h \ dgraph.h \ dmapping.h \ bdgraph.h \ bdgraph_bipart_st.h \ kdgraph.h \ kdgraph_map_rb.h \ kdgraph_map_rb_part.h \ kdgraph_map_st.h kdgraph_map_st$(OBJ) : kdgraph_map_st.c \ module.h \ common.h \ parser.h \ arch$(OBJ) \ graph.h \ dgraph.h \ dgraph_coarsen.h \ mapping.h \ dmapping.h \ bdgraph.h \ bdgraph_bipart_st.h \ kgraph.h \ kgraph_map_st.h \ kdgraph.h \ kdgraph_map_rb.h \ kdgraph_map_st.h kgraph$(OBJ) : kgraph.c \ module.h \ common.h \ graph.h \ arch$(OBJ) \ mapping.h \ kgraph.h kgraph_band$(OBJ) : kgraph_band.c \ module.h \ common.h \ arch$(OBJ) \ graph.h \ mapping.h \ kgraph.h kgraph_check$(OBJ) : kgraph_check.c \ module.h \ common.h \ graph.h \ arch$(OBJ) \ mapping.h \ kgraph.h kgraph_map_bd$(OBJ) : kgraph_map_bd.c \ module.h \ common.h \ parser.h \ graph.h \ arch$(OBJ) \ mapping.h \ kgraph.h \ kgraph_map_bd.h kgraph_map_cp$(OBJ) : kgraph_map_cp.c \ module.h \ common.h \ parser.h \ graph.h \ arch$(OBJ) \ mapping.h \ kgraph.h \ kgraph_map_cp.h kgraph_map_df$(OBJ) : kgraph_map_df.c \ kgraph_map_df_loop.c \ module.h \ common.h \ parser.h \ graph.h \ arch$(OBJ) \ mapping.h \ kgraph.h \ kgraph_map_df.h kgraph_map_ex$(OBJ) : kgraph_map_ex.c \ module.h \ common.h \ graph.h \ arch$(OBJ) \ mapping.h \ kgraph.h \ kgraph_map_ex.h kgraph_map_fm$(OBJ) : kgraph_map_fm.c \ module.h \ common.h \ parser.h \ graph.h \ arch$(OBJ) \ mapping.h \ kgraph.h \ kgraph_map_fm.h \ kgraph_map_rb.h kgraph_map_ml$(OBJ) : kgraph_map_ml.c \ module.h \ common.h \ parser.h \ graph.h \ graph_coarsen.h \ arch$(OBJ) \ mapping.h \ kgraph.h \ kgraph_map_ml.h kgraph_map_rb$(OBJ) : kgraph_map_rb.c \ module.h \ common.h \ parser.h \ graph.h \ arch$(OBJ) \ mapping.h \ bgraph.h \ bgraph_bipart_st.h \ kgraph.h \ kgraph_map_rb.h \ kgraph_map_rb_map.h \ kgraph_map_rb_part.h kgraph_map_rb_map$(OBJ) : kgraph_map_rb_map.c \ module.h \ common.h \ parser.h \ graph.h \ arch$(OBJ) \ mapping.h \ bgraph.h \ bgraph_bipart_st.h \ kgraph.h \ kgraph_map_rb.h \ kgraph_map_rb_map.h kgraph_map_rb_part$(OBJ) : kgraph_map_rb_part.c \ module.h \ common.h \ parser.h \ graph.h \ arch$(OBJ) \ mapping.h \ bgraph.h \ bgraph_bipart_st.h \ kgraph.h \ kgraph_map_rb.h \ kgraph_map_rb_part.h kgraph_map_st$(OBJ) : kgraph_map_st.c \ module.h \ common.h \ parser.h \ graph.h \ arch$(OBJ) \ mapping.h \ bgraph.h \ bgraph_bipart_st.h \ kgraph.h \ kgraph_map_bd.h \ kgraph_map_cp.h \ kgraph_map_df.h \ kgraph_map_fm.h \ kgraph_map_ml.h \ kgraph_map_rb.h kgraph_store$(OBJ) : kgraph_store.c \ module.h \ common.h \ graph.h \ arch$(OBJ) \ mapping.h \ kgraph.h library_arch$(OBJ) : library_arch.c \ module.h \ common.h \ graph.h \ arch$(OBJ) \ arch_cmplt.h \ scotch.h library_arch_f$(OBJ) : library_arch_f.c \ module.h \ common.h \ scotch.h library_arch_build$(OBJ) : library_arch_build.c \ module.h \ common.h \ parser.h \ graph.h \ arch$(OBJ) \ arch_build.h \ mapping.h \ bgraph.h \ bgraph_bipart_st.h \ scotch.h library_arch_build_f$(OBJ) : library_arch_build_f.c \ module.h \ common.h \ scotch.h library_common_f$(OBJ) : library_common_f.c \ module.h \ common.h \ scotch.h library_dgraph$(OBJ) : library_dgraph.c \ module.h \ common.h \ graph.h \ dgraph.h \ ptscotch.h library_dgraph_f$(OBJ) : library_dgraph_f.c \ module.h \ common.h \ ptscotch.h library_dgraph_band$(OBJ) : library_dgraph_band.c \ module.h \ common.h \ dgraph.h \ ptscotch.h library_dgraph_band_f$(OBJ) : library_dgraph_band_f.c \ module.h \ common.h \ ptscotch.h library_dgraph_build$(OBJ) : library_dgraph_build.c \ module.h \ common.h \ dgraph.h \ ptscotch.h library_dgraph_build_f$(OBJ) : library_dgraph_build_f.c \ module.h \ common.h \ ptscotch.h library_dgraph_build_grid3d$(OBJ): library_dgraph_build_grid3d.c \ module.h \ common.h \ dgraph.h \ ptscotch.h library_dgraph_build_grid3d_f$(OBJ): library_dgraph_build_grid3d_f.c \ module.h \ common.h \ ptscotch.h library_dgraph_check$(OBJ) : library_dgraph_check.c \ module.h \ common.h \ dgraph.h \ ptscotch.h library_dgraph_check_f$(OBJ) : library_dgraph_check_f.c \ module.h \ common.h \ ptscotch.h library_dgraph_coarsen$(OBJ) : library_dgraph_coarsen.c \ module.h \ common.h \ dgraph.h \ dgraph_coarsen.h \ ptscotch.h library_dgraph_coarsen_f$(OBJ) : library_dgraph_coarsen_f.c \ module.h \ common.h \ ptscotch.h library_dgraph_gather$(OBJ) : library_dgraph_gather.c \ module.h \ common.h \ dgraph.h \ ptscotch.h library_dgraph_gather_f$(OBJ) : library_dgraph_gather_f.c \ module.h \ common.h \ ptscotch.h library_dgraph_grow$(OBJ) : library_dgraph_grow.c \ module.h \ common.h \ dgraph.h \ ptscotch.h library_dgraph_halo$(OBJ) : library_dgraph_halo.c \ module.h \ common.h \ dgraph.h \ dgraph_halo.h \ ptscotch.h library_dgraph_halo_f$(OBJ) : library_dgraph_halo_f.c \ module.h \ common.h \ ptscotch.h library_dgraph_induce$(OBJ) : library_dgraph_induce.c \ module.h \ common.h \ dgraph.h \ ptscotch.h library_dgraph_induce_f$(OBJ) : library_dgraph_induce_f.c \ module.h \ common.h \ ptscotch.h library_dgraph_io_load$(OBJ) : library_dgraph_io_load.c \ module.h \ common.h \ dgraph.h \ ptscotch.h library_dgraph_io_load_f$(OBJ) : library_dgraph_io_load_f.c \ module.h \ common.h \ ptscotch.h library_dgraph_io_save$(OBJ) : library_dgraph_io_save.c \ module.h \ common.h \ dgraph.h \ ptscotch.h library_dgraph_io_save_f$(OBJ) : library_dgraph_io_save_f.c \ module.h \ common.h \ ptscotch.h library_dgraph_map$(OBJ) : library_dgraph_map.c \ module.h \ common.h \ parser.h \ arch$(OBJ) \ dgraph.h \ dmapping.h \ kdgraph.h \ kdgraph_map_st.h \ library_dmapping.h \ ptscotch.h library_dgraph_map_f$(OBJ) : library_dgraph_map_f.c \ module.h \ common.h \ ptscotch.h library_dgraph_map_view$(OBJ) : library_dgraph_map_view.c \ module.h \ common.h \ parser.h \ dgraph.h \ dgraph_halo.h \ arch$(OBJ) \ dmapping.h \ kdgraph.h \ library_dmapping.h \ ptscotch.h library_dgraph_map_view_f$(OBJ) : library_dgraph_map_view_f.c \ module.h \ common.h \ ptscotch.h library_dgraph_order$(OBJ) : library_dgraph_order.c \ module.h \ common.h \ parser.h \ dgraph.h \ dorder.h \ hdgraph.h \ hdgraph_order_st.h \ ptscotch.h library_dgraph_order_f$(OBJ) : library_dgraph_order_f.c \ module.h \ common.h \ ptscotch.h library_dgraph_order_gather$(OBJ): library_dgraph_order_gather.c \ module.h \ common.h \ dgraph.h \ order.h \ dorder.h \ library_order.h \ ptscotch.h library_dgraph_order_gather_f$(OBJ): library_dgraph_order_gather_f.c \ module.h \ common.h \ ptscotch.h library_dgraph_order_io$(OBJ) : library_dgraph_order_io.c \ module.h \ common.h \ dgraph.h \ dorder.h \ ptscotch.h library_dgraph_order_io_f$(OBJ) : library_dgraph_order_io_f.c \ module.h \ common.h \ ptscotch.h library_dgraph_order_io_block$(OBJ): library_dgraph_order_io_block.c \ module.h \ common.h \ dgraph.h \ dorder.h \ ptscotch.h library_dgraph_order_io_block_f$(OBJ): library_dgraph_order_io_block_f.c \ module.h \ common.h \ ptscotch.h library_dgraph_order_perm$(OBJ) : library_dgraph_order_perm.c \ module.h \ common.h \ dgraph.h \ dorder.h \ ptscotch.h library_dgraph_order_perm_f$(OBJ): library_dgraph_order_perm_f.c \ module.h \ common.h \ ptscotch.h library_dgraph_order_tree_dist$(OBJ): library_dgraph_order_tree_dist.c \ module.h \ common.h \ dgraph.h \ dorder.h \ ptscotch.h library_dgraph_order_tree_dist_f$(OBJ): library_dgraph_order_tree_dist_f.c \ module.h \ common.h \ ptscotch.h library_dgraph_redist$(OBJ) : library_dgraph_redist.c \ module.h \ common.h \ dgraph.h \ ptscotch.h library_dgraph_redist_f$(OBJ) : library_dgraph_redist_f.c \ module.h \ common.h \ ptscotch.h library_dgraph_scatter$(OBJ) : library_dgraph_scatter.c \ module.h \ common.h \ dgraph.h \ ptscotch.h library_dgraph_scatter_f$(OBJ) : library_dgraph_scatter_f.c \ module.h \ common.h \ ptscotch.h library_dgraph_stat$(OBJ) : library_dgraph_stat.c \ module.h \ common.h \ dgraph.h \ ptscotch.h \ library_dgraph_stat.h library_dgraph_stat_f$(OBJ) : library_dgraph_stat_f.c \ module.h \ common.h \ ptscotch.h library_dmapping$(OBJ) : library_dmapping.c \ module.h \ common.h \ ptscotch.h library_dorder$(OBJ) : library_dorder.c \ module.h \ common.h \ ptscotch.h library_error$(OBJ) : library_error.c \ module.h \ common.h \ scotch.h library_error_exit$(OBJ) : library_error_exit.c \ module.h \ common.h \ scotch.h library_error_pt$(OBJ) : library_error.c \ module.h \ common.h \ scotch.h $(CC) $(CFLAGS) $(CLIBFLAGS) -c $(<) -o $(@) library_error_exit_pt$(OBJ) : library_error_exit.c \ module.h \ common.h \ scotch.h $(CC) $(CFLAGS) $(CLIBFLAGS) -c $(<) -o $(@) library_geom$(OBJ) : library_geom.c \ module.h \ common.h \ geom.h \ graph.h \ scotch.h library_geom_f$(OBJ) : library_geom_f.c \ module.h \ common.h \ scotch.h library_graph$(OBJ) : library_graph.c \ module.h \ common.h \ graph.h \ graph_io.h \ scotch.h library_graph_f$(OBJ) : library_graph_f.c \ module.h \ common.h \ scotch.h library_graph_base$(OBJ) : library_graph_base.c \ module.h \ common.h \ graph.h \ scotch.h library_graph_base_f$(OBJ) : library_graph_base_f.c \ module.h \ common.h \ scotch.h library_graph_check$(OBJ) : library_graph_check.c \ module.h \ common.h \ graph.h \ scotch.h library_graph_check_f$(OBJ) : library_graph_check_f.c \ module.h \ common.h \ scotch.h library_graph_coarsen$(OBJ) : library_graph_coarsen.c \ module.h \ common.h \ graph.h \ graph_coarsen.h \ scotch.h library_graph_coarsen_f$(OBJ) : library_graph_coarsen_f.c \ module.h \ common.h \ scotch.h library_graph_color$(OBJ) : library_graph_color.c \ module.h \ common.h \ graph.h \ scotch.h library_graph_color_f$(OBJ) : library_graph_color_f.c \ module.h \ common.h \ scotch.h library_graph_io_chac$(OBJ) : library_graph_io_chac.c \ module.h \ common.h \ geom.h \ graph.h \ scotch.h library_graph_io_chac_f$(OBJ) : library_graph_io_chac_f.c \ module.h \ common.h \ scotch.h library_graph_io_habo$(OBJ) : library_graph_io_habo.c \ module.h \ common.h \ geom.h \ graph.h \ scotch.h library_graph_io_habo_f$(OBJ) : library_graph_io_habo_f.c \ module.h \ common.h \ scotch.h library_graph_io_mmkt$(OBJ) : library_graph_io_mmkt.c \ module.h \ common.h \ geom.h \ graph.h \ scotch.h library_graph_io_mmkt_f$(OBJ) : library_graph_io_mmkt_f.c \ module.h \ common.h \ scotch.h library_graph_io_scot$(OBJ) : library_graph_io_scot.c \ module.h \ common.h \ geom.h \ graph.h \ scotch.h library_graph_io_scot_f$(OBJ) : library_graph_io_scot_f.c \ module.h \ common.h \ scotch.h library_graph_map$(OBJ) : library_graph_map.c \ module.h \ common.h \ parser.h \ graph.h \ arch$(OBJ) \ mapping.h \ kgraph.h \ kgraph_map_st.h \ library_mapping.h \ scotch.h library_graph_map_f$(OBJ) : library_graph_map_f.c \ module.h \ common.h \ scotch.h library_graph_map_io$(OBJ) : library_graph_map_io.c \ module.h \ common.h \ graph.h \ arch$(OBJ) \ library_mapping.h \ library_graph_map_io.h \ scotch.h library_graph_map_io_f$(OBJ) : library_graph_map_io_f.c \ module.h \ common.h \ scotch.h library_graph_map_view$(OBJ) : library_graph_map_view.c \ module.h \ common.h \ parser.h \ graph.h \ arch$(OBJ) \ mapping.h \ kgraph.h \ library_mapping.h \ library_graph_map_view.h \ scotch.h library_graph_map_view_f$(OBJ) : library_graph_map_view_f.c \ module.h \ common.h \ scotch.h library_graph_order$(OBJ) : library_graph_order.c \ module.h \ common.h \ parser.h \ graph.h \ order.h \ hgraph.h \ hgraph_order_st.h \ library_order.h \ scotch.h library_graph_order_f$(OBJ) : library_graph_order_f.c \ module.h \ common.h \ scotch.h library_graph_part_ovl$(OBJ) : library_graph_part_ovl.c \ module.h \ common.h \ parser.h \ graph.h \ wgraph.h \ wgraph_part_st.h \ scotch.h library_graph_part_ovl_f$(OBJ) : library_graph_part_ovl_f.c \ module.h \ common.h \ scotch.h library_mapping$(OBJ) : library_mapping.c \ module.h \ common.h \ scotch.h library_memory$(OBJ) : library_memory.c \ module.h \ common.h \ scotch.h library_memory_f$(OBJ) : library_memory_f.c \ module.h \ common.h \ scotch.h library_mesh$(OBJ) : library_mesh.c \ module.h \ common.h \ graph.h \ mesh.h \ scotch.h library_mesh_f$(OBJ) : library_mesh_f.c \ module.h \ common.h \ scotch.h library_mesh_graph$(OBJ) : library_mesh_graph.c \ module.h \ common.h \ graph.h \ mesh.h \ scotch.h library_mesh_graph_f$(OBJ) : library_mesh_graph_f.c \ module.h \ common.h \ scotch.h library_mesh_io_habo$(OBJ) : library_mesh_io_habo.c \ module.h \ common.h \ geom.h \ graph.h \ mesh.h \ scotch.h library_mesh_io_habo_f$(OBJ) : library_mesh_io_habo_f.c \ module.h \ common.h \ scotch.h library_mesh_io_scot$(OBJ) : library_mesh_io_scot.c \ module.h \ common.h \ geom.h \ graph.h \ mesh.h \ scotch.h library_mesh_io_scot_f$(OBJ) : library_mesh_io_scot_f.c \ module.h \ common.h \ scotch.h library_mesh_order$(OBJ) : library_mesh_order.c \ module.h \ common.h \ parser.h \ graph.h \ mesh.h \ hmesh.h \ order.h \ hmesh_order_st.h \ scotch.h \ library_order.h library_mesh_order_f$(OBJ) : library_mesh_order_f.c \ module.h \ common.h \ scotch.h library_order$(OBJ) : library_order.c \ module.h \ common.h \ scotch.h library_parser$(OBJ) : library_parser.c \ module.h \ common.h \ parser.h \ scotch.h library_parser_f$(OBJ) : library_parser_f.c \ module.h \ common.h \ scotch.h library_random$(OBJ) : library_random.c \ module.h \ common.h \ scotch.h library_random_f$(OBJ) : library_random_f.c \ module.h \ common.h \ scotch.h library_strat$(OBJ) : library_strat.c \ module.h \ common.h \ scotch.h library_version$(OBJ) : library_version.c \ module.h \ common.h \ scotch.h library_version_f$(OBJ) : library_version_f.c \ module.h \ common.h \ scotch.h mapping$(OBJ) : mapping.c \ module.h \ common.h \ graph.h \ arch$(OBJ) \ mapping.h mapping_io$(OBJ) : mapping_io.c \ module.h \ common.h \ graph.h \ arch$(OBJ) \ mapping.h \ mapping_io.h mesh$(OBJ) : mesh.c \ module.h \ common.h \ graph.h \ mesh.h mesh_check$(OBJ) : mesh_check.c \ module.h \ common.h \ graph.h \ mesh.h mesh_coarsen$(OBJ) : mesh_coarsen.c \ module.h \ common.h \ graph.h \ mesh.h mesh_graph$(OBJ) : mesh_graph.c \ module.h \ common.h \ graph.h \ mesh.h \ mesh_graph.h mesh_induce_sepa$(OBJ) : mesh_induce_sepa.c \ module.h \ common.h \ graph.h \ mesh.h \ mesh_induce_sepa.h mesh_io$(OBJ) : mesh_io.c \ module.h \ common.h \ graph.h \ graph_io.h \ mesh.h \ mesh_io.h mesh_io_habo$(OBJ) : mesh_io_habo.c \ module.h \ common.h \ geom.h \ graph.h \ mesh.h mesh_io_scot$(OBJ) : mesh_io_scot.c \ module.h \ common.h \ geom.h \ graph.h \ mesh.h order$(OBJ) : order.c \ module.h \ common.h \ graph.h \ order.h order_check$(OBJ) : order_check.c \ module.h \ common.h \ graph.h \ order.h order_io$(OBJ) : order_io.c \ module.h \ common.h \ graph.h \ order.h order_tree$(OBJ) : order_tree.c \ module.h \ common.h \ graph.h \ order.h parser$(OBJ) : parser.c \ module.h \ common.h \ parser.h \ parser_yy.h parser_ll.c : parser_ll.l \ module.h \ common.h \ parser.h \ parser_ll.h \ parser_ly.h ($(LEX) parser_ll.l && \ $(MV) lex.yy.c parser_ll.c) || \ $(CP) last_resort/parser_ll.c . parser_ll$(OBJ) : parser_ll.c \ parser_ly.h parser_ly.h : parser_yy$(OBJ) parser_yy.c : parser_yy.y \ module.h \ common.h \ parser.h \ parser_yy.h ($(YACC) -d -v parser_yy.y && \ $(MV) y.tab.c parser_yy.c && \ $(MV) y.tab.h parser_ly.h) || \ $(CP) last_resort/parser_ly.h last_resort/parser_yy.c . parser_yy$(OBJ) : parser_yy.c vdgraph$(OBJ) : vdgraph.c \ module.h \ common.h \ dgraph.h \ vdgraph.h vdgraph_check$(OBJ) : vdgraph_check.c \ module.h \ common.h \ dgraph.h \ vdgraph.h vdgraph_gather_all$(OBJ) : vdgraph_gather_all.c \ module.h \ common.h \ comm.h \ graph.h \ vgraph.h \ dgraph.h \ vdgraph.h vdgraph_separate_bd$(OBJ) : vdgraph_separate_bd.c \ module.h \ common.h \ parser.h \ dgraph.h \ vdgraph.h \ vdgraph_separate_bd.h \ vdgraph_separate_st.h vdgraph_separate_df$(OBJ) : vdgraph_separate_df.c \ module.h \ common.h \ dgraph.h \ vdgraph.h \ vdgraph_separate_df.h vdgraph_separate_ml$(OBJ) : vdgraph_separate_ml.c \ module.h \ common.h \ parser.h \ dgraph.h \ dgraph_coarsen.h \ vdgraph.h \ vdgraph_separate_ml.h \ vdgraph_separate_st.h vdgraph_separate_sq$(OBJ) : vdgraph_separate_sq.c \ module.h \ common.h \ comm.h \ parser.h \ graph.h \ vgraph.h \ vgraph_separate_st.h \ dgraph.h \ vdgraph.h \ vdgraph_separate_sq.h vdgraph_separate_st$(OBJ) : vdgraph_separate_st.c \ module.h \ common.h \ parser.h \ graph.h \ vgraph.h \ vgraph_separate_st.h \ dgraph.h \ dgraph_coarsen.h \ vdgraph.h \ vdgraph_separate_bd.h \ vdgraph_separate_df.h \ vdgraph_separate_ml.h \ vdgraph_separate_sq.h \ vdgraph_separate_st.h \ vdgraph_separate_zr.h vdgraph_separate_zr$(OBJ) : vdgraph_separate_zr.c \ module.h \ common.h \ dgraph.h \ vdgraph.h \ vdgraph_separate_zr.h vdgraph_store$(OBJ) : vdgraph_store.c \ module.h \ common.h \ dgraph.h \ vdgraph.h vgraph$(OBJ) : vgraph.c \ module.h \ common.h \ graph.h \ vgraph.h vgraph_check$(OBJ) : vgraph_check.c \ module.h \ common.h \ graph.h \ vgraph.h vgraph_separate_bd$(OBJ) : vgraph_separate_bd.c \ module.h \ common.h \ parser.h \ graph.h \ vgraph.h \ vgraph_separate_bd.h \ vgraph_separate_st.h vgraph_separate_df$(OBJ) : vgraph_separate_df.c \ module.h \ common.h \ graph.h \ vgraph.h \ vgraph_separate_df.h vgraph_separate_es$(OBJ) : vgraph_separate_es.c \ module.h \ common.h \ parser.h \ graph.h \ arch$(OBJ) \ mapping.h \ bgraph.h \ bgraph_bipart_st.h \ vgraph.h \ vgraph_separate_es.h vgraph_separate_fm$(OBJ) : vgraph_separate_fm.c \ module.h \ common.h \ gain.h \ graph.h \ vgraph.h \ vgraph_separate_gg.h \ vgraph_separate_fm.h vgraph_separate_gg$(OBJ) : vgraph_separate_gg.c \ module.h \ common.h \ graph.h \ vgraph.h \ vgraph_separate_gg.h vgraph_separate_gp$(OBJ) : vgraph_separate_gp.c \ module.h \ common.h \ graph.h \ vgraph.h \ vgraph_separate_gp.h vgraph_separate_ml$(OBJ) : vgraph_separate_ml.c \ module.h \ common.h \ parser.h \ graph.h \ graph_coarsen.h \ vgraph.h \ vgraph_separate_ml.h \ vgraph_separate_st.h vgraph_separate_th$(OBJ) : vgraph_separate_th.c \ module.h \ common.h \ graph.h \ vgraph.h \ vgraph_separate_th.h vgraph_separate_vw$(OBJ) : vgraph_separate_vw.c \ module.h \ common.h \ graph.h \ vgraph.h \ vgraph_separate_vw.h vgraph_separate_zr$(OBJ) : vgraph_separate_zr.c \ module.h \ common.h \ graph.h \ vgraph.h \ vgraph_separate_zr.h vgraph_separate_st$(OBJ) : vgraph_separate_st.c \ gain.h \ module.h \ common.h \ parser.h \ graph.h \ arch$(OBJ) \ mapping.h \ bgraph.h \ bgraph_bipart_st.h \ vgraph.h \ vgraph_separate_bd.h \ vgraph_separate_df.h \ vgraph_separate_fm.h \ vgraph_separate_gg.h \ vgraph_separate_gp.h \ vgraph_separate_ml.h \ vgraph_separate_th.h \ vgraph_separate_vw.h \ vgraph_separate_zr.h \ vgraph_separate_st.h vgraph_store$(OBJ) : vgraph_store.c \ module.h \ common.h \ graph.h \ vgraph.h vmesh$(OBJ) : vmesh.c \ module.h \ common.h \ graph.h \ mesh.h \ vmesh.h vmesh_check$(OBJ) : vmesh_check.c \ module.h \ common.h \ graph.h \ mesh.h \ vmesh.h vmesh_separate_fm$(OBJ) : vmesh_separate_fm.c \ module.h \ common.h \ graph.h \ mesh.h \ vmesh.h \ vmesh_separate_fm.h vmesh_separate_gg$(OBJ) : vmesh_separate_gg.c \ module.h \ common.h \ graph.h \ mesh.h \ vmesh.h \ vmesh_separate_gg.h vmesh_separate_gr$(OBJ) : vmesh_separate_gr.c \ module.h \ common.h \ parser.h \ graph.h \ vgraph.h \ vgraph_separate_st.h \ mesh.h \ vmesh.h \ vmesh_separate_gr.h vmesh_separate_ml$(OBJ) : vmesh_separate_ml.c \ module.h \ common.h \ parser.h \ graph.h \ mesh.h \ mesh_coarsen.h \ vmesh.h \ vmesh_separate_ml.h \ vmesh_separate_st.h vmesh_separate_zr$(OBJ) : vmesh_separate_zr.c \ module.h \ common.h \ graph.h \ mesh.h \ vmesh.h \ vmesh_separate_zr.h vmesh_separate_st$(OBJ) : vmesh_separate_st.c \ gain.h \ module.h \ common.h \ parser.h \ graph.h \ mesh.h \ mesh_coarsen.h \ vmesh.h \ vmesh_separate_fm.h \ vmesh_separate_gg.h \ vmesh_separate_gr.h \ vmesh_separate_ml.h \ vmesh_separate_zr.h \ vmesh_separate_st.h vmesh_store$(OBJ) : vmesh_store.c \ module.h \ common.h \ graph.h \ mesh.h \ vmesh.h wgraph$(OBJ) : wgraph.c \ module.h \ common.h \ graph.h \ wgraph.h wgraph_check$(OBJ) : wgraph_check.c \ module.h \ common.h \ graph.h \ wgraph.h wgraph_part_fm$(OBJ) : wgraph_part_fm.c \ module.h \ common.h \ graph.h \ wgraph.h \ wgraph_part_fm.h wgraph_part_gg$(OBJ) : wgraph_part_gg.c \ module.h \ common.h \ graph.h \ wgraph.h \ wgraph_part_gg.h wgraph_part_gp$(OBJ) : wgraph_part_gp.c \ module.h \ common.h \ graph.h \ wgraph.h \ wgraph_part_gp.h wgraph_part_ml$(OBJ) : wgraph_part_ml.c \ module.h \ common.h \ parser.h \ graph.h \ graph_coarsen.h \ wgraph.h \ wgraph_part_ml.h \ wgraph_part_st.h wgraph_part_rb$(OBJ) : wgraph_part_rb.c \ module.h \ common.h \ parser.h \ graph.h \ arch.h \ mapping.h \ vgraph.h \ vgraph_separate_st.h \ vgraph_separate_zr.h \ wgraph.h \ wgraph_part_rb.h \ scotch.h wgraph_part_st$(OBJ) : wgraph_part_st.c \ gain.h \ module.h \ common.h \ parser.h \ graph.h \ graph_coarsen.h \ vgraph.h \ vgraph_separate_st.h \ wgraph.h \ wgraph_part_fm.h \ wgraph_part_gg.h \ wgraph_part_gp.h \ wgraph_part_ml.h \ wgraph_part_rb.h \ wgraph_part_zr.h \ wgraph_part_st.h wgraph_part_zr$(OBJ) : wgraph_part_zr.c \ module.h \ common.h \ graph.h \ wgraph.h \ wgraph_part_zr.h wgraph_store$(OBJ) : wgraph_store.c \ module.h \ common.h \ graph.h \ wgraph.h dummysizes$(EXE) : dummysizes.c \ module.h \ common.h \ arch$(OBJ) \ graph.h \ geom.h \ mesh.h \ mapping.h \ order.h \ parser.h $(CCD) $(CFLAGS) -DSCOTCH_VERSION=$(VERSION) -DSCOTCH_RELEASE=$(RELEASE) -DSCOTCH_PATCHLEVEL=$(PATCHLEVEL) $(<) -o $(@) $(LDFLAGS) ptdummysizes$(EXE) : dummysizes.c \ module.h \ common.h \ dgraph.h \ dorder.h $(CCD) $(CFLAGS) -DSCOTCH_VERSION=$(VERSION) -DSCOTCH_RELEASE=$(RELEASE) -DSCOTCH_PATCHLEVEL=$(PATCHLEVEL) $(<) -o $(@) $(LDFLAGS) scotch.h : dummysizes$(EXE) \ library.h ./dummysizes$(EXE) library.h scotch.h scotchf.h : dummysizes$(EXE) \ library_f.h ./dummysizes$(EXE) library_f.h scotchf.h ptscotch.h : ptdummysizes$(EXE) \ library_pt.h ./ptdummysizes$(EXE) library_pt.h ptscotch.h ptscotchf.h : ptdummysizes$(EXE) \ library_pt_f.h ./ptdummysizes$(EXE) library_pt_f.h ptscotchf.h libscotch$(LIB) : $(LIBSCOTCHDEPS) $(AR) $(ARFLAGS) $(@) $(?) -$(RANLIB) $(@) libscotcherr$(LIB) : library_error$(OBJ) $(AR) $(ARFLAGS) $(@) $(?) -$(RANLIB) $(@) libscotcherrexit$(LIB) : library_error_exit$(OBJ) $(AR) $(ARFLAGS) $(@) $(?) -$(RANLIB) $(@) libptscotch$(LIB) : $(LIBPTSCOTCHDEPS) $(AR) $(ARFLAGS) $(@) $(?) -$(RANLIB) $(@) libptscotcherr$(LIB) : library_error_pt$(OBJ) $(AR) $(ARFLAGS) $(@) $(?) -$(RANLIB) $(@) libptscotcherrexit$(LIB) : library_error_exit_pt$(OBJ) $(AR) $(ARFLAGS) $(@) $(?) -$(RANLIB) $(@) scotch-6.0.4.dfsg/src/libscotch/hgraph_order_st.h0000644002563400244210000001025512037534735025171 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hgraph_order_st.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data **/ /** declarations for the main graph **/ /** ordering routine. **/ /** **/ /** DATES : # Version 3.2 : from : 31 oct 1996 **/ /** to : 29 aug 1998 **/ /** # Version 3.3 : from : 02 oct 1998 **/ /** to 07 sep 2001 **/ /** # Version 4.0 : from : 29 dec 2001 **/ /** to : 15 jan 2003 **/ /** # Version 6.0 : from : 17 oct 2012 **/ /** to : 17 oct 2012 **/ /** **/ /************************************************************/ /* ** The type definitions. */ /*+ Method types. +*/ typedef enum HgraphOrderStMethodType_ { HGRAPHORDERSTMETHBL = 0, /*+ Block splitting post-processing +*/ HGRAPHORDERSTMETHCP, /*+ Graph compression +*/ HGRAPHORDERSTMETHGP, /*+ Gibbs-Poole-Stockmeyer +*/ HGRAPHORDERSTMETHHD, /*+ Block Halo Approximate Minimum Degree +*/ HGRAPHORDERSTMETHHF, /*+ Block Halo Approximate Minimum Fill +*/ HGRAPHORDERSTMETHKP, /*+ K-way block partitioning +*/ HGRAPHORDERSTMETHND, /*+ Nested Dissection +*/ HGRAPHORDERSTMETHSI, /*+ Simple +*/ HGRAPHORDERSTMETHNBR /*+ Number of methods +*/ } HgraphOrderStMethodType; /* ** The external declarations. */ extern StratTab hgraphorderststratab; /* ** The function prototypes. */ #ifndef HGRAPH_ORDER_ST #define static #endif int hgraphOrderSt (const Hgraph * restrict const, Order * restrict const, const Gnum, OrderCblk * restrict const, const Strat * const); #undef static scotch-6.0.4.dfsg/src/libscotch/library_dgraph_grow.c0000644002563400244210000001164712055776322026047 0ustar trophimeutilisateurs du domaine/* Copyright 2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_grow.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the distri- **/ /** buted graph growing routine of **/ /** the libScotch library. **/ /** **/ /** DATES : # Version 6.0 : from : 26 sep 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "dgraph.h" #include "dgraph_halo.h" #include "ptscotch.h" /**********************************/ /* */ /* Distance computation routines. */ /* */ /**********************************/ #define DGRAPHBANDGROWNAME dgraphGrow #define DGRAPHBANDGROWEDGE(n) /* No need to count edges */ #define DGRAPHBANDGROWENQ1 /* Color array already set */ #define DGRAPHBANDGROWENQ2 vnumgsttax[vertlocnum] /* Set vertex color */ #define DGRAPHBANDGROWENQ3 vsnddattab[nsndidxnum ++] = vnumgsttax[vertlocnum] /* Send color value */ #define DGRAPHBANDGROWENQ4 vrcvdatptr[vertrcvnum + 1] /* Get and set color */ #define DGRAPHBANDGROWSMUL(n) ((n) * 2) /* Add space for color value */ #include "dgraph_band_grow.h" #include "dgraph_band_grow.c" #undef DGRAPHBANDGROWNAME #undef DGRAPHBANDGROWEDGE #undef DGRAPHBANDGROWENQ1 #undef DGRAPHBANDGROWENQ2 #undef DGRAPHBANDGROWENQ3 #undef DGRAPHBANDGROWENQ4 #undef DGRAPHBANDGROWSMUL /*********************************/ /* */ /* This routine is the C API for */ /* the graph growing routine. */ /* */ /*********************************/ /*+ This routine grows areas from a given *** set of seeds of some color. Several *** seeds can have the same color. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_dgraphGrow ( SCOTCH_Dgraph * const orggrafptr, const SCOTCH_Num seedlocnbr, SCOTCH_Num * const seedloctab, const SCOTCH_Num distval, SCOTCH_Num * const partgsttab) { Gnum bandvertlocnbr; /* Not used */ Gnum bandvertlvlnum; /* Not used */ Gnum bandedgelocsiz; /* Not used */ Dgraph * restrict const grafptr = (Dgraph *) orggrafptr; if (dgraphGhst (grafptr) != 0) { /* Compute ghost edge array if not already present */ errorPrint ("SCOTCH_dgraphGrow: cannot compute ghost edge array"); return (1); } return ((((grafptr->flagval & DGRAPHCOMMPTOP) != 0) ? dgraphGrowPtop : dgraphGrowColl) (grafptr, seedlocnbr, seedloctab, distval, partgsttab - grafptr->baseval, &bandvertlvlnum, &bandvertlocnbr, &bandedgelocsiz)); } scotch-6.0.4.dfsg/src/libscotch/kdgraph_map_st.c0000644002563400244210000002021211631447170024762 0ustar trophimeutilisateurs du domaine/* Copyright 2008-2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kdgraph_map_st.c **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the strategy and **/ /** method tables for the parallel **/ /** multi-way static mapping routines. **/ /** **/ /** DATES : # Version 5.1 : from : 16 jun 2008 **/ /** to 14 apr 2011 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define KDGRAPH_MAP_ST #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "dgraph.h" #include "dgraph_coarsen.h" #include "arch.h" #include "mapping.h" #include "dmapping.h" #include "bdgraph.h" #include "bdgraph_bipart_st.h" #include "kgraph.h" #include "kgraph_map_st.h" #include "kdgraph.h" #include "kdgraph_map_rb.h" #include "kdgraph_map_st.h" /* ** The static and global variables. */ static union { KdgraphMapRbParam param; StratNodeMethodData padding; } kdgraphmapstdefaultrb = { { &stratdummy, &stratdummy, 0.05 } }; static StratMethodTab kdgraphmapstmethtab[] = { /* Mapping methods array */ { KDGRAPHMAPSTMETHRB, "r", kdgraphMapRb, &kdgraphmapstdefaultrb }, { -1, NULL, NULL, NULL } }; static StratParamTab kdgraphmapstparatab[] = { /* Method parameter list */ { KDGRAPHMAPSTMETHRB, STRATPARAMSTRAT, "sep", (byte *) &kdgraphmapstdefaultrb.param, (byte *) &kdgraphmapstdefaultrb.param.stratsep, (void *) &bdgraphbipartststratab }, { KDGRAPHMAPSTMETHRB, STRATPARAMSTRAT, "seq", (byte *) &kdgraphmapstdefaultrb.param, (byte *) &kdgraphmapstdefaultrb.param.stratseq, (void *) &kgraphmapststratab }, { KDGRAPHMAPSTMETHRB, STRATPARAMDOUBLE, "bal", (byte *) &kdgraphmapstdefaultrb.param, (byte *) &kdgraphmapstdefaultrb.param.kbalval, NULL }, { KDGRAPHMAPSTMETHNBR, STRATPARAMINT, NULL, NULL, NULL, NULL } }; static StratParamTab kdgraphmapstcondtab[] = { /* Graph condition parameter table */ { STRATNODENBR, STRATPARAMINT, NULL, NULL, NULL, NULL } }; StratTab kdgraphmapststratab = { /* Strategy tables for graph mapping methods */ kdgraphmapstmethtab, kdgraphmapstparatab, kdgraphmapstcondtab }; /****************************************/ /* */ /* This is the generic mapping routine. */ /* */ /****************************************/ /* This routine computes the given ** mapping according to the given ** strategy. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int kdgraphMapSt ( Kdgraph * restrict const grafptr, /*+ Mapping graph +*/ Kdmapping * restrict const mappptr, /*+ Dynamic mapping +*/ const Strat * restrict const strat) /*+ Mapping strategy +*/ { StratTest val; int o; #ifdef SCOTCH_DEBUG_KDGRAPH2 if (sizeof (Gnum) != sizeof (INT)) { errorPrint ("kdgraphMapSt: invalid type specification for parser variables"); return (1); } if ((sizeof (KdgraphMapRbParam) > sizeof (StratNodeMethodData))) { errorPrint ("kdgraphMapSt: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_KDGRAPH2 */ #ifdef SCOTCH_DEBUG_KDGRAPH1 if ((strat->tabl != &kdgraphmapststratab) && (strat != &stratdummy)) { errorPrint ("kdgraphMapSt: invalid parameter (1)"); return (1); } #endif /* SCOTCH_DEBUG_KDGRAPH1 */ o = 0; switch (strat->type) { case STRATNODECONCAT : o = kdgraphMapSt (grafptr, mappptr, strat->data.concat.strat[0]); /* Apply first strategy */ if (o == 0) /* If it worked all right */ o |= kdgraphMapSt (grafptr, mappptr, strat->data.concat.strat[1]); /* Then apply second strategy */ break; case STRATNODECOND : o = stratTestEval (strat->data.cond.test, &val, (void *) grafptr); /* Evaluate expression */ if (o == 0) { /* If evaluation was correct */ #ifdef SCOTCH_DEBUG_KDGRAPH2 if ((val.typetest != STRATTESTVAL) || (val.typenode != STRATPARAMLOG)) { errorPrint ("kdgraphMapSt: invalid test result"); o = 1; break; } #endif /* SCOTCH_DEBUG_KDGRAPH2 */ if (val.data.val.vallog == 1) /* If expression is true */ o = kdgraphMapSt (grafptr, mappptr, strat->data.cond.strat[0]); /* Apply first strategy */ else { /* Else if expression is false */ if (strat->data.cond.strat[1] != NULL) /* And if there is an else statement */ o = kdgraphMapSt (grafptr, mappptr, strat->data.cond.strat[1]); /* Apply second strategy */ } } break; case STRATNODEEMPTY : break; case STRATNODESELECT : errorPrint ("kdgraphMapSt: selection operator not implemented for k-way strategies"); return (1); #ifdef SCOTCH_DEBUG_KDGRAPH1 case STRATNODEMETHOD : #else /* SCOTCH_DEBUG_KDGRAPH1 */ default : #endif /* SCOTCH_DEBUG_KDGRAPH1 */ return (strat->tabl->methtab[strat->data.method.meth].func (grafptr, mappptr, (void *) &strat->data.method.data)); #ifdef SCOTCH_DEBUG_KDGRAPH1 default : errorPrint ("kdgraphMapSt: invalid parameter (2)"); return (1); #endif /* SCOTCH_DEBUG_KDGRAPH1 */ } return (o); } scotch-6.0.4.dfsg/src/libscotch/library_pt.h0000644002563400244210000002630412056363620024162 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007-2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_pt.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Jun-Ho HER (v6.0) **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : Declaration file for the LibPtscotch **/ /** parallel static mapping and sparse **/ /** matrix block ordering library. **/ /** **/ /** DATES : # Version 3.2 : from : 07 sep 1996 **/ /** to 22 aug 1998 **/ /** # Version 3.3 : from : 02 oct 1998 **/ /** to 31 may 1999 **/ /** # Version 3.4 : from : 10 oct 1999 **/ /** to 15 nov 2001 **/ /** # Version 4.0 : from : 11 dec 2001 **/ /** to 20 dec 2005 **/ /** # Version 5.0 : from : 26 apr 2006 **/ /** to : 20 feb 2008 **/ /** # Version 5.1 : from : 30 nov 2007 **/ /** to : 07 aug 2011 **/ /** # Version 6.0 : from : 12 sep 2008 **/ /** to 01 dec 2012 **/ /** **/ /************************************************************/ #ifndef PTSCOTCH_H #define PTSCOTCH_H /* ** The defines and includes. */ #ifndef SCOTCH_H #include "scotch.h" #endif /* SCOTCH_H */ /* ** The type and structure definitions. */ /*+ Parallel processing flag. +*/ #ifndef SCOTCH_PTSCOTCH #define SCOTCH_DUMMYPTFLAG #endif /* SCOTCH_PTSCOTCH */ /*+ Opaque objects. The dummy sizes of these objects, computed at compile-time by program "dummysizes", are given as double values for proper padding +*/ typedef struct { double dummy[DUMMYSIZEDGRAPH]; } SCOTCH_Dgraph; typedef struct { double dummy[DUMMYSIZEDGRAPHHALOREQ]; } SCOTCH_DgraphHaloReq; typedef struct { double dummy[DUMMYSIZEDMAP]; } SCOTCH_Dmapping; typedef struct { double dummy[DUMMYSIZEDORDER]; } SCOTCH_Dordering; /* ** The function prototypes. */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ SCOTCH_Dgraph * SCOTCH_dgraphAlloc (void); int SCOTCH_dgraphInit (SCOTCH_Dgraph * const, MPI_Comm); void SCOTCH_dgraphExit (SCOTCH_Dgraph * const); void SCOTCH_dgraphFree (SCOTCH_Dgraph * const); int SCOTCH_dgraphLoad (SCOTCH_Dgraph * const, FILE * const, const SCOTCH_Num, const SCOTCH_Num); int SCOTCH_dgraphSave (SCOTCH_Dgraph * const, FILE * const); int SCOTCH_dgraphCheck (const SCOTCH_Dgraph * const); int SCOTCH_dgraphBand (SCOTCH_Dgraph * const, const SCOTCH_Num, SCOTCH_Num * const, const SCOTCH_Num, SCOTCH_Dgraph * const); int SCOTCH_dgraphBuild (SCOTCH_Dgraph * const, const SCOTCH_Num, const SCOTCH_Num, const SCOTCH_Num, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, const SCOTCH_Num, const SCOTCH_Num, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const); int SCOTCH_dgraphBuildGrid3D (SCOTCH_Dgraph * const, const SCOTCH_Num, const SCOTCH_Num, const SCOTCH_Num, const SCOTCH_Num, const SCOTCH_Num, const int); int SCOTCH_dgraphCoarsen (SCOTCH_Dgraph * const, const SCOTCH_Num, const double, const SCOTCH_Num, SCOTCH_Dgraph * const, SCOTCH_Num * const); int SCOTCH_dgraphGather (const SCOTCH_Dgraph * const, SCOTCH_Graph * const); int SCOTCH_dgraphGrow (SCOTCH_Dgraph * const, const SCOTCH_Num, SCOTCH_Num * const, const SCOTCH_Num, SCOTCH_Num * const); int SCOTCH_dgraphInducePart (SCOTCH_Dgraph * const, const SCOTCH_Num * const, const SCOTCH_Num, const SCOTCH_Num, SCOTCH_Dgraph * const); int SCOTCH_dgraphScatter (SCOTCH_Dgraph * const, const SCOTCH_Graph * const); int SCOTCH_dgraphRedist (SCOTCH_Dgraph * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num, const SCOTCH_Num, SCOTCH_Dgraph * const); void SCOTCH_dgraphSize (const SCOTCH_Dgraph * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const); void SCOTCH_dgraphData (const SCOTCH_Dgraph * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num ** const, SCOTCH_Num ** const, SCOTCH_Num ** const, SCOTCH_Num ** const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num ** const, SCOTCH_Num ** const, SCOTCH_Num ** const, MPI_Comm * const); int SCOTCH_dgraphStat (const SCOTCH_Dgraph * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, double * const, double * const, SCOTCH_Num * const, SCOTCH_Num * const, double * const, double * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, double * const, double * const); int SCOTCH_dgraphGhst (SCOTCH_Dgraph * const); int SCOTCH_dgraphHalo (SCOTCH_Dgraph * const, void * const, const MPI_Datatype); int SCOTCH_dgraphHaloAsync (SCOTCH_Dgraph * const, void * const, const MPI_Datatype, SCOTCH_DgraphHaloReq * const); SCOTCH_DgraphHaloReq * SCOTCH_dgraphHaloReqAlloc (void); int SCOTCH_dgraphHaloWait (SCOTCH_DgraphHaloReq * const); int SCOTCH_dgraphMapInit (const SCOTCH_Dgraph * const, SCOTCH_Dmapping * const, const SCOTCH_Arch * const, SCOTCH_Num * const); void SCOTCH_dgraphMapExit (const SCOTCH_Dgraph * const, SCOTCH_Dmapping * const); int SCOTCH_dgraphMapSave (const SCOTCH_Dgraph * const, const SCOTCH_Dmapping * const, FILE * const); int SCOTCH_dgraphMapView (SCOTCH_Dgraph * const, const SCOTCH_Dmapping * const, FILE * const); int SCOTCH_dgraphMapCompute (SCOTCH_Dgraph * const, SCOTCH_Dmapping * const, SCOTCH_Strat * const); int SCOTCH_dgraphMap (SCOTCH_Dgraph * const, const SCOTCH_Arch * const, SCOTCH_Strat * const, SCOTCH_Num * const); int SCOTCH_dgraphPart (SCOTCH_Dgraph * const, const SCOTCH_Num, SCOTCH_Strat * const, SCOTCH_Num * const); int SCOTCH_dgraphCorderInit (const SCOTCH_Dgraph * const, SCOTCH_Ordering * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const); void SCOTCH_dgraphCorderExit (const SCOTCH_Dgraph * const, SCOTCH_Ordering * const); int SCOTCH_dgraphOrderInit (const SCOTCH_Dgraph * const, SCOTCH_Dordering * const); void SCOTCH_dgraphOrderExit (const SCOTCH_Dgraph * const, SCOTCH_Dordering * const); int SCOTCH_dgraphOrderSave (const SCOTCH_Dgraph * const, const SCOTCH_Dordering * const, FILE * const); int SCOTCH_dgraphOrderSaveBlock (const SCOTCH_Dgraph * const, const SCOTCH_Dordering * const, FILE * const); int SCOTCH_dgraphOrderSaveMap (const SCOTCH_Dgraph * const, const SCOTCH_Dordering * const, FILE * const); int SCOTCH_dgraphOrderSaveTree (const SCOTCH_Dgraph * const, const SCOTCH_Dordering * const, FILE * const); int SCOTCH_dgraphOrderPerm (const SCOTCH_Dgraph * const, const SCOTCH_Dordering * const, SCOTCH_Num * const); SCOTCH_Num SCOTCH_dgraphOrderCblkDist (const SCOTCH_Dgraph * const, const SCOTCH_Dordering * const); int SCOTCH_dgraphOrderTreeDist (const SCOTCH_Dgraph * const, const SCOTCH_Dordering * const, SCOTCH_Num * const, SCOTCH_Num * const); int SCOTCH_dgraphOrderCompute (SCOTCH_Dgraph * const, SCOTCH_Dordering * const, SCOTCH_Strat * const); int SCOTCH_dgraphOrderComputeList (SCOTCH_Dgraph * const, SCOTCH_Dordering * const, const SCOTCH_Num, const SCOTCH_Num * const, SCOTCH_Strat * const); int SCOTCH_dgraphOrderGather (const SCOTCH_Dgraph * const, const SCOTCH_Dordering * const, SCOTCH_Ordering * const); SCOTCH_Dmapping * SCOTCH_dmapAlloc (void); SCOTCH_Dordering * SCOTCH_dorderAlloc (void); int SCOTCH_stratDgraphMap (SCOTCH_Strat * const, const char * const); int SCOTCH_stratDgraphMapBuild (SCOTCH_Strat * const, const SCOTCH_Num, const SCOTCH_Num, const SCOTCH_Num, const double); int SCOTCH_stratDgraphClusterBuild (SCOTCH_Strat * const, const SCOTCH_Num, const SCOTCH_Num, const SCOTCH_Num, const double, const double); int SCOTCH_stratDgraphOrder (SCOTCH_Strat * const, const char * const); int SCOTCH_stratDgraphOrderBuild (SCOTCH_Strat * const, const SCOTCH_Num, const SCOTCH_Num, const SCOTCH_Num, const double); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PTSCOTCH_H */ scotch-6.0.4.dfsg/src/libscotch/dmapping.h0000644002563400244210000001171111631447171023610 0ustar trophimeutilisateurs du domaine/* Copyright 2008,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dmapping.h **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** Jun-Ho HER (v6.0) **/ /** **/ /** FUNCTION : These lines are the declarations for **/ /** the parallel mapping handling routines. **/ /** **/ /** DATES : # Version 5.1 : from : 31 mar 2008 **/ /** to 04 nov 2010 **/ /** **/ /************************************************************/ #define DMAPPING_H /* ** The type definitions. */ /*+ This structure defines a mapping fragment. +*/ typedef struct DmappingFrag_ { struct DmappingFrag_ * nextptr; /*+ Pointer to next fragment +*/ Gnum vertnbr; /*+ Number of local vertices in mapping +*/ Gnum * vnumtab; /*+ Vertex index array +*/ Anum * parttab; /*+ Mapping array [vertlocnbr] +*/ Anum domnnbr; /*+ Local number of domains +*/ ArchDom * domntab; /*+ Array of domains [domnnbr] +*/ } DmappingFrag; /*+ This structure defines an (eventually partial) mapping of a source graph to a target architecture. +*/ typedef struct Dmapping_ { struct DmappingFrag_ * fragptr; /*+ Pointer to first mapping fragment +*/ Gnum fragnbr; /*+ Number of local fragments +*/ Gnum vertlocmax; /*+ Size of biggest local fragment +*/ Gnum vertlocnbr; /*+ Number of local vertices in mapping +*/ Arch archdat; /*+ Architecture data +*/ #ifdef SCOTCH_PTHREAD pthread_mutex_t mutelocdat; /*+ Local mutex for updates +*/ #endif /* SCOTCH_PTHREAD */ } Dmapping; /*+ The sort structure, used to sort mapped vertices. Field vertnum is first and field termnum is a Gnum and not an Anum because of intSort2asc1. +*/ typedef struct DmappingTermSort_ { Gnum vertnum; /*+ Vertex number: FIRST +*/ Gnum termnum; /*+ Direct permutation index +*/ } DmappingTermSort; /* ** The function prototypes. */ #ifndef DMAPPING #define static #endif int dmapInit (Dmapping * restrict const, const Arch * restrict const); void dmapExit (Dmapping * const); void dmapAdd (Dmapping * restrict const, DmappingFrag * restrict const); int dmapSave (const Dmapping * restrict const, const Dgraph * restrict const, FILE * restrict const); int dmapTerm (const Dmapping * restrict const, const Dgraph * restrict const, Gnum * restrict const); #undef static scotch-6.0.4.dfsg/src/libscotch/dgraph_allreduce.c0000644002563400244210000001022011631447170025262 0ustar trophimeutilisateurs du domaine/* Copyright 2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_allreduce.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the distributed source **/ /** graph building routines. **/ /** **/ /** DATES : # Version 5.0 : from : 28 aug 2006 **/ /** to : 28 aug 2006 **/ /** **/ /************************************************************/ #define DGRAPH #include "module.h" #include "common.h" #include "dgraph.h" /* This routine creates an allreduce operator from ** the function pointer that is passed to it, and ** use it to perform an allreduce operation on the ** given data. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int dgraphAllreduceMaxSum2 ( Gnum * reduloctab, /* Pointer to array of local Gnum data */ Gnum * reduglbtab, /* Pointer to array of reduced Gnum data */ int redumaxsumnbr, /* Number of max + sum Gnum operations */ MPI_User_function * redufuncptr, /* Pointer to operator function */ MPI_Comm proccomm) /* Communicator to be used for reduction */ { MPI_Datatype redutypedat; /* Data type for finding best separator */ MPI_Op reduoperdat; /* Handle of MPI operator for finding best separator */ if ((MPI_Type_contiguous (redumaxsumnbr, GNUM_MPI, &redutypedat) != MPI_SUCCESS) || (MPI_Type_commit (&redutypedat) != MPI_SUCCESS) || (MPI_Op_create (redufuncptr, 1, &reduoperdat) != MPI_SUCCESS)) { errorPrint ("dgraphAllreduceMaxSum: communication error (1)"); return (1); } if (MPI_Allreduce (reduloctab, reduglbtab, 1, redutypedat, reduoperdat, proccomm) != MPI_SUCCESS) { errorPrint ("dgraphAllreduceMaxSum: communication error (2)"); return (1); } if ((MPI_Op_free (&reduoperdat) != MPI_SUCCESS) || (MPI_Type_free (&redutypedat) != MPI_SUCCESS)) { errorPrint ("dgraphAllreduceMaxSum: communication error (3)"); return (1); } return (0); } scotch-6.0.4.dfsg/src/libscotch/bdgraph_bipart_zr.c0000644002563400244210000000663211631447170025474 0ustar trophimeutilisateurs du domaine/* Copyright 2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bdgraph_bipart_zr.c **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** **/ /** FUNCTION : This module moves all of the vertices **/ /** to the first subdomain of the **/ /** bipartition. **/ /** **/ /** DATES : # Version 5.1 : from : 10 sep 2007 **/ /** to 26 oct 2007 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define BDGRAPH_BIPART_ZR #include "module.h" #include "common.h" #include "arch.h" #include "dgraph.h" #include "bdgraph.h" #include "bdgraph_bipart_zr.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine moves all of the graph vertices ** to the first part of the partition. ** It returns: ** - 0 : if the bipartitioning could be computed. ** - !0 : on error. */ int bdgraphBipartZr ( Bdgraph * const grafptr) /*+ Active graph +*/ { if (grafptr->compglbload0 != grafptr->s.veloglbsum) /* If not all vertices already in part zero */ bdgraphZero (grafptr); #ifdef SCOTCH_DEBUG_BDGRAPH2 if (bdgraphCheck (grafptr) != 0) { errorPrint ("bdgraphBipartZr: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_BDGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/hgraph_order_cp.h0000644002563400244210000001102212473176270025136 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hgraph_order_cp.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the graph compression **/ /** ordering routine. **/ /** **/ /** DATES : # Version 3.2 : from : 29 aug 1998 **/ /** to : 09 sep 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to : 03 jan 1999 **/ /** # Version 4.0 : from : 01 jan 2003 **/ /** to : 01 jan 2003 **/ /** # Version 5.1 : from : 04 nov 2010 **/ /** to : 04 nov 2010 **/ /** # Version 6.0 : from : 09 nov 2014 **/ /** to 09 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ Prime number for hashing vertex numbers. +*/ #define HGRAPHORDERCPHASHPRIME 17 /* Prime number */ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct HgraphOrderCpParam_ { double comprat; /*+ Compression ratio threshold +*/ Strat * stratcpr; /*+ Compressed subgraph ordering strategy +*/ Strat * stratunc; /*+ Uncompressed subgraph ordering strategy +*/ } HgraphOrderCpParam; /*+ This structure holds fine neighbor hashing data. +*/ typedef struct HgraphOrderCpHash_ { Gnum vertnum; /*+ Origin vertex (i.e. pass) number +*/ Gnum vertend; /*+ Adjacent end vertex number +*/ } HgraphOrderCpHash; /*+ This structure holds coarse neighbor mate data. +*/ typedef struct HgraphOrderCpMate_ { Gnum coarvertend; /*+ Adjacent coarse end vertex number +*/ Gnum finevertend; /*+ Adjacent end vertex number +*/ } HgraphOrderCpMate; /* ** The function prototypes. */ #ifndef HGRAPH_ORDER_CP #define static #endif int hgraphOrderCp (const Hgraph * const, Order * const, const Gnum, OrderCblk * const, const HgraphOrderCpParam * const); static Gnum hgraphOrderCpTree (const Gnum * const, const Gnum * const, OrderCblk * const, const Gnum); #undef static scotch-6.0.4.dfsg/src/libscotch/library_dgraph_build.c0000644002563400244210000001414012055775550026161 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_build.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the distri- **/ /** buted source graph handling routines of **/ /** the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 23 feb 2007 **/ /** to 18 jul 2007 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "dgraph.h" #include "ptscotch.h" /****************************************/ /* */ /* These routines are the C API for the */ /* distributed graph handling routines. */ /* */ /****************************************/ /*+ This routine fills the contents of the given *** opaque distributed graph structure with the *** data provided by the user. The base value *** allows the user to set the graph base to 0 or 1. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_dgraphBuild ( SCOTCH_Dgraph * const grafptr, /* Distributed graph structure to fill */ const Gnum baseval, /* Base for indexing */ const Gnum vertlocnbr, /* Number of local vertices */ const Gnum vertlocmax, /* Maximum number of local vertices */ Gnum * const vertloctab, /* Local vertex begin array */ Gnum * const vendloctab, /* Local vertex end array */ Gnum * const veloloctab, /* Local vertex load array (if any) */ Gnum * const vlblloctab, /* Local vertex label array (if any) */ const Gnum edgelocnbr, /* Number of local edges */ const Gnum edgelocsiz, /* Size of local edge array */ Gnum * const edgeloctab, /* Local edge array */ Gnum * const edgegsttab, /* Ghost edge array (if any); not const */ Gnum * const edloloctab) /* Local edge load array (if any) */ { Dgraph * srcgrafptr; /* Pointer to source graph structure */ Gnum * vertloctax; Gnum * vendloctax; Gnum * veloloctax; Gnum * vlblloctax; Gnum * edgeloctax; Gnum * edgegsttax; Gnum * edloloctax; #ifdef SCOTCH_DEBUG_LIBRARY1 if (sizeof (SCOTCH_Dgraph) < sizeof (Dgraph)) { errorPrint ("SCOTCH_dgraphBuild: internal error"); return (1); } #endif /* SCOTCH_DEBUG_LIBRARY1 */ if ((baseval < 0) || (baseval > 1)) { errorPrint ("SCOTCH_dgraphBuild: invalid base parameter"); return (1); } srcgrafptr = (Dgraph *) grafptr; /* Use structure as source graph */ vertloctax = (Gnum *) vertloctab - baseval; vendloctax = ((vendloctab == NULL) || (vendloctab == vertloctab + 1)) ? vertloctax + 1 : (Gnum *) vendloctab - baseval; veloloctax = ((veloloctab == NULL) || (veloloctab == vertloctab)) ? NULL : (Gnum *) veloloctab - baseval; vlblloctax = ((vlblloctab == NULL) || (vlblloctab == vertloctab)) ? NULL : (Gnum *) vlblloctab - baseval; edgeloctax = (Gnum *) edgeloctab - baseval; edgegsttax = ((edgegsttab == NULL) || (edgegsttab == edgeloctab)) ? NULL : (Gnum *) edgegsttab - baseval; edloloctax = ((edloloctab == NULL) || (edloloctab == edgeloctab)) ? NULL : (Gnum *) edloloctab - baseval; return (dgraphBuild (srcgrafptr, baseval, vertlocnbr, vertlocmax, vertloctax, vendloctax, veloloctax, NULL, vlblloctax, edgelocnbr, edgelocsiz, edgeloctax, edgegsttax, edloloctax)); } scotch-6.0.4.dfsg/src/libscotch/library_graph_color_f.c0000644002563400244210000000637711700334740026342 0ustar trophimeutilisateurs du domaine/* Copyright 2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_coarsen_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the Fortran API for the **/ /** graph coloring routine of the libSCOTCH **/ /** library. **/ /** **/ /** DATES : # Version 6.0 : from : 02 jan 2012 **/ /** to 02 jan 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the coloring routine. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFGRAPHCOLOR, scotchfgraphcolor, ( \ const SCOTCH_Graph * const grafptr, \ SCOTCH_Num * const colotab, \ SCOTCH_Num * const coloptr, \ const SCOTCH_Num * const flagptr, \ int * const revaptr), \ (grafptr, colotab, coloptr, flagptr, revaptr)) { *revaptr = SCOTCH_graphColor (grafptr, colotab, coloptr, *flagptr); } scotch-6.0.4.dfsg/src/libscotch/order_io.c0000644002563400244210000002361611631447171023615 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : order_io.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles generic orderings. **/ /** **/ /** DATES : # Version 3.2 : from : 19 oct 1996 **/ /** to 27 aug 1998 **/ /** # Version 4.0 : from : 19 dec 2001 **/ /** to 28 jun 2004 **/ /** # Version 5.0 : from : 12 sep 2007 **/ /** to 27 feb 2008 **/ /** # Version 5.1 : from : 11 aug 2010 **/ /** to 11 aug 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define ORDER_IO #include "module.h" #include "common.h" #include "graph.h" #include "order.h" /************************************/ /* */ /* These routines handle orderings. */ /* */ /************************************/ /* This routine loads an ordering. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int orderLoad ( Order * restrict const ordeptr, const Gnum * restrict const vlbltab, FILE * restrict const stream) { Gnum * restrict permtab; Gnum vertnum; if (vlbltab != NULL) { errorPrint ("orderLoad: vertex labels not yet supported"); return (1); } if ((permtab = memAlloc (ordeptr->vnodnbr * sizeof (Gnum))) == NULL) { errorPrint ("orderLoad: out of memory"); return (1); } if (intLoad (stream, &ordeptr->vnodnbr) != 1) { errorPrint ("orderLoad: bad input (1)"); memFree (permtab); return (1); } if (vlbltab == NULL) { /* If ordering does not have label array */ for (vertnum = 0; vertnum < ordeptr->vnodnbr; vertnum ++) { Gnum vertval; if ((intLoad (stream, &vertval) != 1) || /* Read item data */ (intLoad (stream, &permtab[vertnum]) != 1)) { errorPrint ("orderLoad: bad input (2)"); memFree (permtab); return (1); } if (vertval != (vertnum + ordeptr->baseval)) { /* Read item data */ errorPrint ("orderLoad: bad input (3)"); memFree (permtab); return (1); } } } orderPeri (permtab, ordeptr->baseval, ordeptr->vnodnbr, ordeptr->peritab, ordeptr->baseval); /* Compute inverse permutation */ memFree (permtab); return (0); } /* This routine saves an ordering. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int orderSave ( const Order * restrict const ordeptr, const Gnum * restrict const vlbltab, FILE * restrict const stream) { const Gnum * restrict vlbltax; Gnum * restrict permtab; Gnum vertnum; vlbltax = (vlbltab != NULL) ? (vlbltab - ordeptr->baseval) : NULL; if ((permtab = memAlloc (ordeptr->vnodnbr * sizeof (Gnum))) == NULL) { errorPrint ("orderSave: out of memory"); return (1); } if (fprintf (stream, GNUMSTRING "\n", (Gnum) ordeptr->vnodnbr) == EOF) { errorPrint ("orderSave: bad output (1)"); memFree (permtab); return (1); } orderPeri (ordeptr->peritab, ordeptr->baseval, ordeptr->vnodnbr, permtab, ordeptr->baseval); /* Compute direct permutation */ if (vlbltax != NULL) { /* If ordering has label array */ for (vertnum = 0; vertnum < ordeptr->vnodnbr; vertnum ++) { if (fprintf (stream, GNUMSTRING "\t" GNUMSTRING "\n", (Gnum) vlbltax[vertnum + ordeptr->baseval], (Gnum) vlbltax[permtab[vertnum]]) == EOF) { errorPrint ("orderSave: bad output (2)"); memFree (permtab); return (1); } } } else { for (vertnum = 0; vertnum < ordeptr->vnodnbr; vertnum ++) { if (fprintf (stream, GNUMSTRING "\t" GNUMSTRING "\n", (Gnum) (vertnum + ordeptr->baseval), (Gnum) permtab[vertnum]) == EOF) { errorPrint ("orderSave: bad output (3)"); memFree (permtab); return (1); } } } memFree (permtab); return (0); } /* This routine saves the column block ** mapping data of the given ordering. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int orderSaveMap ( const Order * restrict const ordeptr, const Gnum * restrict const vlbltab, FILE * const stream) { const Gnum * restrict vlbltax; const Gnum * restrict peritax; Gnum * restrict rangtab; Gnum * restrict cblktax; Gnum vnodnnd; Gnum vnodnum; Gnum cblknum; int o; if (fprintf (stream, GNUMSTRING "\n", (Gnum) ordeptr->vnodnbr) == EOF) { errorPrint ("orderSaveMap: bad output (1)"); return (1); } if (memAllocGroup ((void **) (void *) &rangtab, (size_t) ((ordeptr->vnodnbr + 1) * sizeof (Gnum)), &cblktax, (size_t) ( ordeptr->vnodnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("orderSaveMap: out of memory"); return (1); } cblktax -= ordeptr->baseval; orderRang (ordeptr, rangtab); peritax = ordeptr->peritab - ordeptr->baseval; for (vnodnum = ordeptr->baseval, vnodnnd = vnodnum + ordeptr->vnodnbr, cblknum = 0; vnodnum < vnodnnd; vnodnum ++) { if (vnodnum >= rangtab[cblknum + 1]) cblknum ++; cblktax[peritax[vnodnum]] = cblknum; } vlbltax = (vlbltab != NULL) ? (vlbltab - ordeptr->baseval) : NULL; for (vnodnum = ordeptr->baseval, o = 0; vnodnum < vnodnnd; vnodnum ++) { if (fprintf (stream, GNUMSTRING "\t" GNUMSTRING "\n", (Gnum) ((vlbltax != NULL) ? vlbltax[vnodnum] : vnodnum), (Gnum) cblktax[vnodnum]) == EOF) { errorPrint ("orderSaveMap: bad output (2)"); o = 1; break; } } memFree (rangtab); /* Free memory group leader */ return (o); } /* This routine saves the separator ** tree data of the given ordering. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int orderSaveTree ( const Order * restrict const ordeptr, const Gnum * restrict const vlbltab, FILE * const stream) { const Gnum * restrict vlbltax; const Gnum * restrict peritax; Gnum * restrict rangtab; Gnum * restrict treetab; Gnum * restrict cblktax; Gnum vnodnnd; Gnum vnodnum; Gnum cblknum; int o; if (fprintf (stream, GNUMSTRING "\n", (Gnum) ordeptr->vnodnbr) == EOF) { errorPrint ("orderSaveTree: bad output (1)"); return (1); } if (memAllocGroup ((void **) (void *) &rangtab, (size_t) ((ordeptr->vnodnbr + 1) * sizeof (Gnum)), &treetab, (size_t) ( ordeptr->vnodnbr * sizeof (Gnum)), &cblktax, (size_t) ( ordeptr->vnodnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("orderSaveTree: out of memory"); return (1); } cblktax -= ordeptr->baseval; orderRang (ordeptr, rangtab); orderTree (ordeptr, treetab); peritax = ordeptr->peritab - ordeptr->baseval; for (vnodnum = ordeptr->baseval, vnodnnd = vnodnum + ordeptr->vnodnbr, cblknum = 0; vnodnum < vnodnnd; vnodnum ++) { if (vnodnum >= rangtab[cblknum + 1]) cblknum ++; cblktax[peritax[vnodnum]] = treetab[cblknum]; } vlbltax = (vlbltab != NULL) ? (vlbltab - ordeptr->baseval) : NULL; for (vnodnum = ordeptr->baseval, o = 0; vnodnum < vnodnnd; vnodnum ++) { if (fprintf (stream, GNUMSTRING "\t" GNUMSTRING "\n", (Gnum) ((vlbltax != NULL) ? vlbltax[vnodnum] : vnodnum), (Gnum) cblktax[vnodnum]) == EOF) { errorPrint ("orderSaveMap: bad output (2)"); o = 1; break; } } memFree (rangtab); /* Free memory group leader */ return (o); } scotch-6.0.4.dfsg/src/libscotch/vdgraph_separate_sq.c0000644002563400244210000002637511631447171026042 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vdgraph_separate_sq.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module computes a separator of the **/ /** given distributed separator graph by **/ /** moving all (interesting) vertices of **/ /** the given graph to every processor, **/ /** running a sequential vertex separation **/ /** computing, and projecting back the **/ /** best result obtained. **/ /** **/ /** DATES : # Version 5.1 : from : 15 feb 2006 **/ /** to 30 jul 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VDGRAPH_SEPARATE_SQ #include "module.h" #include "common.h" #include "comm.h" #include "parser.h" #include "graph.h" #include "vgraph.h" #include "vgraph_separate_st.h" #include "dgraph.h" #include "vdgraph.h" #include "vdgraph_separate_sq.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine is the reduction-loc operator which ** returns in inout[2] the rank of the process which ** holds the best partition. ** It returns: ** - void : in all cases. */ static void vdgraphSeparateSqOpBest ( const Gnum * const in, /* First operand */ Gnum * const inout, /* Second and output operand */ const int * const len, /* Number of instances; should be 1, not used */ const MPI_Datatype * const typedat) /* MPI datatype; not used */ { if (inout[3] == 1) { /* Handle cases when at least one of them is erroneous */ if (in[3] == 1) return; inout[0] = in[0]; inout[1] = in[1]; inout[2] = in[2]; inout[3] = in[3]; return; } else if (in[3] == 1) return; if ((in[0] < inout[0]) || /* Select best partition */ ((in[0] == inout[0]) && ((in[1] < inout[1]) || ((in[1] == inout[1]) && (in[2] < inout[2]))))) { inout[0] = in[0]; inout[1] = in[1]; inout[2] = in[2]; } } /* This routine computes a partition of the ** given distributed graph by gathering as many ** copies of the graph as there are processes ** sharing the distributed graph, running a ** sequential algorithm on them, and collecting ** the best solution found. ** It returns: ** - 0 : if the bipartitioning could be computed. ** - !0 : on error. */ int vdgraphSeparateSq ( Vdgraph * const dgrfptr, /*+ Distributed graph +*/ const VdgraphSeparateSqParam * const paraptr) /*+ Method parameters +*/ { Vgraph cgrfdat; /* Centralized vertex separator graph structure */ Gnum reduloctab[7]; /* Local array for best separator data (7 for Bcast) */ Gnum reduglbtab[4]; /* Global array for best separator data */ MPI_Datatype besttypedat; /* Data type for finding best separator */ MPI_Op bestoperdat; /* Handle of MPI operator for finding best separator */ int bestprocnum; /* Rank of process holding best partition */ Gnum * restrict vnumloctax; Gnum vertlocnum; Gnum complocsize1; Gnum complocload1; Gnum complocload2; Gnum fronlocnbr; int o; if ((MPI_Type_contiguous (4, GNUM_MPI, &besttypedat) != MPI_SUCCESS) || (MPI_Type_commit (&besttypedat) != MPI_SUCCESS) || (MPI_Op_create ((MPI_User_function *) vdgraphSeparateSqOpBest, 1, &bestoperdat) != MPI_SUCCESS)) { errorPrint ("vdgraphSeparateSq: communication error (1)"); return (1); } reduloctab[0] = /* In case of error, maximum frontier size */ reduloctab[1] = GNUMMAX; /* And maximum load imbalance */ reduloctab[2] = dgrfptr->s.proclocnum; reduloctab[3] = 0; /* Assume sequential separation went fine */ vnumloctax = dgrfptr->s.vnumloctax; /* No need for vertex number array when centralizing graph */ dgrfptr->s.vnumloctax = NULL; o = vdgraphGatherAll (dgrfptr, &cgrfdat); dgrfptr->s.vnumloctax = vnumloctax; /* Restore vertex number array */ if (o != 0) { errorPrint ("vdgraphSeparateSq: cannot build centralized graph"); return (1); } if (vgraphSeparateSt (&cgrfdat, paraptr->strat) != 0) { /* Separate centralized graph */ errorPrint ("vdgraphSeparateSq: cannot separate centralized graph"); reduloctab[3] = 1; } else { /* Fill local array with local separator data */ reduloctab[0] = ((cgrfdat.fronnbr != 0) || ((cgrfdat.compload[0] != 0) && (cgrfdat.compload[1] != 0))) ? cgrfdat.fronnbr : (cgrfdat.fronnbr + cgrfdat.s.vertnbr); /* Partitions with empty separators unwanted if they are completely unbalanced */ reduloctab[1] = cgrfdat.comploaddlt; } if (MPI_Allreduce (reduloctab, reduglbtab, 1, besttypedat, bestoperdat, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("vdgraphSeparateSq: communication error (2)"); return (1); } #ifdef SCOTCH_DEBUG_VDGRAPH2 if (MPI_Allreduce (&reduglbtab[3], &reduloctab[3], 1, GNUM_MPI, MPI_SUM, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("vdgraphSeparateSq: communication error (3)"); return (1); } if ((reduloctab[3] != 0) && (reduloctab[3] != dgrfptr->s.procglbnbr)) { errorPrint ("vdgraphSeparateSq: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_VDGRAPH2 */ if ((MPI_Op_free (&bestoperdat) != MPI_SUCCESS) || (MPI_Type_free (&besttypedat) != MPI_SUCCESS)) { errorPrint ("vdgraphSeparateSq: communication error (4)"); return (1); } if (reduglbtab[3] != 0) { /* If none of the sequential methods succeeded */ vgraphExit (&cgrfdat); return (1); } bestprocnum = (int) reduglbtab[2]; if (dgrfptr->s.proclocnum == bestprocnum) { /* If process holds best partition */ reduloctab[0] = cgrfdat.compload[0]; /* Global values to share */ reduloctab[1] = cgrfdat.compload[1]; reduloctab[2] = cgrfdat.compload[2]; reduloctab[3] = cgrfdat.comploaddlt; reduloctab[4] = cgrfdat.compsize[0]; reduloctab[5] = cgrfdat.compsize[1]; reduloctab[6] = cgrfdat.fronnbr; } if (MPI_Bcast (reduloctab, 7, GNUM_MPI, bestprocnum, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("vdgraphSeparateSq: communication error (5)"); return (1); } dgrfptr->compglbload[0] = reduloctab[0]; dgrfptr->compglbload[1] = reduloctab[1]; dgrfptr->compglbload[2] = reduloctab[2]; dgrfptr->compglbloaddlt = reduloctab[3]; dgrfptr->compglbsize[0] = reduloctab[4]; dgrfptr->compglbsize[1] = reduloctab[5]; dgrfptr->compglbsize[2] = reduloctab[6]; if (commScatterv (cgrfdat.parttax, dgrfptr->s.proccnttab, dgrfptr->s.procdsptab, GRAPHPART_MPI, /* No base for sending as procdsptab holds based values */ dgrfptr->partgsttax + dgrfptr->s.baseval, dgrfptr->s.vertlocnbr, GRAPHPART_MPI, bestprocnum, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("vdgraphSeparateSq: communication error (6)"); return (1); } complocsize1 = complocload1 = complocload2 = 0; for (vertlocnum = dgrfptr->s.baseval, fronlocnbr = 0; vertlocnum < dgrfptr->s.vertlocnnd; vertlocnum ++) { int partval; Gnum partval1; partval = dgrfptr->partgsttax[vertlocnum]; partval1 = partval & 1; complocsize1 += partval1; /* Superscalar update */ if (partval == 2) /* Build local frontier */ dgrfptr->fronloctab[fronlocnbr ++] = vertlocnum; if (dgrfptr->s.veloloctax != NULL) { Gnum partval2; Gnum veloval; veloval = dgrfptr->s.veloloctax[vertlocnum]; partval2 = (partval >> 1) & 1; complocload1 += (-partval1) & veloval; /* Superscalar update */ complocload2 += (-partval2) & veloval; /* Superscalar update */ } } dgrfptr->complocsize[0] = dgrfptr->s.vertlocnbr - fronlocnbr - complocsize1; dgrfptr->complocsize[1] = complocsize1; dgrfptr->complocsize[2] = fronlocnbr; if (dgrfptr->s.veloloctax != NULL) { dgrfptr->complocload[0] = dgrfptr->s.velolocsum - complocload1 - complocload2; dgrfptr->complocload[1] = complocload1; dgrfptr->complocload[2] = complocload2; } else { dgrfptr->complocload[0] = dgrfptr->complocsize[0]; dgrfptr->complocload[1] = dgrfptr->complocsize[1]; dgrfptr->complocload[2] = fronlocnbr; } vgraphExit (&cgrfdat); #ifdef SCOTCH_DEBUG_VDGRAPH2 if (vdgraphCheck (dgrfptr) != 0) { errorPrint ("vdgraphSeparateSq: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_VDGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/vgraph.c0000644002563400244210000000757511631447170023307 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vgraph.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the separator **/ /** handling routines. **/ /** **/ /** DATES : # Version 3.2 : from : 24 aug 1996 **/ /** to 03 nov 1997 **/ /** # Version 4.0 : from : 12 dec 2001 **/ /** to 08 jan 2004 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VGRAPH #include "module.h" #include "common.h" #include "graph.h" #include "vgraph.h" /*************************/ /* */ /* These routines handle */ /* separator graphs. */ /* */ /*************************/ /* This routine frees the contents ** of the given active graph. ** It returns: ** - VOID : in all cases. */ void vgraphExit ( Vgraph * const grafptr) { if (grafptr->parttax != NULL) memFree (grafptr->parttax + grafptr->s.baseval); if (grafptr->frontab != NULL) memFree (grafptr->frontab); graphFree (&grafptr->s); /* Free source graph */ #ifdef SCOTCH_DEBUG_VGRAPH2 memSet (grafptr, ~0, sizeof (Vgraph)); #endif /* SCOTCH_DEBUG_VGRAPH2 */ } /* This routine moves all of the graph ** vertices to the first part. ** It returns: ** - VOID : in all cases. */ void vgraphZero ( Vgraph * const grafptr) { memSet (grafptr->parttax + grafptr->s.baseval, 0, grafptr->s.vertnbr * sizeof (GraphPart)); /* Set all vertices to part 0 */ grafptr->compload[0] = grafptr->s.velosum; /* No frontier vertices */ grafptr->compload[1] = grafptr->compload[2] = 0; grafptr->comploaddlt = grafptr->s.velosum; grafptr->compsize[0] = grafptr->s.vertnbr; grafptr->compsize[1] = grafptr->fronnbr = 0; } scotch-6.0.4.dfsg/src/libscotch/last_resort/0000755002563400244210000000000012412577230024176 5ustar trophimeutilisateurs du domainescotch-6.0.4.dfsg/src/libscotch/last_resort/parser_yy.c0000644002563400244210000024052712412577230026371 0ustar trophimeutilisateurs du domaine/* A Bison parser, made by GNU Bison 3.0.2. */ /* Bison implementation for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "3.0.2" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 0 /* Push parsers. */ #define YYPUSH 0 /* Pull parsers. */ #define YYPULL 1 /* Substitute the variable and function names. */ #define yyparse scotchyyparse #define yylex scotchyylex #define yyerror scotchyyerror #define yydebug scotchyydebug #define yynerrs scotchyynerrs #define yylval scotchyylval #define yychar scotchyychar /* Copy the first part of user declarations. */ #line 1 "parser_yy.y" /* yacc.c:339 */ /* Copyright 2004,2007,2008,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : parser_yy.y **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the syntactic parser **/ /** which processes strategy strings. **/ /** **/ /** DATES : # Version 3.1 : from : 07 nov 1995 **/ /** to 13 jun 1996 **/ /** # Version 3.2 : from : 24 sep 1996 **/ /** to 27 feb 1997 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 4.0 : from : 20 dec 2001 **/ /** to 11 jun 2004 **/ /** # Version 5.1 : from : 30 oct 2007 **/ /** to 24 jul 2011 **/ /** # Version 6.0 : from : 30 sep 2014 **/ /** to 30 sep 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define PARSER_YY #include "module.h" #include "common.h" #undef INTEGER /* In case someone defined them */ #undef DOUBLE #include "parser.h" #include "parser_ll.h" #include "parser_yy.h" /* #define SCOTCH_DEBUG_PARSER3 */ #ifdef SCOTCH_DEBUG_PARSER3 extern int yydebug; #define YYDEBUG 1 #endif /* SCOTCH_DEBUG_PARSER3 */ /* ** The static and global definitions. ** See also at the end of this file. */ static const StratTab * parserstrattab; /* Pointer to parsing tables */ static Strat * parserstratcurr = NULL; /* Pointer to current strategy node */ static StratParamTab * parserparamcurr = NULL; /* Pointer to current parameter */ extern unsigned int parsermethtokentab[]; /* Pre-definition for stupid compilers */ #line 165 "y.tab.c" /* yacc.c:339 */ # ifndef YY_NULLPTR # if defined __cplusplus && 201103L <= __cplusplus # define YY_NULLPTR nullptr # else # define YY_NULLPTR 0 # endif # endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* In a future release of Bison, this section will be replaced by #include "y.tab.h". */ #ifndef YY_SCOTCHYY_Y_TAB_H_INCLUDED # define YY_SCOTCHYY_Y_TAB_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif #if YYDEBUG extern int scotchyydebug; #endif /* Token type. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { METHODNAME = 258, PARAMNAME = 259, VALCASE = 260, VALDOUBLE = 261, VALINT = 262, VALSTRING = 263, VALSTRAT = 264, VALPARAM = 265, VALTEST = 266 }; #endif /* Tokens. */ #define METHODNAME 258 #define PARAMNAME 259 #define VALCASE 260 #define VALDOUBLE 261 #define VALINT 262 #define VALSTRING 263 #define VALSTRAT 264 #define VALPARAM 265 #define VALTEST 266 /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE YYSTYPE; union YYSTYPE { #line 92 "parser_yy.y" /* yacc.c:355 */ char CASEVAL; /* Case value */ StratTest * TEST; /* Test type */ StratTestType TESTOP; /* Relational type */ double DOUBLE; /* Double-precision */ INT INTEGER; /* Integer */ char STRING[PARSERSTRINGLEN]; /* Character string */ struct { const StratTab * tabl; /* Current tables */ Strat * strat; /* Current method */ StratParamTab * param; /* Current parameter */ } SAVE; /* Parameter type */ Strat * STRAT; /* Strategy tree */ #line 242 "y.tab.c" /* yacc.c:355 */ }; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif extern YYSTYPE scotchyylval; int scotchyyparse (void); #endif /* !YY_SCOTCHYY_Y_TAB_H_INCLUDED */ /* Copy the second part of user declarations. */ #line 257 "y.tab.c" /* yacc.c:358 */ #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #else typedef signed char yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(Msgid) dgettext ("bison-runtime", Msgid) # endif # endif # ifndef YY_ # define YY_(Msgid) Msgid # endif #endif #ifndef YY_ATTRIBUTE # if (defined __GNUC__ \ && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C # define YY_ATTRIBUTE(Spec) __attribute__(Spec) # else # define YY_ATTRIBUTE(Spec) /* empty */ # endif #endif #ifndef YY_ATTRIBUTE_PURE # define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) #endif #ifndef YY_ATTRIBUTE_UNUSED # define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) #endif #if !defined _Noreturn \ && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) # if defined _MSC_VER && 1200 <= _MSC_VER # define _Noreturn __declspec (noreturn) # else # define _Noreturn YY_ATTRIBUTE ((__noreturn__)) # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(E) ((void) (E)) #else # define YYUSE(E) /* empty */ #endif #if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ /* Suppress an incorrect diagnostic about yylval being uninitialized. */ # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") # define YY_IGNORE_MAYBE_UNINITIALIZED_END \ _Pragma ("GCC diagnostic pop") #else # define YY_INITIAL_VALUE(Value) Value #endif #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_END #endif #ifndef YY_INITIAL_VALUE # define YY_INITIAL_VALUE(Value) /* Nothing. */ #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS # include /* INFRINGES ON USER NAME SPACE */ /* Use EXIT_SUCCESS as a witness for stdlib.h. */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's 'empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined EXIT_SUCCESS void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined EXIT_SUCCESS void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss_alloc; YYSTYPE yyvs_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) # define YYCOPY_NEEDED 1 /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (0) #endif #if defined YYCOPY_NEEDED && YYCOPY_NEEDED /* Copy COUNT objects from SRC to DST. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(Dst, Src, Count) \ __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) # else # define YYCOPY(Dst, Src, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (Dst)[yyi] = (Src)[yyi]; \ } \ while (0) # endif # endif #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ #define YYFINAL 13 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 93 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 31 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 37 /* YYNRULES -- Number of rules. */ #define YYNRULES 65 /* YYNSTATES -- Number of states. */ #define YYNSTATES 93 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 266 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM as returned by yylex, without out-of-bounds checking. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 24, 2, 2, 2, 30, 23, 2, 17, 18, 29, 27, 21, 28, 2, 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 15, 25, 22, 26, 14, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 19, 12, 20, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { 0, 132, 132, 138, 156, 159, 161, 176, 194, 198, 202, 198, 226, 229, 234, 239, 243, 247, 246, 308, 312, 308, 316, 319, 320, 324, 323, 362, 397, 412, 427, 444, 444, 468, 476, 479, 497, 500, 518, 521, 537, 541, 544, 563, 567, 571, 577, 593, 596, 600, 606, 622, 625, 631, 647, 650, 656, 660, 661, 664, 679, 696, 737, 741, 744, 748 }; #endif #if YYDEBUG || YYERROR_VERBOSE || 0 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "METHODNAME", "PARAMNAME", "VALCASE", "VALDOUBLE", "VALINT", "VALSTRING", "VALSTRAT", "VALPARAM", "VALTEST", "'|'", "'/'", "'?'", "';'", "':'", "'('", "')'", "'{'", "'}'", "','", "'='", "'&'", "'!'", "'<'", "'>'", "'+'", "'-'", "'*'", "'%'", "$accept", "STRAT", "STRATSELECT", "STRATEMPTY", "STRATCONCAT", "STRATTEST", "$@1", "$@2", "STRATTESTELSE", "STRATGROUP", "STRATMETHOD", "$@3", "METHODPARAM", "$@4", "$@5", "PARAMLIST", "PARAMPARAM", "@6", "PARAMVAL", "@7", "TEST", "TESTOR", "TESTAND", "TESTNOT", "TESTREL", "TESTRELOP", "TESTEXPR1", "TESTEXPR1OP", "TESTEXPR2", "TESTEXPR2OP", "TESTEXPR3", "TESTEXPR3OP", "TESTEXPR4", "TESTVAL", "TESTVAR", "VALSDOUBLE", "VALSINT", YY_NULLPTR }; #endif # ifdef YYPRINT /* YYTOKNUM[NUM] -- (External) token number corresponding to the (internal) symbol number NUM (which must be that of a token). */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 124, 47, 63, 59, 58, 40, 41, 123, 125, 44, 61, 38, 33, 60, 62, 43, 45, 42, 37 }; # endif #define YYPACT_NINF -33 #define yypact_value_is_default(Yystate) \ (!!((Yystate) == (-33))) #define YYTABLE_NINF -32 #define yytable_value_is_error(Yytable_value) \ 0 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ static const yytype_int8 yypact[] = { 5, -33, 5, 10, 7, -33, 5, -33, 4, -33, -33, 19, 40, -33, 5, -33, 27, -33, 20, -33, -33, -33, -33, -33, 27, 27, -33, -33, -33, 28, 3, -33, -33, 47, -1, 33, 13, -33, -33, -33, -33, -33, 44, 41, 39, -33, 42, 27, 27, -33, -33, -33, 43, 43, -33, -33, -33, 43, -33, 43, -33, 55, -33, -33, -33, 5, 3, -33, 43, -4, 33, 13, -33, 46, 44, 57, -9, 14, 8, -33, -33, 5, 63, -33, -33, -33, -33, 5, -33, -33, 7, -33, 7 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. Performed when YYTABLE does not specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 6, 17, 6, 0, 2, 4, 5, 8, 0, 12, 16, 22, 0, 1, 6, 7, 0, 18, 0, 15, 3, 61, 63, 65, 0, 0, 48, 49, 10, 34, 36, 38, 41, 0, 0, 47, 51, 54, 57, 58, 59, 60, 0, 0, 0, 39, 0, 0, 0, 44, 43, 45, 0, 0, 62, 64, 52, 0, 55, 0, 25, 20, 24, 40, 56, 6, 35, 37, 0, 42, 46, 50, 53, 0, 0, 0, 14, 0, 0, 23, 21, 6, 0, 33, 27, 30, 26, 6, 28, 29, 13, 11, 32 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { -33, -33, -2, 66, -33, 75, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, 9, -33, -33, -33, -33, 58, 37, -21, -33, -33, -22, -32, 34, -33, 29, -33, 30, -33, -33, 12, 15 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { -1, 3, 4, 5, 6, 7, 8, 46, 82, 9, 10, 11, 17, 18, 75, 61, 62, 73, 86, 87, 28, 29, 30, 31, 32, 52, 33, 34, 35, 57, 36, 59, 37, 38, 39, 40, 41 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule whose number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int8 yytable[] = { 12, 53, 44, 14, 45, 54, 55, 81, 1, 83, 13, -31, 53, 84, 22, 23, 85, 16, -9, 14, -31, -31, 2, 26, 27, -31, 48, 67, -31, -31, 69, 21, 64, 22, 23, 26, 27, 53, -19, 42, 47, 26, 27, 58, 24, 53, 77, 21, 60, 22, 23, 25, 14, 47, 26, 27, 65, 64, 19, 63, 68, 49, 56, 76, 50, 51, 26, 27, 78, 49, 26, 27, 50, 51, 26, 27, 74, 80, 91, 90, 20, 15, 43, 79, 66, 92, 71, 70, 0, 72, 88, 0, 0, 89 }; static const yytype_int8 yycheck[] = { 2, 33, 24, 12, 25, 6, 7, 16, 3, 1, 0, 3, 44, 5, 6, 7, 8, 13, 13, 12, 12, 13, 17, 27, 28, 17, 23, 48, 20, 21, 52, 4, 18, 6, 7, 27, 28, 69, 19, 19, 12, 27, 28, 30, 17, 77, 68, 4, 4, 6, 7, 24, 12, 12, 27, 28, 14, 18, 18, 18, 17, 22, 29, 65, 25, 26, 27, 28, 22, 22, 27, 28, 25, 26, 27, 28, 21, 20, 15, 81, 14, 6, 24, 74, 47, 87, 57, 53, -1, 59, 78, -1, -1, 78 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 3, 17, 32, 33, 34, 35, 36, 37, 40, 41, 42, 33, 0, 12, 36, 13, 43, 44, 18, 34, 4, 6, 7, 17, 24, 27, 28, 51, 52, 53, 54, 55, 57, 58, 59, 61, 63, 64, 65, 66, 67, 19, 52, 57, 54, 38, 12, 23, 22, 25, 26, 56, 58, 6, 7, 29, 60, 30, 62, 4, 46, 47, 18, 18, 14, 53, 54, 17, 57, 59, 61, 63, 48, 21, 45, 33, 57, 22, 47, 20, 16, 39, 1, 5, 8, 49, 50, 66, 67, 33, 15, 33 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 31, 32, 33, 33, 34, 34, 35, 35, 37, 38, 36, 36, 39, 39, 40, 40, 42, 41, 44, 45, 43, 43, 46, 46, 48, 47, 49, 49, 49, 49, 50, 49, 49, 51, 52, 52, 53, 53, 54, 54, 54, 55, 56, 56, 56, 57, 57, 58, 58, 59, 59, 60, 61, 61, 62, 63, 63, 63, 64, 64, 65, 66, 66, 67, 67 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 1, 3, 1, 1, 0, 2, 1, 0, 0, 8, 1, 2, 0, 3, 1, 0, 3, 0, 0, 5, 0, 3, 1, 0, 4, 1, 1, 1, 1, 0, 2, 1, 1, 3, 1, 3, 1, 2, 3, 1, 3, 1, 1, 1, 3, 1, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 1, 1, 1, 1, 2, 1, 2, 1 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY) \ { \ yychar = (Token); \ yylval = (Value); \ YYPOPSTACK (yylen); \ yystate = *yyssp; \ goto yybackup; \ } \ else \ { \ yyerror (YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (0) /* Error token number */ #define YYTERROR 1 #define YYERRCODE 256 /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (0) /* This macro is provided for backward compatibility. */ #ifndef YY_LOCATION_PRINT # define YY_LOCATION_PRINT(File, Loc) ((void) 0) #endif # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value); \ YYFPRINTF (stderr, "\n"); \ } \ } while (0) /*----------------------------------------. | Print this symbol's value on YYOUTPUT. | `----------------------------------------*/ static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) { FILE *yyo = yyoutput; YYUSE (yyo); if (!yyvaluep) return; # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # endif YYUSE (yytype); } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) { YYFPRINTF (yyoutput, "%s %s (", yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ static void yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) { int yybot = *yybottom; YYFPRINTF (stderr, " %d", yybot); } YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (0) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ static void yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule) { unsigned long int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yystos[yyssp[yyi + 1 - yynrhs]], &(yyvsp[(yyi + 1) - (yynrhs)]) ); YYFPRINTF (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyssp, yyvsp, Rule); \ } while (0) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ static YYSIZE_T yystrlen (const char *yystr) { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ static char * yystpcpy (char *yydest, const char *yysrc) { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message about the unexpected token YYTOKEN for the state stack whose top is YYSSP. Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is not large enough to hold the message. In that case, also set *YYMSG_ALLOC to the required number of bytes. Return 2 if the required number of bytes is too large to store. */ static int yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, yytype_int16 *yyssp, int yytoken) { YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); YYSIZE_T yysize = yysize0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; /* Internationalized format string. */ const char *yyformat = YY_NULLPTR; /* Arguments of yyformat. */ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; /* Number of reported tokens (one for the "unexpected", one per "expected"). */ int yycount = 0; /* There are many possibilities here to consider: - If this state is a consistent state with a default action, then the only way this function was invoked is if the default action is an error action. In that case, don't check for expected tokens because there are none. - The only way there can be no lookahead present (in yychar) is if this state is a consistent state with a default action. Thus, detecting the absence of a lookahead is sufficient to determine that there is no unexpected or expected token to report. In that case, just report a simple "syntax error". - Don't assume there isn't a lookahead just because this state is a consistent state with a default action. There might have been a previous inconsistent state, consistent state with a non-default action, or user semantic action that manipulated yychar. - Of course, the expected token list depends on states to have correct lookahead information, and it depends on the parser not to perform extra reductions after fetching a lookahead from the scanner and before detecting a syntax error. Thus, state merging (from LALR or IELR) and default reductions corrupt the expected token list. However, the list is correct for canonical LR with one exception: it will still contain any token that will not be accepted due to an error action in a later state. */ if (yytoken != YYEMPTY) { int yyn = yypact[*yyssp]; yyarg[yycount++] = yytname[yytoken]; if (!yypact_value_is_default (yyn)) { /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. In other words, skip the first -YYN actions for this state because they are default actions. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yyx; for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR && !yytable_value_is_error (yytable[yyx + yyn])) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; break; } yyarg[yycount++] = yytname[yyx]; { YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) return 2; yysize = yysize1; } } } } switch (yycount) { # define YYCASE_(N, S) \ case N: \ yyformat = S; \ break YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); # undef YYCASE_ } { YYSIZE_T yysize1 = yysize + yystrlen (yyformat); if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) return 2; yysize = yysize1; } if (*yymsg_alloc < yysize) { *yymsg_alloc = 2 * yysize; if (! (yysize <= *yymsg_alloc && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; return 1; } /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ { char *yyp = *yymsg; int yyi = 0; while ((*yyp = *yyformat) != '\0') if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyformat += 2; } else { yyp++; yyformat++; } } return 0; } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) { YYUSE (yyvaluep); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YYUSE (yytype); YY_IGNORE_MAYBE_UNINITIALIZED_END } /* The lookahead symbol. */ int yychar; /* The semantic value of the lookahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; /*----------. | yyparse. | `----------*/ int yyparse (void) { int yystate; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* The stacks and their tools: 'yyss': related to states. 'yyvs': related to semantic values. Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs; YYSTYPE *yyvsp; YYSIZE_T yystacksize; int yyn; int yyresult; /* Lookahead token as an internal (translated) token number. */ int yytoken = 0; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; yyssp = yyss = yyssa; yyvsp = yyvs = yyvsa; yystacksize = YYINITDEPTH; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); if (yystate == YYFINAL) YYACCEPT; goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yypact_value_is_default (yyn)) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = yylex (); } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yytable_value_is_error (yyn)) goto yyerrlab; yyn = -yyn; goto yyreduce; } /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token. */ yychar = YYEMPTY; yystate = yyn; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: '$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 2: #line 133 "parser_yy.y" /* yacc.c:1646 */ { parserstratcurr = ((yyvsp[0].STRAT)); /* Save pointer to root of tree */ } #line 1406 "y.tab.c" /* yacc.c:1646 */ break; case 3: #line 139 "parser_yy.y" /* yacc.c:1646 */ { Strat * strat; if ((strat = (Strat *) memAlloc (sizeof (Strat))) == NULL) { errorPrint ("stratParserParse: out of memory (2)"); stratExit ((yyvsp[-2].STRAT)); stratExit ((yyvsp[0].STRAT)); YYABORT; } strat->tabl = parserstrattab; strat->type = STRATNODESELECT; strat->data.select.strat[0] = ((yyvsp[-2].STRAT)); strat->data.select.strat[1] = ((yyvsp[0].STRAT)); ((yyval.STRAT)) = strat; } #line 1428 "y.tab.c" /* yacc.c:1646 */ break; case 6: #line 161 "parser_yy.y" /* yacc.c:1646 */ { Strat * strat; if ((strat = (Strat *) memAlloc (sizeof (Strat))) == NULL) { errorPrint ("stratParserParse: out of memory (3)"); YYABORT; } strat->tabl = parserstrattab; strat->type = STRATNODEEMPTY; ((yyval.STRAT)) = strat; } #line 1446 "y.tab.c" /* yacc.c:1646 */ break; case 7: #line 177 "parser_yy.y" /* yacc.c:1646 */ { Strat * strat; if ((strat = (Strat *) memAlloc (sizeof (Strat))) == NULL) { errorPrint ("stratParserParse: out of memory (4)"); stratExit ((yyvsp[-1].STRAT)); stratExit ((yyvsp[0].STRAT)); YYABORT; } strat->tabl = parserstrattab; strat->type = STRATNODECONCAT; strat->data.concat.strat[0] = ((yyvsp[-1].STRAT)); strat->data.concat.strat[1] = ((yyvsp[0].STRAT)); ((yyval.STRAT)) = strat; } #line 1468 "y.tab.c" /* yacc.c:1646 */ break; case 9: #line 198 "parser_yy.y" /* yacc.c:1646 */ { stratParserSelect (VALTEST); /* Parse parameter tokens */ } #line 1476 "y.tab.c" /* yacc.c:1646 */ break; case 10: #line 202 "parser_yy.y" /* yacc.c:1646 */ { stratParserSelect (VALSTRAT); /* Parse strategy tokens */ } #line 1484 "y.tab.c" /* yacc.c:1646 */ break; case 11: #line 206 "parser_yy.y" /* yacc.c:1646 */ { Strat * strat; if ((strat = (Strat *) memAlloc (sizeof (Strat))) == NULL) { errorPrint ("stratParserParse: out of memory (1)"); stratExit ((yyvsp[-2].STRAT)); if (((yyvsp[-1].STRAT)) != NULL) stratExit ((yyvsp[-1].STRAT)); stratTestExit ((yyvsp[-5].TEST)); YYABORT; } strat->tabl = parserstrattab; strat->type = STRATNODECOND; strat->data.cond.test = ((yyvsp[-5].TEST)); strat->data.cond.strat[0] = ((yyvsp[-2].STRAT)); strat->data.cond.strat[1] = ((yyvsp[-1].STRAT)); ((yyval.STRAT)) = strat; } #line 1509 "y.tab.c" /* yacc.c:1646 */ break; case 13: #line 230 "parser_yy.y" /* yacc.c:1646 */ { ((yyval.STRAT)) = ((yyvsp[0].STRAT)); } #line 1517 "y.tab.c" /* yacc.c:1646 */ break; case 14: #line 234 "parser_yy.y" /* yacc.c:1646 */ { ((yyval.STRAT)) = NULL; } #line 1525 "y.tab.c" /* yacc.c:1646 */ break; case 15: #line 240 "parser_yy.y" /* yacc.c:1646 */ { ((yyval.STRAT)) = ((yyvsp[-1].STRAT)); } #line 1533 "y.tab.c" /* yacc.c:1646 */ break; case 17: #line 247 "parser_yy.y" /* yacc.c:1646 */ { Strat * strat; int meth; int methlen; StratMethodTab * methtab; int i, j; meth = methlen = 0; /* No method recognized yet */ methtab = parserstrattab->methtab; /* Point to the method table */ for (i = 0; methtab[i].name != NULL; i ++) { if ((strncasecmp (((yyvsp[0].STRING)), /* Find longest matching code name */ methtab[i].name, j = strlen (methtab[i].name)) == 0) && (j > methlen)) { meth = methtab[i].meth; methlen = j; } } if (methlen == 0) { /* If method name not known */ errorPrint ("stratParserParse: invalid method name \"%s\", before \"%s\"", ((yyvsp[0].STRING)), stratParserRemain ()); YYABORT; } if ((strat = (Strat *) memAlloc (sizeof (Strat))) == NULL) { errorPrint ("stratParserParse: out of memory (5)"); YYABORT; } strat->tabl = parserstrattab; strat->type = STRATNODEMETHOD; strat->data.method.meth = meth; /* Set method type */ if (methtab[meth].data != NULL) /* If default values exist */ memcpy (&strat->data.method.data, /* Set values to default */ methtab[meth].data, sizeof (StratNodeMethodData)); parserstratcurr = strat; /* Structure available for parameter processing */ } #line 1577 "y.tab.c" /* yacc.c:1646 */ break; case 18: #line 287 "parser_yy.y" /* yacc.c:1646 */ { StratParamTab * paratab; int i; paratab = parserstrattab->paratab; /* Point to the parameter table */ for (i = 0; paratab[i].name != NULL; i ++) { if ((paratab[i].meth == parserstratcurr->data.method.meth) && /* If a strategy parameter found for this method */ (paratab[i].type == STRATPARAMSTRAT)) { if (*((Strat **) ((byte *) &parserstratcurr->data.method.data + /* And this parameter has not been set */ (paratab[i].dataofft - paratab[i].database))) == NULL) errorPrintW ("stratParserParse: strategy parameter \"%s\" of method \"%s\" not set, before \"%s\"", paratab[i].name, parserstrattab->methtab[parserstratcurr->data.method.meth].name, stratParserRemain ()); } } ((yyval.STRAT)) = parserstratcurr; /* Return current structure */ parserstratcurr = NULL; /* No current structure */ } #line 1600 "y.tab.c" /* yacc.c:1646 */ break; case 19: #line 308 "parser_yy.y" /* yacc.c:1646 */ { stratParserSelect (VALPARAM); /* Parse parameter tokens */ } #line 1608 "y.tab.c" /* yacc.c:1646 */ break; case 20: #line 312 "parser_yy.y" /* yacc.c:1646 */ { stratParserSelect (VALSTRAT); /* Parse strategy tokens */ } #line 1616 "y.tab.c" /* yacc.c:1646 */ break; case 25: #line 324 "parser_yy.y" /* yacc.c:1646 */ { int para; int paralen; StratParamTab * paratab; int i, j; para = paralen = 0; /* No parameter recognized yet */ paratab = parserstrattab->paratab; /* Point to the parameter table */ for (i = 0; paratab[i].name != NULL; i ++) { if ((paratab[i].meth == parserstratcurr->data.method.meth) && (strncasecmp (((yyvsp[0].STRING)), /* Find longest matching parameter name */ paratab[i].name, j = strlen (paratab[i].name)) == 0) && (j > paralen)) { para = i; paralen = j; } } if (paralen == 0) { errorPrint ("stratParserParse: invalid method parameter name \"%s\", before \"%s\"", ((yyvsp[0].STRING)), stratParserRemain ()); YYABORT; } ((yyval.SAVE)).tabl = parserstrattab; /* Save current strategy tables */ parserparamcurr = ¶tab[para]; /* Save current parameter value */ stratParserSelect (parsermethtokentab[parserparamcurr->type & ~STRATPARAMDEPRECATED]); /* Get non-deprecated type */ if (parserparamcurr->type == STRATPARAMSTRAT) /* If parameter is a strategy */ parserstrattab = (StratTab *) parserparamcurr->datasltr; /* Use new strategy tables */ } #line 1652 "y.tab.c" /* yacc.c:1646 */ break; case 26: #line 356 "parser_yy.y" /* yacc.c:1646 */ { stratParserSelect (VALPARAM); /* Go-on reading parameters */ parserstrattab = ((yyvsp[-2].SAVE)).tabl; /* Restore current strategy tables */ } #line 1661 "y.tab.c" /* yacc.c:1646 */ break; case 27: #line 363 "parser_yy.y" /* yacc.c:1646 */ { char c; /* Character read */ char * p; /* Pointer to selector string */ int i; /* Index in selector string */ if ((parserparamcurr->type & STRATPARAMDEPRECATED) == 0) { /* If parameter is not deprecated */ c = ((yyvsp[0].CASEVAL)); /* First, use char as is */ for (p = (char *) parserparamcurr->datasltr, i = 0; (*p != '\0') && (*p != c); p ++, i ++) ; if (*p == '\0') { /* Char was not found */ c = tolower (c); /* Convert char to lower case */ for (p = (char *) parserparamcurr->datasltr, i = 0; (*p != '\0') && (*p != c); p ++, i ++) ; if (*p == '\0') { errorPrint ("stratParserParse: invalid method parameter switch \"%s=%c\", before \"%s\"", parserparamcurr->name, ((yyvsp[0].CASEVAL)), stratParserRemain ()); YYABORT; } } #ifdef SCOTCH_DEBUG_PARSER2 if ((parserparamcurr->dataofft - parserparamcurr->database + sizeof (int)) > sizeof (StratNodeMethodData)) { errorPrint ("stratParserParse: internal error (1)"); YYABORT; } #endif /* SCOTCH_DEBUG_PARSER2 */ *((int *) ((byte *) &parserstratcurr->data.method.data + (parserparamcurr->dataofft - parserparamcurr->database))) = i; } } #line 1700 "y.tab.c" /* yacc.c:1646 */ break; case 28: #line 398 "parser_yy.y" /* yacc.c:1646 */ { if ((parserparamcurr->type & STRATPARAMDEPRECATED) == 0) { /* If parameter is not deprecated */ #ifdef SCOTCH_DEBUG_PARSER2 if ((parserparamcurr->dataofft - parserparamcurr->database + sizeof (double)) > sizeof (StratNodeMethodData)) { errorPrint ("stratParserParse: internal error (2)"); YYABORT; } #endif /* SCOTCH_DEBUG_PARSER2 */ *((double *) ((byte *) &parserstratcurr->data.method.data + (parserparamcurr->dataofft - parserparamcurr->database))) = ((yyvsp[0].DOUBLE)); } } #line 1719 "y.tab.c" /* yacc.c:1646 */ break; case 29: #line 413 "parser_yy.y" /* yacc.c:1646 */ { if ((parserparamcurr->type & STRATPARAMDEPRECATED) == 0) { /* If parameter is not deprecated */ #ifdef SCOTCH_DEBUG_PARSER2 if ((parserparamcurr->dataofft - parserparamcurr->database + sizeof (INT)) > sizeof (StratNodeMethodData)) { errorPrint ("stratParserParse: internal error (3)"); YYABORT; } #endif /* SCOTCH_DEBUG_PARSER2 */ *((INT *) ((byte *) &parserstratcurr->data.method.data + (parserparamcurr->dataofft - parserparamcurr->database))) = (INT) ((yyvsp[0].INTEGER)); } } #line 1738 "y.tab.c" /* yacc.c:1646 */ break; case 30: #line 428 "parser_yy.y" /* yacc.c:1646 */ { if ((parserparamcurr->type & STRATPARAMDEPRECATED) == 0) { /* If parameter is not deprecated */ #ifdef SCOTCH_DEBUG_PARSER2 if ((parserparamcurr->dataofft - parserparamcurr->database + strlen ((yyvsp[0].STRING)) + 1) > sizeof (StratNodeMethodData)) { errorPrint ("stratParserParse: internal error (4)"); YYABORT; } #endif /* SCOTCH_DEBUG_PARSER2 */ strcpy ((char *) ((byte *) &parserstratcurr->data.method.data + (parserparamcurr->dataofft - parserparamcurr->database)), ((yyvsp[0].STRING))); } } #line 1758 "y.tab.c" /* yacc.c:1646 */ break; case 31: #line 444 "parser_yy.y" /* yacc.c:1646 */ { ((yyval.SAVE)).strat = parserstratcurr; ((yyval.SAVE)).param = parserparamcurr; parserstratcurr = NULL; parserparamcurr = NULL; } #line 1769 "y.tab.c" /* yacc.c:1646 */ break; case 32: #line 451 "parser_yy.y" /* yacc.c:1646 */ { parserstratcurr = ((yyvsp[-1].SAVE)).strat; /* Restore current method */ parserparamcurr = ((yyvsp[-1].SAVE)).param; /* Restore current parameter */ if ((parserparamcurr->type & STRATPARAMDEPRECATED) == 0) { /* If parameter is not deprecated */ #ifdef SCOTCH_DEBUG_PARSER2 if ((parserparamcurr->dataofft - parserparamcurr->database + sizeof (Strat *)) > sizeof (StratNodeMethodData)) { errorPrint ("stratParserParse: internal error (5)"); YYABORT; } #endif /* SCOTCH_DEBUG_PARSER2 */ *((Strat **) ((byte *) &parserstratcurr->data.method.data + (parserparamcurr->dataofft - parserparamcurr->database))) = ((yyvsp[0].STRAT)); } } #line 1791 "y.tab.c" /* yacc.c:1646 */ break; case 33: #line 469 "parser_yy.y" /* yacc.c:1646 */ { errorPrint ("stratParserParse: invalid value for parameter \"%s\" of method \"%s\", before \"%s\"", parserparamcurr->name, parserstratcurr->tabl->methtab[parserstratcurr->data.method.meth].name, stratParserRemain ()); YYABORT; } #line 1801 "y.tab.c" /* yacc.c:1646 */ break; case 35: #line 480 "parser_yy.y" /* yacc.c:1646 */ { StratTest * test; if ((test = (StratTest *) memAlloc (sizeof (StratTest))) == NULL) { errorPrint ("stratParserParse: out of memory (6)"); stratTestExit ((yyvsp[-2].TEST)); stratTestExit ((yyvsp[0].TEST)); YYABORT; } test->typetest = STRATTESTOR; test->typenode = STRATPARAMLOG; test->data.test[0] = ((yyvsp[-2].TEST)); test->data.test[1] = ((yyvsp[0].TEST)); ((yyval.TEST)) = test; } #line 1823 "y.tab.c" /* yacc.c:1646 */ break; case 37: #line 501 "parser_yy.y" /* yacc.c:1646 */ { StratTest * test; if ((test = (StratTest *) memAlloc (sizeof (StratTest))) == NULL) { errorPrint ("stratParserParse: out of memory (7)"); stratTestExit ((yyvsp[-2].TEST)); stratTestExit ((yyvsp[0].TEST)); YYABORT; } test->typetest = STRATTESTAND; test->typenode = STRATPARAMLOG; test->data.test[0] = ((yyvsp[-2].TEST)); test->data.test[1] = ((yyvsp[0].TEST)); ((yyval.TEST)) = test; } #line 1845 "y.tab.c" /* yacc.c:1646 */ break; case 39: #line 522 "parser_yy.y" /* yacc.c:1646 */ { StratTest * test; if ((test = (StratTest *) memAlloc (sizeof (StratTest))) == NULL) { errorPrint ("stratParserParse: out of memory (8)"); stratTestExit ((yyvsp[0].TEST)); YYABORT; } test->typetest = STRATTESTNOT; test->typenode = STRATPARAMLOG; test->data.test[0] = ((yyvsp[0].TEST)); ((yyval.TEST)) = test; } #line 1865 "y.tab.c" /* yacc.c:1646 */ break; case 40: #line 538 "parser_yy.y" /* yacc.c:1646 */ { ((yyval.TEST)) = ((yyvsp[-1].TEST)); } #line 1873 "y.tab.c" /* yacc.c:1646 */ break; case 42: #line 545 "parser_yy.y" /* yacc.c:1646 */ { StratTest * test; if ((test = (StratTest *) memAlloc (sizeof (StratTest))) == NULL) { errorPrint ("stratParserParse: out of memory (9)"); stratTestExit ((yyvsp[-2].TEST)); stratTestExit ((yyvsp[0].TEST)); YYABORT; } test->typetest = ((yyvsp[-1].TESTOP)); test->typenode = STRATPARAMLOG; test->data.test[0] = ((yyvsp[-2].TEST)); test->data.test[1] = ((yyvsp[0].TEST)); ((yyval.TEST)) = test; } #line 1894 "y.tab.c" /* yacc.c:1646 */ break; case 43: #line 564 "parser_yy.y" /* yacc.c:1646 */ { ((yyval.TESTOP)) = STRATTESTLT; } #line 1902 "y.tab.c" /* yacc.c:1646 */ break; case 44: #line 568 "parser_yy.y" /* yacc.c:1646 */ { ((yyval.TESTOP)) = STRATTESTEQ; } #line 1910 "y.tab.c" /* yacc.c:1646 */ break; case 45: #line 572 "parser_yy.y" /* yacc.c:1646 */ { ((yyval.TESTOP)) = STRATTESTGT; } #line 1918 "y.tab.c" /* yacc.c:1646 */ break; case 46: #line 578 "parser_yy.y" /* yacc.c:1646 */ { StratTest * test; if ((test = (StratTest *) memAlloc (sizeof (StratTest))) == NULL) { errorPrint ("stratParserParse: out of memory (10)"); stratTestExit ((yyvsp[-2].TEST)); stratTestExit ((yyvsp[0].TEST)); YYABORT; } test->typetest = ((yyvsp[-1].TESTOP)); test->data.test[0] = ((yyvsp[-2].TEST)); test->data.test[1] = ((yyvsp[0].TEST)); ((yyval.TEST)) = test; } #line 1938 "y.tab.c" /* yacc.c:1646 */ break; case 48: #line 597 "parser_yy.y" /* yacc.c:1646 */ { ((yyval.TESTOP)) = STRATTESTADD; } #line 1946 "y.tab.c" /* yacc.c:1646 */ break; case 49: #line 601 "parser_yy.y" /* yacc.c:1646 */ { ((yyval.TESTOP)) = STRATTESTSUB; } #line 1954 "y.tab.c" /* yacc.c:1646 */ break; case 50: #line 607 "parser_yy.y" /* yacc.c:1646 */ { StratTest * test; if ((test = (StratTest *) memAlloc (sizeof (StratTest))) == NULL) { stratTestExit ((yyvsp[-2].TEST)); stratTestExit ((yyvsp[0].TEST)); errorPrint ("stratParserParse: out of memory (11)"); YYABORT; } test->typetest = ((yyvsp[-1].TESTOP)); test->data.test[0] = ((yyvsp[-2].TEST)); test->data.test[1] = ((yyvsp[0].TEST)); ((yyval.TEST)) = test; } #line 1974 "y.tab.c" /* yacc.c:1646 */ break; case 52: #line 626 "parser_yy.y" /* yacc.c:1646 */ { ((yyval.TESTOP)) = STRATTESTMUL; } #line 1982 "y.tab.c" /* yacc.c:1646 */ break; case 53: #line 632 "parser_yy.y" /* yacc.c:1646 */ { StratTest * test; if ((test = (StratTest *) memAlloc (sizeof (StratTest))) == NULL) { errorPrint ("stratParserParse: out of memory (12)"); stratTestExit ((yyvsp[-2].TEST)); stratTestExit ((yyvsp[0].TEST)); YYABORT; } test->typetest = ((yyvsp[-1].TESTOP)); test->data.test[0] = ((yyvsp[-2].TEST)); test->data.test[1] = ((yyvsp[0].TEST)); ((yyval.TEST)) = test; } #line 2002 "y.tab.c" /* yacc.c:1646 */ break; case 55: #line 651 "parser_yy.y" /* yacc.c:1646 */ { ((yyval.TESTOP)) = STRATTESTMOD; } #line 2010 "y.tab.c" /* yacc.c:1646 */ break; case 56: #line 657 "parser_yy.y" /* yacc.c:1646 */ { ((yyval.TEST)) = ((yyvsp[-1].TEST)); } #line 2018 "y.tab.c" /* yacc.c:1646 */ break; case 59: #line 665 "parser_yy.y" /* yacc.c:1646 */ { StratTest * test; if ((test = (StratTest *) memAlloc (sizeof (StratTest))) == NULL) { errorPrint ("stratParserParse: out of memory (13)"); YYABORT; } test->typetest = STRATTESTVAL; test->typenode = STRATPARAMDOUBLE; test->data.val.valdbl = ((yyvsp[0].DOUBLE)); ((yyval.TEST)) = test; } #line 2037 "y.tab.c" /* yacc.c:1646 */ break; case 60: #line 680 "parser_yy.y" /* yacc.c:1646 */ { StratTest * test; if ((test = (StratTest *) memAlloc (sizeof (StratTest))) == NULL) { errorPrint ("stratParserParse: out of memory (14)"); YYABORT; } test->typetest = STRATTESTVAL; test->typenode = STRATPARAMINT; test->data.val.valint = ((yyvsp[0].INTEGER)); ((yyval.TEST)) = test; } #line 2056 "y.tab.c" /* yacc.c:1646 */ break; case 61: #line 697 "parser_yy.y" /* yacc.c:1646 */ { StratTest * test; StratParamTab * condtab; int para; int paralen; int i, j; para = paralen = 0; /* No parameter recognized yet */ condtab = parserstrattab->condtab; /* Point to parameter table */ for (i = 0; condtab[i].name != NULL; i ++) { if ((strncasecmp (((yyvsp[0].STRING)), /* Find longest matching parameter name */ condtab[i].name, j = strlen (condtab[i].name)) == 0) && (j > paralen)) { para = i; paralen = j; } } if (paralen == 0) { errorPrint ("stratParserParse: invalid graph parameter name \"%s\", before \"%s\"", ((yyvsp[0].STRING)), stratParserRemain ()); YYABORT; } if ((test = (StratTest *) memAlloc (sizeof (StratTest))) == NULL) { errorPrint ("stratParserParse: out of memory (15)"); YYABORT; } test->typetest = STRATTESTVAR; test->typenode = condtab[para].type; test->data.var.datatab = parserstrattab; test->data.var.datadisp = condtab[para].dataofft - condtab[para].database; ((yyval.TEST)) = test; } #line 2099 "y.tab.c" /* yacc.c:1646 */ break; case 62: #line 738 "parser_yy.y" /* yacc.c:1646 */ { ((yyval.DOUBLE)) = (((yyvsp[-1].TESTOP)) == STRATTESTSUB) ? - ((yyvsp[0].DOUBLE)) : ((yyvsp[0].DOUBLE)); } #line 2107 "y.tab.c" /* yacc.c:1646 */ break; case 64: #line 745 "parser_yy.y" /* yacc.c:1646 */ { ((yyval.INTEGER)) = (((yyvsp[-1].TESTOP)) == STRATTESTSUB) ? - ((yyvsp[0].INTEGER)) : ((yyvsp[0].INTEGER)); } #line 2115 "y.tab.c" /* yacc.c:1646 */ break; #line 2119 "y.tab.c" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires that yytoken be updated with the new translation. We take the approach of translating immediately before every use of yytoken. One alternative is translating here after every semantic action, but that translation would be missed if the semantic action invokes YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an incorrect destructor might then be invoked immediately. In the case of YYERROR or YYBACKUP, subsequent parser actions might lead to an incorrect destructor call or verbose syntax error message before the lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*--------------------------------------. | yyerrlab -- here on detecting error. | `--------------------------------------*/ yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (YY_("syntax error")); #else # define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ yyssp, yytoken) { char const *yymsgp = YY_("syntax error"); int yysyntax_error_status; yysyntax_error_status = YYSYNTAX_ERROR; if (yysyntax_error_status == 0) yymsgp = yymsg; else if (yysyntax_error_status == 1) { if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); if (!yymsg) { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; yysyntax_error_status = 2; } else { yysyntax_error_status = YYSYNTAX_ERROR; yymsgp = yymsg; } } yyerror (yymsgp); if (yysyntax_error_status == 2) goto yyexhaustedlab; } # undef YYSYNTAX_ERROR #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval); yychar = YYEMPTY; } } /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #if !defined yyoverflow || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEMPTY) { /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = YYTRANSLATE (yychar); yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval); } /* Do not reclaim the symbols of the rule whose action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif return yyresult; } #line 751 "parser_yy.y" /* yacc.c:1906 */ /* ** The static and global definitions (bis). ** These are put at the end of the file because ** the token values that they use are not yet ** defined in the first section of the file. */ unsigned int parsermethtokentab[] = { /* Table for parameter/token type conversion */ VALCASE, VALDOUBLE, VALINT, -1, /* No logical parameters */ VALSTRAT, VALSTRING, -1 /* One more value to detect array overflow */ }; /************************************/ /* */ /* These routines drive the parser. */ /* */ /************************************/ /* This routine is the entry point for ** the strategy parser. ** It returns: ** - !NULL : pointer to the strategy. ** - NULL : on error. */ Strat * stratParserParse ( const StratTab * const strattab, /*+ Pointer to parsing tables +*/ const char * const string) /*+ Strategy string to parse +*/ { yyclearin; /* Reset the parser state */ #ifdef SCOTCH_DEBUG_PARSER3 yydebug = 1; /* Set debugging if needed */ #endif /* SCOTCH_DEBUG_PARSER3 */ stratParserInit (string); /* Initialize the lexical parser */ parserstrattab = strattab; /* Point to the parsing tables */ parserstratcurr = NULL; /* Clear up the temporary strategy pointer */ if (stratParserParse2 () != 0) { /* Parse the strategy string */ if (parserstratcurr != NULL) stratExit (parserstratcurr); return (NULL); } return (parserstratcurr); /* Return strategy pointer */ } /* This routine displays the parser error message. ** It returns: ** - 1 : in all cases. */ static int stratParserError ( const char * const errstr) { errorPrint ("stratParserParse: invalid strategy string, before \"%s\"", stratParserRemain ()); return (1); } scotch-6.0.4.dfsg/src/libscotch/last_resort/svn-commit.tmp~0000644002563400244210000000014512412577230027212 0ustar trophimeutilisateurs du domaine --This line, and those below, will be ignored-- M parser_ll.c M parser_ly.h M parser_yy.c scotch-6.0.4.dfsg/src/libscotch/last_resort/parser_ly.h0000644002563400244210000000650112412577230026351 0ustar trophimeutilisateurs du domaine/* A Bison parser, made by GNU Bison 3.0.2. */ /* Bison interface for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ #ifndef YY_SCOTCHYY_Y_TAB_H_INCLUDED # define YY_SCOTCHYY_Y_TAB_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif #if YYDEBUG extern int scotchyydebug; #endif /* Token type. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { METHODNAME = 258, PARAMNAME = 259, VALCASE = 260, VALDOUBLE = 261, VALINT = 262, VALSTRING = 263, VALSTRAT = 264, VALPARAM = 265, VALTEST = 266 }; #endif /* Tokens. */ #define METHODNAME 258 #define PARAMNAME 259 #define VALCASE 260 #define VALDOUBLE 261 #define VALINT 262 #define VALSTRING 263 #define VALSTRAT 264 #define VALPARAM 265 #define VALTEST 266 /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE YYSTYPE; union YYSTYPE { #line 92 "parser_yy.y" /* yacc.c:1909 */ char CASEVAL; /* Case value */ StratTest * TEST; /* Test type */ StratTestType TESTOP; /* Relational type */ double DOUBLE; /* Double-precision */ INT INTEGER; /* Integer */ char STRING[PARSERSTRINGLEN]; /* Character string */ struct { const StratTab * tabl; /* Current tables */ Strat * strat; /* Current method */ StratParamTab * param; /* Current parameter */ } SAVE; /* Parameter type */ Strat * STRAT; /* Strategy tree */ #line 91 "y.tab.h" /* yacc.c:1909 */ }; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif extern YYSTYPE scotchyylval; int scotchyyparse (void); #endif /* !YY_SCOTCHYY_Y_TAB_H_INCLUDED */ scotch-6.0.4.dfsg/src/libscotch/last_resort/parser_ll.c0000644002563400244210000015776212412577227026355 0ustar trophimeutilisateurs du domaine#line 2 "lex.yy.c" #line 4 "lex.yy.c" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define yy_create_buffer scotchyy_create_buffer #define yy_delete_buffer scotchyy_delete_buffer #define yy_flex_debug scotchyy_flex_debug #define yy_init_buffer scotchyy_init_buffer #define yy_flush_buffer scotchyy_flush_buffer #define yy_load_buffer_state scotchyy_load_buffer_state #define yy_switch_to_buffer scotchyy_switch_to_buffer #define yyin scotchyyin #define yyleng scotchyyleng #define yylex scotchyylex #define yylineno scotchyylineno #define yyout scotchyyout #define yyrestart scotchyyrestart #define yytext scotchyytext #define yywrap scotchyywrap #define yyalloc scotchyyalloc #define yyrealloc scotchyyrealloc #define yyfree scotchyyfree #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 37 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE scotchyyrestart(scotchyyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #define YY_BUF_SIZE 16384 #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern yy_size_t scotchyyleng; extern FILE *scotchyyin, *scotchyyout; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up scotchyytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up scotchyytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via scotchyyrestart()), so that the user can continue scanning by * just pointing scotchyyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* Stack of input buffers. */ static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] /* yy_hold_char holds the character lost when scotchyytext is formed. */ static char yy_hold_char; static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ yy_size_t scotchyyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = (char *) 0; static int yy_init = 0; /* whether we need to initialize */ static int yy_start = 0; /* start state number */ /* Flag which is used to allow scotchyywrap()'s to do buffer switches * instead of setting up a fresh scotchyyin. A bit of a hack ... */ static int yy_did_buffer_switch_on_eof; void scotchyyrestart (FILE *input_file ); void scotchyy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); YY_BUFFER_STATE scotchyy_create_buffer (FILE *file,int size ); void scotchyy_delete_buffer (YY_BUFFER_STATE b ); void scotchyy_flush_buffer (YY_BUFFER_STATE b ); void scotchyypush_buffer_state (YY_BUFFER_STATE new_buffer ); void scotchyypop_buffer_state (void ); static void scotchyyensure_buffer_stack (void ); static void scotchyy_load_buffer_state (void ); static void scotchyy_init_buffer (YY_BUFFER_STATE b,FILE *file ); #define YY_FLUSH_BUFFER scotchyy_flush_buffer(YY_CURRENT_BUFFER ) YY_BUFFER_STATE scotchyy_scan_buffer (char *base,yy_size_t size ); YY_BUFFER_STATE scotchyy_scan_string (yyconst char *yy_str ); YY_BUFFER_STATE scotchyy_scan_bytes (yyconst char *bytes,yy_size_t len ); void *scotchyyalloc (yy_size_t ); void *scotchyyrealloc (void *,yy_size_t ); void scotchyyfree (void * ); #define yy_new_buffer scotchyy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ scotchyyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ scotchyy_create_buffer(scotchyyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ scotchyyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ scotchyy_create_buffer(scotchyyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ typedef unsigned char YY_CHAR; FILE *scotchyyin = (FILE *) 0, *scotchyyout = (FILE *) 0; typedef int yy_state_type; extern int scotchyylineno; int scotchyylineno = 1; extern char *scotchyytext; #define yytext_ptr scotchyytext static yy_state_type yy_get_previous_state (void ); static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); static int yy_get_next_buffer (void ); static void yy_fatal_error (yyconst char msg[] ); /* Done after the current pattern has been matched and before the * corresponding action - sets up scotchyytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ scotchyyleng = (size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 13 #define YY_END_OF_BUFFER 14 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[53] = { 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 14, 12, 11, 11, 1, 2, 3, 4, 5, 12, 8, 10, 11, 2, 0, 4, 0, 0, 5, 0, 0, 7, 0, 8, 0, 10, 4, 0, 4, 6, 0, 6, 9, 0, 9, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 5, 6, 1, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 8, 8, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int32_t yy_meta[10] = { 0, 1, 2, 2, 1, 1, 1, 3, 3, 3 } ; static yyconst flex_int16_t yy_base[58] = { 0, 0, 2, 0, 0, 2, 0, 5, 0, 57, 56, 55, 54, 56, 55, 8, 0, 58, 65, 0, 0, 65, 0, 65, 12, 16, 53, 20, 0, 0, 0, 49, 0, 25, 48, 0, 28, 50, 65, 39, 0, 31, 0, 32, 36, 33, 35, 30, 27, 38, 24, 21, 65, 47, 22, 17, 50, 3 } ; static yyconst flex_int16_t yy_def[58] = { 0, 53, 53, 2, 3, 2, 5, 5, 7, 2, 2, 2, 2, 2, 2, 2, 15, 52, 52, 54, 54, 52, 55, 52, 52, 52, 56, 52, 57, 54, 55, 52, 24, 52, 52, 25, 52, 56, 52, 52, 27, 52, 57, 52, 52, 52, 52, 52, 52, 52, 52, 52, 0, 52, 52, 52, 52, 52 } ; static yyconst flex_int16_t yy_nxt[75] = { 0, 52, 19, 20, 19, 20, 42, 21, 21, 21, 22, 22, 23, 23, 23, 27, 28, 28, 31, 32, 30, 33, 34, 35, 29, 36, 39, 40, 51, 41, 44, 51, 45, 47, 48, 48, 50, 48, 51, 43, 45, 33, 46, 45, 36, 49, 49, 41, 18, 18, 18, 37, 37, 37, 38, 46, 43, 38, 52, 26, 26, 25, 25, 24, 24, 17, 52, 52, 52, 52, 52, 52, 52, 52, 52 } ; static yyconst flex_int16_t yy_chk[75] = { 0, 0, 1, 1, 2, 2, 57, 3, 3, 3, 5, 5, 7, 7, 7, 15, 15, 15, 24, 24, 55, 24, 25, 25, 54, 25, 27, 27, 51, 27, 33, 50, 33, 36, 48, 36, 41, 47, 41, 43, 45, 43, 46, 44, 46, 49, 39, 49, 53, 53, 53, 56, 56, 56, 37, 34, 31, 26, 17, 14, 13, 12, 11, 10, 9, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52 } ; static yy_state_type yy_last_accepting_state; static char *yy_last_accepting_cpos; extern int scotchyy_flex_debug; int scotchyy_flex_debug = 0; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET char *scotchyytext; #line 1 "parser_ll.l" #line 2 "parser_ll.l" /* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : parser_ll.l **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the lexical parser **/ /** which processes strategy strings. **/ /** **/ /** DATES : # Version 3.1 : from : 07 nov 1995 **/ /** to 23 aug 1996 **/ /** # Version 3.2 : from : 24 sep 1996 **/ /** to 05 jun 1997 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 11 sep 2001 **/ /** # Version 4.0 : from : 20 dec 2001 **/ /** to 23 dec 2001 **/ /** # Version 5.1 : from : 09 jun 2009 **/ /** to 24 jul 2011 **/ /** **/ /** NOTES : # In order for flex to read its input **/ /** with getc() instead of fread, we set **/ /** YY_ALWAYS_INTERACTIVE to 1. This may **/ /** not always work with future releases. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define PARSER_LL #include "module.h" #include "common.h" #undef INTEGER /* In case someone defined them */ #undef DOUBLE #include "parser.h" #include "parser_ll.h" #include "parser_yy.h" #include "parser_ly.h" /*+ Definitions produced by yacc +*/ /* Assume no interactive parsing. */ #ifdef X_OSDOS /* Available only with MKS LEX */ #ifdef YY_INTERACTIVE #undef YY_INTERACTIVE #endif /* YY_INTERACTIVE */ #define YY_INTERACTIVE 0 #endif /* X_OSDOS */ #ifdef FLEX_SCANNER #define YY_ALWAYS_INTERACTIVE 1 /* Set the parser as interactive and read one char at a time */ #define YY_INPUT(buf,result,max_size) { int c = stratParserInput (); result = (c == 0) ? YY_NULL : ((buf)[0] = c, 1); } #else /* FLEX_SCANNER */ #undef getc /* Redirect I/O functions */ #define getc yygetc #undef yygetc #define yygetc(stream) stratParserInput () #endif /* FLEX_SCANNER */ #define YY_NO_UNPUT /* No prototype for yyunput as not defined */ #define YY_SKIP_YYWRAP /* No prototype for scotchyywrap as defined as macro */ #define scotchyywrap() (1) /* Always return end-of-file on end-of-string */ /* ** The static variables. */ static const char * stratparserstringptr; /* Pointer to the string to parse */ #line 611 "lex.yy.c" #define INITIAL 0 #define lstrat 1 #define lparam 2 #define lparamcase 3 #define lparamdouble 4 #define lparamint 5 #define lparamstring 6 #define ltest 7 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif static int yy_init_globals (void ); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int scotchyylex_destroy (void ); int scotchyyget_debug (void ); void scotchyyset_debug (int debug_flag ); YY_EXTRA_TYPE scotchyyget_extra (void ); void scotchyyset_extra (YY_EXTRA_TYPE user_defined ); FILE *scotchyyget_in (void ); void scotchyyset_in (FILE * in_str ); FILE *scotchyyget_out (void ); void scotchyyset_out (FILE * out_str ); yy_size_t scotchyyget_leng (void ); char *scotchyyget_text (void ); int scotchyyget_lineno (void ); void scotchyyset_lineno (int line_number ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int scotchyywrap (void ); #else extern int scotchyywrap (void ); #endif #endif static void yyunput (int c,char *buf_ptr ); #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void ); #else static int input (void ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( scotchyytext, scotchyyleng, 1, scotchyyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ size_t n; \ for ( n = 0; n < max_size && \ (c = getc( scotchyyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( scotchyyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = fread(buf, 1, max_size, scotchyyin))==0 && ferror(scotchyyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(scotchyyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int scotchyylex (void); #define YY_DECL int scotchyylex (void) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after scotchyytext and scotchyyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; #line 121 "parser_ll.l" #line 802 "lex.yy.c" if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! scotchyyin ) scotchyyin = stdin; if ( ! scotchyyout ) scotchyyout = stdout; if ( ! YY_CURRENT_BUFFER ) { scotchyyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = scotchyy_create_buffer(scotchyyin,YY_BUF_SIZE ); } scotchyy_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of scotchyytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 53 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_base[yy_current_state] != 65 ); yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: YY_RULE_SETUP #line 122 "parser_ll.l" { strncpy (yylval.STRING, scotchyytext, PARSERSTRINGLEN); yylval.STRING[PARSERSTRINGLEN - 1] = '\0'; return (METHODNAME); } YY_BREAK case 2: YY_RULE_SETUP #line 128 "parser_ll.l" { strncpy (yylval.STRING, scotchyytext, PARSERSTRINGLEN); yylval.STRING[PARSERSTRINGLEN - 1] = '\0'; return (PARAMNAME); } YY_BREAK case 3: YY_RULE_SETUP #line 134 "parser_ll.l" { yylval.CASEVAL = scotchyytext[0]; return (VALCASE); } YY_BREAK case 4: YY_RULE_SETUP #line 139 "parser_ll.l" { yylval.DOUBLE = atof (scotchyytext); return (VALDOUBLE); } YY_BREAK case 5: YY_RULE_SETUP #line 144 "parser_ll.l" { yylval.INTEGER = (INT) atol (scotchyytext); return (VALINT); } YY_BREAK case 6: YY_RULE_SETUP #line 148 "parser_ll.l" { yylval.INTEGER = (INT) atof (scotchyytext); /* FLOAT is put after so that INTEGER can be matched */ return (VALINT); } YY_BREAK case 7: /* rule 7 can match eol */ YY_RULE_SETUP #line 153 "parser_ll.l" { scotchyytext[scotchyyleng - 1] = '\0'; /* Remove the heading and trailing \" */ strncpy (yylval.STRING, scotchyytext + 1, PARSERSTRINGLEN); yylval.STRING[PARSERSTRINGLEN - 1] = '\0'; return (VALSTRING); } YY_BREAK case 8: YY_RULE_SETUP #line 160 "parser_ll.l" { yylval.INTEGER = (INT) atol (scotchyytext); return (VALINT); } YY_BREAK case 9: YY_RULE_SETUP #line 164 "parser_ll.l" { yylval.DOUBLE = atof (scotchyytext); return (VALDOUBLE); } YY_BREAK case 10: YY_RULE_SETUP #line 168 "parser_ll.l" { strncpy (yylval.STRING, scotchyytext, PARSERSTRINGLEN); yylval.STRING[PARSERSTRINGLEN - 1] = '\0'; return (PARAMNAME); } YY_BREAK case 11: /* rule 11 can match eol */ YY_RULE_SETUP #line 174 "parser_ll.l" ; YY_BREAK case 12: YY_RULE_SETUP #line 175 "parser_ll.l" return (scotchyytext[0]); YY_BREAK case 13: YY_RULE_SETUP #line 177 "parser_ll.l" ECHO; YY_BREAK #line 987 "lex.yy.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(lstrat): case YY_STATE_EOF(lparam): case YY_STATE_EOF(lparamcase): case YY_STATE_EOF(lparamdouble): case YY_STATE_EOF(lparamint): case YY_STATE_EOF(lparamstring): case YY_STATE_EOF(ltest): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed scotchyyin at a new source and called * scotchyylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = scotchyyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_c_buf_p); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( scotchyywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * scotchyytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of scotchyylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (void) { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { yy_size_t num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ scotchyyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; scotchyyrestart(scotchyyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) scotchyyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (void) { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 53 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) { register int yy_is_jam; register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 53 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 52); return yy_is_jam ? 0 : yy_current_state; } static void yyunput (int c, register char * yy_bp ) { register char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up scotchyytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register yy_size_t number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void) #else static int input (void) #endif { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ scotchyyrestart(scotchyyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( scotchyywrap( ) ) return EOF; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve scotchyytext */ (yy_hold_char) = *++(yy_c_buf_p); return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void scotchyyrestart (FILE * input_file ) { if ( ! YY_CURRENT_BUFFER ){ scotchyyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = scotchyy_create_buffer(scotchyyin,YY_BUF_SIZE ); } scotchyy_init_buffer(YY_CURRENT_BUFFER,input_file ); scotchyy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void scotchyy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * scotchyypop_buffer_state(); * scotchyypush_buffer_state(new_buffer); */ scotchyyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; scotchyy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (scotchyywrap()) processing, but the only time this flag * is looked at is after scotchyywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } static void scotchyy_load_buffer_state (void) { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; scotchyyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE scotchyy_create_buffer (FILE * file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) scotchyyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in scotchyy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) scotchyyalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in scotchyy_create_buffer()" ); b->yy_is_our_buffer = 1; scotchyy_init_buffer(b,file ); return b; } /** Destroy the buffer. * @param b a buffer created with scotchyy_create_buffer() * */ void scotchyy_delete_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) scotchyyfree((void *) b->yy_ch_buf ); scotchyyfree((void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a scotchyyrestart() or at EOF. */ static void scotchyy_init_buffer (YY_BUFFER_STATE b, FILE * file ) { int oerrno = errno; scotchyy_flush_buffer(b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then scotchyy_init_buffer was _probably_ * called from scotchyyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void scotchyy_flush_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) scotchyy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void scotchyypush_buffer_state (YY_BUFFER_STATE new_buffer ) { if (new_buffer == NULL) return; scotchyyensure_buffer_stack(); /* This block is copied from scotchyy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from scotchyy_switch_to_buffer. */ scotchyy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void scotchyypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; scotchyy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { scotchyy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void scotchyyensure_buffer_stack (void) { yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)scotchyyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in scotchyyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)scotchyyrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in scotchyyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE scotchyy_scan_buffer (char * base, yy_size_t size ) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return 0; b = (YY_BUFFER_STATE) scotchyyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in scotchyy_scan_buffer()" ); b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = 0; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; scotchyy_switch_to_buffer(b ); return b; } /** Setup the input buffer state to scan a string. The next call to scotchyylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * scotchyy_scan_bytes() instead. */ YY_BUFFER_STATE scotchyy_scan_string (yyconst char * yystr ) { return scotchyy_scan_bytes(yystr,strlen(yystr) ); } /** Setup the input buffer state to scan the given bytes. The next call to scotchyylex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE scotchyy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; buf = (char *) scotchyyalloc(n ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in scotchyy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = scotchyy_scan_buffer(buf,n ); if ( ! b ) YY_FATAL_ERROR( "bad buffer in scotchyy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yy_fatal_error (yyconst char* msg ) { (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up scotchyytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ scotchyytext[scotchyyleng] = (yy_hold_char); \ (yy_c_buf_p) = scotchyytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ scotchyyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the current line number. * */ int scotchyyget_lineno (void) { return scotchyylineno; } /** Get the input stream. * */ FILE *scotchyyget_in (void) { return scotchyyin; } /** Get the output stream. * */ FILE *scotchyyget_out (void) { return scotchyyout; } /** Get the length of the current token. * */ yy_size_t scotchyyget_leng (void) { return scotchyyleng; } /** Get the current token. * */ char *scotchyyget_text (void) { return scotchyytext; } /** Set the current line number. * @param line_number * */ void scotchyyset_lineno (int line_number ) { scotchyylineno = line_number; } /** Set the input stream. This does not discard the current * input buffer. * @param in_str A readable stream. * * @see scotchyy_switch_to_buffer */ void scotchyyset_in (FILE * in_str ) { scotchyyin = in_str ; } void scotchyyset_out (FILE * out_str ) { scotchyyout = out_str ; } int scotchyyget_debug (void) { return scotchyy_flex_debug; } void scotchyyset_debug (int bdebug ) { scotchyy_flex_debug = bdebug ; } static int yy_init_globals (void) { /* Initialization is the same as for the non-reentrant scanner. * This function is called from scotchyylex_destroy(), so don't allocate here. */ (yy_buffer_stack) = 0; (yy_buffer_stack_top) = 0; (yy_buffer_stack_max) = 0; (yy_c_buf_p) = (char *) 0; (yy_init) = 0; (yy_start) = 0; /* Defined in main.c */ #ifdef YY_STDINIT scotchyyin = stdin; scotchyyout = stdout; #else scotchyyin = (FILE *) 0; scotchyyout = (FILE *) 0; #endif /* For future reference: Set errno on error, since we are called by * scotchyylex_init() */ return 0; } /* scotchyylex_destroy is for both reentrant and non-reentrant scanners. */ int scotchyylex_destroy (void) { /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ scotchyy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; scotchyypop_buffer_state(); } /* Destroy the stack itself. */ scotchyyfree((yy_buffer_stack) ); (yy_buffer_stack) = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * scotchyylex() is called, initialization will occur. */ yy_init_globals( ); return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *scotchyyalloc (yy_size_t size ) { return (void *) malloc( size ); } void *scotchyyrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void scotchyyfree (void * ptr ) { free( (char *) ptr ); /* see scotchyyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 177 "parser_ll.l" /*******************************************/ /* */ /* These routines handle data input to the */ /* lexical analyzer. */ /* */ /*******************************************/ /* This routine initializes the ** lexical analyzer. ** It returns: ** - VOID : in all cases. */ void stratParserInit ( const char * const string) /*+ Strategy string to parse +*/ { #ifdef FLEX_SCANNER scotchyyrestart (scotchyyin); /* (Re-)initialize the parser */ #endif /* FLEX_SCANNER */ stratParserSelect (VALSTRAT); /* Begin with a strategy */ stratparserstringptr = string; /* Point to beginning of string */ } /* This routine reads a single character ** from the input string. ** It returns: ** - 0 : if end of string reached. ** - !0 : character from string. */ static int stratParserInput () { if (*stratparserstringptr == '\0') /* If end-of-string reached */ return (0); /* Return end-of-file token */ else /* Else return the character */ return ((int) (unsigned char) *stratparserstringptr ++); } /* This routine returns the pointer to the ** remaining part of the string. */ const char * stratParserRemain () { return (stratparserstringptr); } /* This routine selects the sub-parser ** to parse the input. ** It returns: ** - VOID : in all cases. */ void stratParserSelect ( unsigned int type) { switch (type) { case VALCASE : BEGIN lparamcase; break; case VALDOUBLE : BEGIN lparamdouble; break; case VALINT : BEGIN lparamint; break; case VALSTRING : BEGIN lparamstring; break; case VALPARAM : BEGIN lparam; break; case VALSTRAT : BEGIN lstrat; break; case VALTEST : BEGIN ltest; break; } } scotch-6.0.4.dfsg/src/libscotch/wgraph_part_gg.c0000644002563400244210000003471312473175601025007 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : wgraph_part_gg.c **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Charles-Edmond BICHOT (v5.1b) **/ /** **/ /** FUNCTION : This module is the vertex overlapped **/ /** graph partitioning rountine based on **/ /** a vertex-oriented version of the Greedy **/ /** Graph Growing algorithm. **/ /** **/ /** DATES : # Version 5.1 : from : 01 dec 2007 **/ /** to : 01 jul 2008 **/ /** # Version 6.0 : from : 05 nov 2009 **/ /** to : 14 mar 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define WGRAPH_PART_GG #include "module.h" #include "common.h" #include "gain.h" #include "graph.h" #include "wgraph.h" #include "wgraph_part_gg.h" /* ** The static variables. */ static const Gnum wgraphpartggloadone = 1; /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the bipartitioning. ** It returns: ** - 0 : if the bipartitioning could be computed. ** - !0 : on error. */ int wgraphPartGg ( Wgraph * restrict const wgrafptr, /*+ Separation graph +*/ const WgraphPartGgParam * const paraptr) /*+ Method parameters +*/ { Gnum i; Gnum gain; Gnum fronnbr; /* Number of frontier vertices */ Gnum fronload; /* Load of frontier vertices */ Gnum frlobst; /* Best frontier load found */ Gnum fronnum; Gnum partval; Gnum vertnum; Gnum vertnum2; Gnum vertnum3; Gnum edgenum; Gnum edgenum2; Gnum palooth; /* Load of vertices in the remained unassigned part */ Gnum paloexc; /* Load of vertices in the current part excepting the frontier */ Gnum frloprt; /* Load of vertices in the frontier of the current part */ Gnum passnum; Gnum velomsk; const Gnum * restrict velobax; /* Data for handling of optional arrays */ Gnum * restrict permtab; /* permutation table */ Gnum * restrict parttax; Gnum * restrict compload; /* Array of part load */ Gnum * restrict compsize; /* Array of part vertices number */ GainTabl * restrict tabl; /* Pointer to gain table */ WgraphPartGgVertex * vexxtax; /* Complementary vertex array */ GainLink * restrict gainlinkptr; WgraphPartGgVertex * restrict vertlist; /* List of vertices */ printf ("GG (" GNUMSTRING ")\n", wgrafptr->s.vertnbr); if (((tabl = gainTablInit (GAIN_LINMAX, WGRAPHSEPAGGSUBBITS)) == NULL) || /* Use logarithmic array only */ memAllocGroup((void **) (void *) &vexxtax, (size_t) (wgrafptr->s.vertnbr * sizeof (WgraphPartGgVertex)), &compload, (size_t) (wgrafptr->partnbr * sizeof (Gnum)), &compsize, (size_t) (wgrafptr->partnbr * sizeof (Gnum)), &parttax, (size_t) (wgrafptr->s.vertnbr * sizeof (Gnum)), &permtab, (size_t) (wgrafptr->s.vertnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("wgraphPartGg: out of memory (1)"); gainTablExit (tabl); return (1); } vexxtax -= wgrafptr->s.baseval; /* Base access to vexxtax */ parttax -= wgrafptr->s.baseval; /* Base access to parttax */ for (vertnum = 0; vertnum < wgrafptr->s.vertnbr; vertnum ++) { /* Initialization of the permutation table */ i = intRandVal (vertnum + 1); permtab[vertnum] = permtab[i]; permtab[i] = vertnum; } if (wgrafptr->s.velotax == NULL) { /* Set accesses to optional arrays */ velobax = &wgraphpartggloadone; /* In case vertices not weighted (least often) */ velomsk = 0; } else { velobax = wgrafptr->s.velotax; velomsk = ~((Gnum) 0); } frlobst = wgrafptr->s.velosum + 1; for (passnum = 0; passnum < paraptr->passnbr; passnum ++) { fronload = fronnbr = 0; vertnum = -1; palooth = wgrafptr->s.velosum; memSet (compload, 0, wgrafptr->partnbr * sizeof (Gnum)); memSet (compsize, 0, wgrafptr->partnbr * sizeof (Gnum)); memSet (parttax + wgrafptr->s.baseval, 0, wgrafptr->s.vertnbr * sizeof (Gnum)); memSet (vexxtax + wgrafptr->s.baseval, 0, wgrafptr->s.vertnbr * sizeof (WgraphPartGgVertex)); gainTablFree (tabl); for (partval = 0; partval < wgrafptr->partnbr; partval ++) { paloexc = frloprt = 0; gainlinkptr = gainTablFrst (tabl); /* Try to take a vertex from the frontier of the last part */ gainTablFree (tabl); if (gainlinkptr != NULL) { /* If the table was not empty */ vertnum = (WgraphPartGgVertex *) gainlinkptr - vexxtax; for (edgenum = wgrafptr->s.verttax[vertnum]; /* search a neighbor vertex that is in the part 0 */ edgenum < wgrafptr->s.vendtax[vertnum]; edgenum ++) { vertnum2 = wgrafptr->s.edgetax[edgenum]; if (parttax[vertnum2] == 0) { gainTablAdd(tabl, &(vexxtax[vertnum2].gainlink), 0); /* Add it in the table in order to be selected */ /* (the table will contain only this vertex) */ fronnbr ++; parttax[vertnum2] = -1; /* Move it in the seperator */ fronload += velobax[vertnum2 & velomsk]; compload[partval] += velobax[vertnum2 & velomsk]; compsize[partval] ++; break; } } } do { /* While the part is not big enought */ gainlinkptr = gainTablFrst(tabl); if (gainlinkptr != NULL) { vertnum = (WgraphPartGgVertex *) gainlinkptr - vexxtax; gainTablDel(tabl, gainlinkptr); } else { /* If the table was empty */ if ((2 * (paloexc + frloprt / 2)) * (wgrafptr->partnbr - partval + 1) <= palooth) { /* If the part load is not big enought */ for (i = 0; i < wgrafptr->s.vertnbr; i ++) { /* select a random vertex in the part 0 */ Gnum pos = i + intRandVal (wgrafptr->s.vertnbr - i); vertnum = permtab[pos]; permtab[pos] = permtab[i]; permtab[i] = vertnum; vertnum += wgrafptr->s.baseval; if (parttax[vertnum] == 0) { for (edgenum = wgrafptr->s.verttax[vertnum]; edgenum < wgrafptr->s.vendtax[vertnum]; edgenum ++) { vertnum2 = wgrafptr->s.edgetax[edgenum]; if (parttax[vertnum2] > 0) { break; } } break; } } fronload += velobax[vertnum & velomsk]; frloprt += velobax[vertnum & velomsk]; compload[partval] += velobax[vertnum & velomsk]; parttax[vertnum] = -1; compsize[partval] ++; fronnbr ++; } else break; } fronnbr --; frloprt -= velobax[vertnum & velomsk]; fronload -= velobax[vertnum & velomsk]; paloexc += velobax[vertnum & velomsk]; parttax[vertnum] = partval; vertlist = NULL; for (edgenum = wgrafptr->s.verttax[vertnum]; edgenum < wgrafptr->s.vendtax[vertnum]; edgenum ++) { vertnum2 = wgrafptr->s.edgetax[edgenum]; if ((parttax[vertnum2] != -1) && (parttax[vertnum2] != partval)) { /* If the vertex is in a different part */ fronnbr ++; parttax[vertnum2] = -1; /* Move the vertex in the separator */ fronload += velobax[vertnum2 & velomsk]; frloprt += velobax[vertnum2 & velomsk]; compload[partval] += velobax[vertnum2 & velomsk]; compsize[partval] ++; vexxtax[vertnum2].partlvl = partval; /* Label the vertex for this part */ vexxtax[vertnum2].prev = vertlist; /* Add the vertex in the list */ vertlist = vexxtax + vertnum2; } else if (parttax[vertnum2] == -1) { if (vexxtax[vertnum2].partlvl == partval) { /* If the vertex is labeled for the current part */ if (vexxtax[vertnum2].gainlink.next != (GainLink * )~0) { /* If the vertex is in the table */ gainTablDel(tabl, &(vexxtax[vertnum2].gainlink)); /* Remove it from table */ vexxtax[vertnum2].prev = vertlist; /* Add the vertex in the list */ vertlist = vexxtax + vertnum2; } } else { frloprt += velobax[vertnum2 & velomsk]; compload[partval] += velobax[vertnum2 & velomsk]; compsize[partval] ++; vexxtax[vertnum2].partlvl = partval; /* Label it for the part */ vexxtax[vertnum2].gainlink.next = (GainLink * )~0; } } } while (vertlist != NULL) { /* For eack linked vertices */ vertnum2 = vertlist - vexxtax; gain = - velobax[vertnum2 & velomsk]; /* Compute gain */ for (edgenum2 = wgrafptr->s.verttax[vertnum2]; edgenum2 < wgrafptr->s.vendtax[vertnum2]; edgenum2 ++) { vertnum3 = wgrafptr->s.edgetax[edgenum2]; if ((parttax[vertnum3] != -1) && (parttax[vertnum3] != partval)) { gain += velobax[vertnum3 & velomsk]; } } gainTablAdd(tabl, &(vertlist->gainlink), gain); /* Add the vertex in the table */ vertlist = vertlist->prev; } } while ((paloexc + frloprt / 2) * (wgrafptr->partnbr - partval + 1) <= palooth); /* While the part is not big enought */ palooth -= (paloexc + frloprt / 2); } compload[0] = compsize[0] = 0; for (vertnum = wgrafptr->s.baseval; vertnum < wgrafptr->s.vertnnd; vertnum++) { /* Recompute load and size of part 0 */ if (parttax[vertnum] == 0) { compload[0] += velobax[vertnum & velomsk]; compsize[0] ++; } else if (parttax[vertnum] == -1) { for (edgenum = wgrafptr->s.verttax[vertnum]; edgenum < wgrafptr->s.vendtax[vertnum]; edgenum ++) { vertnum2 = wgrafptr->s.edgetax[edgenum]; if (parttax[vertnum2] == 0) { compload[0] += velobax[vertnum & velomsk]; compsize[0] ++; break; } } } } if (frlobst > fronload) { /* If the pass frontier load is better than the better one */ wgrafptr->fronnbr = fronnbr; wgrafptr->fronload = fronload; memCpy (wgrafptr->compload, compload, sizeof (Gnum) * wgrafptr->partnbr); memCpy (wgrafptr->compsize, compsize, sizeof (Gnum) * wgrafptr->partnbr); memCpy (wgrafptr->parttax + wgrafptr->s.baseval, parttax + wgrafptr->s.baseval, sizeof (Gnum) * wgrafptr->s.vertnbr); for (vertnum = wgrafptr->s.baseval, fronnum = 0; vertnum < wgrafptr->s.vertnnd; vertnum ++) { /* Recompute frontab */ if (parttax[vertnum] == -1) wgrafptr->frontab[fronnum ++] = vertnum; } frlobst = fronload; /* This frontier load will the best found */ } } for (partval = 0; partval < wgrafptr->partnbr; partval ++) printf("\033[0;33mcompload[" GNUMSTRING "] " GNUMSTRING " " GNUMSTRING "\033[0m\n", partval, wgrafptr->compload[partval], wgrafptr->compsize[partval]); memFree(vexxtax + wgrafptr->s.baseval); /* Free work arrays */ gainTablExit (tabl); return (0); } scotch-6.0.4.dfsg/src/libscotch/hgraph_order_hd.h0000644002563400244210000000727211631447170025136 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2009 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hgraph_order_hd.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the block-oriented Halo **/ /** Approximate (Multiple) Minimum Degree **/ /** ordering routine. **/ /** **/ /** DATES : # Version 3.2 : from : 09 aug 1998 **/ /** to : 18 aug 1998 **/ /** # Version 3.3 : from : 02 oct 1998 **/ /** to : 19 oct 1998 **/ /** # Version 4.0 : from : 14 jan 2003 **/ /** to : 24 jan 2004 **/ /** # Version 5.1 : from : 01 oct 2009 **/ /** to : 01 oct 2009 **/ /** **/ /************************************************************/ /* ** The defines. */ #define HGRAPHORDERHDCOMPRAT 1.2L /*+ Compression ratio +*/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct HgraphOrderHdParam_ { INT colmin; /*+ Minimum number of columns +*/ INT colmax; /*+ Maximum number of columns +*/ double fillrat; /*+ Fill-in ratio +*/ } HgraphOrderHdParam; /* ** The function prototypes. */ #ifndef HGRAPH_ORDER_HD #define static #endif int hgraphOrderHd (const Hgraph * restrict const, Order * restrict const, const Gnum, OrderCblk * restrict const, const HgraphOrderHdParam * restrict const); #undef static scotch-6.0.4.dfsg/src/libscotch/graph_coarsen.h0000644002563400244210000002261412474554132024632 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2011-2013,2015 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : graph_coarsen.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the source graph coarsening **/ /** functions. **/ /** **/ /** DATES : # Version 0.0 : from : 02 dec 1992 **/ /** to 18 may 1993 **/ /** # Version 1.3 : from : 30 apr 1994 **/ /** to 18 may 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to 18 aug 1994 **/ /** # Version 3.0 : from : 07 jul 1995 **/ /** to 28 sep 1995 **/ /** # Version 3.1 : from : 28 nov 1995 **/ /** to 28 nov 1995 **/ /** # Version 3.2 : from : 07 sep 1996 **/ /** to 17 sep 1998 **/ /** # Version 4.0 : from : 13 dec 2001 **/ /** to 05 dec 2004 **/ /** # Version 6.0 : from : 09 mar 2011 **/ /** to 27 feb 2015 **/ /** **/ /************************************************************/ /* ** The defines. */ #ifdef SCOTCH_PTHREAD #define GRAPHCOARSENTHREAD #endif /* SCOTCH_PTHREAD */ /** Prime number for hashing vertex numbers. **/ #define GRAPHCOARSENHASHPRIME 1049 /* Prime number */ /* ** The type and structure definitions. */ /*+ Here are the edge matching function types for coarsening. +*/ typedef enum GraphCoarsenType_ { GRAPHCOARHEM, /*+ Heavy-edge matching +*/ GRAPHCOARSCN, /*+ Scanning (first) matching +*/ GRAPHCOARNBR /*+ Number of matching types +*/ } GraphCoarsenType; /*+ The multinode table element, which contains pairs of based indices of collapsed vertices. Both values are equal for uncollapsed vertices. As the base values of the fine and coarse graphs may be different, the values of the collapsed vertices are set with respect to the base value of the fine graph. +*/ typedef struct GraphCoarsenMulti_ { Gnum vertnum[2]; /*+ Numbers of the collapsed vertices of a multinode +*/ } GraphCoarsenMulti; /*+ A table made of such elements is used during coarsening to build the edge array of the new graph, after the labeling of the vertices. +*/ typedef struct GraphCoarsenHash_ { Gnum vertorgnum; /*+ Origin vertex (i.e. pass) number +*/ Gnum vertendnum; /*+ Other end vertex number +*/ Gnum edgenum; /*+ Number of corresponding edge +*/ } GraphCoarsenHash; /*+ The matching and coarsening routine parameter structure. It contains the thread-independent data. +*/ typedef struct GraphCoarsenData_ { ThreadGroupHeader thrddat; /*+ Thread handling data +*/ const Graph * finegrafptr; /*+ Fine graph to perform matching on +*/ const Anum * fineparotax; /*+ Old part array +*/ const Anum * finepfixtax; /*+ Array of fixed vertices +*/ Gnum finevfixnbr; /*+ Number of fine fixed vertices +*/ Gnum * finematetax; /*+ Fine mate array / fine-to-coarse array +*/ Graph * coargrafptr; /*+ Coarse graph to build +*/ Gnum coarvertmax; /*+ Maximum number of vertices to get +*/ Gnum coarvertnbr; /*+ Global number of coarse vertices after matching +*/ Gnum * coarvfixptr; /*+ Pointer to number of coarse fixed vertices +*/ GraphCoarsenMulti * coarmulttab; /*+ Multinode array +*/ Gnum coarhashmsk; /*+ Hash table mask +*/ #ifdef SCOTCH_PTHREAD int * restrict finelocktax; /*+ Matching lock array (if any) +*/ Gnum * restrict finequeutab; /*+ Matching queue array (if any) +*/ void (* fendptr) (void *); /*+ Pointer to final / sequential match routine +*/ void (* fmidptr) (void *); /*+ Pointer to intermediate match routine (if any) +*/ #endif /* SCOTCH_PTHREAD */ void (* fbegptr) (void *); /*+ Pointer to beginning match routine (if any) +*/ } GraphCoarsenData; /*+ The thread-specific data block. +*/ typedef struct GraphCoarsenThread_ { ThreadHeader thrddat; /*+ Thread management data +*/ Gunum randval; /*+ Per-thread unsigned random value +*/ GraphCoarsenHash * coarhashtab; /*+ End vertex hash table (may be local) +*/ Gnum coarvertnnd; /*+ After-last coarse vertex number +*/ Gnum coarvertbas; /*+ Minimum coarse vertex number; for prefix scan +*/ Gnum coarvertnbr; /*+ Number of coarse vertices to date; TRICK: scan dummy area +*/ Gnum coaredloadj; /*+ (Local) coarse edge load sum adjust +*/ Gnum coardegrmax; /*+ (Local) maximum degree +*/ Gnum coaredgebas; /*+ Minimum coarse edge number; for prefix scan +*/ Gnum finevertbas; /*+ Start of fine vertex range; TRICK: scan dummy area +*/ Gnum finevertnnd; /*+ End of fine vertex range +*/ Gnum finequeubas; /*+ Minimum perturbation or queue index for matching +*/ Gnum finequeunnd; /*+ After-last perturbation or queue index for matching +*/ } GraphCoarsenThread; /* ** The function prototypes. */ #ifndef GRAPH_COARSEN #define static #endif int graphCoarsen (const Graph * restrict const, Graph * restrict const, GraphCoarsenMulti * restrict * const, const Gnum, const double, const Anum * restrict const, const Anum * restrict const, const Gnum, Gnum * restrict const); int graphCoarsenBuild (const Graph * restrict const, Graph * restrict const, GraphCoarsenMulti * restrict * const, const Gnum, Gnum * restrict const); #ifdef GRAPHCOARSENTHREAD static void graphCoarsenEdgeCt (GraphCoarsenThread *); #endif /* GRAPHCOARSENTHREAD */ static void graphCoarsenEdgeLl (GraphCoarsenThread *); static void graphCoarsenEdgeLu (GraphCoarsenThread *); #undef static scotch-6.0.4.dfsg/src/libscotch/hgraph_order_gp.c0000644002563400244210000002750012473143151025135 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2009 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hgraph_order_gp.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module orders a subgraph (most **/ /** likely a separator) using the Gibbs, **/ /** Poole, and Stockmeyer algorithm. **/ /** **/ /** DATES : # Version 3.2 : from : 31 oct 1996 **/ /** to 27 aug 1998 **/ /** # Version 3.3 : from : 02 oct 1998 **/ /** to : 02 oct 1998 **/ /** # Version 4.0 : from : 28 jun 2002 **/ /** to : 01 dec 2003 **/ /** # Version 4.0 : from : 10 sep 2007 **/ /** to : 10 sep 2007 **/ /** # Version 5.1 : from : 01 oct 2009 **/ /** to : 01 oct 2009 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HGRAPH_ORDER_GP #include "module.h" #include "common.h" #include "graph.h" #include "order.h" #include "hgraph.h" #include "hgraph_order_gp.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the ordering. ** It returns: ** - 0 : if the ordering could be computed. ** - !0 : on error. */ int hgraphOrderGp ( const Hgraph * restrict const grafptr, Order * restrict const ordeptr, const Gnum ordenum, OrderCblk * restrict const cblkptr, /*+ Single column-block +*/ const HgraphOrderGpParam * restrict const paraptr) { HgraphOrgerGpQueue queudat; /* Neighbor queue */ HgraphOrderGpVertex * restrict vexxtax; /* Based access to vertex array */ Gnum passnum; /* Pass number */ Gnum rootnum; /* Number of root vertex */ Gnum diamnum; /* Vertex which achieves diameter */ int diamflag; /* Flag set if diameter changed */ Gnum diamdist; /* Maximum diameter value found */ Gnum vertdist; /* DIstance of current vertex */ Gnum vertnum; /* Number of current vertex */ Gnum edgenum; /* Number of current edge */ Gnum ordeval; /* Current ordering value */ Gnum ordevnd; /* End value of ordering */ const Gnum * restrict const verttax = grafptr->s.verttax; const Gnum * restrict const vnumtax = grafptr->s.vnumtax; const Gnum * restrict const vnhdtax = grafptr->vnhdtax; const Gnum * restrict const edgetax = grafptr->s.edgetax; if (memAllocGroup ((void **) (void *) &queudat.qtab, (size_t) (grafptr->vnohnbr * sizeof (Gnum)), &vexxtax, (size_t) (grafptr->vnohnbr * sizeof (HgraphOrderGpVertex)), NULL) == NULL) { errorPrint ("hgraphOrderGp: out of memory"); return (1); } memSet (vexxtax, 0, grafptr->vnohnbr * sizeof (HgraphOrderGpVertex)); /* Initialize pass numbers */ vexxtax -= grafptr->s.baseval; #ifdef SCOTCH_DEBUG_ORDER2 memSet (ordeptr->peritab + ordenum, ~0, grafptr->vnohnbr * sizeof (Gnum)); #endif /* SCOTCH_DEBUG_ORDER2 */ for (ordeval = ordenum, rootnum = grafptr->s.baseval, /* For all connected components */ ordevnd = ordeval + grafptr->vnohnbr; ordeval < ordevnd; ) { while (vexxtax[rootnum].passnum != 0) { /* Find first unallocated root */ rootnum ++; #ifdef SCOTCH_DEBUG_ORDER2 if (rootnum >= grafptr->vnohnnd) { errorPrint ("hgraphOrderGp: internal error (1)"); memFree (queudat.qtab); /* Free group leader */ return (1); } #endif /* SCOTCH_DEBUG_ORDER2 */ } diamnum = rootnum; /* Start from found root */ diamdist = 0; for (diamflag = 0, passnum = 1; /* Loop if modifications */ (diamflag ++ == 0) && (passnum <= paraptr->passnbr); passnum ++) { Gnum diamdegr; /* Degree of current pseudo-peripherial vertex */ hgraphOrderGpQueueFlush (&queudat); /* Flush vertex queue */ hgraphOrderGpQueuePut (&queudat, diamnum); /* Start from diameter vertex */ vexxtax[diamnum].passnum = passnum; /* It has been enqueued */ vexxtax[diamnum].vertdist = 0; /* It is at distance zero */ diamdegr = vnhdtax[diamnum] - verttax[diamnum]; do { /* Loop on vertices in queue */ vertnum = hgraphOrderGpQueueGet (&queudat); /* Get vertex from queue */ #ifdef SCOTCH_DEBUG_ORDER2 if ((vertnum < grafptr->s.baseval) || (vertnum >= grafptr->vnohnnd)) { errorPrint ("hgraphOrderGp: internal error (2)"); memFree (queudat.qtab); /* Free group leader */ return (1); } #endif /* SCOTCH_DEBUG_ORDER2 */ vertdist = vexxtax[vertnum].vertdist; /* Get vertex distance */ if ((vertdist > diamdist) || /* If vertex increases diameter */ ((vertdist == diamdist) && /* Or is at diameter distance */ ((vnhdtax[vertnum] - verttax[vertnum]) < diamdegr))) { /* With smaller degree */ diamnum = vertnum; /* Set it as new diameter vertex */ diamdist = vertdist; diamdegr = vnhdtax[vertnum] - verttax[vertnum]; diamflag = 0; } vertdist ++; /* Set neighbor distance */ for (edgenum = verttax[vertnum]; edgenum < vnhdtax[vertnum]; edgenum ++) { Gnum vertend; vertend = edgetax[edgenum]; #ifdef SCOTCH_DEBUG_ORDER2 if ((vertend < grafptr->s.baseval) || (vertend >= grafptr->vnohnnd)) { errorPrint ("hgraphOrderGp: internal error (3)"); memFree (queudat.qtab); /* Free group leader */ return (1); } #endif /* SCOTCH_DEBUG_ORDER2 */ if (vexxtax[vertend].passnum < passnum) { /* If vertex not queued yet */ hgraphOrderGpQueuePut (&queudat, vertend); /* Enqueue neighbor vertex */ vexxtax[vertend].passnum = passnum; vexxtax[vertend].vertdist = vertdist; } } } while (! hgraphOrderGpQueueEmpty (&queudat)); /* As long as queue is not empty */ } hgraphOrderGpQueueFlush (&queudat); /* Flush vertex queue */ hgraphOrderGpQueuePut (&queudat, diamnum); /* Start from diameter vertex */ vexxtax[diamnum].passnum = passnum; /* Vertex has been enqueued */ do { /* Loop on vertices in queue */ vertnum = hgraphOrderGpQueueGet (&queudat); /* Get vertex from queue */ if (vexxtax[vertnum].passnum > passnum) /* If vertex already ordered (by-level ordering) */ continue; /* Skip to next vertex in queue */ vertdist = vexxtax[vertnum].vertdist; /* Get vertex distance */ do { /* Loop on vertices in layer */ Gnum edgennd; /* End of edge sub-array */ ordeptr->peritab[ordeval ++] = (vnumtax == NULL) ? vertnum : vnumtax[vertnum]; vexxtax[vertnum].passnum = passnum + 1; /* Set vertex as ordered */ for (edgenum = verttax[vertnum], edgennd = vnhdtax[vertnum], vertnum = ~0; edgenum < edgennd; edgenum ++) { /* Need edgennd because vertnum is overwritten */ Gnum vertend; vertend = edgetax[edgenum]; if ((vexxtax[vertend].vertdist == vertdist) && /* If neighbor vertex in same layer */ (vexxtax[vertend].passnum <= passnum)) { /* And not yet ordered */ vertnum = vertend; /* Set neighbor as next vertex */ edgenum ++; /* Process next neighbors, not this one again */ break; /* Process next neighbors without further testing */ } if (vexxtax[vertend].passnum < passnum) { /* Else if vertex not yet enqueued */ hgraphOrderGpQueuePut (&queudat, vertend); /* Enqueue neighbor vertex */ vexxtax[vertend].passnum = passnum; /* Set it as enqueued */ } } for ( ; edgenum < edgennd; edgenum ++) { /* Enqueue remaining neighbors */ Gnum vertend; vertend = edgetax[edgenum]; if (vexxtax[vertend].passnum < passnum) { /* If neighbor not yet enqueued */ hgraphOrderGpQueuePut (&queudat, vertend); /* Enqueue neighbor vertex */ vexxtax[vertend].passnum = passnum; /* Set it as enqueued */ } } } while (vertnum != ~0); } while (! hgraphOrderGpQueueEmpty (&queudat)); /* As long as queue is not empty */ } #ifdef SCOTCH_DEBUG_ORDER2 for (ordeval = ordenum; ordeval < ordenum + grafptr->vnohnbr; ordeval ++) { if (ordeptr->peritab[ordeval] == ~0) { errorPrint ("hgraphOrderGp: internal error (4)"); memFree (queudat.qtab); /* Free group leader */ return (1); } } #endif /* SCOTCH_DEBUG_ORDER2 */ memFree (queudat.qtab); /* Group freeing */ return (0); } scotch-6.0.4.dfsg/src/libscotch/kgraph_map_cp.h0000644002563400244210000000533312376070670024612 0ustar trophimeutilisateurs du domaine/* Copyright 2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph_map_cp.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the mapping method that copy the **/ /** old mapping has a mapping result. **/ /** **/ /** DATES : # Version 6.0 : from : 16 jan 2012 **/ /** to 23 aug 2014 **/ /** **/ /************************************************************/ /* ** The function prototypes. */ #ifndef KGRAPH_MAP_CP #define static #endif int kgraphMapCp (Kgraph * restrict const); #undef static scotch-6.0.4.dfsg/src/libscotch/library_graph_map_f.c0000644002563400244210000003222712053750142025772 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010-2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_map_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module is the Fortran API for the **/ /** mapping routines of the libSCOTCH **/ /** library. **/ /** **/ /** DATES : # Version 3.4 : from : 02 dec 1999 **/ /** to 15 nov 2001 **/ /** # Version 4.0 : from : 12 jan 2004 **/ /** to 12 dec 2005 **/ /** # Version 5.1 : from : 27 mar 2010 **/ /** to 31 aug 2011 **/ /** # Version 6.0 : from : 17 apr 2011 **/ /** to 23 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the mapping routines. */ /* */ /**************************************/ /* ** */ /* TODO update fortran interface... */ FORTRAN ( \ SCOTCHFGRAPHMAPINIT, scotchfgraphmapinit, ( \ const SCOTCH_Graph * const grafptr, \ SCOTCH_Mapping * const mappptr, \ const SCOTCH_Arch * const archptr, \ SCOTCH_Num * const mapptab, \ int * const revaptr), \ (grafptr, mappptr, archptr, mapptab, revaptr)) { *revaptr = SCOTCH_graphMapInit (grafptr, mappptr, archptr, mapptab); } /* ** */ FORTRAN ( \ SCOTCHFGRAPHMAPEXIT, scotchfgraphmapexit, ( \ const SCOTCH_Graph * const grafptr, \ SCOTCH_Mapping * const mappptr), \ (grafptr, mappptr)) { SCOTCH_graphMapExit (grafptr, mappptr); } /* ** */ FORTRAN ( \ SCOTCHFGRAPHMAPCOMPUTE, scotchfgraphmapcompute, ( \ SCOTCH_Graph * const grafptr, \ SCOTCH_Mapping * const mappptr, \ SCOTCH_Strat * const straptr, \ int * const revaptr), \ (grafptr, mappptr, straptr, revaptr)) { *revaptr = SCOTCH_graphMapCompute (grafptr, mappptr, straptr); } /* ** */ FORTRAN ( \ SCOTCHFGRAPHMAPFIXEDCOMPUTE, scotchfgraphmapfixedcompute, ( \ SCOTCH_Graph * const grafptr, \ SCOTCH_Mapping * const mappptr, \ SCOTCH_Strat * const straptr, \ int * const revaptr), \ (grafptr, mappptr, straptr, revaptr)) { *revaptr = SCOTCH_graphMapFixedCompute (grafptr, mappptr, straptr); } /* ** */ FORTRAN ( \ SCOTCHFGRAPHREMAPCOMPUTE, scotchfgraphremapcompute, ( \ SCOTCH_Graph * const grafptr, \ SCOTCH_Mapping * const mappptr, \ SCOTCH_Mapping * const mapoptr, \ const double * const emraptr, \ const SCOTCH_Num * const vmlotab, \ SCOTCH_Strat * const straptr, \ int * const revaptr), \ (grafptr, mappptr, mapoptr, emraptr, vmlotab, straptr, revaptr)) { *revaptr = SCOTCH_graphRemapCompute (grafptr, mappptr, mapoptr, *emraptr, vmlotab, straptr); } /* ** */ FORTRAN ( \ SCOTCHFGRAPHREMAPFIXEDCOMPUTE, scotchfgraphremapfixedcompute, ( \ SCOTCH_Graph * const grafptr, \ SCOTCH_Mapping * const mappptr, \ SCOTCH_Mapping * const mapoptr, \ const double * const emraptr, \ const SCOTCH_Num * const vmlotab, \ SCOTCH_Strat * const straptr, \ int * const revaptr), \ (grafptr, mappptr, mapoptr, emraptr, vmlotab, straptr, revaptr)) { *revaptr = SCOTCH_graphRemapFixedCompute (grafptr, mappptr, mapoptr, *emraptr, vmlotab, straptr); } /* ** */ FORTRAN ( \ SCOTCHFGRAPHMAP, scotchfgraphmap, ( \ SCOTCH_Graph * const grafptr, \ const SCOTCH_Arch * const archptr, \ SCOTCH_Strat * const straptr, \ SCOTCH_Num * const parttab, \ int * const revaptr), \ (grafptr, archptr, straptr, parttab, revaptr)) { *revaptr = SCOTCH_graphMap (grafptr, archptr, straptr, parttab); } /* ** */ FORTRAN ( \ SCOTCHFGRAPHMAPFIXED, scotchfgraphmapfixed, ( \ SCOTCH_Graph * const grafptr, \ const SCOTCH_Arch * const archptr, \ SCOTCH_Strat * const straptr, \ SCOTCH_Num * const parttab, \ int * const revaptr), \ (grafptr, archptr, straptr, parttab, revaptr)) { *revaptr = SCOTCH_graphMapFixed (grafptr, archptr, straptr, parttab); } /* ** */ FORTRAN ( \ SCOTCHFGRAPHREMAP, scotchfgraphremap, ( \ SCOTCH_Graph * const grafptr, \ const SCOTCH_Arch * const archptr, \ SCOTCH_Num * const parotab, \ const double * const emraptr, \ const SCOTCH_Num * const vmlotab, \ SCOTCH_Strat * const straptr, \ SCOTCH_Num * const parttab, \ int * const revaptr), \ (grafptr, archptr, parotab, emraptr, vmlotab, straptr, parttab, revaptr)) { *revaptr = SCOTCH_graphRemap (grafptr, archptr, parotab, *emraptr, vmlotab, straptr, parttab); } /* ** */ FORTRAN ( \ SCOTCHFGRAPHREMAPFIXED, scotchfgraphremapfixed, ( \ SCOTCH_Graph * const grafptr, \ const SCOTCH_Arch * const archptr, \ SCOTCH_Num * const parotab, \ const double * const emraptr, \ const SCOTCH_Num * const vmlotab, \ SCOTCH_Strat * const straptr, \ SCOTCH_Num * const parttab, \ int * const revaptr), \ (grafptr, archptr, parotab, emraptr, vmlotab, straptr, parttab, revaptr)) { *revaptr = SCOTCH_graphRemapFixed (grafptr, archptr, parotab, *emraptr, vmlotab, straptr, parttab); } /* ** */ FORTRAN ( \ SCOTCHFGRAPHPART, scotchfgraphpart, ( \ SCOTCH_Graph * const grafptr, \ const SCOTCH_Num * const partptr, \ SCOTCH_Strat * const straptr, \ SCOTCH_Num * const mapptab, \ int * const revaptr), \ (grafptr, partptr, straptr, mapptab, revaptr)) { *revaptr = SCOTCH_graphPart (grafptr, *partptr, straptr, mapptab); } /* ** */ FORTRAN ( \ SCOTCHFGRAPHPARTFIXED, scotchfgraphpartfixed, ( \ SCOTCH_Graph * const grafptr, \ const SCOTCH_Num * const partptr, \ SCOTCH_Strat * const straptr, \ SCOTCH_Num * const mapptab, \ int * const revaptr), \ (grafptr, partptr, straptr, mapptab, revaptr)) { *revaptr = SCOTCH_graphPartFixed (grafptr, *partptr, straptr, mapptab); } /* ** */ FORTRAN ( \ SCOTCHFGRAPHREPART, scotchfgraphrepart, ( \ SCOTCH_Graph * const grafptr, \ const SCOTCH_Num * const partptr, \ SCOTCH_Num * const parotab, \ const double * const emraptr, \ const SCOTCH_Num * const vmlotab, \ SCOTCH_Strat * const straptr, \ SCOTCH_Num * const mapptab, \ int * const revaptr), \ (grafptr, partptr, parotab, emraptr, vmlotab, straptr, mapptab, revaptr)) { *revaptr = SCOTCH_graphRepart (grafptr, *partptr, parotab, *emraptr, vmlotab, straptr, mapptab); } /* ** */ FORTRAN ( \ SCOTCHFGRAPHREPARTFIXED, scotchfgraphrepartfixed, ( \ SCOTCH_Graph * const grafptr, \ const SCOTCH_Num * const partptr, \ SCOTCH_Num * const parotab, \ const double * const emraptr, \ const SCOTCH_Num * const vmlotab, \ SCOTCH_Strat * const straptr, \ SCOTCH_Num * const mapptab, \ int * const revaptr), \ (grafptr, partptr, parotab, emraptr, vmlotab, straptr, mapptab, revaptr)) { *revaptr = SCOTCH_graphRepartFixed (grafptr, *partptr, parotab, *emraptr, vmlotab, straptr, mapptab); } /* String lengths are passed at the very ** end of the argument list. */ FORTRAN ( \ SCOTCHFSTRATGRAPHMAP, scotchfstratgraphmap, ( \ SCOTCH_Strat * const stratptr, \ const char * const string, \ int * const revaptr, \ const int strnbr), \ (stratptr, string, revaptr, strnbr)) { char * restrict strtab; /* Pointer to null-terminated string */ if ((strtab = (char *) memAlloc (strnbr + 1)) == NULL) { /* Allocate temporary space */ errorPrint ("SCOTCHFSTRATGRAPHMAP: out of memory (1)"); *revaptr = 1; } memCpy (strtab, string, strnbr); /* Copy string contents */ strtab[strnbr] = '\0'; /* Terminate string */ *revaptr = SCOTCH_stratGraphMap (stratptr, strtab); /* Call original routine */ memFree (strtab); } /* ** */ FORTRAN ( \ SCOTCHFSTRATGRAPHMAPBUILD, scotchfstratgraphmapbuild, ( \ SCOTCH_Strat * const stratptr, \ const SCOTCH_Num * const flagval, \ const SCOTCH_Num * const partnbr, \ const double * const kbalptr, \ int * const revaptr), \ (stratptr, flagval, partnbr, kbalptr, revaptr)) { *revaptr = SCOTCH_stratGraphMapBuild (stratptr, *flagval, *partnbr, *kbalptr); } /* ** */ FORTRAN ( \ SCOTCHFSTRATGRAPHCLUSTERBUILD, scotchfstratgraphclusterbuild, ( \ SCOTCH_Strat * const stratptr, \ const SCOTCH_Num * const flagval, \ const SCOTCH_Num * const pwgtval, \ const double * const densval, \ const double * const bbalptr, \ int * const revaptr), \ (stratptr, flagval, pwgtval, densval, bbalptr, revaptr)) { *revaptr = SCOTCH_stratGraphClusterBuild (stratptr, *flagval, *pwgtval, *densval, *bbalptr); } scotch-6.0.4.dfsg/src/libscotch/hmesh_order_hx.h0000644002563400244210000000645211631447170025014 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh_order_hx.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the halo mesh block Approxi- **/ /** mate (Multiple) Minimum Degree and Fill **/ /** ordering routines. **/ /** **/ /** DATES : # Version 4.0 : from : 09 dec 2003 **/ /** to 09 dec 2003 **/ /** **/ /************************************************************/ /* ** The defines. */ #define HMESHORDERHXHASHPRIME 17 /* Prime number */ /* ** The type and structure definitions. */ /*+ A table made of such elements is used to compute the external degree of non-halo vertices. +*/ typedef struct HmeshOrderHxHash_ { Gnum vertnum; /*+ Origin vertex (i.e. pass) number +*/ Gnum vertend; /*+ End vertex number in mesh +*/ } HmeshOrderHxHash; /* ** The function prototypes. */ #ifndef HMESH_ORDER_HX #define static #endif int hmeshOrderHxFill (const Hmesh * restrict const, Gnum * restrict const, Gnum * restrict const, Gnum * restrict const, Gnum * restrict const, Gnum * restrict const); #undef static scotch-6.0.4.dfsg/src/libscotch/vdgraph_separate_zr.c0000644002563400244210000000632511631447170026042 0ustar trophimeutilisateurs du domaine/* Copyright 2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vdgraph_separate_zr.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module moves all of the vertices **/ /** of the distributed separator graph to **/ /** the first subdomain. **/ /** **/ /** DATES : # Version 5.0 : from : 07 feb 2006 **/ /** to 07 feb 2006 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VDGRAPH_SEPARATE_ZR #include "module.h" #include "common.h" #include "dgraph.h" #include "vdgraph.h" #include "vdgraph_separate_zr.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine moves all of the graph vertices ** to the first part of the partition. ** It returns: ** - 0 : if the bipartitioning could be computed. ** - !0 : on error. */ int vdgraphSeparateZr ( Vdgraph * const grafptr) /*+ Active graph +*/ { if (grafptr->compglbload[0] != grafptr->s.veloglbsum) /* If not all vertices already in part zero */ vdgraphZero (grafptr); return (0); } scotch-6.0.4.dfsg/src/libscotch/library_dgraph_map_f.c0000644002563400244210000002107012055776741026147 0ustar trophimeutilisateurs du domaine/* Copyright 2008,2010-2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_map_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the Fortran API for the **/ /** parallel mapping routines of the **/ /** libSCOTCH library. **/ /** **/ /** DATES : # Version 5.1 : from : 28 jun 2008 **/ /** to 31 aug 2011 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "ptscotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the parallel mapping routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFDGRAPHMAPINIT, scotchfdgraphmapinit, ( \ const SCOTCH_Dgraph * const grafptr, \ SCOTCH_Dmapping * const mapptr, \ const SCOTCH_Arch * const archptr, \ SCOTCH_Num * const termloctab, \ int * const revaptr), \ (grafptr, mapptr, archptr, termloctab, revaptr)) { *revaptr = SCOTCH_dgraphMapInit (grafptr, mapptr, archptr, termloctab); } /* ** */ FORTRAN ( \ SCOTCHFDGRAPHMAPEXIT, scotchfdgraphmapexit, ( \ const SCOTCH_Dgraph * const grafptr, \ SCOTCH_Dmapping * const mapptr), \ (grafptr, mapptr)) { SCOTCH_dgraphMapExit (grafptr, mapptr); } /* ** */ FORTRAN ( \ SCOTCHFDGRAPHMAPSAVE, scotchfdgraphmapsave, ( \ const SCOTCH_Dgraph * const grafptr, \ SCOTCH_Dmapping * const mapptr, \ int * const fileptr, \ int * const revaptr), \ (grafptr, mapptr, fileptr, revaptr)) { FILE * stream; /* Stream to build from handle */ int filenum; /* Duplicated handle */ int o; if ((filenum = dup (*fileptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFDGRAPHMAPSAVE: cannot duplicate handle"); *revaptr = 1; /* Indicate error */ return; } if ((stream = fdopen (filenum, "w")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFDGRAPHMAPSAVE: cannot open output stream"); close (filenum); *revaptr = 1; return; } o = SCOTCH_dgraphMapSave (grafptr, mapptr, stream); fclose (stream); /* This closes filenum too */ *revaptr = o; } /* ** */ FORTRAN ( \ SCOTCHFDGRAPHMAPCOMPUTE, scotchfdgraphmapcompute, ( \ SCOTCH_Dgraph * const grafptr, \ SCOTCH_Dmapping * const mapptr, \ SCOTCH_Strat * const stratptr, \ int * const revaptr), \ (grafptr, mapptr, stratptr, revaptr)) { *revaptr = SCOTCH_dgraphMapCompute (grafptr, mapptr, stratptr); } /* ** */ FORTRAN ( \ SCOTCHFDGRAPHMAP, scotchfdgraphmap, ( \ SCOTCH_Dgraph * const grafptr, \ const SCOTCH_Arch * const archptr, \ SCOTCH_Strat * const stratptr, \ SCOTCH_Num * const termloctab, \ int * const revaptr), \ (grafptr, archptr, stratptr, termloctab, revaptr)) { *revaptr = SCOTCH_dgraphMap (grafptr, archptr, stratptr, termloctab); } /* ** */ FORTRAN ( \ SCOTCHFDGRAPHPART, scotchfdgraphpart, ( \ SCOTCH_Dgraph * const grafptr, \ const SCOTCH_Num * const partptr, \ SCOTCH_Strat * const stratptr, \ SCOTCH_Num * const termloctab, \ int * const revaptr), \ (grafptr, partptr, stratptr, termloctab, revaptr)) { *revaptr = SCOTCH_dgraphPart (grafptr, *partptr, stratptr, termloctab); } /* String lengths are passed at the very ** end of the argument list. */ FORTRAN ( \ SCOTCHFSTRATDGRAPHMAP, scotchfstratdgraphmap, ( \ SCOTCH_Strat * const stratptr, \ const char * const string, \ int * const revaptr, \ const int strnbr), \ (stratptr, string, revaptr, strnbr)) { char * restrict strtab; /* Pointer to null-terminated string */ if ((strtab = (char *) memAlloc (strnbr + 1)) == NULL) { /* Allocate temporary space */ errorPrint ("SCOTCHFSTRATDGRAPHMAP: out of memory (1)"); *revaptr = 1; } memCpy (strtab, string, strnbr); /* Copy string contents */ strtab[strnbr] = '\0'; /* Terminate string */ *revaptr = SCOTCH_stratDgraphMap (stratptr, strtab); /* Call original routine */ memFree (strtab); } /* ** */ FORTRAN ( \ SCOTCHFSTRATDGRAPHMAPBUILD, scotchfstratdgraphmapbuild, ( \ SCOTCH_Strat * const stratptr, \ const SCOTCH_Num * const flagval, \ const SCOTCH_Num * const procnbr, \ const SCOTCH_Num * const partnbr, \ const double * const kbalval, \ int * const revaptr), \ (stratptr, flagval, procnbr, partnbr, kbalval, revaptr)) { *revaptr = SCOTCH_stratDgraphMapBuild (stratptr, *flagval, *procnbr, *partnbr, *kbalval); } /* ** */ FORTRAN ( \ SCOTCHFSTRATDGRAPHCLUSTERBUILD, scotchfstratdgraphclusterbuild, ( \ SCOTCH_Strat * const stratptr, \ const SCOTCH_Num * const flagval, \ const SCOTCH_Num * const procnbr, \ const SCOTCH_Num * const pwgtval, \ const double * const densval, \ const double * const bbalval, \ int * const revaptr), \ (stratptr, flagval, procnbr, pwgtval, densval, bbalval, revaptr)) { *revaptr = SCOTCH_stratDgraphClusterBuild (stratptr, *flagval, *procnbr, *pwgtval, *densval, *bbalval); } scotch-6.0.4.dfsg/src/libscotch/bdgraph_bipart_sq.c0000644002563400244210000003044312400674231025454 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2010,2011,2013,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bdgraph_bipart_sq.c **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module computes a bipartition of a **/ /** given bipartitioned distributed graph **/ /** by moving all (interesting) vertices of **/ /** the given graph to every processor, **/ /** executing a sequential bipartition **/ /** routine, and projecting back the best **/ /** result obtained. **/ /** **/ /** DATES : # Version 5.1 : from : 27 dec 2007 **/ /** to 14 apr 2011 **/ /** # Version 6.0 : from : 27 dec 2007 **/ /** to 31 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define BDGRAPH_BIPART_SQ #include "module.h" #include "common.h" #include "comm.h" #include "arch.h" #include "parser.h" #include "graph.h" #include "bgraph.h" #include "bgraph_bipart_st.h" #include "dgraph.h" #include "bdgraph.h" #include "bdgraph_bipart_sq.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine is the reduction-loc operator which ** returns in inout[2] the rank of the process which ** holds the best partition. ** It returns: ** - void : in all cases. */ static void bdgraphBipartSqOpBest ( const Gnum * const in, /* First operand */ Gnum * const inout, /* Second and output operand */ const int * const len, /* Number of instances; should be 1, not used */ const MPI_Datatype * const typedat) /* MPI datatype; not used */ { inout[5] |= in[5]; /* Propagate errors */ inout[4] += in[4]; /* Count cases for which a bipartitioning error occured */ if (inout[3] == 1) { /* Handle cases when at least one of them is erroneous */ if (in[3] == 1) return; inout[0] = in[0]; inout[1] = in[1]; inout[2] = in[2]; inout[3] = in[3]; return; } else if (in[3] == 1) return; if ((in[0] < inout[0]) || /* Select best partition */ ((in[0] == inout[0]) && ((in[1] < inout[1]) || ((in[1] == inout[1]) && (in[2] < inout[2]))))) { inout[0] = in[0]; inout[1] = in[1]; inout[2] = in[2]; } } /* This routine computes a partition of the ** given distributed graph by gathering as many ** copies of the graph as there are processes ** sharing the distributed graph, running a ** sequential algorithm on them, and collecting ** the best solution found. ** It returns: ** - 0 : if the bipartition could be computed. ** - !0 : on error. */ int bdgraphBipartSq ( Bdgraph * const dgrfptr, /*+ Distributed graph +*/ const BdgraphBipartSqParam * const paraptr) /*+ Method parameters +*/ { Bgraph cgrfdat; /* Centralized bipartitioned graph structure */ Gnum reduloctab[6]; /* Local array for best bipartition data (7 for Bcast) */ Gnum reduglbtab[6]; /* Global array for best bipartition data */ MPI_Datatype besttypedat; /* Data type for finding best bipartition */ MPI_Op bestoperdat; /* Handle of MPI operator for finding best bipartition */ int bestprocnum; /* Rank of process holding best partition */ Gnum * restrict vnumloctax; Gnum vertlocnum; Gnum complocsize1; Gnum complocload1; Gnum fronlocnbr; int o; if ((MPI_Type_contiguous (6, GNUM_MPI, &besttypedat) != MPI_SUCCESS) || (MPI_Type_commit (&besttypedat) != MPI_SUCCESS) || (MPI_Op_create ((MPI_User_function *) bdgraphBipartSqOpBest, 1, &bestoperdat) != MPI_SUCCESS)) { errorPrint ("bdgraphBipartSq: communication error (1)"); return (1); } reduloctab[0] = /* In case of error, maximum communication load */ reduloctab[1] = GNUMMAX; /* And maximum load imbalance */ reduloctab[2] = dgrfptr->s.proclocnum; reduloctab[3] = /* Assume sequential bipartioning went fine */ reduloctab[4] = 0; reduloctab[5] = 0; /* Assume no errors */ vnumloctax = dgrfptr->s.vnumloctax; /* No need for vertex number array when centralizing graph */ dgrfptr->s.vnumloctax = NULL; o = bdgraphGatherAll (dgrfptr, &cgrfdat); dgrfptr->s.vnumloctax = vnumloctax; /* Restore vertex number array */ if (o != 0) { errorPrint ("bdgraphBipartSq: cannot build centralized graph"); return (1); } if (bgraphBipartSt (&cgrfdat, paraptr->strat) != 0) { /* Bipartition centralized graph */ errorPrint ("bdgraphBipartSq: cannot bipartition centralized graph"); reduloctab[3] = reduloctab[4] = 1; } else { /* Fill local array with local bipartition data */ reduloctab[0] = ((cgrfdat.fronnbr != 0) || ((cgrfdat.compsize0 != 0) && ((cgrfdat.s.vertnbr - cgrfdat.compsize0) != 0))) ? cgrfdat.commload : GNUMMAX; /* Partitions with empty bipartitions unwanted if they are completely unbalanced */ reduloctab[1] = cgrfdat.compload0dlt; } if (dgrfptr->partgsttax == NULL) { if (dgraphGhst (&dgrfptr->s) != 0) { /* Compute ghost edge array if not already present, before copying graph fields */ errorPrint ("bdgraphBipartSq: cannot compute ghost edge array"); reduloctab[5] = 1; } else { if ((dgrfptr->partgsttax = (GraphPart *) memAlloc (dgrfptr->s.vertgstnbr * sizeof (GraphPart))) == NULL) { errorPrint ("bdgraphBipartSq: out of memory (1)"); reduloctab[5] = 1; /* Allocated data will be freed along with graph structure */ } dgrfptr->partgsttax -= dgrfptr->s.baseval; } if ((dgrfptr->fronloctab = (Gnum *) memAlloc (dgrfptr->s.vertlocnbr * sizeof (Gnum))) == NULL) { errorPrint ("bdgraphBipartSq: out of memory (2)"); reduloctab[5] = 1; } } if (MPI_Allreduce (reduloctab, reduglbtab, 1, besttypedat, bestoperdat, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphBipartSq: communication error (2)"); return (1); } if ((reduloctab[4] != 0) && (reduloctab[4] != dgrfptr->s.procglbnbr)) { errorPrint ("bdgraphBipartSq: internal error"); return (1); } if ((MPI_Op_free (&bestoperdat) != MPI_SUCCESS) || (MPI_Type_free (&besttypedat) != MPI_SUCCESS)) { errorPrint ("bdgraphBipartSq: communication error (3)"); return (1); } if (reduglbtab[3] != 0) { /* If none of the sequential methods succeeded */ bgraphExit (&cgrfdat); return (1); } bestprocnum = (int) reduglbtab[2]; if (dgrfptr->s.proclocnum == bestprocnum) { /* If process holds best partition */ reduloctab[0] = cgrfdat.compload0; /* Global values to share */ reduloctab[1] = cgrfdat.compsize0; reduloctab[2] = cgrfdat.commload; reduloctab[3] = cgrfdat.commgainextn; reduloctab[4] = cgrfdat.fronnbr; } if (MPI_Bcast (reduloctab, 5, GNUM_MPI, bestprocnum, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphBipartSq: communication error (4)"); return (1); } dgrfptr->compglbload0 = reduloctab[0]; dgrfptr->compglbload0dlt = reduloctab[0] - dgrfptr->compglbload0avg; dgrfptr->compglbsize0 = reduloctab[1]; dgrfptr->commglbload = reduloctab[2]; dgrfptr->commglbgainextn = reduloctab[3]; dgrfptr->fronglbnbr = reduloctab[4]; if (commScatterv (cgrfdat.parttax, dgrfptr->s.proccnttab, dgrfptr->s.procdsptab, GRAPHPART_MPI, /* No base for sending as procdsptab holds based values */ dgrfptr->partgsttax + dgrfptr->s.baseval, dgrfptr->s.vertlocnbr, GRAPHPART_MPI, bestprocnum, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphBipartSq: communication error (5)"); return (1); } if (dgraphHaloSync (&dgrfptr->s, (byte *) (dgrfptr->partgsttax + dgrfptr->s.baseval), GRAPHPART_MPI) != 0) { errorPrint ("bdgraphBipartSq: cannot perform halo exchange"); return (1); } complocsize1 = complocload1 = 0; for (vertlocnum = dgrfptr->s.baseval, fronlocnbr = 0; vertlocnum < dgrfptr->s.vertlocnnd; vertlocnum ++) { int partval; Gnum partval1; Gnum commcut; Gnum edgelocnum; partval = dgrfptr->partgsttax[vertlocnum]; partval1 = partval & 1; complocsize1 += partval1; /* Superscalar update */ if (dgrfptr->s.veloloctax != NULL) { Gnum veloval; veloval = dgrfptr->s.veloloctax[vertlocnum]; complocload1 += (-partval1) & veloval; /* Superscalar update */ } for (edgelocnum = dgrfptr->s.vertloctax[vertlocnum], commcut = 0; edgelocnum < dgrfptr->s.vendloctax[vertlocnum]; edgelocnum ++) { /* Build local frontier */ int partend; int partdlt; partend = dgrfptr->partgsttax[dgrfptr->s.edgegsttax[edgelocnum]]; partdlt = partval ^ partend; commcut |= partdlt; } if (commcut != 0) dgrfptr->fronloctab[fronlocnbr ++] = vertlocnum; } dgrfptr->fronlocnbr = fronlocnbr; dgrfptr->complocsize0 = dgrfptr->s.vertlocnbr - complocsize1; dgrfptr->complocload0 = (dgrfptr->s.veloloctax != NULL) ? (dgrfptr->s.velolocsum - complocload1) : dgrfptr->complocsize0; bgraphExit (&cgrfdat); #ifdef SCOTCH_DEBUG_BDGRAPH2 if (bdgraphCheck (dgrfptr) != 0) { errorPrint ("bdgraphBipartSq: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_BDGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/library_dgraph_order_f.c0000644002563400244210000001754112055777221026507 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_order_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the Fortran API for the **/ /** distributed graph ordering routines of **/ /** the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 16 feb 2007 **/ /** to 31 may 2008 **/ /** # Version 5.1 : from : 27 mar 2010 **/ /** to 25 jul 2010 **/ /** # Version 6.0 : from : 08 jan 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "ptscotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the ordering routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFDGRAPHORDERINIT, scotchfdgraphorderinit, ( \ const SCOTCH_Dgraph * const grafptr, \ SCOTCH_Dordering * const ordeptr, \ int * const revaptr), \ (grafptr, ordeptr, revaptr)) { *revaptr = SCOTCH_dgraphOrderInit (grafptr, ordeptr); } /* ** */ FORTRAN ( \ SCOTCHFDGRAPHORDEREXIT, scotchfdgraphorderexit, ( \ const SCOTCH_Dgraph * const grafptr, \ SCOTCH_Dordering * const ordeptr), \ (grafptr, ordeptr)) { SCOTCH_dgraphOrderExit (grafptr, ordeptr); } /* ** */ FORTRAN ( \ SCOTCHFDGRAPHORDERSAVE, scotchfdgraphordersave, ( \ const SCOTCH_Dgraph * const grafptr, \ const SCOTCH_Dordering * const ordeptr, \ int * const fileptr, \ int * const revaptr), \ (grafptr, ordeptr, fileptr, revaptr)) { FILE * stream; /* Stream to build from handle */ int filenum; /* Duplicated handle */ int o; if (*fileptr == -1) /* If process is not the root */ stream = NULL; else { /* Open stream for root process */ if ((filenum = dup (*fileptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFDGRAPHORDERSAVE: cannot duplicate handle"); *revaptr = 1; /* Indicate error */ return; } if ((stream = fdopen (filenum, "w")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFDGRAPHORDERSAVE: cannot open output stream"); close (filenum); *revaptr = 1; return; } } o = SCOTCH_dgraphOrderSave (grafptr, ordeptr, stream); if (stream != NULL) fclose (stream); /* This closes filenum too */ *revaptr = o; } /* ** */ FORTRAN ( \ SCOTCHFDGRAPHORDERCOMPUTE, scotchfdgraphordercompute, ( \ SCOTCH_Dgraph * const grafptr, \ SCOTCH_Dordering * const ordeptr, \ SCOTCH_Strat * const stratptr, \ int * const revaptr), \ (grafptr, ordeptr, stratptr, revaptr)) { *revaptr = SCOTCH_dgraphOrderCompute (grafptr, ordeptr, stratptr); } /* ** */ FORTRAN ( \ SCOTCHFDGRAPHORDERCOMPUTELIST, scotchfdgraphordercomputelist, ( \ SCOTCH_Dgraph * const grafptr, \ SCOTCH_Dordering * const ordeptr, \ const SCOTCH_Num * listptr, \ const SCOTCH_Num * const listtab, \ SCOTCH_Strat * const stratptr, \ int * const revaptr), \ (grafptr, ordeptr, listptr, listtab, stratptr, revaptr)) { *revaptr = SCOTCH_dgraphOrderComputeList (grafptr, ordeptr, *listptr, listtab, stratptr); } /* ** */ FORTRAN ( \ SCOTCHFSTRATDGRAPHORDER, scotchfstratdgraphorder, ( \ SCOTCH_Strat * const stratptr, \ const char * const string, \ int * const revaptr, \ const int strnbr), \ (stratptr, string, revaptr, strnbr)) { char * restrict strtab; /* Pointer to null-terminated string */ if ((strtab = (char *) memAlloc (strnbr + 1)) == NULL) { /* Allocate temporary space */ errorPrint ("SCOTCHFSTRATDGRAPHORDER: out of memory (1)"); *revaptr = 1; } memCpy (strtab, string, strnbr); /* Copy string contents */ strtab[strnbr] = '\0'; /* Terminate string */ *revaptr = SCOTCH_stratDgraphOrder (stratptr, strtab); /* Call original routine */ memFree (strtab); /* Prevent compiler warnings */ } /* ** */ FORTRAN ( \ SCOTCHFSTRATDGRAPHORDERBUILD, scotchfstratdgraphorderbuild, ( \ SCOTCH_Strat * const stratptr, \ const SCOTCH_Num * const flagval, \ const SCOTCH_Num * const procnbr, \ const SCOTCH_Num * const levlnbr, \ const double * const balrat, \ int * const revaptr), \ (stratptr, flagval, procnbr, levlnbr, balrat, revaptr)) { *revaptr = SCOTCH_stratDgraphOrderBuild (stratptr, *flagval, *procnbr, *levlnbr, *balrat); } scotch-6.0.4.dfsg/src/libscotch/vgraph_separate_gg.c0000644002563400244210000003432011713201314025621 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vgraph_separate_gg.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module separates an active **/ /** graph using a vertex-oriented version **/ /** of the Greedy Graph Growing algorithm. **/ /** **/ /** DATES : # Version 3.2 : from : 10 nov 1997 **/ /** to 15 jul 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 4.0 : from : 19 dec 2001 **/ /** to 22 jan 2004 **/ /** # Version 5.0 : from : 02 jan 2007 **/ /** to 24 mar 2008 **/ /** # Version 5.1 : from : 09 nov 2008 **/ /** to 09 nov 2008 **/ /** # Version 6.0 : from : 04 feb 2012 **/ /** to 04 feb 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VGRAPH_SEPARATE_GG #include "module.h" #include "common.h" #include "gain.h" #include "graph.h" #include "vgraph.h" #include "vgraph_separate_gg.h" /* ** The static variables. */ static const Gnum vgraphseparateggloadone = 1; /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the bipartitioning. ** It returns: ** - 0 : if the bipartitioning could be computed. ** - !0 : on error. */ int vgraphSeparateGg ( Vgraph * restrict const grafptr, /*+ Separation graph +*/ const VgraphSeparateGgParam * const paraptr) /*+ Method parameters +*/ { GainTabl * restrict tablptr; /* Pointer to gain table */ VgraphSeparateGgVertex * restrict vexxtax; /* Complementary vertex array */ Gnum vertnum; /* Index of current vertex */ Gnum * restrict permtab; /* Table for finding new roots */ Gnum permnum; /* Current permutation index */ Gnum fronnum; INT passnum; const Gnum * restrict velobax; /* Data for handling optional arrays */ Gnum velomsk; /* Mask for handling optional arrays */ Gnum comploaddlt; Gnum compload2; Gnum compsize1; Gnum compsize2; const Gnum * restrict const verttax = grafptr->s.verttax; const Gnum * restrict const vendtax = grafptr->s.vendtax; const Gnum * restrict const velotax = grafptr->s.velotax; const Gnum * restrict const edgetax = grafptr->s.edgetax; const Gnum * restrict const edlotax = grafptr->s.edlotax; GraphPart * restrict const parttax = grafptr->parttax; Gnum * restrict const frontab = grafptr->frontab; if (((tablptr = gainTablInit (GAIN_LINMAX, VGRAPHSEPAGGSUBBITS)) == NULL) || /* Use logarithmic array only */ ((vexxtax = (VgraphSeparateGgVertex *) memAlloc (grafptr->s.vertnbr * sizeof (VgraphSeparateGgVertex))) == NULL)) { errorPrint ("vgraphSeparateGg: out of memory (1)"); if (tablptr != NULL) gainTablExit (tablptr); return (1); } vexxtax -= grafptr->s.baseval; /* Base access to vexxtax */ permtab = NULL; /* Do not allocate permutation array yet */ if (grafptr->s.velotax == NULL) { /* Set accesses to optional arrays */ velobax = &vgraphseparateggloadone; /* In case vertices not weighted (least often) */ velomsk = 0; } else { velobax = grafptr->s.velotax; velomsk = ~((Gnum) 0); } for (passnum = 0; passnum < paraptr->passnbr; passnum ++) { /* For all passes */ VgraphSeparateGgVertex * vexxptr; /* Pointer to current vertex to swap */ memSet (vexxtax + grafptr->s.baseval, 0, grafptr->s.vertnbr * sizeof (VgraphSeparateGgVertex)); /* All vertices to part 0 */ gainTablFree (tablptr); /* Reset gain table */ permnum = 0; /* No permutation built yet */ comploaddlt = grafptr->s.velosum; /* Reset separation parameters */ compload2 = 0; vexxptr = vexxtax + (grafptr->s.baseval + intRandVal (grafptr->s.vertnbr)); /* Randomly select first root vertex */ do { /* Loop on root vertices */ Gnum vertnum; /* Number of current vertex */ Gnum veloval; /* Load of selected vertex */ Gnum compgain2; vexxptr->gainlink.next = /* TRICK: allow deletion of root vertex */ vexxptr->gainlink.prev = (GainLink *) vexxptr; #ifdef SCOTCH_DEBUG_GAIN2 vexxptr->gainlink.tabl = NULL; #endif /* SCOTCH_DEBUG_GAIN2 */ vertnum = vexxptr - vexxtax; /* Get root vertex based number */ if (velomsk == 0) { /* If vertices are not weighted */ veloval = 1; compgain2 = vendtax[vertnum] - verttax[vertnum] - 1; } else { /* Graph vertices are weighted */ Gnum edgenum; veloval = velobax[vertnum]; compgain2 = - veloval; for (edgenum = verttax[vertnum]; edgenum < vendtax[vertnum]; edgenum ++) compgain2 += velobax[edgetax[edgenum]]; } vexxptr->compgain2 = compgain2; /* Set root gain (root not in separator) */ comploaddlt -= veloval; /* Move vertex from part 0 to separator */ compload2 += veloval; do { /* While vertices can be retrieved */ VgraphSeparateGgVertex * sepaptr; /* List of vertices in separator */ Gnum veloval; /* Load of selected vertex */ Gnum edgenum; vertnum = vexxptr - vexxtax; /* Get number of selected vertex */ veloval = velobax[vertnum & velomsk]; if (comploaddlt < abs (comploaddlt - veloval)) { /* If swapping would cause imbalance */ permnum = grafptr->s.vertnbr; /* Terminate swapping process */ vexxptr = NULL; break; } gainTablDel (tablptr, (GainLink *) vexxptr); /* Remove vertex from table */ vexxptr->gainlink.next = VGRAPHSEPAGGSTATEPART1; /* Put vertex in part 1 */ compload2 += vexxptr->compgain2; /* Update partition parameters */ comploaddlt -= vexxptr->compgain2 + 2 * veloval; sepaptr = NULL; /* No separator vertices to relink yet */ for (edgenum = verttax[vertnum]; /* (Re-)link neighbor vertices */ edgenum < vendtax[vertnum]; edgenum ++) { Gnum vertend; VgraphSeparateGgVertex * vexxend; vertend = edgetax[edgenum]; /* Point to end vertex */ vexxend = vexxtax + vertend; if (vexxend->gainlink.next == VGRAPHSEPAGGSTATEPART0) { /* If end in part 0 */ Gnum veloend; Gnum edgtnum; Gnum compgain2; vexxend->gainlink.next = VGRAPHSEPAGGSTATEPART2; /* Move vertex to separator */ vexxend->gainlink.prev = (GainLink *) sepaptr; /* Chain vertex */ sepaptr = vexxend; veloend = velobax[vertend & velomsk]; compgain2 = - veloend; for (edgtnum = verttax[vertend]; edgtnum < vendtax[vertend]; edgtnum ++) { Gnum vertent; VgraphSeparateGgVertex * vexxent; vertent = edgetax[edgtnum]; /* Point to end vertex */ vexxent = vexxtax + vertent; if (vexxent->gainlink.next == VGRAPHSEPAGGSTATEPART0) compgain2 += velobax[vertent & velomsk]; else if (vexxent->gainlink.next >= VGRAPHSEPAGGSTATEPART2) { vexxent->compgain2 -= veloend; if (vexxent->gainlink.next >= VGRAPHSEPAGGSTATELINK) { gainTablDel (tablptr, (GainLink *) vexxent); /* Unlink vertex */ vexxent->gainlink.next = VGRAPHSEPAGGSTATEPART2; /* Chain vertex */ vexxent->gainlink.prev = (GainLink *) sepaptr; sepaptr = vexxent; } } } vexxend->compgain2 = compgain2; } } while (sepaptr != NULL) { /* For all vertices in chain list */ vexxptr = sepaptr; /* Unlink vertex from list */ sepaptr = (VgraphSeparateGgVertex *) vexxptr->gainlink.prev; gainTablAdd (tablptr, (GainLink *) vexxptr, vexxptr->compgain2); /* Relink it */ } } while ((vexxptr = (VgraphSeparateGgVertex *) gainTablFrst (tablptr)) != NULL); if (permnum == 0) { /* If permutation has not been built yet */ if (permtab == NULL) { /* If permutation array not allocated yet */ if ((permtab = (Gnum *) memAlloc (grafptr->s.vertnbr * sizeof (Gnum))) == NULL) { errorPrint ("vgraphSeparateGg: out of memory (2)"); memFree (vexxtax + grafptr->s.baseval); gainTablExit (tablptr); return (1); } intAscn (permtab, grafptr->s.vertnbr, grafptr->s.baseval); /* Initialize based permutation array */ } intPerm (permtab, grafptr->s.vertnbr); /* Build random permutation */ } for ( ; permnum < grafptr->s.vertnbr; permnum ++) { /* Find next root vertex */ if (vexxtax[permtab[permnum]].gainlink.next == VGRAPHSEPAGGSTATEPART0) { vexxptr = vexxtax + permtab[permnum ++]; break; } } } while (vexxptr != NULL); if ((passnum == 0) || /* If first try */ ( (grafptr->compload[2] > compload2) || /* Or if better solution reached */ ((grafptr->compload[2] == compload2) && (abs (grafptr->comploaddlt) > abs (comploaddlt))))) { Gnum vertnum; grafptr->comploaddlt = comploaddlt; /* Set graph parameters */ grafptr->compload[2] = compload2; for (vertnum = grafptr->s.baseval; vertnum < grafptr->s.vertnnd; vertnum ++) /* Copy bipartition state */ parttax[vertnum] = (vexxtax[vertnum].gainlink.next <= VGRAPHSEPAGGSTATEPART2) ? (GraphPart) (intptr_t) vexxtax[vertnum].gainlink.next : (GraphPart) 2; } } if (permtab != NULL) /* Free work arrays */ memFree (permtab); memFree (vexxtax + grafptr->s.baseval); gainTablExit (tablptr); grafptr->compload[0] = (grafptr->s.velosum + grafptr->comploaddlt - grafptr->compload[2]) / 2; grafptr->compload[1] = grafptr->s.velosum - grafptr->compload[2] - grafptr->compload[0]; compsize1 = compsize2 = 0; for (vertnum = grafptr->s.baseval, fronnum = 0; vertnum < grafptr->s.vertnnd; vertnum ++) { Gnum partval; partval = (Gnum) parttax[vertnum]; compsize1 += (partval & 1); /* Superscalar update */ compsize2 += (partval >> 1); if (partval == 2) /* If vertex belongs to frontier */ frontab[fronnum ++] = vertnum; /* Record it in frontier array */ } grafptr->compsize[0] = grafptr->s.vertnbr - compsize1 - compsize2; grafptr->compsize[1] = compsize1; grafptr->fronnbr = compsize2; #ifdef SCOTCH_DEBUG_VGRAPH2 if (vgraphCheck (grafptr) != 0) { errorPrint ("vgraphSeparateGg: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/dgraph_check.c0000644002563400244210000005776012275671712024431 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2010,2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_check.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** Francois CHATENET (P0.0) **/ /** Sebastien FOUCAULT (P0.0) **/ /** Nicolas GICQUEL (P0.1) **/ /** Jerome LACOSTE (P0.1) **/ /** Cedric CHEVALIER (v5.0) **/ /** **/ /** FUNCTION : Part of a parallel static mapper. **/ /** This module contains the distributed **/ /** graph consistency checking routine. **/ /** **/ /** # Version P0.0 : from : 01 apr 1997 **/ /** to 20 jun 1997 **/ /** # Version P0.1 : from : 14 apr 1998 **/ /** to 20 jun 1998 **/ /** # Version P0.2 : from : 11 may 1999 **/ /** to 02 feb 2000 **/ /** # Version 5.0 : from : 04 jul 2005 **/ /** to : 10 sep 2007 **/ /** # Version 5.1 : from : 20 nov 2008 **/ /** to : 30 jul 2010 **/ /** # Version 6.0 : from : 29 sep 2012 **/ /** to : 09 feb 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DGRAPH_CHECK #include "module.h" #include "common.h" #include "dgraph.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This function checks the consistency ** of the given distributed graph. ** It returns: ** - 0 : if graph data are consistent. ** - !0 : on error. */ int dgraphCheck ( const Dgraph * restrict const grafptr) { MPI_Comm proccomm; /* Graph communicator */ int procglbnbr; /* Number of processes sharing graph data */ int proclocnum; /* Number of this process */ int procrcvnum; /* Number of process from which to receive */ int procsndnum; /* Number of process to which to send */ int procngbsel; /* Value of the currently used neighbor buffers */ int procngbnum; /* Number of current neighbor process */ Gnum * procngbtab; /* Array of neighbor vertex ranges */ int procnum; Gnum vertlocnum; Gnum vertngbmin; /* Smallest vertex number of neighbor process */ Gnum vertngbmax; /* Largest vertex number of neighbor process */ int vertngbnbr[2]; /* Size of the neighbor vertex arrays */ Gnum * restrict vertngbtab[2]; /* Array of two neighbor vertex arrays */ Gnum * restrict vertngbptr; /* Pointer to working neighbor vertex array */ Gnum * restrict vendngbtab[2]; /* Array of two neighbor end vertex arrays */ Gnum * restrict vendngbptr; /* Pointer to working neighbor end vertex array */ Gnum edgelocnbr; /* Local number of edges */ int edgengbnbr[2]; /* Size of the neighbor vertex arrays */ Gnum * restrict edgengbtab[2]; /* Array of two neighbor edge arrays */ Gnum * restrict edgengbptr; /* Pointer to working neighbor edge array */ Gnum * restrict edlongbtab[2]; /* Array of two neighbor edge load arrays */ Gnum * restrict edlongbptr; /* Pointer to working neighbor edge load array */ Gnum edlolocsiz; /* Size of neighbor edge load array (if any) */ int cheklocval; /* Local consistency flag */ int chekglbval; /* Global consistency flag */ Gnum reduloctab[20]; /* Arrays for reductions */ Gnum reduglbtab[20]; MPI_Request requloctab[8]; /* Arrays for pipelined communications */ MPI_Status statloctab[8]; Gnum * restrict const vertloctax = grafptr->vertloctax; Gnum * restrict const vendloctax = grafptr->vendloctax; Gnum * restrict const veloloctax = grafptr->veloloctax; Gnum * restrict const edgeloctax = grafptr->edgeloctax; Gnum * restrict const edgegsttax = grafptr->edgegsttax; Gnum * restrict const edloloctax = grafptr->edloloctax; proccomm = grafptr->proccomm; /* Simplify */ if (MPI_Barrier (proccomm) != MPI_SUCCESS) { /* Synchronize */ errorPrint ("dgraphCheck: communication error (1)"); return (1); } cheklocval = /* Assume everything is all right */ chekglbval = 0; MPI_Comm_size (proccomm, &procglbnbr); /* Get communicator data */ MPI_Comm_rank (proccomm, &proclocnum); if ((grafptr->procglbnbr != procglbnbr) || (grafptr->proclocnum != proclocnum) || ((grafptr->procdsptab == NULL) && (grafptr->vertlocnbr != 0))) { errorPrint ("dgraphCheck: inconsistent communication data (1)"); cheklocval = 1; } if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, proccomm) != MPI_SUCCESS) { errorPrint ("dgraphCheck: communication error (2)"); return (1); } if (chekglbval != 0) return (1); reduloctab[0] = (grafptr->procdsptab == NULL) ? 0 : 1; /* If private data not initialized */ if (MPI_Allreduce (reduloctab, reduglbtab, 1, GNUM_MPI, MPI_SUM, proccomm) != MPI_SUCCESS) { errorPrint ("dgraphCheck: communication error (3)"); return (1); } if (reduglbtab[0] == 0) /* If distributed graph is empty */ return (0); /* Do not go any further */ if (reduglbtab[0] != procglbnbr) { /* If private data not consistently here */ errorPrint ("dgraphCheck: inconsistent communication data (2)"); return (1); } for (procrcvnum = 0; procrcvnum < grafptr->procglbnbr; procrcvnum ++) { if ((grafptr->proccnttab[procrcvnum] < 0) || (grafptr->proccnttab[procrcvnum] != (grafptr->procdsptab[procrcvnum + 1] - grafptr->procdsptab[procrcvnum])) || (grafptr->proccnttab[procrcvnum] > (grafptr->procvrttab[procrcvnum + 1] - grafptr->procvrttab[procrcvnum]))) { errorPrint ("dgraphCheck: inconsistent communication data (3)"); cheklocval = 1; } } if (grafptr->proccnttab[proclocnum] != grafptr->vertlocnbr) { errorPrint ("dgraphCheck: inconsistent communication data (4)"); cheklocval = 1; } procrcvnum = (proclocnum + 1) % procglbnbr; /* Compute indices of neighbors */ procsndnum = (proclocnum - 1 + procglbnbr) % procglbnbr; if ((procngbtab = (Gnum *) memAlloc ((procglbnbr + 1) * sizeof (Gnum))) == NULL) { errorPrint ("dgraphCheck: out of memory (1)"); cheklocval = 1; } if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, proccomm) != MPI_SUCCESS) { errorPrint ("dgraphCheck: communication error (4)"); return (1); } if (chekglbval != 0) { if (procngbtab != NULL) memFree (procngbtab); return (1); } MPI_Sendrecv (grafptr->procdsptab, procglbnbr + 1, GNUM_MPI, procsndnum, TAGPROCVRTTAB, /* Check vertex range array */ procngbtab, procglbnbr + 1, GNUM_MPI, procrcvnum, TAGPROCVRTTAB, proccomm, &statloctab[0]); for (procngbnum = 0; procngbnum <= procglbnbr; procngbnum ++) { if (grafptr->procdsptab[procngbnum] != procngbtab[procngbnum]) { errorPrint ("dgraphCheck: inconsistent communication data (5)"); cheklocval = 1; break; } } MPI_Sendrecv (grafptr->procvrttab, procglbnbr + 1, GNUM_MPI, procsndnum, TAGPROCVRTTAB, /* Check vertex range array */ procngbtab, procglbnbr + 1, GNUM_MPI, procrcvnum, TAGPROCVRTTAB, proccomm, &statloctab[0]); for (procngbnum = 0; procngbnum <= procglbnbr; procngbnum ++) { if (grafptr->procvrttab[procngbnum] != procngbtab[procngbnum]) { errorPrint ("dgraphCheck: inconsistent communication data (6)"); cheklocval = 1; break; } } memFree (procngbtab); if ((grafptr->baseval < 0) || /* Elementary constraints on graph fields */ (grafptr->baseval > 1) || /* Strong limitation on base value */ (grafptr->vertlocnbr < 0) || (grafptr->vertlocnnd != (grafptr->vertlocnbr + grafptr->baseval)) || (((grafptr->flagval & DGRAPHHASEDGEGST) != 0) && ((grafptr->vertgstnbr < grafptr->vertlocnbr) || (grafptr->vertgstnnd != (grafptr->vertgstnbr + grafptr->baseval)))) || (grafptr->edgelocnbr < 0) || (grafptr->edgelocsiz < grafptr->edgelocnbr)) { errorPrint ("dgraphCheck: inconsistent local graph data"); cheklocval = 1; } reduloctab[ 0] = grafptr->flagval; reduloctab[ 1] = - grafptr->flagval; reduloctab[ 2] = grafptr->baseval; reduloctab[ 3] = - grafptr->baseval; reduloctab[ 4] = grafptr->vertglbnbr; reduloctab[ 5] = - grafptr->vertglbnbr; reduloctab[ 6] = grafptr->vertglbmax; reduloctab[ 7] = - grafptr->vertglbmax; reduloctab[ 8] = grafptr->vertlocnbr; reduloctab[ 9] = grafptr->edgeglbnbr; reduloctab[10] = - grafptr->edgeglbnbr; reduloctab[11] = grafptr->edgeglbmax; reduloctab[12] = - grafptr->edgeglbmax; reduloctab[13] = grafptr->edgelocnbr; reduloctab[14] = grafptr->edgelocsiz; reduloctab[15] = grafptr->edgeglbsmx; reduloctab[16] = - grafptr->edgeglbsmx; reduloctab[17] = grafptr->degrglbmax; reduloctab[18] = - grafptr->degrglbmax; reduloctab[19] = (Gnum) cheklocval; if (MPI_Allreduce (reduloctab, reduglbtab, 20, GNUM_MPI, MPI_MAX, proccomm) != MPI_SUCCESS) { errorPrint ("dgraphCheck: communication error (5)"); return (1); } if (reduglbtab[19] != 0) return (1); if ((reduglbtab[ 1] != - reduglbtab[ 0]) || /* Check if global graph data match */ (reduglbtab[ 3] != - reduglbtab[ 2]) || (reduglbtab[ 5] != - reduglbtab[ 4]) || (reduglbtab[ 7] != - reduloctab[ 6]) || (reduglbtab[ 8] != reduloctab[ 6]) || (reduglbtab[10] != - reduglbtab[ 9]) || (reduglbtab[12] != - reduglbtab[11]) || (reduglbtab[13] != reduloctab[11]) || /* Recompute and test maximum number of local edges */ (reduglbtab[14] != reduloctab[15]) || /* Recompute and test maximum size of local edge array */ (reduglbtab[16] != - reduloctab[15]) || (reduglbtab[18] != - reduloctab[17])) { errorPrint ("dgraphCheck: inconsistent global graph data (1)"); cheklocval = 1; } reduloctab[0] = (veloloctax != NULL) ? 1 : 0; /* Check consistency */ reduloctab[1] = (edgegsttax != NULL) ? 1 : 0; reduloctab[2] = (edloloctax != NULL) ? 1 : 0; reduloctab[3] = (grafptr->vnumloctax != NULL) ? 1 : 0; reduloctab[4] = grafptr->vertlocnbr; /* Recompute local sizes */ reduloctab[5] = grafptr->edgelocnbr; reduloctab[6] = (Gnum) cheklocval; if (MPI_Allreduce (reduloctab, reduglbtab, 7, GNUM_MPI, MPI_SUM, proccomm) != MPI_SUCCESS) { errorPrint ("dgraphCheck: communication error (6)"); return (1); } if (reduglbtab[6] != 0) return (1); if (((reduglbtab[0] != 0) && (reduglbtab[0] != procglbnbr)) || ((reduglbtab[1] != 0) && (reduglbtab[1] != procglbnbr)) || ((reduglbtab[2] != 0) && (reduglbtab[2] != procglbnbr)) || ((reduglbtab[3] != 0) && (reduglbtab[3] != procglbnbr)) || (reduglbtab[4] != grafptr->vertglbnbr) || (reduglbtab[5] != grafptr->edgeglbnbr)) { errorPrint ("dgraphCheck: inconsistent global graph data (2)"); cheklocval = 1; } for (vertlocnum = grafptr->baseval, edgelocnbr = 0; vertlocnum < grafptr->vertlocnnd; vertlocnum ++) { Gnum edgelocnum; if ((vendloctax[vertlocnum] < vertloctax[vertlocnum]) || (vendloctax[vertlocnum] > (grafptr->edgelocsiz + grafptr->baseval))) { errorPrint ("dgraphCheck: inconsistent local vertex arrays"); edgelocnbr = grafptr->edgelocnbr; /* Avoid unwanted cascaded error messages */ cheklocval = 1; break; } edgelocnbr += vendloctax[vertlocnum] - vertloctax[vertlocnum]; if ((grafptr->flagval & DGRAPHHASEDGEGST) != 0) { /* If ghost edge array is valid */ for (edgelocnum = vertloctax[vertlocnum]; edgelocnum < vendloctax[vertlocnum]; edgelocnum ++) { if ((edgegsttax[edgelocnum] < grafptr->baseval) || (edgegsttax[edgelocnum] >= grafptr->vertgstnnd)) { errorPrint ("dgraphCheck: inconsistent ghost edge array"); edgelocnbr = grafptr->edgelocnbr; /* Avoid unwanted cascaded error messages */ vertlocnum = grafptr->vertlocnnd; /* Exit outer loop */ cheklocval = 1; break; } if ((edloloctax != NULL) && (edloloctax[edgelocnum] <= 0)) { errorPrint ("dgraphCheck: invalid edge load"); edgelocnbr = grafptr->edgelocnbr; /* Avoid unwanted cascaded error messages */ vertlocnum = grafptr->vertlocnnd; /* Exit outer loop */ cheklocval = 1; break; } } } } if (edgelocnbr != grafptr->edgelocnbr) { errorPrint ("dgraphCheck: invalid local number of edges"); cheklocval = 1; } if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, proccomm) != MPI_SUCCESS) { errorPrint ("dgraphCheck: communication error (7)"); return (1); } if (chekglbval != 0) return (1); if (veloloctax != NULL) { /* Check vertex load consistency */ Gnum velolocsum; Gnum veloglbsum; for (vertlocnum = grafptr->baseval, velolocsum = 0; vertlocnum < grafptr->vertlocnnd; vertlocnum ++) { Gnum veloval; veloval = veloloctax[vertlocnum]; if ((veloval < 0) && (cheklocval == 0)) { errorPrint ("dgraphCheck: invalid vertex load"); cheklocval = 1; } velolocsum += veloval; } MPI_Allreduce (&velolocsum, &veloglbsum, 1, GNUM_MPI, MPI_SUM, proccomm); if (velolocsum != grafptr->velolocsum) { errorPrint ("dgraphCheck: invalid local vertex load sum"); cheklocval = 1; } if (veloglbsum != grafptr->veloglbsum) { errorPrint ("dgraphCheck: invalid global vertex load sum"); cheklocval = 1; } MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, proccomm); if (chekglbval != 0) return (1); } edlolocsiz = (edloloctax != NULL) ? grafptr->edgeglbsmx : 0; if (memAllocGroup ((void **) (void *) &vertngbtab[0], (size_t) (grafptr->vertglbmax * sizeof (Gnum)), /* Send vertex and vertex end arrays, even when they are compact */ &vertngbtab[1], (size_t) (grafptr->vertglbmax * sizeof (Gnum)), &vendngbtab[0], (size_t) (grafptr->vertglbmax * sizeof (Gnum)), &vendngbtab[1], (size_t) (grafptr->vertglbmax * sizeof (Gnum)), &edgengbtab[0], (size_t) (grafptr->edgeglbsmx * sizeof (Gnum)), &edgengbtab[1], (size_t) (grafptr->edgeglbsmx * sizeof (Gnum)), &edlongbtab[0], (size_t) (edlolocsiz * sizeof (Gnum)), &edlongbtab[1], (size_t) (edlolocsiz * sizeof (Gnum)), NULL) == NULL) { errorPrint ("dgraphCheck: out of memory (2)"); cheklocval = 1; } edgengbtab[0] -= grafptr->baseval; /* Base edges arrays only */ edgengbtab[1] -= grafptr->baseval; if (edloloctax == NULL) { /* If graph edges are not weighted */ edlongbtab[0] = /* Edge load arrays are fake */ edlongbtab[1] = NULL; } else { edlongbtab[0] -= grafptr->baseval; edlongbtab[1] -= grafptr->baseval; } if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, proccomm) != MPI_SUCCESS) { errorPrint ("dgraphCheck: communication error (8)"); return (1); } if (chekglbval != 0) { if (cheklocval == 0) memFree (vertngbtab[0]); /* Free group leader */ return (1); } procngbsel = 0; /* Initial work array selector */ vertngbptr = vertloctax + grafptr->baseval; /* Start working on self arrays */ vendngbptr = vendloctax + grafptr->baseval; /* Un-base vertex arrays */ edgengbptr = edgeloctax; /* Edge arrays are based */ edlongbptr = edloloctax; vertngbnbr[0] = grafptr->vertlocnbr; /* Set number of local vertices and edges to send */ edgengbnbr[0] = grafptr->edgelocsiz; /* Send all of edge array is case graph is not compact */ for (procnum = 0; procnum < procglbnbr; procnum ++) { /* For all processes including self */ Gnum procngbnum; Gnum vertlocnum; Gnum vertglbnum; procngbnum = (proclocnum + procnum) % procglbnbr; /* Compute neighbor process number */ vertngbmin = grafptr->procvrttab[procngbnum]; /* Get neighbor vertex number range */ vertngbmax = grafptr->procvrttab[procngbnum + 1]; #ifdef SCOTCH_DEBUG_DGRAPH2 if ((vertngbnbr[procngbsel] != grafptr->proccnttab[procngbnum]) || (vertngbnbr[procngbsel] > (vertngbmax - vertngbmin))) { errorPrint ("dgraphCheck: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ if (procnum < (procglbnbr - 1)) { /* For all rounds except the last one */ MPI_Irecv (vertngbtab[1 - procngbsel], grafptr->vertglbmax, GNUM_MPI, procrcvnum, TAGVERTLOCTAB, proccomm, &requloctab[4]); MPI_Irecv (vendngbtab[1 - procngbsel], grafptr->vertglbmax, GNUM_MPI, procrcvnum, TAGVENDLOCTAB, proccomm, &requloctab[5]); MPI_Irecv (edgengbtab[1 - procngbsel] + grafptr->baseval, grafptr->edgeglbsmx, GNUM_MPI, procrcvnum, TAGEDGELOCTAB, proccomm, &requloctab[6]); MPI_Isend (vertngbptr, vertngbnbr[procngbsel], GNUM_MPI, procsndnum, TAGVERTLOCTAB, proccomm, &requloctab[1]); MPI_Isend (vendngbptr, vertngbnbr[procngbsel], GNUM_MPI, procsndnum, TAGVENDLOCTAB, proccomm, &requloctab[2]); MPI_Isend (edgengbptr + grafptr->baseval, edgengbnbr[procngbsel], GNUM_MPI, procsndnum, TAGEDGELOCTAB, proccomm, &requloctab[3]); if (edlongbptr != NULL) { MPI_Irecv (edlongbtab[1 - procngbsel] + grafptr->baseval, grafptr->edgeglbsmx, GNUM_MPI, procrcvnum, TAGEDLOLOCTAB, proccomm, &requloctab[7]); MPI_Isend (edlongbptr + grafptr->baseval, edgengbnbr[procngbsel], GNUM_MPI, procsndnum, TAGEDLOLOCTAB, proccomm, &requloctab[0]); /* Complete communications before accessing arrays being sent */ MPI_Waitall (8, &requloctab[0], &statloctab[0]); } else MPI_Waitall (6, &requloctab[1], &statloctab[1]); MPI_Get_count (&statloctab[4], GNUM_MPI, &vertngbnbr[1 - procngbsel]); MPI_Get_count (&statloctab[6], GNUM_MPI, &edgengbnbr[1 - procngbsel]); } for (vertlocnum = grafptr->baseval, vertglbnum = grafptr->procvrttab[proclocnum]; vertlocnum < grafptr->vertlocnnd; vertlocnum ++, vertglbnum ++) { Gnum edgelocnum; for (edgelocnum = vertloctax[vertlocnum]; edgelocnum < vendloctax[vertlocnum]; edgelocnum ++) { Gnum vertglbend; vertglbend = edgeloctax[edgelocnum]; if ((vertglbend >= vertngbmin) && /* If end vertex belongs to current neighbor process */ (vertglbend < vertngbmax)) { Gnum edgengbnum; Gnum edgengbnnd; Gnum edgengbsum; for (edgengbnum = vertngbptr[vertglbend - vertngbmin], edgengbnnd = vendngbptr[vertglbend - vertngbmin], edgengbsum = 0; edgengbnum < edgengbnnd; edgengbnum ++) { if (edgengbptr[edgengbnum] == vertglbnum) { /* If matching edge found */ edgengbsum ++; /* Account for it */ if ((edlongbptr != NULL) && /* If edge weights do not match */ (edlongbptr[edgengbnum] != edloloctax[edgelocnum])) cheklocval = 3; } } if (edgengbsum < 1) /* If matching edge not found */ cheklocval = 1; else if (edgengbsum > 1) /* If duplicate edge */ cheklocval = 2; } } } MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, proccomm); if (chekglbval != 0) { /* Error number ranges from 1 to 3 */ if (chekglbval == 1) errorPrint ("dgraphCheck: arc data do not match"); else if (chekglbval == 2) errorPrint ("dgraphCheck: duplicate arc"); else errorPrint ("dgraphCheck: arc load data do not match"); memFree (vertngbtab[0]); /* Free group leader */ return (1); } procngbsel ^= 1; /* Swap work and receive buffers */ vertngbptr = vertngbtab[procngbsel]; /* Point to future work buffers */ vendngbptr = vendngbtab[procngbsel]; /* Vertex pointers are unbased */ edgengbptr = edgengbtab[procngbsel]; /* Edge pointers are based */ edlongbptr = edlongbtab[procngbsel]; } memFree (vertngbtab[0]); /* Free group leader */ return (0); } scotch-6.0.4.dfsg/src/libscotch/dorder_io_tree.c0000644002563400244210000001665511631447170025004 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dorder_io_tree.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles distributed **/ /** orderings. **/ /** **/ /** DATES : # Version 5.0 : from : 26 jul 2007 **/ /** to 26 jul 2007 **/ /** # Version 5.1 : from : 30 jul 2010 **/ /** to 30 jul 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DORDER #include "module.h" #include "common.h" #include "comm.h" #include "dgraph.h" #include "order.h" #include "dorder.h" /************************************/ /* */ /* These routines handle orderings. */ /* */ /************************************/ /* This routine saves a distributed ordering. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int dorderSaveTree2 ( const Dorder * restrict const ordeptr, const Dgraph * restrict const grafptr, FILE * restrict const stream, int (* funcptr) (const Order * const, const Gnum * const, FILE * const)) { Order corddat; /* Centralized ordering for tree structure */ Gnum * restrict vlbltab; int procglbnbr; int protnum; int reduloctab[3]; int reduglbtab[3]; int cheklocval; int chekglbval; if (stream != NULL) { /* If file provided */ reduloctab[0] = 1; /* This process is the root */ reduloctab[1] = ordeptr->proclocnum; /* Get its rank */ } else { reduloctab[0] = /* This process is not the root */ reduloctab[1] = 0; } reduloctab[2] = (grafptr->vlblloctax != NULL) ? 1 : 0; /* See if vertex labels provided */ if (MPI_Allreduce (reduloctab, reduglbtab, 3, MPI_INT, MPI_SUM, ordeptr->proccomm) != MPI_SUCCESS) { errorPrint ("dorderSaveTree2: communication error (1)"); return (1); } if (reduglbtab[0] != 1) { errorPrint ("dorderSaveTree2: should have only one root"); return (1); } MPI_Comm_size (ordeptr->proccomm, &procglbnbr); if ((reduglbtab[2] != 0) && (reduglbtab[2] != procglbnbr)) { errorPrint ("dorderSaveTree2: inconsistent parameters"); return (1); } protnum = (int) reduglbtab[1]; /* Get rank of root process */ cheklocval = 0; vlbltab = NULL; if (reduglbtab[2] != 0) { if (protnum == ordeptr->proclocnum) if ((vlbltab = memAlloc (ordeptr->vnodglbnbr * sizeof (Gnum))) == NULL) { errorPrint ("dorderSaveTree2: out of memory"); cheklocval = 1; } #ifdef SCOTCH_DEBUG_DORDER1 /* Communication cannot be merged with a useful one */ if (MPI_Bcast (&cheklocval, 1, MPI_INT, protnum, ordeptr->proccomm) != MPI_SUCCESS) { errorPrint ("dorderSaveTree2: communication error (2)"); return (1); } #endif /* SCOTCH_DEBUG_DORDER1 */ if (cheklocval != 0) return (1); if (commGatherv (grafptr->vlblloctax + grafptr->baseval, grafptr->vertlocnbr, GNUM_MPI, vlbltab, grafptr->proccnttab, grafptr->procdsptab, GNUM_MPI, protnum, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dorderSaveTree2: communication error (3)"); return (1); } } if (protnum == ordeptr->proclocnum) cheklocval = orderInit (&corddat, ordeptr->baseval, ordeptr->vnodglbnbr, NULL); #ifdef SCOTCH_DEBUG_DORDER1 /* Communication cannot be merged with a useful one */ if (MPI_Bcast (&cheklocval, 1, MPI_INT, protnum, ordeptr->proccomm) != MPI_SUCCESS) { errorPrint ("dorderSaveTree2: communication error (4)"); return (1); } #endif /* SCOTCH_DEBUG_DORDER1 */ if (cheklocval != 0) return (1); if (protnum == ordeptr->proclocnum) { cheklocval = dorderGather (ordeptr, &corddat); /* Need inverse permutation too */ if (cheklocval == 0) cheklocval = funcptr (&corddat, vlbltab, stream); orderExit (&corddat); } else cheklocval = dorderGather (ordeptr, NULL); if (vlbltab != NULL) memFree (vlbltab); #ifdef SCOTCH_DEBUG_DORDER1 /* Communication cannot be merged with a useful one */ if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, ordeptr->proccomm) != MPI_SUCCESS) { errorPrint ("dorderSaveTree2: communication error (3)"); return (1); } #else /* SCOTCH_DEBUG_DORDER1 */ chekglbval = cheklocval; #endif /* SCOTCH_DEBUG_DORDER1 */ return (chekglbval); } /* This routine saves the separator tree ** data of the given distributed ordering. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int dorderSaveTree ( const Dorder * restrict const ordeptr, const Dgraph * restrict const grafptr, FILE * restrict const stream) { return (dorderSaveTree2 (ordeptr, grafptr, stream, orderSaveTree)); } /* This routine saves the column block ** mapping data of the given distributed ** ordering. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int dorderSaveMap ( const Dorder * restrict const ordeptr, const Dgraph * restrict const grafptr, FILE * restrict const stream) { return (dorderSaveTree2 (ordeptr, grafptr, stream, orderSaveMap)); } scotch-6.0.4.dfsg/src/libscotch/arch.c0000644002563400244210000004051312400054107022707 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007-2013 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : arch.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module handles the generic target **/ /** architecture functions. **/ /** **/ /** DATES : # Version 0.0 : from : 01 dec 1992 **/ /** to : 24 mar 1993 **/ /** # Version 1.2 : from : 04 feb 1994 **/ /** to : 11 feb 1994 **/ /** # Version 1.3 : from : 20 apr 1994 **/ /** to : 20 apr 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to : 23 dec 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to : 29 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 16 aug 1995 **/ /** # Version 3.1 : from : 02 may 1996 **/ /** to 17 jul 1996 **/ /** # Version 3.2 : from : 07 sep 1996 **/ /** to 28 sep 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 3.4 : from : 08 nov 2001 **/ /** to 08 nov 2001 **/ /** # Version 4.0 : from : 04 nov 2003 **/ /** to 09 jan 2004 **/ /** # Version 5.1 : from : 11 dec 2007 **/ /** to 25 jun 2010 **/ /** # Version 6.0 : from : 14 fev 2011 **/ /** to 26 nov 2013 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define ARCH #include "module.h" #include "common.h" #include "arch.h" #include "arch_cmplt.h" #include "arch_cmpltw.h" #include "arch_deco.h" #include "arch_dist.h" #include "arch_hcub.h" #include "arch_mesh.h" #include "arch_tleaf.h" #include "arch_torus.h" #include "arch_vcmplt.h" #include "arch_vhcub.h" /* ** The static definitions. */ static const ArchClass archClassTab[] = { ARCHCLASSBLOCK ("cmplt", Cmplt, ARCHPART), ARCHCLASSBLOCK ("cmpltw", Cmpltw, ARCHPART), ARCHCLASSBLOCK ("deco", Deco, ARCHNONE), ARCHCLASSBLOCK ("dist", Dist, ARCHNONE), ARCHCLASSBLOCK ("hcub", Hcub, ARCHNONE), ARCHCLASSBLOCK ("tleaf", Tleaf, ARCHNONE), ARCHCLASSBLOCK ("ltleaf", Ltleaf, ARCHNONE), ARCHCLASSBLOCK ("mesh2D", Mesh2, ARCHNONE), #ifdef SCOTCH_DEBUG_ARCH3 ARCHCLASSBLOCK ("mesh2O", Mesh2o, ARCHNONE), ARCHCLASSBLOCK ("mesh2U", Mesh2u, ARCHNONE), #endif /* SCOTCH_DEBUG_ARCH3 */ ARCHCLASSBLOCK ("mesh3D", Mesh3, ARCHNONE), ARCHCLASSBLOCK ("torus2D", Torus2, ARCHNONE), ARCHCLASSBLOCK ("torus3D", Torus3, ARCHNONE), ARCHCLASSBLOCK ("torusXD", TorusX, ARCHNONE), ARCHCLASSBLOCK ("varcmplt", Vcmplt, ARCHPART | ARCHVAR), ARCHCLASSBLOCK ("varhcub", Vhcub, ARCHVAR), ARCHCLASSBLOCKNULL }; /**************************************/ /* */ /* These are the entry points for the */ /* generic architecture routines. */ /* */ /**************************************/ /* This routine initializes an architecture structure. ** It zeroes the architecture body so that architecture ** specific routines can check if their pointers have ** been initialized or not. ** It returns: ** - !NULL : pointer to the target architecture. ** - NULL : on error. */ int archInit ( Arch * restrict const archptr) { memSet (archptr, 0, sizeof (Arch)); /* Initialize architecture body (arch->class = NULL) */ return (0); } /* This routine deletes an architecture. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archExit ( Arch * restrict const archptr) { return (archFree (archptr)); /* Free architecture data */ } /* This routine frees the architecture data. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archFree ( Arch * restrict const archptr) { int o; o = 0; /* Assume everything will be all right */ if ((archptr->class != NULL) && (archptr->class->archFree != NULL)) /* If there is a specific freeing routing */ o = archptr->class->archFree (&archptr->data); /* Call it */ memSet (archptr, 0, sizeof (Arch)); /* Initialize the architecture body (arch->class = NULL) */ return (o); } /* This routine loads an architecture. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archLoad ( Arch * restrict const archptr, FILE * const stream) { const ArchClass * restrict class; /* Pointer to architecture class */ char name[256]; /* Architecture name string */ if (fscanf (stream, "%255s", name) != 1) { /* Read architecture name */ errorPrint ("archLoad: cannot load architecture type"); return (1); } name[255] = '\0'; /* Set end of string */ if ((class = archClass (name)) == NULL) { /* Get class from its name */ errorPrint ("archLoad: invalid architecture type"); return (1); } if (class->archLoad != NULL) { /* If class has loading function */ if (class->archLoad (&archptr->data, stream) != 0) { /* Load class data */ errorPrint ("archLoad: cannot load architecture data"); class->archFree (&archptr->data); /* Perform clean-up */ memSet (archptr, 0, sizeof (Arch)); /* Initialize architecture body */ return (1); } } archptr->class = class; /* Set architecture class */ archptr->flagval = archptr->class->flagval; /* Copy architecture flag */ return (0); } /* This routine saves an architecture. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archSave ( const Arch * restrict const archptr, FILE * restrict const stream) { int o; if (archptr->class == NULL) /* If no architecture type defined */ return (0); /* Nothing to do */ o = (fprintf (stream, "%s\n", /* Write architecture class */ archptr->class->archname) == EOF); if (archptr->class->archSave != NULL) /* If class has saving function */ o |= archptr->class->archSave (&archptr->data, stream); /* Write architecture data */ o |= (fprintf (stream, "\n") == EOF); if (o != 0) errorPrint ("archSave: bad output"); return (o); } /* This routine returns the pointer to ** the class of a given architecture ** name. ** It returns: ** - !NULL : class pointer. ** - NULL : on error. */ const ArchClass * archClass ( const char * const name) { const ArchClass * restrict class; /* Pointer to architecture class */ for (class = archClassTab; /* For all classes */ (class->archname != NULL) && /* Search if class names match */ (strcasecmp (name, class->archname) != 0); class ++) ; return ((class->archname != NULL) ? class : NULL); } /**************************************/ /* */ /* These are the entry points for the */ /* generic domain routines. They are */ /* used only in debugging mode, to */ /* provide breakpoints for routines */ /* which are else implemented as */ /* macros for the sake of efficiency. */ /* */ /**************************************/ /* This function returns the smallest number ** of terminal domain included within the ** given domain. */ #ifdef SCOTCH_DEBUG_ARCH2 ArchDomNum archDomNum ( const Arch * const archptr, const ArchDom * const domptr) { return (archDomNum2 (archptr, domptr)); /* Call proper routine */ } #endif /* SCOTCH_DEBUG_ARCH2 */ /* This function computes the terminal domain ** associated with the given terminal number. ** It returns: ** - 0 : if label is valid and domain has been updated. ** - 1 : if label is invalid. ** - 2 : on error. */ #ifdef SCOTCH_DEBUG_ARCH2 int archDomTerm ( const Arch * const archptr, ArchDom * restrict const domptr, const ArchDomNum domnum) { return (archDomTerm2 (archptr, domptr, domnum)); /* Call proper routine */ } #endif /* SCOTCH_DEBUG_ARCH2 */ /* This function returns the number ** of elements in the given domain. ** It returns: ** - >0 : size of the domain. ** - 0 : on error. */ #ifdef SCOTCH_DEBUG_ARCH2 Anum archDomSize ( const Arch * const archptr, const ArchDom * const domptr) { return (archDomSize2 (archptr, domptr)); /* Call proper routine */ } #endif /* SCOTCH_DEBUG_ARCH2 */ /* This function returns the weight ** of the given domain. ** It returns: ** - >0 : weight of the domain. ** - 0 : on error. */ #ifdef SCOTCH_DEBUG_ARCH2 Anum archDomWght ( const Arch * const archptr, const ArchDom * const domptr) { return (archDomWght2 (archptr, domptr)); /* Call proper routine */ } #endif /* SCOTCH_DEBUG_ARCH2 */ /* This function gives the average ** distance between two domains. ** It returns: ** - !-1 : distance between subdomains. ** - -1 : on error. */ #ifdef SCOTCH_DEBUG_ARCH2 Anum archDomDist ( const Arch * const archptr, const ArchDom * const dom0ptr, const ArchDom * const dom1ptr) { return (archDomDist2 (archptr, dom0ptr, dom1ptr)); /* Call proper routine */ } #endif /* SCOTCH_DEBUG_ARCH2 */ /* This function sets the biggest ** available domain for the given ** architecture. ** It returns: ** - 0 : on success. ** - !0 : on error. */ #ifdef SCOTCH_DEBUG_ARCH2 int archDomFrst ( const Arch * const archptr, ArchDom * const domptr) { return (archDomFrst2 (archptr, domptr)); /* Call proper routine */ } #endif /* SCOTCH_DEBUG_ARCH2 */ /* This routine reads domain information ** from the given stream. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archDomLoad ( const Arch * const archptr, ArchDom * const domptr, FILE * const stream) { return (archptr->class->domLoad (&archptr->data, /* Call proper routine */ &domptr->data, stream)); } /* This routine saves domain information ** to the given stream. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archDomSave ( const Arch * const archptr, const ArchDom * const domptr, FILE * const stream) { return (archptr->class->domSave (&archptr->data, /* Call proper routine */ &domptr->data, stream)); } /* This function tries to split a domain into ** two subdomains. The two subdomains are created ** so that subdomain 0 has same T_domNum as ** original domain. ** It returns: ** - 0 : if bipartitioning succeeded. ** - 1 : if bipartitioning could not be performed. ** - 2 : on error. */ #ifdef SCOTCH_DEBUG_ARCH2 int archDomBipart ( const Arch * const archptr, const ArchDom * const domptr, ArchDom * const dom0ptr, ArchDom * const dom1ptr) { int o; o = archDomBipart2 (archptr, domptr, dom0ptr, dom1ptr); /* Call proper routine */ if ((o == 0) && /* Check domain number consistency for fixed-sized architectures */ (strncmp (archName (archptr), "var", 3) != 0) && (archDomNum (archptr, dom0ptr) != archDomNum (archptr, domptr))) { errorPrint ("archDomBipart: domain number mismatch"); return (2); } return (o); } #endif /* SCOTCH_DEBUG_ARCH2 */ /* This function checks if dom1 is ** included in dom0. ** It returns: ** - 0 : if dom1 is not included in dom0. ** - 1 : if dom1 is included in dom0. ** - 2 : on error. */ #ifdef SCOTCH_DEBUG_ARCH2 int archDomIncl ( const Arch * const archptr, const ArchDom * const dom0ptr, const ArchDom * const dom1ptr) { return archDomIncl2 (archptr, dom0ptr, dom1ptr); } #endif /* SCOTCH_DEBUG_ARCH2 */ /* This function creates the MPI_Datatype for ** complete graph domains. ** It returns: ** - 0 : if type could be created. ** - 1 : on error. */ #ifdef SCOTCH_PTSCOTCH int archDomMpiType ( const Arch * const archptr, MPI_Datatype * const typeptr) { int bloktab[2]; MPI_Aint disptab[2]; MPI_Datatype typetab[2]; int o; bloktab[0] = /* Build structured type to set up upper bound of domain datatype */ bloktab[1] = 1; disptab[0] = 0; /* Displacement of real datatype is base of array */ disptab[1] = sizeof (ArchDom); /* Displacement of upper bound is size of ArchDom */ typetab[1] = MPI_UB; o = ((int (*) (const void * const, const void * const)) archptr->class->domMpiType) ((const void * const) &archptr->data, &typetab[0]); if (o == 0) o = (MPI_Type_struct (2, bloktab, disptab, typetab, typeptr) != MPI_SUCCESS); if (o == 0) o = (MPI_Type_commit (typeptr) != MPI_SUCCESS); /* Created MPI types have to be committed */ return (o); } #endif /* SCOTCH_PTSCOTCH */ scotch-6.0.4.dfsg/src/libscotch/kdgraph_map_rb_map.c0000644002563400244210000000625611631447171025611 0ustar trophimeutilisateurs du domaine/* Copyright 2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kdgraph_map_rb_map.c **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** **/ /** FUNCTION : This module performs the Dual Recursive **/ /** Bipartitioning mapping algorithm **/ /** in parallel for non-complete graphs. **/ /** **/ /** DATES : # Version 5.1 : from : 24 jun 2008 **/ /** to 24 jun 2008 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define KDGRAPH_MAP_RB_MAP #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "arch.h" #include "dgraph.h" #include "dmapping.h" #include "kdgraph.h" #include "kdgraph_map_rb.h" #include "kdgraph_map_rb_map.h" #include "kdgraph_map_st.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ int kdgraphMapRbMap ( Kdgraph * restrict const grafptr, Kdmapping * restrict const mappptr, const KdgraphMapRbParam * restrict const paraptr) { errorPrint ("kdgraphMapRbMap: not implemented yet"); return (1); } scotch-6.0.4.dfsg/src/libscotch/dgraph_halo_fill.c0000644002563400244210000000740111631447170025262 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_halo_fill.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a parallel static mapper. **/ /** This module contains the halo update **/ /** routines. **/ /** **/ /** # Version 5.0 : from : 31 dec 2006 **/ /** to 05 feb 2008 **/ /** # Version 5.1 : from : 28 aug 2008 **/ /** to 29 aug 2010 **/ /** **/ /************************************************************/ /* This function fills the send array used by ** all of the halo routines. ** It returns: ** - void : in all cases. */ static void DGRAPHHALOFILLNAME ( const Dgraph * restrict const grafptr, const void * restrict const attrgsttab, /* Attribute array to diffuse */ const int attrglbsiz, /* Type extent of attribute */ byte ** restrict const attrdsptab) /* Temporary address displacement array */ { byte * restrict attrgstptr; const int * restrict procsidptr; const int * restrict procsidnnd; for (procsidptr = grafptr->procsidtab, procsidnnd = procsidptr + grafptr->procsidnbr, attrgstptr = (byte *) attrgsttab; procsidptr < procsidnnd; procsidptr ++) { int procsidval; procsidval = *procsidptr; if (procsidval < 0) attrgstptr -= ((Gnum) procsidval) * DGRAPHHALOFILLSIZE; else { byte * attrdspptr; attrdspptr = attrdsptab[procsidval]; attrdsptab[procsidval] = attrdspptr + DGRAPHHALOFILLSIZE; /* Skip to next position in send buffer */ DGRAPHHALOFILLCOPY (attrdspptr, attrgstptr, DGRAPHHALOFILLSIZE); } } } scotch-6.0.4.dfsg/src/libscotch/vmesh_separate_ml.h0000644002563400244210000000721511631447171025513 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vmesh_separate_ml.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the multi-level node separation **/ /** routines. **/ /** **/ /** DATES : # Version 4.0 : from : 20 feb 2003 **/ /** to 31 aug 2005 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct VmeshSeparateMlParam_ { INT vnodnbr; /*+ Minimum number of node vertices +*/ double coarrat; /*+ Coarsening ratio +*/ MeshCoarsenType coartype; /*+ Element matching function type +*/ Strat * stratlow; /*+ Strategy at lowest level +*/ Strat * stratasc; /*+ Strategy at ascending levels +*/ } VmeshSeparateMlParam; /* ** The function prototypes. */ #ifndef VMESH_SEPARATE_ML #define static #endif static int vmeshSeparateMlCoarsen (const Vmesh * restrict const, Vmesh * restrict const, Gnum * restrict * const, const VmeshSeparateMlParam * const); static int vmeshSeparateMlUncoarsen (Vmesh * const, const Vmesh * const, const Gnum * restrict const); int vmeshSeparateMl (Vmesh * const, const VmeshSeparateMlParam * const); static int vmeshSeparateMl2 (Vmesh * const, const VmeshSeparateMlParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/hmesh_order_nd.c0000644002563400244210000002125611631447171024771 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh_order_nd.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module orders mesh nodes using the **/ /** nested dissection algorithm. **/ /** **/ /** DATES : # Version 4.0 : from : 06 jan 2002 **/ /** to 05 jan 2005 **/ /** # Version 5.0 : from : 25 jul 2007 **/ /** to : 12 sep 2007 **/ /** # Version 5.1 : from : 09 nov 2008 **/ /** to : 09 nov 2008 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HMESH_ORDER_ND #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "order.h" #include "mesh.h" #include "hmesh.h" #include "hmesh_order_nd.h" #include "hmesh_order_st.h" #include "vmesh.h" #include "vmesh_separate_st.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the ordering. ** It returns: ** - 0 : if the ordering could be computed. ** - !0 : on error. */ int hmeshOrderNd ( const Hmesh * restrict const meshptr, Order * restrict const ordeptr, const Gnum ordenum, OrderCblk * restrict const cblkptr, const HmeshOrderNdParam * const paraptr) { Hmesh indmeshdat; /* Induced halo mesh data */ Vmesh nspmeshdat; /* Node separation mesh */ Gnum vertnbr; int o; if (hmeshMesh (meshptr, &nspmeshdat.m) != 0) { errorPrint ("hmeshOrderNd: cannot create node separation mesh"); return (1); } nspmeshdat.ecmpsize[0] = nspmeshdat.m.velmnbr; nspmeshdat.ecmpsize[1] = 0; nspmeshdat.ncmpload[0] = nspmeshdat.m.vnlosum; nspmeshdat.ncmpload[1] = 0; nspmeshdat.ncmpload[2] = 0; nspmeshdat.ncmploaddlt = nspmeshdat.m.vnlosum; nspmeshdat.ncmpsize[0] = nspmeshdat.m.vnodnbr; nspmeshdat.ncmpsize[1] = 0; nspmeshdat.fronnbr = 0; nspmeshdat.levlnum = meshptr->levlnum; vertnbr = nspmeshdat.m.velmnbr + nspmeshdat.m.vnodnbr; if (memAllocGroup ((void **) (void *) &nspmeshdat.parttax, (size_t) (vertnbr * sizeof (GraphPart)), &nspmeshdat.frontab, (size_t) (vertnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("hmeshOrderNd: out of memory (1)"); return (1); } memSet (nspmeshdat.parttax, 0, vertnbr * sizeof (GraphPart)); /* Set all vertices to part 0 */ nspmeshdat.parttax -= nspmeshdat.m.baseval; if (vmeshSeparateSt (&nspmeshdat, paraptr->sepstrat) != 0) { /* Separate mesh */ vmeshExit (&nspmeshdat); return (1); } if ((nspmeshdat.ncmpsize[0] == 0) || /* If could not separate more */ (nspmeshdat.ncmpsize[1] == 0)) { vmeshExit (&nspmeshdat); return (hmeshOrderSt (meshptr, ordeptr, ordenum, cblkptr, paraptr->ordstratlea)); /* Order this leaf */ } cblkptr->typeval = ORDERCBLKNEDI; /* Node becomes a nested dissection node */ if ((cblkptr->cblktab = (OrderCblk *) memAlloc (3 * sizeof (OrderCblk))) == NULL) { errorPrint ("hmeshOrderNd: out of memory (2)"); vmeshExit (&nspmeshdat); return (1); } cblkptr->cblktab[0].typeval = ORDERCBLKOTHR; /* Build column blocks */ cblkptr->cblktab[0].vnodnbr = nspmeshdat.ncmpsize[0]; cblkptr->cblktab[0].cblknbr = 0; cblkptr->cblktab[0].cblktab = NULL; cblkptr->cblktab[1].typeval = ORDERCBLKOTHR; cblkptr->cblktab[1].vnodnbr = nspmeshdat.ncmpsize[1]; cblkptr->cblktab[1].cblknbr = 0; cblkptr->cblktab[1].cblktab = NULL; cblkptr->cblktab[2].vnodnbr = nspmeshdat.fronnbr; cblkptr->cblktab[2].cblknbr = 0; cblkptr->cblktab[2].cblktab = NULL; if (nspmeshdat.fronnbr != 0) { /* If separator not empty */ cblkptr->cblknbr = 3; /* It is a three-cell tree node */ ordeptr->cblknbr += 2; /* Two more column blocks created */ ordeptr->treenbr += 3; /* Three more tree nodes created */ cblkptr->cblktab[2].typeval = ORDERCBLKOTHR; cblkptr->cblktab[2].vnodnbr = nspmeshdat.fronnbr; cblkptr->cblktab[2].cblknbr = 0; cblkptr->cblktab[2].cblktab = NULL; if (meshInduceSepa (&nspmeshdat.m, nspmeshdat.parttax, nspmeshdat.fronnbr, nspmeshdat.frontab, &indmeshdat.m) != 0) { errorPrint ("hmeshOrderNd: cannot build induced subgraph (1)"); memFree (nspmeshdat.frontab); /* Free remaining space */ return (1); } indmeshdat.vnohnbr = indmeshdat.m.vnodnbr; /* Fill halo mesh structure of non-halo mesh */ indmeshdat.vnohnnd = indmeshdat.m.vnodnnd; indmeshdat.vehdtax = indmeshdat.m.vendtax; indmeshdat.vnhlsum = indmeshdat.m.vnlosum; indmeshdat.enohnbr = indmeshdat.m.edgenbr; indmeshdat.levlnum = meshptr->levlnum; /* Separator mesh is at level of original mesh */ o = hmeshOrderSt (&indmeshdat, ordeptr, ordenum + nspmeshdat.ncmpsize[0] + nspmeshdat.ncmpsize[1], cblkptr->cblktab + 2, paraptr->ordstratsep); hmeshExit (&indmeshdat); } else { /* Separator is empty */ cblkptr->cblknbr = 2; /* It is a two-cell tree node */ ordeptr->cblknbr ++; /* One more column block created */ ordeptr->treenbr += 2; /* Two more tree nodes created */ o = 0; /* No separator ordering computed */ } if (o == 0) { if (hmeshInducePart (meshptr, nspmeshdat.parttax, 0, nspmeshdat.ecmpsize[0], nspmeshdat.ncmpsize[0], nspmeshdat.fronnbr, &indmeshdat) != 0) { errorPrint ("hmeshOrderNd: cannot build induced subgraph (2)"); memFree (nspmeshdat.frontab); /* Free remaining space */ return (1); } o = hmeshOrderNd (&indmeshdat, ordeptr, ordenum, cblkptr->cblktab, paraptr); hmeshExit (&indmeshdat); } if (o == 0) { if (hmeshInducePart (meshptr, nspmeshdat.parttax, 1, nspmeshdat.ecmpsize[1], nspmeshdat.ncmpsize[1], nspmeshdat.fronnbr, &indmeshdat) != 0) { errorPrint ("hmeshOrderNd: cannot build induced subgraph (3)"); memFree (nspmeshdat.frontab); /* Free remaining space */ return (1); } o = hmeshOrderNd (&indmeshdat, ordeptr, ordenum + nspmeshdat.ncmpsize[0], cblkptr->cblktab + 1, paraptr); hmeshExit (&indmeshdat); } vmeshExit (&nspmeshdat); return (0); } scotch-6.0.4.dfsg/src/libscotch/wgraph_part_rb.h0000644002563400244210000000742711631447170025022 0ustar trophimeutilisateurs du domaine/* Copyright 2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : wgraph_part_rb.h **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the vertex overlapped graph partit- **/ /** ioning based on recursive bipartitioni- **/ /** ng approach. **/ /** **/ /** DATES : # Version 6.0 : from : 16 mar 2010 **/ /** to 04 nov 2010 **/ /** **/ /** NOTES : # This code derives from the code of **/ /** kgraph_map_rb_part.h for the vertex **/ /** overlapped graph partitioning. **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct WgraphPartRbParam_ { Strat * stratptr; /*+ Bipartitioning strategy used +*/ } WgraphPartRbParam; /*+ This structure holds global data. +*/ typedef struct WgraphPartRbData_ { const Graph * grafptr; /*+ Pointer to top-level graph +*/ Gnum * frontab; /*+ Pointer to top-level frontier array +*/ Gnum fronnbr; /*+ Current number of frontier vertices +*/ Mapping mappdat; /*+ Current state of mapping +*/ Strat * stratptr; /*+ Bipartitioning strategy used +*/ } WgraphPartRbData; /* ** The function prototypes. */ #ifndef WGRAPH_PART_RB #define static #endif int wgraphPartRb (Wgraph * restrict const, const WgraphPartRbParam * restrict const); #undef static scotch-6.0.4.dfsg/src/libscotch/hgraph_order_si.c0000644002563400244210000001037412473144056025150 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hgraph_order_si.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module orders halo graph vertices **/ /** using a simple method. **/ /** **/ /** DATES : # Version 3.2 : from : 01 nov 1996 **/ /** to 21 aug 1998 **/ /** # Version 3.3 : from : 02 oct 1998 **/ /** to 02 oct 1998 **/ /** # Version 4.0 : from : 19 dec 2001 **/ /** to 11 dec 2002 **/ /** # Version 6.0 : from : 17 oct 2012 **/ /** to : 04 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HGRAPH_ORDER_SI #include "module.h" #include "common.h" #include "graph.h" #include "order.h" #include "hgraph.h" #include "hgraph_order_si.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the ordering. ** It returns: ** - 0 : if the ordering could be computed. ** - !0 : on error. */ int hgraphOrderSi ( const Hgraph * restrict const grafptr, Order * restrict const ordeptr, const Gnum ordenum, /*+ Zero-based ordering number +*/ OrderCblk * restrict const cblkptr) /*+ Single column-block +*/ { Gnum vnohnnd; Gnum vertnum; Gnum vnumnum; Gnum * restrict const peritab = ordeptr->peritab; const Gnum * restrict const vnumtax = grafptr->s.vnumtax; vnohnnd = grafptr->vnohnnd; if (vnumtax == NULL) { /* If graph is original graph */ for (vertnum = grafptr->s.baseval, vnumnum = ordenum; vertnum < vnohnnd; vertnum ++, vnumnum ++) peritab[vnumnum] = vertnum; } else { /* Graph is not original graph */ for (vertnum = grafptr->s.baseval, vnumnum = ordenum; vertnum < vnohnnd; vertnum ++, vnumnum ++) peritab[vnumnum] = vnumtax[vertnum]; } return (0); } scotch-6.0.4.dfsg/src/libscotch/library_dmapping.c0000644002563400244210000000643412056000427025324 0ustar trophimeutilisateurs du domaine/* Copyright 2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dmapping.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains miscellaneous **/ /** routines for handling distributed **/ /** graph mappings. **/ /** **/ /** DATES : # Version 5.1 : from : 17 nov 2010 **/ /** to 17 nov 2010 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "ptscotch.h" /****************************************/ /* */ /* These routines are the C API for */ /* mapping structure handling routines. */ /* */ /****************************************/ /*+ This routine reserves a memory area *** of a size sufficient to store a *** graph mapping structure. *** It returns: *** - !NULL : if the initialization succeeded. *** - NULL : on error. +*/ SCOTCH_Dmapping * SCOTCH_dmapAlloc () { return ((SCOTCH_Dmapping *) memAlloc (sizeof (SCOTCH_Dmapping))); } scotch-6.0.4.dfsg/src/libscotch/dgraph_build_grid3d.c0000644002563400244210000004471711631447170025677 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_build_grid3d.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Cedric CHEVALIER (5.0) **/ /** **/ /** FUNCTION : These lines are the distributed source **/ /** graph building routines for 3D grid **/ /** graphs. **/ /** **/ /** DATES : # Version 5.0 : from : 21 jul 2005 **/ /** to : 10 sep 2007 **/ /** # Version 5.1 : from : 05 jun 2010 **/ /** to : 06 jun 2010 **/ /** **/ /************************************************************/ #define DGRAPH_BUILD_GRID3D #include "module.h" #include "common.h" #include "dgraph.h" #include "dgraph_build_grid3d.h" /**************************************/ /* */ /* Vertex neighbor handling routines. */ /* */ /**************************************/ /* ** */ static Gnum dgraphBuildGrid3Dvertex26M ( const DgraphBuildGrid3DData * restrict const dataptr, const Gnum vertglbnum, Gnum edgelocnum, const Gnum posxval, const Gnum posyval, const Gnum poszval) { Gnum ngbxmin; Gnum ngbxmax; Gnum ngbxval; Gnum ngbymin; Gnum ngbymax; Gnum ngbyval; Gnum ngbzmin; Gnum ngbzmax; Gnum ngbzval; ngbxmin = (posxval > 0) ? -1 : 0; ngbymin = (posyval > 0) ? -1 : 0; ngbzmin = (poszval > 0) ? -1 : 0; ngbxmax = (posxval < (dataptr->dimxval - 1)) ? 1 : 0; ngbymax = (posyval < (dataptr->dimyval - 1)) ? 1 : 0; ngbzmax = (poszval < (dataptr->dimzval - 1)) ? 1 : 0; for (ngbzval = ngbzmin; ngbzval <= ngbzmax; ngbzval ++) { for (ngbyval = ngbymin; ngbyval <= ngbymax; ngbyval ++) { for (ngbxval = ngbxmin; ngbxval <= ngbxmax; ngbxval ++) { if ((ngbxval | ngbyval | ngbzval) != 0) /* If not loop edge */ DGRAPHBUILDGRID3DNGB (dataptr, vertglbnum, edgelocnum ++, (posxval + dataptr->dimxval + ngbxval) % dataptr->dimxval, (posyval + dataptr->dimyval + ngbyval) % dataptr->dimyval, (poszval + dataptr->dimzval + ngbzval) % dataptr->dimzval); } } } return (edgelocnum); } /* ** */ static Gnum dgraphBuildGrid3Dvertex26T ( const DgraphBuildGrid3DData * restrict const dataptr, const Gnum vertglbnum, Gnum edgelocnum, const Gnum posxval, const Gnum posyval, const Gnum poszval) { Gnum ngbxmin; Gnum ngbxmax; Gnum ngbxval; Gnum ngbymin; Gnum ngbymax; Gnum ngbyval; Gnum ngbzmin; Gnum ngbzmax; Gnum ngbzval; ngbxmin = dataptr->t26.ngbxmin; ngbxmax = dataptr->t26.ngbxmax; ngbymin = dataptr->t26.ngbymin; ngbymax = dataptr->t26.ngbymax; ngbzmin = dataptr->t26.ngbzmin; ngbzmax = dataptr->t26.ngbzmax; for (ngbzval = ngbzmin; ngbzval <= ngbzmax; ngbzval ++) { for (ngbyval = ngbymin; ngbyval <= ngbymax; ngbyval ++) { for (ngbxval = ngbxmin; ngbxval <= ngbxmax; ngbxval ++) { Gnum vertglbend; vertglbend = (((poszval + ngbzval) % dataptr->dimzval) * dataptr->dimyval + ((posyval + ngbyval) % dataptr->dimyval)) * dataptr->dimxval + ((posxval + ngbxval) % dataptr->dimxval) + dataptr->baseval; if (vertglbend != vertglbnum) { /* If not loop edge */ if (dataptr->edloloctax != NULL) dataptr->edloloctax[edgelocnum] = ((vertglbend + vertglbnum) % 16) + 1; dataptr->edgeloctax[edgelocnum ++] = vertglbend; } } } } return (edgelocnum); } /* ** */ static Gnum dgraphBuildGrid3Dvertex6M ( const DgraphBuildGrid3DData * restrict const dataptr, const Gnum vertglbnum, Gnum edgelocnum, const Gnum posxval, const Gnum posyval, const Gnum poszval) { Gnum ngbxval; Gnum ngbyval; Gnum ngbzval; ngbxval = posxval - 1; if (ngbxval >= 0) DGRAPHBUILDGRID3DNGB (dataptr, vertglbnum, edgelocnum ++, ngbxval, posyval, poszval); ngbxval = posxval + 1; if (ngbxval < dataptr->dimxval) DGRAPHBUILDGRID3DNGB (dataptr, vertglbnum, edgelocnum ++, ngbxval, posyval, poszval); ngbyval = posyval - 1; if (ngbyval >= 0) DGRAPHBUILDGRID3DNGB (dataptr, vertglbnum, edgelocnum ++, posxval, ngbyval, poszval); ngbyval = posyval + 1; if (ngbyval < dataptr->dimyval) DGRAPHBUILDGRID3DNGB (dataptr, vertglbnum, edgelocnum ++, posxval, ngbyval, poszval); ngbzval = poszval - 1; if (ngbzval >= 0) DGRAPHBUILDGRID3DNGB (dataptr, vertglbnum, edgelocnum ++, posxval, posyval, ngbzval); ngbzval = poszval + 1; if (ngbzval < dataptr->dimzval) DGRAPHBUILDGRID3DNGB (dataptr, vertglbnum, edgelocnum ++, posxval, posyval, ngbzval); return (edgelocnum); } /* ** */ static Gnum dgraphBuildGrid3Dvertex6T ( const DgraphBuildGrid3DData * restrict const dataptr, const Gnum vertglbnum, Gnum edgelocnum, const Gnum posxval, const Gnum posyval, const Gnum poszval) { Gnum ngbxval; Gnum ngbyval; Gnum ngbzval; if (dataptr->dimxval > 1) { ngbxval = (posxval + 1) % dataptr->dimxval; DGRAPHBUILDGRID3DNGB (dataptr, vertglbnum, edgelocnum ++, ngbxval, posyval, poszval); if (dataptr->dimxval > 2) { ngbxval = (posxval + dataptr->dimxval - 1) % dataptr->dimxval; DGRAPHBUILDGRID3DNGB (dataptr, vertglbnum, edgelocnum ++, ngbxval, posyval, poszval); } } if (dataptr->dimyval > 1) { ngbyval = (posyval + 1) % dataptr->dimyval; DGRAPHBUILDGRID3DNGB (dataptr, vertglbnum, edgelocnum ++, posxval, ngbyval, poszval); if (dataptr->dimyval > 2) { ngbyval = (posyval + dataptr->dimyval - 1) % dataptr->dimyval; DGRAPHBUILDGRID3DNGB (dataptr, vertglbnum, edgelocnum ++, posxval, ngbyval, poszval); } } if (dataptr->dimzval > 1) { ngbzval = (poszval + 1) % dataptr->dimzval; DGRAPHBUILDGRID3DNGB (dataptr, vertglbnum, edgelocnum ++, posxval, posyval, ngbzval); if (dataptr->dimzval > 2) { ngbzval = (poszval + dataptr->dimzval - 1) % dataptr->dimzval; DGRAPHBUILDGRID3DNGB (dataptr, vertglbnum, edgelocnum ++, posxval, posyval, ngbzval); } } return (edgelocnum); } /*******************************************/ /* */ /* The distributed graph building routine. */ /* */ /*******************************************/ /* This routine builds a distrbuted grid graph ** of the given dimensions. ** hashval is the increment between two vertex ** indices (1 for sliced meshes). ** flagval is a combilation of: ** - 1 : 26-neighbor mesh (default: 6-neighbor mesh). ** - 2 : torus (default: mesh) ** - 4 : weighted vertices (default: no weights). ** - 8 : weighted edges (default: no weights). ** It returns: ** - 0 : graph created. ** - !0 : on error. */ int dgraphBuildGrid3D ( Dgraph * restrict const grafptr, /* Graph */ const Gnum baseval, /* Base value */ const Gnum dimxval, /* First dimension */ const Gnum dimyval, /* Second dimension */ const Gnum dimzval, /* Third dimension */ const Gnum incrval, /* Increment step */ const int flagval) /* Grid type */ { DgraphBuildGrid3DData datadat; /* Data structure for creating vertices */ Gnum proclocadj; /* Number of processes with most vertices */ Gnum vertglbmin; /* Minimum global index of local vertices */ Gnum vertglbnbr; Gnum vertlocnbr; Gnum vertlocnnd; Gnum vertlocnum; Gnum * vertloctax; Gnum velolocsiz; Gnum velolocsum; Gnum * veloloctax; Gnum * vlblloctax; Gnum vlbllocsiz; Gnum edgelocsiz; Gnum edgelocnum; Gnum * edgeloctab; Gnum edlolocsiz; Gnum * edloloctab; Gnum degrglbmax; #ifdef SCOTCH_DEBUG_DGRAPH1 if ((dimxval < 1) || (dimyval < 1) || (dimzval < 1)) { /* At least one vertex */ errorPrint ("dgraphBuildGrid3D: invalid parameters (1)"); return (1); } if (incrval < 1) { errorPrint ("dgraphBuildGrid3D: invalid parameters (2)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH1 */ vertglbnbr = dimxval * dimyval * dimzval; vertlocnbr = DATASIZE (vertglbnbr, grafptr->procglbnbr, grafptr->proclocnum); if ((flagval & 1) != 0) { /* If 26-neighbor mesh */ degrglbmax = 26; if ((flagval & 2) != 0) { /* If torus graph */ datadat.t26.ngbxmin = (dimxval > 1) ? (dimxval - 1) : dimxval; /* Avoid loop edges */ datadat.t26.ngbxmax = (dimxval > 2) ? (dimxval + 1) : dimxval; datadat.t26.ngbymin = (dimyval > 1) ? (dimyval - 1) : dimyval; datadat.t26.ngbymax = (dimyval > 2) ? (dimyval + 1) : dimyval; datadat.t26.ngbzmin = (dimzval > 1) ? (dimzval - 1) : dimzval; datadat.t26.ngbzmax = (dimzval > 2) ? (dimzval + 1) : dimzval; datadat.funcvrtptr = dgraphBuildGrid3Dvertex26T; } else datadat.funcvrtptr = dgraphBuildGrid3Dvertex26M; } else { /* If 6-neighbor mesh */ degrglbmax = 6; datadat.funcvrtptr = ((flagval & 2) != 0) ? dgraphBuildGrid3Dvertex6T : dgraphBuildGrid3Dvertex6M; } edgelocsiz = vertlocnbr * degrglbmax; /* (Possibly upper bound on) number of edges */ vlbllocsiz = (incrval != 1) ? vertlocnbr : 0; /* If no hashing, no need for vertex labels */ velolocsiz = ((flagval & 4) != 0) ? vertlocnbr : 0; edlolocsiz = ((flagval & 8) != 0) ? edgelocsiz : 0; if (memAllocGroup ((void **) (void *) &vertloctax, (size_t) ((vertlocnbr + 1) * sizeof (Gnum)), /* +1 to indicate end of array */ &veloloctax, (size_t) (velolocsiz * sizeof (Gnum)), &vlblloctax, (size_t) (vlbllocsiz * sizeof (Gnum)), NULL) == NULL) { errorPrint ("dgraphBuildGrid3D: out of memory (1)"); return (1); } if (memAllocGroup ((void **) (void *) &edgeloctab, (size_t) (edgelocsiz * sizeof (Gnum)), &edloloctab, (size_t) (edlolocsiz * sizeof (Gnum)), NULL) == NULL) { memFree (vertloctax); errorPrint ("dgraphBuildGrid3D: out of memory (2)"); return (1); } datadat.baseval = baseval; datadat.dimxval = dimxval; datadat.dimyval = dimyval; datadat.dimzval = dimzval; datadat.edgeloctax = edgeloctab - baseval; datadat.edloloctax = ((flagval & 8) != 0) ? (edloloctab - baseval) : NULL; vertloctax = vertloctax - baseval; veloloctax = ((flagval & 4) != 0) ? (veloloctax - baseval) : NULL; vlblloctax = (incrval != 1) ? (vlblloctax - baseval) : NULL; proclocadj = vertglbnbr % grafptr->procglbnbr; /* Number of processes with +1 number of vertices */ vertglbmin = (vertglbnbr / grafptr->procglbnbr) * grafptr->proclocnum + MIN (grafptr->proclocnum, proclocadj); edgelocnum = vertlocnum = baseval; vertlocnnd = baseval + vertlocnbr; velolocsum = (veloloctax == NULL) ? vertlocnbr : 0; if (incrval != 1) { /* If strided or pseudo-randomly distributed mesh */ Gnum vertglbidx; /* Un-based global index of current vertex */ Gnum rondlocnbr; /* Number of already completed rounds of increments */ Gnum a; Gnum b; a = (vertglbnbr > incrval) ? vertglbnbr : incrval; /* Get biggest of the two */ b = (vertglbnbr + incrval) - a; /* Get smallest of the two */ do { Gnum t; t = a % b; if (t == 0) break; a = b; b = t; } while (b > 1); /* Compute GCD of vertglbnbr and incrval in b */ rondlocnbr = (vertglbmin * b) / vertglbnbr; vertglbidx = (vertglbmin * incrval + rondlocnbr) % vertglbnbr; /* Compute skewed index, with rounds */ for ( ; vertlocnum < vertlocnnd; vertlocnum ++) { Gnum vertglbnum; Gnum positmp; Gnum posxval; Gnum posyval; Gnum poszval; poszval = vertglbidx / (dimxval * dimyval); positmp = vertglbidx % (dimxval * dimyval); posyval = positmp / dimxval; posxval = positmp % dimxval; vertglbnum = vertglbidx + baseval; vertloctax[vertlocnum] = edgelocnum; vlblloctax[vertlocnum] = vertglbnum; if (veloloctax != NULL) { velolocsum += veloloctax[vertlocnum] = (vertglbnum % 16) + 1; } edgelocnum = datadat.funcvrtptr (&datadat, vertglbnum, edgelocnum, posxval, posyval, poszval); #ifdef SCOTCH_DEBUG_DGRAPH2 if (edgelocnum > (edgelocsiz + baseval)) { errorPrint ("dgraphBuildGrid3D: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ vertglbidx = (vertglbidx + incrval) % vertglbnbr; /* Add increment to global index */ if (vertglbidx == rondlocnbr) { /* If we looped back to the current beginning */ rondlocnbr ++; /* Start a new round of increments */ vertglbidx = rondlocnbr; } } } else { /* Regularly sliced mesh */ Gnum vertglbnum; /* Based global vertex number */ Gnum positmp; Gnum posxval; Gnum posyval; Gnum poszval; poszval = vertglbmin / (dimxval * dimyval); positmp = vertglbmin % (dimxval * dimyval); posyval = positmp / dimxval; posxval = positmp % dimxval; for (vertglbnum = vertglbmin + baseval; vertlocnum < vertlocnnd; vertlocnum ++, vertglbnum ++) { vertloctax[vertlocnum] = edgelocnum; if (veloloctax != NULL) { velolocsum += veloloctax[vertlocnum] = (vertglbnum % 16) + 1; } edgelocnum = datadat.funcvrtptr (&datadat, vertglbnum, edgelocnum, posxval, posyval, poszval); #ifdef SCOTCH_DEBUG_DGRAPH2 if (edgelocnum > (edgelocsiz + baseval)) { errorPrint ("dgraphBuildGrid3D: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ if (++ posxval >= dimxval) { posxval = 0; if (++ posyval >= dimyval) { posyval = 0; poszval ++; #ifdef SCOTCH_DEBUG_DGRAPH2 if ((poszval >= dimzval) && (vertglbnum < (vertglbnbr + baseval - 1))){ errorPrint ("dgraphBuildGrid3D: internal error (X)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ } } } } vertloctax[vertlocnum] = edgelocnum; /* Mark end of local vertex array */ grafptr->flagval = (DGRAPHFREETABS | DGRAPHVERTGROUP | DGRAPHEDGEGROUP); /* All arrays will be freed on exit */ if (dgraphBuild2 (grafptr, baseval, /* Build distributed graph */ vertlocnbr, vertlocnbr, vertloctax, vertloctax + 1, veloloctax, velolocsum, NULL, vlblloctax, edgelocnum - baseval, edgelocsiz, datadat.edgeloctax, NULL, datadat.edloloctax, degrglbmax) != 0) { memFree (datadat.edgeloctax + baseval); /* Free memory group leaders */ memFree (vertloctax + baseval); return (1); } return (0); } scotch-6.0.4.dfsg/src/libscotch/vgraph_store.c0000644002563400244210000001431311631447170024507 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vgraph_store.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the save data **/ /** structure handling routines for separa- **/ /** tion graphs. **/ /** **/ /** DATES : # Version 3.3 : from : 17 oct 1998 **/ /** to 17 oct 1998 **/ /** # Version 3.4 : from : 11 dec 2001 **/ /** to : 11 dec 2001 **/ /** # Version 4.0 : from : 01 jan 2002 **/ /** to : 06 jan 2002 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VGRAPH_STORE #include "module.h" #include "common.h" #include "graph.h" #include "vgraph.h" /**********************************/ /* */ /* Store graph handling routines. */ /* */ /**********************************/ /* This routine builds a save structure ** for the given active graph. ** It returns: ** - 0 : if allocation succeeded. ** - !0 : on error. */ int vgraphStoreInit ( const Vgraph * restrict const grafptr, VgraphStore * restrict const storptr) { Gnum savsize; savsize = grafptr->s.vertnbr * (sizeof (GraphPart) + sizeof (Gnum)); /* Compute size for frontier and part arrays */ if ((storptr->datatab = (byte *) memAlloc (savsize)) == NULL) { /* Allocate save structure */ errorPrint ("vgraphStoreInit: out of memory"); return (1); } return (0); } /* This routine frees a save structure. ** It returns: ** - VOID : in all cases. */ void vgraphStoreExit ( VgraphStore * const storptr) { memFree (storptr->datatab); #ifdef SCOTCH_DEBUG_VGRAPH2 storptr->datatab = NULL; #endif /* SCOTCH_DEBUG_VGRAPH2 */ } /* This routine saves partition data from the ** given active graph to the given save structure. ** It returns: ** - VOID : in all cases. */ void vgraphStoreSave ( const Vgraph * const grafptr, VgraphStore * const storptr) { byte * parttab; /* Pointer to part data save area */ byte * frontab; /* Pointer to frontier data save area */ storptr->fronnbr = grafptr->fronnbr; /* Save partition parameters */ storptr->comploaddlt = grafptr->comploaddlt; storptr->compload[0] = grafptr->compload[0]; storptr->compload[1] = grafptr->compload[1]; storptr->compsize0 = grafptr->compsize[0]; frontab = storptr->datatab; /* Compute data offsets within save structure */ parttab = frontab + grafptr->fronnbr * sizeof (Gnum); memCpy (frontab, grafptr->frontab, grafptr->fronnbr * sizeof (Gnum)); memCpy (parttab, grafptr->parttax + grafptr->s.baseval, grafptr->s.vertnbr * sizeof (GraphPart)); } /* This routine updates partition data of the ** given active graph, using the given save graph. ** It returns: ** - VOID : in all cases. */ void vgraphStoreUpdt ( Vgraph * const grafptr, const VgraphStore * const storptr) { byte * frontab; /* Pointer to frontier data save area */ byte * parttab; /* Pointer to part data save area */ grafptr->compload[0] = storptr->compload[0]; /* Load partition parameters */ grafptr->compload[1] = storptr->compload[1]; grafptr->compload[2] = grafptr->s.velosum - (storptr->compload[0] + storptr->compload[1]); grafptr->comploaddlt = storptr->comploaddlt; grafptr->compsize[0] = storptr->compsize0; grafptr->compsize[1] = grafptr->s.vertnbr - (storptr->compsize0 + storptr->fronnbr); grafptr->fronnbr = storptr->fronnbr; frontab = storptr->datatab; /* Compute data offsets within save structure */ parttab = frontab + grafptr->fronnbr * sizeof (Gnum); memCpy (grafptr->frontab, frontab, grafptr->fronnbr * sizeof (Gnum)); memCpy (grafptr->parttax + grafptr->s.baseval, parttab, grafptr->s.vertnbr * sizeof (GraphPart)); #ifdef SCOTCH_DEBUG_VGRAPH2 if (vgraphCheck (grafptr) != 0) errorPrint ("vgraphStoreUpdt: inconsistent graph data"); #endif /* SCOTCH_DEBUG_VGRAPH2 */ } scotch-6.0.4.dfsg/src/libscotch/graph_band.c0000644002563400244210000001743311762164002024072 0ustar trophimeutilisateurs du domaine/* Copyright 2010,2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : graph_band.c **/ /** **/ /** AUTHOR : Sebastien FOURESTIER (v6.0) **/ /** Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module computes a band graph **/ /** from the given frontier array. **/ /** **/ /** DATES : # Version 6.0 : from : 05 jan 2010 **/ /** to : 22 sep 2011 **/ /** **/ /** NOTES : # This code derives from the code of **/ /** dgraph_band.c in version 5.1. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GRAPH_BAND #include "module.h" #include "common.h" #include "graph.h" /**********************************/ /* */ /* Distance computation routines. */ /* */ /**********************************/ /* This routine computes an index array ** of given width around the current separator. ** It returns: ** - 0 : if the index array could be computed. ** - !0 : on error. */ int graphBand ( const Graph * restrict const grafptr, /*+ Graph +*/ const Gnum queunbr, /*+ Number of frontier vertices, start size for vertex queue +*/ Gnum * restrict const queutab, /*+ Array of frontier vertices, re-used as queue array +*/ const Gnum distmax, /*+ Maximum distance from separator vertices +*/ Gnum * restrict * restrict const vnumptr, /*+ Pointer to vnumtax +*/ Gnum * restrict const bandvertlvlptr, /*+ Pointer to based start index of last level +*/ Gnum * restrict const bandvertptr, /*+ Pointer to bandvertnbr +*/ Gnum * restrict const bandedgeptr, /*+ Pointer to bandedgenbr +*/ const Gnum * restrict const pfixtax, /*+ Fixed partition array +*/ Gnum * restrict const bandvfixptr) /*+ Pointer to bandvfixnbr +*/ { Gnum queunum; Gnum * restrict vnumtax; /* Index array for vertices kept in band graph */ Gnum queuheadidx; /* Index of head of queue */ Gnum queutailidx; /* Index of tail of queue */ Gnum bandvertlvlnum; Gnum bandvertnum; Gnum bandedgenbr; Gnum distval; Gnum bandvfixnbr; /* Number of band fixed vertices */ const Gnum * restrict const verttax = grafptr->verttax; const Gnum * restrict const vendtax = grafptr->vendtax; const Gnum * restrict const edgetax = grafptr->edgetax; if ((vnumtax = memAlloc (grafptr->vertnbr * sizeof (Gnum))) == NULL) { errorPrint ("graphBand: out of memory (1)"); return (1); } bandvertlvlnum = /* Start index of last level is start index */ bandvertnum = grafptr->baseval; /* Reset number of band vertices */ bandedgenbr = bandvfixnbr = 0; memSet (vnumtax, ~0, grafptr->vertnbr * sizeof (Gnum)); /* Reset part array */ vnumtax -= grafptr->baseval; for (queunum = 0; queunum < queunbr; queunum ++) { /* All frontier vertices will be first vertices of band graph */ Gnum vertnum; vertnum = queutab[queunum]; if ((pfixtax != NULL) && (pfixtax[vertnum] != -1)) { /* It is a fixed vertex */ vnumtax[vertnum] = -2; /* Set vertex as fixed */ bandvfixnbr ++; } else vnumtax[vertnum] = bandvertnum ++; /* Keep frontier vertex in band */ bandedgenbr += vendtax[vertnum] - verttax[vertnum]; /* Account for its edges */ } queuheadidx = 0; /* No queued vertex read yet */ queutailidx = queunbr; /* All frontier vertices are already in queue */ for (distval = 0; ++ distval <= distmax; ) { Gnum queunextidx; /* Tail index for enqueuing vertices of next band */ bandvertlvlnum = bandvertnum; *bandvertlvlptr = bandvertlvlnum; /* Save start index of current level, based */ for (queunextidx = queutailidx; queuheadidx < queutailidx; ) { /* For all vertices in queue */ Gnum vertnum; Gnum edgenum; vertnum = queutab[queuheadidx ++]; /* Dequeue vertex */ for (edgenum = verttax[vertnum]; edgenum < vendtax[vertnum]; edgenum ++) { Gnum vertend; vertend = edgetax[edgenum]; if (vnumtax[vertend] != ~0) /* If end vertex has already been processed */ continue; /* Skip to next vertex */ if ((pfixtax != NULL) && (pfixtax[vertend] != -1)) { /* If fixed vertex */ vnumtax[vertend] = -2; /* Set vertex as fixed */ bandvfixnbr ++; } else vnumtax[vertend] = bandvertnum ++; /* Enqueue vertex label */ bandedgenbr += vendtax[vertend] - verttax[vertend]; /* Account for its edges */ queutab[queunextidx ++] = vertend; /* Enqueue vertex for next pass */ } } queutailidx = queunextidx; /* Prepare queue for next sweep */ } *vnumptr = vnumtax; *bandvfixptr = bandvfixnbr; *bandvertptr = bandvertnum - grafptr->baseval; *bandedgeptr = bandedgenbr; return (0); } scotch-6.0.4.dfsg/src/libscotch/mesh_coarsen.c0000644002563400244210000007771511774577101024477 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mesh_coarsen.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the source mesh **/ /** coarsening functions. **/ /** **/ /** DATES : # Version 4.0 : from : 30 jan 2004 **/ /** to 05 may 2004 **/ /** # Version 5.0 : from : 12 sep 2007 **/ /** to 12 sep 2007 **/ /** **/ /** NOTES : # The coarsening process is as follows. **/ /** First, node collapsing is performed, **/ /** such that pairs of matching nodes are **/ /** created, or kept as single nodes. **/ /** Then, elements are built, and merged **/ /** whenever possible. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define MESH_COARSEN #include "module.h" #include "common.h" #include "graph.h" #include "mesh.h" #include "mesh_coarsen.h" /* ** The static variables. */ static void (* meshCoarFuncTab[MESHCOARSENNBR]) () = { /* Tables of matching routines */ meshCoarsenMatchNg }; /***************************/ /* */ /* The coarsening routine. */ /* */ /***************************/ /* This routine coarsens the given "finemesh" into ** "coarmesh", as long as the coarsening ratio remains ** below some threshold value and the coarsened mesh ** is not too small. ** It returns: ** - 0 : if the mesh has been coarsened. ** - 1 : if the mesh could not be coarsened. ** - 2 : on error. */ int meshCoarsen ( const Mesh * restrict const finemeshptr, /*+ Mesh to coarsen +*/ Mesh * restrict const coarmeshptr, /*+ Coarse mesh to build +*/ Gnum * restrict * const finecoarptr, /*+ Pointer to multinode data +*/ const Gnum coarnbr, /*+ Minimum number of coarse nodes +*/ const double coarrat, /*+ Maximum contraction ratio +*/ const MeshCoarsenType coartype) /*+ Matching type +*/ { Gnum coarhashsiz; /* Size of the hash table */ Gnum coarhashmsk; /* Mask for access to hash table */ MeshCoarsenHngb * restrict coarhngbtab; /* Table of edges to other multinodes */ MeshCoarsenHbdg * restrict coarhbdgtab; /* Table of bridge nodes to other multinodes */ Gnum * restrict coarverttax; /* Pointer to coarse vertex array */ Gnum * restrict coarvelotax; /* Pointer to coarse vertex load array */ Gnum * restrict coaredgetax; /* Pointer to coarse edge array */ Gnum coaredgenbr; /* (Upper bound of) number of edges in mesh */ Gnum coaredgenum; /* Number of current coarse edge */ Gnum coarvertnbr; /* Number of vertices in coarse mesh */ Gnum coarvelmnbr; /* Number of coarse element vertices */ Gnum coarvnodnbr; /* Number of coarse node vertices */ Gnum finevertnbr; /* Number of vertices in fine graph */ Gnum * restrict finecoartax; /* Based access to finecoartab */ Gnum coarvelmnum; /* Number of currently selected coarse element */ Gnum coareelmnum; Gnum coarvnodnum; Gnum coardegrmax; MeshCoarsenMult * restrict finemulttax; Gnum coaredgetmp; size_t coarvelooftval; size_t coaredgeoftval; #ifdef SCOTCH_DEBUG_MESH2 if (coartype >= MESHCOARSENNBR) { errorPrint ("meshCoarsen: invalid parameter"); return (2); } #endif /* SCOTCH_DEBUG_MESH2 */ memSet (coarmeshptr, 0, sizeof (Mesh)); /* Initialize coarse mesh */ coarmeshptr->flagval = GRAPHFREEVERT; coarmeshptr->baseval = finemeshptr->baseval; finevertnbr = finemeshptr->velmnbr + finemeshptr->vnodnbr; if ((finecoartax = (Gnum *) memAlloc (finevertnbr * sizeof (Gnum))) == NULL) { errorPrint ("meshCoarsen: out of memory (1)"); /* Allocate coarse mesh uncoarsening array */ return (2); } memSet (finecoartax, ~0, finevertnbr * sizeof (Gnum)); finecoartax -= finemeshptr->baseval; /* Set based access to finecoartax */ for (coarhashmsk = 31, coarhashsiz = finemeshptr->degrmax * finemeshptr->degrmax - 1; /* Compute size of hash table */ coarhashmsk < coarhashsiz; coarhashmsk = coarhashmsk * 2 + 1) ; coarhashsiz = coarhashmsk + 1; if (memAllocGroup ((void **) (void *) &coarverttax, (size_t) ((finevertnbr + 1) * sizeof (Gnum)), /* Upper bound on number of coarse vertices */ &coarvelotax, (size_t) ( finevertnbr * sizeof (Gnum)), /* Upper bound on number of coarse vertices */ &coaredgetax, (size_t) ( finemeshptr->edgenbr * sizeof (Gnum)), &coarhngbtab, (size_t) ( coarhashsiz * sizeof (MeshCoarsenHngb)), &coarhbdgtab, (size_t) ( coarhashsiz * sizeof (MeshCoarsenHbdg)), &finemulttax, (size_t) ( finemeshptr->velmnbr * sizeof (MeshCoarsenMult)), NULL) == NULL) { errorPrint ("meshCoarsen: out of memory (2)"); /* Allocate coarser mesh structure */ memFree (finecoartax + finemeshptr->baseval); return (2); } memSet (coarhngbtab, ~0, coarhashsiz * sizeof (MeshCoarsenHngb)); memSet (coarhbdgtab, ~0, coarhashsiz * sizeof (MeshCoarsenHbdg)); finemulttax -= coarmeshptr->baseval; #define SCOTCH_DEBUG_MESH3 #ifdef SCOTCH_DEBUG_MESH3 fprintf (stderr, "-------- ENTERING COARSENING ---------\n"); fprintf (stderr, "finenodenbr=%ld, fineelemnbr=%ld, fineedgenbr=%ld, finedegrmax=%ld\n", (long) finemeshptr->vnodnbr, (long) finemeshptr->velmnbr, (long) finemeshptr->edgenbr, (long) finemeshptr->degrmax); #endif /* SCOTCH_DEBUG_MESH3 */ meshCoarFuncTab[coartype] (finemeshptr, finemulttax, finecoartax, &coarvelmnbr, &coarvnodnbr, &coaredgenbr); /* Call proper matching function */ #ifndef DEAD_CODE coarvnodnbr = finemeshptr->vnodnbr; /* TODO : coarvnodnbr estimator is wrong : too tight */ coaredgenbr = finemeshptr->edgenbr; #endif /* DEAD_CODE */ coarvertnbr = coarvelmnbr + coarvnodnbr; memOffset ((void *) coarverttax, &coarverttax, (size_t) ((coarvertnbr + 1) * sizeof (Gnum)), &coarvelotax, (size_t) ( coarvertnbr * sizeof (Gnum)), &coaredgetax, (size_t) ( coaredgenbr * sizeof (Gnum)), NULL); /* Hast tables and finemulttax stay in place */ coarverttax -= coarmeshptr->baseval; coarvelotax -= coarmeshptr->baseval; coaredgetax -= coarmeshptr->baseval; coarmeshptr->velmbas = coarmeshptr->baseval; coarmeshptr->velmnbr = coarvelmnbr; coarmeshptr->velmnnd = coarmeshptr->vnodbas = coarvelmnbr + coarmeshptr->velmbas; for (coarvelmnum = coaredgenum = coarmeshptr->baseval, coarvnodnum = coarmeshptr->vnodbas, coardegrmax = 0; /* For all coarse elements */ coarvelmnum < coarmeshptr->velmnnd; coarvelmnum ++) { Gnum coarveloval; /* Weight of coarsened element */ Gnum coarvnisnum; /* Number of coarse isolated node */ Gnum finevelmnum; /* Number of current element */ int i; coarverttax[coarvelmnum] = coaredgenum; coarvnisnum = ~0; /* No isolated node yet for this element pair */ coarveloval = 0; i = 0; do { /* For both elements of element pair (if they are different) */ Gnum fineeelmnum; finevelmnum = finemulttax[coarvelmnum].finevelmnum[i]; /* Get number of current element */ coarveloval += ((finemeshptr->velotax != NULL) ? finemeshptr->velotax[finevelmnum] : 1); for (fineeelmnum = finemeshptr->verttax[finevelmnum]; fineeelmnum < finemeshptr->vendtax[finevelmnum]; fineeelmnum ++) { Gnum finevnodnum; /* Number of current node neighbor */ Gnum fineenodnum; Gnum finevdegval; Gnum finevnloval; Gnum finevelmend; Gnum coarvnodtmp; Gnum coarhnodtmp; finevnodnum = finemeshptr->edgetax[fineeelmnum]; fineenodnum = finemeshptr->verttax[finevnodnum]; finevdegval = finemeshptr->vendtax[finevnodnum] - fineenodnum; finevnloval = (finemeshptr->vnlotax != NULL) ? finemeshptr->vnlotax[finevnodnum] : 1; if ((finevdegval == 2) && /* If node is an external bridge to another coarse element */ ((finevelmend = (finemeshptr->edgetax[fineenodnum] + finemeshptr->edgetax[fineenodnum + 1] - finevelmnum)) != finemulttax[coarvelmnum].finevelmnum[1 - i])) { Gnum coarvelmend; Gnum coarhelmend; coarvelmend = finecoartax[finevelmend]; /* Get coarse index of end element */ coarvnodtmp = finecoartax[finevnodnum]; /* Get coarse number of fine node */ for (coarhelmend = (coarvelmend * MESHCOARSENHASHPRIME) & coarhashmsk; ; coarhelmend = (coarhelmend + 1) & coarhashmsk) { if (coarhbdgtab[coarhelmend].coarvelmnum != coarvelmnum) { /* If bridge not yet considered */ coarhbdgtab[coarhelmend].coarvelmnum = coarvelmnum; /* Add it to element neighbor list */ coarhbdgtab[coarhelmend].coarvelmend = coarvelmend; if (coarvnodtmp == -1) { /* If bridge nodes not considered before by other element */ coarhbdgtab[coarhelmend].coarvnodnum = /* Assign it */ finecoartax[finevnodnum] = coarvnodtmp = coarvnodnum ++; coarverttax[coarvnodtmp] = 2; /* Prepare the fact that another element will see the node */ coarvelotax[coarvnodtmp] = finevnloval; } coaredgetax[coaredgenum ++] = coarvnodtmp; /* Directly add coarse node to element neighborhood */ break; } if (coarhbdgtab[coarhelmend].coarvelmend == coarvelmend) { /* If bridge already present */ if (coarvnodtmp == -1) { /* If we are the first element to see the bridge node */ finecoartax[finevnodnum] = coarvnodtmp = coarhbdgtab[coarhelmend].coarvnodnum; /* Assign it */ coarvelotax[coarvnodtmp] += finevnloval; /* Update the weight of the node */ } /* Else node already processed with full load, so nothing to do */ break; } } continue; /* Edge has been added or will not be */ } else if (finevdegval < 3) { /* Else if node is isolated or is an internal bridge */ if ((finevdegval == 2) && /* Process bridge edges only once */ (finevelmnum >= finemulttax[coarvelmnum].finevelmnum[1 - i])) continue; if (coarvnisnum == ~0) { /* If no isolated node for this element pair */ coarvnisnum = coarvnodnum ++; /* Create isolated node */ coarverttax[coarvnisnum] = 1; coarvelotax[coarvnisnum] = finevnloval; coaredgetax[coaredgenum ++] = coarvnisnum; } else /* If isolated node already exists */ coarvelotax[coarvnisnum] += finevnloval; /* Add node contribution to it */ finecoartax[finevnodnum] = coarvnisnum; /* Map fine node to isolated node */ continue; } else { coarvnodtmp = finecoartax[finevnodnum]; /* Get coarse number of fine node */ if (coarvnodtmp == ~0) { /* If coarse number not yet assigned */ finecoartax[finevnodnum] = coarvnodtmp = coarvnodnum ++; /* Assign it */ coarverttax[coarvnodtmp] = 0; /* No connections to the node yet */ coarvelotax[coarvnodtmp] = finevnloval; } } for (coarhnodtmp = (coarvnodtmp * MESHCOARSENHASHPRIME) & coarhashmsk; ; coarhnodtmp = (coarhnodtmp + 1) & coarhashmsk) { if (coarhngbtab[coarhnodtmp].coarvelmnum != coarvelmnum) { /* If node neighbor not yet considered */ coarhngbtab[coarhnodtmp].coarvelmnum = coarvelmnum; /* Add it to element neighbor list */ coarhngbtab[coarhnodtmp].coarvnodnum = coarvnodtmp; coaredgetax[coaredgenum ++] = coarvnodtmp; coarverttax[coarvnodtmp] ++; /* One more edge referencing the node */ break; } if (coarhngbtab[coarhnodtmp].coarvnodnum == coarvnodtmp) /* If node already present, nothing to do */ break; } } } while (i ++, finevelmnum != finemulttax[coarvelmnum].finevelmnum[1]); coarvelotax[coarvelmnum] = coarveloval; /* Lose initial weights of elements, if any, to keep coarsening weights */ if ((coaredgenum - coarverttax[coarvelmnum]) > coardegrmax) coardegrmax = (coaredgenum - coarverttax[coarvelmnum]); } coarmeshptr->vnodnnd = coarvnodnum; coarmeshptr->vnodnbr = coarvnodnum - coarmeshptr->vnodbas; coarmeshptr->velosum = finemeshptr->velosum; coarmeshptr->vnlosum = finemeshptr->vnlosum; coarmeshptr->edgenbr = 2 * (coaredgenum - coarmeshptr->baseval); for (coarvnodnum = coarmeshptr->vnodbas, coaredgetmp = coaredgenum; /* Build start indices for node edge sub-arrays */ coarvnodnum < coarmeshptr->vnodnnd; coarvnodnum ++) { Gnum coardegrval; coardegrval = coarverttax[coarvnodnum]; coarverttax[coarvnodnum] = coaredgetmp; coaredgetmp += coardegrval; if (coardegrval > coardegrmax) coardegrmax = coardegrval; } coarmeshptr->degrmax = coardegrmax; for (coarvelmnum = coareelmnum = coarmeshptr->baseval; coarvelmnum < coarmeshptr->velmnnd; coarvelmnum ++) { Gnum coareelmnnd; coareelmnnd = (coarvelmnum < (coarmeshptr->velmnnd - 1)) ? coarverttax[coarvelmnum + 1] : coaredgenum; while (coareelmnum < coareelmnnd) { Gnum coarvnodnum; coarvnodnum = coaredgetax[coareelmnum ++]; coaredgetax[coarverttax[coarvnodnum] ++] = coarvelmnum; } } memMov (&coarverttax[coarmeshptr->vnodbas + 1], /* Re-build start indices for node edge sub-arrays */ &coarverttax[coarmeshptr->vnodbas], coarmeshptr->vnodnbr * sizeof (Gnum)); coarverttax[coarmeshptr->vnodbas] = coaredgenum; coarvelooftval = coarvelotax - coarverttax; coaredgeoftval = coaredgetax - coarverttax; coarverttax = memRealloc (coarverttax + coarmeshptr->baseval, (coaredgeoftval + coarmeshptr->edgenbr) * sizeof (Gnum)); /* Re-allocate array to save space */ coarmeshptr->verttax = coarverttax - coarmeshptr->baseval; coarmeshptr->vendtax = coarmeshptr->verttax + 1; coarmeshptr->velotax = coarmeshptr->verttax + coarvelooftval; coarmeshptr->vnlotax = coarmeshptr->velotax; /* Same array for both vertex load sub-arrays */ coarmeshptr->edgetax = coarmeshptr->verttax + coaredgeoftval; #ifdef SCOTCH_DEBUG_MESH2 if (meshCheck (coarmeshptr) != 0) { /* Check mesh consistency */ errorPrint ("meshCoarsen: internal error (7)"); return (2); } #endif /* SCOTCH_DEBUG_MESH2 */ *finecoarptr = finecoartax; /* Return multinode array */ #ifdef SCOTCH_DEBUG_MESH3 fprintf (stderr, "coarvnodnbr=%ld\tcoarvelmnbr=%ld\tcoaredgenbr=%ld, coardegrmax=%ld\n", (long) coarmeshptr->vnodnbr, (long) coarmeshptr->velmnbr, (long) coarmeshptr->edgenbr, (long) coarmeshptr->degrmax); fprintf (stderr, "-------- EXITING COARSENING ---------\n"); /* TODO REMOVE */ #endif /* SCOTCH_DEBUG_MESH3 */ return (0); } /********************************************/ /* */ /* The matching subroutines. In fact, these */ /* are merging routines, which merge */ /* elements of the fine mesh to form larger */ /* elements in the coarse mesh. */ /* New elements are ordered in increasing */ /* order from baseval, while nodes are */ /* ordered in decreasing order from -2, as */ /* -1 is a reserved flag value used */ /* for labelling non yet considered */ /* vertices. */ /* */ /********************************************/ /* This routine performs elements matching by ** selecting the elements that share most nodes ** with the first element. */ static void meshCoarsenMatchNg ( const Mesh * restrict const finemeshptr, /* Fine mesh to perform matching on */ MeshCoarsenMult * restrict const finemulttax, /* Array of fine multielements */ Gnum * restrict const finecoartax, /* Fine to coarse vertex array */ Gnum * restrict const coarvelmptr, /* Pointer to number of coarse element vertices */ Gnum * restrict const coarvnodptr, /* Pointer to (upper bound on) number of coarse node vertices */ Gnum * restrict const coaredgeptr) /* Pointer to (upper bound on) number of edges */ { Gnum coarvelmnum; /* Number of current coarse element vertex */ Gnum finepertbas; /* Index of base of perturbation area */ Gnum finepertnbr; /* Size of perturbation area */ MeshCoarsenNgHash * restrict finehashtab; /* Hash table of neighbor elements */ Gnum finehashsiz; Gnum finehashmsk; Gnum coarvnodnbr; Gnum coaredgenbr; for (finehashmsk = 31, finehashsiz = finemeshptr->degrmax * finemeshptr->degrmax - 1; /* Compute size of hash table */ finehashmsk < finehashsiz; finehashmsk = finehashmsk * 2 + 1) ; finehashsiz = finehashmsk + 1; if ((finehashtab = (MeshCoarsenNgHash *) memAlloc (finehashsiz * sizeof (MeshCoarsenNgHash))) == NULL) { *coarvelmptr = finemeshptr->velmnbr; /* Indicate no coarsening occured */ return; } memSet (finehashtab, ~0, finehashsiz * sizeof (MeshCoarsenNgHash)); finehashmsk = finehashsiz - 1; coarvelmnum = finemeshptr->baseval; /* Start numbering elements in ascending order */ coarvnodnbr = finemeshptr->vnodnbr; coaredgenbr = finemeshptr->edgenbr; if (finemeshptr->velotax != NULL) { /* If fine mesh has element coarsening vertex weights, perform first pass */ Gnum finevelomin; Gnum finevelomax; Gnum finevelmnum; finevelomin = (3 * finemeshptr->velosum) / (5 * finemeshptr->velmnbr); finevelomax = (5 * finemeshptr->velosum) / finemeshptr->velmnbr; for (finevelmnum = finemeshptr->velmbas; finevelmnum < finemeshptr->velmnnd; finevelmnum ++) { Gnum fineeelmnum; Gnum finehelmnum; Gnum finevnisnbr; /* Number of isolated node vertices */ Gnum finehebsnum; /* Hash number of best matching element */ Gnum finevebsnum; /* Number of best matching element */ Gnum finevnbsnbr; /* Number of nodes shared with best element */ if (finecoartax[finevelmnum] != ~0) /* If element already selected */ continue; if (finemeshptr->velotax[finevelmnum] >= finevelomin) { /* If element is large enough, leave it for the second pass */ if (finemeshptr->velotax[finevelmnum] > finevelomax) { /* Except if it is too large, as then it is not matched */ finecoartax[finevelmnum] = coarvelmnum; finemulttax[coarvelmnum].finevelmnum[0] = finemulttax[coarvelmnum].finevelmnum[1] = finevelmnum; fprintf (stderr, "++ %ld %ld\n", (long) finevelmnum, (long) finemeshptr->velotax[finevelmnum]); /* TODO REMOVE */ coarvelmnum ++; /* One more single vertex created */ } continue; } finecoartax[finevelmnum] = coarvelmnum; /* Set vertex as used so that it will not be considered as an end vertex */ finehelmnum = (finevelmnum * MESHCOARSENHASHPRIME) & finehashmsk; finehashtab[finehelmnum].velmnum = finevelmnum; /* Put element in hash table so that number of end vertex is right even for uncoarsened elements */ finehashtab[finehelmnum].velmend = finevelmnum; finehebsnum = finehelmnum; /* Mate is element itself */ finevnbsnbr = 0; /* Will never be selected */ finevnisnbr = 0; /* No isolated node vertices yet */ for (fineeelmnum = finemeshptr->verttax[finevelmnum]; /* For all node neighbors of current element */ fineeelmnum < finemeshptr->vendtax[finevelmnum]; fineeelmnum ++) { Gnum finevnodnum; Gnum fineenodnum; Gnum fineenodnnd; Gnum finevdegval; Gnum finevnbgval; finevnodnum = finemeshptr->edgetax[fineeelmnum]; fineenodnum = finemeshptr->verttax[finevnodnum]; fineenodnnd = finemeshptr->vendtax[finevnodnum]; finevdegval = fineenodnnd - fineenodnum; if (finevdegval == 1) { /* If node is isolated */ finevnisnbr ++; continue; /* Directly skip to next node */ } finevnbgval = (finevdegval == 2) ? 1 : 0; /* If node is a bridge which connects the element to only one other element */ for ( ; fineenodnum < fineenodnnd; fineenodnum ++) { /* For all elements which are neighbors of current node */ Gnum finevelmend; Gnum finehelmend; Gnum finevnngnbr; /* Current number of neigoboring nodes that connect the two elements */ finevelmend = finemeshptr->edgetax[fineenodnum]; if (finecoartax[finevelmend] != ~0) /* If end element vertex already matched, do not consider it */ continue; for (finehelmend = (finevelmend * MESHCOARSENHASHPRIME) & finehashmsk; ; finehelmend = (finehelmend + 1) & finehashmsk) { if (finehashtab[finehelmend].velmnum != finevelmnum) { /* If element neighbor not yet considered */ finevnngnbr = 1; finehashtab[finehelmend].velmnum = finevelmnum; finehashtab[finehelmend].velmend = finevelmend; finehashtab[finehelmend].vnngnbr = finevnngnbr; finehashtab[finehelmend].vnbgnbr = finevnbgval; } else if (finehashtab[finehelmend].velmend == finevelmend) { /* Else if element found */ finevnngnbr = ++ finehashtab[finehelmend].vnngnbr; finehashtab[finehelmend].vnbgnbr += finevnbgval; } else /* Else go on searching */ continue; if (finevnngnbr > finevnbsnbr) { finehebsnum = finehelmend; finevnbsnbr = finevnngnbr; } break; } } } finevebsnum = finehashtab[finehebsnum].velmend; finemulttax[coarvelmnum].finevelmnum[0] = finevelmnum; /* Set matching pair */ finemulttax[coarvelmnum].finevelmnum[1] = finevebsnum; if (finevelmnum != finevebsnum) { /* If a matching element has been found */ finecoartax[finevebsnum] = coarvelmnum; if (finevnisnbr > 0) finevnisnbr --; coarvnodnbr -= finehashtab[finehebsnum].vnbgnbr + finevnisnbr; coaredgenbr -= 2 * finevnisnbr + 4 * finehashtab[finehebsnum].vnbgnbr; } coarvelmnum ++; /* Number nodes in ascending order */ } } for (finepertbas = finemeshptr->velmbas, /* Run cache-friendly perturbation on elements */ finepertnbr = 2 + intRandVal (MESHCOARSENPERTPRIME - 2); /* Compute perturbation area size */ finepertbas < finemeshptr->velmnnd; finepertbas += finepertnbr) { Gnum finepertval; /* Current index in perturbation area */ if (finepertbas + finepertnbr > finemeshptr->velmnnd) finepertnbr = finemeshptr->velmnnd - finepertbas; finepertval = 0; /* Start from first perturbation element vertex */ do { /* Loop on perturbation element vertices */ Gnum finevelmnum; /* Number of currently selected fine element vertex */ Gnum fineeelmnum; Gnum finehelmnum; Gnum finevnisnbr; /* Number of isolated node vertices */ Gnum finehebsnum; /* Hash number of best matching element */ Gnum finevebsnum; /* Number of best matching element */ Gnum finevnbsnbr; /* Number of nodes shared with best element */ finevelmnum = finepertbas + finepertval; /* Compute corresponding elemennt number */ if (finecoartax[finevelmnum] != ~0) /* If element already selected */ continue; finecoartax[finevelmnum] = coarvelmnum; /* Set vertex as used so that it will not be considered as an end vertex */ finehelmnum = (finevelmnum * MESHCOARSENHASHPRIME) & finehashmsk; finehashtab[finehelmnum].velmnum = finevelmnum; /* Put element in hash table so that number of end vertex is right even for uncoarsened elements */ finehashtab[finehelmnum].velmend = finevelmnum; finehebsnum = finehelmnum; /* Mate is element itself */ finevnbsnbr = 0; /* Will never be selected */ finevnisnbr = 0; /* No isolated node vertices yet */ for (fineeelmnum = finemeshptr->verttax[finevelmnum]; /* For all node neighbors of current element */ fineeelmnum < finemeshptr->vendtax[finevelmnum]; fineeelmnum ++) { Gnum finevnodnum; Gnum fineenodnum; Gnum fineenodnnd; Gnum finevdegval; Gnum finevnbgval; finevnodnum = finemeshptr->edgetax[fineeelmnum]; fineenodnum = finemeshptr->verttax[finevnodnum]; fineenodnnd = finemeshptr->vendtax[finevnodnum]; finevdegval = fineenodnnd - fineenodnum; if (finevdegval == 1) { /* If node is isolated */ finevnisnbr ++; continue; /* Directly skip to next node */ } finevnbgval = (finevdegval == 2) ? 1 : 0; /* If node is a bridge which connects the element to only one other element */ for ( ; fineenodnum < fineenodnnd; fineenodnum ++) { /* For all elements which are neighbors of current node */ Gnum finevelmend; Gnum finehelmend; Gnum finevnngnbr; /* Current number of neigoboring nodes that connect the two elements */ finevelmend = finemeshptr->edgetax[fineenodnum]; if (finecoartax[finevelmend] != ~0) /* If end element vertex already matched, do not consider it */ continue; for (finehelmend = (finevelmend * MESHCOARSENHASHPRIME) & finehashmsk; ; finehelmend = (finehelmend + 1) & finehashmsk) { if (finehashtab[finehelmend].velmnum != finevelmnum) { /* If element neighbor not yet considered */ finevnngnbr = 1; finehashtab[finehelmend].velmnum = finevelmnum; finehashtab[finehelmend].velmend = finevelmend; finehashtab[finehelmend].vnngnbr = finevnngnbr; finehashtab[finehelmend].vnbgnbr = finevnbgval; } else if (finehashtab[finehelmend].velmend == finevelmend) { /* Else if element found */ finevnngnbr = ++ finehashtab[finehelmend].vnngnbr; finehashtab[finehelmend].vnbgnbr += finevnbgval; } else /* Else go on searching */ continue; if (finevnngnbr > finevnbsnbr) { finehebsnum = finehelmend; finevnbsnbr = finevnngnbr; } break; } } } finevebsnum = finehashtab[finehebsnum].velmend; finemulttax[coarvelmnum].finevelmnum[0] = finevelmnum; /* Set matching pair */ finemulttax[coarvelmnum].finevelmnum[1] = finevebsnum; if (finevelmnum != finevebsnum) { /* If a matching element has been found */ finecoartax[finevebsnum] = coarvelmnum; if (finevnisnbr > 0) finevnisnbr --; coarvnodnbr -= finehashtab[finehebsnum].vnbgnbr + finevnisnbr; coaredgenbr -= 2 * finevnisnbr + 4 * finehashtab[finehebsnum].vnbgnbr; } coarvelmnum ++; /* Number nodes in ascending order */ } while ((finepertval = (finepertval + MESHCOARSENPERTPRIME) % finepertnbr) != 0); /* Compute next perturbation index */ } memFree (finehashtab); *coarvelmptr = coarvelmnum - finemeshptr->velmbas; *coarvnodptr = coarvnodnbr; *coaredgeptr = coaredgenbr; return; } scotch-6.0.4.dfsg/src/libscotch/library_graph_map_view_f.c0000644002563400244210000001011011631447170027014 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_map_view_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the Fortran API for the **/ /** mapping routines of the libSCOTCH **/ /** library. **/ /** **/ /** DATES : # Version 4.0 : from : 21 nov 2005 **/ /** to 21 nov 2005 **/ /** # Version 5.1 : from : 27 mar 2010 **/ /** to 27 mar 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the mapping routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFGRAPHMAPVIEW, scotchfgraphmapview, ( \ const SCOTCH_Graph * const grafptr, \ const SCOTCH_Mapping * const mapptr, \ int * const fileptr, \ int * const revaptr), \ (grafptr, mapptr, fileptr, revaptr)) { FILE * stream; /* Stream to build from handle */ int filenum; /* Duplicated handle */ int o; if ((filenum = dup (*fileptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFGRAPHMAPVIEW: cannot duplicate handle"); *revaptr = 1; /* Indicate error */ return; } if ((stream = fdopen (filenum, "w")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFGRAPHMAPVIEW: cannot open output stream"); close (filenum); *revaptr = 1; return; } o = SCOTCH_graphMapView (grafptr, mapptr, stream); fclose (stream); /* This closes filenum too */ *revaptr = o; } scotch-6.0.4.dfsg/src/libscotch/kgraph_map_rb.h0000644002563400244210000002214412405520022024572 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph_map_rb.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the Dual Recursive Bipartitioning **/ /** mapping algorithm. **/ /** **/ /** DATES : # Version 0.0 : from : 23 mar 1993 **/ /** to 12 may 1993 **/ /** # Version 1.3 : from : 06 apr 1994 **/ /** to 09 apr 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to 04 nov 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to 30 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 28 sep 1995 **/ /** # Version 3.1 : from : 15 nov 1995 **/ /** to 15 nov 1995 **/ /** # Version 3.2 : from : 01 oct 1996 **/ /** to 10 jun 1998 **/ /** # Version 3.3 : from : 19 oct 1998 **/ /** to 17 may 1999 **/ /** # Version 3.4 : from : 12 sep 2001 **/ /** to 06 nov 2001 **/ /** # Version 4.0 : from : 29 nov 2003 **/ /** to 05 may 2006 **/ /** # Version 5.1 : from : 07 oct 2008 **/ /** to 28 mar 2011 **/ /** # Version 6.0 : from : 07 aug 2014 **/ /** to 24 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ Prime number for hashing terminal domain numbers. +*/ #define KGRAPHMAPRBVFLOHASHPRIME 17 /*+ Prime number for hashing +*/ /*+ Kinds of external edge processing. +*/ #define KGRAPHMAPRBVEEXNONE 0x0000 /* No options set */ #define KGRAPHMAPRBVEEXMAPP 0x0001 /* Graph mapping */ #define KGRAPHMAPRBVEEXVFIX 0x0002 /* Fixed vertices */ #define KGRAPHMAPRBVEEXREMA 0x0004 /* Remapping */ #define KGRAPHMAPRBVEEXEDGE (KGRAPHMAPRBVEEXMAPP | KGRAPHMAPRBVEEXVFIX) #define KGRAPHMAPRBVEEXVERT (KGRAPHMAPRBVEEXREMA) /* ** The type and structure definitions. */ /*+ Job selection policy types. +*/ typedef enum KgraphMapRbPolicy_ { KGRAPHMAPRBPOLIRANDOM = 0, /*+ Random job selection policy +*/ KGRAPHMAPRBPOLILEVEL, /*+ Select job with highest level +*/ KGRAPHMAPRBPOLISIZE, /*+ Select job with largest size +*/ KGRAPHMAPRBPOLINEIGHBOR, /*+ Priority level computed with respect to neighbors +*/ KGRAPHMAPRBPOLINGLEVEL, /*+ Select job with most neighbors of higher level +*/ KGRAPHMAPRBPOLINGSIZE, /*+ Select job with most neighbors of smaller size +*/ KGRAPHMAPRBPOLIOLD /*+ Select job in old style (version 2.x) +*/ } KgraphMapRbPolicy; /*+ Method parameters. +*/ typedef struct KgraphMapRbParam_ { int flagjobtie; /*+ Flag set of job pools are tied +*/ int flagmaptie; /*+ Flag set if mappings are tied +*/ KgraphMapRbPolicy polival; /*+ Job selection policy +*/ Strat * strat; /*+ Bipartitioning strategy used +*/ double kbalval; /*+ K-way imbalance ratio +*/ } KgraphMapRbParam; /*+ This structure holds the data passed to each bipartitioning job. +*/ typedef struct KgraphMapRbData_ { const Graph * grafptr; /*+ Pointer to top-level graph, possibly with fixed vertices +*/ Mapping * mappptr; /*+ Mapping to compute +*/ struct { /*+ Remapping structure +*/ const Mapping * mappptr; /*+ Old mapping (for remapping only) +*/ const Gnum * vmlotax; /*+ Array of vertex migration costs +*/ Gnum cmloval; /*+ Migration edge load for remapping +*/ Gnum crloval; /*+ Regular edge load for mapping +*/ } r; const Anum * pfixtax; /*+ Fixed vertex partition array +*/ const KgraphMapRbParam * paraptr; /*+ Pointer to mapping parameter structure +*/ double comploadrat; /*+ Ideal load balance per weight unit +*/ double comploadmin; /*+ Minimum vertex load per target load +*/ double comploadmax; /*+ Maximum vertex load per target load +*/ } KgraphMapRbData; /*+ Fixed vertex load type. An array of such cells stores the loads of strictly positive fixed vertices (zero ones are discarded) that must be assigned to some subdomain of the current domain to be bipartitioned. +*/ typedef struct KgraphMapRbVflo_ { Anum termnum; /*+ Terminal domain number +*/ Gnum veloval; /*+ Vertex load +*/ } KgraphMapRbVflo; /*+ Hash structure for merging fixed vertex domains with non-fixed vertex domains. +*/ typedef struct KgraphMapRbVfloHash_ { Anum termnum; /*+ Terminal domain number +*/ Anum domnnum; /*+ Domain number in domain array +*/ } KgraphMapRbVfloHash; /* ** The function prototypes. */ #ifndef KGRAPH_MAP_RB #define static #endif int kgraphMapRb (Kgraph * const, const KgraphMapRbParam * const); int kgraphMapRbVfloBuild (const Arch * restrict const, const Graph * restrict const, const Gnum, const Anum * restrict const, Graph * restrict const, Anum * restrict const, KgraphMapRbVflo * restrict * restrict const); void kgraphMapRbVfloSplit (const Arch * restrict const, const ArchDom * restrict const, const Anum, KgraphMapRbVflo * restrict const, Anum * restrict const, Gnum * restrict const); int kgraphMapRbVfloMerge (Mapping * restrict const, const Gnum, const Anum * restrict const, const Anum); int kgraphMapRbBgraph (const KgraphMapRbData * restrict const, Bgraph * restrict const, const Graph * restrict const, const Mapping * restrict const, const ArchDom * restrict const, const Gnum * restrict const); #undef static scotch-6.0.4.dfsg/src/libscotch/bgraph_bipart_fm.c0000644002563400244210000014240412400054124025261 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bgraph_bipart_fm.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module bipartitions an active **/ /** graph using our improvements of the **/ /** Fiduccia-Mattheyses heuristics. **/ /** **/ /** DATES : # Version 1.0 : from : 30 sep 1993 **/ /** to 09 oct 1993 **/ /** # Version 1.1 : from : 15 oct 1993 **/ /** to 15 oct 1993 **/ /** # Version 1.2 : from : 07 feb 1994 **/ /** to 15 feb 1994 **/ /** # Version 1.3 : from : 06 apr 1994 **/ /** to 30 apr 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to 03 nov 1994 **/ /** # Version 3.1 : from : 06 nov 1995 **/ /** to 07 jun 1996 **/ /** # Version 3.2 : from : 21 sep 1996 **/ /** to 13 sep 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 12 mar 1999 **/ /** # Version 3.4 : from : 01 jun 2001 **/ /** to 01 jun 2001 **/ /** # Version 4.0 : from : 20 dec 2003 **/ /** to 05 may 2006 **/ /** # Version 5.0 : from : 24 mar 2008 **/ /** to : 22 may 2008 **/ /** # Version 5.1 : from : 30 oct 2008 **/ /** to : 14 apr 2011 **/ /** # Version 6.0 : from : 23 fev 2011 **/ /** to 09 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define BGRAPH_BIPART_FM #define SCOTCH_TABLE_GAIN #include "module.h" #include "common.h" #include "fibo.h" #include "gain.h" #include "graph.h" #include "arch.h" #include "bgraph.h" #include "bgraph_bipart_fm.h" #include "bgraph_bipart_gg.h" /*********************************/ /* */ /* Gain table handling routines. */ /* */ /*********************************/ #ifdef SCOTCH_TABLE_GAIN /* This routine returns the vertex of best gain ** whose swap will keep the balance correct. ** It returns: ** - !NULL : pointer to the vertex. ** - NULL : if no more vertices available. */ static BgraphBipartFmVertex * bgraphBipartFmTablGet ( BgraphBipartFmTabl * restrict const gainptr, /*+ Gain table +*/ const Gnum deltcur, /*+ Current imbalance +*/ const Gnum deltmin, /*+ Minimum imbalance +*/ const Gnum deltmax) /*+ Maximum imbalance +*/ { GainTabl * tablptr; BgraphBipartFmVertex * vexxptr; BgraphBipartFmVertex * vertbest; Gnum gainbest; const GainEntr * tablbest; Gnum deltbest; tablptr = *gainptr; tablbest = tablptr->tend; /* Assume no candidate vertex found yet */ gainbest = GAINMAX; vertbest = NULL; deltbest = deltmax; for (vexxptr = (BgraphBipartFmVertex *) gainTablFrst (tablptr); /* Select candidate vertices */ (vexxptr != NULL) && (vexxptr->gainlink.tabl < tablbest); vexxptr = (BgraphBipartFmVertex *) gainTablNext (tablptr, &vexxptr->gainlink)) { Gnum deltnew; deltnew = deltcur + vexxptr->compgain; if ((deltnew >= deltmin) && /* If vertex enforces balance */ (deltnew <= deltmax)) { deltnew = abs (deltnew); if ((vexxptr->commgain < gainbest) || /* And if it gives better gain */ ((vexxptr->commgain == gainbest) && /* Or if it gives better load */ (deltnew < deltbest))) { tablbest = vexxptr->gainlink.tabl; /* Select it */ gainbest = vexxptr->commgain; vertbest = vexxptr; deltbest = deltnew; } } } return (vertbest); } #else /* SCOTCH_TABLE_GAIN */ /* bgraphBipartFmCmpFunc(a,b) must return a negative ** number if a is "better" than b. The smaller, the ** better. */ static int bgraphBipartFmCmpFunc ( const FiboNode * const data0ptr, /* TRICK: BgraphBipartFmLink is FIRST in BgraphBipartFmVertex */ const FiboNode * const data1ptr) { const BgraphBipartFmVertex * const node0ptr = (BgraphBipartFmVertex *) data0ptr; const BgraphBipartFmVertex * const node1ptr = (BgraphBipartFmVertex *) data1ptr; if (node0ptr->commgain < node1ptr->commgain) return (-1); if (node0ptr->commgain > node1ptr->commgain) return (1); return (0); } static BgraphBipartFmVertex * bgraphBipartFmTablGet ( BgraphBipartFmTabl * restrict const tablptr, /*+ Gain table +*/ const Gnum deltcur, /*+ Current imbalance +*/ const Gnum deltmin, /*+ Minimum imbalance +*/ const Gnum deltmax) /*+ Maximum imbalance +*/ { FiboNode * remoptr; /* List of removed links */ BgraphBipartFmVertex * vexxptr; BgraphBipartFmVertex * vertbest; Gnum gainbest; Gnum deltbest; FiboNode * linkptr; /* Pointer to current gain link */ gainbest = GAINMAX; vertbest = NULL; deltbest = deltmax; remoptr = NULL; while ((linkptr = fiboTreeMin (tablptr)) != NULL) { /* Select candidate vertices */ Gnum deltnew; Gnum gainval; /* Separator gain of current link */ vexxptr = (BgraphBipartFmVertex *) linkptr; gainval = vexxptr->commgain; if (gainval > gainbest) /* If no more interesting vertices, stop searching */ break; fiboTreeDel (tablptr, linkptr); /* Remove vertex link from table */ linkptr->linkdat.prevptr = remoptr; /* Node has been removed but is not kept */ remoptr = linkptr; /* It will be chained back afterwards */ deltnew = deltcur + vexxptr->compgain; if ((deltnew >= deltmin) && /* If vertex enforces balance */ (deltnew <= deltmax)) { deltnew = abs (deltnew); if (deltnew <= deltbest) { /* If vertex enforces balance */ vertbest = vexxptr; gainbest = gainval; deltbest = deltnew; } } } while (remoptr != NULL) { /* Put back all temporarily removed nodes */ FiboNode * tempptr; tempptr = remoptr; /* Get pointer to node */ remoptr = remoptr->linkdat.prevptr; /* Find next node */ fiboTreeAdd (tablptr, tempptr); /* Re-link node */ } return (vertbest); } #endif /* SCOTCH_TABLE_GAIN */ /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the bipartitioning. ** It returns: ** - 0 : if bipartitioning could be computed. ** - 1 : on error. */ int bgraphBipartFm ( Bgraph * restrict const grafptr, /*+ Active graph +*/ const BgraphBipartFmParam * const paraptr) /*+ Method parameters +*/ { BgraphBipartFmTabl tabldat; /* Gain table */ BgraphBipartFmTabl * tablptr; /* Pointer to gain table */ INT passnbr; /* Maximum number of passes to go */ BgraphBipartFmSave * restrict savetab; /* Pointer to move array */ Gnum movenbr; /* Number of uneffective moves done */ Gnum savenbr; /* Number of recorded backtrack moves */ Gnum mswpnum; /* Current number of recording sweep */ int moveflag; /* Flag set if useful moves made */ int swapval; /* Flag set if global swap performed */ int swapvalbst; /* Recorded swap value for best position */ Gnum hashsiz; /* Size of hash table */ Gnum hashmsk; /* Mask for access to hash table */ Gnum hashnum; /* Hash value */ BgraphBipartFmVertex * lockptr; /* Linked list of locked vertices */ BgraphBipartFmVertex * restrict hashtab; /* Extended vertex array */ Gnum hashmax; Gnum hashnbr; void * hashtmp; /* Temporary variable to avoid "restrict" */ Gnum comploadsum; /* Overall vertex load sum, including fixed */ Gnum compload0dltmit; /* Theoretical smallest imbalance allowed */ Gnum compload0dltmat; /* Theoretical largest imbalance allowed */ Gnum compload0dltmin; /* Smallest imbalance allowed */ Gnum compload0dltmax; /* Largest imbalance allowed */ Gnum compload0dltbst; /* Best imbalance value found to date */ Gnum compload0dlt; /* Current imbalance */ Gnum compsize0dlt; /* Update of size of part 0 */ Gnum commgainextn; /* Current external communication gain */ Gnum commgainextnbst; /* External gain of best recorded position */ Gnum commload; /* Communication load of current position */ Gnum commloadbst; /* Best communication load to date */ Gnum domndist; /* Distance between the two subdomains */ Gnum fronnbr; Gnum fronnum; BgraphBipartFmType typeval; const Gnum * restrict const verttax = grafptr->s.verttax; /* Fast accesses */ const Gnum * restrict const vendtax = grafptr->s.vendtax; const Gnum * restrict const velotax = grafptr->s.velotax; const Gnum * restrict const edgetax = grafptr->s.edgetax; const Gnum * restrict const edlotax = grafptr->s.edlotax; const Gnum * restrict const veextax = grafptr->veextax; comploadsum = grafptr->s.velosum + grafptr->vfixload[0] + grafptr->vfixload[1]; compload0dltmat = (paraptr->deltval <= 0.0L) ? 0 : ((Gnum) ((double) comploadsum * paraptr->deltval / (double) MAX (grafptr->domnwght[0], grafptr->domnwght[1])) + 1); compload0dltmit = MAX ((grafptr->compload0min - grafptr->compload0avg), - compload0dltmat); compload0dltmat = MIN ((grafptr->compload0max - grafptr->compload0avg), compload0dltmat); compload0dltmin = MIN (grafptr->compload0dlt, compload0dltmit); /* Set current maximum distance */ compload0dltmax = MAX (grafptr->compload0dlt, compload0dltmat); typeval = BGRAPHBIPARTFMTYPEBOUNDARY; /* Start by using boundary moves only */ if (grafptr->fronnbr == 0) { /* If no current frontier */ if ((grafptr->compload0dlt >= compload0dltmit) && /* If balance is correct */ (grafptr->compload0dlt <= compload0dltmat)) return (0); /* Nothing to do */ else { /* Imbalance must be fought */ BgraphBipartGgParam paradat; paradat.passnbr = 4; /* Use a standard algorithm */ if (bgraphBipartGg (grafptr, ¶dat) != 0) /* Return if error */ return (1); if (grafptr->fronnbr == 0) /* If new partition has no frontier */ return (0); /* This algorithm is still useless */ compload0dltmin = MIN (compload0dltmit, grafptr->compload0dlt); compload0dltmax = MAX (compload0dltmat, grafptr->compload0dlt); typeval = BGRAPHBIPARTFMTYPEALL; } } #ifdef SCOTCH_DEBUG_BGRAPH2 hashnbr = 2 * grafptr->fronnbr + 1; /* Ensure resizing will be performed, for maximum code coverage */ #else /* SCOTCH_DEBUG_BGRAPH2 */ hashnbr = 4 * (grafptr->fronnbr + paraptr->movenbr + grafptr->s.degrmax); #endif /* SCOTCH_DEBUG_BGRAPH2 */ if (hashnbr > grafptr->s.vertnbr) hashnbr = grafptr->s.vertnbr; if (typeval == BGRAPHBIPARTFMTYPEALL) /* Take maximum space so that hashmax will fit */ hashnbr = grafptr->s.vertnbr * 4; for (hashsiz = 256; hashsiz < hashnbr; hashsiz <<= 1) ; /* Get upper power of two */ hashmsk = hashsiz - 1; hashmax = hashsiz >> 2; if (bgraphBipartFmTablInit (&tabldat) != 0) { errorPrint ("bgraphBipartFm: internal error (1)"); /* Unable to do proper initialization */ bgraphBipartFmTablExit (&tabldat); return (1); } tablptr = &tabldat; if (memAllocGroup ((void **) (void *) &hashtmp, (size_t) (hashsiz * sizeof (BgraphBipartFmVertex)), &savetab, (size_t) (hashsiz * sizeof (BgraphBipartFmSave)), NULL) == NULL) { errorPrint ("bgraphBipartFm: out of memory (1)"); bgraphBipartFmTablExit (tablptr); return (1); } hashtab = hashtmp; memSet (hashtab, ~0, hashsiz * sizeof (BgraphBipartFmVertex)); /* Set all vertex numbers to ~0 */ domndist = grafptr->domndist; if (typeval == BGRAPHBIPARTFMTYPEALL) { Gnum vertnum; for (vertnum = grafptr->s.baseval; vertnum < grafptr->s.vertnnd; vertnum ++) { /* Set initial gains */ Gnum veloval; Gnum hashnum; Gnum edgenum; Gnum edloval; Gnum commcut; Gnum commgain; int partval; int partdlt; partval = grafptr->parttax[vertnum]; for (edgenum = verttax[vertnum], commcut = commgain = 0, edloval = 1; edgenum < vendtax[vertnum]; edgenum ++) { Gnum vertend; int partend; int partdlt; vertend = edgetax[edgenum]; partend = grafptr->parttax[vertend]; if (edlotax != NULL) edloval = edlotax[edgenum]; partdlt = partval ^ partend; commcut += partdlt; commgain += (1 - 2 * partdlt) * edloval; } commgain *= domndist; /* Adjust internal gains with respect to external gains */ partdlt = 2 * partval - 1; veloval = (velotax != NULL) ? velotax[vertnum] : 1; for (hashnum = (vertnum * BGRAPHBIPARTFMHASHPRIME) & hashmsk; hashtab[hashnum].vertnum != ~0; hashnum = (hashnum + 1) & hashmsk) ; hashtab[hashnum].vertnum = vertnum; /* Implicitely set slot as used */ hashtab[hashnum].partval = partval; hashtab[hashnum].compgain = partdlt * veloval; hashtab[hashnum].commgain = (veextax == NULL) ? commgain : (commgain - partdlt * veextax[vertnum]); hashtab[hashnum].commcut = commcut; hashtab[hashnum].mswpnum = 0; /* Implicitely set slot as used */ bgraphBipartFmTablAdd (tablptr, &hashtab[hashnum]); } } else { for (fronnum = 0, hashnbr = grafptr->fronnbr; /* Set initial gains */ fronnum < hashnbr; fronnum ++) { Gnum vertnum; Gnum veloval; Gnum hashnum; Gnum edgenum; Gnum edloval; Gnum commcut; Gnum commgain; int partval; int partdlt; vertnum = grafptr->frontab[fronnum]; partval = grafptr->parttax[vertnum]; for (edgenum = verttax[vertnum], commcut = commgain = 0, edloval = 1; edgenum < vendtax[vertnum]; edgenum ++) { Gnum vertend; int partend; int partdlt; vertend = edgetax[edgenum]; partend = grafptr->parttax[vertend]; if (edlotax != NULL) edloval = edlotax[edgenum]; partdlt = partval ^ partend; commcut += partdlt; commgain += (1 - 2 * partdlt) * edloval; } commgain *= domndist; /* Adjust internal gains with respect to external gains */ partdlt = 2 * partval - 1; veloval = (velotax != NULL) ? velotax[vertnum] : 1; for (hashnum = (vertnum * BGRAPHBIPARTFMHASHPRIME) & hashmsk; hashtab[hashnum].vertnum != ~0; hashnum = (hashnum + 1) & hashmsk) ; hashtab[hashnum].vertnum = vertnum; /* Implicitely set slot as used */ hashtab[hashnum].partval = partval; hashtab[hashnum].compgain = partdlt * veloval; hashtab[hashnum].commgain = (veextax == NULL) ? commgain : (commgain - partdlt * veextax[vertnum]); hashtab[hashnum].commcut = commcut; hashtab[hashnum].mswpnum = 0; /* Implicitely set slot as used */ bgraphBipartFmTablAdd (tablptr, &hashtab[hashnum]); } } compload0dltbst = grafptr->compload0dlt; commloadbst = grafptr->commload; commgainextnbst = grafptr->commgainextn; swapvalbst = 0; /* No global swap performed yet */ #ifdef SCOTCH_DEBUG_BGRAPH2 #ifdef SCOTCH_DEBUG_BGRAPH3 if (bgraphBipartFmCheck (grafptr, hashtab, hashmsk, 0, compload0dltbst, commloadbst, commgainextnbst) != 0) { errorPrint ("bgraphBipartFm: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH3 */ #endif /* SCOTCH_DEBUG_BGRAPH2 */ passnbr = paraptr->passnbr; /* Set remaining number of passes */ savenbr = 0; /* For empty backtrack of first pass */ mswpnum = 0; /* Will be incremented afterwards */ lockptr = NULL; /* Locked list is empty */ do { /* As long as there are improvements */ BgraphBipartFmVertex * vexxptr; while (savenbr -- > 0) { /* Delete exceeding moves */ Gnum hashnum; int partval; hashnum = savetab[savenbr].hashnum; partval = savetab[savenbr].partval; hashtab[hashnum].partval = partval; /* Restore vertex data */ hashtab[hashnum].compgain = savetab[savenbr].compgain; hashtab[hashnum].commgain = savetab[savenbr].commgain; hashtab[hashnum].commcut = savetab[savenbr].commcut; if (bgraphBipartFmIsTabl (&hashtab[hashnum])) { /* If vertex is linked */ bgraphBipartFmTablDel (tablptr, &hashtab[hashnum]); /* Unlink it */ bgraphBipartFmSetFree (&hashtab[hashnum]); /* Set it as free */ } if (bgraphBipartFmIsFree (&hashtab[hashnum]) && (partval == 2)) /* If vertex not locked and in separator */ bgraphBipartFmTablAdd (tablptr, &hashtab[hashnum]); /* Re-link it */ } compload0dlt = compload0dltbst; /* Restore best separator parameters */ commload = commloadbst; commgainextn = commgainextnbst; swapval = swapvalbst; mswpnum ++; /* Forget all recorded moves */ #ifdef SCOTCH_DEBUG_BGRAPH2 #ifdef SCOTCH_DEBUG_BGRAPH3 if (bgraphBipartFmCheck (grafptr, hashtab, hashmsk, swapval, compload0dlt, commload, commgainextn) != 0) { errorPrint ("bgraphBipartFm: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH3 */ #endif /* SCOTCH_DEBUG_BGRAPH2 */ while (lockptr != NULL) { /* For all vertices in locked list */ BgraphBipartFmVertex * vexxptr; vexxptr = lockptr; /* Unlink vertex from list */ lockptr = bgraphBipartFmChainNext (vexxptr); if ((typeval == BGRAPHBIPARTFMTYPEALL) || (vexxptr->commcut > 0)) /* If vertex has cut edges or should be put anyway */ bgraphBipartFmTablAdd (tablptr, vexxptr); /* Put it in table */ else bgraphBipartFmSetFree (vexxptr); /* Set it free anyway */ } moveflag = 0; /* No useful moves made */ movenbr = 0; /* No uneffective moves recorded yet */ savenbr = 0; /* Back up to beginning of table */ while ((movenbr < paraptr->movenbr) && /* As long as we can find effective vertices */ ((vexxptr = (BgraphBipartFmVertex *) bgraphBipartFmTablGet (tablptr, compload0dlt, compload0dltmin, compload0dltmax)) != NULL)) { Gnum vertnum; /* Number of current vertex */ int partval; /* Part of current vertex */ Gnum edgenum; Gnum edloval; bgraphBipartFmTablDel (tablptr, vexxptr); /* Remove it from table */ bgraphBipartFmSetUsed (vexxptr); /* Mark it as used */ bgraphBipartFmChain (&lockptr, vexxptr); /* Lock it */ vertnum = vexxptr->vertnum; partval = vexxptr->partval; if (vexxptr->mswpnum != mswpnum) { /* If vertex data not yet recorded */ vexxptr->mswpnum = mswpnum; savetab[savenbr].hashnum = vexxptr - hashtab; savetab[savenbr].partval = partval; savetab[savenbr].compgain = vexxptr->compgain; savetab[savenbr].commgain = vexxptr->commgain; savetab[savenbr].commcut = vexxptr->commcut; savenbr ++; /* One more move recorded */ } movenbr ++; /* One more move done */ commload += vexxptr->commgain; compload0dlt += vexxptr->compgain; if (veextax != NULL) commgainextn += 2 * (2 * partval - 1) * veextax[vertnum]; vexxptr->partval = partval ^ 1; /* Swap vertex first in case neighbors are added */ vexxptr->compgain = - vexxptr->compgain; vexxptr->commgain = - vexxptr->commgain; vexxptr->commcut = vendtax[vertnum] - verttax[vertnum] - vexxptr->commcut; edloval = 1; for (edgenum = verttax[vertnum]; /* (Re-)link neighbors */ edgenum < vendtax[vertnum]; edgenum ++) { Gnum vertend; /* Number of current end neighbor vertex */ Gnum hashnum; vertend = edgetax[edgenum]; if (edlotax != NULL) edloval = edlotax[edgenum]; for (hashnum = (vertend * BGRAPHBIPARTFMHASHPRIME) & hashmsk; ; hashnum = (hashnum + 1) & hashmsk) { if (hashtab[hashnum].vertnum == vertend) { /* If hash slot found */ int partdlt; if (hashtab[hashnum].mswpnum != mswpnum) { /* If vertex data not yet recorded */ savetab[savenbr].hashnum = hashnum; /* Record them */ savetab[savenbr].partval = hashtab[hashnum].partval; savetab[savenbr].compgain = hashtab[hashnum].compgain; savetab[savenbr].commgain = hashtab[hashnum].commgain; savetab[savenbr].commcut = hashtab[hashnum].commcut; hashtab[hashnum].mswpnum = mswpnum; savenbr ++; } partdlt = 2 * (partval ^ hashtab[hashnum].partval) - 1; hashtab[hashnum].commgain += (domndist * 2) * edloval * partdlt; hashtab[hashnum].commcut -= partdlt; if (! bgraphBipartFmIsUsed(&hashtab[hashnum])) { /* If vertex is of use */ if (bgraphBipartFmIsTabl(&hashtab[hashnum])) { /* If vertex is linked */ bgraphBipartFmTablDel (tablptr, &hashtab[hashnum]); /* Remove it from table */ bgraphBipartFmSetFree (&hashtab[hashnum]); /* Mark it as free anyway */ } if (hashtab[hashnum].commcut > 0) /* If vertex belongs to the frontier */ bgraphBipartFmTablAdd (tablptr, &hashtab[hashnum]); /* Re-link it */ } break; } if (hashtab[hashnum].vertnum == ~0) { /* If hash slot empty */ Gnum commgain; /* Communication gain of current vertex */ Gnum commgainold; /* Old communication gain of current vertex */ Gnum veloval; Gnum veexval; int partold; int partdlt; if (hashnbr >= hashmax) { /* If extended vertex table is already full */ if (bgraphBipartFmResize (&hashtab, &hashmax, &hashmsk, &savetab, savenbr, tablptr, &lockptr) != 0) { errorPrint ("bgraphBipartFm: out of memory (2)"); memFree (hashtab); /* Free group leader */ bgraphBipartFmTablExit (tablptr); } for (hashnum = (vertend * BGRAPHBIPARTFMHASHPRIME) & hashmsk; hashtab[hashnum].vertnum != ~0; hashnum = (hashnum + 1) & hashmsk) ; /* Search for new first free slot */ } if (edlotax != NULL) { /* If graph edges are weighted */ Gnum edgeend; for (edgeend = verttax[vertend], commgainold = 0; /* Compute neighbor edge load sum */ edgeend < vendtax[vertend]; edgeend ++) commgainold += edlotax[edgeend]; commgain = commgainold - 2 * edloval; } else { /* Graph edges are not weighted */ commgainold = vendtax[vertend] - verttax[vertend]; commgain = commgainold - 2; } veloval = 1; if (velotax != NULL) veloval = velotax[vertend]; veexval = 0; if (veextax != NULL) veexval = veextax[vertend]; #ifdef SCOTCH_DEBUG_BGRAPH2 if (grafptr->parttax[vertend] != (partval ^ swapval)) { errorPrint ("bgraphBipartFm: internal error (4)"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH2 */ partold = partval ^ swapval ^ swapvalbst; /* Get part of vertex as in latest accepted configuration */ partdlt = 2 * partold - 1; /* Compute values to fill save table according to last stable configuration */ savetab[savenbr].hashnum = hashnum; /* Record initial state of new vertex */ savetab[savenbr].partval = partold; savetab[savenbr].compgain = partdlt * veloval; savetab[savenbr].commgain = commgainold * domndist - (partdlt * veexval); savetab[savenbr].commcut = 0; savenbr ++; partdlt = 2 * partval - 1; /* Compute values to fill hash table according to current configuration */ hashtab[hashnum].vertnum = vertend; hashtab[hashnum].partval = partval; /* It was a neighbor of the moved vertex, in current global swap state */ hashtab[hashnum].compgain = partdlt * veloval; hashtab[hashnum].commgain = commgain * domndist - (partdlt * veexval); hashtab[hashnum].commcut = 1; hashtab[hashnum].mswpnum = mswpnum; /* Vertex has just been saved */ hashnbr ++; /* One more vertex in hash table */ bgraphBipartFmTablAdd (tablptr, &hashtab[hashnum]); break; } } } if (commload < commloadbst) { /* If move improves the cost */ compload0dltbst = compload0dlt; /* This move was effective */ commloadbst = commload; commgainextnbst = commgainextn; swapvalbst = swapval; moveflag = 1; movenbr = savenbr = 0; mswpnum ++; } else if (commload == commloadbst) { if (abs (compload0dlt) < abs (compload0dltbst)) { compload0dltbst = compload0dlt; /* This move was effective */ commgainextnbst = commgainextn; swapvalbst = swapval; moveflag = 1; movenbr = savenbr = 0; mswpnum ++; } else if (abs (compload0dlt) == abs (compload0dltbst)) { compload0dltbst = compload0dlt; /* Forget backtracking */ commgainextnbst = commgainextn; swapvalbst = swapval; savenbr = 0; mswpnum ++; } } if ((compload0dltmin < compload0dltmit) || /* If must restrict distance bounds */ (compload0dltmax > compload0dltmat)) { if ((compload0dlt > compload0dltmin) && /* If we have done something useful */ (compload0dlt < compload0dltmax)) { compload0dltmin = MIN (compload0dltmit, compload0dlt); /* Update bounds */ compload0dltmax = MAX (compload0dltmat, compload0dlt); compload0dltbst = compload0dlt; /* Record best move done */ commloadbst = commload; commgainextnbst = commgainextn; swapvalbst = swapval; moveflag = 1; movenbr = savenbr = 0; mswpnum ++; } } #ifdef SCOTCH_DEBUG_BGRAPH2 #ifdef SCOTCH_DEBUG_BGRAPH3 if (bgraphBipartFmCheck (grafptr, hashtab, hashmsk, swapval, compload0dlt, commload, commgainextn) != 0) { errorPrint ("bgraphBipartFm: internal error (5)"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH3 */ #endif /* SCOTCH_DEBUG_BGRAPH2 */ if (commgainextn < 0) { /* If global swap improves gain */ Gnum compload0dlttmp; #ifdef SCOTCH_DEBUG_BGRAPH2 if (veextax == NULL) { /* commgainextn should always be 0 if (veextab == NULL) */ errorPrint ("bgraphBipartFm: internal error (6)"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH2 */ compload0dlttmp = grafptr->s.velosum - compload0dlt - 2 * grafptr->compload0avg; if (abs (compload0dlttmp) <= compload0dltmax) { /* If still within bounds, perform actual swapping */ Gnum hashnum; commload += commgainextn; /* Perform global swap */ commgainextn = - commgainextn; compload0dlt = compload0dlttmp; swapval ^= 1; for (hashnum = 0; hashnum <= hashmsk; hashnum ++) { /* hashsiz no longer valid after resizing, so use hashmsk */ Gnum commgain; if (hashtab[hashnum].mswpnum == ~0) /* If hash slot not used, skip it */ continue; if (hashtab[hashnum].mswpnum != mswpnum) { /* And vertex data not yet recorded */ hashtab[hashnum].mswpnum = mswpnum; /* Record them */ savetab[savenbr].hashnum = hashnum; savetab[savenbr].partval = hashtab[hashnum].partval; savetab[savenbr].compgain = hashtab[hashnum].compgain; savetab[savenbr].commgain = hashtab[hashnum].commgain; savetab[savenbr].commcut = hashtab[hashnum].commcut; savenbr ++; } hashtab[hashnum].partval ^= 1; /* Swap the vertex */ hashtab[hashnum].compgain = - hashtab[hashnum].compgain; commgain = veextax[hashtab[hashnum].vertnum]; if (commgain != 0) { /* If vertex has external cocycle edges */ hashtab[hashnum].commgain += 2 * (1 - 2 * hashtab[hashnum].partval) * commgain; /* Compute new gain */ if (bgraphBipartFmIsTabl (&hashtab[hashnum])) { /* If vertex is linked */ bgraphBipartFmTablDel (tablptr, &hashtab[hashnum]); /* Remove it from table */ bgraphBipartFmTablAdd (tablptr, &hashtab[hashnum]); /* Re-link it */ } } } if ((commload < commloadbst) || /* If move improves cost */ ((commload == commloadbst) && (abs (compload0dlt) < abs (compload0dltbst)))) { compload0dltbst = compload0dlt; /* Then record best move done */ commloadbst = commload; commgainextnbst = commgainextn; swapvalbst = swapval; moveflag = 1; movenbr = savenbr = 0; mswpnum ++; } #ifdef SCOTCH_DEBUG_BGRAPH2 #ifdef SCOTCH_DEBUG_BGRAPH3 if (bgraphBipartFmCheck (grafptr, hashtab, hashmsk, swapval, compload0dlt, commload, commgainextn) != 0) { errorPrint ("bgraphBipartFm: internal error (7)"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH3 */ #endif /* SCOTCH_DEBUG_BGRAPH2 */ } } } } while ((moveflag != 0) && /* As long as vertices are moved */ (-- passnbr != 0)); /* And we are allowed to loop (TRICK for negative values) */ #ifdef SCOTCH_DEBUG_BGRAPH2 #ifdef SCOTCH_DEBUG_BGRAPH3 if (bgraphBipartFmCheck (grafptr, hashtab, hashmsk, swapval, compload0dlt, commload, commgainextn) != 0) { errorPrint ("bgraphBipartFm: internal error (8)"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH3 */ #endif /* SCOTCH_DEBUG_BGRAPH2 */ compsize0dlt = 0; /* No difference to number of vertices yet */ if (swapvalbst != 0) { /* If global swap needed */ Gnum vertnum; compsize0dlt = grafptr->s.vertnbr - 2 * grafptr->compsize0; /* Set difference so as to swap all vertices */ for (vertnum = grafptr->s.baseval; vertnum < grafptr->s.vertnnd; vertnum ++) /* Swap all vertices in part array */ grafptr->parttax[vertnum] ^= 1; } while (savenbr -- > 0) { /* Delete exceeding moves */ Gnum hashnum; hashnum = savetab[savenbr].hashnum; hashtab[hashnum].partval = savetab[savenbr].partval; /* Restore vertex data */ hashtab[hashnum].commcut = savetab[savenbr].commcut; } compload0dlt = compload0dltbst; /* Restore best separator parameters */ commload = commloadbst; commgainextn = commgainextnbst; for (hashnum = fronnbr = 0; /* Build new frontier */ hashnum <= hashmsk; hashnum ++) { /* hashsiz no longer valid after resizing, so use hashmsk */ Gnum vertnum; int partval; vertnum = hashtab[hashnum].vertnum; /* Get vertex data from slot */ if (vertnum == ~0) continue; partval = hashtab[hashnum].partval; if (grafptr->parttax[vertnum] != partval) { /* If vertex part changed */ grafptr->parttax[vertnum] = partval; /* Set new part value */ compsize0dlt += (1 - 2 * partval); /* Adjust size of part 0 accordingly */ } if (hashtab[hashnum].commcut > 0) /* If vertex belongs to cut */ grafptr->frontab[fronnbr ++] = vertnum; /* Add vertex to frontier */ } grafptr->fronnbr = fronnbr; grafptr->compload0 = compload0dlt + grafptr->compload0avg; grafptr->compload0dlt = compload0dlt; grafptr->compsize0 += compsize0dlt; grafptr->commload = commload; grafptr->commgainextn = commgainextn; grafptr->bbalval = (double) ((grafptr->compload0dlt < 0) ? (- grafptr->compload0dlt) : grafptr->compload0dlt) / (double) grafptr->compload0avg; #ifdef SCOTCH_DEBUG_BGRAPH2 if (bgraphCheck (grafptr) != 0) { errorPrint ("bgraphBipartFm: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH2 */ memFree (hashtab); /* Free group leader */ bgraphBipartFmTablExit (tablptr); return (0); } /* This routine doubles the size all of the arrays ** involved in handling the hash table and hash ** vertex arrays. ** It returns: ** - 0 : if resizing succeeded. ** - !0 : if out of memory. */ static int bgraphBipartFmResize ( BgraphBipartFmVertex * restrict * hashtabptr, /*+ Extended vertex array +*/ Gnum * restrict const hashmaxptr, /*+ Size of vertex array +*/ Gnum * const hashmskptr, /*+ Pointer to hash table mask +*/ BgraphBipartFmSave * restrict * savetabptr, /*+ Move array +*/ const Gnum savenbr, /*+ Number of moves recorded +*/ BgraphBipartFmTabl * tablptr, /*+ Gain table +*/ BgraphBipartFmVertex ** const lockptr) /*+ Pointer to locked list +*/ { BgraphBipartFmVertex * restrict hashtab; /* Extended vertex array */ BgraphBipartFmSave * savetab; /* Move backtracking array */ BgraphBipartFmSave * saveold; /* Pointer to translated old save array */ Gnum savenum; Gnum hashold; /* Size of old hash table (half of new) */ Gnum hashsiz; Gnum hashmax; Gnum hashmsk; Gnum hashsta; /* Start index of range of hash indices to move */ Gnum hashend; /* End index of range of hash indices to move */ Gnum hashnum; hashmax = *hashmaxptr << 1; /* Compute new sizes */ hashold = *hashmaxptr << 2; hashsiz = *hashmaxptr << 3; hashmsk = hashsiz - 1; #ifdef SCOTCH_DEBUG_BGRAPH2 if (sizeof (BgraphBipartFmVertex) < sizeof (BgraphBipartFmSave)) { /* Should always be true */ errorPrint ("bgraphBipartFmResize: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH2 */ if (memReallocGroup ((void *) *hashtabptr, &hashtab, (size_t) (hashsiz * sizeof (BgraphBipartFmVertex)), &savetab, (size_t) (hashsiz * sizeof (BgraphBipartFmSave)), NULL) == NULL) { errorPrint ("bgraphBipartFmResize: out of memory"); return (1); } saveold = (BgraphBipartFmSave *) ((byte *) hashtab + ((byte *) *savetabptr - (byte *) *hashtabptr)); for (savenum = savenbr - 1; savenum >= 0; savenum --) { /* Move save array, in reverse order */ savetab[savenum].commcut = saveold[savenum].commcut; savetab[savenum].commgain = saveold[savenum].commgain; savetab[savenum].compgain = saveold[savenum].compgain; savetab[savenum].partval = saveold[savenum].partval; savetab[savenum].hashnum = hashtab[saveold[savenum].hashnum].vertnum; /* Temporarily translate from hash index to number */ } *hashtabptr = hashtab; *hashmaxptr = hashmax; *hashmskptr = hashmsk; *savetabptr = savetab; memSet (hashtab + hashold, ~0, hashold * sizeof (BgraphBipartFmVertex)); bgraphBipartFmTablFree (tablptr); /* Reset gain table */ *lockptr = NULL; /* Rebuild lock list */ for (hashsta = hashold - 1; hashtab[hashsta].vertnum != ~0; hashsta --) ; /* Start index of first segment to reconsider is last empty slot */ hashend = hashold; /* First segment to reconsider ends at the end of the old array */ while (hashend != hashsta) { /* For each of the two segments to consider */ for (hashnum = hashsta; hashnum < hashend; hashnum ++) { /* Re-compute position of vertices in new table */ Gnum vertnum; vertnum = hashtab[hashnum].vertnum; if (vertnum != ~0) { /* If hash slot used */ Gnum hashnew; for (hashnew = (vertnum * BGRAPHBIPARTFMHASHPRIME) & hashmsk; ; hashnew = (hashnew + 1) & hashmsk) { if (hashnew == hashnum) /* If hash slot is the same */ break; /* There is nothing to do */ if (hashtab[hashnew].vertnum == ~0) { /* If new slot is empty */ #ifdef SCOTCH_DEBUG_BGRAPH2 if ((hashnew > hashnum) && (hashnew < hashend)) { /* If vertex is not moved either before its old position or after the end of the segment */ errorPrint ("bgraphBipartFmResize: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH2 */ hashtab[hashnew] = hashtab[hashnum]; /* Copy data to new slot */ hashtab[hashnum].mswpnum = ~0; /* TRICK: not tested at creation */ hashtab[hashnum].vertnum = ~0; /* Make old slot empty */ break; } } if (bgraphBipartFmIsTabl (&hashtab[hashnew])) /* If vertex was linked, re-link it */ bgraphBipartFmTablAdd (tablptr, &hashtab[hashnew]); else if (bgraphBipartFmIsUsed (&hashtab[hashnew])) /* Re-lock used vertices */ bgraphBipartFmChain (lockptr, &hashtab[hashnew]); /* Lock it */ } } hashend = hashsta; /* End of second segment to consider is start of first one */ hashsta = 0; /* Start of second segment is beginning of array */ } /* After second segment, hashsta = hashend = 0 and loop stops */ for (savenum = 0; savenum < savenbr; savenum ++) { Gnum vertnum; Gnum hashnum; vertnum = savetab[savenum].hashnum; /* Get vertex number temporarily saved */ for (hashnum = (vertnum * BGRAPHBIPARTFMHASHPRIME) & hashmsk; hashtab[hashnum].vertnum != vertnum; hashnum = (hashnum + 1) & hashmsk) { #ifdef SCOTCH_DEBUG_BGRAPH2 if (hashtab[hashnum].vertnum == ~0) { errorPrint ("bgraphBipartFmResize: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH2 */ } savetab[savenum].hashnum = hashnum; /* Set new hash table index */ } return (0); } /* This routine checks the consistency of ** the hash structures. ** It returns: ** - 0 : in case of success. ** - !0 : in case of error. */ #ifdef SCOTCH_DEBUG_BGRAPH3 static int bgraphBipartFmCheck ( const Bgraph * restrict const grafptr, const BgraphBipartFmVertex * restrict const hashtab, const Gnum hashmsk, const int swapval, const Gnum compload0dlt, const Gnum commload, const Gnum commgainextn) { Gnum domndist; Gnum hashnum; Gnum compload0tmp; Gnum commloaddlttmp; /* Difference between old and current communication load */ Gnum commloadextndlttmp; Gnum commgainextntmp; domndist = grafptr->domndist; compload0tmp = (swapval == 0) ? grafptr->compload0 : (grafptr->s.velosum - grafptr->compload0); commloaddlttmp = 0; /* No difference yet */ commloadextndlttmp = swapval * grafptr->commgainextn; commgainextntmp = (1 - 2 * swapval) * grafptr->commgainextn; for (hashnum = 0; hashnum <= hashmsk; hashnum ++) { /* For all vertex slots */ Gnum vertnum; Gnum veloval; Gnum veexval; Gnum edgenum; int partval; int partold; Gnum commcut; Gnum commgain; Gnum commgainextn; vertnum = hashtab[hashnum].vertnum; if (vertnum == ~0) /* If unallocated slot */ continue; /* Skip to next slot */ veloval = (velotax != NULL) ? velotax[vertnum] : 1; partval = hashtab[hashnum].partval; if ((partval < 0) || (partval > 1)) { errorPrint ("bgraphBipartFmCheck: invalid vertex part value"); return (1); } if (hashtab[hashnum].compgain != (2 * partval - 1) * veloval) { errorPrint ("bgraphBipartFmCheck: invalid vertex computation gain"); return (1); } partold = grafptr->parttax[vertnum] ^ swapval; veexval = (veextax != NULL) ? veextax[vertnum] : 0; compload0tmp += (partval ^ partold) * (1 - 2 * partval) * veloval; commgainextn = (1 - 2 * partval) * veexval; commgainextntmp += (partval ^ partold) * commgainextn * 2; commloadextndlttmp -= (partval ^ partold) * commgainextn; commcut = commgain = 0; for (edgenum = verttax[vertnum]; /* For all neighbors */ edgenum < vendtax[vertnum]; edgenum ++) { Gnum edloval; Gnum vertend; Gnum hashend; int partend; int partond; int partdlt; vertend = edgetax[edgenum]; partond = grafptr->parttax[vertend] ^ swapval; edloval = (edlotax != NULL) ? edlotax[edgenum] : 1; for (hashend = (vertend * BGRAPHBIPARTFMHASHPRIME) & hashmsk; ; hashend = (hashend + 1) & hashmsk) { if (hashtab[hashend].vertnum == vertend) { /* If end vertex found */ partend = hashtab[hashend].partval; break; } if (hashtab[hashend].vertnum == ~0) { /* If end vertex not present */ partend = partond; /* Keep old end part */ break; } } partdlt = partval ^ partend; commcut += partdlt; commgain += (1 - 2 * partdlt) * edloval; commloaddlttmp += (partdlt - (partold ^ partond)) * edloval; /* Will account twice for difference of edge loads */ } if (commcut != hashtab[hashnum].commcut) { errorPrint ("bgraphBipartFmCheck: invalid vertex cut value"); return (1); } if ((commgain * domndist + commgainextn) != hashtab[hashnum].commgain) { errorPrint ("bgraphBipartFmCheck: invalid vertex communication gain value"); return (1); } } if ((compload0tmp - grafptr->compload0avg) != compload0dlt) { errorPrint ("bgraphBipartFmCheck: invalid computation load"); return (1); } if ((grafptr->commload + (commloaddlttmp / 2) * domndist) != (commload - commloadextndlttmp)) { errorPrint ("bgraphBipartFmCheck: invalid communication load"); return (1); } if (commgainextntmp != commgainextn) { errorPrint ("bgraphBipartFmCheck: invalid external communication gain"); return (1); } return (0); } #endif /* SCOTCH_DEBUG_BGRAPH3 */ scotch-6.0.4.dfsg/src/libscotch/library_dgraph_scatter.c0000644002563400244210000000677612056000074026526 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_scatter.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the distri- **/ /** buted source graph handling routines of **/ /** the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 28 apr 2006 **/ /** to 12 jul 2007 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "graph.h" #include "dgraph.h" #include "ptscotch.h" /************************************/ /* */ /* These routines are the C API for */ /* the graph handling routines. */ /* */ /************************************/ /*+ This routine scatters the data of a *** centralized graph on a distributed graph. *** It returns: *** - 0 : if the scattering succeeded. *** - !0 : on error. +*/ int SCOTCH_dgraphScatter ( SCOTCH_Dgraph * const dgrfptr, const SCOTCH_Graph * const cgrfptr) { const Graph * srccgrfptr; srccgrfptr = (((void *) cgrfptr) == ((void *) dgrfptr)) ? NULL : (const Graph *) cgrfptr; /* Consider same pointers as flag for non-root process */ return (dgraphScatter ((Dgraph *) dgrfptr, srccgrfptr)); } scotch-6.0.4.dfsg/src/libscotch/bgraph_bipart_fm.h0000644002563400244210000002574511660506652025315 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bgraph_bipart_fm.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for our Improved Fiduccia-Mattheyses **/ /** bipartitioning algorithm. **/ /** **/ /** DATES : # Version 1.0 : from : 30 sep 1993 **/ /** to 09 oct 1993 **/ /** # Version 1.1 : from : 15 oct 1993 **/ /** to 15 oct 1993 **/ /** # Version 1.3 : from : 06 apr 1994 **/ /** to 13 apr 1994 **/ /** # Version 2.0 : from : 04 jul 1994 **/ /** to 25 nov 1994 **/ /** # Version 3.0 : from : 06 jul 1995 **/ /** to 06 jul 1995 **/ /** # Version 3.1 : from : 06 nov 1995 **/ /** to 07 jun 1996 **/ /** # Version 3.2 : from : 21 sep 1996 **/ /** to 13 sep 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 12 mar 1999 **/ /** # Version 4.0 : from : 27 aug 2004 **/ /** to 27 aug 2004 **/ /** # Version 6.0 : from : 23 fev 2011 **/ /** to 05 sep 2011 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ Prime number for hashing vertex numbers. +*/ #define BGRAPHBIPARTFMHASHPRIME 17 /*+ Prime number for hashing +*/ /* ** The type and structure definitions. */ /*+ Move type. +*/ typedef enum BgraphBipartFmType_ { BGRAPHBIPARTFMTYPEALL, /*+ All vertices +*/ BGRAPHBIPARTFMTYPEBOUNDARY /*+ Boundary vertices only +*/ } BgraphBipartFmType; /*+ This structure holds the method parameters. +*/ typedef struct BgraphBipartFmParam_ { INT movenbr; /*+ Maximum number of uneffective moves that can be done +*/ INT passnbr; /*+ Number of passes to be performed (-1 : infinite) +*/ double deltval; /*+ Maximum weight imbalance ratio +*/ BgraphBipartFmType typeval; /*+ Whether considered vertices are boundary or all +*/ } BgraphBipartFmParam; #ifdef BGRAPH_BIPART_FM /* Private part of the module */ /*+ The hash vertex structure. For trick reasons, the gain table data structure must be the first field of the structure. +*/ #ifdef SCOTCH_TABLE_GAIN typedef GainTabl * BgraphBipartFmTabl; typedef GainLink BgraphBipartFmLink; #else /* SCOTCH_TABLE_GAIN */ typedef FiboTree BgraphBipartFmTabl; typedef FiboNode BgraphBipartFmLink; #endif /* SCOTCH_TABLE_GAIN */ typedef struct BgraphBipartFmVertex_ { BgraphBipartFmLink gainlink; /*+ Gain link: FIRST +*/ Gnum vertnum; /*+ Number of vertex +*/ int partval; /*+ Vertex part +*/ Gnum compgain; /*+ Computation gain +*/ Gnum commgain; /*+ Communication gain +*/ Gnum commcut; /*+ Cut edges +*/ Gnum mswpnum; /*+ Number of move sweep when data recorded +*/ } BgraphBipartFmVertex; /*+ The move recording structure. +*/ typedef struct BgraphBipartFmSave_ { Gnum hashnum; /*+ Number of vertex slot +*/ int partval; /*+ Vertex part +*/ Gnum compgain; /*+ Computation gain +*/ Gnum commgain; /*+ Communication gain +*/ Gnum commcut; /*+ Cut edges +*/ } BgraphBipartFmSave; /* ** The function prototypes. */ static BgraphBipartFmVertex * bgraphBipartFmTablGet (BgraphBipartFmTabl * restrict const, const Gnum, const Gnum, const Gnum); static int bgraphBipartFmResize (BgraphBipartFmVertex * restrict *, Gnum * restrict const, Gnum * const, BgraphBipartFmSave * restrict *, const Gnum, BgraphBipartFmTabl * const, BgraphBipartFmVertex ** const); #ifdef SCOTCH_DEBUG_BGRAPH3 static int bgraphBipartFmCheck (const Bgraph * restrict const, const BgraphBipartFmVertex * restrict const, const Gnum, const int, const Gnum, const Gnum, const Gnum); #endif /* SCOTCH_DEBUG_BGRAPH3 */ #endif /* BGRAPH_BIPART_FM */ int bgraphBipartFm (Bgraph * restrict const, const BgraphBipartFmParam * const); /* ** The macro definitions. */ #ifdef SCOTCH_TABLE_GAIN /*+ Gain table subbits. +*/ #define BGRAPHBIPARTFMSUBBITS 4 /** Gain table vertex status. **/ #define BGRAPHBIPARTFMSTATEFREE ((GainLink *) 0) /*+ Vertex in initial state +*/ #define BGRAPHBIPARTFMSTATEUSED ((GainLink *) 1) /*+ Swapped vertex +*/ #define BGRAPHBIPARTFMSTATELINK ((GainLink *) 2) /*+ Currently in gain table if higher +*/ /*+ Service routines. +*/ #define bgraphBipartFmTablInit(t) (((*(t)) = gainTablInit (GAINMAX, BGRAPHBIPARTFMSUBBITS)) == NULL) #define bgraphBipartFmTablFree(t) gainTablFree (*(t)) #define bgraphBipartFmTablExit(t) do { \ if (*(t) != NULL) \ gainTablExit (*(t)); \ } while (0) #define bgraphBipartFmTablAdd(t,v) gainTablAdd ((*(t)), &(v)->gainlink, (v)->commgain) #define bgraphBipartFmTablDel(t,v) gainTablDel ((*(t)), &(v)->gainlink) #define bgraphBipartFmIsFree(v) ((v)->gainlink.next == BGRAPHBIPARTFMSTATEFREE) #define bgraphBipartFmIsTabl(v) ((v)->gainlink.next >= BGRAPHBIPARTFMSTATELINK) #define bgraphBipartFmIsUsed(v) ((v)->gainlink.next == BGRAPHBIPARTFMSTATEUSED) #define bgraphBipartFmSetFree(v) do { \ (v)->gainlink.next = BGRAPHBIPARTFMSTATEFREE; \ } while (0) #define bgraphBipartFmSetUsed(v) do { \ (v)->gainlink.next = BGRAPHBIPARTFMSTATEUSED; \ } while (0) #define bgraphBipartFmChain(l,v) do { \ (v)->gainlink.prev = (GainLink *) *(l); \ *(l) = (v); \ } while (0) #define bgraphBipartFmChainNext(v) ((BgraphBipartFmVertex *) (v)->gainlink.prev) #else /* SCOTCH_TABLE_GAIN */ /** Gain table vertex status. **/ #define BGRAPHBIPARTFMSTATEFREE ((FiboNode *) 0) /*+ Vertex in initial state +*/ #define BGRAPHBIPARTFMSTATEUSED ((FiboNode *) 1) /*+ Swapped vertex +*/ #define BGRAPHBIPARTFMSTATELINK ((FiboNode *) 2) /*+ Currently in gain table if higher +*/ /*+ Service routines. +*/ #define bgraphBipartFmTablInit(t) (fiboTreeInit ((t), bgraphBipartFmCmpFunc)) #define bgraphBipartFmTablFree(t) fiboTreeFree (t) #define bgraphBipartFmTablExit(t) fiboTreeExit (t) #define bgraphBipartFmTablAdd(t,v) fiboTreeAdd ((t), &(v)->gainlink) #define bgraphBipartFmTablDel(t,v) fiboTreeDel ((t), &(v)->gainlink) #define bgraphBipartFmIsFree(v) ((v)->gainlink.linkdat.nextptr == BGRAPHBIPARTFMSTATEFREE) #define bgraphBipartFmIsTabl(v) ((v)->gainlink.linkdat.nextptr >= BGRAPHBIPARTFMSTATELINK) #define bgraphBipartFmIsUsed(v) ((v)->gainlink.linkdat.nextptr == BGRAPHBIPARTFMSTATEUSED) #define bgraphBipartFmSetFree(v) do { \ (v)->gainlink.linkdat.nextptr = BGRAPHBIPARTFMSTATEFREE; \ } while (0) #define bgraphBipartFmSetUsed(v) do { \ (v)->gainlink.linkdat.nextptr = BGRAPHBIPARTFMSTATEUSED; \ } while (0) #define bgraphBipartFmChain(l,v) do { \ (v)->gainlink.linkdat.prevptr = (FiboNode *) *(l); \ *(l) = (v); \ } while (0) #define bgraphBipartFmChainNext(v) ((BgraphBipartFmVertex *) (v)->gainlink.linkdat.prevptr) #endif /* SCOTCH_TABLE_GAIN */ scotch-6.0.4.dfsg/src/libscotch/hdgraph_gather.c0000644002563400244210000005247012054775745024775 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hdgraph_gather.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the routine which **/ /** builds a centralized halo graph by **/ /** gathering the pieces of a distributed **/ /** halo graph. **/ /** **/ /** DATES : # Version 5.0 : from : 19 apr 2006 **/ /** to : 10 sep 2007 **/ /** # Version 5.1 : from : 30 jul 2010 **/ /** to : 30 jul 2010 **/ /** # Version 6.0 : from : 27 nov 2012 **/ /** to 27 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HDGRAPH_GATHER #include "module.h" #include "common.h" #include "comm.h" #include "graph.h" #include "hgraph.h" #include "dgraph.h" #include "hdgraph.h" /******************************/ /* */ /* These routines handle halo */ /* distributed source graphs. */ /* */ /******************************/ /* This function gathers the pieces of ** a distributed halo graph to build a ** centralized halo graph. ** There is no gathered vnumtab array if ** the original graph did not have one, as ** vertices are gathered in global order, or ** else the original vnumloctab is gathered. ** It returns: ** - 0 : if graph data are consistent. ** - !0 : on error. */ int hdgraphGather ( Hdgraph * restrict const dgrfptr, /* Distributed halo graph */ Hgraph * restrict const cgrfptr) /* Centralized halo graph */ { Gnum vertlocnum; Gnum vertlocadj; /* Local vertex array adjust */ Gnum vhallocnnd; int vhallocnbr; /* Local copy for sending as a MPI_INT */ Gnum * restrict verthaltax; Gnum * restrict edgehaltax; Gnum edgehalnum; int ehallocnbr; /* Local copy for sending as a MPI_INT */ int rootnum; /* Index of root process */ Gnum reduloctab[4]; /* Arrays for reductions */ Gnum reduglbtab[4]; int * restrict recvcnttab; /* Arrays for parametrizing gather operations */ int * restrict recvdsptab; int cheklocval; int chekglbval; Gnum degrmax; if (cgrfptr != NULL) { /* If centralized graph provided */ reduloctab[0] = 1; /* This process is the root */ reduloctab[1] = (Gnum) dgrfptr->s.proclocnum; /* Get its rank */ } else { reduloctab[0] = /* This process is not the root */ reduloctab[1] = 0; } reduloctab[2] = dgrfptr->vhallocnbr; reduloctab[3] = dgrfptr->ehallocnbr; if (MPI_Allreduce (reduloctab, reduglbtab, 4, GNUM_MPI, MPI_SUM, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("hdgraphGather: communication error (1)"); return (1); } if (reduglbtab[0] != 1) { errorPrint ("hdgraphGather: should have only one root"); return (1); } rootnum = (int) reduglbtab[1]; /* Get rank of root process */ degrmax = dgrfptr->s.degrglbmax; /* Distributed degree does not account for halo edges */ cheklocval = 0; if (cgrfptr != NULL) { /* If process is root */ Gnum vnohnbr; Gnum vertnbr; Gnum velonbr; Gnum vnumnbr; Gnum * restrict velotax; Gnum * restrict vnumtax; Gnum edgenbr; vnohnbr = dgrfptr->s.vertglbnbr; vertnbr = vnohnbr + reduglbtab[2]; velonbr = (dgrfptr->s.veloloctax != NULL) ? vertnbr : 0; vnumnbr = (dgrfptr->s.vnumloctax != NULL) ? vnohnbr : 0; /* Vertex numbers only serve for non-halo vertices */ edgenbr = dgrfptr->s.edgeglbnbr + 2 * reduglbtab[3]; /* Twice since halo vertices will be created for real */ cgrfptr->s.flagval = GRAPHFREEEDGE | GRAPHEDGEGROUP | GRAPHFREEVERT | GRAPHVERTGROUP; /* In case of premature freeing on error */ recvcnttab = NULL; if (memAllocGroup ((void **) (void *) &cgrfptr->s.verttax, (size_t) ((vertnbr + 1) * sizeof (Gnum)), /* Compact vertex array */ &velotax, (size_t) (velonbr * sizeof (Gnum)), &vnumtax, (size_t) (vnumnbr * sizeof (Gnum)), &cgrfptr->vnhdtax, (size_t) (vnohnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("hdgraphGather: out of memory (1)"); cheklocval = 1; } else if (cgrfptr->s.verttax -= dgrfptr->s.baseval, cgrfptr->s.velotax = (dgrfptr->s.veloloctax != NULL) ? velotax - dgrfptr->s.baseval : NULL, cgrfptr->s.vnumtax = (dgrfptr->s.vnumloctax != NULL) ? vnumtax - dgrfptr->s.baseval : NULL, cgrfptr->vnhdtax -= dgrfptr->s.baseval, ((cgrfptr->s.edgetax = (Gnum *) memAlloc (edgenbr * sizeof (Gnum))) == NULL)) { errorPrint ("hdgraphGather: out of memory (2)"); cheklocval = 1; } else if (cgrfptr->s.edgetax -= dgrfptr->s.baseval, memAllocGroup ((void **) (void *) &recvcnttab, (size_t) (dgrfptr->s.procglbnbr * sizeof (int)), &recvdsptab, (size_t) (dgrfptr->s.procglbnbr * sizeof (int)), NULL) == NULL) { errorPrint ("hdgraphGather: out of memory (3)"); cheklocval = 1; } else { cgrfptr->s.baseval = dgrfptr->s.baseval; cgrfptr->s.vertnbr = vertnbr; cgrfptr->s.vertnnd = vertnbr + dgrfptr->s.baseval; cgrfptr->s.vendtax = cgrfptr->s.verttax + 1; /* Compact edge array */ cgrfptr->s.velosum = dgrfptr->s.veloglbsum + reduglbtab[2]; /* Halo vertices have unity vertex loads */ cgrfptr->s.vlbltax = NULL; cgrfptr->s.edgenbr = edgenbr; cgrfptr->s.edlotax = NULL; cgrfptr->s.edlosum = edgenbr; cgrfptr->s.procptr = NULL; /* Not a multi-sequential gather: no communication possible */ cgrfptr->vnohnbr = vnohnbr; cgrfptr->vnohnnd = vnohnbr + dgrfptr->s.baseval; cgrfptr->vnlosum = dgrfptr->s.veloglbsum; cgrfptr->enohnbr = cgrfptr->enohsum = dgrfptr->s.edgeglbnbr; cgrfptr->levlnum = dgrfptr->levlnum; } } if ((cheklocval == 0) && (memAllocGroup ((void **) (void *) &verthaltax, (size_t) (dgrfptr->vhallocnbr * sizeof (Gnum)), &edgehaltax, (size_t) (dgrfptr->ehallocnbr * sizeof (Gnum)), NULL) == NULL)) { errorPrint ("hdgraphGather: out of memory (4)"); cheklocval = 1; } else { verthaltax -= dgrfptr->s.baseval; edgehaltax -= dgrfptr->s.baseval; } if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_SUM, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("hdgraphGather: communication error (2)"); return (1); } if (chekglbval != 0) { if (verthaltax != NULL) memFree (verthaltax + dgrfptr->s.baseval); if (cgrfptr != NULL) { /* If data were previously allocated */ if (recvcnttab != NULL) memFree (recvcnttab); hgraphExit (cgrfptr); } return (1); } if (dgrfptr->vhndloctax == dgrfptr->s.vertloctax + 1) { /* If distributed halo graph is compact */ Gnum procglbnum; Gnum edgenum; if (cgrfptr != NULL) { Gnum vertnum; cgrfptr->s.verttax[dgrfptr->s.baseval] = dgrfptr->s.baseval; if (commGatherv (dgrfptr->s.vertloctax + 1 + dgrfptr->s.baseval, /* Do not send first index, it is always equal to baseval */ dgrfptr->s.vertlocnbr, GNUM_MPI, cgrfptr->s.verttax + 1, /* First index will always be equal to baseval too, and procdsptab holds based values */ dgrfptr->s.proccnttab, dgrfptr->s.procdsptab, GNUM_MPI, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("hdgraphGather: communication error (3)"); return (1); } if (commGatherv (dgrfptr->s.vendloctax + dgrfptr->s.baseval, dgrfptr->s.vertlocnbr, GNUM_MPI, cgrfptr->vnhdtax, /* procdsptab holds based values */ dgrfptr->s.proccnttab, dgrfptr->s.procdsptab, GNUM_MPI, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("hdgraphGather: communication error (4)"); return (1); } for (procglbnum = 1, vertnum = dgrfptr->s.procdsptab[1] + 1; /* Adjust index sub-arrays for all processors except the first one */ procglbnum < dgrfptr->s.procglbnbr; procglbnum ++) { Gnum vertnnd; Gnum edgeadj; for (vertnnd = dgrfptr->s.procdsptab[procglbnum + 1] + 1, edgeadj = cgrfptr->s.verttax[vertnum - 1] - dgrfptr->s.baseval; vertnum < vertnnd; vertnum ++) { cgrfptr->s.verttax[vertnum] += edgeadj; cgrfptr->vnhdtax[vertnum - 1] += edgeadj; } } for (procglbnum = 0, edgenum = dgrfptr->s.baseval; /* Build arrays for MPI_Gatherv on edge arrays */ procglbnum < dgrfptr->s.procglbnbr; procglbnum ++) { recvcnttab[procglbnum] = cgrfptr->s.verttax[dgrfptr->s.procdsptab[procglbnum + 1]] - cgrfptr->s.verttax[dgrfptr->s.procdsptab[procglbnum]]; /* verttax used twice since centralized graph is compact */ recvdsptab[procglbnum] = edgenum; edgenum += recvcnttab[procglbnum]; } if (MPI_Gatherv (dgrfptr->s.edgeloctax + dgrfptr->s.baseval, /* Gather edge arrays with global vertex indices */ (int) (dgrfptr->s.edgelocnbr + dgrfptr->ehallocnbr), GNUM_MPI, cgrfptr->s.edgetax, recvcnttab, recvdsptab, GNUM_MPI, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("hdgraphGather: communication error (5)"); return (1); } } else { if (MPI_Gatherv (dgrfptr->s.vertloctax + 1 + dgrfptr->s.baseval, /* Do not send first index, it is always equal to baseval */ (int) dgrfptr->s.vertlocnbr, GNUM_MPI, NULL, NULL, NULL, GNUM_MPI, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("hdgraphGather: communication error (6)"); return (1); } if (MPI_Gatherv (dgrfptr->s.vendloctax + dgrfptr->s.baseval, (int) dgrfptr->s.vertlocnbr, GNUM_MPI, NULL, NULL, NULL, GNUM_MPI, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("hdgraphGather: communication error (7)"); return (1); } if (MPI_Gatherv (dgrfptr->s.edgeloctax + dgrfptr->s.baseval, /* Gather edge arrays with global vertex indices */ (int) (dgrfptr->s.edgelocnbr + dgrfptr->ehallocnbr), GNUM_MPI, NULL, NULL, NULL, GNUM_MPI, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("hdgraphGather: communication error (8)"); return (1); } } } else { errorPrint ("hdgraphGather: Not implemented"); /* Not really necessary as all Hdgraph structures created by Scotch itself are compact */ return (1); } memSet (verthaltax + dgrfptr->s.baseval, 0, dgrfptr->vhallocnbr * sizeof (Gnum)); /* Initialize halo end vertex count array */ for (vertlocnum = dgrfptr->s.baseval; vertlocnum < dgrfptr->s.vertlocnnd; vertlocnum ++) { Gnum edgelocnum; for (edgelocnum = dgrfptr->s.vendloctax[vertlocnum]; edgelocnum < dgrfptr->vhndloctax[vertlocnum]; edgelocnum ++) verthaltax[dgrfptr->s.edgeloctax[edgelocnum]] ++; /* One more edge to this halo vertex */ } vhallocnbr = (int) dgrfptr->vhallocnbr; if (MPI_Gather (&vhallocnbr, 1, MPI_INT, recvcnttab, 1, MPI_INT, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("hdgraphGather: communication error (9)"); return (1); } if (cgrfptr != NULL) { /* Build gather parameter array to receive halo edge counts */ Gnum procglbnum; Gnum vertnum; for (procglbnum = 0, vertnum = 0; procglbnum < dgrfptr->s.procglbnbr; procglbnum ++) { /* Displacements start from zero because adjusted later */ recvdsptab[procglbnum] = vertnum; vertnum += recvcnttab[procglbnum]; } if (MPI_Gatherv (verthaltax + dgrfptr->s.baseval, (int) dgrfptr->vhallocnbr, GNUM_MPI, /* Gather count arrays of halo vertices */ cgrfptr->s.verttax + cgrfptr->vnohnnd + 1, recvcnttab, recvdsptab, GNUM_MPI, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("hdgraphGather: communication error (10)"); return (1); } for (procglbnum = 0, vertnum = dgrfptr->s.baseval; /* Adjust end vertex indices for halo edges */ procglbnum < dgrfptr->s.procglbnbr; procglbnum ++) { Gnum vertnnd; Gnum vertadj; for (vertnnd = dgrfptr->s.procdsptab[procglbnum + 1], vertadj = cgrfptr->vnohnbr + recvdsptab[procglbnum]; vertnum < vertnnd; vertnum ++) { Gnum edgenum; if (degrmax < (cgrfptr->s.vendtax[vertnum] - cgrfptr->s.verttax[vertnum])) /* Account for halo edges in maximum degree */ degrmax = (cgrfptr->s.vendtax[vertnum] - cgrfptr->s.verttax[vertnum]); for (edgenum = cgrfptr->vnhdtax[vertnum]; edgenum < cgrfptr->s.vendtax[vertnum]; edgenum ++) cgrfptr->s.edgetax[edgenum] += vertadj; } } } else { if (MPI_Gatherv (verthaltax + dgrfptr->s.baseval, (int) dgrfptr->vhallocnbr, GNUM_MPI, /* Gather count arrays of halo vertices */ NULL, NULL, NULL, GNUM_MPI, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("hdgraphGather: communication error (11)"); return (1); } } for (vertlocnum = edgehalnum = dgrfptr->s.baseval, vhallocnnd = dgrfptr->vhallocnbr + dgrfptr->s.baseval; vertlocnum < vhallocnnd; vertlocnum ++) { /* Prepare index array for edge collection */ Gnum degrlocval; degrlocval = verthaltax[vertlocnum]; verthaltax[vertlocnum] = edgehalnum; edgehalnum += degrlocval; } vertlocadj = dgrfptr->s.procdsptab[dgrfptr->s.proclocnum] - dgrfptr->s.baseval; for (vertlocnum = dgrfptr->s.baseval; vertlocnum < dgrfptr->s.vertlocnnd; vertlocnum ++) { /* Collect halo edge ends */ Gnum edgelocnum; for (edgelocnum = dgrfptr->s.vendloctax[vertlocnum]; edgelocnum < dgrfptr->vhndloctax[vertlocnum]; edgelocnum ++) edgehaltax[verthaltax[dgrfptr->s.edgeloctax[edgelocnum]] ++] = vertlocnum + vertlocadj; } ehallocnbr = (int) dgrfptr->ehallocnbr; if (MPI_Gather (&ehallocnbr, 1, MPI_INT, recvcnttab, 1, MPI_INT, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) { /* Gather halo edge counts */ errorPrint ("hdgraphGather: communication error (12)"); return (1); } if (cgrfptr != NULL) { /* Compute receive arrays for edge sub-arrays of halo vertices */ Gnum procglbnum; Gnum edgeadj; for (procglbnum = 0, edgeadj = 0; procglbnum < dgrfptr->s.procglbnbr; procglbnum ++) { recvdsptab[procglbnum] = edgeadj; edgeadj += recvcnttab[procglbnum]; } if (MPI_Gatherv (edgehaltax + dgrfptr->s.baseval, (int) dgrfptr->ehallocnbr, GNUM_MPI, /* Gather edge arrays of halo vertices */ cgrfptr->s.edgetax + cgrfptr->enohnbr + reduglbtab[3] + dgrfptr->s.baseval, recvcnttab, recvdsptab, GNUM_MPI, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("hdgraphGather: communication error (13)"); return (1); } } else { if (MPI_Gatherv (edgehaltax + dgrfptr->s.baseval, (int) dgrfptr->ehallocnbr, GNUM_MPI, /* Gather edge arrays of halo vertices */ NULL, NULL, NULL, GNUM_MPI, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("hdgraphGather: communication error (14)"); return (1); } } memFree (verthaltax + dgrfptr->s.baseval); /* Free group leader */ if (cgrfptr != NULL) { /* Finalize vertex and edge arrays of centralized graph */ Gnum vertnum; Gnum edgeadj; if (dgrfptr->s.veloloctax != NULL) { /* Get vertex loads if any */ if (commGatherv (dgrfptr->s.veloloctax + dgrfptr->s.baseval, dgrfptr->s.vertlocnbr, GNUM_MPI, cgrfptr->s.velotax, dgrfptr->s.proccnttab, dgrfptr->s.procdsptab, GNUM_MPI, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("hdgraphGather: communication error (15)"); return (1); } for (vertnum = cgrfptr->vnohnnd; vertnum < cgrfptr->s.vertnnd; vertnum ++) /* complete filling of vertex load array */ cgrfptr->s.velotax[vertnum] = 1; } if (dgrfptr->s.vnumloctax != NULL) { /* Get vertex numbers if any */ if (commGatherv (dgrfptr->s.vnumloctax + dgrfptr->s.baseval, dgrfptr->s.vertlocnbr, GNUM_MPI, cgrfptr->s.vnumtax, dgrfptr->s.proccnttab, dgrfptr->s.procdsptab, GNUM_MPI, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("hdgraphGather: communication error (16)"); return (1); } } memFree (recvcnttab); /* Free group leader */ for (vertnum = cgrfptr->vnohnnd + 1, edgeadj = cgrfptr->s.verttax[cgrfptr->vnohnnd]; /* Adjust vertex array for halo vertices */ vertnum <= cgrfptr->s.vertnnd; vertnum ++) { Gnum degrval; degrval = cgrfptr->s.verttax[vertnum]; if (degrmax < degrval) /* Account for halo edges in maximum degree */ degrmax = degrval; edgeadj += degrval; cgrfptr->s.verttax[vertnum] = edgeadj; } cgrfptr->s.degrmax = degrmax; } else { if (dgrfptr->s.veloloctax != NULL) { /* Get vertex loads if any */ if (MPI_Gatherv (dgrfptr->s.veloloctax + dgrfptr->s.baseval, (int) dgrfptr->s.vertlocnbr, GNUM_MPI, NULL, NULL, NULL, GNUM_MPI, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("hdgraphGather: communication error (17)"); return (1); } } if (dgrfptr->s.vnumloctax != NULL) { /* Get vertex numbers if any */ if (MPI_Gatherv (dgrfptr->s.vnumloctax + dgrfptr->s.baseval, (int) dgrfptr->s.vertlocnbr, GNUM_MPI, NULL, NULL, NULL, GNUM_MPI, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("hdgraphGather: communication error (18)"); return (1); } } } #ifdef SCOTCH_DEBUG_HDGRAPH2 cheklocval = (cgrfptr != NULL) ? hgraphCheck (cgrfptr) : 0; if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("hdgraphGather: communication error (19)"); return (1); } if (chekglbval != 0) { errorPrint ("hdgraphGather: internal error"); if (cgrfptr != NULL) hgraphExit (cgrfptr); return (1); } #endif /* SCOTCH_DEBUG_HDGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/hgraph_order_st.c0000644002563400244210000003712212037540015025152 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hgraph_order_st.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the generic call to the **/ /** graph ordering module, using a given **/ /** strategy. **/ /** **/ /** DATES : # Version 3.2 : from : 19 oct 1996 **/ /** to 09 sep 1998 **/ /** # Version 3.3 : from : 02 oct 1998 **/ /** to 07 sep 2001 **/ /** # Version 4.0 : from : 27 dec 2001 **/ /** to 05 jan 2005 **/ /** # Version 5.0 : from : 31 may 2008 **/ /** to 31 may 2008 **/ /** # Version 6.0 : from : 17 oct 2012 **/ /** to 17 oct 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HGRAPH_ORDER_ST #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "arch.h" #include "mapping.h" #include "order.h" #include "hgraph.h" #include "hgraph_order_bl.h" #include "hgraph_order_cp.h" #include "hgraph_order_gp.h" #include "hgraph_order_hd.h" #include "hgraph_order_hf.h" #include "hgraph_order_kp.h" #include "hgraph_order_nd.h" #include "hgraph_order_si.h" #include "hgraph_order_st.h" #include "kgraph.h" #include "kgraph_map_st.h" #include "vgraph.h" #include "vgraph_separate_st.h" /* ** The static and global variables. */ static Hgraph hgraphorderstgraphdummy; /* Dummy graph for offset computations */ static union { /* Default parameters for block splitting method */ HgraphOrderBlParam param; /* Parameter zone */ StratNodeMethodData padding; /* To avoid reading out of structure */ } hgraphorderstdefaultbl = { { &stratdummy, 8 } }; static union { HgraphOrderCpParam param; StratNodeMethodData padding; } hgraphorderstdefaultcp = { { 0.70L, &stratdummy, &stratdummy } }; static union { HgraphOrderGpParam param; StratNodeMethodData padding; } hgraphorderstdefaultgp = { { 3 } }; static union { HgraphOrderHdParam param; StratNodeMethodData padding; } hgraphorderstdefaulthd = { { 1, 10000, 0.08L } }; static union { HgraphOrderHfParam param; StratNodeMethodData padding; } hgraphorderstdefaulthf = { { 1, 1000000, 0.08L } }; static union { HgraphOrderKpParam param; StratNodeMethodData padding; } hgraphorderstdefaultkp = { { 1, &stratdummy } }; static union { /* Default parameters for nested dissection method */ HgraphOrderNdParam param; StratNodeMethodData padding; } hgraphorderstdefaultnd = { { &stratdummy, &stratdummy, &stratdummy } }; static StratMethodTab hgraphorderstmethtab[] = { /* Graph ordering methods array */ { HGRAPHORDERSTMETHBL, "b", hgraphOrderBl, &hgraphorderstdefaultbl }, { HGRAPHORDERSTMETHCP, "c", hgraphOrderCp, &hgraphorderstdefaultcp }, { HGRAPHORDERSTMETHGP, "g", hgraphOrderGp, &hgraphorderstdefaultgp }, { HGRAPHORDERSTMETHHD, "d", hgraphOrderHd, &hgraphorderstdefaulthd }, { HGRAPHORDERSTMETHHF, "f", hgraphOrderHf, &hgraphorderstdefaulthf }, { HGRAPHORDERSTMETHKP, "k", hgraphOrderKp, &hgraphorderstdefaultkp }, { HGRAPHORDERSTMETHND, "n", hgraphOrderNd, &hgraphorderstdefaultnd }, { HGRAPHORDERSTMETHSI, "s", hgraphOrderSi, NULL }, { -1, NULL, NULL, NULL } }; static StratParamTab hgraphorderstparatab[] = { /* The method parameter list */ { HGRAPHORDERSTMETHBL, STRATPARAMSTRAT, "strat", (byte *) &hgraphorderstdefaultbl.param, (byte *) &hgraphorderstdefaultbl.param.strat, (void *) &hgraphorderststratab }, { HGRAPHORDERSTMETHBL, STRATPARAMINT, "cmin", (byte *) &hgraphorderstdefaultbl.param, (byte *) &hgraphorderstdefaultbl.param.cblkmin, NULL }, { HGRAPHORDERSTMETHCP, STRATPARAMDOUBLE, "rat", (byte *) &hgraphorderstdefaultcp.param, (byte *) &hgraphorderstdefaultcp.param.comprat, NULL }, { HGRAPHORDERSTMETHCP, STRATPARAMSTRAT, "cpr", (byte *) &hgraphorderstdefaultcp.param, (byte *) &hgraphorderstdefaultcp.param.stratcpr, (void *) &hgraphorderststratab }, { HGRAPHORDERSTMETHCP, STRATPARAMSTRAT, "unc", (byte *) &hgraphorderstdefaultcp.param, (byte *) &hgraphorderstdefaultcp.param.stratunc, (void *) &hgraphorderststratab }, { HGRAPHORDERSTMETHGP, STRATPARAMINT, "pass", (byte *) &hgraphorderstdefaultgp.param, (byte *) &hgraphorderstdefaultgp.param.passnbr, NULL }, { HGRAPHORDERSTMETHHD, STRATPARAMINT, "cmin", (byte *) &hgraphorderstdefaulthd.param, (byte *) &hgraphorderstdefaulthd.param.colmin, NULL }, { HGRAPHORDERSTMETHHD, STRATPARAMINT, "cmax", (byte *) &hgraphorderstdefaulthd.param, (byte *) &hgraphorderstdefaulthd.param.colmax, NULL }, { HGRAPHORDERSTMETHHD, STRATPARAMDOUBLE, "frat", (byte *) &hgraphorderstdefaulthd.param, (byte *) &hgraphorderstdefaulthd.param.fillrat, NULL }, { HGRAPHORDERSTMETHHF, STRATPARAMINT, "cmin", (byte *) &hgraphorderstdefaulthf.param, (byte *) &hgraphorderstdefaulthf.param.colmin, NULL }, { HGRAPHORDERSTMETHHF, STRATPARAMINT, "cmax", (byte *) &hgraphorderstdefaulthf.param, (byte *) &hgraphorderstdefaulthf.param.colmax, NULL }, { HGRAPHORDERSTMETHHF, STRATPARAMDOUBLE, "frat", (byte *) &hgraphorderstdefaulthf.param, (byte *) &hgraphorderstdefaulthf.param.fillrat, NULL }, { HGRAPHORDERSTMETHKP, STRATPARAMINT, "siz", (byte *) &hgraphorderstdefaultkp.param, (byte *) &hgraphorderstdefaultkp.param.partsiz, NULL }, { HGRAPHORDERSTMETHKP, STRATPARAMSTRAT, "strat", (byte *) &hgraphorderstdefaultkp.param, (byte *) &hgraphorderstdefaultkp.param.strat, (void *) &kgraphmapststratab }, { HGRAPHORDERSTMETHND, STRATPARAMSTRAT, "sep", (byte *) &hgraphorderstdefaultnd.param, (byte *) &hgraphorderstdefaultnd.param.sepstrat, (void *) &vgraphseparateststratab }, { HGRAPHORDERSTMETHND, STRATPARAMSTRAT, "ole", (byte *) &hgraphorderstdefaultnd.param, (byte *) &hgraphorderstdefaultnd.param.ordstratlea, (void *) &hgraphorderststratab }, { HGRAPHORDERSTMETHND, STRATPARAMSTRAT, "ose", (byte *) &hgraphorderstdefaultnd.param, (byte *) &hgraphorderstdefaultnd.param.ordstratsep, (void *) &hgraphorderststratab }, { HGRAPHORDERSTMETHNBR, STRATPARAMINT, NULL, NULL, NULL, NULL } }; static StratParamTab hgraphorderstcondtab[] = { /* Graph condition parameter table */ { STRATNODECOND, STRATPARAMINT, "edge", (byte *) &hgraphorderstgraphdummy, (byte *) &hgraphorderstgraphdummy.s.edgenbr, NULL }, { STRATNODECOND, STRATPARAMINT, "levl", (byte *) &hgraphorderstgraphdummy, (byte *) &hgraphorderstgraphdummy.levlnum, NULL }, { STRATNODECOND, STRATPARAMINT, "load", (byte *) &hgraphorderstgraphdummy, (byte *) &hgraphorderstgraphdummy.vnlosum, NULL }, { STRATNODECOND, STRATPARAMDOUBLE, "mdeg", (byte *) &hgraphorderstgraphdummy, (byte *) &hgraphorderstgraphdummy.s.degrmax, NULL }, { STRATNODECOND, STRATPARAMINT, "vert", (byte *) &hgraphorderstgraphdummy, (byte *) &hgraphorderstgraphdummy.vnohnbr, /* Only consider non-halo vertices */ NULL }, { STRATNODENBR, STRATPARAMINT, NULL, NULL, NULL, NULL } }; StratTab hgraphorderststratab = { /* Strategy tables for graph ordering methods */ hgraphorderstmethtab, hgraphorderstparatab, hgraphorderstcondtab }; /************************************/ /* */ /* This routine is the entry point */ /* for the graph ordering routines. */ /* */ /************************************/ /* This routine computes an ordering ** with respect to a given strategy. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int hgraphOrderSt ( const Hgraph * restrict const grafptr, /*+ Subgraph to order +*/ Order * restrict const ordeptr, /*+ Ordering to complete +*/ const Gnum ordenum, /*+ Index to start ordering at +*/ OrderCblk * restrict const cblkptr, /*+ Current column block +*/ const Strat * restrict const strat) /*+ Graph ordering strategy +*/ { StratTest val; int o; if (grafptr->vnohnbr == 0) /* Return immediately if nothing to do */ return (0); o = 0; switch (strat->type) { case STRATNODECONCAT : errorPrint ("hgraphOrderSt: concatenation operator not available for graph ordering strategies"); return (1); case STRATNODECOND : o = stratTestEval (strat->data.cond.test, &val, (void *) grafptr); /* Evaluate expression */ if (o == 0) { /* If evaluation was correct */ #ifdef SCOTCH_DEBUG_HGRAPH2 if ((val.typetest != STRATTESTVAL) && (val.typenode != STRATPARAMLOG)) { errorPrint ("hgraphOrderSt: invalid test result"); o = 1; break; } #endif /* SCOTCH_DEBUG_HGRAPH2 */ if (val.data.val.vallog == 1) /* If expression is true */ o = hgraphOrderSt (grafptr, ordeptr, ordenum, cblkptr, strat->data.cond.strat[0]); /* Apply first strategy */ else { /* Else if expression is false */ if (strat->data.cond.strat[1] != NULL) /* And if there is an else statement */ o = hgraphOrderSt (grafptr, ordeptr, ordenum, cblkptr, strat->data.cond.strat[1]); /* Apply second strategy */ } } break; case STRATNODEEMPTY : hgraphOrderSi (grafptr, ordeptr, ordenum, cblkptr); /* Always maintain a consistent ordering */ break; case STRATNODESELECT : errorPrint ("hgraphOrderSt: selection operator not available for graph ordering strategies"); return (1); #ifdef SCOTCH_DEBUG_HGRAPH2 case STRATNODEMETHOD : #else /* SCOTCH_DEBUG_HGRAPH2 */ default : #endif /* SCOTCH_DEBUG_HGRAPH2 */ return (strat->tabl->methtab[strat->data.method.meth].func (grafptr, ordeptr, ordenum, cblkptr, (void *) &strat->data.method.data)); #ifdef SCOTCH_DEBUG_HGRAPH2 default : errorPrint ("hgraphOrderSt: invalid parameter"); return (1); #endif /* SCOTCH_DEBUG_HGRAPH2 */ } return (o); } scotch-6.0.4.dfsg/src/libscotch/bgraph_bipart_gp.c0000644002563400244210000003064012376577564025321 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bipart_gp.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module bipartitions an active **/ /** graph using the Gibbs, Poole, and **/ /** Stockmeyer algorithm. **/ /** **/ /** DATES : # Version 2.0 : from : 02 jun 1994 **/ /** to 05 oct 1994 **/ /** # Version 3.1 : from : 02 may 1996 **/ /** to 02 may 1996 **/ /** # Version 3.2 : from : 21 sep 1996 **/ /** to 13 sep 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 3.4 : from : 01 jun 2001 **/ /** to 01 jun 2001 **/ /** # Version 4.0 : from : 04 nov 2003 **/ /** to 27 nov 2006 **/ /** # Version 5.0 : from : 10 sep 2007 **/ /** to 22 feb 2011 **/ /** # Version 6.0 : from : 08 aug 2014 **/ /** to 08 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define BGRAPH_BIPART_GP #include "module.h" #include "common.h" #include "graph.h" #include "arch.h" #include "bgraph.h" #include "bgraph_bipart_gp.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the bipartitioning. ** It returns: ** - 0 : if bipartitioning could be computed. ** - 1 : on error. */ int bgraphBipartGp ( Bgraph * restrict const grafptr, const BgraphBipartGpParam * const paraptr) /*+ Method parameters +*/ { BgraphBipartGpQueue queudat; /* Neighbor queue */ BgraphBipartGpVertex * restrict vexxtax; /* Complementary vertex array */ Gnum compload0dlt; Gnum compsize0; Gnum commloadintn; Gnum commloadextn; Gnum commgainextn; Gnum rootnum; /* Index of potential next root */ const Gnum * restrict const verttax = grafptr->s.verttax; /* Fast accesses */ const Gnum * restrict const vendtax = grafptr->s.vendtax; const Gnum * restrict const velotax = grafptr->s.velotax; const Gnum * restrict const edgetax = grafptr->s.edgetax; const Gnum * restrict const edlotax = grafptr->s.edlotax; const Gnum * restrict const veextax = grafptr->veextax; if (grafptr->compload0 != grafptr->s.velosum) /* If not all vertices already in part 0 */ bgraphZero (grafptr); /* Move all graph vertices to part 0 */ if (memAllocGroup ((void **) (void *) &queudat.queutab, (size_t) (grafptr->s.vertnbr * sizeof (Gnum)), &vexxtax, (size_t) (grafptr->s.vertnbr * sizeof (BgraphBipartGpVertex)), NULL) == NULL) { errorPrint ("bgraphBipartGp: out of memory"); return (1); } memSet (vexxtax, 0, grafptr->s.vertnbr * sizeof (BgraphBipartGpVertex)); /* Initialize pass numbers */ vexxtax -= grafptr->s.baseval; compsize0 = grafptr->s.vertnbr; /* All vertices in part zero */ compload0dlt = grafptr->s.velosum - grafptr->compload0avg; commloadintn = 0; commloadextn = grafptr->commloadextn0; commgainextn = grafptr->commgainextn0; for (rootnum = grafptr->s.baseval; /* Loop on connected components */ (rootnum < grafptr->s.vertnnd) && (compload0dlt > 0); rootnum ++) { Gnum passnum; /* Pass number */ Gnum diamnum; /* Number of current diameter vertex */ Gnum diamval; /* Current diameter value */ Gnum diamdeg; /* Degree of current diameter vertex */ int diamflag; /* Flag set if improvement in diameter between passes */ while (vexxtax[rootnum].passnum != 0) /* Find first unallocated vertex */ rootnum ++; for (diamnum = rootnum, diamval = diamdeg = 0, diamflag = 1, passnum = 1; /* Start from root */ (passnum < paraptr->passnbr) && (diamflag -- != 0); passnum ++) { /* Loop if improvements */ bgraphBipartGpQueueFlush (&queudat); /* Flush vertex queue */ bgraphBipartGpQueuePut (&queudat, diamnum); /* Start from diameter vertex */ vexxtax[diamnum].passnum = passnum; /* It has been enqueued */ vexxtax[diamnum].distval = 0; do { /* Loop on vertices in queue */ Gnum vertnum; Gnum distval; Gnum edgenum; vertnum = bgraphBipartGpQueueGet (&queudat); /* Get vertex from queue */ distval = vexxtax[vertnum].distval; /* Get vertex distance */ if ((distval > diamval) || /* If vertex increases diameter */ ((distval == diamval) && /* Or is at diameter distance */ ((vendtax[vertnum] - verttax[vertnum]) < diamdeg))) { /* With smaller degree */ diamnum = vertnum; /* Set it as new diameter vertex */ diamval = distval; diamdeg = vendtax[vertnum] - verttax[vertnum]; diamflag = 1; } distval ++; /* Set neighbor distance */ for (edgenum = verttax[vertnum]; edgenum < vendtax[vertnum]; edgenum ++) { Gnum vertend; /* End vertex number */ vertend = edgetax[edgenum]; if (vexxtax[vertend].passnum < passnum) { /* If vertex not yet queued */ bgraphBipartGpQueuePut (&queudat, vertend); /* Enqueue neighbor vertex */ vexxtax[vertend].passnum = passnum; vexxtax[vertend].distval = distval; } } } while (! bgraphBipartGpQueueEmpty (&queudat)); /* As long as queue is not empty */ } bgraphBipartGpQueueFlush (&queudat); /* Flush vertex queue */ bgraphBipartGpQueuePut (&queudat, diamnum); /* Start from diameter vertex */ vexxtax[diamnum].passnum = passnum; /* It has been enqueued */ vexxtax[diamnum].distval = 0; do { /* Loop on vertices in queue */ Gnum vertnum; Gnum veloval; Gnum veexval; Gnum distval; Gnum edgenum; vertnum = bgraphBipartGpQueueGet (&queudat); /* Get vertex from queue */ veloval = (velotax != NULL) ? velotax[vertnum] : 1; veexval = (veextax != NULL) ? veextax[vertnum] : 0; grafptr->parttax[vertnum] = 1; /* Move selected vertex to part 1 */ compsize0 --; compload0dlt -= veloval; commloadextn += veexval; commgainextn -= veexval * 2; distval = vexxtax[vertnum].distval + 1; for (edgenum = verttax[vertnum]; edgenum < vendtax[vertnum]; edgenum ++) { Gnum vertend; /* End vertex number */ vertend = edgetax[edgenum]; if (vexxtax[vertend].passnum < passnum) { /* If vertex not yet queued */ bgraphBipartGpQueuePut (&queudat, vertend); /* Enqueue neighbor vertex */ vexxtax[vertend].passnum = passnum; vexxtax[vertend].distval = distval; } } } while ((compload0dlt > 0) && (! bgraphBipartGpQueueEmpty (&queudat))); /* As long as balance not achieved and queue is not empty */ if (! bgraphBipartGpQueueEmpty (&queudat)) { /* If frontier non empty */ Gnum edloval; Gnum fronnbr; fronnbr = 0; /* No frontier yet */ edloval = 1; /* Assume no edge loads */ do { Gnum vertnum; Gnum edgenum; vertnum = bgraphBipartGpQueueGet (&queudat); /* Get vertex from queue */ grafptr->frontab[fronnbr ++] = vertnum; #ifdef SCOTCH_DEBUG_BGRAPH2 if (grafptr->parttax[vertnum] != 0) { errorPrint ("bgraphBipartGp: internal error"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH2 */ for (edgenum = verttax[vertnum]; edgenum < vendtax[vertnum]; edgenum ++) { Gnum vertend; /* End vertex number */ vertend = edgetax[edgenum]; if (grafptr->parttax[vertend] == 1) { /* If vertex belongs to other part */ if (edlotax != NULL) edloval = edlotax[edgenum]; commloadintn += edloval; if (vexxtax[vertend].distval != ~0) { /* If neighbor vertex not already put in frontier */ grafptr->frontab[fronnbr ++] = vertend; /* Record it in frontier */ vexxtax[vertend].distval = ~0; /* Set it as recorded */ } } } } while (! bgraphBipartGpQueueEmpty (&queudat)); grafptr->fronnbr = fronnbr; break; /* No need to process rest of graph */ } /* Else grafptr->fronnbr = 0 anyway */ } grafptr->compload0 = grafptr->compload0avg + compload0dlt; grafptr->compload0dlt = compload0dlt; grafptr->compsize0 = compsize0; grafptr->commload = commloadintn * grafptr->domndist + commloadextn; grafptr->commgainextn = commgainextn; grafptr->bbalval = (double) ((grafptr->compload0dlt < 0) ? (- grafptr->compload0dlt) : grafptr->compload0dlt) / (double) grafptr->compload0avg; memFree (queudat.queutab); /* Free group leader */ #ifdef SCOTCH_DEBUG_BGRAPH2 if (bgraphCheck (grafptr) != 0) { errorPrint ("bgraphBipartGp: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/vgraph_separate_zr.c0000644002563400244210000000641511631447170025676 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vgraph_separate_zr.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module moves all of the vertices **/ /** to the first subdomain. **/ /** **/ /** DATES : # Version 3.3 : from : 31 may 1999 **/ /** to 31 may 1999 **/ /** # Version 4.0 : from : 19 dec 2001 **/ /** to 29 may 2004 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VGRAPH_SEPARATE_ZR #include "module.h" #include "common.h" #include "graph.h" #include "vgraph.h" #include "vgraph_separate_zr.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine moves all of the graph vertices ** to the first part of the partition. ** It returns: ** - 0 : if the bipartitioning could be computed. ** - !0 : on error. */ int vgraphSeparateZr ( Vgraph * const grafptr) /*+ Active graph +*/ { if (grafptr->compload[0] != grafptr->s.velosum) /* If not all vertices already in part zero */ vgraphZero (grafptr); return (0); } scotch-6.0.4.dfsg/src/libscotch/order.c0000644002563400244210000002404412370025065023115 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : order.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles generic orderings. **/ /** **/ /** DATES : # Version 3.2 : from : 19 oct 1996 **/ /** to 27 aug 1998 **/ /** # Version 4.0 : from : 19 dec 2001 **/ /** to 26 dec 2004 **/ /** # Version 5.0 : from : 25 jul 2007 **/ /** to 25 jul 2007 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define ORDER #include "module.h" #include "common.h" #include "graph.h" #include "order.h" /************************************/ /* */ /* These routines handle orderings. */ /* */ /************************************/ /* This routine initializes an ordering ** with respect to a given source graph. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int orderInit ( Order * restrict const ordeptr, const Gnum baseval, const Gnum vnodnbr, Gnum * restrict const peritab) { ordeptr->flagval = ORDERNONE; ordeptr->baseval = baseval; ordeptr->vnodnbr = vnodnbr; ordeptr->treenbr = /* Initialize a simple blocking */ ordeptr->cblknbr = 1; ordeptr->cblktre.typeval = ORDERCBLKOTHR; ordeptr->cblktre.vnodnbr = vnodnbr; ordeptr->cblktre.cblknbr = 0; ordeptr->cblktre.cblktab = NULL; ordeptr->peritab = peritab; if (ordeptr->peritab == NULL) { /* Inverse permutation must be allocated */ ordeptr->flagval |= ORDERFREEPERI; /* Flag it so it will be freed */ if ((ordeptr->peritab = (Gnum *) memAlloc (vnodnbr * sizeof (Gnum))) == NULL) { errorPrint ("orderInit: out of memory"); return (1); } } #ifdef SCOTCH_DEBUG_ORDER2 memSet (ordeptr->peritab, ~0, vnodnbr * sizeof (Gnum)); #endif /* SCOTCH_DEBUG_ORDER2 */ return (0); } /* This routine frees the contents ** of the given ordering. ** It returns: ** - 0 : on success. ** - !0 : on error. */ void orderExit ( Order * restrict const ordeptr) { if (ordeptr->cblktre.cblktab != NULL) /* Free column block tree */ orderExit2 (ordeptr->cblktre.cblktab, ordeptr->cblktre.cblknbr); if ((ordeptr->peritab != NULL) && ((ordeptr->flagval & ORDERFREEPERI) != 0)) /* If peritab is group leader */ memFree (ordeptr->peritab); /* Free group leader */ #ifdef SCOTCH_DEBUG_ORDER2 memSet (ordeptr, ~0, sizeof (Order)); #endif /* SCOTCH_DEBUG_ORDER2 */ } static void orderExit2 ( OrderCblk * restrict const cblktab, const Gnum cblknbr) { Gnum cblknum; for (cblknum = 0; cblknum < cblknbr; cblknum ++) { if (cblktab[cblknum].cblktab != NULL) orderExit2 (cblktab[cblknum].cblktab, cblktab[cblknum].cblknbr); } memFree (cblktab); } /* This routine computes the inverse permutation ** of the given permutation, according to the ** direct and inverse base values. ** It returns: ** - VOID : in all cases. */ void orderPeri ( const Gnum * restrict const permtab, /* Permutation to invert */ const Gnum permbas, /* Permutation base value */ const Gnum permnbr, /* Number of permutation indices */ Gnum * restrict const peritab, /* Array of inverse permutation */ const Gnum peribas) /* Base value of inverse permutation */ { Gnum permnum; for (permnum = 0; permnum < permnbr; permnum ++) peritab[permtab[permnum] - permbas] = permnum + peribas; } /* This routine computes the column block ** range array of the given ordering. ** It returns: ** - VOID : in all cases. */ void orderRang ( const Order * restrict const ordeptr, /* Ordering */ Gnum * restrict const rangtab) /* Column block range array [+1] */ { Gnum * rangptr; Gnum ordenum; rangptr = rangtab; /* Set beginning of range array */ ordenum = ordeptr->baseval; /* Set initial number */ orderRang2 (&rangptr, &ordenum, &ordeptr->cblktre); *rangptr = ordenum; /* Set end of range array */ } static void orderRang2 ( Gnum ** restrict const rangppt, Gnum * restrict const ordeppt, const OrderCblk * restrict const cblkptr) { Gnum cblknum; #ifdef SCOTCH_DEBUG_ORDER2 Gnum * restrict rangtmp; if (cblkptr->vnodnbr < 1) errorPrint ("orderRang2: internal error (1)"); #endif /* SCOTCH_DEBUG_ORDER2 */ if (cblkptr->cblktab == NULL) { /* If leaf of column block tree */ *(*rangppt) ++ = *ordeppt; /* Set beginning of column block */ *ordeppt += cblkptr->vnodnbr; /* Advance by column block size */ } else { #ifdef SCOTCH_DEBUG_ORDER2 rangtmp = *rangppt; #endif /* SCOTCH_DEBUG_ORDER2 */ for (cblknum = 0; cblknum < cblkptr->cblknbr; cblknum ++) orderRang2 (rangppt, ordeppt, &cblkptr->cblktab[cblknum]); #ifdef SCOTCH_DEBUG_ORDER2 if ((*ordeppt - *rangtmp) != cblkptr->vnodnbr) errorPrint ("orderRang2: internal error (2)"); #endif /* SCOTCH_DEBUG_ORDER2 */ } } /* This routine computes the separator tree ** array of the given ordering. ** It returns: ** - VOID : in all cases. */ void orderTree ( const Order * restrict const ordeptr, /* Ordering */ Gnum * restrict const treetab) /* Column block separator tree array */ { Gnum cblanum; cblanum = ordeptr->cblknbr + ordeptr->baseval - 1; /* Set number of last column block */ orderTree2 (treetab - ordeptr->baseval, &cblanum, &ordeptr->cblktre, -1); #ifdef SCOTCH_DEBUG_ORDER2 if (cblanum != ordeptr->baseval - 1) errorPrint ("orderTree: internal error"); #endif /* SCOTCH_DEBUG_ORDER2 */ } static void orderTree2 ( Gnum * restrict const treetax, /* Based access to tree table */ Gnum * restrict const cblaptr, /* Pointer to current number of last column block, in descending order */ const OrderCblk * restrict const cblkptr, /* Current column block tree node */ Gnum cbfanum) /* Current number of ancestor separator column block */ { #ifdef SCOTCH_DEBUG_ORDER2 if (cblkptr->vnodnbr < 1) errorPrint ("orderTree2: internal error (1)"); #endif /* SCOTCH_DEBUG_ORDER2 */ if (cblkptr->cblktab == NULL) /* If leaf of column block tree */ treetax[(*cblaptr) --] = cbfanum; /* Set its ancestor */ else { /* Node has sub-nodes */ Gnum cblknum; cblknum = cblkptr->cblknbr - 1; /* Assume all column blocks will be scanned */ if ((cblkptr->cblknbr == 3) && /* If node is a nested dissection node */ (cblkptr->typeval == ORDERCBLKNEDI)) { /* With a non-empty separator */ Gnum cblanum; cblanum = *cblaptr; /* Save number of last column block of separator */ orderTree2 (treetax, cblaptr, &cblkptr->cblktab[cblknum], cbfanum); /* Scan separator apart */ cbfanum = cblanum; /* Separator becomes most recent ancestor of parts */ cblknum = 1; /* Only scan the two parts, not the separator */ } for ( ; cblknum >= 0; cblknum --) { orderTree2 (treetax, cblaptr, &cblkptr->cblktab[cblknum], cbfanum); #ifdef SCOTCH_DEBUG_ORDER2 if (*cblaptr < -1) errorPrint ("orderTree2: internal error (2)"); #endif /* SCOTCH_DEBUG_ORDER2 */ } } } scotch-6.0.4.dfsg/src/libscotch/vdgraph_separate_st.c0000644002563400244210000004300512412577405026034 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2009,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vdgraph_separate_st.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Cedric CHEVALIER **/ /** **/ /** FUNCTION : This module contains the global **/ /** distributed separation strategy and **/ /** method tables. **/ /** **/ /** DATES : # Version 5.0 : from : 16 feb 2006 **/ /** to 01 aug 2007 **/ /** # Version 5.1 : from : 05 nov 2007 **/ /** to 26 may 2009 **/ /** # Version 6.0 : from : 01 may 2014 **/ /** to 30 sep 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VDGRAPH_SEPARATE_ST #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "vgraph.h" #include "vgraph_separate_st.h" #include "dgraph.h" #include "dgraph_coarsen.h" #include "vdgraph.h" #include "vdgraph_separate_bd.h" #include "vdgraph_separate_df.h" #include "vdgraph_separate_ml.h" #include "vdgraph_separate_sq.h" #include "vdgraph_separate_st.h" #include "vdgraph_separate_zr.h" /* ** The static and global variables. */ static Vdgraph vdgraphdummy; /* Dummy distributed separator graph for offset computations */ static union { VdgraphSeparateBdParam param; StratNodeMethodData padding; } vdgraphseparatedefaultbd = { { 3, &stratdummy } }; static union { VdgraphSeparateDfParam param; StratNodeMethodData padding; } vdgraphseparatedefaultdf = { { 0, 300, 1.0, 0.0, 0.2 } }; static union { VdgraphSeparateMlParam param; StratNodeMethodData padding; } vdgraphseparatedefaultml = { { 5, 1000, 2, 10000, 0.8L, &stratdummy, &stratdummy, &stratdummy } }; static union { VdgraphSeparateSqParam param; StratNodeMethodData padding; } vdgraphseparatedefaultsq = { { &stratdummy } }; static StratMethodTab vdgraphseparatestmethtab[] = { /* Distributed graph separation methods array */ { VDGRAPHSEPASTMETHBD, "b", vdgraphSeparateBd, &vdgraphseparatedefaultbd }, { VDGRAPHSEPASTMETHDF, "d", vdgraphSeparateDf, &vdgraphseparatedefaultdf }, { VDGRAPHSEPASTMETHML, "m", vdgraphSeparateMl, &vdgraphseparatedefaultml }, { VDGRAPHSEPASTMETHSQ, "q", vdgraphSeparateSq, &vdgraphseparatedefaultsq }, { VDGRAPHSEPASTMETHZR, "z", vdgraphSeparateZr, NULL }, { -1, NULL, NULL, NULL } }; static StratParamTab vdgraphseparatestparatab[] = { /* Distributed graph separation method parameter list */ { VDGRAPHSEPASTMETHBD, STRATPARAMINT, "width", (byte *) &vdgraphseparatedefaultbd.param, (byte *) &vdgraphseparatedefaultbd.param.distmax, NULL }, { VDGRAPHSEPASTMETHBD, STRATPARAMSTRAT, "strat", (byte *) &vdgraphseparatedefaultbd.param, (byte *) &vdgraphseparatedefaultbd.param.strat, (void *) &vdgraphseparateststratab }, { VDGRAPHSEPASTMETHDF, STRATPARAMINT, "part", (byte *) &vdgraphseparatedefaultdf.param, (byte *) &vdgraphseparatedefaultdf.param.partval, NULL }, { VDGRAPHSEPASTMETHDF, STRATPARAMINT, "pass", (byte *) &vdgraphseparatedefaultdf.param, (byte *) &vdgraphseparatedefaultdf.param.passnbr, NULL }, { VDGRAPHSEPASTMETHDF, STRATPARAMDOUBLE, "bal", (byte *) &vdgraphseparatedefaultdf.param, (byte *) &vdgraphseparatedefaultdf.param.deltval, NULL }, { VDGRAPHSEPASTMETHDF, STRATPARAMDOUBLE, "dif", (byte *) &vdgraphseparatedefaultdf.param, (byte *) &vdgraphseparatedefaultdf.param.cdifval, NULL }, { VDGRAPHSEPASTMETHDF, STRATPARAMDOUBLE, "rem", (byte *) &vdgraphseparatedefaultdf.param, (byte *) &vdgraphseparatedefaultdf.param.cremval, NULL }, { VDGRAPHSEPASTMETHML, STRATPARAMSTRAT, "asc", (byte *) &vdgraphseparatedefaultml.param, (byte *) &vdgraphseparatedefaultml.param.stratasc, (void *) &vdgraphseparateststratab }, { VDGRAPHSEPASTMETHML, STRATPARAMSTRAT, "low", (byte *) &vdgraphseparatedefaultml.param, (byte *) &vdgraphseparatedefaultml.param.stratlow, (void *) &vdgraphseparateststratab }, { VDGRAPHSEPASTMETHML, STRATPARAMSTRAT, "seq", (byte *) &vdgraphseparatedefaultml.param, (byte *) &vdgraphseparatedefaultml.param.stratseq, (void *) &vdgraphseparateststratab }, { VDGRAPHSEPASTMETHML, STRATPARAMINT, "pass", (byte *) &vdgraphseparatedefaultml.param, (byte *) &vdgraphseparatedefaultml.param.passnbr, NULL }, { VDGRAPHSEPASTMETHML, STRATPARAMINT, "vert", (byte *) &vdgraphseparatedefaultml.param, (byte *) &vdgraphseparatedefaultml.param.coarnbr, NULL }, { VDGRAPHSEPASTMETHML, STRATPARAMINT, "dvert", (byte *) &vdgraphseparatedefaultml.param, (byte *) &vdgraphseparatedefaultml.param.foldmax, NULL }, { VDGRAPHSEPASTMETHML, STRATPARAMCASE, "fold", (byte *) &vdgraphseparatedefaultml.param, (byte *) &vdgraphseparatedefaultml.param.foldval, (void *) "nfd" }, { VDGRAPHSEPASTMETHML, STRATPARAMDOUBLE, "rat", (byte *) &vdgraphseparatedefaultml.param, (byte *) &vdgraphseparatedefaultml.param.coarrat, NULL }, { VDGRAPHSEPASTMETHML, STRATPARAMDEPRECATED | STRATPARAMINT, "dlevl", NULL, NULL, NULL }, /* Wait until MUMPS 5.0 */ { VDGRAPHSEPASTMETHML, STRATPARAMDEPRECATED | STRATPARAMINT, "proc", NULL, NULL, NULL }, { VDGRAPHSEPASTMETHSQ, STRATPARAMSTRAT, "strat", (byte *) &vdgraphseparatedefaultsq.param, (byte *) &vdgraphseparatedefaultsq.param.strat, (void *) &vgraphseparateststratab }, { VDGRAPHSEPASTMETHNBR, STRATPARAMINT, NULL, NULL, NULL, NULL } }; static StratParamTab vdgraphseparatestcondtab[] = { /* Distributed graph condition parameter table */ { STRATNODECOND, STRATPARAMINT, "edge", (byte *) &vdgraphdummy, (byte *) &vdgraphdummy.s.edgeglbnbr, NULL }, { STRATNODECOND, STRATPARAMINT, "levl", (byte *) &vdgraphdummy, (byte *) &vdgraphdummy.levlnum, NULL }, { STRATNODECOND, STRATPARAMINT, "load", (byte *) &vdgraphdummy, (byte *) &vdgraphdummy.s.veloglbsum, NULL }, { STRATNODECOND, STRATPARAMINT, "proc", (byte *) &vdgraphdummy, (byte *) &vdgraphdummy.s.procglbnbr, NULL }, { STRATNODECOND, STRATPARAMINT, "rank", (byte *) &vdgraphdummy, (byte *) &vdgraphdummy.s.proclocnum, NULL }, { STRATNODECOND, STRATPARAMINT, "vert", (byte *) &vdgraphdummy, (byte *) &vdgraphdummy.s.vertglbnbr, NULL }, { STRATNODENBR, STRATPARAMINT, NULL, NULL, NULL, NULL } }; StratTab vdgraphseparateststratab = { /* Strategy tables for distributed vertex separation methods */ vdgraphseparatestmethtab, vdgraphseparatestparatab, vdgraphseparatestcondtab }; /*******************************************/ /* */ /* This is the generic separation routine. */ /* */ /*******************************************/ /* This routine computes the separation of the ** given distributed graph according to the given ** strategy. ** All distributed vertex separation routines must ** be collective, that is, they must all return ** the same success or failure return value on all ** of the processors onto which they are run. Else, ** the behavior of the software is unpredictable. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int vdgraphSeparateSt ( Vdgraph * restrict const grafptr, /*+ Distributed separation graph +*/ const Strat * restrict const strat) /*+ Separation strategy +*/ { StratTest val; VdgraphStore savetab[2]; /* Results of the two strategies */ Gnum compglbload2; /* Saved global separator load */ int o; #ifdef SCOTCH_DEBUG_VDGRAPH2 MPI_Comm proccommold; /* Save area for old communicator */ #endif /* SCOTCH_DEBUG_VDGRAPH2 */ #ifdef SCOTCH_DEBUG_VDGRAPH2 if (sizeof (Gnum) != sizeof (INT)) { errorPrint ("vdgraphSeparateSt: invalid type specification for parser variables"); return (1); } if (sizeof (VdgraphSeparateSqParam) > sizeof (StratNodeMethodData)) { errorPrint ("vdgraphSeparateSt: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_VDGRAPH2 */ #ifdef SCOTCH_DEBUG_VDGRAPH1 if ((strat->tabl != &vdgraphseparateststratab) && (strat != &stratdummy)) { errorPrint ("vdgraphSeparateSt: invalid parameter (1)"); return (1); } #endif /* SCOTCH_DEBUG_VDGRAPH1 */ o = 0; switch (strat->type) { case STRATNODECONCAT : o = vdgraphSeparateSt (grafptr, strat->data.concat.strat[0]); /* Apply first strategy */ if (o == 0) /* If it worked all right */ o |= vdgraphSeparateSt (grafptr, strat->data.concat.strat[1]); /* Then apply second strategy */ break; case STRATNODECOND : o = stratTestEval (strat->data.cond.test, &val, (void *) grafptr); /* Evaluate expression */ if (o == 0) { /* If evaluation was correct */ #ifdef SCOTCH_DEBUG_VDGRAPH2 if ((val.typetest != STRATTESTVAL) || (val.typenode != STRATPARAMLOG)) { errorPrint ("vdgraphSeparateSt: invalid test result"); o = 1; break; } #endif /* SCOTCH_DEBUG_VDGRAPH2 */ if (val.data.val.vallog == 1) /* If expression is true */ o = vdgraphSeparateSt (grafptr, strat->data.cond.strat[0]); /* Apply first strategy */ else { /* Else if expression is false */ if (strat->data.cond.strat[1] != NULL) /* And if there is an else statement */ o = vdgraphSeparateSt (grafptr, strat->data.cond.strat[1]); /* Apply second strategy */ } } break; case STRATNODEEMPTY : break; case STRATNODESELECT : /* TODO: Can be multithreaded! */ if (((vdgraphStoreInit (grafptr, &savetab[0])) != 0) || /* Allocate save areas */ ((vdgraphStoreInit (grafptr, &savetab[1])) != 0)) { errorPrint ("vdgraphSeparateSt: out of memory"); vdgraphStoreExit (&savetab[0]); return (1); } vdgraphStoreSave (grafptr, &savetab[1]); /* Save initial bipartition */ if (vdgraphSeparateSt (grafptr, strat->data.select.strat[0]) != 0) { /* If first strategy didn't work */ vdgraphStoreUpdt (grafptr, &savetab[1]); /* Restore initial bipartition */ vdgraphStoreSave (grafptr, &savetab[0]); /* Save it as result */ } else { /* First strategy worked */ vdgraphStoreSave (grafptr, &savetab[0]); /* Save its result */ vdgraphStoreUpdt (grafptr, &savetab[1]); /* Restore initial bipartition */ } if (vdgraphSeparateSt (grafptr, strat->data.select.strat[1]) != 0) /* If second strategy didn't work */ vdgraphStoreUpdt (grafptr, &savetab[1]); /* Restore initial bipartition as its result */ compglbload2 = grafptr->s.veloglbsum - savetab[0].compglbload[0] - savetab[0].compglbload[1]; /* Compute saved separator load */ if ( (compglbload2 < grafptr->compglbload[2]) || /* If first strategy is better */ ((compglbload2 == grafptr->compglbload[2]) && (abs (savetab[0].compglbloaddlt) < abs (grafptr->compglbloaddlt)))) vdgraphStoreUpdt (grafptr, &savetab[0]); /* Restore its result */ vdgraphStoreExit (&savetab[0]); /* Free both save areas */ vdgraphStoreExit (&savetab[1]); break; #ifdef SCOTCH_DEBUG_VDGRAPH1 case STRATNODEMETHOD : #else /* SCOTCH_DEBUG_VDGRAPH1 */ default : #endif /* SCOTCH_DEBUG_VDGRAPH1 */ #ifdef SCOTCH_DEBUG_VDGRAPH2 proccommold = grafptr->s.proccomm; /* Create new communicator to isolate method communications */ MPI_Comm_dup (proccommold, &grafptr->s.proccomm); #endif /* SCOTCH_DEBUG_VDGRAPH2 */ o = strat->tabl->methtab[strat->data.method.meth].func (grafptr, (void *) &strat->data.method.data); #ifdef SCOTCH_DEBUG_VDGRAPH2 MPI_Comm_free (&grafptr->s.proccomm); /* Restore old communicator */ grafptr->s.proccomm = proccommold; #endif /* SCOTCH_DEBUG_VDGRAPH2 */ #ifdef SCOTCH_DEBUG_VDGRAPH1 break; default : errorPrint ("vdgraphSeparateSt: invalid parameter (2)"); return (1); #endif /* SCOTCH_DEBUG_VDGRAPH1 */ } return (o); } scotch-6.0.4.dfsg/src/libscotch/vgraph_check.c0000644002563400244210000001551411631447170024434 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vgraph_check.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the separator **/ /** graph consistency checking routine. **/ /** **/ /** DATES : # Version 3.2 : from : 24 aug 1996 **/ /** to 03 nov 1997 **/ /** # Version 4.0 : from : 12 dec 2001 **/ /** to 08 jan 2004 **/ /** # Version 5.0 : from : 16 sep 2006 **/ /** to : 16 sep 2006 **/ /** # Version 5.1 : from : 09 nov 2008 **/ /** to : 09 nov 2008 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VGRAPH #include "module.h" #include "common.h" #include "graph.h" #include "vgraph.h" /*************************/ /* */ /* These routines handle */ /* separator graphs. */ /* */ /*************************/ /* This routine checks the consistency ** of the given separator graph. ** It returns: ** - 0 : if graph data are consistent. ** - !0 : on error. */ int vgraphCheck ( const Vgraph * const grafptr) { Gnum vertnum; /* Number of current vertex */ Gnum fronnum; /* Number of frontier vertex */ Gnum compload[3]; Gnum compsize[3]; Gnum commcut[3]; if (grafptr->comploaddlt != (grafptr->compload[0] - grafptr->compload[1])) { errorPrint ("vgraphCheck: invalid balance"); return (1); } for (vertnum = grafptr->s.baseval; vertnum < grafptr->s.vertnnd; vertnum ++) { if (grafptr->parttax[vertnum] > 2) { errorPrint ("vgraphCheck: invalid part array"); return (1); } } if ((grafptr->fronnbr < 0) || (grafptr->fronnbr > grafptr->s.vertnbr)) { errorPrint ("vgraphCheck: invalid number of frontier vertices"); return (1); } for (fronnum = 0; fronnum < grafptr->fronnbr; fronnum ++) { Gnum vertnum; vertnum = grafptr->frontab[fronnum]; if ((vertnum < grafptr->s.baseval) || (vertnum >= grafptr->s.vertnnd)) { errorPrint ("vgraphCheck: invalid vertex index in frontier array"); return (1); } if (grafptr->parttax[vertnum] != 2) { errorPrint ("vgraphCheck: invalid vertex in frontier array"); return (1); } } compload[0] = compload[1] = compload[2] = 0; compsize[0] = compsize[1] = compsize[2] = 0; for (vertnum = grafptr->s.baseval; vertnum < grafptr->s.vertnnd; vertnum ++) { int partnum; /* Part of current vertex */ Gnum edgenum; /* Number of current edge */ partnum = (int) grafptr->parttax[vertnum]; compload[partnum] += (grafptr->s.velotax == NULL) ? 1 : grafptr->s.velotax[vertnum]; compsize[partnum] ++; commcut[0] = commcut[1] = commcut[2] = 0; if ((grafptr->s.verttax[vertnum] < grafptr->s.baseval) || (grafptr->s.verttax[vertnum] > grafptr->s.vendtax[vertnum])) { errorPrint ("vgraphCheck: invalid graph structure (1)"); return (1); } for (edgenum = grafptr->s.verttax[vertnum]; edgenum < grafptr->s.vendtax[vertnum]; edgenum ++) { Gnum vertend; vertend = grafptr->s.edgetax[edgenum]; if ((vertend < grafptr->s.baseval) || (vertend >= grafptr->s.vertnnd)) { errorPrint ("vgraphCheck: invalid graph structure (2)"); return (1); } commcut[grafptr->parttax[vertend]] ++; } #ifdef SCOTCH_DEBUG_VGRAPH3 if (partnum == 2) { if ((commcut[0] == 0) || (commcut[1] == 0)) errorPrintW ("vgraphCheck: no-use separator vertex%s (%ld)", /* Warning only */ ((grafptr->levlnum == 0) ? " at level 0" : ""), (long) vertnum); } else { #else if (partnum != 2) { #endif /* SCOTCH_DEBUG_VGRAPH3 */ if (commcut[1 - partnum] != 0) { errorPrint ("vgraphCheck: vertex should be in separator (%ld)", (long) vertnum); return (1); } } } if ((grafptr->compload[0] != compload[0]) || (grafptr->compload[1] != compload[1]) || (grafptr->compload[2] != compload[2])) { errorPrint ("vgraphCheck: invalid part loads"); return (1); } if (grafptr->comploaddlt != (grafptr->compload[0] - grafptr->compload[1])) { errorPrint ("vgraphCheck: invalid balance"); return (1); } if ((grafptr->compsize[0] != compsize[0]) || (grafptr->compsize[1] != compsize[1]) || (grafptr->fronnbr != compsize[2])) { errorPrint ("vgraphCheck: invalid part sizes"); return (1); } return (0); } scotch-6.0.4.dfsg/src/libscotch/hdgraph_order_sq.h0000644002563400244210000000640611631447170025330 0ustar trophimeutilisateurs du domaine/* Copyright 2008,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hdgraph_order_sq.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the halo distributed graph centra- **/ /** lized ordering algorithm. **/ /** **/ /** DATES : # Version 5.1 : from : 11 nov 2008 **/ /** to 04 nov 2010 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct HdgraphOrderSqParam_ { Strat * ordstratseq; /*+ Sequential ordering strategy +*/ } HdgraphOrderSqParam; /* ** The function prototypes. */ #ifndef HDGRAPH_ORDER_SQ #define static #endif int hdgraphOrderSq (Hdgraph * const, DorderCblk * const, const HdgraphOrderSqParam * const); int hdgraphOrderSq2 (Hgraph * restrict const, DorderCblk * restrict const, const Strat * restrict const); static DorderNode * hdgraphOrderSqTree (const Order * const); static void hdgraphOrderSqTree2 (DorderNode * const, Gnum * const, const OrderCblk * const, const Gnum, const Gnum); #undef static scotch-6.0.4.dfsg/src/libscotch/library_dgraph_order.c0000644002563400244210000003015712412035044026163 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2010,2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_order.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the distri- **/ /** buted graph ordering routines of the **/ /** libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 25 apr 2006 **/ /** to 11 nov 2008 **/ /** # Version 5.1 : from : 29 mar 2010 **/ /** to 14 aug 2010 **/ /** # Version 6.0 : from : 08 jan 2012 **/ /** to 28 sep 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "parser.h" #include "dgraph.h" #include "dorder.h" #include "hdgraph.h" #include "hdgraph_order_st.h" #include "ptscotch.h" /************************************/ /* */ /* These routines are the C API for */ /* the distributed graph ordering */ /* routines. */ /* */ /************************************/ /*+ This routine initializes an API ordering *** with respect to the given source graph *** and the locations of output parameters. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_dgraphOrderInit ( const SCOTCH_Dgraph * const grafptr, /*+ Distributed graph to order +*/ SCOTCH_Dordering * const ordeptr) /*+ Ordering structure to initialize +*/ { Dgraph * srcgrafptr; Dorder * srcordeptr; #ifdef SCOTCH_DEBUG_LIBRARY1 if (sizeof (SCOTCH_Dordering) < sizeof (Dorder)) { errorPrint ("SCOTCH_graphDorderInit: internal error"); return (1); } #endif /* SCOTCH_DEBUG_LIBRARY1 */ srcgrafptr = (Dgraph *) grafptr; /* Use structure as source graph */ srcordeptr = (Dorder *) ordeptr; return (dorderInit (srcordeptr, srcgrafptr->baseval, srcgrafptr->vertglbnbr, srcgrafptr->proccomm)); } /*+ This routine frees an API ordering. *** It returns: *** - VOID : in all cases. +*/ void SCOTCH_dgraphOrderExit ( const SCOTCH_Dgraph * const grafptr, SCOTCH_Dordering * const ordeptr) { dorderExit ((Dorder *) ordeptr); } /*+ This routine saves the contents of *** the given ordering to the given stream. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_dgraphOrderSave ( const SCOTCH_Dgraph * const grafptr, /*+ Graph to order +*/ const SCOTCH_Dordering * const ordeptr, /*+ Ordering to save +*/ FILE * const stream) /*+ Output stream +*/ { return (dorderSave ((Dorder *) ordeptr, (Dgraph *) grafptr, stream)); } /*+ This routine computes an ordering *** of the API ordering structure with *** respect to the given strategy. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_dgraphOrderCompute ( SCOTCH_Dgraph * const grafptr, /*+ Graph to order +*/ SCOTCH_Dordering * const ordeptr, /*+ Ordering to compute +*/ SCOTCH_Strat * const stratptr) /*+ Ordering strategy +*/ { return (SCOTCH_dgraphOrderComputeList (grafptr, ordeptr, 0, NULL, stratptr)); } /*+ This routine computes a partial ordering *** of the listed vertices of the API ordering *** structure graph with respect to the given *** strategy. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_dgraphOrderComputeList ( SCOTCH_Dgraph * const grafptr, /*+ Graph to order +*/ SCOTCH_Dordering * const ordeptr, /*+ Ordering to compute +*/ const SCOTCH_Num listnbr, /*+ Number of vertices in list +*/ const SCOTCH_Num * const listtab, /*+ List of vertex indices to order +*/ SCOTCH_Strat * const stratptr) /*+ Ordering strategy +*/ { Dorder * srcordeptr; /* Pointer to ordering */ DorderCblk * srccblkptr; /* Initial column block */ Dgraph * restrict srcgrafptr; /* Pointer to scotch graph */ Hdgraph srcgrafdat; /* Halo source graph structure */ Gnum srclistnbr; /* Number of items in list */ Gnum * restrict srclisttab; /* Subgraph vertex list */ const Strat * ordstratptr; /* Pointer to ordering strategy */ srcgrafptr = (Dgraph *) grafptr; #ifdef SCOTCH_DEBUG_DGRAPH2 if (dgraphCheck (srcgrafptr) != 0) { errorPrint ("SCOTCH_dgraphOrderComputeList: invalid input graph"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ if (*((Strat **) stratptr) == NULL) /* Set default ordering strategy if necessary */ SCOTCH_stratDgraphOrderBuild (stratptr, SCOTCH_STRATQUALITY, srcgrafptr->procglbnbr, 0, 0.2); ordstratptr = *((Strat **) stratptr); if (ordstratptr->tabl != &hdgraphorderststratab) { errorPrint ("SCOTCH_dgraphOrderComputeList: not a distributed ordering strategy"); return (1); } srcgrafdat.s = *srcgrafptr; /* Copy non-halo graph data */ srcgrafdat.s.edloloctax = NULL; /* Never mind about edge loads */ srcgrafdat.s.vlblloctax = NULL; /* Do not propagate vertex labels */ srcgrafdat.vhallocnbr = 0; /* No halo on graph */ srcgrafdat.vhndloctax = srcgrafdat.s.vendloctax; srcgrafdat.ehallocnbr = 0; srcgrafdat.levlnum = 0; srcordeptr = (Dorder *) ordeptr; /* Get ordering */ srclistnbr = (Gnum) listnbr; /* Build vertex list */ srclisttab = (Gnum *) listtab; intRandInit (); /* Check that random number generator is initialized */ /* TODO: Take list into account */ dorderFree (srcordeptr); /* Clean all existing ordering data */ if ((srccblkptr = dorderFrst (srcordeptr)) == NULL) { errorPrint ("SCOTCH_dgraphOrderComputeList: cannot create root column block"); return (1); } hdgraphOrderSt (&srcgrafdat, srccblkptr, ordstratptr); dorderDispose (srccblkptr); srcgrafptr->flagval |= srcgrafdat.s.flagval & (DGRAPHFREEEDGEGST | DGRAPHHASEDGEGST); srcgrafptr->edgegsttax = srcgrafdat.s.edgegsttax; /* Get edge ghost array from working graph if it gained one */ *srcgrafptr = srcgrafdat.s; /* Get back Dgraph structure, possibly updated (additional ghost data arrays) */ return (0); } /*+ This routine parses the given *** distributed graph ordering strategy. *** It returns: *** - 0 : if string successfully scanned. *** - !0 : on error. +*/ int SCOTCH_stratDgraphOrder ( SCOTCH_Strat * const stratptr, const char * const string) { if (*((Strat **) stratptr) != NULL) stratExit (*((Strat **) stratptr)); if ((*((Strat **) stratptr) = stratInit (&hdgraphorderststratab, string)) == NULL) { errorPrint ("SCOTCH_stratDgraphOrder: error in ordering strategy"); return (1); } return (0); } /*+ This routine provides predefined *** ordering strategies. *** It returns: *** - 0 : if string successfully initialized. *** - !0 : on error. +*/ int SCOTCH_stratDgraphOrderBuild ( SCOTCH_Strat * const stratptr, /*+ Strategy to create +*/ const SCOTCH_Num flagval, /*+ Desired characteristics +*/ const SCOTCH_Num procnbr, /*+ Number of processes for running +*/ const SCOTCH_Num levlnbr, /*+ Number of nested dissection levels +*/ const double balrat) /*+ Desired imbalance ratio +*/ { char bufftab[8192]; /* Should be enough */ char bbaltab[32]; char levltab[32]; char verttab[32]; Gnum vertnbr; char * tstpptr; char * tstsptr; char * oleaptr; char * osepptr; vertnbr = MAX (2000 * procnbr, 10000); vertnbr = MIN (vertnbr, 1000000); sprintf (bbaltab, "%lf", balrat); sprintf (levltab, GNUMSTRING, levlnbr); sprintf (verttab, GNUMSTRING, vertnbr); strcpy (bufftab, "n{sep=/()?m{vert=,asc=b{width=3,strat=q{strat=f}},low=q{strat=h},seq=q{strat=m{vert=120,low=h{pass=10},asc=b{width=3,bnd=f{bal=},org=h{pass=10}f{bal=}}}}};,ole=q{strat=n{sep=/()?m{vert=120,low=h{pass=10},asc=b{width=3,bnd=f{bal=},org=h{pass=10}f{bal=}}};,ole=,ose=}},ose=s,osq=n{sep=/()?m{vert=120,low=h{pass=10},asc=b{width=3,bnd=f{bal=},org=h{pass=10}f{bal=}}};,ole=,ose=}}"); switch (flagval & (SCOTCH_STRATLEVELMIN | SCOTCH_STRATLEVELMAX)) { case SCOTCH_STRATLEVELMIN : tstpptr = "0=0"; tstsptr = "(levl<)|(vert>240)"; break; case SCOTCH_STRATLEVELMAX : tstpptr = "(levl<)"; tstsptr = "(levl<)&(vert>240)"; break; case (SCOTCH_STRATLEVELMIN | SCOTCH_STRATLEVELMAX) : tstpptr = tstsptr = "levl<"; oleaptr = "s"; /* Simple ordering for leaves */ break; default : tstpptr = "0=0"; tstsptr = "vert>240"; break; } oleaptr = ((flagval & SCOTCH_STRATLEAFSIMPLE) != 0) ? "s" : "f{cmin=15,cmax=100000,frat=0.0}"; osepptr = ((flagval & SCOTCH_STRATSEPASIMPLE) != 0) ? "s" : "g"; stringSubst (bufftab, "", tstpptr); stringSubst (bufftab, "", tstsptr); stringSubst (bufftab, "", levltab); stringSubst (bufftab, "", oleaptr); stringSubst (bufftab, "", osepptr); stringSubst (bufftab, "", bbaltab); stringSubst (bufftab, "", verttab); if (SCOTCH_stratDgraphOrder (stratptr, bufftab) != 0) { errorPrint ("SCOTCH_stratDgraphOrderBuild: error in parallel ordering strategy"); return (1); } return (0); } scotch-6.0.4.dfsg/src/libscotch/hgraph_order_cp.c0000644002563400244210000007115312473176240025141 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2009,2014,2015 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hgraph_order_cp.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module orders vertices by compres- **/ /** sing vertices with identical adjacency **/ /** structure. **/ /** **/ /** DATES : # Version 3.2 : from : 29 aug 1998 **/ /** to 12 sep 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 03 jan 1999 **/ /** # Version 4.0 : from : 01 jan 2003 **/ /** to 05 jan 2005 **/ /** # Version 5.0 : from : 29 dec 2006 **/ /** to 22 may 2008 **/ /** # Version 5.1 : from : 01 oct 2009 **/ /** to : 01 oct 2009 **/ /** # Version 6.0 : from : 04 aug 2014 **/ /** to : 24 feb 2015 **/ /** **/ /** NOTES : # Pre-hashing proves itself extremely **/ /** efficient, since for graphs that **/ /** will be compressed very few writes **/ /** will be performed in the pre-hashing **/ /** array, and for others, for which pre- **/ /** hashing costs much more, it will save **/ /** time in the end. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HGRAPH_ORDER_CP #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "order.h" #include "hgraph.h" #include "hgraph_order_cp.h" #include "hgraph_order_st.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the ordering. ** It returns: ** - 0 : if the ordering could be computed. ** - !0 : on error. */ int hgraphOrderCp ( const Hgraph * restrict const finegrafptr, Order * restrict const fineordeptr, const Gnum ordenum, /*+ Zero-based ordering number +*/ OrderCblk * restrict const cblkptr, /*+ Single column-block +*/ const HgraphOrderCpParam * const paraptr) { Hgraph coargrafdat; /* Compressed halo subgraph */ Order coarordedat; /* Ordering of compressed halo subgraph */ Gnum * coarperitab; /* Coarse permutation array */ const Gnum * restrict coarperitax; /* Temporary based access to coarperitab */ Gnum coarvertnbr; /* Number of compressed vertices */ Gnum coarvertnum; /* Number of current compressed vertex */ Gnum coarvnhdsiz; /* Size of non-halo end vertex array; zero if graph has no halo */ Gnum coarvsizsiz; /* Size of coarse vertex sizes array; zero if no fine vertex loads */ Gnum * restrict coarvsiztax; /* Array of coarse vertex sizes (as number of merged fine vertices) */ Gnum coaredgenbr; /* Number of compressed edges */ Gnum coaredgenum; /* Number of current compressed edge */ Gnum coarenohnnd; /* Position in edge array of first edge of first halo vertex */ Gnum * restrict coarvpostax; /* Position in fine permutation of fine vertices merged into same vertex */ Gnum * restrict finecoartax; /* Original to compressed vertex number array */ HgraphOrderCpMate * restrict finematetab; /* Array of fine vertices that may be compressed with current vertex */ HgraphOrderCpHash * restrict finehashtab; /* Neighbor hash table */ Gnum finehashmsk; /* Mask for access to hash table */ int * restrict finehasptab; /* Pre-hashing table */ Gnum finehaspmsk; /* Mask for access to pre-hashing table */ Gnum * restrict finehsumtax; /* Array of hash values for each original vertex */ Gnum finevertnbr; /* Number of fine vertices in compressed elimination tree */ Gnum finevertnum; /* Number of current original vertex */ Gnum finevsizsum; /* Sum of compressed vertex sizes to build fine inverse permutation */ void * dataptr; /* Flag of memory allocation success */ Gnum * restrict const fineperitab = fineordeptr->peritab; const Gnum * restrict const fineverttax = finegrafptr->s.verttax; const Gnum * restrict const finevelotax = finegrafptr->s.velotax; const Gnum * restrict const finevendtax = finegrafptr->s.vendtax; const Gnum * restrict const finevnumtax = finegrafptr->s.vnumtax; const Gnum * restrict const finevnhdtax = finegrafptr->vnhdtax; const Gnum * restrict const fineedgetax = finegrafptr->s.edgetax; for (finehashmsk = 15; /* Set neighbor hash table sizes */ finehashmsk < finegrafptr->s.degrmax; finehashmsk = finehashmsk * 2 + 1) ; finehashmsk = finehashmsk * 4 + 3; /* Fill hash table at 1/4 of capacity */ if (((finecoartax = (Gnum *) memAlloc (finegrafptr->s.vertnbr * sizeof (Gnum))) == NULL) || (memAllocGroup ((void **) (void *) &finehashtab, (size_t) ((finehashmsk + 1) * sizeof (HgraphOrderCpHash)), &finematetab, (size_t) (finegrafptr->s.degrmax * sizeof (HgraphOrderCpMate)), NULL) == NULL) || ((finehsumtax = (Gnum *) memAlloc (finegrafptr->vnohnbr * sizeof (Gnum))) == NULL)) { errorPrint ("hgraphOrderCp: out of memory (1)"); if (finecoartax != NULL) { if (finehashtab != NULL) memFree (finehashtab); memFree (finecoartax); } return (1); } finehsumtax -= finegrafptr->s.baseval; /* TRICK: do not base finecoartax yet (see later) */ finehasptab = (int *) finecoartax; /* Use finecoartab as temporary pre-hash table */ for (finehaspmsk = 1; /* Get pre-hash mask that fits in finecoartab */ finehaspmsk < finegrafptr->s.vertnbr; /* Smallest (2^i)-1 value >= vertnbr */ finehaspmsk = finehaspmsk * 2 + 1) ; finehaspmsk >>= 1; /* Ensure masked data will always fit into finecoartab array */ finehaspmsk = (finehaspmsk * (sizeof (Gnum) / sizeof (int))) + ((sizeof (Gnum) / sizeof (int)) - 1); if (finehaspmsk >= ((sizeof (int) << (3 + 1)) - 1)) /* Only use 1/8 of array for pre-hashing, for increased cache locality */ finehaspmsk >>= 3; memSet (finehasptab, 0, (finehaspmsk + 1) * sizeof (int)); /* Initialize pre-hash table */ for (finevertnum = finegrafptr->s.baseval, coarvertnbr = finegrafptr->vnohnbr; /* For all non-halo vertices */ finevertnum < finegrafptr->vnohnnd; finevertnum ++) { Gnum fineedgenum; /* Current edge number */ Gnum finehsumval; /* Hash sum value */ Gnum finehsumbit; for (fineedgenum = fineverttax[finevertnum], finehsumval = finevertnum; /* For all edges, including halo edges */ fineedgenum < finevendtax[finevertnum]; fineedgenum ++) finehsumval += fineedgetax[fineedgenum]; finehsumtax[finevertnum] = finehsumval; finehsumbit = finehsumval & ((sizeof (int) << 3) - 1); /* Get bit mask and byte position (division should be optimized into a shift) */ finehsumval /= (sizeof (int) << 3); finehsumval &= finehaspmsk; /* Make hash sum value fit into finehasptab */ coarvertnbr -= (finehasptab[finehsumval] >> finehsumbit) & 1; /* If hash value already in pre-hash table, maybe one more vertex compressed */ finehasptab[finehsumval] |= (1 << finehsumbit); /* Put value into pre-hash table anyway */ } if ((double) coarvertnbr > ((double) finegrafptr->vnohnbr * paraptr->comprat)) { /* If graph needs not be compressed */ memFree (finehsumtax + finegrafptr->s.baseval); memFree (finehashtab); memFree (finecoartax); /* Not yet based */ return (hgraphOrderSt (finegrafptr, fineordeptr, ordenum, cblkptr, paraptr->stratunc)); } finecoartax -= finegrafptr->s.baseval; /* Base finecoartab array */ memSet (finehashtab, ~0, (finehashmsk + 1) * sizeof (HgraphOrderCpHash)); hgraphInit (&coargrafdat); /* Initialize compressed halo graph structure */ coargrafdat.s.baseval = 1; /* Base coarse graph to 1 because hgraphOrderHb and hgraphOrderHf prefer it */ for (finevertnum = finegrafptr->s.baseval, coarvertnbr = coargrafdat.s.baseval, coaredgenbr = finegrafptr->s.edgenbr; /* For all non-halo vertices */ finevertnum < finegrafptr->vnohnnd; finevertnum ++) { Gnum finedegrval; /* Degree of current fine vertex */ Gnum finehsumval; /* Current hash sum value */ Gnum finematenbr; /* Number of mates of current vertex */ Gnum fineedgenum; /* Current edge number */ finedegrval = finevendtax[finevertnum] - fineverttax[finevertnum]; finehsumval = finehsumtax[finevertnum]; finematenbr = 0; /* Reset potential mate array */ for (fineedgenum = fineverttax[finevertnum]; /* For all edges, including halo edges */ fineedgenum < finevendtax[finevertnum]; fineedgenum ++) { Gnum finevertend; finevertend = fineedgetax[fineedgenum]; if ((finevertend < finevertnum) && /* If neighbor has same characteristics */ (finehsumval == finehsumtax[finevertend]) && (finedegrval == (finevendtax[finevertend] - fineverttax[finevertend]))) { Gnum finematenum; Gnum coarvertend; for (finematenum = 0, coarvertend = finecoartax[finevertend]; /* Search if end vertex has already been compressed with some mate */ (finematenum < finematenbr) && (finematetab[finematenum].coarvertend != coarvertend); finematenum ++) ; if (finematenum == finematenbr) { /* If new slot needed */ finematetab[finematenum].coarvertend = coarvertend; /* Build it */ finematetab[finematenum].finevertend = finevertend; finematenbr ++; } } } finecoartax[finevertnum] = coarvertnbr ++; /* Assume no mate found */ if (finematenbr > 0) { /* If potential mates exist */ Gnum fineedgenum; /* Current edge number */ Gnum finehashnum; for (fineedgenum = fineverttax[finevertnum]; /* For all edges, including halo edges */ fineedgenum < finevendtax[finevertnum]; fineedgenum ++) { Gnum finevertend; finevertend = fineedgetax[fineedgenum]; /* Add end vertex to hash table */ for (finehashnum = (finevertend * HGRAPHORDERCPHASHPRIME) & finehashmsk; /* Search for empty slot in hash table */ finehashtab[finehashnum].vertnum == finevertnum; finehashnum = (finehashnum + 1) & finehashmsk) ; finehashtab[finehashnum].vertnum = finevertnum; finehashtab[finehashnum].vertend = finevertend; } for (finehashnum = (finevertnum * HGRAPHORDERCPHASHPRIME) & finehashmsk; /* Add current vertex to hash table */ finehashtab[finehashnum].vertnum == finevertnum; finehashnum = (finehashnum + 1) & finehashmsk) ; finehashtab[finehashnum].vertnum = finevertnum; finehashtab[finehashnum].vertend = finevertnum; finematenbr --; /* Point to first potential mate */ do { /* For all potential mates */ Gnum fineedgenum; /* Current edge number */ Gnum fineedgennd; for (fineedgenum = fineverttax[finematetab[finematenbr].finevertend], /* For all edges, including halo edges */ fineedgennd = finevendtax[finematetab[finematenbr].finevertend]; fineedgenum < fineedgennd; fineedgenum ++) { Gnum finevertend; finevertend = fineedgetax[fineedgenum]; for (finehashnum = (finevertend * HGRAPHORDERCPHASHPRIME) & finehashmsk; ; finehashnum = (finehashnum + 1) & finehashmsk) { if (finehashtab[finehashnum].vertnum != finevertnum) /* If mate neighbor not found in hash table */ goto loop_failed; /* Vertex cannot be merged to mate, so skip to next mate */ if (finehashtab[finehashnum].vertend == finevertend) /* Else if mate neighbor found in hash table */ break; /* Skip to next mate neighbor to find */ } } coarvertnbr --; /* Same adjacency structure */ finecoartax[finevertnum] = finematetab[finematenbr].coarvertend; /* Get number */ coaredgenbr -= finedegrval + 1; /* Remove exceeding edges */ break; loop_failed: ; } while (finematenbr -- > 0); } } coargrafdat.vnohnnd = coarvertnbr; /* Save number of non-halo vertices */ memFree (finehsumtax + finegrafptr->s.baseval); if ((double) (coarvertnbr - coargrafdat.s.baseval) > ((double) finegrafptr->vnohnbr * paraptr->comprat)) { /* If graph needs not be compressed */ memFree (finehashtab); memFree (finecoartax + finegrafptr->s.baseval); return (hgraphOrderSt (finegrafptr, fineordeptr, ordenum, cblkptr, paraptr->stratunc)); } for ( ; finevertnum < finegrafptr->s.vertnnd; finevertnum ++) /* For all halo vertices */ finecoartax[finevertnum] = coarvertnbr ++; /* Halo vertices are never compressed */ coargrafdat.s.flagval = GRAPHFREETABS | GRAPHVERTGROUP; /* Do not set HGRAPHFREEVNHD since vnhdtax allocated in group */ coargrafdat.s.vertnbr = coarvertnbr - coargrafdat.s.baseval; coargrafdat.s.vertnnd = coarvertnbr; coargrafdat.s.velosum = finegrafptr->s.velosum; coargrafdat.s.degrmax = finegrafptr->s.degrmax; coargrafdat.vnohnbr = coargrafdat.vnohnnd - coargrafdat.s.baseval; coargrafdat.vnlosum = finegrafptr->vnlosum; coarvnhdsiz = (finegrafptr->s.vertnbr == finegrafptr->vnohnbr) ? 0 : coargrafdat.vnohnbr; /* If no halo, no need for vnhdtax; will use vendtax */ coarvsizsiz = (finevelotax == NULL) ? 0 : coarvertnbr; /* If no fine vertex loads, use coarse velotax as coarvsiztax */ if ((dataptr = memAllocGroup ((void **) (void *) &coargrafdat.s.verttax, (size_t) ((coarvertnbr + 1) * sizeof (Gnum)), &coargrafdat.vnhdtax, (size_t) (coarvnhdsiz * sizeof (Gnum)), &coargrafdat.s.velotax, (size_t) (coarvertnbr * sizeof (Gnum)), &coarvsiztax, (size_t) (coarvsizsiz * sizeof (Gnum)), NULL)) != NULL) { dataptr = coargrafdat.s.edgetax = (Gnum *) memAlloc (coaredgenbr * sizeof (Gnum)); } if (dataptr == NULL) { errorPrint ("hgraphOrderCp: out of memory (2)"); hgraphExit (&coargrafdat); memFree (finehashtab); memFree (finecoartax + finegrafptr->s.baseval); return (1); } coargrafdat.s.verttax -= coargrafdat.s.baseval; coargrafdat.s.vendtax = coargrafdat.s.verttax + 1; /* Use compact representation of arrays */ coargrafdat.s.velotax -= coargrafdat.s.baseval; coargrafdat.s.edgetax -= coargrafdat.s.baseval; coargrafdat.vnhdtax = (finegrafptr->s.vertnbr == finegrafptr->vnohnbr) ? coargrafdat.s.vendtax : coargrafdat.vnhdtax - coargrafdat.s.baseval; coarvsiztax = (finevelotax == NULL) ? coargrafdat.s.velotax : coarvsiztax - coargrafdat.s.baseval; memSet (finehashtab, ~0, (finehashmsk + 1) * sizeof (HgraphOrderCpHash)); for (finevertnum = finegrafptr->s.baseval, coarvertnum = coaredgenum = coargrafdat.s.baseval; /* For all non-halo vertices */ finevertnum < finegrafptr->vnohnnd; finevertnum ++) { Gnum fineedgenum; /* Current edge number */ if (finecoartax[finevertnum] != coarvertnum) /* Skip fine vertices until we find one that is part of current coarse vertex */ continue; coargrafdat.s.verttax[coarvertnum] = coaredgenum; coarvsiztax[coarvertnum] = 1; /* Fill coargrafdat.s.velotax if finegrafptr has no vertex loads */ for (fineedgenum = fineverttax[finevertnum]; /* For all non-halo edges of vertex */ fineedgenum < finevnhdtax[finevertnum]; fineedgenum ++) { Gnum finevertend; Gnum finehashnum; finevertend = fineedgetax[fineedgenum]; if (finecoartax[finevertend] == coarvertnum) { /* If neighbor is merged into us, merge load but do not write edge */ coarvsiztax[coarvertnum] ++; /* Fill coargrafdat.s.velotax if finegrafptr has no vertex loads */ continue; } for (finehashnum = (finecoartax[finevertend] * HGRAPHORDERCPHASHPRIME) & finehashmsk; ; /* Search for end vertex in hash table */ finehashnum = (finehashnum + 1) & finehashmsk) { if (finehashtab[finehashnum].vertnum != coarvertnum) { finehashtab[finehashnum].vertnum = coarvertnum; finehashtab[finehashnum].vertend = coargrafdat.s.edgetax[coaredgenum ++] = finecoartax[finevertend]; break; } if (finehashtab[finehashnum].vertend == finecoartax[finevertend]) break; /* If edge already exists */ } } coargrafdat.vnhdtax[coarvertnum] = coaredgenum; /* Set end of non-halo edge sub-array */ for ( ; fineedgenum < finegrafptr->s.vendtax[finevertnum]; fineedgenum ++) { /* For edges linking to halo vertices */ Gnum finevertend; finevertend = fineedgetax[fineedgenum]; coargrafdat.s.edgetax[coaredgenum ++] = finecoartax[finevertend]; /* Halo vertices are always defined and unique */ } coarvertnum ++; } for (coarenohnnd = coaredgenum; finevertnum < finegrafptr->s.vertnnd; finevertnum ++) { /* For all halo vertices */ Gnum fineedgenum; /* Current edge number */ #ifdef SCOTCH_DEBUG_ORDER2 if (finecoartax[finevertnum] != coarvertnum) { errorPrint ("hgraphOrderCp: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_ORDER2 */ coargrafdat.s.verttax[coarvertnum] = coaredgenum; coarvsiztax[coarvertnum] = 1; /* Fill coargrafdat.s.velotax if finegrafptr has no vertex loads */ for (fineedgenum = fineverttax[finevertnum]; /* For all edges of halo vertex */ fineedgenum < finevendtax[finevertnum]; fineedgenum ++) { Gnum finevertend; Gnum finehashnum; finevertend = fineedgetax[fineedgenum]; #ifdef SCOTCH_DEBUG_ORDER2 if (finecoartax[finevertend] == coarvertnum) { /* No neighbor can be merged into us since halo vertices are unique */ errorPrint ("hgraphOrderCp: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_ORDER2 */ for (finehashnum = (finecoartax[finevertend] * HGRAPHORDERCPHASHPRIME) & finehashmsk; ; /* Search for end vertex in hash table */ finehashnum = (finehashnum + 1) & finehashmsk) { if (finehashtab[finehashnum].vertnum != coarvertnum) { finehashtab[finehashnum].vertnum = coarvertnum; finehashtab[finehashnum].vertend = coargrafdat.s.edgetax[coaredgenum ++] = finecoartax[finevertend]; break; } if (finehashtab[finehashnum].vertend == finecoartax[finevertend]) break; /* If edge already exists */ } } coarvertnum ++; } coargrafdat.s.verttax[coarvertnum] = coaredgenum; /* Set end of compact vertex array */ coargrafdat.s.edlosum = coargrafdat.s.edgenbr = coaredgenum - coargrafdat.s.baseval; coargrafdat.enohsum = coargrafdat.enohnbr = coargrafdat.s.edgenbr - 2 * (coaredgenum - coarenohnnd); if (finevelotax != NULL) { /* If fine graph has vertex loads */ memSet (coargrafdat.s.velotax + coargrafdat.s.baseval, 0, coargrafdat.s.vertnbr * sizeof (Gnum)); for (finevertnum = finegrafptr->s.baseval; finevertnum < finegrafptr->s.vertnnd; finevertnum ++) /* Compute vertex loads for compressed graph */ coargrafdat.s.velotax[finecoartax[finevertnum]] += finevelotax[finevertnum]; } memFree (finehashtab); coargrafdat.s.edgetax = (Gnum *) memRealloc (coargrafdat.s.edgetax + coargrafdat.s.baseval, coargrafdat.s.edgenbr * sizeof (Gnum)) - coargrafdat.s.baseval; #ifdef SCOTCH_DEBUG_ORDER2 if (hgraphCheck (&coargrafdat) != 0) { errorPrint ("hgraphOrderCp: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_ORDER2 */ if ((coarperitab = memAlloc (coargrafdat.vnohnbr * sizeof (Gnum))) == NULL) { /* Coarse permutation only for non-halo vertices */ errorPrint ("hgraphOrderCp: out of memory (3)"); hgraphExit (&coargrafdat); memFree (finecoartax + finegrafptr->s.baseval); return (1); } orderInit (&coarordedat, coargrafdat.s.baseval, coargrafdat.vnohnbr, coarperitab); /* Build ordering of compressed subgraph */ if (hgraphOrderSt (&coargrafdat, &coarordedat, 0, &coarordedat.cblktre, paraptr->stratcpr) != 0) { memFree (coarperitab); hgraphExit (&coargrafdat); memFree (finecoartax + finegrafptr->s.baseval); return (1); } *cblkptr = coarordedat.cblktre; /* Link sub-tree to ordering */ coarordedat.cblktre.cblktab = NULL; /* Unlink sub-tree from sub-ordering */ finevertnbr = hgraphOrderCpTree (coarordedat.peritab, /* Expand sub-tree */ coarvsiztax, cblkptr, 0); #ifdef SCOTCH_DEBUG_ORDER2 if (finevertnbr != finegrafptr->vnohnbr) { errorPrint ("hgraphOrderCp: internal error (4)"); return (1); } #endif /* SCOTCH_DEBUG_ORDER2 */ fineordeptr->treenbr += coarordedat.treenbr - 1; /* Adjust number of tree nodes */ fineordeptr->cblknbr += coarordedat.cblknbr - 1; /* Adjust number of column blocks */ coarvpostax = coargrafdat.s.verttax; /* Re-cycle verttab (not velotab as may be merged with coarvsiztab) */ coarperitax = coarperitab - coargrafdat.s.baseval; for (coarvertnum = coargrafdat.s.baseval, finevsizsum = 0; /* Compute initial indices for inverse permutation expansion */ coarvertnum < coargrafdat.vnohnnd; coarvertnum ++) { coarvpostax[coarperitax[coarvertnum]] = finevsizsum; finevsizsum += coarvsiztax[coarperitax[coarvertnum]]; } if (finevnumtax == NULL) { /* If fine graph is original graph */ for (finevertnum = finegrafptr->s.baseval; finevertnum < finegrafptr->vnohnnd; finevertnum ++) /* Compute fine permutation */ fineperitab[coarvpostax[finecoartax[finevertnum]] ++] = finevertnum; } else { /* Graph is not original graph */ for (finevertnum = finegrafptr->s.baseval; finevertnum < finegrafptr->vnohnnd; finevertnum ++) /* Compute fine permutation */ fineperitab[coarvpostax[finecoartax[finevertnum]] ++] = finevnumtax[finevertnum]; } memFree (coarperitab); memFree (finecoartax + finegrafptr->s.baseval); orderExit (&coarordedat); hgraphExit (&coargrafdat); /* Free coarvsiztab as part of vertex group */ return (0); } /* This routine turns the coarse elimination ** tree produced by the ordering of the coarse ** graph into a fine elimination tree, according ** to the cardinality of the coarse vertices. ** It returns: ** - !0 : overall number of fine vertices, in all cases. */ static Gnum hgraphOrderCpTree ( const Gnum * restrict const coarperitab, /* Coarse inverse permutation */ const Gnum * restrict const coarvsiztax, /* Array of fine sizes of coarse vertices */ OrderCblk * restrict const coficblkptr, /* Current coarse/fine column block cell */ const Gnum coarordenum) /* Compressed vertex to start expansion at */ { Gnum finevertnbr; /* Number of fine vertices in subtree */ finevertnbr = 0; /* No fine vertices yet */ if (coficblkptr->cblktab == NULL) { /* If leaf of column block tree */ Gnum coarvnumnum; for (coarvnumnum = coarordenum; coarvnumnum < coarordenum + coficblkptr->vnodnbr; coarvnumnum ++) finevertnbr += coarvsiztax[coarperitab[coarvnumnum]]; /* Sum-up fine vertices */ } else { Gnum coarvertnbr; /* Number of coarse vertices in cell */ Gnum coarvertsum; /* Number of coarse vertices in subtree */ Gnum coficblknum; /* Index in column block array */ for (coficblknum = 0, coarvertsum = coarordenum; /* Start at current coarse index */ coficblknum < coficblkptr->cblknbr; coficblknum ++) { coarvertnbr = coficblkptr->cblktab[coficblknum].vnodnbr; /* Save number of coarse vertices */ finevertnbr += hgraphOrderCpTree (coarperitab, coarvsiztax, &coficblkptr->cblktab[coficblknum], coarvertsum); coarvertsum += coarvertnbr; /* Sum-up coarse vertices */ } } coficblkptr->vnodnbr = finevertnbr; /* Set number of fine vertices */ return (finevertnbr); /* Return accumulated number */ } scotch-6.0.4.dfsg/src/libscotch/library_graph_coarsen_f.c0000644002563400244210000001021012474554132026643 0ustar trophimeutilisateurs du domaine/* Copyright 2011,2015 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_coarsen_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the Fortran API for the **/ /** graph coarsening routine of the **/ /** libSCOTCH library. **/ /** **/ /** DATES : # Version 5.1 : from : 07 aug 2011 **/ /** to 07 aug 2011 **/ /** # Version 6.0 : from : 28 feb 2015 **/ /** to 28 feb 2015 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the coarsening routine. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFGRAPHCOARSEN, scotchfgraphcoarsen, ( \ SCOTCH_Graph * const finegrafptr, \ SCOTCH_Graph * const coargrafptr, \ SCOTCH_Num * const coarmulttab, \ SCOTCH_Num * const coarnbrptr, \ double * const coarratptr, \ int * const revaptr), \ (finegrafptr, coargrafptr, coarmulttab, coarnbrptr, coarratptr, revaptr)) { *revaptr = SCOTCH_graphCoarsen (finegrafptr, coargrafptr, coarmulttab, *coarnbrptr, *coarratptr); } /* ** */ FORTRAN ( \ SCOTCHFGRAPHCOARSENBUILD, scotchfgraphcoarsenbuild, ( \ SCOTCH_Graph * const finegrafptr, \ SCOTCH_Graph * const coargrafptr, \ SCOTCH_Num * const coarmulttab, \ SCOTCH_Num * const coarnbrptr, \ SCOTCH_Num * const finematetab, \ int * const revaptr), \ (finegrafptr, coargrafptr, coarmulttab, coarnbrptr, finematetab, revaptr)) { *revaptr = SCOTCH_graphCoarsenBuild (finegrafptr, coargrafptr, coarmulttab, *coarnbrptr, finematetab); } scotch-6.0.4.dfsg/src/libscotch/hmesh_check.c0000644002563400244210000001124211631447170024243 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh_check.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles the halo source **/ /** mesh functions. **/ /** **/ /** DATES : # Version 4.0 : from : 12 sep 2002 **/ /** to 11 may 2004 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HMESH #include "module.h" #include "common.h" #include "graph.h" #include "mesh.h" #include "hmesh.h" /****************************************/ /* */ /* These routines handle source meshes. */ /* */ /****************************************/ /* This routine checks the consistency ** of the given halo mesh. ** It returns: ** - 0 : if halo mesh data are consistent. ** - !0 : on error. */ int hmeshCheck ( const Hmesh * const meshptr) { Gnum vnhlsum; if ((meshptr->vnohnnd < meshptr->m.vnodbas) || (meshptr->vnohnnd > meshptr->m.vnodnnd)) { errorPrint ("hmeshCheck: invalid halo node numbers"); return (1); } if (meshCheck (&meshptr->m) != 0) { errorPrint ("hmeshCheck: invalid non-halo mesh structure"); return (1); } if (meshptr->vehdtax != meshptr->m.vendtax) { Gnum veihnbr; Gnum velmnum; for (velmnum = meshptr->m.velmbas, veihnbr = 0; /* For all element vertices */ velmnum < meshptr->m.velmnnd; velmnum ++) { if ((meshptr->vehdtax[velmnum] < meshptr->m.verttax[velmnum]) || (meshptr->vehdtax[velmnum] > meshptr->m.vendtax[velmnum])) { errorPrint ("hmeshCheck: invalid non-halo end vertex array"); return (1); } if (meshptr->vehdtax[velmnum] == meshptr->m.verttax[velmnum]) veihnbr ++; } if (veihnbr != meshptr->veihnbr) { errorPrint ("hmeshCheck: invalid number of halo-isolated element vertices (1)"); return (1); } } else { if (meshptr->veihnbr != 0) { errorPrint ("hmeshCheck: invalid number of halo-isolated element vertices (2)"); return (1); } } if (meshptr->m.vnlotax == NULL) /* Recompute non-halo node vertex load sum */ vnhlsum = meshptr->vnohnnd - meshptr->m.vnodbas; else { Gnum vnodnum; for (vnodnum = meshptr->m.vnodbas, vnhlsum = 0; vnodnum < meshptr->vnohnnd; vnodnum ++) vnhlsum += meshptr->m.vnlotax[vnodnum]; } if (vnhlsum != meshptr->vnhlsum) { errorPrint ("hmeshCheck: invalid non-halo vertex load sum"); return (1); } return (0); } scotch-6.0.4.dfsg/src/libscotch/kdgraph_map_rb_part.c0000644002563400244210000005022712473174702026001 0ustar trophimeutilisateurs du domaine/* Copyright 2008-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kdgraph_map_rb_part.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module performs the Dual Recursive **/ /** Bipartitioning mapping algorithm **/ /** in parallel. It does so for complete **/ /** graph architectures, hence performing **/ /** plain graph partitioning, which **/ /** avoids to take care of what the other **/ /** processes are doing. **/ /** **/ /** DATES : # Version 5.1 : from : 21 jun 2008 **/ /** to 31 aug 2011 **/ /** # Version 6.0 : from : 03 mar 2011 **/ /** to 31 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define KDGRAPH_MAP_RB #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "arch.h" #include "bgraph.h" #include "bgraph_bipart_st.h" #include "mapping.h" #include "kgraph.h" #include "kgraph_map_st.h" #include "dgraph.h" #include "dmapping.h" #include "bdgraph.h" #include "bdgraph_bipart_st.h" #include "kdgraph.h" #include "kdgraph_map_rb.h" #include "kdgraph_map_rb_part.h" #include "kdgraph_map_st.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine sequentially computes a mapping ** of the given subgraph and adds its result to ** the given distributed mapping. Since no ** cocycle data is needed, the un-synchronized ** sequential Scotch routine can be used as is. ** It returns: ** - 0 : if the mapping could be computed. ** - !0 : on error. */ static int kdgraphMapRbPartSequ ( KdgraphMapRbPartGraph * restrict const grafptr, Dmapping * restrict const mappptr, const KdgraphMapRbPartData * restrict const dataptr) { Graph * restrict cgrfptr; Kgraph kgrfdat; /* Centralized mapping graph */ DmappingFrag * restrict fragptr; cgrfptr = &grafptr->data.cgrfdat; if (kgraphInit (&kgrfdat, cgrfptr, &mappptr->archdat, &grafptr->domnorg, 0, NULL, NULL, 1, 1, NULL) != 0) { errorPrint ("kdgraphMapRbPartSequ: cannot initialize centralized graph"); return (1); } kgrfdat.s.flagval = (kgrfdat.s.flagval & ~GRAPHBITSUSED) | cgrfptr->flagval; /* Free sequential graph along with mapping data */ kgrfdat.s.vnumtax = NULL; /* Remove index array if any */ kgrfdat.comploadrat = dataptr->comploadrat; /* Use ideal load of full graph and not of subgraph */ if (kgraphMapSt (&kgrfdat, dataptr->paraptr->stratseq) != 0) { /* Compute sequential mapping */ kgraphExit (&kgrfdat); return (1); } if (((fragptr = memAlloc (sizeof (DmappingFrag))) == NULL) || ((fragptr->vnumtab = memAlloc (cgrfptr->vertnbr * sizeof (Gnum))) == NULL)) { errorPrint ("kdgraphMapRbPartSequ: out of memory"); if (fragptr != NULL) memFree (fragptr); kgraphExit (&kgrfdat); return (1); } fragptr->vertnbr = cgrfptr->vertnbr; fragptr->parttab = kgrfdat.m.parttax + kgrfdat.s.baseval; fragptr->domnnbr = kgrfdat.m.domnnbr; fragptr->domntab = kgrfdat.m.domntab; kgrfdat.m.parttax = NULL; /* Keep sequential mapping arrays for distributed mapping fragment */ kgrfdat.m.domntab = NULL; if (kgrfdat.m.domnmax > kgrfdat.m.domnnbr) fragptr->domntab = memRealloc (fragptr->domntab, kgrfdat.m.domnnbr * sizeof (ArchDom)); /* Reallocate mapping array */ if (cgrfptr->vnumtax != NULL) memCpy (fragptr->vnumtab, cgrfptr->vnumtax + cgrfptr->baseval, cgrfptr->vertnbr * sizeof (Gnum)); else { Gnum vertadj; Gnum vertnum; for (vertnum = 0, vertadj = cgrfptr->baseval; vertnum < cgrfptr->vertnbr; vertnum ++) fragptr->vnumtab[vertnum] = vertadj + vertnum; } dmapAdd (mappptr, fragptr); /* Add mapping fragment */ kgraphExit (&kgrfdat); /* Free mapping without some of its arrays */ return (0); } /* This routine builds either a centralized or a ** distributed subgraph, according to the number ** of processes in the given part. The calling ** conventions of this routine have been designed ** so as to allow for multi-threading. */ static void * kdgraphMapRbPartFold2 ( void * const dataptr) /* Pointer to thread data */ { KdgraphMapRbPartThread * fldthrdptr; /* Thread input parameters */ KdgraphMapRbPartGraph * restrict fldgrafptr; /* Pointer to folded graph area */ Dgraph indgrafdat; /* Induced distributed graph */ void * o; fldthrdptr = (KdgraphMapRbPartThread *) dataptr; fldgrafptr = fldthrdptr->fldgrafptr; if (fldthrdptr->fldprocnbr == 0) /* If recursion stopped, build mapping of graph part */ return ((void *) (intptr_t) kdgraphMapRbAddPart (fldthrdptr->orggrafptr, fldthrdptr->mappptr, fldthrdptr->inddomnptr, fldthrdptr->indvertnbr, fldthrdptr->indparttax + fldthrdptr->orggrafptr->baseval, fldthrdptr->indpartval)); dgraphInit (&indgrafdat, fldthrdptr->orggrafptr->proccomm); /* Re-use communicator of original graph */ if (dgraphInducePart (fldthrdptr->orggrafptr, fldthrdptr->indparttax, /* Compute unfinished induced subgraph on all processes */ fldthrdptr->indvertnbr, fldthrdptr->indpartval, &indgrafdat) != 0) return ((void *) 1); if (fldthrdptr->fldprocnbr > 1) { /* If subpart has several processes, fold a distributed graph */ o = (void *) (intptr_t) dgraphFold2 (&indgrafdat, fldthrdptr->fldpartval, /* Fold temporary induced subgraph from all processes */ &fldgrafptr->data.dgrfdat, fldthrdptr->fldproccomm, NULL, NULL, MPI_INT); fldgrafptr->data.dgrfdat.flagval |= DGRAPHFREECOMM; /* Split communicator has to be freed */ } else { /* Create a centralized graph */ Graph * restrict fldcgrfptr; fldcgrfptr = (fldthrdptr->fldprocnum == 0) ? &fldgrafptr->data.cgrfdat : NULL; /* See if we are the receiver */ o = (void *) (intptr_t) dgraphGather (&indgrafdat, fldcgrfptr); /* Gather centralized subgraph from all other processes */ } dgraphExit (&indgrafdat); /* Free temporary induced graph */ return (o); } static int kdgraphMapRbPartFold ( Bdgraph * restrict const actgrafptr, Dmapping * restrict const mappptr, const ArchDom * restrict const domnsubtab, KdgraphMapRbPartGraph * restrict const fldgrafptr) { KdgraphMapRbPartThread fldthrdtab[2]; int fldprocnbr; /* Number of processes in part of this process */ int fldprocnbr0; /* Number of processes in first part */ int fldprocnum; int fldproccol; int fldpartval; Gnum indvertlocmax; /* Local number of vertices in biggest subgraph */ Gnum indflagtab[2]; /* Array of subjob continuation flags */ GraphPart indpartmax; /* Induced part having most vertices */ #ifdef SCOTCH_PTHREAD Dgraph orggrafdat; /* Structure for copying graph fields except communicator */ pthread_t thrdval; /* Data of second thread */ #endif /* SCOTCH_PTHREAD */ int o; indflagtab[0] = /* Assume both jobs will not continue */ indflagtab[1] = 0; if ((actgrafptr->compglbsize0 != 0) && /* If graph has been bipartitioned */ (actgrafptr->compglbsize0 != actgrafptr->s.vertglbnbr)) { if (archVar (&mappptr->archdat)) { /* If architecture is variable-sized */ if (actgrafptr->compglbsize0 > 1) /* If graph is not single vertex, go on */ indflagtab[0] = ~0; /* All bits set to 1 */ if ((actgrafptr->s.vertglbnbr - actgrafptr->compglbsize0) > 1) indflagtab[1] = ~0; } else { /* Architecture is not variable-sized */ if (archDomSize (&mappptr->archdat, &domnsubtab[0]) > 1) /* Stop when target is one vertex */ indflagtab[0] = ~0; if (archDomSize (&mappptr->archdat, &domnsubtab[1]) > 1) indflagtab[1] = ~0; } } if ((indflagtab[0] | indflagtab[1]) == 0) { /* If both subjobs stop */ fldgrafptr->procnbr = 0; /* Nothing to do on return */ return (kdgraphMapRbAddBoth (&actgrafptr->s, mappptr, domnsubtab, actgrafptr->partgsttax + actgrafptr->s.baseval)); /* Map both subdomains in the same time */ } if ((2 * actgrafptr->compglbsize0) >= actgrafptr->s.vertglbnbr) { /* Get part of largest subgraph */ indpartmax = 0; indvertlocmax = actgrafptr->complocsize0; } else { indpartmax = 1; indvertlocmax = actgrafptr->s.vertlocnbr - actgrafptr->complocsize0; } fldprocnbr0 = (actgrafptr->s.procglbnbr + 1) / 2; /* Get number of processes in part 0 (always more than in part 1) */ fldthrdtab[0].mappptr = mappptr; /* Load data to pass to the subgraph building routines */ fldthrdtab[0].orggrafptr = &actgrafptr->s; fldthrdtab[0].inddomnptr = &domnsubtab[indpartmax]; fldthrdtab[0].indvertnbr = indvertlocmax; fldthrdtab[0].indpartval = indpartmax; fldthrdtab[0].indparttax = actgrafptr->partgsttax; fldthrdtab[0].fldgrafptr = fldgrafptr; fldthrdtab[0].fldpartval = 0; fldthrdtab[0].fldprocnbr = indflagtab[indpartmax] & fldprocnbr0; /* Stop if domain limited to one vertex */ fldthrdtab[1].mappptr = mappptr; fldthrdtab[1].orggrafptr = &actgrafptr->s; /* Assume jobs won't be run concurrently */ fldthrdtab[1].inddomnptr = &domnsubtab[indpartmax ^ 1]; fldthrdtab[1].indvertnbr = actgrafptr->s.vertlocnbr - indvertlocmax; fldthrdtab[1].indpartval = indpartmax ^ 1; fldthrdtab[1].indparttax = actgrafptr->partgsttax; fldthrdtab[1].fldgrafptr = fldgrafptr; fldthrdtab[1].fldpartval = 1; fldthrdtab[1].fldprocnbr = indflagtab[indpartmax ^ 1] & (actgrafptr->s.procglbnbr - fldprocnbr0); /* Stop if domain limited to one vertex */ if (actgrafptr->s.proclocnum < fldprocnbr0) { /* Compute color and rank in our future subpart */ fldpartval = 0; fldprocnum = actgrafptr->s.proclocnum; fldprocnbr = fldprocnbr0; } else { fldpartval = 1; fldprocnum = actgrafptr->s.proclocnum - fldprocnbr0; fldprocnbr = actgrafptr->s.procglbnbr - fldprocnbr0; } fldgrafptr->domnorg = *fldthrdtab[fldpartval].inddomnptr; /* Set data of our folded graph */ fldgrafptr->procnbr = fldthrdtab[fldpartval].fldprocnbr; fldgrafptr->levlnum = actgrafptr->levlnum + 1; /* One level down in the DRB process */ fldproccol = fldpartval; /* Split color is the part value */ if (fldgrafptr->procnbr <= 1) /* If our part will have only one processor or will stop */ fldproccol = MPI_UNDEFINED; /* Do not create any sub-communicator for it */ if (MPI_Comm_split (actgrafptr->s.proccomm, fldproccol, fldprocnum, &fldthrdtab[fldpartval].fldproccomm) != MPI_SUCCESS) { /* Assign folded communicator to proper part */ errorPrint ("kdgraphMapRbPartFold: communication error"); return (1); } fldthrdtab[fldpartval].fldprocnum = fldprocnum; /* This will be our rank afterwards */ fldthrdtab[fldpartval ^ 1].fldprocnum = -1; /* Other part will not be in communicator */ fldthrdtab[fldpartval ^ 1].fldproccomm = MPI_COMM_NULL; #ifdef SCOTCH_PTHREAD if ((indflagtab[0] & indflagtab[1]) != 0) { /* If both subjobs have meaningful things to do in parallel */ orggrafdat = actgrafptr->s; /* Create a separate graph structure to change its communicator */ orggrafdat.flagval = (orggrafdat.flagval & ~DGRAPHFREEALL) | DGRAPHFREECOMM; fldthrdtab[1].orggrafptr = &orggrafdat; MPI_Comm_dup (actgrafptr->s.proccomm, &orggrafdat.proccomm); /* Duplicate communicator to avoid interferences in communications */ if (pthread_create (&thrdval, NULL, kdgraphMapRbPartFold2, (void *) &fldthrdtab[1]) != 0) /* If could not create thread */ o = ((int) (intptr_t) kdgraphMapRbPartFold2 ((void *) &fldthrdtab[0])) || /* Perform inductions in sequence */ ((int) (intptr_t) kdgraphMapRbPartFold2 ((void *) &fldthrdtab[1])); else { /* Newly created thread is processing subgraph 1, so let's process subgraph 0 */ void * o2; o = (int) (intptr_t) kdgraphMapRbPartFold2 ((void *) &fldthrdtab[0]); /* Work on copy with private communicator */ pthread_join (thrdval, &o2); o |= (int) (intptr_t) o2; } MPI_Comm_free (&orggrafdat.proccomm); } else #endif /* SCOTCH_PTHREAD */ o = ((int) (intptr_t) kdgraphMapRbPartFold2 ((void *) &fldthrdtab[0])) || /* Perform inductions in sequence */ ((int) (intptr_t) kdgraphMapRbPartFold2 ((void *) &fldthrdtab[1])); return (o); } /* This routine performs the Dual Recursive ** Bipartitioning mapping in parallel. ** It returns: ** - 0 : if the mapping could be computed. ** - !0 : on error. */ static int kdgraphMapRbPart2 ( KdgraphMapRbPartGraph * restrict const grafptr, const KdgraphMapRbPartData * restrict const dataptr) { ArchDom domnsubtab[2]; /* Temporary subdomains */ Bdgraph actgrafdat; /* Active bipartitioning graph */ KdgraphMapRbPartGraph indgrafdat; /* Induced folded graph area */ Gnum comploadavg; Dmapping * mappptr; int o; mappptr = dataptr->mappptr; o = ((archVar (&mappptr->archdat)) && /* If architecture is variable-sized */ (grafptr->data.dgrfdat.vertglbnbr <= 1)) /* And source subgraph is of minimal size */ ? 1 /* Then do not bipartition target more */ : archDomBipart (&mappptr->archdat, &grafptr->domnorg, &domnsubtab[0], &domnsubtab[1]); switch (o) { case 1 : /* If target domain is terminal */ return (kdgraphMapRbAddOne (&grafptr->data.dgrfdat, mappptr, &grafptr->domnorg)); /* Update mapping and return */ case 2 : /* On error */ errorPrint ("kdgraphMapRbPart2: cannot bipartition domain"); return (1); } if (dgraphGhst (&grafptr->data.dgrfdat) != 0) { /* Compute ghost edge array if not already present, to have vertgstnbr (and procsidtab) */ errorPrint ("kdgraphMapRbPart2: cannot compute ghost edge array"); return (1); } o = bdgraphInit (&actgrafdat, &grafptr->data.dgrfdat, NULL, &mappptr->archdat, domnsubtab); /* Create active graph */ actgrafdat.levlnum = grafptr->levlnum; /* Initial level of bipartition graph is DRB recursion level */ comploadavg = (double) actgrafdat.s.veloglbsum / (double) archDomWght (&mappptr->archdat, &grafptr->domnorg); actgrafdat.compglbload0min = actgrafdat.compglbload0avg - (Gnum) MIN ((dataptr->comploadmax - comploadavg) * actgrafdat.domnwght[0], (comploadavg - dataptr->comploadmin) * actgrafdat.domnwght[1]); actgrafdat.compglbload0max = actgrafdat.compglbload0avg + (Gnum) MIN ((comploadavg - dataptr->comploadmin) * actgrafdat.domnwght[0], (dataptr->comploadmax - comploadavg) * actgrafdat.domnwght[1]); if ((o != 0) || (bdgraphBipartSt (&actgrafdat, dataptr->paraptr->stratsep) != 0)) { /* Bipartition edge-separation graph */ bdgraphExit (&actgrafdat); return (1); } o = kdgraphMapRbPartFold (&actgrafdat, mappptr, domnsubtab, &indgrafdat); bdgraphExit (&actgrafdat); /* Free additional bipartitioning data */ dgraphExit (&grafptr->data.dgrfdat); /* Free graph before going to next level */ if (o == 0) { if (indgrafdat.procnbr == 1) /* If sequential job */ o = kdgraphMapRbPartSequ (&indgrafdat, mappptr, dataptr); else if (indgrafdat.procnbr > 1) /* If distributed job */ o = kdgraphMapRbPart2 (&indgrafdat, dataptr); } return (o); } int kdgraphMapRbPart ( Kdgraph * restrict const grafptr, Kdmapping * restrict const mappptr, const KdgraphMapRbParam * restrict const paraptr) { KdgraphMapRbPartGraph grafdat; KdgraphMapRbPartData datadat; grafdat.domnorg = grafptr->m.domnorg; /* Used in all cases */ grafdat.procnbr = grafptr->s.procglbnbr; grafdat.levlnum = 0; /* Set initial DRB level to zero */ datadat.mappptr = mappptr->mappptr; datadat.paraptr = paraptr; datadat.comploadrat = (double) grafptr->s.veloglbsum / (double) archDomWght (&mappptr->mappptr->archdat, &grafptr->m.domnorg); datadat.comploadmin = (1.0 - paraptr->kbalval) * datadat.comploadrat; datadat.comploadmax = (1.0 + paraptr->kbalval) * datadat.comploadrat; if (grafptr->s.procglbnbr <= 1) { /* If single process, switch immediately to sequential mode */ if (dgraphGather (&grafptr->s, &grafdat.data.cgrfdat) != 0) { errorPrint ("kdgraphMapRbPart: cannot centralize graph"); return (1); } return (kdgraphMapRbPartSequ (&grafdat, mappptr->mappptr, &datadat)); } grafdat.data.dgrfdat = grafptr->s; /* Create a clone graph that will never be freed */ grafdat.data.dgrfdat.flagval &= ~DGRAPHFREEALL; return (kdgraphMapRbPart2 (&grafdat, &datadat)); /* Perform DRB */ } scotch-6.0.4.dfsg/src/libscotch/library_mesh.c0000644002563400244210000004305011631447170024464 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_mesh.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the source **/ /** mesh handling routines of the **/ /** libSCOTCH library. **/ /** **/ /** DATES : # Version 4.0 : from : 23 sep 2002 **/ /** to 11 may 2004 **/ /** # Version 5.1 : from : 17 nov 2010 **/ /** to 17 nov 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "graph.h" #include "mesh.h" #include "scotch.h" /************************************/ /* */ /* These routines are the C API for */ /* the mesh handling routines. */ /* */ /************************************/ /*+ This routine reserves a memory area *** of a size sufficient to store a *** centralized mesh structure. *** It returns: *** - !NULL : if the initialization succeeded. *** - NULL : on error. +*/ SCOTCH_Mesh * SCOTCH_meshAlloc () { return ((SCOTCH_Mesh *) memAlloc (sizeof (SCOTCH_Mesh))); } /*+ This routine initializes the opaque *** mesh structure used to handle meshes *** in the Scotch library. *** It returns: *** - 0 : if the initialization succeeded. *** - !0 : on error. +*/ int SCOTCH_meshInit ( SCOTCH_Mesh * const meshptr) { if (sizeof (SCOTCH_Num) != sizeof (Gnum)) { errorPrint ("SCOTCH_meshInit: internal error (1)"); return (1); } if (sizeof (SCOTCH_Mesh) < sizeof (Mesh)) { errorPrint ("SCOTCH_meshInit: internal error (2)"); return (1); } return (meshInit ((Mesh *) meshptr)); } /*+ This routine frees the contents of the *** given opaque mesh structure. *** It returns: *** - VOID : in all cases. +*/ void SCOTCH_meshExit ( SCOTCH_Mesh * const meshptr) { meshExit ((Mesh *) meshptr); } /*+ This routine loads the given opaque mesh *** structure with the data of the given stream. *** The base value allows the user to set the *** mesh base to 0 or 1, or to the base value *** of the stream if the base value is equal *** to -1. *** It returns: *** - 0 : if the loading succeeded. *** - !0 : on error. +*/ int SCOTCH_meshLoad ( SCOTCH_Mesh * const meshptr, FILE * const stream, const SCOTCH_Num baseval) { if ((baseval < -1) || (baseval > 1)) { errorPrint ("SCOTCH_meshLoad: invalid base parameter"); return (1); } return (meshLoad ((Mesh * const) meshptr, stream, (Gnum) baseval)); } /*+ This routine saves the contents of the given *** opaque mesh structure to the given stream. *** It returns: *** - 0 : if the saving succeeded. *** - !0 : on error. +*/ int SCOTCH_meshSave ( const SCOTCH_Mesh * const meshptr, FILE * const stream) { return (meshSave ((const Mesh * const) meshptr, stream)); } /*+ This routine fills the contents of the given *** opaque mesh structure with the data provided *** by the user. The base value allows the user to *** set the mesh base to 0 or 1. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_meshBuild ( SCOTCH_Mesh * const meshptr, /* Mesh structure to fill */ const SCOTCH_Num velmbas, /* Base index for element vertices */ const SCOTCH_Num vnodbas, /* Base index for node vertices */ const SCOTCH_Num velmnbr, /* Number of elements in mesh graph */ const SCOTCH_Num vnodnbr, /* Number of vertices in mesh graph */ const SCOTCH_Num * const verttab, /* Vertex array [vertnbr or vertnbr+1] */ const SCOTCH_Num * const vendtab, /* Vertex end array [vertnbr] */ const SCOTCH_Num * const velotab, /* Element vertex load array */ const SCOTCH_Num * const vnlotab, /* Node vertex load array */ const SCOTCH_Num * const vlbltab, /* Vertex label array */ const SCOTCH_Num edgenbr, /* Number of edges (arcs) */ const SCOTCH_Num * const edgetab) /* Edge array [edgenbr] */ { Mesh * srcmeshptr; /* Pointer to source mesh structure */ Gnum degrmax; /* Maximum degree */ Gnum veisnbr; /* Number of isolated element vertices */ Gnum vertnum; /* Current vertex number */ #ifdef SCOTCH_DEBUG_LIBRARY1 if (sizeof (SCOTCH_Mesh) < sizeof (Mesh)) { errorPrint ("SCOTCH_meshBuild: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_LIBRARY1 */ if ((velmbas < 0) || (vnodbas < 0) || ((velmbas > 1) && (vnodbas > 1))) { errorPrint ("SCOTCH_meshBuild: invalid base parameters"); return (1); } if (((velmbas + velmnbr) != vnodbas) && ((vnodbas + vnodnbr) != velmbas)) { errorPrint ("SCOTCH_meshBuild: invalid element or node range"); return (1); } srcmeshptr = (Mesh *) meshptr; /* Use structure as source mesh */ srcmeshptr->flagval = MESHNONE; srcmeshptr->baseval = MIN (velmbas, vnodbas); srcmeshptr->velmnbr = velmnbr; srcmeshptr->velmbas = velmbas; srcmeshptr->velmnnd = velmbas + velmnbr; srcmeshptr->vnodnbr = vnodnbr; srcmeshptr->vnodbas = vnodbas; srcmeshptr->vnodnnd = vnodbas + vnodnbr; srcmeshptr->verttax = (Gnum *) verttab - srcmeshptr->baseval; srcmeshptr->vendtax = ((vendtab == NULL) || (vendtab == verttab) || (vendtab == verttab + 1)) ? srcmeshptr->verttax + 1 : (Gnum *) vendtab - srcmeshptr->baseval; srcmeshptr->velotax = ((velotab == NULL) || (velotab == verttab)) ? NULL : (Gnum *) velotab - srcmeshptr->velmbas; srcmeshptr->vnlotax = ((vnlotab == NULL) || (vnlotab == verttab)) ? NULL : (Gnum *) vnlotab - srcmeshptr->vnodbas; srcmeshptr->vlbltax = ((vlbltab == NULL) || (vlbltab == verttab)) ? NULL : (Gnum *) vlbltab - srcmeshptr->baseval; srcmeshptr->edgenbr = edgenbr; srcmeshptr->edgetax = (Gnum *) edgetab - srcmeshptr->baseval; if (srcmeshptr->velotax == NULL) /* Compute element vertex load sum */ srcmeshptr->velosum = srcmeshptr->velmnbr; else { Gnum velosum; /* Sum of element vertex loads */ for (vertnum = srcmeshptr->velmbas, velosum = 0; vertnum < srcmeshptr->velmnnd; vertnum ++) velosum += srcmeshptr->velotax[vertnum]; srcmeshptr->velosum = velosum; } if (srcmeshptr->vnlotax == NULL) /* Compute node vertex load sum */ srcmeshptr->vnlosum = srcmeshptr->vnodnbr; else { Gnum vnlosum; /* Sum of node vertex loads */ for (vertnum = srcmeshptr->vnodbas, vnlosum = 0; vertnum < srcmeshptr->vnodnnd; vertnum ++) vnlosum += srcmeshptr->vnlotax[vertnum]; srcmeshptr->vnlosum = vnlosum; } for (vertnum = srcmeshptr->velmbas, veisnbr = degrmax = 0; /* Compute maximum degree */ vertnum < srcmeshptr->velmnnd; vertnum ++) { Gnum degrval; /* Degree of current vertex */ degrval = srcmeshptr->vendtax[vertnum] - srcmeshptr->verttax[vertnum]; if (degrval > degrmax) degrmax = degrval; else if (degrval == 0) /* Count number of isolated element vertices */ veisnbr ++; } srcmeshptr->veisnbr = veisnbr; for (vertnum = srcmeshptr->vnodbas; /* Compute maximum degree */ vertnum < srcmeshptr->vnodnnd; vertnum ++) { Gnum degrval; /* Degree of current vertex */ degrval = srcmeshptr->vendtax[vertnum] - srcmeshptr->verttax[vertnum]; if (degrval > degrmax) degrmax = degrval; } srcmeshptr->degrmax = degrmax; #ifdef SCOTCH_DEBUG_LIBRARY1 if (meshCheck (srcmeshptr) != 0) { errorPrint ("SCOTCH_meshBuild: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_LIBRARY1 */ return (0); } /*+ This routine checks the consistency *** of the given mesh. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_meshCheck ( const SCOTCH_Mesh * const meshptr) { return (meshCheck ((const Mesh * const) meshptr)); } /*+ This routine accesses mesh size data. *** NULL pointers on input indicate unwanted *** data. *** It returns: *** - VOID : in all cases. +*/ void SCOTCH_meshSize ( const SCOTCH_Mesh * const meshptr, SCOTCH_Num * const velmnbr, SCOTCH_Num * const vnodnbr, SCOTCH_Num * const edgenbr) { const Mesh * srcmeshptr; srcmeshptr = (Mesh *) meshptr; if (velmnbr != NULL) *velmnbr = (SCOTCH_Num) srcmeshptr->velmnbr; if (vnodnbr != NULL) *vnodnbr = (SCOTCH_Num) srcmeshptr->vnodnbr; if (edgenbr != NULL) *edgenbr = (SCOTCH_Num) srcmeshptr->edgenbr; } /*+ This routine accesses all of the mesh data. *** NULL pointers on input indicate unwanted *** data. NULL pointers on output indicate *** unexisting arrays. *** It returns: *** - VOID : in all cases. +*/ void SCOTCH_meshData ( const SCOTCH_Mesh * const meshptr, /* Mesh structure to read */ SCOTCH_Num * const velmbas, /* Base index for elements */ SCOTCH_Num * const vnodbas, /* Base index for nodes */ SCOTCH_Num * const velmnbr, /* Number of elements */ SCOTCH_Num * const vnodnbr, /* Number of nodes */ SCOTCH_Num ** const verttab, /* Vertex array [vertnbr+1] */ SCOTCH_Num ** const vendtab, /* Vertex array [vertnbr] */ SCOTCH_Num ** const velotab, /* Element vertex load array */ SCOTCH_Num ** const vnlotab, /* Vertex load array */ SCOTCH_Num ** const vlbltab, /* Vertex label array */ SCOTCH_Num * const edgenbr, /* Number of edges (arcs) */ SCOTCH_Num ** const edgetab, /* Edge array [edgenbr] */ SCOTCH_Num * const degrnbr) /* Maximum degree */ { const Mesh * srcmeshptr; /* Pointer to source mesh structure */ srcmeshptr = (const Mesh *) meshptr; if (velmnbr != NULL) *velmnbr = srcmeshptr->velmnbr; if (vnodnbr != NULL) *vnodnbr = srcmeshptr->vnodnbr; if (velmbas != NULL) *velmbas = srcmeshptr->velmbas; if (vnodbas != NULL) *vnodbas = srcmeshptr->vnodbas; if (verttab != NULL) *verttab = srcmeshptr->verttax + srcmeshptr->baseval; if (vendtab != NULL) *vendtab = srcmeshptr->vendtax + srcmeshptr->baseval; if (velotab != NULL) *velotab = (srcmeshptr->velotax != NULL) ? (srcmeshptr->velotax + srcmeshptr->velmbas) : NULL; if (vnlotab != NULL) *vnlotab = (srcmeshptr->vnlotax != NULL) ? (srcmeshptr->vnlotax + srcmeshptr->vnodbas) : NULL; if (vlbltab != NULL) *vlbltab = (srcmeshptr->vlbltax != NULL) ? (srcmeshptr->vlbltax + srcmeshptr->baseval) : NULL; if (edgenbr != NULL) *edgenbr = srcmeshptr->edgenbr; if (edgetab != NULL) *edgetab = srcmeshptr->edgetax + srcmeshptr->baseval; if (degrnbr != NULL) *degrnbr = srcmeshptr->degrmax; } /*+ This routine computes statistics *** on the given graph. *** It returns: *** - VOID : in all cases. +*/ void SCOTCH_meshStat ( const SCOTCH_Mesh * const meshptr, SCOTCH_Num * const vnlominptr, /* Vertex loads only for nodes */ SCOTCH_Num * const vnlomaxptr, SCOTCH_Num * const vnlosumptr, double * const vnloavgptr, double * const vnlodltptr, SCOTCH_Num * const edegminptr, /* Element degree data */ SCOTCH_Num * const edegmaxptr, double * const edegavgptr, double * const edegdltptr, SCOTCH_Num * const ndegminptr, /* Node degree data */ SCOTCH_Num * const ndegmaxptr, double * const ndegavgptr, double * const ndegdltptr) { const Mesh * restrict srcmeshptr; Gnum vnlomin; Gnum vnlomax; double vnloavg; double vnlodlt; Gnum degrmin; Gnum degrmax; double degravg; double degrdlt; srcmeshptr = (Mesh *) meshptr; vnlodlt = 0.0L; if (srcmeshptr->vnodnbr > 0) { if (srcmeshptr->vnlotax != NULL) { /* If mesh has node vertex loads */ Gnum vnodnum; vnlomin = GNUMMAX; vnlomax = 0; vnloavg = (double) srcmeshptr->vnlosum / (double) srcmeshptr->vnodnbr; for (vnodnum = srcmeshptr->vnodbas; vnodnum < srcmeshptr->vnodnnd; vnodnum ++) { if (srcmeshptr->vnlotax[vnodnum] < vnlomin) /* Account for vertex loads */ vnlomin = srcmeshptr->vnlotax[vnodnum]; if (srcmeshptr->vnlotax[vnodnum] > vnlomax) vnlomax = srcmeshptr->vnlotax[vnodnum]; vnlodlt += fabs ((double) srcmeshptr->vnlotax[vnodnum] - vnloavg); } vnlodlt /= (double) srcmeshptr->vnodnbr; } else { vnlomin = vnlomax = 1; vnloavg = 1.0L; } } else { vnlomin = vnlomax = 0; vnloavg = 0.0L; } if (vnlominptr != NULL) *vnlominptr = (SCOTCH_Num) vnlomin; if (vnlomaxptr != NULL) *vnlomaxptr = (SCOTCH_Num) vnlomax; if (vnlosumptr != NULL) *vnlosumptr = (SCOTCH_Num) srcmeshptr->vnlosum; if (vnloavgptr != NULL) *vnloavgptr = (double) vnloavg; if (vnlodltptr != NULL) *vnlodltptr = (double) vnlodlt; degrmax = 0; degrdlt = 0.0L; if (srcmeshptr->velmnbr > 0) { Gnum velmnum; degrmin = GNUMMAX; degravg = (double) srcmeshptr->edgenbr / (double) (2 * srcmeshptr->velmnbr); for (velmnum = srcmeshptr->velmbas; velmnum < srcmeshptr->velmnnd; velmnum ++) { Gnum degrval; degrval = srcmeshptr->vendtax[velmnum] - srcmeshptr->verttax[velmnum]; /* Get element degree */ if (degrval < degrmin) degrmin = degrval; if (degrval > degrmax) degrmax = degrval; degrdlt += fabs ((double) degrval - degravg); } degrdlt /= (double) srcmeshptr->velmnbr; } else { degrmin = 0; degravg = 0.0L; } if (edegminptr != NULL) *edegminptr = (SCOTCH_Num) degrmin; if (edegmaxptr != NULL) *edegmaxptr = (SCOTCH_Num) degrmax; if (edegavgptr != NULL) *edegavgptr = (double) degravg; if (edegdltptr != NULL) *edegdltptr = (double) degrdlt; degrmax = 0; degrdlt = 0.0L; if (srcmeshptr->vnodnbr > 0) { Gnum vnodnum; degrmin = GNUMMAX; degravg = (double) srcmeshptr->edgenbr / (double) (2 * srcmeshptr->vnodnbr); for (vnodnum = srcmeshptr->vnodbas; vnodnum < srcmeshptr->vnodnnd; vnodnum ++) { Gnum degrval; degrval = srcmeshptr->vendtax[vnodnum] - srcmeshptr->verttax[vnodnum]; /* Get element degree */ if (degrval < degrmin) degrmin = degrval; if (degrval > degrmax) degrmax = degrval; degrdlt += fabs ((double) degrval - degravg); } degrdlt /= (double) srcmeshptr->vnodnbr; } else { degrmin = 0; degravg = 0.0L; } if (ndegminptr != NULL) *ndegminptr = (SCOTCH_Num) degrmin; if (ndegmaxptr != NULL) *ndegmaxptr = (SCOTCH_Num) degrmax; if (ndegavgptr != NULL) *ndegavgptr = (double) degravg; if (ndegdltptr != NULL) *ndegdltptr = (double) degrdlt; } scotch-6.0.4.dfsg/src/libscotch/dgraph_gather_all.c0000644002563400244210000005534112054775445025452 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_gather_all.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the routine which **/ /** builds a centralized graph on all **/ /** processes by gathering the pieces of **/ /** a distributed graph. **/ /** **/ /** DATES : # Version 5.0 : from : 07 feb 2006 **/ /** to 17 jun 2008 **/ /** # Version 5.1 : from : 30 jul 2010 **/ /** to 30 jul 2010 **/ /** # Version 6.0 : from : 27 nov 2012 **/ /** to 27 nov 2012 **/ /** **/ /** NOTES : # The definitions of MPI_Gather and **/ /** MPI_Gatherv indicate that elements in **/ /** the receive array should not be **/ /** written more than once. Great care **/ /** should be taken to enforce this rule, **/ /** especially when the number of **/ /** vertices in the centralized graph is **/ /** smaller than the number of **/ /** processes. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DGRAPH #include "module.h" #include "common.h" #include "comm.h" #include "graph.h" #include "dgraph.h" /* This function gathers on all processes ** the pieces of a distributed graph to ** build a centralized graph. This function ** does not compute edlosum on the centralized ** graphs when it is already given in the passed ** value, as a non-negative number. ** It returns: ** - 0 : if graph data are consistent. ** - !0 : on error. */ static int dgraphGatherAll3 ( Gnum * const senddattab, const Gnum sendcntnbr, Gnum * const recvdattab, Gnum * const recvcnttab, Gnum * const recvdsptab, const int rootnum, MPI_Comm comm) { if (rootnum == -1) /* If collective communication wanted */ return (commAllgatherv (senddattab, sendcntnbr, GNUM_MPI, recvdattab, recvcnttab, recvdsptab, GNUM_MPI, comm)); else return (commGatherv (senddattab, sendcntnbr, GNUM_MPI, recvdattab, recvcnttab, recvdsptab, GNUM_MPI, rootnum, comm)); } int dgraphGatherAll2 ( const Dgraph * restrict const dgrfptr, /* Distributed graph */ Graph * restrict cgrfptr, /* Centralized graph */ const Gnum edlosum, /* -1 means recompute */ const int protnum) /* -1 means allgather */ { Gnum baseval; Gnum * restrict verttax; /* Target vertex array for root, dummy for non-roots */ Gnum * restrict velotax; /* Target vertex load array for root, dummy for non-roots */ Gnum * restrict vnumtax; /* Target vertex index array for root, dummy for non-roots */ Gnum * restrict vlbltax; /* Target vertex label array for root, dummy for non-roots */ Gnum * restrict edgetax; /* Target edge array for root, dummy for non-roots */ Gnum * restrict edlotax; /* Target edge load array for root, dummy for non-roots */ Gnum vertlocnbr; /* Size of temporary distributed vertex array */ Gnum * restrict vertloctax; /* Temporary vertex array if graph is not compact */ Gnum edgelocnbr; /* Size of temporary distributed edge array */ Gnum * restrict edgeloctab; /* Temporary edge array if distributed graph is not compact */ Gnum * restrict recvcnttab; /* Count array for gather operations */ Gnum * restrict recvdsptab; /* Displacement array for gather operations */ int cheklocval; int chekglbval; const Gnum * restrict const edgeloctax = dgrfptr->edgeloctax; #ifdef SCOTCH_DEBUG_DGRAPH1 cheklocval = 0; if (cgrfptr != NULL) /* Centralized graphs should be provided by all */ cheklocval = 1; if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_SUM, dgrfptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphGatherAll2: communication error (1)"); return (1); } if (protnum == -1) { /* If collective gathering wanted */ if (chekglbval != dgrfptr->procglbnbr) { errorPrint ("dgraphGatherAll2: centralized graphs should be provided on every process"); return (1); } } else { /* Single gathering wanted */ if (chekglbval != 1) { errorPrint ("dgraphGatherAll2: should have only one root"); return (1); } } #endif /* SCOTCH_DEBUG_DGRAPH1 */ baseval = dgrfptr->baseval; cheklocval = 0; if (cgrfptr != NULL) { /* If root process */ Gnum velonbr; Gnum vnumnbr; Gnum vlblnbr; Gnum edlonbr; velonbr = (dgrfptr->veloloctax != NULL) ? dgrfptr->vertglbnbr : 0; vnumnbr = (dgrfptr->vnumloctax != NULL) ? dgrfptr->vertglbnbr : 0; vlblnbr = (dgrfptr->vlblloctax != NULL) ? dgrfptr->vertglbnbr : 0; edlonbr = (dgrfptr->edloloctax != NULL) ? dgrfptr->edgeglbnbr : 0; if (memAllocGroup ((void **) (void *) &cgrfptr->verttax, (size_t) ((dgrfptr->vertglbnbr + 1) * sizeof (Gnum)), &cgrfptr->velotax, (size_t) (velonbr * sizeof (Gnum)), &cgrfptr->vnumtax, (size_t) (vnumnbr * sizeof (Gnum)), &cgrfptr->vlbltax, (size_t) (vlblnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("dgraphGatherAll2: out of memory (1)"); cheklocval = 1; } else if (memAllocGroup ((void **) (void *) &cgrfptr->edgetax, (size_t) (dgrfptr->edgeglbnbr * sizeof (Gnum)), &cgrfptr->edlotax, (size_t) (edlonbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("dgraphGatherAll2: out of memory (2)"); cheklocval = 1; } } if (dgrfptr->vendloctax == (dgrfptr->vertloctax + 1)) { /* If distributed graph is compact */ vertlocnbr = /* No need to recompact arrays */ edgelocnbr = 0; } else { /* Need extra space to compact vertex and edge arrays before sending */ vertlocnbr = dgrfptr->vertlocnbr; edgelocnbr = dgrfptr->edgelocnbr; } if (cheklocval == 0) { if (memAllocGroup ((void **) (void *) &recvcnttab, (size_t) (dgrfptr->procglbnbr * sizeof (Gnum)), /* Allocated for non-roots too but don't care as these are very small */ &recvdsptab, (size_t) (dgrfptr->procglbnbr * sizeof (Gnum)), &vertloctax, (size_t) (vertlocnbr * sizeof (Gnum)), &edgeloctab, (size_t) (edgelocnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("dgraphGatherAll2: out of memory (3)"); cheklocval = 1; } } #ifdef SCOTCH_DEBUG_DGRAPH1 /* Communication cannot be merged with a useful one */ if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, dgrfptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphGatherAll2: communication error (2)"); return (1); } #else /* SCOTCH_DEBUG_DGRAPH1 */ chekglbval = cheklocval; #endif /* SCOTCH_DEBUG_DGRAPH1 */ if (chekglbval != 0) { if (recvcnttab != NULL) memFree (recvcnttab); if (cgrfptr->verttax != NULL) { if (cgrfptr->edgetax != NULL) memFree (cgrfptr->edgetax); /* Arrays are not based yet */ memFree (cgrfptr->verttax); } return (1); } if (cgrfptr != NULL) { verttax = cgrfptr->verttax - baseval; velotax = (dgrfptr->veloloctax != NULL) ? (cgrfptr->velotax - baseval) : NULL; vnumtax = (dgrfptr->vnumloctax != NULL) ? (cgrfptr->vnumtax - baseval) : NULL; vlbltax = (dgrfptr->vlblloctax != NULL) ? (cgrfptr->vlbltax - baseval) : NULL; edgetax = cgrfptr->edgetax - baseval; edlotax = (dgrfptr->edloloctax != NULL) ? (cgrfptr->edlotax - baseval) : NULL; cgrfptr->flagval = GRAPHFREEVERT | GRAPHVERTGROUP | GRAPHFREEEDGE | GRAPHEDGEGROUP; /* Other arrays are grouped, too */ cgrfptr->baseval = baseval; cgrfptr->vertnbr = dgrfptr->vertglbnbr; cgrfptr->vertnnd = dgrfptr->vertglbnbr + baseval; cgrfptr->verttax = verttax; cgrfptr->vendtax = verttax + 1; /* Compact edge array */ cgrfptr->velotax = velotax; cgrfptr->velosum = dgrfptr->veloglbsum; cgrfptr->vnumtax = vnumtax; cgrfptr->vlbltax = vlbltax; cgrfptr->edgenbr = dgrfptr->edgeglbnbr; cgrfptr->edgetax = edgetax; cgrfptr->edlotax = edlotax; cgrfptr->edlosum = edlosum; cgrfptr->degrmax = dgrfptr->degrglbmax; cgrfptr->procptr = NULL; /* This field exists only when compiled with SCOTCH_PTSCOTCH */ } #ifdef SCOTCH_DEBUG_DGRAPH2 /* Prevent Valgrind from yelling */ else { /* Process is not root */ verttax = velotax = vlbltax = edgetax = edlotax = NULL; } #endif /* SCOTCH_DEBUG_DGRAPH2 */ if (dgrfptr->vendloctax == (dgrfptr->vertloctax + 1)) { /* If distributed graph is compact */ if (dgraphGatherAll3 (dgrfptr->vertloctax + baseval + 1, dgrfptr->vertlocnbr, /* Do not send first index, it is always equal to baseval */ verttax + 1, /* First index will always be equal to baseval too, and procdsptab holds based values */ dgrfptr->proccnttab, dgrfptr->procdsptab, protnum, dgrfptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphGatherAll2: communication error (3)"); return (1); } if (cgrfptr != NULL) { Gnum procnum; verttax[baseval] = baseval; for (procnum = 1; procnum < dgrfptr->procglbnbr; procnum ++) { /* Adjust index sub-arrays for all processes except the first one */ Gnum vertnum; Gnum vertnnd; Gnum edgedlt; for (vertnum = dgrfptr->procdsptab[procnum] + 1, vertnnd = dgrfptr->proccnttab[procnum] + vertnum, edgedlt = verttax[vertnum - 1] - baseval; vertnum < vertnnd; vertnum ++) verttax[vertnum] += edgedlt; } } } else { /* Distributed graph is not compact */ Gnum vertlocnum; Gnum * restrict edgelocptr; vertloctax -= baseval; /* Base temporary vertex array */ for (vertlocnum = baseval, edgelocptr = edgeloctab; /* Build vertex send array */ vertlocnum < dgrfptr->vertlocnnd; vertlocnum ++) { Gnum edgelocnum; vertloctax[vertlocnum] = dgrfptr->vendloctax[vertlocnum] - dgrfptr->vertloctax[vertlocnum]; /* Get edge counts */ for (edgelocnum = dgrfptr->vertloctax[vertlocnum]; edgelocnum < dgrfptr->vendloctax[vertlocnum]; edgelocnum ++) *edgelocptr ++ = edgeloctax[edgelocnum]; } if (dgraphGatherAll3 (vertloctax + baseval, dgrfptr->vertlocnbr, verttax + 1, /* First index will always be equal to baseval, and procdsptab holds based values */ dgrfptr->proccnttab, dgrfptr->procdsptab, protnum, dgrfptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphGatherAll2: communication error (4)"); return (1); } if (cgrfptr != NULL) { Gnum vertnum; Gnum edgenum; verttax[baseval] = baseval; for (vertnum = baseval + 1, edgenum = baseval; /* Create compact centralized vertex array */ vertnum <= cgrfptr->vertnnd; vertnum ++) { edgenum += verttax[vertnum]; verttax[vertnum] = edgenum; } #ifdef SCOTCH_DEBUG_DGRAPH2 if (verttax[cgrfptr->vertnnd] != (cgrfptr->edgenbr + baseval)) { errorPrint ("dgraphGatherAll2: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ } } if (dgrfptr->veloloctax != NULL) { if (dgraphGatherAll3 (dgrfptr->veloloctax + baseval, dgrfptr->vertlocnbr, velotax, /* Based array since procdsptab holds based values */ dgrfptr->proccnttab, dgrfptr->procdsptab, protnum, dgrfptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphGatherAll2: communication error (6)"); return (1); } } if (dgrfptr->vnumloctax != NULL) { if (dgraphGatherAll3 (dgrfptr->vnumloctax + baseval, dgrfptr->vertlocnbr, vnumtax, /* Based array since procdsptab holds based values */ dgrfptr->proccnttab, dgrfptr->procdsptab, protnum, dgrfptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphGatherAll2: communication error (5)"); return (1); } } if (dgrfptr->vlblloctax != NULL) { if (dgraphGatherAll3 (dgrfptr->vlblloctax + baseval, dgrfptr->vertlocnbr, vlbltax, /* Based array since procdsptab holds based values */ dgrfptr->proccnttab, dgrfptr->procdsptab, protnum, dgrfptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphGatherAll2: communication error (7)"); return (1); } } if (cgrfptr != NULL) { Gnum procnum; Gnum edgenum; for (procnum = 0, edgenum = baseval; /* Build arrays for MPI_Gatherv on edge arrays */ procnum < dgrfptr->procglbnbr; procnum ++) { recvcnttab[procnum] = verttax[dgrfptr->procdsptab[procnum] + dgrfptr->proccnttab[procnum]] - verttax[dgrfptr->procdsptab[procnum]]; /* verttax used twice since centralized graph is compact */ recvdsptab[procnum] = edgenum; edgenum += recvcnttab[procnum]; } #ifdef SCOTCH_DEBUG_DGRAPH2 if ((recvdsptab[dgrfptr->procglbnbr - 1] + recvcnttab[dgrfptr->procglbnbr - 1]) != (cgrfptr->edgenbr + baseval)) { errorPrint ("dgraphGatherAll2: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ } if (dgrfptr->vendloctax == (dgrfptr->vertloctax + 1)) { /* If distributed graph is compact */ if (dgraphGatherAll3 (dgrfptr->edgeloctax + baseval, dgrfptr->edgelocnbr, /* Send global indices */ edgetax, /* Based array as recvdsptab holds based values */ recvcnttab, recvdsptab, protnum, dgrfptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphGatherAll2: communication error (8)"); return (1); } if (dgrfptr->edloloctax != NULL) { if (dgraphGatherAll3 (dgrfptr->edloloctax + baseval, dgrfptr->edgelocnbr, edlotax, /* Based array as recvdsptab holds based values */ recvcnttab, recvdsptab, protnum, dgrfptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphGatherAll2: communication error (9)"); return (1); } } } else { /* Distributed graph is not compact */ if (dgraphGatherAll3 (edgeloctab, dgrfptr->edgelocnbr, edgetax, /* Based array as recvdsptab holds based values */ recvcnttab, recvdsptab, protnum, dgrfptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphGatherAll2: communication error (10)"); return (1); } if (dgrfptr->edloloctax != NULL) { Gnum vertlocnum; Gnum * restrict edlolocptr; for (vertlocnum = baseval, edlolocptr = edgeloctab; /* Recycle edge send array to build edge load send array */ vertlocnum < dgrfptr->vertlocnnd; vertlocnum ++) { Gnum edgelocnum; for (edgelocnum = dgrfptr->vertloctax[vertlocnum]; edgelocnum < dgrfptr->vendloctax[vertlocnum]; edgelocnum ++) *edlolocptr ++ = dgrfptr->edloloctax[edgelocnum]; } if (dgraphGatherAll3 (edgeloctab, dgrfptr->edgelocnbr, /* Send compacted edge load array */ edlotax, /* Based array as recvdsptab holds based values */ recvcnttab, recvdsptab, protnum, dgrfptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphGatherAll2: communication error (11)"); return (1); } } } if (cgrfptr != NULL) { if ((dgrfptr->procdsptab[dgrfptr->procglbnbr] != /* If graph has holes, relabel end vertices */ dgrfptr->procvrttab[dgrfptr->procglbnbr])) { Gnum procnum; for (procnum = 0; procnum < dgrfptr->procglbnbr; procnum ++) { /* Accelerate search per sender process */ Gnum vertlocmin; Gnum vertlocmax; Gnum vertlocadj; Gnum edgelocnum; Gnum edgelocnnd; vertlocmin = dgrfptr->procvrttab[procnum]; /* Initialize search accelerator */ vertlocmax = dgrfptr->procvrttab[procnum + 1]; vertlocadj = dgrfptr->procdsptab[procnum] - vertlocmin; for (edgelocnum = recvdsptab[procnum], edgelocnnd = edgelocnum + recvcnttab[procnum]; edgelocnum < edgelocnnd; edgelocnum ++) { Gnum vertlocend; vertlocend = cgrfptr->edgetax[edgelocnum]; if ((vertlocend >= vertlocmin) && /* If end vertex is local with respect to current process */ (vertlocend < vertlocmax)) cgrfptr->edgetax[edgelocnum] = vertlocend + vertlocadj; else { /* End vertex is not local */ int procngbmin; int procngbmax; for (procngbmin = 0, procngbmax = dgrfptr->procglbnbr; procngbmax - procngbmin > 1; ) { int procngbnum; procngbnum = (procngbmax + procngbmin) / 2; if (dgrfptr->procvrttab[procngbnum] <= vertlocend) procngbmin = procngbnum; else procngbmax = procngbnum; } cgrfptr->edgetax[edgelocnum] = vertlocend + dgrfptr->procdsptab[procngbmin] - dgrfptr->procvrttab[procngbmin]; } } } } if (cgrfptr->edlotax == NULL) /* If no edge loads */ cgrfptr->edlosum = cgrfptr->edgenbr; /* Edge load sum is trivial */ else { if (edlosum >= 0) /* If edge load sum already computed by library call */ cgrfptr->edlosum = edlosum; else { /* Compute it from scratch on every root process (small graph assumed) */ Gnum edgenum; Gnum edgennd; Gnum edlotmp; for (edgenum = cgrfptr->baseval, edgennd = edgenum + cgrfptr->edgenbr, edlotmp = 0; /* Edge load array is always compact */ edgenum < edgennd; edgenum ++) edlotmp += cgrfptr->edlotax[edgenum]; cgrfptr->edlosum = edlotmp; } } } memFree (recvcnttab); #ifdef SCOTCH_DEBUG_DGRAPH2 cheklocval = (cgrfptr != NULL) ? graphCheck (cgrfptr) : 0; if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, dgrfptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphGatherAll2: communication error (12)"); return (1); } if (chekglbval != 0) { errorPrint ("dgraphGatherAll2: inconsistent centralized graph data"); if (cgrfptr != NULL) graphFree (cgrfptr); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ return (0); } /* This function gathers on all processes ** the pieces of a distributed graph to ** build a centralized graph. ** Since the resulting centralized graphs are ** supposed to be small in the general case, ** edlosum is computed without communication ** on each of the processors. ** It returns: ** - 0 : if graph data are consistent. ** - !0 : on error. */ int dgraphGatherAll ( const Dgraph * restrict const dgrfptr, /* Distributed graph */ Graph * restrict cgrfptr) /* Centralized graph */ { return (dgraphGatherAll2 (dgrfptr, cgrfptr, -1, -1)); } scotch-6.0.4.dfsg/src/libscotch/library_order.c0000644002563400244210000000621311631447170024643 0ustar trophimeutilisateurs du domaine/* Copyright 2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_order.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains miscellaneous **/ /** routines for handling centralized **/ /** graph orderings. **/ /** **/ /** DATES : # Version 5.1 : from : 17 nov 2010 **/ /** to 17 nov 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /*****************************************/ /* */ /* These routines are the C API for */ /* ordering structure handling routines. */ /* */ /*****************************************/ /*+ This routine reserves a memory area *** of a size sufficient to store a *** graph ordering structure. *** It returns: *** - !NULL : if the initialization succeeded. *** - NULL : on error. +*/ SCOTCH_Ordering * SCOTCH_orderAlloc () { return ((SCOTCH_Ordering *) memAlloc (sizeof (SCOTCH_Ordering))); } scotch-6.0.4.dfsg/src/libscotch/vgraph_separate_bd.h0000644002563400244210000000763211631447171025640 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vgraph_separate_bd.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** : Cedric CHEVALIER **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the separation graph banding **/ /** module. **/ /** **/ /** DATES : Version 5.0 : from : 18 oct 2004 **/ /** to : 16 sep 2006 **/ /** Version 5.1 : from : 30 oct 2007 **/ /** to : 04 nov 2010 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct VgraphSeparateBdParam_ { Gnum distmax; /*+ Maximum distance to separator +*/ Strat * stratbnd; /*+ Strategy for band graph +*/ Strat * stratorg; /*+ Strategy for original graph +*/ } VgraphSeparateBdParam; /*+ Neighbor queue. +*/ typedef struct VgraphSeparateBdQueue_ { Gnum * head; /*+ Head of distance queue +*/ Gnum * tail; /*+ Tail of distance queue +*/ Gnum * qtab; /*+ Array of queue elements +*/ } VgraphSeparateBdQueue; /* ** The function prototypes. */ int vgraphSeparateBd (Vgraph * restrict const, const VgraphSeparateBdParam * restrict const); /* ** The macro definitions. */ #define vgraphSeparateBdQueueFlush(queue) ((queue)->head = (queue)->tail = (queue)->qtab) #define vgraphSeparateBdQueueEmpty(queue) ((queue)->head <= (queue)->tail) #define vgraphSeparateBdQueuePut(queue,vnum) (* ((queue)->head ++) = (vnum)) #define vgraphSeparateBdQueueGet(queue) (* ((queue)->tail ++)) scotch-6.0.4.dfsg/src/libscotch/hall_order_hd.c0000644002563400244210000011567711774576734024632 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hall_order_hd.c **/ /** **/ /** AUTHOR : Patrick AMESTOY **/ /** Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module orders a halo graph or mesh **/ /** structure using the block-oriented Halo **/ /** Approximate (Multiple) Minimum Degree **/ /** algorithm, with super-variable **/ /** accounting (HaloAMD v2.0). **/ /** **/ /** DATES : # Version 3.2 : from : 09 aug 1998 **/ /** to 18 aug 1998 **/ /** # Version 3.3 : from : 02 oct 1998 **/ /** to : 05 jan 1999 **/ /** # Version 4.0 : from : 14 jan 2003 **/ /** to : 29 aug 2007 **/ /** # Version 6.0 : from : 08 mar 2012 **/ /** to : 08 mar 2012 **/ /** **/ /** NOTES : # This module contains pieces of code **/ /** that belong to other people; see **/ /** below. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HALL_ORDER_HD #include "module.h" #include "common.h" #include "graph.h" #include "hall_order_hd.h" /* -- translated by f2c (version 19970219). */ /** -------------------------------------------------------------------- **/ /** December 8th 2003 **/ /** Unique version for both graph of variables and graphs of elements **/ /** Let us refer to as **/ /** Gv a graph with only variables **/ /** Ge a graph with both variables and elements **/ /** **/ /** Notations used: **/ /** **/ /** Let V be the set of nodes **/ /** V = Ve + V0 + V1 **/ /** V0 = Set of variable nodes (not in halo) **/ /** V1 = Set of variable nodes (in halo) **/ /** Ve = Set of element nodes **/ /** **/ /** All 3 sets are disjoint, Ve and V1 can be empty **/ /** **/ /** Modifications w.r.t. previous version : **/ /** **/ /** New Input: **/ /** --------- **/ /** nbelts : integer holding size of Ve **/ /** =0 if Gv (graph of variables) **/ /** >0 if Ge **/ /** **/ /** Extension of the meaning of input entry len for nodes in Ve **/ /** --------- **/ /** len(i) = | Adj(i) | if i \in V0 U Ve **/ /** ( Note that in the case of a GE graph **/ /** if v\in V0 then len(v) = nb of elements adjacent to v ) **/ /** len(i) = - | Adj(i) | if i \in V1 **/ /** or -N -1 if | Adj(i) | = 0 and i \in V1 **/ /** **/ /** Modified the meaning of input entry elen **/ /** --------- **/ /** if e \in Ve then elen (e) = -N-1 **/ /** if v \in V0 then elen (v) = External degree of v **/ /** Gv : elen (v) = len(v) **/ /** Ge : elen (v) **/ /** should be computed in SCOTCH **/ /** if v \in V1 then elen (v) = 0 **/ /** **/ /** **/ /** Output is unchanged **/ /** --------- **/ /** **/ /** **/ /** End remarks done on December 8th 2003 **/ /** ---------------------------------------------------------------------**/ void hallOrderHdHalmd ( const Gnum n, /* Matrix order */ const Gnum nbelts, /* Number of elements */ const Gnum iwlen, /* Length of array iw */ Gnum * restrict pe, /* Array of indexes in iw of start of row i */ Gnum pfree, /* Useful size in iw */ Gnum * restrict len, /* Array of lengths of adjacency lists */ Gnum * restrict iw, /* Adjacency list array */ Gnum * restrict nv, /* Array of element degrees */ Gnum * restrict elen, /* Array that holds the inverse permutation */ Gnum * restrict last, /* Array that holds the permutation */ Gnum * restrict ncmpa, /* Number of times array iw was compressed */ Gnum * restrict degree, /* Array that holds degree data */ Gnum * restrict head, /* Linked list structure */ Gnum * restrict next, /* Linked list structure */ Gnum * restrict w) /* Flag array */ { Gnum deg, degme, dext, dmax, e, elenme, eln, hash, hmod, i, ilast, inext, j, jlast, jnext, k, knt1, knt2, knt3, lenj, ln, me = 0, mem, mindeg, nel, newmem, nleft, nvi, nvj, nvpiv, slenme, we, wflg, wnvi, x, nbflag, nreal, lastd, nelme; Gnum p, p1, p2, p3, pdst, pend, pj, pme, pme1, pme2, pn, psrc; /** -------------------------------------------------------------------- **/ /** HALOAMD_V6: (January 1999, P. Amestoy) **/ /** *********** **/ /** 1/ ERROR 2 detection followed by stop statement suppressed. **/ /** 2/ Pb 1 identified in V5 was not correctly solved. **/ /** **/ /** HALOAMD_V5: (December 1998, P. Amestoy) **/ /** *********** **/ /** 1/ Solved problem with matrix psmigr 1, because upper bound degree **/ /** DEG>N was considered as a node of V1. **/ /** **/ /** HALOAMD_V4: (October 1998, P. Amestoy) **/ /** *********** **/ /** Only MA41 interface (ok for both scotch and MA41) is included in **/ /** this file. **/ /** **/ /** HALOAMD_V3: (August 1998, P. Amestoy) **/ /** ********** **/ /** Solved problem in version 2: variables of V1 with len(i)=0 were not **/ /** well processed. See modification of the input to characterize those **/ /** variables. **/ /** Problem detected by Jacko Koster while experimenting with C version **/ /** 2 of haloAMD in the context of multiple front method based on **/ /** MA27: "if for an interface variable i, row i in the matrix has only **/ /** a nonzero entry on the diagonal, we first remove this entry and **/ /** len(i) is set to zero on input to HALOAMD. However, this means that **/ /** HALOAMD will treat variable i as an interior variable (in V0) **/ /** instead as an interface variable (in V1). It is indeed a bit **/ /** strange to have such interface variables but we encountered some **/ /** in our debugging experiments with some random partitionings. **/ /** Solution: **/ /** IF on input i \in V1 and len(i)=0 (that is adjlist(i)={}) THEN **/ /** len(i) must be set on input to -N-1. **/ /** ENDIF **/ /** Therefore, all variables i / len(i) < 0 and only those are in V1. **/ /** Variables with len(i) = -N-1 are then processed differently at the **/ /** beginning of the code. **/ /** **/ /** HALOAMD_V2: (April 1998) **/ /** ********** **/ /** The end of the tree (including links to block of flagged indices **/ /** is built) . The list of flagged indices is considered as a dense **/ /** amalgamated node. **/ /** Tested on rosanna: ~amestoy/MA41_NEW/SUN_RISC_dbl/SOFT **/ /** **/ /** Comments on the OUTPUT: **/ /** ---------------------- **/ /** **/ /** Let V= V0 U V1 the nodes of the initial graph (|V|=n). **/ /** The assembly tree corresponds to the tree of the supernodes (or **/ /** supervariables). Each node of the assembly tree is then composed of **/ /** one principal variable and a list of secondary variables. The list **/ /** of variable of a node (principal + secondary variables) then **/ /** describes the structure of the diagonal bloc of the supernode. **/ /** The elimination tree denotes the tree of all the variables(=nodes) **/ /** and is therefore of order n. The arrays NV(N) and PE(N) give a **/ /** description of the assembly tree. **/ /** **/ /** 1/ Description of array nv(N) (on OUPUT) **/ /** nv(i)=0 i is a secondary variable. **/ /** N+1> nv(i) >0 i is a principal variable, nv(i) holds the number **/ /** of elements in column i of L (true degree of i) **/ /** nv(i) = N+1 then i is a flagged variable (belonging to V1) **/ /** **/ /** 2/ Description of array PE(N) (on OUPUT) **/ /** pe(i) = -(father of variable/node i) in the elimination tree. **/ /** If nv (i) .gt. 0, then i represents a node in the assembly tree, **/ /** and the parent of i is -pe (i), or zero if i is a root. **/ /** If nv (i) = 0, then (i,-pe (i)) represents an edge in a **/ /** subtree, the root of which is a node in the assembly tree. **/ /** **/ /** 3/ Example: **/ /** Let If be a root node father of Is in the assembly tree. **/ /** If is the principal variable of the node If and let If1, If2, If3 **/ /** be the secondary variables of node If. Is is the principal **/ /** variable of the node Is and let Is1, Is2 be the secondary **/ /** variables of node Is. **/ /** Then: **/ /** NV(If1)=NV(If2)=NV(If3) = 0 (secondary variables) **/ /** NV(Is1)=NV(Is2) = 0 (secondary variables) **/ /** NV(If) > 0 (principal variable) **/ /** NV(Is) > 0 (principal variable) **/ /** PE(If) = 0 (root node) **/ /** PE(Is) = -If (If is the father of Is in the assembly tree) **/ /** PE(If1)=PE(If2)=PE(If3)= -If (If is the principal variable) **/ /** PE(Is1)=PE(Is2)= -Is (Is is the principal variable) **/ /** **/ /** HALOAMD_V1: (September 1997) **/ /** ********** **/ /** Initial version designed to experiment the numerical (fill-in) **/ /** impact of taking into account the halo. This code should be able to **/ /** experiment no-halo, partial halo, complete halo. **/ /** -------------------------------------------------------------------- **/ /** HALOAMD is designed to process a graph composed of two types **/ /** of nodes, V0 and V1, extracted from a larger gragh. **/ /** V0^V1 = {}, **/ /** We used Min. degree heuristic to order only **/ /** nodes in V0, but the adjacency to nodes **/ /** in V1 is taken into account during ordering. **/ /** Nodes in V1 are odered at last. **/ /** Adjacency between nodes of V1 need not be provided, **/ /** however |len(i)| must always corresponds to the number of **/ /** edges effectively provided in the adjacency list of i. **/ /** On input : **/ /** ******** **/ /** Nodes INODE in V1 are flagged with len(INODE) = -degree **/ /** Update version HALO V3 (August 1998): **/ /** if len(i)=0 and i \in V1 then len(i) must be set **/ /** on input to -N-1. **/ /** ERROR return : **/ /** ************ **/ /** Negative value in ncmpa indicates an error detected **/ /** by HALOAMD. **/ /** **/ /** The graph provided MUST follow the rule: **/ /** if (i,j) is an edge in the gragh then **/ /** j must be in the adjacency list of i AND **/ /** i must be in the adjacency list of j. **/ /** **/ /** REMARKS : **/ /** ------- **/ /** 1/ Providing edges between nodes of V1 should not **/ /** affect the final ordering, only the amount of edges **/ /** of the halo should effectively affect the solution. **/ /** This code should work in the following cases: **/ /** 1/ halo not provided **/ /** 2/ halo partially provided **/ /** 3/ complete halo **/ /** 4/ complete halo+interconnection between nodes of V1. **/ /** **/ /** 1/ should run and provide identical results (w.r.t to **/ /** current implementation of AMD in SCOTCH). **/ /** 3/ and 4/ should provide identical results. **/ /** **/ /** 2/ All modifications of the MC47 initial code are indicated **/ /** with begin HALO .. end HALO **/ /** **/ /** Ordering of nodes in V0 is based on Approximate Minimum Degree **/ /** ordering algorithm, with aggressive absorption: **/ /** Given a representation of the nonzero pattern of a symmetric matrix, **/ /** A, (excluding the diagonal) perform an approximate minimum **/ /** (UMFPACK/MA38-style) degree ordering to compute a pivot order **/ /** such that fill-in in the Cholesky **/ /** factors A = LL^T is kept low. At each step, the pivot **/ /** selected is the one with the minimum UMFPACK/MA38-style **/ /** upper-bound on the external degree. Aggresive absorption is **/ /** used to tighten the bound on the degree. This can result an **/ /** significant improvement in the quality of the ordering for **/ /** some matrices. **/ /** The approximate degree algorithm implemented here is the **/ /** symmetric analogue of the degree update algorithm in MA38, by **/ /** Davis and Duff, also in the Harwell Subroutine Library. **/ /** **/ /** **** CAUTION: ARGUMENTS ARE NOT CHECKED FOR ERRORS ON INPUT. ***** **/ /** ** If you want error checking, a more versatile input format, and ** **/ /** ** a simpler user interface, then use MC47A/AD in the Harwell ** **/ /** ** Subroutine Library, which checks for errors, transforms the ** **/ /** ** input, and calls MC47B/BD. ** **/ /** ******************************************************************** **/ /** References: (UF Tech Reports are available via anonymous ftp **/ /** to ftp.cis.ufl.edu:cis/tech-reports). **/ /** [1] Timothy A. Davis and Iain Duff, "An unsymmetric-pattern **/ /** multifrontal method for sparse LU factorization", **/ /** SIAM J. Matrix Analysis and Applications, to appear. **/ /** also Univ. of Florida Technical Report TR-94-038. **/ /** Discuss UMFPACK / MA38. **/ /** [2] Patrick Amestoy, Timothy A. Davis, and Iain S. Duff, **/ /** "An approximate minimum degree ordering algorithm," **/ /** SIAM J. Matrix Analysis and Applications (to appear), **/ /** also Univ. of Florida Technical Report TR-94-039. **/ /** Discusses this routine. **/ /** [3] Alan George and Joseph Liu, "The evolution of the **/ /** minimum degree ordering algorithm," SIAM Review, vol. **/ /** 31, no. 1, pp. 1-19, March 1989. We list below the **/ /** features mentioned in that paper that this code **/ /** includes: **/ /** mass elimination: **/ /** Yes. MA27 relied on supervariable detection for mass **/ /** elimination. **/ /** indistinguishable nodes: **/ /** Yes (we call these "supervariables"). This was also **/ /** in the MA27 code - although we modified the method of **/ /** detecting them (the previous hash was the true degree, **/ /** which we no longer keep track of). A supervariable is **/ /** a set of rows with identical nonzero pattern. All **/ /** variables in a supervariable are eliminated together. **/ /** Each supervariable has as its numerical name that of **/ /** one of its variables (its principal variable). **/ /** quotient graph representation: **/ /** Yes. We use the term "element" for the cliques formed **/ /** during elimination. This was also in the MA27 code. **/ /** The algorithm can operate in place, but it will work **/ /** more efficiently if given some "elbow room." **/ /** element absorption: **/ /** Yes. This was also in the MA27 code. **/ /** external degree: **/ /** Yes. The MA27 code was based on the true degree. **/ /** incomplete degree update and multiple elimination: **/ /** No. This was not in MA27, either. Our method of **/ /** degree update within MC47B/BD is element-based, not **/ /** variable-based. It is thus not well-suited for use **/ /** with incomplete degree update or multiple elimination. **/ /** -------------------------------------------------------------------- **/ /** Authors, and Copyright (C) 1995 by: **/ /** Timothy A. Davis, Patrick Amestoy, Iain S. Duff, & **/ /** John K. Reid. **/ /** Modified (V1) by P.R. Amestoy ENSEEIHT (1997) **/ /** Modified (V2) by P.R. Amestoy ENSEEIHT (1998) **/ /** Modified (V3) by P.R. Amestoy ENSEEIHT (1998) **/ /** Modified (V4) by P.R. Amestoy ENSEEIHT (1998) **/ /** Modified (V5) by P.R. Amestoy ENSEEIHT (1998) **/ /** Modified (V6) by P.R. Amestoy ENSEEIHT (1999) **/ /** **/ /** Dates: September, 1995 **/ /** September, 1997 (halo AMD V1) **/ /** April, 1998 (halo AMD V2) **/ /** August, 1998 (halo AMD V3) **/ -- w; /* Parameter adjustments */ -- next; -- head; -- degree; -- last; -- elen; -- nv; -- len; -- pe; -- iw; wflg = 2; mindeg = 1; *ncmpa = 0; nel = 0; hmod = MAX (1, (n - 1)); dmax = 0; mem = pfree - 1; nbflag = 0; lastd = 0; memSet (last + 1, 0, n * sizeof (Gnum)); memSet (head + 1, 0, n * sizeof (Gnum)); if (nbelts == 0) { /* Patch 8/12/03 */ memSet (elen + 1, 0, n * sizeof (Gnum)); for (i = 1; i <= n; i ++) { nv[i] = 1; w[i] = 1; if (len[i] < 0) { degree[i] = n + 1; nbflag ++; if (len[i] == - (n + 1)) { /* Patch 09/08/98 */ len[i] = 0; pe[i] = 0; /* Patch 12/12/03 : Because of compress, we force skipping those entries (which are anyway empty) */ } else len[i] = - len[i]; } else degree[i] = len[i]; } } else { /* Patch 08/12/03 : Duplicate part of previous loop to avoid sytematic testing for elements */ for (i = 1; i <= n; i ++) { nv[i] = 1; w[i] = 1; if (len[i] < 0) { /* i \in V1 */ degree[i] = n + 1; nbflag ++; if (len[i] == - (n + 1)) { /* Patch 09/08/98 */ len[i] = 0; pe[i] = 0; /* Patch 12/12/03 : because of compress, we force skipping those entries (which are anyway empty) */ elen[i] = 0; /* Patch 16/12/03 */ } else { len[i] = - len[i]; elen[i] = len[i]; /* Patch 16/12/03 : only elements are adjacent to a variable */ } } else { /* i \in Ve or V0 */ if (elen[i] < 0) { /* i \in Ve */ nel ++; degree[i] = len[i]; elen[i] = - nel; dmax = MAX (dmax, degree[i]); /* Patch 11/03/04 */ } else { degree[i] = elen[i]; elen[i] = len[i]; /* Patch 16/12/03 : only elements are adjacent to a variable */ } } } } #ifdef SCOTCH_DEBUG_ORDER2 if (nbelts != nel) /* Temporary Patch 8/12/03 */ printf ("error 8Dec2003\n"); #endif /* SCOTCH_DEBUG_ORDER2 */ nreal = n - nbflag; for (i = 1; i <= n; i ++) { if (elen[i] < 0 ) /* Patch 16/12/03 : Skip elements */ continue; deg = degree[i]; if (deg == (n + 1)) { deg = n; if (lastd == 0) { lastd = i; head[deg] = i; next[i] = 0; last[i] = 0; } else { next[lastd] = i; last[i] = lastd; lastd = i; next[i] = 0; } } else if (deg > 0) { inext = head[deg]; if (inext != 0) last[inext] = i; next[i] = inext; head[deg] = i; } else { nel ++; elen[i] = - nel; pe[i] = 0; w[i] = 0; } } /* L20: */ nleft = n - nel; /* Patch v5 12/12/98 */ while (nel < nreal) { /* WHILE (selecting pivots) DO */ for (deg = mindeg; deg <= n; deg ++) { /* Patch 17/11/97 */ me = head[deg]; if (me > 0) break; /* GO to 50 */ } /* L40: */ mindeg = deg; if (me <= 0) { /* Error 1 */ *ncmpa = -n; return; } inext = next[me]; if (inext != 0) last[inext] = 0; head[deg] = inext; elenme = elen[me]; elen[me] = - (nel + 1); nvpiv = nv[me]; nel += nvpiv; nv[me] = - nvpiv; degme = 0; if (elenme == 0) { pme1 = pe[me]; pme2 = pme1 - 1; for (p = pme1; p <= pme1 + len[me] - 1; p ++) { i = iw[p]; nvi = nv[i]; if (nvi > 0) { degme += nvi; nv[i] = - nvi; pme2 ++; iw[pme2] = i; if (degree[i] <= n) { ilast = last[i]; inext = next[i]; if (inext != 0) last[inext] = ilast; if (ilast != 0) next[ilast] = inext; else head[degree[i]] = inext; } } } /* L60: */ newmem = 0; } else { p = pe[me]; pme1 = pfree; slenme = len[me] - elenme; for (knt1 = 1; knt1 <= elenme + 1; knt1 ++) { if (knt1 > elenme) { e = me; pj = p; ln = slenme; } else { e = iw[p ++]; pj = pe[e]; ln = len[e]; } for (knt2 = 1; knt2 <= ln; knt2 ++) { i = iw[pj ++]; nvi = nv[i]; if (nvi > 0) { if (pfree > iwlen) { pe[me] = p; len[me] -= knt1; if (len[me] == 0) pe[me] = 0; pe[e] = pj; len[e] = ln - knt2; if (len[e] == 0) pe[e] = 0; (*ncmpa) ++; for (j = 1; j <= n; j ++) { pn = pe[j]; if (pn > 0) { pe[j] = iw[pn]; iw[pn] = - j; } } /* L70: */ pdst = 1; psrc = 1; pend = pme1 - 1; while (psrc <= pend) { /* L80: */ j = - iw[psrc ++]; if (j > 0) { iw[pdst] = pe[j]; pe[j] = pdst ++; lenj = len[j]; for (knt3 = 0; knt3 <= lenj - 2; knt3 ++) iw[pdst + knt3] = iw[psrc + knt3]; pdst = pdst + (lenj - 1); psrc = psrc + (lenj - 1); } } p1 = pdst; for (psrc = pme1; psrc <= pfree - 1; psrc ++, pdst ++) /* L100: */ iw[pdst] = iw[psrc]; pme1 = p1; pfree = pdst; pj = pe[e]; p = pe[me]; } degme += nvi; nv[i] = - nvi; iw[pfree] = i; pfree ++; if (degree[i] <= n) { ilast = last[i]; inext = next[i]; if (inext != 0) last[inext] = ilast; if (ilast != 0) next[ilast] = inext; else head[degree[i]] = inext; } } } /* L110: */ if (e != me) { pe[e] = -me; w[e] = 0; } } /* L120: */ pme2 = pfree - 1; newmem = pfree - pme1; mem += newmem; } degree[me] = degme; pe[me] = pme1; len[me] = pme2 - pme1 + 1; if (wflg + n <= wflg) { for (x = 1; x <= n; x ++) { if (w[x] != 0) w[x] = 1; } /* L130: */ wflg = 2; } for (pme = pme1; pme <= pme2; pme ++) { i = iw[pme]; eln = elen[i]; if (eln > 0) { nvi = - nv[i]; wnvi = wflg - nvi; for (p = pe[i]; p < pe[i] + eln; p ++) { e = iw[p]; we = w[e]; if (we >= wflg) we -= nvi; else if (we != 0) we = degree[e] + wnvi; w[e] = we; } /* L140: */ } } /* L150: */ for (pme = pme1; pme <= pme2; pme ++) { i = iw[pme]; p1 = pe[i]; p2 = p1 + elen[i] - 1; pn = p1; hash = 0; deg = 0; for (p = p1; p <= p2; p ++) { e = iw[p]; dext = w[e] - wflg; if (dext > 0) { deg += dext; iw[pn ++] = e; hash += e; } else if (dext == 0) { pe[e] = -me; w[e] = 0; } } /* L160: */ elen[i] = pn - p1 + 1; p3 = pn; for (p = p2 + 1; p < p1 + len[i]; p ++) { j = iw[p]; nvj = nv[j]; if (nvj > 0) { deg += nvj; iw[pn ++] = j; hash += j; } } /* L170: */ if (degree[i] == (n + 1)) deg = n + 1; if (deg == 0) { pe[i] = - me; nvi = - nv[i]; degme -= nvi; nvpiv += nvi; nel += nvi; nv[i] = 0; elen[i] = 0; } else { if (degree[i] != (n + 1)) { /* Patch v6 05/01/99 */ deg = MIN (nleft, deg); /* Patch v5 12/12/98 */ degree[i] = MIN (degree[i], deg); } iw[pn] = iw[p3]; iw[p3] = iw[p1]; iw[p1] = me; len[i] = pn - p1 + 1; if (deg <= n) { hash = (hash % hmod) + 1; j = head[hash]; if (j <= 0) { next[i] = - j; head[hash] = - i; } else { next[i] = last[j]; last[j] = i; } last[i] = hash; } } } /* L180: */ degree[me] = degme; dmax = MAX (dmax, degme); wflg += dmax; if (wflg + n <= wflg) { for (x = 1; x <= n; x ++) { if (w[x] != 0) w[x] = 1; } wflg = 2; } for (pme = pme1; pme <= pme2; pme ++) { i = iw[pme]; if ((nv[i] < 0) && (degree[i] <= n)) { hash = last[i]; j = head[hash]; if (j == 0) continue; if (j < 0) { i = - j; head[hash] = 0; } else { i = last[j]; last[j] = 0; } if (i == 0) continue; L200: /* WHILE LOOP: */ if (next[i] != 0) { ln = len[i]; eln = elen[i]; for (p = pe[i] + 1; p < pe[i] + ln; p ++) w[iw[p]] = wflg; jlast = i; j = next[i]; L220: /* WHILE LOOP: */ if (j != 0) { if (len[j] != ln) goto L240; if (elen[j] != eln) goto L240; for (p = pe[j] + 1; p < pe[j] + ln; p ++) { if (w[iw[p]] != wflg) goto L240; } /* L230: */ pe[j] = -i; nv[i] += nv[j]; nv[j] = 0; elen[j] = 0; j = next[j]; next[jlast] = j; goto L220; L240: jlast = j; j = next[j]; goto L220; } wflg ++; i = next[i]; if (i != 0) goto L200; } } } p = pme1; nleft = n - nel; for (pme = pme1; pme <= pme2; pme ++) { i = iw[pme]; nvi = - nv[i]; if (nvi > 0) { nv[i] = nvi; if (degree[i] <= n) { deg = MIN (degree[i] + degme, nleft) - nvi; inext = head[deg]; if (inext != 0) last[inext] = i; next[i] = inext; last[i] = 0; head[deg] = i; mindeg = MIN (mindeg, deg); degree[i] = deg; } iw[p ++] = i; } } /* L260: */ nv[me] = nvpiv + degme; len[me] = p - pme1; if (len[me] == 0) { pe[me] = 0; w[me] = 0; } if (newmem != 0) { pfree = p; mem = mem - newmem + len[me]; } } /* END WHILE (selecting pivots) */ if (nel < n) { /* Patch 12/12/98 (old: nreal < n) */ for (deg = mindeg; deg <= n; deg ++) { me = head[deg]; if (me > 0) break; } mindeg = deg; nelme = - (nel + 1); for (x = 1; x <= n; x ++) { if ((pe[x] > 0) && (elen[x] < 0)) pe[x] = - me; else if (degree[x] == (n + 1)) { nel += nv[x]; pe[x] = - me; elen[x] = 0; nv[x] = 0; /* Patch 12/12/98 (old: n + 1) */ } } elen[me] = nelme; nv[me] = n - nreal; /* Patch 12/12/98 (old: n + 1) */ pe[me] = 0; if (nel != n) { /* Error 2 */ *ncmpa = - (n + 1); return; } } for (i = 1; i <= n; i ++) { if (elen[i] == 0) { j = - pe[i]; while (elen[j] >= 0) /* L270: */ j = - pe[j]; e = j; k = - elen[e]; j = i; while (elen[j] >= 0) { /* L280: */ jnext = - pe[j]; pe[j] = - e; if (elen[j] == 0) elen[j] = k ++; j = jnext; } elen[e] = - k; } } /* L290: */ #ifdef DEAD_CODE /* No need for permutations */ for (i = 1; i <= n; i ++) { /* Patch 19/10/98 */ k = abs (elen[i]); last[k] = i; elen[i] = k; } /* L300: */ #endif /* DEAD_CODE */ } scotch-6.0.4.dfsg/src/libscotch/library_dgraph.c0000644002563400244210000002216212055773245025004 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2009,2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the distri- **/ /** buted source graph handling routines of **/ /** the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 26 apr 2006 **/ /** to 14 apr 2008 **/ /** # Version 5.1 : from : 26 mar 2009 **/ /** to 17 nov 2010 **/ /** # Version 6.0 : from : 27 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "graph.h" /* For graphPtscotch() */ #include "dgraph.h" #include "ptscotch.h" /****************************************/ /* */ /* These routines are the C API for the */ /* distributed graph handling routines. */ /* */ /****************************************/ /*+ This routine reserves a memory area *** of a size sufficient to store a *** distributed graph structure. *** It returns: *** - !NULL : if the initialization succeeded. *** - NULL : on error. +*/ SCOTCH_Dgraph * SCOTCH_dgraphAlloc () { return ((SCOTCH_Dgraph *) memAlloc (sizeof (SCOTCH_Dgraph))); } /*+ This routine initializes the opaque *** distributed graph structure used to *** handle distributed graphs in the *** Scotch library. *** It returns: *** - 0 : if the initialization succeeded. *** - !0 : on error. +*/ int SCOTCH_dgraphInit ( SCOTCH_Dgraph * const grafptr, MPI_Comm proccomm) /* Communicator to be used for all communications */ { #ifdef SCOTCH_PTHREAD int thrdlvlval; #endif /* SCOTCH_PTHREAD */ #ifdef SCOTCH_PTHREAD MPI_Query_thread (&thrdlvlval); if (thrdlvlval < MPI_THREAD_MULTIPLE) { errorPrint ("SCOTCH_dgraphInit: Scotch compiled with SCOTCH_PTHREAD and program not launched with MPI_THREAD_MULTIPLE"); return (1); } #endif /* SCOTCH_PTHREAD */ if (sizeof (SCOTCH_Num) != sizeof (Gnum)) { errorPrint ("SCOTCH_dgraphInit: internal error (1)"); return (1); } if (sizeof (SCOTCH_Dgraph) < sizeof (Dgraph)) { errorPrint ("SCOTCH_dgraphInit: internal error (2)"); return (1); } return (dgraphInit ((Dgraph *) grafptr, proccomm)); } /*+ This routine frees the contents of the *** given opaque graph structure. *** It returns: *** - VOID : in all cases. +*/ void SCOTCH_dgraphExit ( SCOTCH_Dgraph * const grafptr) { dgraphExit ((Dgraph *) grafptr); } /*+ This routine frees the contents of the *** given opaque graph structure but does *** not free its private data. *** It returns: *** - VOID : in all cases. +*/ void SCOTCH_dgraphFree ( SCOTCH_Dgraph * const grafptr) { dgraphFree ((Dgraph *) grafptr); } /*+ This routine accesses graph size data. *** NULL pointers on input indicate unwanted *** data. *** It returns: *** - VOID : in all cases. +*/ void SCOTCH_dgraphSize ( const SCOTCH_Dgraph * const grafptr, SCOTCH_Num * const vertglbnbr, SCOTCH_Num * const vertlocnbr, SCOTCH_Num * const edgeglbnbr, SCOTCH_Num * const edgelocnbr) { const Dgraph * srcgrafptr; srcgrafptr = (Dgraph *) grafptr; if (vertglbnbr != NULL) *vertglbnbr = (SCOTCH_Num) (srcgrafptr->vertglbnbr); if (vertlocnbr != NULL) *vertlocnbr = (SCOTCH_Num) (srcgrafptr->vertlocnbr); if (edgeglbnbr != NULL) *edgeglbnbr = (SCOTCH_Num) srcgrafptr->edgeglbnbr; if (edgelocnbr != NULL) *edgelocnbr = (SCOTCH_Num) srcgrafptr->edgelocnbr; } /*+ This routine accesses all of the graph data. *** NULL pointers on input indicate unwanted *** data. NULL pointers on output indicate *** unexisting arrays. *** It returns: *** - VOID : in all cases. +*/ void SCOTCH_dgraphData ( const SCOTCH_Dgraph * const grafptr, /* Graph structure to read */ SCOTCH_Num * const baseptr, /* Base value */ SCOTCH_Num * const vertglbptr, /* Number of global vertices */ SCOTCH_Num * const vertlocptr, /* Number of local vertices */ SCOTCH_Num * const vertlocptz, /* Maximum number of local vertices */ SCOTCH_Num * const vertgstptr, /* Number of local + ghost vertices */ SCOTCH_Num ** const vertloctab, /* Vertex array [vertnbr+1] */ SCOTCH_Num ** const vendloctab, /* Vertex array [vertnbr] */ SCOTCH_Num ** const veloloctab, /* Vertex load array */ SCOTCH_Num ** const vlblloctab, /* Vertex label array */ SCOTCH_Num * const edgeglbptr, /* Number of global edges (arcs) */ SCOTCH_Num * const edgelocptr, /* Number of local edges (arcs) */ SCOTCH_Num * const edgelocptz, /* Size of local edge array */ SCOTCH_Num ** const edgeloctab, /* Local edge array [edgelocsiz] */ SCOTCH_Num ** const edgegsttab, /* Ghost edge array [edgelocsiz] */ SCOTCH_Num ** const edloloctab, /* Edge load array [edgelocsiz] */ MPI_Comm * const comm) /* MPI Communicator */ { const Dgraph * srcgrafptr; /* Pointer to source graph structure */ srcgrafptr = (const Dgraph *) grafptr; if (baseptr != NULL) *baseptr = srcgrafptr->baseval; if (vertglbptr != NULL) *vertglbptr = srcgrafptr->vertglbnbr; if (vertlocptr != NULL) *vertlocptr = srcgrafptr->vertlocnbr; if (vertlocptz != NULL) *vertlocptz = srcgrafptr->procvrttab[srcgrafptr->proclocnum + 1] - srcgrafptr->procvrttab[srcgrafptr->proclocnum]; if (vertgstptr != NULL) *vertgstptr = ((srcgrafptr->flagval & DGRAPHHASEDGEGST) != 0) ? srcgrafptr->vertgstnbr : -1; if (vertloctab != NULL) *vertloctab = srcgrafptr->vertloctax + srcgrafptr->baseval; if (vendloctab != NULL) *vendloctab = srcgrafptr->vendloctax + srcgrafptr->baseval; if (veloloctab != NULL) *veloloctab = (srcgrafptr->veloloctax != NULL) ? srcgrafptr->veloloctax + srcgrafptr->baseval : NULL; if (vlblloctab != NULL) *vlblloctab = (srcgrafptr->vlblloctax != NULL) ? srcgrafptr->vlblloctax + srcgrafptr->baseval : NULL; if (edgeglbptr != NULL) *edgeglbptr = srcgrafptr->edgeglbnbr; if (edgelocptr != NULL) *edgelocptr = srcgrafptr->edgelocnbr; if (edgelocptz != NULL) *edgelocptz = srcgrafptr->edgelocsiz; if (edgeloctab != NULL) *edgeloctab = srcgrafptr->edgeloctax + srcgrafptr->baseval; if (edgegsttab != NULL) *edgegsttab = (srcgrafptr->edgegsttax != NULL) ? srcgrafptr->edgegsttax + srcgrafptr->baseval : NULL; if (edloloctab != NULL) *edloloctab = (srcgrafptr->edloloctax != NULL) ? srcgrafptr->edloloctax + srcgrafptr->baseval : NULL; if (comm != NULL) *comm = srcgrafptr->proccomm; } scotch-6.0.4.dfsg/src/libscotch/dgraph.c0000644002563400244210000002016112024162405023237 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Francois CHATENET (P0.0) **/ /** Sebastien FOUCAULT (P0.0) **/ /** Nicolas GICQUEL (P0.1) **/ /** Jerome LACOSTE (P0.1) **/ /** Cedric CHEVALIER **/ /** **/ /** FUNCTION : This module contains the distributed **/ /** graph data structure handling **/ /** routines. **/ /** **/ /** DATES : # Version P0.0 : from : 01 apr 1997 **/ /** to 01 apr 1997 **/ /** # Version P0.1 : from : 12 apr 1998 **/ /** to 20 jun 1998 **/ /** # Version 5.0 : from : 16 feb 2005 **/ /** to : 17 jul 2008 **/ /** # Version 5.1 : from : 21 jun 2008 **/ /** to : 30 jul 2010 **/ /** # Version 6.0 : from : 12 sep 2012 **/ /** to : 12 sep 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DGRAPH #include "module.h" #include "common.h" #include "dgraph.h" /*************************************/ /* */ /* These routines handle distributed */ /* source graphs. */ /* */ /*************************************/ /* This routine initializes a distributed graph ** structure. In order to avoid collective ** communication whenever possible, the allocation ** of send and receive index arrays is not performed ** in the routine itself, but rather delegated to ** subsequent routines such as dgraphBuild. ** However, these arrays will not be freed by ** dgraphFree, but by dgraphExit. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int dgraphInit ( Dgraph * restrict const grafptr, /* Distributed graph structure */ MPI_Comm proccomm) /* Communicator to be used for all communications */ { memSet (grafptr, 0, sizeof (Dgraph)); /* Clear public and private graph fields */ grafptr->proccomm = proccomm; /* Set private fields */ MPI_Comm_size (proccomm, &grafptr->procglbnbr); /* Get communicator data */ MPI_Comm_rank (proccomm, &grafptr->proclocnum); return (0); } /* This routine frees the public and private data ** of the given distributed graph, but not its ** communicator. ** Private data could have been kept and freed only ** in dgraphExit(). Yet, freeing it along with the ** graph public data is a way to avoid memory ** fragmentation. Moreover, it allows to use compact ** private data if some graphs are known not to have ** holes. ** It is not a collective routine, as no communication ** is needed to perform the freeing of memory structures. ** It returns: ** - VOID : in all cases. */ static void dgraphFree2 ( Dgraph * restrict const grafptr) { if ((grafptr->flagval & DGRAPHFREETABS) != 0) { /* If local arrays must be freed */ if (grafptr->vertloctax != NULL) memFree (grafptr->vertloctax + grafptr->baseval); if ((grafptr->flagval & DGRAPHVERTGROUP) == 0) { /* If vertex arrays not grouped */ if (grafptr->vendloctax != (grafptr->vertloctax + 1)) memFree (grafptr->vendloctax + grafptr->baseval); if (grafptr->veloloctax != NULL) memFree (grafptr->veloloctax + grafptr->baseval); if (grafptr->vnumloctax != NULL) memFree (grafptr->vnumloctax + grafptr->baseval); if (grafptr->vlblloctax != NULL) memFree (grafptr->vlblloctax + grafptr->baseval); } if (grafptr->edgeloctax != NULL) memFree (grafptr->edgeloctax + grafptr->baseval); if ((grafptr->flagval & DGRAPHEDGEGROUP) == 0) { /* If edge arrays not grouped */ if (grafptr->edloloctax != NULL) memFree (grafptr->edloloctax + grafptr->baseval); } } if ((grafptr->flagval & DGRAPHFREEPSID) != 0) { /* If process send arrays must be freed */ if (grafptr->procsidtab != NULL) memFree (grafptr->procsidtab); } if ((grafptr->flagval & DGRAPHFREEEDGEGST) != 0) { /* If ghost array must be freed */ if (grafptr->edgegsttax != NULL) memFree (grafptr->edgegsttax + grafptr->baseval); } if ((grafptr->flagval & DGRAPHFREEPRIV) != 0) /* If private data has to be freed */ if (grafptr->procdsptab != NULL) memFree (grafptr->procdsptab); /* Free group leader of graph private data */ } void dgraphFree ( Dgraph * restrict const grafptr) { DgraphFlag flagval; MPI_Comm proccomm; /* Data for temporarily saving private data */ int procglbnbr; int proclocnum; dgraphFree2 (grafptr); /* Free all user fields */ flagval = grafptr->flagval & DGRAPHFREECOMM; proccomm = grafptr->proccomm; /* Save private fields only */ procglbnbr = grafptr->procglbnbr; proclocnum = grafptr->proclocnum; memSet (grafptr, 0, sizeof (Dgraph)); /* Reset graph structure */ grafptr->flagval = flagval; /* Restore private fields */ grafptr->proccomm = proccomm; grafptr->procglbnbr = procglbnbr; grafptr->proclocnum = proclocnum; return; } /* This routine destroys a distributed graph structure. ** It is not a collective routine, as no communication ** is needed to perform the freeing of memory structures. ** Private data are always destroyed. If this is not ** wanted, use dgraphFree() instead. ** It returns: ** - VOID : in all cases. */ void dgraphExit ( Dgraph * restrict const grafptr) { if ((grafptr->flagval & DGRAPHFREECOMM) != 0) /* If communicator has to be freed */ MPI_Comm_free (&grafptr->proccomm); /* Free it */ dgraphFree2 (grafptr); #ifdef SCOTCH_DEBUG_DGRAPH1 memSet (grafptr, 0, sizeof (Dgraph)); #endif /* SCOTCH_DEBUG_DGRAPH1 */ } scotch-6.0.4.dfsg/src/libscotch/library_graph_f.c0000644002563400244210000002476711650475033025154 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API for **/ /** the source graph handling routines of **/ /** the libSCOTCH library. **/ /** **/ /** DATES : # Version 3.4 : from : 02 dec 1999 **/ /** to 15 nov 2001 **/ /** # Version 4.0 : from : 11 dec 2001 **/ /** to 17 mar 2005 **/ /** # Version 5.0 : from : 11 jul 2007 **/ /** to 11 jul 2007 **/ /** # Version 5.1 : from : 27 mar 2010 **/ /** to 15 apr 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the graph handling routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFGRAPHINIT, scotchfgraphinit, ( \ SCOTCH_Graph * const grafptr, \ int * const revaptr), \ (grafptr, revaptr)) { *revaptr = SCOTCH_graphInit (grafptr); } /* ** */ FORTRAN ( \ SCOTCHFGRAPHEXIT, scotchfgraphexit, ( \ SCOTCH_Graph * const grafptr), \ (grafptr)) { SCOTCH_graphExit (grafptr); } /* ** */ FORTRAN ( \ SCOTCHFGRAPHFREE, scotchfgraphfree, ( \ SCOTCH_Graph * const grafptr), \ (grafptr)) { SCOTCH_graphFree (grafptr); } /* When an input stream is built from the given ** file handle, it is set as unbuffered, so as to ** allow for multiple stream reads from the same ** file handle. If it were buffered, too many ** input characters would be read on the first ** block read. */ FORTRAN ( \ SCOTCHFGRAPHLOAD, scotchfgraphload, ( \ SCOTCH_Graph * const grafptr, \ int * const fileptr, \ const SCOTCH_Num * const baseptr, \ const SCOTCH_Num * const flagptr, \ int * const revaptr), \ (grafptr, fileptr, baseptr, flagptr, revaptr)) { FILE * stream; /* Stream to build from handle */ int filenum; /* Duplicated handle */ int o; if ((filenum = dup (*fileptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFGRAPHLOAD: cannot duplicate handle"); *revaptr = 1; /* Indicate error */ return; } if ((stream = fdopen (filenum, "r")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFGRAPHLOAD: cannot open input stream"); close (filenum); *revaptr = 1; return; } setbuf (stream, NULL); /* Do not buffer on input */ o = SCOTCH_graphLoad (grafptr, stream, *baseptr, *flagptr); fclose (stream); /* This closes filenum too */ *revaptr = o; } /* ** */ FORTRAN ( \ SCOTCHFGRAPHSAVE, scotchfgraphsave, ( \ const SCOTCH_Graph * const grafptr, \ int * const fileptr, \ int * const revaptr), \ (grafptr, fileptr, revaptr)) { FILE * stream; /* Stream to build from handle */ int filenum; /* Duplicated handle */ int o; if ((filenum = dup (*fileptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFGRAPHSAVE: cannot duplicate handle"); *revaptr = 1; /* Indicate error */ return; } if ((stream = fdopen (filenum, "w")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFGRAPHSAVE: cannot open output stream"); close (filenum); *revaptr = 1; return; } o = SCOTCH_graphSave (grafptr, stream); fclose (stream); /* This closes filenum too */ *revaptr = o; } /* ** */ FORTRAN ( \ SCOTCHFGRAPHBUILD, scotchfgraphbuild, ( \ SCOTCH_Graph * const grafptr, \ const SCOTCH_Num * const baseptr, \ const SCOTCH_Num * const vertptr, \ const SCOTCH_Num * const verttab, \ const SCOTCH_Num * const vendtab, \ const SCOTCH_Num * const velotab, \ const SCOTCH_Num * const vlbltab, \ const SCOTCH_Num * const edgeptr, \ const SCOTCH_Num * const edgetab, \ const SCOTCH_Num * const edlotab, \ int * const revaptr), \ (grafptr, baseptr, vertptr, verttab, vendtab, \ velotab, vlbltab, edgeptr, edgetab, edlotab, \ revaptr)) { *revaptr = SCOTCH_graphBuild (grafptr, *baseptr, *vertptr, verttab, vendtab, velotab, vlbltab, *edgeptr, edgetab, edlotab); } /* ** */ FORTRAN ( \ SCOTCHFGRAPHSIZE, scotchfgraphsize, ( \ const SCOTCH_Graph * const grafptr, \ SCOTCH_Num * const vertptr, \ SCOTCH_Num * const edgeptr), \ (grafptr, vertptr, edgeptr)) { SCOTCH_graphSize (grafptr, vertptr, edgeptr); } /* ** */ FORTRAN ( \ SCOTCHFGRAPHDATA, scotchfgraphdata, ( \ const SCOTCH_Graph * const grafptr, \ const SCOTCH_Num * const indxptr, \ SCOTCH_Num * const baseptr, \ SCOTCH_Num * const vertptr, \ SCOTCH_Idx * const vertidx, \ SCOTCH_Idx * const vendidx, \ SCOTCH_Idx * const veloidx, \ SCOTCH_Idx * const vlblidx, \ SCOTCH_Num * const edgeptr, \ SCOTCH_Idx * const edgeidx, \ SCOTCH_Idx * const edloidx), \ (grafptr, indxptr, baseptr, \ vertptr, vertidx, vendidx, veloidx, vlblidx, \ edgeptr, edgeidx, edloidx)) { SCOTCH_Num * verttab; /* Pointer to graph arrays */ SCOTCH_Num * vendtab; SCOTCH_Num * velotab; SCOTCH_Num * vlbltab; SCOTCH_Num * edgetab; SCOTCH_Num * edlotab; SCOTCH_graphData (grafptr, baseptr, vertptr, &verttab, &vendtab, &velotab, &vlbltab, edgeptr, &edgetab, &edlotab); *vertidx = (verttab - indxptr) + 1; /* Add 1 since Fortran indices start at 1 */ *vendidx = (vendtab - indxptr) + 1; *veloidx = (velotab != NULL) ? (velotab - indxptr) + 1 : *vertidx; *vlblidx = (vlbltab != NULL) ? (vlbltab - indxptr) + 1 : *vertidx; *edgeidx = (edgetab - indxptr) + 1; *edloidx = (edlotab != NULL) ? (edlotab - indxptr) + 1 : *edgeidx; } /* ** */ FORTRAN ( \ SCOTCHFGRAPHSTAT, scotchfgraphstat, ( \ const SCOTCH_Graph * const grafptr, \ SCOTCH_Num * const velominptr, \ SCOTCH_Num * const velomaxptr, \ SCOTCH_Num * const velosumptr, \ double * veloavgptr, \ double * velodltptr, \ SCOTCH_Num * const degrminptr, \ SCOTCH_Num * const degrmaxptr, \ double * degravgptr, \ double * degrdltptr, \ SCOTCH_Num * const edlominptr, \ SCOTCH_Num * const edlomaxptr, \ SCOTCH_Num * const edlosumptr, \ double * edloavgptr, \ double * edlodltptr), \ (grafptr, velominptr, velomaxptr, velosumptr, \ veloavgptr, velodltptr, degrminptr, \ degrmaxptr, degravgptr, degrdltptr, \ edlominptr, edlomaxptr, edlosumptr, \ edloavgptr, edlodltptr)) { SCOTCH_graphStat (grafptr, velominptr, velomaxptr, velosumptr, veloavgptr, velodltptr, degrminptr, degrmaxptr, degravgptr, degrdltptr, edlominptr, edlomaxptr, edlosumptr, edloavgptr, edlodltptr); } scotch-6.0.4.dfsg/src/libscotch/dgraph_fold_dup.c0000644002563400244210000001666712412035044025132 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2009 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_fold_dup.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module folds a distributed graph **/ /** into two distinct copies, which may **/ /** be different when the number of **/ /** processes is odd. **/ /** **/ /** DATES : # Version 5.0 : from : 10 aug 2006 **/ /** to : 20 jun 2007 **/ /** # Version 5.1 : from : 14 nov 2008 **/ /** to : 28 oct 2009 **/ /** # Version 6.0 : from : 28 sep 2014 **/ /** to : 28 sep 2014 **/ /** **/ /************************************************************/ #define DGRAPH #define DGRAPH_FOLD_DUP #include "module.h" #include "common.h" #include "dgraph.h" #include "dgraph_fold_dup.h" /******************************/ /* */ /* This routine handles */ /* distributed source graphs. */ /* */ /******************************/ /* This routine builds two folded graphs of ** a given graph on each of the two halves ** of the processes. The number of processes ** does not need to be even. There is a ** multi-threaded version, as well as a ** sequential one. ** It returns: ** - 0 : on success. ** - !0 : on error. */ #ifdef SCOTCH_PTHREAD static void * dgraphFoldDup2 ( void * const dataptr) /* Pointer to thread data */ { DgraphFoldDupData * fldthrdptr; fldthrdptr = (DgraphFoldDupData *) dataptr; return ((void *) (intptr_t) dgraphFold2 (fldthrdptr->orggrafptr, fldthrdptr->partval, fldthrdptr->fldgrafptr, fldthrdptr->fldproccomm, fldthrdptr->orgdataptr, fldthrdptr->flddataptr, fldthrdptr->datatype)); } #endif /* SCOTCH_PTHREAD */ int dgraphFoldDup ( const Dgraph * restrict const orggrafptr, Dgraph * restrict const fldgrafptr, void * restrict const orgdataptr, /* Un-based array of data which must be folded, e.g. coarmulttab */ void ** restrict const flddataptr, /* Un-based array of data which must be folded, e.g. coarmulttab */ MPI_Datatype datatype) { int fldprocnbr; int fldprocnum; int fldproccol; MPI_Comm fldproccommtab[2]; #ifdef SCOTCH_PTHREAD Dgraph orggrafdat; DgraphFoldDupData fldthrdtab[2]; pthread_t thrdval; /* Data of second thread */ #endif /* SCOTCH_PTHREAD */ int o; fldprocnbr = (orggrafptr->procglbnbr + 1) / 2; /* Median cut on number of processors */ if (orggrafptr->proclocnum < fldprocnbr) { /* Compute color and rank in two subparts */ fldproccol = 0; fldprocnum = orggrafptr->proclocnum; fldproccommtab[1] = MPI_COMM_NULL; } else { fldproccol = 1; fldprocnum = orggrafptr->proclocnum - fldprocnbr; fldproccommtab[0] = MPI_COMM_NULL; } if (MPI_Comm_split (orggrafptr->proccomm, fldproccol, fldprocnum, &fldproccommtab[fldproccol]) != MPI_SUCCESS) { errorPrint ("dgraphFoldDup: communication error (1)"); return (1); } #ifdef SCOTCH_PTHREAD orggrafdat = *orggrafptr; /* Create a separate graph structure to change its communicator */ fldthrdtab[0].orggrafptr = orggrafptr; fldthrdtab[0].fldgrafptr = fldgrafptr; fldthrdtab[0].fldproccomm = fldproccommtab[0]; fldthrdtab[0].partval = 0; fldthrdtab[0].orgdataptr = orgdataptr; fldthrdtab[0].flddataptr = flddataptr; fldthrdtab[0].datatype = datatype; fldthrdtab[1].orggrafptr = &orggrafdat; fldthrdtab[1].fldgrafptr = fldgrafptr; fldthrdtab[1].fldproccomm = fldproccommtab[1]; fldthrdtab[1].partval = 1; fldthrdtab[1].orgdataptr = orgdataptr; fldthrdtab[1].flddataptr = flddataptr; fldthrdtab[1].datatype = datatype; if (MPI_Comm_dup (orggrafptr->proccomm, &orggrafdat.proccomm) != MPI_SUCCESS) { /* Duplicate communicator to avoid interferences in communications */ errorPrint ("dgraphFoldDup: communication error (2)"); return (1); } if (pthread_create (&thrdval, NULL, dgraphFoldDup2, (void *) &fldthrdtab[1]) != 0) /* If could not create thread */ o = (int) (intptr_t) dgraphFold2 (orggrafptr, 0, fldgrafptr, fldproccommtab[0], orgdataptr, flddataptr, datatype) || /* Call routines in sequence */ (int) (intptr_t) dgraphFold2 (orggrafptr, 1, fldgrafptr, fldproccommtab[1], orgdataptr, flddataptr, datatype); else { /* Newly created thread is processing subgraph 1, so let's process subgraph 0 */ void * o2; o = (int) (intptr_t) dgraphFoldDup2 ((void *) &fldthrdtab[0]); /* Work on copy with private communicator */ pthread_join (thrdval, &o2); o |= (int) (intptr_t) o2; } MPI_Comm_free (&orggrafdat.proccomm); #else /* SCOTCH_PTHREAD */ o = (dgraphFold2 (orggrafptr, 0, fldgrafptr, fldproccommtab[0], orgdataptr, flddataptr, datatype) || /* Call routines in sequence */ dgraphFold2 (orggrafptr, 1, fldgrafptr, fldproccommtab[1], orgdataptr, flddataptr, datatype)); #endif /* SCOTCH_PTHREAD */ fldgrafptr->prockeyval = fldproccol; /* Discriminate between folded communicators at same level */ return (o); } scotch-6.0.4.dfsg/src/libscotch/bgraph_store.c0000644002563400244210000001506311631447171024467 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bgraph_store.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the save data **/ /** structure handling routines for bipar- **/ /** tition graphs. **/ /** **/ /** DATES : # Version 3.3 : from : 17 oct 1998 **/ /** to 17 oct 1998 **/ /** # Version 4.0 : from : 18 dec 2001 **/ /** to 16 jun 2004 **/ /** # Version 5.1 : from : 22 feb 2011 **/ /** to 22 feb 2011 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define BGRAPH_STORE #include "module.h" #include "common.h" #include "graph.h" #include "arch.h" #include "bgraph.h" /**********************************/ /* */ /* Store graph handling routines. */ /* */ /**********************************/ /* This routine builds a save structure ** for the given active graph. ** It returns: ** - 0 : if allocation succeeded. ** - !0 : on error. */ int bgraphStoreInit ( const Bgraph * const grafptr, BgraphStore * const storptr) { Gnum savsize; savsize = (grafptr->s.vertnnd - grafptr->s.baseval) * (sizeof (GraphPart) + sizeof (Gnum)); /* Compute size for frontier and part arrays */ if ((storptr->datatab = (byte *) memAlloc (savsize)) == NULL) { /* Allocate save structure */ errorPrint ("bgraphStoreInit: out of memory"); return (1); } return (0); } /* This routine frees a save structure. ** It returns: ** - VOID : in all cases. */ void bgraphStoreExit ( BgraphStore * const storptr) { memFree (storptr->datatab); #ifdef SCOTCH_DEBUG_BGRAPH2 storptr->datatab = NULL; #endif /* SCOTCH_DEBUG_BGRAPH2 */ } /* This routine saves partition data from the ** given active graph to the given save structure. ** It returns: ** - VOID : in all cases. */ void bgraphStoreSave ( const Bgraph * const grafptr, BgraphStore * const storptr) { Gnum vertnbr; /* Number of vertices in graph */ byte * parttab; /* Pointer to part data save area */ byte * frontab; /* Pointer to frontier data save area */ storptr->fronnbr = grafptr->fronnbr; /* Save partition parameters */ storptr->compload0dlt = grafptr->compload0dlt; storptr->compsize0 = grafptr->compsize0; storptr->commload = grafptr->commload; storptr->commgainextn = grafptr->commgainextn; frontab = storptr->datatab; /* Compute data offsets within save structure */ parttab = frontab + grafptr->fronnbr * sizeof (Gnum); vertnbr = grafptr->s.vertnnd - grafptr->s.baseval; memCpy (frontab, grafptr->frontab, grafptr->fronnbr * sizeof (Gnum)); memCpy (parttab, grafptr->parttax + grafptr->s.baseval, vertnbr * sizeof (GraphPart)); } /* This routine updates partition data of the ** given active graph, using the given save graph. ** It returns: ** - VOID : in all cases. */ void bgraphStoreUpdt ( Bgraph * const grafptr, const BgraphStore * const storptr) { Gnum vertnbr; /* Number of vertices in graph */ byte * frontab; /* Pointer to frontier data save area */ byte * parttab; /* Pointer to part data save area */ grafptr->fronnbr = storptr->fronnbr; /* Load partition parameters */ grafptr->compload0 = storptr->compload0dlt + grafptr->compload0avg; grafptr->compload0dlt = storptr->compload0dlt; grafptr->compsize0 = storptr->compsize0; grafptr->commload = storptr->commload; grafptr->commgainextn = storptr->commgainextn; grafptr->bbalval = (double) ((grafptr->compload0dlt < 0) ? (- grafptr->compload0dlt) : grafptr->compload0dlt) / (double) grafptr->compload0avg; frontab = storptr->datatab; /* Compute data offsets within save structure */ parttab = frontab + grafptr->fronnbr * sizeof (Gnum); vertnbr = grafptr->s.vertnnd - grafptr->s.baseval; memCpy (grafptr->frontab, frontab, grafptr->fronnbr * sizeof (Gnum)); memCpy (grafptr->parttax + grafptr->s.baseval, parttab, vertnbr * sizeof (GraphPart)); #ifdef SCOTCH_DEBUG_BGRAPH2 if (bgraphCheck (grafptr) != 0) errorPrint ("bgraphStoreUpdt: inconsistent graph data"); #endif /* SCOTCH_DEBUG_BGRAPH2 */ } scotch-6.0.4.dfsg/src/libscotch/hmesh.h0000644002563400244210000001317511631447170023122 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data **/ /** declarations for the halo mesh **/ /** structure. **/ /** **/ /** DATES : # Version 4.0 : from : 31 dec 2001 **/ /** to 29 apr 2004 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ Halo mesh structure. Only node vertices can be halo vertices, not element vertices. Halo node vertices are numbered with the highest available node numbers. Since un-haloing of a mesh should be costless, and since the vertex array must be continuous, when a halo mesh indeed bears halo nodes, it is preferrable that elements be numbered first, then non-halo node vertices, then halo vertices, so that the removal of the halo does not create holes in the vertex array. Else, the indices of the halo nodes must be reassigned to empty elements, which results in a larger structure until it is coarsened or induced. If no halo is present, the order of nodes and elements is not relevant. As for the halo graph structure, in the adjacency list of elements, halo node neighbors must all be put after non-halo node neighbors, so that the edge sub-array comprised between verttab[i] and vnhdtab[i] refer only to non-halo node neighbors, such that edgetab can be re-used by the un-halo-ed mesh. Since Hmesh halo meshes are used only for node ordering, the velotab and vnumtab arrays that are created by hmesh*() routines can be restricted to their node part. It must be guaranteed that this does not create problems at freeing time, for instance by grouping these arrays with verttab. +*/ typedef struct Hmesh_ { Mesh m; /*+ Source mesh +*/ Gnum * restrict vehdtax; /*+ End vertex array for elements [based] (non-halo nodes look at m.vendtax) +*/ Gnum veihnbr; /*+ Number of halo isolated element vertices, which have halo nodes only +*/ Gnum vnohnbr; /*+ Number of non-halo node vertices +*/ Gnum vnohnnd; /*+ Based number of first halo node vertex in mesh graph (m.vnodnnd if none) +*/ Gnum vnhlsum; /*+ Sum of non-halo node vertex weights +*/ Gnum enohnbr; /*+ Number of non-halo edges +*/ Gnum levlnum; /*+ Nested dissection level +*/ } Hmesh; /* ** The function prototypes. */ #ifndef HMESH #define static #endif void hmeshExit (Hmesh * const); Gnum hmeshBase (Hmesh * const, const Gnum); #ifdef HGRAPH_H int hmeshHgraph (const Hmesh * restrict const, Hgraph * restrict const); #endif /* HGRAPH_H */ int hmeshInducePart (const Hmesh * const, const GraphPart * const, const GraphPart, const Gnum, const Gnum, const Gnum, Hmesh * const); int hmeshMesh (const Hmesh * restrict const, Mesh * restrict const); int hmeshCheck (const Hmesh *); #undef static scotch-6.0.4.dfsg/src/libscotch/library_graph_io_habo_f.c0000644002563400244210000001212311631447171026614 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_io_habo_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the Fortran API for the **/ /** graph i/o routines of the libSCOTCH **/ /** library. **/ /** **/ /** DATES : # Version 4.0 : from : 23 nov 2005 **/ /** to 23 nov 2005 **/ /** # Version 5.1 : from : 27 mar 2010 **/ /** to 27 mar 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the mapping routines. */ /* */ /**************************************/ /* String lengths are passed at the very ** end of the argument list. */ FORTRAN ( \ SCOTCHFGRAPHGEOMLOADHABO, scotchfgraphgeomloadhabo, ( \ SCOTCH_Graph * const grafptr, \ SCOTCH_Geom * const geomptr, \ const int * const filegrfptr, \ const int * const filegeoptr, \ const char * const dataptr, /* No use */ \ int * const revaptr, \ const int datanbr), \ (grafptr, geomptr, filegrfptr, filegeoptr, dataptr, revaptr, datanbr)) { FILE * filegrfstream; /* Streams to build from handles */ FILE * filegeostream; int filegrfnum; /* Duplicated handle */ int filegeonum; int o; if ((filegrfnum = dup (*filegrfptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFGRAPHGEOMLOADHABO: cannot duplicate handle (1)"); *revaptr = 1; /* Indicate error */ return; } if ((filegeonum = dup (*filegeoptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFGRAPHGEOMLOADHABO: cannot duplicate handle (2)"); close (filegrfnum); *revaptr = 1; /* Indicate error */ return; } if ((filegrfstream = fdopen (filegrfnum, "r")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFGRAPHGEOMLOADHABO: cannot open input stream (1)"); close (filegrfnum); close (filegeonum); *revaptr = 1; return; } if ((filegeostream = fdopen (filegeonum, "r")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFGRAPHGEOMLOADHABO: cannot open input stream (2)"); fclose (filegrfstream); close (filegeonum); *revaptr = 1; return; } o = SCOTCH_graphGeomLoadHabo (grafptr, geomptr, filegrfstream, filegeostream, NULL); fclose (filegrfstream); /* This closes file descriptors too */ fclose (filegeostream); *revaptr = o; } scotch-6.0.4.dfsg/src/libscotch/library_graph_io_habo.c0000644002563400244210000000677511631447170026326 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_io_habo.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the Harwell- **/ /** Boeing geometry and graph handling **/ /** routines of the libSCOTCH library. **/ /** **/ /** DATES : # Version 4.0 : from : 18 nov 2003 **/ /** to 19 jan 2004 **/ /** # Version 5.1 : from : 27 apr 2010 **/ /** to 27 apr 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "geom.h" #include "graph.h" #include "scotch.h" /*************************************/ /* */ /* These routines are the C API for */ /* the Harwell-Boeing geometry */ /* handling routines. */ /* */ /*************************************/ /*+ This routine loads the given opaque geom *** structure with the data of the given stream. *** - 0 : if loading succeeded. *** - !0 : on error. +*/ int SCOTCH_graphGeomLoadHabo ( SCOTCH_Graph * restrict const grafptr, SCOTCH_Geom * restrict const geomptr, FILE * const filegrfptr, FILE * const filegeoptr, const char * const dataptr) { return (graphGeomLoadHabo ((Graph *) grafptr, (Geom *) geomptr, filegrfptr, filegeoptr, dataptr)); } scotch-6.0.4.dfsg/src/libscotch/library_random_f.c0000644002563400244210000000673212416704313025320 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_random_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API for **/ /** the random generator handling routines **/ /** of the libSCOTCH library. **/ /** **/ /** DATES : # Version 4.0 : from : 21 nov 2005 **/ /** to 23 nov 2005 **/ /** # Version 6.0 : from : 08 oct 2012 **/ /** to 03 oct 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the random handling routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFRANDOMPROC, scotchfrandomproc, ( \ const int * const procnum), \ (procnum)) { SCOTCH_randomProc (*procnum); } /* ** */ FORTRAN ( \ SCOTCHFRANDOMRESET, scotchfrandomreset, (), \ ()) { SCOTCH_randomReset (); } /* ** */ FORTRAN ( \ SCOTCHFRANDOMSEED, scotchfrandomseed, ( \ const SCOTCH_Num * const seedptr), \ (seedptr)) { SCOTCH_randomSeed (*seedptr); } scotch-6.0.4.dfsg/src/libscotch/arch_mesh.c0000644002563400244210000005672412354555434023757 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010,2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : arch_mesh.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module handles the mesh graph **/ /** target architectures. **/ /** **/ /** DATES : # Version 0.0 : from : 01 dec 1992 **/ /** to : 24 mar 1993 **/ /** # Version 1.2 : from : 04 feb 1994 **/ /** to : 11 feb 1994 **/ /** # Version 1.3 : from : 20 apr 1994 **/ /** to : 20 apr 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to : 23 dec 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to : 29 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 08 sep 1995 **/ /** # Version 3.1 : from : 22 jul 1996 **/ /** to 23 jul 1996 **/ /** # Version 3.2 : from : 16 oct 1996 **/ /** to 14 may 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 4.0 : from : 09 jan 2004 **/ /** to 10 mar 2005 **/ /** # Version 5.1 : from : 21 jan 2008 **/ /** to 11 aug 2010 **/ /** # Version 6.0 : from : 14 fev 2011 **/ /** to 14 fev 2011 **/ /** **/ /** NOTES : # The vertices of the (dX,dY) mesh are **/ /** numbered as terminals so that **/ /** t(0,0) = 0, t(1,0) = 1, **/ /** t(dX - 1, 0) = dX - 1, t(0,1) = dX, **/ /** and t(x,y) = (y * dX) + x. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define ARCH_MESH #include "module.h" #include "common.h" #include "arch.h" #include "arch_mesh.h" /***********************************************/ /* */ /* These are the 2-dimensional mesh routines. */ /* */ /***********************************************/ /* This routine loads the ** bidimensional mesh architecture. ** It returns: ** - 0 : if the architecture has been successfully read. ** - !0 : on error. */ int archMesh2ArchLoad ( ArchMesh2 * restrict const archptr, FILE * restrict const stream) { #ifdef SCOTCH_DEBUG_ARCH1 if ((sizeof (ArchMesh2) > sizeof (ArchDummy)) || (sizeof (ArchMesh2Dom) > sizeof (ArchDomDummy))) { errorPrint ("archMesh2ArchLoad: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ if ((intLoad (stream, &archptr->c[0]) != 1) || (intLoad (stream, &archptr->c[1]) != 1) || (archptr->c[0] < 1) || (archptr->c[1] < 1)) { errorPrint ("archMesh2ArchLoad: bad input"); return (1); } return (0); } /* This routine saves the ** bidimensional mesh architecture. ** It returns: ** - 0 : if the architecture has been successfully written. ** - !0 : on error. */ int archMesh2ArchSave ( const ArchMesh2 * const archptr, FILE * restrict const stream) { #ifdef SCOTCH_DEBUG_ARCH1 if ((sizeof (ArchMesh2) > sizeof (ArchDummy)) || (sizeof (ArchMesh2Dom) > sizeof (ArchDomDummy))) { errorPrint ("archMesh2ArchSave: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ if (fprintf (stream, ANUMSTRING " " ANUMSTRING " ", (Anum) archptr->c[0], (Anum) archptr->c[1]) == EOF) { errorPrint ("archMesh2ArchSave: bad output"); return (1); } return (0); } /* This function returns the smallest number ** of terminal domain included in the given ** domain. */ ArchDomNum archMesh2DomNum ( const ArchMesh2 * const archptr, const ArchMesh2Dom * const domptr) { return ((domptr->c[1][0] * archptr->c[0]) + domptr->c[0][0]); /* Return vertex number */ } /* This function returns the terminal domain associated ** with the given terminal number in the architecture. ** It returns: ** - 0 : if label is valid and domain has been updated. ** - 1 : if label is invalid. ** - 2 : on error. */ int archMesh2DomTerm ( const ArchMesh2 * const archptr, ArchMesh2Dom * const domptr, const ArchDomNum domnum) { if (domnum < (archptr->c[0] * archptr->c[1])) { /* If valid label */ domptr->c[0][0] = /* Set the domain */ domptr->c[0][1] = domnum % archptr->c[0]; domptr->c[1][0] = domptr->c[1][1] = domnum / archptr->c[0]; return (0); } return (1); /* Cannot set domain */ } /* This function returns the number of ** elements in the rectangular domain. */ Anum archMesh2DomSize ( const ArchMesh2 * const archptr, const ArchMesh2Dom * const domptr) { return ((domptr->c[0][1] - domptr->c[0][0] + 1) * (domptr->c[1][1] - domptr->c[1][0] + 1)); } /* This function returns the average ** distance between two rectangular ** domains (in fact the distance between ** the centers of the domains). */ Anum archMesh2DomDist ( const ArchMesh2 * const archptr, const ArchMesh2Dom * const dom0ptr, const ArchMesh2Dom * const dom1ptr) { return (((abs (dom0ptr->c[0][0] + dom0ptr->c[0][1] - dom1ptr->c[0][0] - dom1ptr->c[0][1]) + 1) / 2) + ((abs (dom0ptr->c[1][0] + dom0ptr->c[1][1] - dom1ptr->c[1][0] - dom1ptr->c[1][1]) + 1) / 2)); } /* This function sets the biggest ** domain available for this ** architecture. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archMesh2DomFrst ( const ArchMesh2 * const archptr, ArchMesh2Dom * restrict const domptr) { domptr->c[0][0] = domptr->c[1][0] = 0; domptr->c[0][1] = archptr->c[0] - 1; domptr->c[1][1] = archptr->c[1] - 1; return (0); } /* This routine reads domain information ** from the given stream. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archMesh2DomLoad ( const ArchMesh2 * const archptr, ArchMesh2Dom * restrict const domptr, FILE * restrict const stream) { if ((intLoad (stream, &domptr->c[0][0]) != 1) || (intLoad (stream, &domptr->c[1][0]) != 1) || (intLoad (stream, &domptr->c[0][1]) != 1) || (intLoad (stream, &domptr->c[1][1]) != 1)) { errorPrint ("archMesh2DomLoad: bad input"); return (1); } return (0); } /* This routine saves domain information ** to the given stream. ** - 0 : on success. ** - !0 : on error. */ int archMesh2DomSave ( const ArchMesh2 * const archptr, const ArchMesh2Dom * const domptr, FILE * restrict const stream) { if (fprintf (stream, ANUMSTRING " " ANUMSTRING " " ANUMSTRING " " ANUMSTRING " ", (Anum) domptr->c[0][0], (Anum) domptr->c[1][0], (Anum) domptr->c[0][1], (Anum) domptr->c[1][1]) == EOF) { errorPrint ("archMesh2DomSave: bad output"); return (1); } return (0); } /* These functions try to split a rectangular ** domain into two subdomains. ** It returns: ** - 0 : if bipartitioning succeeded. ** - 1 : if bipartitioning could not be performed. ** - 2 : on error. */ int archMesh2DomBipart ( const ArchMesh2 * const archptr, const ArchMesh2Dom * const domptr, ArchMesh2Dom * restrict const dom0ptr, ArchMesh2Dom * restrict const dom1ptr) { Anum dimsiz[2]; int dimval; /* Dimension along which to split */ dimsiz[0] = domptr->c[0][1] - domptr->c[0][0]; dimsiz[1] = domptr->c[1][1] - domptr->c[1][0]; if ((dimsiz[0] | dimsiz[1]) == 0) /* Return if cannot bipartition more */ return (1); dimval = 1; if ((dimsiz[0] > dimsiz[1]) || /* Split domain in two along largest dimension */ ((dimsiz[0] == dimsiz[1]) && (archptr->c[0] > archptr->c[1]))) dimval = 0; if (dimval == 0) { /* Split across the X dimension */ dom0ptr->c[0][0] = domptr->c[0][0]; dom0ptr->c[0][1] = (domptr->c[0][0] + domptr->c[0][1]) / 2; dom1ptr->c[0][0] = dom0ptr->c[0][1] + 1; dom1ptr->c[0][1] = domptr->c[0][1]; dom0ptr->c[1][0] = dom1ptr->c[1][0] = domptr->c[1][0]; dom0ptr->c[1][1] = dom1ptr->c[1][1] = domptr->c[1][1]; } else { /* Split across the Y dimension */ dom0ptr->c[0][0] = dom1ptr->c[0][0] = domptr->c[0][0]; dom0ptr->c[0][1] = dom1ptr->c[0][1] = domptr->c[0][1]; dom0ptr->c[1][0] = domptr->c[1][0]; dom0ptr->c[1][1] = (domptr->c[1][0] + domptr->c[1][1]) / 2; dom1ptr->c[1][0] = dom0ptr->c[1][1] + 1; dom1ptr->c[1][1] = domptr->c[1][1]; } return (0); } int archMesh2DomBipartO ( const ArchMesh2 * const archptr, const ArchMesh2Dom * const domptr, ArchMesh2Dom * restrict const dom0ptr, ArchMesh2Dom * restrict const dom1ptr) { if ((domptr->c[0][0] == domptr->c[0][1]) && /* Return if cannot bipartition more */ (domptr->c[1][0] == domptr->c[1][1])) return (1); if (domptr->c[1][1] == domptr->c[1][0]) { /* If the Y dimension cannot be cut */ dom0ptr->c[0][0] = domptr->c[0][0]; /* Cut in the X dimension */ dom0ptr->c[0][1] = (domptr->c[0][0] + domptr->c[0][1]) / 2; dom1ptr->c[0][0] = dom0ptr->c[0][1] + 1; dom1ptr->c[0][1] = domptr->c[0][1]; dom0ptr->c[1][0] = dom1ptr->c[1][0] = domptr->c[1][0]; dom0ptr->c[1][1] = dom1ptr->c[1][1] = domptr->c[1][1]; } else { /* If the Y dimension can be cut, cut it */ dom0ptr->c[0][0] = dom1ptr->c[0][0] = domptr->c[0][0]; dom0ptr->c[0][1] = dom1ptr->c[0][1] = domptr->c[0][1]; dom0ptr->c[1][0] = domptr->c[1][0]; dom0ptr->c[1][1] = (domptr->c[1][0] + domptr->c[1][1]) / 2; dom1ptr->c[1][0] = dom0ptr->c[1][1] + 1; dom1ptr->c[1][1] = domptr->c[1][1]; } return (0); } int archMesh2DomBipartU ( const ArchMesh2 * const archptr, const ArchMesh2Dom * const domptr, ArchMesh2Dom * restrict const dom0ptr, ArchMesh2Dom * restrict const dom1ptr) { if ((domptr->c[0][0] == domptr->c[0][1]) && /* Return if cannot bipartition more */ (domptr->c[1][0] == domptr->c[1][1])) return (1); if ((domptr->c[0][1] - domptr->c[0][0]) > /* Split domain unevenly along largest dimension */ (domptr->c[1][1] - domptr->c[1][0])) { dom0ptr->c[0][0] = domptr->c[0][0]; dom0ptr->c[0][1] = (domptr->c[0][0] + domptr->c[0][1] + domptr->c[0][1]) / 3; dom1ptr->c[0][0] = dom0ptr->c[0][1] + 1; dom1ptr->c[0][1] = domptr->c[0][1]; dom0ptr->c[1][0] = dom1ptr->c[1][0] = domptr->c[1][0]; dom0ptr->c[1][1] = dom1ptr->c[1][1] = domptr->c[1][1]; } else { dom0ptr->c[0][0] = dom1ptr->c[0][0] = domptr->c[0][0]; dom0ptr->c[0][1] = dom1ptr->c[0][1] = domptr->c[0][1]; dom0ptr->c[1][0] = domptr->c[1][0]; dom0ptr->c[1][1] = (domptr->c[1][0] + domptr->c[1][1] + domptr->c[1][1]) / 3; dom1ptr->c[1][0] = dom0ptr->c[1][1] + 1; dom1ptr->c[1][1] = domptr->c[1][1]; } return (0); } /* This function checks if dom1 is ** included in dom0. ** It returns: ** - 0 : if dom1 is not included in dom0. ** - 1 : if dom1 is included in dom0. ** - 2 : on error. */ int archMesh2DomIncl ( const ArchMesh2 * const archptr, const ArchMesh2Dom * const dom0ptr, const ArchMesh2Dom * const dom1ptr) { if ((dom0ptr->c[0][0] <= dom1ptr->c[0][0]) && (dom0ptr->c[0][1] >= dom1ptr->c[0][1]) && (dom0ptr->c[1][0] <= dom1ptr->c[1][0]) && (dom0ptr->c[1][1] >= dom1ptr->c[1][1])) return (1); return (0); } /* This function creates the MPI_Datatype for ** 2D mesh domains. ** It returns: ** - 0 : if type could be created. ** - 1 : on error. */ #ifdef SCOTCH_PTSCOTCH int archMesh2DomMpiType ( const ArchMesh2 * const archptr, MPI_Datatype * const typeptr) { MPI_Type_contiguous (4, ANUM_MPI, typeptr); return (0); } #endif /* SCOTCH_PTSCOTCH */ /***********************************************/ /* */ /* These are the 3-dimensional mesh routines. */ /* */ /***********************************************/ /* This routine loads the ** tridimensional mesh architecture. ** It returns: ** - 0 : if the architecture has been successfully read. ** - !0 : on error. */ int archMesh3ArchLoad ( ArchMesh3 * restrict const archptr, FILE * restrict const stream) { #ifdef SCOTCH_DEBUG_ARCH1 if ((sizeof (ArchMesh3) > sizeof (ArchDummy)) || (sizeof (ArchMesh3Dom) > sizeof (ArchDomDummy))) { errorPrint ("archMesh3ArchLoad: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ if ((intLoad (stream, &archptr->c[0]) != 1) || (intLoad (stream, &archptr->c[1]) != 1) || (intLoad (stream, &archptr->c[2]) != 1) || (archptr->c[0] < 1) || (archptr->c[1] < 1) || (archptr->c[2] < 1)) { errorPrint ("archMesh3ArchLoad: bad input"); return (1); } return (0); } /* This routine saves the ** tridimensional mesh architecture. ** It returns: ** - 0 : if the architecture has been successfully written. ** - !0 : on error. */ int archMesh3ArchSave ( const ArchMesh3 * const archptr, FILE * restrict const stream) { #ifdef SCOTCH_DEBUG_ARCH1 if ((sizeof (ArchMesh3) > sizeof (ArchDummy)) || (sizeof (ArchMesh3Dom) > sizeof (ArchDomDummy))) { errorPrint ("archMesh3ArchSave: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ if (fprintf (stream, ANUMSTRING " " ANUMSTRING " " ANUMSTRING " ", (Anum) archptr->c[0], (Anum) archptr->c[1], (Anum) archptr->c[2]) == EOF) { errorPrint ("archMesh3ArchSave: bad output"); return (1); } return (0); } /* This function returns the smallest number ** of terminal domain included in the given ** domain. */ ArchDomNum archMesh3DomNum ( const ArchMesh3 * const archptr, const ArchMesh3Dom * const domptr) { return ((((domptr->c[2][0] * archptr->c[1]) + /* Return the vertex number */ domptr->c[1][0]) * archptr->c[0]) + domptr->c[0][0]); } /* This function returns the terminal domain associated ** with the given terminal number in the architecture. ** It returns: ** - 0 : if label is valid and domain has been updated. ** - 1 : if label is invalid. ** - 2 : on error. */ int archMesh3DomTerm ( const ArchMesh3 * const archptr, ArchMesh3Dom * const domptr, const ArchDomNum domnum) { if (domnum < (archptr->c[0] * archptr->c[1] * archptr->c[2])) { /* If valid label */ domptr->c[0][0] = /* Set the domain */ domptr->c[0][1] = domnum % archptr->c[0]; domptr->c[1][0] = domptr->c[1][1] = (domnum / archptr->c[0]) % archptr->c[1]; domptr->c[2][0] = domptr->c[2][1] = domnum / (archptr->c[0] * archptr->c[1]); return (0); } return (1); /* Cannot set domain */ } /* This function returns the number of ** elements in the cubic domain. */ Anum archMesh3DomSize ( const ArchMesh3 * const archptr, const ArchMesh3Dom * const domptr) { return ((domptr->c[0][1] - domptr->c[0][0] + 1) * (domptr->c[1][1] - domptr->c[1][0] + 1) * (domptr->c[2][1] - domptr->c[2][0] + 1)); } /* This function returns the average distance ** between two cubic domains (in fact the ** distance between the centers of the domains). */ Anum archMesh3DomDist ( const ArchMesh3 * const archptr, const ArchMesh3Dom * const dom0ptr, const ArchMesh3Dom * const dom1ptr) { return (((abs (dom0ptr->c[0][0] + dom0ptr->c[0][1] - dom1ptr->c[0][0] - dom1ptr->c[0][1]) + 1) / 2) + ((abs (dom0ptr->c[1][0] + dom0ptr->c[1][1] - dom1ptr->c[1][0] - dom1ptr->c[1][1]) + 1) / 2) + ((abs (dom0ptr->c[2][0] + dom0ptr->c[2][1] - dom1ptr->c[2][0] - dom1ptr->c[2][1]) + 1) / 2)); } /* This function sets the biggest ** domain available for this ** architecture. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archMesh3DomFrst ( const ArchMesh3 * const archptr, ArchMesh3Dom * restrict const domptr) { domptr->c[0][0] = domptr->c[1][0] = domptr->c[2][0] = 0; domptr->c[0][1] = archptr->c[0] - 1; domptr->c[1][1] = archptr->c[1] - 1; domptr->c[2][1] = archptr->c[2] - 1; return (0); } /* This routine reads domain information ** from the given stream. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archMesh3DomLoad ( const ArchMesh3 * const archptr, ArchMesh3Dom * restrict const domptr, FILE * restrict const stream) { if ((intLoad (stream, &domptr->c[0][0]) != 1) || (intLoad (stream, &domptr->c[1][0]) != 1) || (intLoad (stream, &domptr->c[2][0]) != 1) || (intLoad (stream, &domptr->c[0][1]) != 1) || (intLoad (stream, &domptr->c[1][1]) != 1) || (intLoad (stream, &domptr->c[2][1]) != 1)) { errorPrint ("archMesh3DomLoad: bad input"); return (1); } return (0); } /* This routine saves domain information ** to the given stream. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archMesh3DomSave ( const ArchMesh3 * const archptr, const ArchMesh3Dom * const domptr, FILE * restrict const stream) { if (fprintf (stream, ANUMSTRING " " ANUMSTRING " " ANUMSTRING " " ANUMSTRING " " ANUMSTRING " " ANUMSTRING " ", (Anum) domptr->c[0][0], (Anum) domptr->c[1][0], (Anum) domptr->c[2][0], (Anum) domptr->c[0][1], (Anum) domptr->c[1][1], (Anum) domptr->c[2][1]) == EOF) { errorPrint ("archMesh3DomSave: bad output"); return (1); } return (0); } /* This function tries to split a cubic ** domain into two subdomains. ** It returns: ** - 0 : if bipartitioning succeeded. ** - 1 : if bipartitioning could not be performed. ** - 2 : on error. */ int archMesh3DomBipart ( const ArchMesh3 * const archptr, const ArchMesh3Dom * const domptr, ArchMesh3Dom * restrict const dom0ptr, ArchMesh3Dom * restrict const dom1ptr) { Anum dimsiz[3]; int dimtmp; int dimval; dimsiz[0] = domptr->c[0][1] - domptr->c[0][0]; dimsiz[1] = domptr->c[1][1] - domptr->c[1][0]; dimsiz[2] = domptr->c[2][1] - domptr->c[2][0]; if ((dimsiz[0] | dimsiz[1] | dimsiz[2]) == 0) /* Return if cannot bipartition more */ return (1); dimval = (archptr->c[1] > archptr->c[0]) ? 1 : 0; /* Assume all subdomain dimensions are equal */ if (archptr->c[2] > archptr->c[dimval]) /* Find priviledged dimension */ dimval = 2; dimtmp = dimval; /* Find best dimension */ if (dimsiz[(dimtmp + 1) % 3] > dimsiz[dimval]) dimval = (dimtmp + 1) % 3; if (dimsiz[(dimtmp + 2) % 3] > dimsiz[dimval]) dimval = (dimtmp + 2) % 3; if (dimval == 0) { /* Split domain in two along largest dimension */ dom0ptr->c[0][0] = domptr->c[0][0]; dom0ptr->c[0][1] = (domptr->c[0][0] + domptr->c[0][1]) / 2; dom1ptr->c[0][0] = dom0ptr->c[0][1] + 1; dom1ptr->c[0][1] = domptr->c[0][1]; dom0ptr->c[1][0] = dom1ptr->c[1][0] = domptr->c[1][0]; dom0ptr->c[1][1] = dom1ptr->c[1][1] = domptr->c[1][1]; dom0ptr->c[2][0] = dom1ptr->c[2][0] = domptr->c[2][0]; dom0ptr->c[2][1] = dom1ptr->c[2][1] = domptr->c[2][1]; } else if (dimval == 1) { dom0ptr->c[0][0] = dom1ptr->c[0][0] = domptr->c[0][0]; dom0ptr->c[0][1] = dom1ptr->c[0][1] = domptr->c[0][1]; dom0ptr->c[1][0] = domptr->c[1][0]; dom0ptr->c[1][1] = (domptr->c[1][0] + domptr->c[1][1]) / 2; dom1ptr->c[1][0] = dom0ptr->c[1][1] + 1; dom1ptr->c[1][1] = domptr->c[1][1]; dom0ptr->c[2][0] = dom1ptr->c[2][0] = domptr->c[2][0]; dom0ptr->c[2][1] = dom1ptr->c[2][1] = domptr->c[2][1]; } else { dom0ptr->c[0][0] = dom1ptr->c[0][0] = domptr->c[0][0]; dom0ptr->c[0][1] = dom1ptr->c[0][1] = domptr->c[0][1]; dom0ptr->c[1][0] = dom1ptr->c[1][0] = domptr->c[1][0]; dom0ptr->c[1][1] = dom1ptr->c[1][1] = domptr->c[1][1]; dom0ptr->c[2][0] = domptr->c[2][0]; dom0ptr->c[2][1] = (domptr->c[2][0] + domptr->c[2][1]) / 2; dom1ptr->c[2][0] = dom0ptr->c[2][1] + 1; dom1ptr->c[2][1] = domptr->c[2][1]; } return (0); } /* This function checks if dom1 is ** included in dom0. ** It returns: ** - 0 : if dom1 is not included in dom0. ** - 1 : if dom1 is included in dom0. ** - 2 : on error. */ int archMesh3DomIncl ( const ArchMesh3 * const archptr, const ArchMesh3Dom * const dom0ptr, const ArchMesh3Dom * const dom1ptr) { if ((dom0ptr->c[0][0] <= dom1ptr->c[0][0]) && (dom0ptr->c[0][1] >= dom1ptr->c[0][1]) && (dom0ptr->c[1][0] <= dom1ptr->c[1][0]) && (dom0ptr->c[1][1] >= dom1ptr->c[1][1]) && (dom0ptr->c[2][0] <= dom1ptr->c[2][0]) && (dom0ptr->c[2][1] >= dom1ptr->c[2][1])) return (1); return (0); } /* This function creates the MPI_Datatype for ** 3D mesh domains. ** It returns: ** - 0 : if type could be created. ** - 1 : on error. */ #ifdef SCOTCH_PTSCOTCH int archMesh3DomMpiType ( const ArchMesh3 * const archptr, MPI_Datatype * const typeptr) { MPI_Type_contiguous (6, ANUM_MPI, typeptr); return (0); } #endif /* SCOTCH_PTSCOTCH */ scotch-6.0.4.dfsg/src/libscotch/bgraph_bipart_zr.c0000644002563400244210000000741711631447170025332 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bgraph_bipart_zr.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module moves all of the vertices **/ /** to the first subdomain of the **/ /** bipartition. **/ /** **/ /** DATES : # Version 3.2 : from : 23 aug 1996 **/ /** to 13 sep 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 3.4 : from : 01 jun 2001 **/ /** to 01 jun 2001 **/ /** # Version 4.0 : from : 01 nov 2003 **/ /** to 29 may 2004 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define BGRAPH_BIPART_ZR #include "module.h" #include "common.h" #include "graph.h" #include "arch.h" #include "bgraph.h" #include "bgraph_bipart_zr.h" /********************************/ /* */ /* Zero bipartitioning routine. */ /* */ /********************************/ /* This routine moves all the vertices ** of the given graph to the first part. ** It returns: ** - 0 : if bipartitioning could be computed. ** - 1 : on error. */ int bgraphBipartZr ( Bgraph * restrict const grafptr) /*+ Active graph +*/ { if (grafptr->compload0 != grafptr->s.velosum) /* If not all vertices already in part zero */ bgraphZero (grafptr); #ifdef SCOTCH_DEBUG_BGRAPH2 if (bgraphCheck (grafptr) != 0) { errorPrint ("bgraphBipartZr: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/parser_yy.h0000644002563400244210000001013011631447170024017 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : parser_yy.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a static mapper. **/ /** These lines are the declarations for **/ /** the strategy strings syntactic parser. **/ /** **/ /** DATES : # Version 3.1 : from : 07 nov 1995 **/ /** to 30 may 1996 **/ /** # Version 3.2 : from : 03 oct 1996 **/ /** to 19 oct 1996 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 4.0 : from : 20 dec 2001 **/ /** to 21 dec 2001 **/ /** # Version 5.1 : from : 09 jun 2009 **/ /** to 07 aug 2010 **/ /** **/ /************************************************************/ /* ** The defines. */ /* Change some function names. */ #if ((defined SCOTCH_RENAME_PARSER) || (defined yylex)) /* If prefix renaming */ #define scotchyyparse stratParserParse2 /* Parser function name */ #define scotchyyerror stratParserError /* Error processing routine */ #ifndef yylval #define yylval scotchyylval /* It should be Yacc/Bison's job to redefine it! */ #endif /* yylval */ #else /* SCOTCH_RENAME_PARSER */ #define yylex stratParserLex /* Lexical analyzer */ #define yyparse stratParserParse2 /* Parser function name */ #define yyerror stratParserError /* Error processing routine */ #endif /* SCOTCH_RENAME_PARSER */ /* ** The function prototypes. */ #ifndef PARSER_YY #define static #endif int yylex (void); Strat * stratParserParse (const StratTab * const, const char * const); int stratParserParse2 (void); static int stratParserError (const char * const); #undef static scotch-6.0.4.dfsg/src/libscotch/vdgraph_separate_bd.c0000644002563400244210000002365111631447171025776 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vdgraph_separate_bd.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Cedric CHEVALIER **/ /** **/ /** FUNCTION : This module computes a separator of the **/ /** given distributed separator graph by **/ /** creating a band graph of given witdh **/ /** around the current separator, computing **/ /** an improved separator of the band **/ /** graph, and projecting back the obtained **/ /** separator in the original graph. **/ /** **/ /** DATES : # Version 5.0 : from : 04 mar 2006 **/ /** to : 07 nov 2007 **/ /** # Version 5.1 : from : 11 nov 2007 **/ /** to : 01 mar 2008 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VDGRAPH_SEPARATE_BD #include "module.h" #include "common.h" #include "parser.h" #include "dgraph.h" #include "vdgraph.h" #include "vdgraph_separate_bd.h" #include "vdgraph_separate_st.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine computes a distributed band graph ** of given width around the current separator and ** applies distributed separation routines to it. ** The distributed graph is not guaranteed to be ** balanced at at all. ** It returns: ** - 0 : if the distributed band graph could be computed. ** - !0 : on error. */ int vdgraphSeparateBd ( Vdgraph * const grafptr, /*+ Distributed graph +*/ const VdgraphSeparateBdParam * const paraptr) /*+ Method parameters +*/ { Vdgraph bandgrafdat; /* Vertex separator band graph structure */ Gnum bandvertancnnd; /* End of local vertex array, without anchors */ Gnum bandvertlocnbr1; /* Number of band graph vertices in part 1 except anchor 1 */ Gnum bandvertlocnum; Gnum bandvertlocancadj; /* Flag set when anchor(s) represent unexistent vertices */ Gnum bandvertglbancadj; /* Global adjustment of anchor vertices */ Gnum complocsizeadj0; Gnum complocsizeadj1; Gnum reduloctab[3]; Gnum reduglbtab[3]; Gnum * restrict edloloctax; /* Save value for edge loads while we pretend we don't have them */ Gnum fronlocnum; if (grafptr->compglbsize[2] == 0) /* If no frontier to base on */ return (0); /* Then do nothing */ if (paraptr->distmax < 1) /* If distance is 0 (or less) */ return (0); /* Then do nothing */ edloloctax = grafptr->s.edloloctax; /* Fake no edge loads on original graph as we do not need them */ grafptr->s.edloloctax = NULL; if (dgraphBand (&grafptr->s, grafptr->complocsize[2], grafptr->fronloctab, grafptr->partgsttax, grafptr->complocload[0] + grafptr->complocload[2], grafptr->complocload[1], paraptr->distmax, &bandgrafdat.s, &bandgrafdat.fronloctab, &bandgrafdat.partgsttax, NULL, &bandvertlocnbr1, &bandvertlocancadj) != 0) { grafptr->s.edloloctax = edloloctax; errorPrint ("vdgraphSeparateBd: cannot create band graph"); return (1); } grafptr->s.edloloctax = edloloctax; /* Restore edge loads, if any */ bandgrafdat.complocsize[0] = bandgrafdat.s.vertlocnbr - (bandvertlocnbr1 + 1) - grafptr->complocsize[2]; /* Add 1 for anchor vertex 1 */ bandgrafdat.complocsize[1] = bandvertlocnbr1 + 1; /* Add 1 for anchor vertex 1 */ complocsizeadj0 = grafptr->complocsize[0] - bandgrafdat.complocsize[0]; complocsizeadj1 = grafptr->complocsize[1] - bandgrafdat.complocsize[1]; reduloctab[0] = bandgrafdat.complocsize[0]; reduloctab[1] = bandgrafdat.complocsize[1]; reduloctab[2] = bandvertlocancadj; /* Sum increases in size and load */ if (MPI_Allreduce (&reduloctab[0], &reduglbtab[0], 3, GNUM_MPI, MPI_SUM, grafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("vdgraphSeparateBd: communication error (1)"); return (1); } bandvertglbancadj = reduglbtab[2]; bandgrafdat.compglbload[0] = grafptr->compglbload[0] + bandvertglbancadj; /* All loads are kept in band graph */ bandgrafdat.compglbload[1] = grafptr->compglbload[1] + bandvertglbancadj; bandgrafdat.compglbload[2] = grafptr->compglbload[2]; bandgrafdat.compglbloaddlt = grafptr->compglbloaddlt; /* Balance is not changed by anchor vertices */ bandgrafdat.complocload[0] = grafptr->complocload[0] + bandvertlocancadj; bandgrafdat.complocload[1] = grafptr->complocload[1] + bandvertlocancadj; bandgrafdat.complocload[2] = grafptr->complocload[2]; bandgrafdat.compglbsize[0] = reduglbtab[0]; bandgrafdat.compglbsize[1] = reduglbtab[1]; bandgrafdat.compglbsize[2] = grafptr->compglbsize[2]; /* All separator vertices are kept in band graph */ bandgrafdat.complocsize[2] = grafptr->complocsize[2]; bandgrafdat.levlnum = grafptr->levlnum; #ifdef SCOTCH_DEBUG_VDGRAPH2 if (vdgraphCheck (&bandgrafdat) != 0) { errorPrint ("vdgraphSeparateBd: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_VDGRAPH2 */ if (vdgraphSeparateSt (&bandgrafdat, paraptr->strat) != 0) { /* Separate distributed band graph */ errorPrint ("vdgraphSeparateBd: cannot separate band graph"); vdgraphExit (&bandgrafdat); return (1); } bandvertancnnd = bandgrafdat.s.vertlocnnd - 2; reduloctab[0] = ((bandgrafdat.partgsttax[bandvertancnnd] == 0) && /* Check if anchor vertices remain in their parts */ (bandgrafdat.partgsttax[bandvertancnnd + 1] == 1)) ? 0 : 1; reduloctab[1] = bandgrafdat.complocsize[0] + complocsizeadj0; reduloctab[2] = bandgrafdat.complocsize[1] + complocsizeadj1; if (MPI_Allreduce (&reduloctab[0], &reduglbtab[0], 3, GNUM_MPI, MPI_SUM, grafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("vdgraphSeparateBd: communication error (2)"); return (1); } if (reduglbtab[0] != 0) { /* If at least one anchor changed of part */ vdgraphExit (&bandgrafdat); /* Then keep original partition */ return (0); } grafptr->compglbload[0] = bandgrafdat.compglbload[0] - bandvertglbancadj; grafptr->compglbload[1] = bandgrafdat.compglbload[1] - bandvertglbancadj; grafptr->compglbload[2] = bandgrafdat.compglbload[2]; grafptr->compglbloaddlt = bandgrafdat.compglbloaddlt; grafptr->compglbsize[0] = reduglbtab[1]; grafptr->compglbsize[1] = reduglbtab[2]; grafptr->compglbsize[2] = bandgrafdat.compglbsize[2]; grafptr->complocload[0] = bandgrafdat.complocload[0] - bandvertlocancadj; grafptr->complocload[1] = bandgrafdat.complocload[1] - bandvertlocancadj; grafptr->complocload[2] = bandgrafdat.complocload[2]; grafptr->complocsize[0] = reduloctab[1]; grafptr->complocsize[1] = reduloctab[2]; grafptr->complocsize[2] = bandgrafdat.complocsize[2]; for (fronlocnum = 0; fronlocnum < bandgrafdat.complocsize[2]; fronlocnum ++) /* Project back separator */ grafptr->fronloctab[fronlocnum] = bandgrafdat.s.vnumloctax[bandgrafdat.fronloctab[fronlocnum]]; for (bandvertlocnum = bandgrafdat.s.baseval; bandvertlocnum < bandvertancnnd; bandvertlocnum ++) /* For all vertices except anchors */ grafptr->partgsttax[bandgrafdat.s.vnumloctax[bandvertlocnum]] = bandgrafdat.partgsttax[bandvertlocnum]; #ifdef SCOTCH_DEBUG_VDGRAPH2 if (vdgraphCheck (grafptr) != 0) { errorPrint ("vdgraphSeparateBd: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_VDGRAPH2 */ vdgraphExit (&bandgrafdat); return (0); } scotch-6.0.4.dfsg/src/libscotch/library_mesh_io_scot.c0000644002563400244210000000771211631447171026211 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_mesh_io_scot.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the Scotch **/ /** geometry and mesh handling routines o f **/ /** the libSCOTCH library. **/ /** **/ /** DATES : # Version 4.0 : from : 19 jan 2004 **/ /** to 19 jan 2004 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "geom.h" #include "graph.h" #include "mesh.h" #include "scotch.h" /*************************************/ /* */ /* These routines are the C API for */ /* the Scotch mesh and geometry */ /* handling routines. */ /* */ /*************************************/ /*+ This routine loads the given opaque mesh *** structure with the data of the given stream. *** - 0 : if loading succeeded. *** - !0 : on error. +*/ int SCOTCH_meshGeomLoadScot ( SCOTCH_Mesh * restrict const meshptr, SCOTCH_Geom * restrict const geomptr, FILE * const filesrcptr, FILE * const filegeoptr, const char * const dataptr) /* No use */ { return (meshGeomLoadScot ((Mesh *) meshptr, (Geom *) geomptr, filesrcptr, filegeoptr, NULL)); } /*+ This routine saves the contents of the given *** opaque mesh structure to the given stream. *** It returns: *** - 0 : if the saving succeeded. *** - !0 : on error. +*/ int SCOTCH_meshGeomSaveScot ( const SCOTCH_Mesh * restrict const meshptr, const SCOTCH_Geom * restrict const geomptr, FILE * const filesrcptr, FILE * const filegeoptr, const char * const dataptr) /* No use */ { return (meshGeomSaveScot ((Mesh *) meshptr, (Geom *) geomptr, filesrcptr, filegeoptr, NULL)); } scotch-6.0.4.dfsg/src/libscotch/library_graph.c0000644002563400244210000004342212057311742024632 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the source **/ /** graph handling routines of the **/ /** libSCOTCH library. **/ /** **/ /** DATES : # Version 3.2 : from : 18 aug 1998 **/ /** to 18 aug 1998 **/ /** # Version 3.3 : from : 02 oct 1998 **/ /** to 01 nov 2001 **/ /** # Version 4.0 : from : 11 dec 2001 **/ /** to 09 dec 2005 **/ /** # Version 5.0 : from : 10 sep 2006 **/ /** to 03 apr 2008 **/ /** # Version 5.1 : from : 17 nov 2010 **/ /** to 17 nov 2010 **/ /** # Version 6.0 : from : 04 dec 2012 **/ /** to 04 dec 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "graph.h" #include "graph_io.h" #include "scotch.h" /************************************/ /* */ /* These routines are the C API for */ /* the graph handling routines. */ /* */ /************************************/ /*+ This routine reserves a memory area *** of a size sufficient to store a *** centralized graph structure. *** It returns: *** - !NULL : if the initialization succeeded. *** - NULL : on error. +*/ SCOTCH_Graph * SCOTCH_graphAlloc () { return ((SCOTCH_Graph *) memAlloc (sizeof (SCOTCH_Graph))); } /*+ This routine initializes the opaque *** graph structure used to handle graphs *** in the Scotch library. *** It returns: *** - 0 : if the initialization succeeded. *** - !0 : on error. +*/ int SCOTCH_graphInit ( SCOTCH_Graph * const grafptr) { if (sizeof (SCOTCH_Num) != sizeof (Gnum)) { errorPrint ("SCOTCH_graphInit: internal error (1)"); return (1); } if (sizeof (SCOTCH_Graph) < sizeof (Graph)) { errorPrint ("SCOTCH_graphInit: internal error (2)"); return (1); } return (graphInit ((Graph *) grafptr)); } /*+ This routine frees the contents of the *** given opaque graph structure. *** It returns: *** - VOID : in all cases. +*/ void SCOTCH_graphExit ( SCOTCH_Graph * const grafptr) { graphExit ((Graph *) grafptr); } /*+ This routine frees the contents of the *** given opaque graph structure. *** It returns: *** - VOID : in all cases. +*/ void SCOTCH_graphFree ( SCOTCH_Graph * const grafptr) { graphFree ((Graph *) grafptr); } /*+ This routine loads the given opaque graph *** structure with the data of the given stream. *** The base value allows the user to set the *** graph base to 0 or 1, or to the base value *** of the stream if the base value is equal *** to -1. On input, vertex loads are discarded if *** flagval is 1, edge loads are discarded if flagval *** is 2, and both if flagval is set to 3. *** It returns: *** - 0 : if the loading succeeded. *** - !0 : on error. +*/ int SCOTCH_graphLoad ( SCOTCH_Graph * const grafptr, FILE * const stream, const SCOTCH_Num baseval, const SCOTCH_Num flagval) { GraphFlag srcgrafflag; /* Graph flags */ if ((baseval < -1) || (baseval > 1)) { errorPrint ("SCOTCH_graphLoad: invalid base parameter"); return (1); } if ((flagval < 0) || (flagval > 3)) { errorPrint ("SCOTCH_graphLoad: invalid flag parameter"); return (1); } srcgrafflag = (((flagval & 1) != 0) ? GRAPHIONOLOADVERT : 0) + (((flagval & 2) != 0) ? GRAPHIONOLOADEDGE : 0); return (graphLoad ((Graph * const) grafptr, stream, (Gnum) baseval, srcgrafflag)); } /*+ This routine saves the contents of the given *** opaque graph structure to the given stream. *** It returns: *** - 0 : if the saving succeeded. *** - !0 : on error. +*/ int SCOTCH_graphSave ( const SCOTCH_Graph * const grafptr, FILE * const stream) { return (graphSave ((const Graph * const) grafptr, stream)); } /*+ This routine fills the contents of the given *** opaque graph structure with the data provided *** by the user. The base value allows the user to *** set the graph base to 0 or 1. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphBuild ( SCOTCH_Graph * const grafptr, /* Graph structure to fill */ const SCOTCH_Num baseval, /* Base value */ const SCOTCH_Num vertnbr, /* Number of vertices */ const SCOTCH_Num * const verttab, /* Vertex array [vertnbr or vertnbr+1] */ const SCOTCH_Num * const vendtab, /* Vertex end array [vertnbr] */ const SCOTCH_Num * const velotab, /* Vertex load array */ const SCOTCH_Num * const vlbltab, /* Vertex label array */ const SCOTCH_Num edgenbr, /* Number of edges (arcs) */ const SCOTCH_Num * const edgetab, /* Edge array [edgenbr] */ const SCOTCH_Num * const edlotab) /* Edge load array */ { Graph * srcgrafptr; /* Pointer to source graph structure */ Gnum vertnum; /* Current vertex number */ Gnum degrmax; /* Maximum degree */ #ifdef SCOTCH_DEBUG_LIBRARY1 if (sizeof (SCOTCH_Graph) < sizeof (Graph)) { errorPrint ("SCOTCH_graphBuild: internal error"); return (1); } #endif /* SCOTCH_DEBUG_LIBRARY1 */ if ((baseval < 0) || (baseval > 1)) { errorPrint ("SCOTCH_graphBuild: invalid base parameter"); return (1); } srcgrafptr = (Graph *) grafptr; /* Use structure as source graph */ srcgrafptr->flagval = GRAPHNONE; srcgrafptr->baseval = baseval; srcgrafptr->vertnbr = vertnbr; srcgrafptr->vertnnd = vertnbr + baseval; srcgrafptr->verttax = (Gnum *) verttab - baseval; srcgrafptr->vendtax = ((vendtab == NULL) || (vendtab == verttab)) ? srcgrafptr->verttax + 1 : (Gnum *) vendtab - baseval; srcgrafptr->velotax = ((velotab == NULL) || (velotab == verttab)) ? NULL : (Gnum *) velotab - baseval; srcgrafptr->vnumtax = NULL; srcgrafptr->vlbltax = ((vlbltab == NULL) || (vlbltab == verttab)) ? NULL : (Gnum *) vlbltab - baseval; srcgrafptr->edgenbr = edgenbr; srcgrafptr->edgetax = (Gnum *) edgetab - baseval; srcgrafptr->edlotax = ((edlotab == NULL) || (edlotab == edgetab)) ? NULL : (Gnum *) edlotab - baseval; if (srcgrafptr->velotax == NULL) /* Compute vertex load sum */ srcgrafptr->velosum = vertnbr; else { Gnum velosum; /* Sum of vertex loads */ for (vertnum = srcgrafptr->baseval, velosum = 0; vertnum < srcgrafptr->vertnnd; vertnum ++) velosum += srcgrafptr->velotax[vertnum]; srcgrafptr->velosum = velosum; } if (srcgrafptr->edlotax == NULL) { /* If no edge loads */ srcgrafptr->edlosum = srcgrafptr->edgenbr; /* Edge load sum is known */ for (vertnum = srcgrafptr->baseval, degrmax = 0; /* Compute maximum degree only */ vertnum < srcgrafptr->vertnnd; vertnum ++) { Gnum degrval; /* Degree of current vertex */ degrval = srcgrafptr->vendtax[vertnum] - srcgrafptr->verttax[vertnum]; if (degrval > degrmax) degrmax = degrval; } } else { /* Graph has edge loads, compute edge load sum */ Gnum edlosum; for (vertnum = srcgrafptr->baseval, edlosum = degrmax = 0; vertnum < srcgrafptr->vertnnd; vertnum ++) { Gnum edgenum; Gnum degrval; /* Degree of current vertex */ degrval = srcgrafptr->vendtax[vertnum] - srcgrafptr->verttax[vertnum]; if (degrval > degrmax) degrmax = degrval; for (edgenum = srcgrafptr->verttax[vertnum]; edgenum < srcgrafptr->vendtax[vertnum]; edgenum ++) edlosum += srcgrafptr->edlotax[edgenum]; } srcgrafptr->edlosum = edlosum; } srcgrafptr->degrmax = degrmax; return (0); } /*+ This routine accesses graph size data. *** NULL pointers on input indicate unwanted *** data. *** It returns: *** - VOID : in all cases. +*/ void SCOTCH_graphSize ( const SCOTCH_Graph * const grafptr, SCOTCH_Num * const vertnbr, SCOTCH_Num * const edgenbr) { const Graph * srcgrafptr; srcgrafptr = (Graph *) grafptr; if (vertnbr != NULL) *vertnbr = (SCOTCH_Num) (srcgrafptr->vertnbr); if (edgenbr != NULL) *edgenbr = (SCOTCH_Num) srcgrafptr->edgenbr; } /*+ This routine accesses all of the graph data. *** NULL pointers on input indicate unwanted *** data. NULL pointers on output indicate *** unexisting arrays. *** It returns: *** - VOID : in all cases. +*/ void SCOTCH_graphData ( const SCOTCH_Graph * const grafptr, /* Graph structure to read */ SCOTCH_Num * const baseptr, /* Base value */ SCOTCH_Num * const vertptr, /* Number of vertices */ SCOTCH_Num ** const verttab, /* Vertex array [vertnbr+1] */ SCOTCH_Num ** const vendtab, /* Vertex array [vertnbr] */ SCOTCH_Num ** const velotab, /* Vertex load array */ SCOTCH_Num ** const vlbltab, /* Vertex label array */ SCOTCH_Num * const edgeptr, /* Number of edges (arcs) */ SCOTCH_Num ** const edgetab, /* Edge array [edgenbr] */ SCOTCH_Num ** const edlotab) /* Edge load array */ { const Graph * srcgrafptr; /* Pointer to source graph structure */ srcgrafptr = (const Graph *) grafptr; if (baseptr != NULL) *baseptr = srcgrafptr->baseval; if (vertptr != NULL) *vertptr = srcgrafptr->vertnbr; if (verttab != NULL) *verttab = srcgrafptr->verttax + srcgrafptr->baseval; if (vendtab != NULL) *vendtab = srcgrafptr->vendtax + srcgrafptr->baseval; if (velotab != NULL) *velotab = (srcgrafptr->velotax != NULL) ? srcgrafptr->velotax + srcgrafptr->baseval : NULL; if (vlbltab != NULL) *vlbltab = (srcgrafptr->vlbltax != NULL) ? srcgrafptr->vlbltax + srcgrafptr->baseval : NULL; if (edgeptr != NULL) *edgeptr = srcgrafptr->edgenbr; if (edgetab != NULL) *edgetab = srcgrafptr->edgetax + srcgrafptr->baseval; if (edlotab != NULL) *edlotab = (srcgrafptr->edlotax != NULL) ? srcgrafptr->edlotax + srcgrafptr->baseval : NULL; } /*+ This routine computes statistics *** on the given graph. *** It returns: *** - VOID : in all cases. +*/ void SCOTCH_graphStat ( const SCOTCH_Graph * const grafptr, SCOTCH_Num * const velominptr, SCOTCH_Num * const velomaxptr, SCOTCH_Num * const velosumptr, double * veloavgptr, double * velodltptr, SCOTCH_Num * const degrminptr, SCOTCH_Num * const degrmaxptr, double * degravgptr, double * degrdltptr, SCOTCH_Num * const edlominptr, SCOTCH_Num * const edlomaxptr, SCOTCH_Num * const edlosumptr, double * edloavgptr, double * edlodltptr) { const Graph * srcgrafptr; Gnum vertnum; Gnum vertnbr; Gnum velomin; Gnum velomax; double veloavg; double velodlt; Gnum degrval; Gnum degrmin; Gnum degrmax; double degravg; double degrdlt; Gnum edgenum; Gnum edlomin; Gnum edlomax; Gnum edlosum; double edloavg; double edlodlt; srcgrafptr = (Graph *) grafptr; vertnbr = srcgrafptr->vertnnd - srcgrafptr->baseval; velodlt = 0.0L; if (vertnbr > 0) { if (srcgrafptr->velotax != NULL) { /* If graph has vertex loads */ velomin = GNUMMAX; velomax = 0; veloavg = (double) srcgrafptr->velosum / (double) vertnbr; for (vertnum = srcgrafptr->baseval; vertnum < srcgrafptr->vertnnd; vertnum ++) { if (srcgrafptr->velotax[vertnum] < velomin) /* Account for vertex loads */ velomin = srcgrafptr->velotax[vertnum]; if (srcgrafptr->velotax[vertnum] > velomax) velomax = srcgrafptr->velotax[vertnum]; velodlt += fabs ((double) srcgrafptr->velotax[vertnum] - veloavg); } velodlt /= (double) vertnbr; } else { velomin = velomax = 1; veloavg = 1.0L; } } else { velomin = velomax = 0; veloavg = 0.0L; } if (velominptr != NULL) *velominptr = (SCOTCH_Num) velomin; if (velomaxptr != NULL) *velomaxptr = (SCOTCH_Num) velomax; if (velosumptr != NULL) *velosumptr = (SCOTCH_Num) srcgrafptr->velosum; if (veloavgptr != NULL) *veloavgptr = (double) veloavg; if (velodltptr != NULL) *velodltptr = (double) velodlt; degrmax = 0; degrdlt = 0.0L; if (vertnbr > 0) { degrmin = GNUMMAX; degravg = (double) srcgrafptr->edgenbr / (double) vertnbr; for (vertnum = srcgrafptr->baseval; vertnum < srcgrafptr->vertnnd; vertnum ++) { degrval = srcgrafptr->vendtax[vertnum] - srcgrafptr->verttax[vertnum]; /* Get vertex degree */ if (degrval < degrmin) degrmin = degrval; if (degrval > degrmax) degrmax = degrval; degrdlt += fabs ((double) degrval - degravg); } degrdlt /= (double) vertnbr; } else { degrmin = 0; degravg = 0.0L; } if (degrminptr != NULL) *degrminptr = (SCOTCH_Num) degrmin; if (degrmaxptr != NULL) *degrmaxptr = (SCOTCH_Num) degrmax; if (degravgptr != NULL) *degravgptr = (double) degravg; if (degrdltptr != NULL) *degrdltptr = (double) degrdlt; edlodlt = 0.0L; if (srcgrafptr->edgenbr > 0) { if (srcgrafptr->edlotax != NULL) { /* If graph has edge loads */ edlomin = GNUMMAX; edlomax = 0; edlosum = 0; for (vertnum = srcgrafptr->baseval; vertnum < srcgrafptr->vertnnd; vertnum ++) { for (edgenum = srcgrafptr->verttax[vertnum]; edgenum < srcgrafptr->vendtax[vertnum]; edgenum ++) { /* For all edges */ if (srcgrafptr->edlotax[edgenum] < edlomin) /* Account for edge load */ edlomin = srcgrafptr->edlotax[edgenum]; if (srcgrafptr->edlotax[edgenum] > edlomax) edlomax = srcgrafptr->edlotax[edgenum]; edlosum += srcgrafptr->edlotax[edgenum]; } } edloavg = (double) edlosum / (double) (2 * srcgrafptr->edgenbr); for (vertnum = srcgrafptr->baseval; vertnum < srcgrafptr->vertnnd; vertnum ++) { for (edgenum = srcgrafptr->verttax[vertnum]; edgenum < srcgrafptr->vendtax[vertnum]; edgenum ++) /* For all edges */ edlodlt += fabs ((double) srcgrafptr->edlotax[edgenum] - edloavg); } edlodlt /= (double) srcgrafptr->edgenbr; } else { edlomin = edlomax = 1; edlosum = srcgrafptr->edgenbr / 2; edloavg = 1.0L; } } else { edlomin = edlomax = 0; edlosum = 0; edloavg = 0.0L; } if (edlominptr != NULL) *edlominptr = (SCOTCH_Num) edlomin; if (edlomaxptr != NULL) *edlomaxptr = (SCOTCH_Num) edlomax; if (edlosumptr != NULL) *edlosumptr = (SCOTCH_Num) edlosum; if (edloavgptr != NULL) *edloavgptr = (double) edloavg; if (edlodltptr != NULL) *edlodltptr = (double) edlodlt; } scotch-6.0.4.dfsg/src/libscotch/dgraph_match_sync_coll.c0000644002563400244210000005205211631447170026474 0ustar trophimeutilisateurs du domaine/* Copyright 2009 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_match_sync_coll.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This routine synchronizes the fragments **/ /** of a distributed matching by means of **/ /** collective communications. **/ /** **/ /** DATES : # Version 5.1 : from : 06 feb 2009 **/ /** to : 22 apr 2009 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DGRAPH_MATCH #include "module.h" #include "common.h" #include "dgraph.h" #include "dgraph_coarsen.h" #include "dgraph_match.h" /*************************************/ /* */ /* These routines handle distributed */ /* source graphs. */ /* */ /*************************************/ /* This routine performs a round of communication ** to synchronize enqueued matching requests across ** processors. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int dgraphMatchSyncColl ( DgraphMatchData * restrict const mateptr) { Gnum queulocnbr; Gnum queulocnum; Gnum matelocnbr; Gnum multlocnbr; Gnum vertlocadj; Gnum edgekptnbr; int procngbnbr; int procngbidx; int procngbnum; int * restrict vsndcnttab; int * restrict vrcvcnttab; int * restrict vsnddsptab; int * restrict vrcvdsptab; Dgraph * restrict const grafptr = mateptr->c.finegrafptr; const int * restrict const procngbtab = grafptr->procngbtab; int * restrict const procgsttax = mateptr->c.procgsttax; const Gnum * restrict const procvgbtab = mateptr->procvgbtab; const Gnum * restrict const vertloctax = grafptr->vertloctax; const Gnum * restrict const vendloctax = grafptr->vendloctax; const Gnum * restrict const edgeloctax = grafptr->edgeloctax; const Gnum * restrict const edgegsttax = grafptr->edgegsttax; Gnum * restrict const queuloctab = mateptr->queuloctab; Gnum * restrict const mategsttax = mateptr->mategsttax; DgraphCoarsenMulti * restrict const multloctab = mateptr->c.multloctab; int * restrict const nsndidxtab = mateptr->c.nsndidxtab; DgraphCoarsenVert * const vsnddattab = mateptr->c.vsnddattab; /* [norestrict:async] */ procngbnbr = grafptr->procngbnbr; #ifdef SCOTCH_DEBUG_DGRAPH2 if (edgeloctax == NULL) { errorPrint ("dgraphMatchSyncColl: not implemented"); return (1); } if (MPI_Barrier (grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphMatchSyncColl: communication error (1)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ if ((vsnddsptab = memAlloc (4 * grafptr->procglbnbr * sizeof (int))) == NULL) { errorPrint ("dgraphMatchSyncColl: out of memory"); return (1); } vsndcnttab = vsnddsptab + grafptr->procglbnbr; /* TRICK: put vsnddsptab, vsndcnttab, vrcvdsptab in order for memSet() */ vrcvdsptab = vsndcnttab + grafptr->procglbnbr; vrcvcnttab = vrcvdsptab + grafptr->procglbnbr; for (procngbnum = 0; procngbnum < procngbnbr; procngbnum ++) /* Reset indices for sending messages */ nsndidxtab[procngbnum] = mateptr->c.vsnddsptab[procngbtab[procngbnum]]; vertlocadj = grafptr->procvrttab[grafptr->proclocnum] - grafptr->baseval; for (queulocnum = 0, queulocnbr = mateptr->queulocnbr; queulocnum < queulocnbr; queulocnum ++) { Gnum vertlocnum; Gnum vertgstnum; Gnum edgelocnum; Gnum mategstnum; Gnum mateglbnum; int procngbnum; int vsndidxnum; vertlocnum = queuloctab[queulocnum]; /* Get local vertex index */ mategstnum = mategsttax[vertlocnum]; /* Get mate (edge ?) index */ if (mategstnum >= -1) /* If vertex not willing to mate or matched locally after being considered during matching phase */ continue; edgelocnum = -2 - mategstnum; /* Get local edge to mate ghost vertex */ #ifdef SCOTCH_DEBUG_DGRAPH2 if ((edgelocnum < grafptr->baseval) || (edgelocnum >= (grafptr->edgelocsiz + grafptr->baseval)) || (mategsttax[edgegsttax[edgelocnum]] != -1)) { errorPrint ("dgraphMatchSyncColl: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ mateglbnum = edgeloctax[edgelocnum]; vertgstnum = edgegsttax[edgelocnum]; procngbnum = procgsttax[vertgstnum]; /* Find neighbor owner process */ if (procngbnum < 0) { /* If neighbor not yet computed */ int procngbmax; procngbnum = 0; procngbmax = procngbnbr; while ((procngbmax - procngbnum) > 1) { /* Find owner process by dichotomy on procvgbtab */ int procngbmed; procngbmed = (procngbmax + procngbnum) / 2; if (procvgbtab[procngbmed] > mateglbnum) procngbmax = procngbmed; else procngbnum = procngbmed; } procgsttax[vertgstnum] = procngbnum; } #ifdef SCOTCH_DEBUG_DGRAPH2 if ((grafptr->procvrttab[procngbtab[procngbnum]] > mateglbnum) || (grafptr->procvrttab[procngbtab[procngbnum] + 1] <= mateglbnum)) { errorPrint ("dgraphMatchSyncColl: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ vsndidxnum = nsndidxtab[procngbnum] ++; /* Get position of message in send array */ #ifdef SCOTCH_DEBUG_DGRAPH2 if (vsndidxnum >= mateptr->c.vsnddsptab[procngbtab[procngbnum] + 1]) { errorPrint ("dgraphMatchSyncColl: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ vsnddattab[vsndidxnum].datatab[0] = vertlocnum + vertlocadj; vsnddattab[vsndidxnum].datatab[1] = mateglbnum; } memSet (vsnddsptab, 0, 3 * grafptr->procglbnbr * sizeof (int)); /* TRICK: resets vsnddsptab, vsndcnttab, vrcvdsptab */ for (procngbnum = 0; procngbnum < procngbnbr; procngbnum ++) { int procglbnum; procglbnum = procngbtab[procngbnum]; vrcvdsptab[procglbnum] = 2 * mateptr->c.vrcvdsptab[procglbnum]; /* Times 2 because a "DgraphCoarsenVert" is two "Gnum"s */ vsnddsptab[procglbnum] = 2 * mateptr->c.vsnddsptab[procglbnum]; vsndcnttab[procglbnum] = 2 * (nsndidxtab[procngbnum] - mateptr->c.vsnddsptab[procglbnum]); } if (MPI_Alltoall (vsndcnttab, 1, MPI_INT, vrcvcnttab, 1, MPI_INT, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphMatchSyncColl: communication error (2)"); return (1); } if (MPI_Alltoallv (vsnddattab, vsndcnttab, vsnddsptab, GNUM_MPI, mateptr->c.vrcvdattab, vrcvcnttab, vrcvdsptab, GNUM_MPI, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphMatchSyncColl: communication error (3)"); return (1); } matelocnbr = mateptr->matelocnbr; multlocnbr = mateptr->c.multlocnbr; edgekptnbr = mateptr->c.edgekptnbr; for (procngbidx = 0; procngbidx < procngbnbr; procngbidx ++) { int procngbnum; int procglbnum; int vrcvidxnnd; int requrcvnum; int requnxtnum; /* Index of location where to pack requests to process when all messages arrive */ procngbnum = (procngbidx + mateptr->c.procngbnxt) % procngbnbr; procglbnum = procngbtab[procngbnum]; vrcvidxnnd = mateptr->c.vrcvdsptab[procglbnum]; if (vrcvcnttab[procglbnum] > 0) { /* If query message is not empty */ Gnum vertsndnbr; /* Number of vertices to be sent to requesting neighbor */ Gnum edgesndnbr; /* Number of edges to be sent to requesting neighbor */ DgraphCoarsenVert * restrict const vrcvdattab = mateptr->c.vrcvdattab; /* Local restrict pointer only when data available */ vertsndnbr = edgesndnbr = 0; for (requrcvnum = requnxtnum = vrcvidxnnd, vrcvidxnnd += (vrcvcnttab[procglbnum] / 2); /* TRICK: each message item costs 2 Gnum's */ requrcvnum < vrcvidxnnd; requrcvnum ++) { Gnum vertglbnum; /* Our global number (the one seen as mate by sender) */ Gnum vertlocnum; /* Our local number (the one seen as mate by sender) */ Gnum vmatglbnum; /* Global number of requesting mate (sender of message) */ Gnum mategstnum; /* The mate we wanted to ask for */ vmatglbnum = vrcvdattab[requrcvnum].datatab[0]; /* Names are opposite because receiving side */ vertglbnum = vrcvdattab[requrcvnum].datatab[1]; vertlocnum = vertglbnum - vertlocadj; #ifdef SCOTCH_DEBUG_DGRAPH2 if ((vertlocnum < grafptr->baseval) || /* If matching request is not directed towards our process */ (vertlocnum >= grafptr->vertlocnnd)) { errorPrint ("dgraphMatchSyncColl: internal error (5)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ mategstnum = mategsttax[vertlocnum]; /* Get our local mating decision data */ if (mategstnum == -1) { /* If local vertex wanted for mating is free */ Gnum edgelocnum; for (edgelocnum = vertloctax[vertlocnum]; edgeloctax[edgelocnum] != vmatglbnum; edgelocnum ++) { #ifdef SCOTCH_DEBUG_DGRAPH2 if (edgelocnum >= vendloctax[vertlocnum]) { errorPrint ("dgraphMatchSyncColl: internal error (6)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ } mategsttax[edgegsttax[edgelocnum]] = vertglbnum; /* We are no longer free */ mategsttax[vertlocnum] = vmatglbnum; /* Leave message as is to acknowledge it */ matelocnbr ++; vertsndnbr ++; edgesndnbr += vendloctax[vertlocnum] - vertloctax[vertlocnum]; } else if (mategstnum < -1) { /* If local vertex is also asking for mating */ Gnum edgelocnum; Gnum mateglbnum; edgelocnum = -2 - mategstnum; mateglbnum = edgeloctax[edgelocnum]; /* Get global number of our remote mate */ if (mateglbnum == vmatglbnum) { /* If it is with the sender */ Gnum flagval; /* Flag for choosing side to create multinode */ mategsttax[vertlocnum] = mateglbnum; /* Say we are mated to inform future requesting processes in same pass */ mategsttax[edgegsttax[edgelocnum]] = vertglbnum; flagval = (mateglbnum > vertglbnum) ? 1 : 0; /* Compute pseudo-random flag always opposite for both ends */ flagval = ((mateglbnum + (mateglbnum - vertglbnum) * flagval) & 1) ^ flagval; if (flagval == 0) { /* If flag is even, create multinode */ multloctab[multlocnbr].vertglbnum[0] = vertglbnum; multloctab[multlocnbr].vertglbnum[1] = mategstnum; /* Remote mate: negative value */ multlocnbr ++; /* One more coarse vertex created */ edgekptnbr += vendloctax[vertlocnum] - vertloctax[vertlocnum]; } else { /* If flag is odd, prepare to send vertex data at build time */ vertsndnbr ++; edgesndnbr += vendloctax[vertlocnum] - vertloctax[vertlocnum]; } /* Go on by destroying message in all cases since both ends know what it is about */ vrcvdattab[requrcvnum --] = vrcvdattab[-- vrcvidxnnd]; /* Replace current message with another one and process it */ matelocnbr ++; /* One more local vertex mated on each side; no messages will tell it */ } else { /* If willing to mate but not with the sender, tell later with whom */ DgraphCoarsenVert vertdat; /* Temporary storage data for swapping vertices */ vertdat = vrcvdattab[requnxtnum]; /* Pack requests to process later at beginning of message */ vrcvdattab[requnxtnum].datatab[0] = vmatglbnum; vrcvdattab[requnxtnum].datatab[1] = -2 - vertlocnum; /* Build appropriate answer to mating request later, when all messages arrived */ if (requnxtnum ++ != requrcvnum) vrcvdattab[requrcvnum] = vertdat; /* Swap vertices if not already at the right place */ } } else /* If already matched, inform sender */ vrcvdattab[requrcvnum].datatab[1] = mategstnum; } mateptr->c.dcntloctab[procglbnum].vertsndnbr += vertsndnbr; mateptr->c.dcntloctab[procglbnum].edgesndnbr += edgesndnbr; } mateptr->c.nrcvidxtab[procngbnum] = vrcvidxnnd; } for (procngbidx = 0; procngbidx < procngbnbr; procngbidx ++) { int procngbnum; int procglbnum; int vsndidxnnd; int vsndidxnum; DgraphCoarsenVert * restrict const vrcvdattab = mateptr->c.vrcvdattab; /* Local restrict pointer only once data received */ procngbnum = (procngbidx + mateptr->c.procngbnxt) % procngbnbr; procglbnum = procngbtab[procngbnum]; vsndidxnnd = mateptr->c.nrcvidxtab[procngbnum]; /* Re-send the messages we have received to acknowledge */ for (vsndidxnum = mateptr->c.vrcvdsptab[procglbnum]; /* Finalize unfinished messages */ vsndidxnum < vsndidxnnd; vsndidxnum ++) { Gnum vertlocnum; Gnum mateglbnum; vertlocnum = vrcvdattab[vsndidxnum].datatab[1]; if (vertlocnum >= 0) /* If no more unfinished messages to process, quit scanning */ break; vertlocnum = -2 - vertlocnum; mateglbnum = mategsttax[vertlocnum]; if (mateglbnum >= 0) /* If vertex we wanted to mate with has been mated in this round */ vrcvdattab[vsndidxnum].datatab[1] = mateglbnum; /* Propagate this information back to the requester */ else { /* Vertex mating data not yet available (maybe in answer) */ vrcvdattab[vsndidxnum] = vrcvdattab[-- vsndidxnnd]; /* Remove message as no reply means not willing */ if (vrcvdattab[vsndidxnum].datatab[1] < 0) /* If replacing message is also to be processed */ vsndidxnum --; /* Do not skip replaced message in next iteration */ } } if (vsndidxnnd < (mateptr->c.vrcvdsptab[procglbnum] + (vrcvcnttab[procglbnum] / 2))) { /* If space created */ vrcvdattab[vsndidxnnd].datatab[0] = /* Indicate end of useful data */ vrcvdattab[vsndidxnnd].datatab[1] = -1; } } if (MPI_Alltoallv (mateptr->c.vrcvdattab, vrcvcnttab, vrcvdsptab, GNUM_MPI, vsnddattab, vsndcnttab, vsnddsptab, GNUM_MPI, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphMatchSyncColl: communication error (3)"); return (1); } for (procngbidx = 0; procngbidx < procngbnbr; procngbidx ++) { int procngbnum; int procglbnum; int vrcvidxnnd; int vrcvidxnum; procngbnum = (procngbidx + mateptr->c.procngbnxt) % procngbnbr; procglbnum = procngbtab[procngbnum]; for (vrcvidxnum = mateptr->c.vsnddsptab[procglbnum], vrcvidxnnd = vrcvidxnum + (vsndcnttab[procglbnum] / 2); /* TRICK: each message item costs 2 Gnum's */ vrcvidxnum < vrcvidxnnd; vrcvidxnum ++) { Gnum edgelocnum; Gnum vertglbnum; /* Our global number (the one seen as mate by sender) */ Gnum vertlocnum; /* Our local number (the one seen as mate by sender) */ Gnum vmatglbnum; /* Global number of vertex to which the mate is mated */ Gnum mategstnum; /* The mate we wanted to ask for */ vertglbnum = vsnddattab[vrcvidxnum].datatab[0]; if (vertglbnum == -1) /* If end of useful space reached */ break; vmatglbnum = vsnddattab[vrcvidxnum].datatab[1]; vertlocnum = vertglbnum - vertlocadj; #ifdef SCOTCH_DEBUG_DGRAPH2 if ((vertlocnum < grafptr->baseval) || /* If matching reply is not directed towards our process */ (vertlocnum >= grafptr->vertlocnnd)) { errorPrint ("dgraphMatchSyncColl: internal error (8)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ mategstnum = mategsttax[vertlocnum]; /* Get our local mating decision data */ edgelocnum = -2 - mategstnum; #ifdef SCOTCH_DEBUG_DGRAPH2 if ((mategstnum >= -1) || /* If we did not ask anything or if we were already matched, no reply message should come to us */ ((mategsttax[edgegsttax[edgelocnum]] >= 0) && /* Also, if our prospective mate was itself already set as matched by a previous reply */ (mategsttax[edgegsttax[edgelocnum]] != vertglbnum) && /* And this message is not the positive reply which acknowledges this mating */ (mategsttax[edgegsttax[edgelocnum]] != vmatglbnum))) { /* Or an informative negative reply which gives again the mate of the ghost */ errorPrint ("dgraphMatchSyncColl: internal error (9)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ if (edgeloctax[edgelocnum] == vmatglbnum) { /* If positive answer from the mate we wanted */ mategsttax[vertlocnum] = vmatglbnum; /* Set local vertex as matched with the mate */ mategsttax[edgegsttax[edgelocnum]] = vertglbnum; /* Update state of ghost mate */ multloctab[multlocnbr].vertglbnum[0] = vertglbnum; multloctab[multlocnbr].vertglbnum[1] = mategstnum; /* Remote mate: negative value */ multlocnbr ++; /* One more coarse vertex created */ matelocnbr ++; edgekptnbr += vendloctax[vertlocnum] - vertloctax[vertlocnum]; } else { /* If negative answer from the mate we wanted */ mategsttax[vertlocnum] = -1; /* Reset local vertex as free for mating */ mategsttax[edgegsttax[edgelocnum]] = vmatglbnum; /* Update state of unwilling ghost mate */ } } } mateptr->matelocnbr = matelocnbr; mateptr->c.multlocnbr = multlocnbr; mateptr->c.edgekptnbr = edgekptnbr; #ifdef SCOTCH_DEBUG_DGRAPH2 if (MPI_Barrier (grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphMatchSyncColl: communication error (11)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ memFree (vsnddsptab); return (0); } scotch-6.0.4.dfsg/src/libscotch/common.h0000644002563400244210000004637012474554132023314 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007-2015 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : common.h **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** David GOUDIN **/ /** Pascal HENON **/ /** Pierre RAMET **/ /** Cedric CHEVALIER (v5.0) **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : Part of a parallel direct block solver. **/ /** These lines are the common data **/ /** declarations for all modules. **/ /** **/ /** DATES : # Version 0.0 : from : 08 may 1998 **/ /** to : 08 jan 2001 **/ /** # Version 1.0 : from : 06 jun 2002 **/ /** to : 06 jun 2002 **/ /** # Version 2.0 : from : 13 jun 2005 **/ /** to : 01 jul 2008 **/ /** # Version 5.1 : from : 09 nov 2008 **/ /** to : 23 nov 2010 **/ /** # Version 6.0 : from : 03 mar 2011 **/ /** to 01 mar 2015 **/ /** **/ /************************************************************/ #define COMMON_H /* ** The includes. */ #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE 600 #endif /* _XOPEN_SOURCE */ #ifndef __USE_XOPEN2K #define __USE_XOPEN2K /* For POSIX pthread_barrier_t */ #endif /* __USE_XOPEN2K */ #include #include /* Fow Windows _pipe () call */ #include #include #include #include #include #if (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) #include #endif /* (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) */ #ifdef HAVE_MALLOC_H #include /* Deprecated, but required on some old systems */ #endif /* HAVE_MALLOC_H */ #include #include #include /* For the effective calls to clock () */ #include #include #include #if ((defined COMMON_TIMING_OLD) || (defined HAVE_SYS_TIME_H)) #include #endif /* ((defined COMMON_TIMING_OLD) || (defined HAVE_SYS_TIME_H)) */ #if ((defined COMMON_TIMING_OLD) || (defined HAVE_SYS_RESOURCE_H)) #include #endif /* ((defined COMMON_TIMING_OLD) || (defined HAVE_SYS_RESOURCE_H)) */ #if ((defined COMMON_WINDOWS) || (defined HAVE_WINDOWS_H)) #include /* For _pipe () */ #include /* For intptr_t */ #include #endif /* ((defined COMMON_WINDOWS) || (defined HAVE_WINDOWS_H)) */ #if ((! defined COMMON_WINDOWS) && (! defined HAVE_NOT_UNISTD_H)) #include #endif /* ((! defined COMMON_WINDOWS) && (! defined HAVE_NOT_UNISTD_H)) */ #ifdef SCOTCH_PTSCOTCH #include #endif /* SCOTCH_PTSCOTCH */ #if ((defined COMMON_PTHREAD) || (defined SCOTCH_PTHREAD)) #include #endif /* ((defined COMMON_PTHREAD) || (defined SCOTCH_PTHREAD)) */ /* ** Working definitions. */ #ifdef COMMON_MEMORY_TRACE #define memAlloc(size) memAllocRecord ((size) | 8) #define memRealloc(ptr,size) memReallocRecord ((ptr), ((size) | 8)) #define memFree(ptr) (memFreeRecord ((void *) (ptr)), 0) #else /* COMMON_MEMORY_TRACE */ #define memAlloc(size) malloc ((size) | 8) /* For platforms which return NULL for malloc(0) */ #define memRealloc(ptr,size) realloc ((ptr),((size) | 8)) #define memFree(ptr) (free ((char *) (ptr)), 0) #endif /* COMMON_MEMORY_TRACE */ #define memSet(ptr,val,siz) memset ((void *) (ptr), (val), (siz)) #define memCpy(dst,src,siz) memcpy ((void *) (dst), (void *) (src), (siz)) #define memMov(dst,src,siz) memmove ((void *) (dst), (void *) (src), (siz)) #define MIN(x,y) (((x) < (y)) ? (x) : (y)) #define MAX(x,y) (((x) < (y)) ? (y) : (x)) #define ABS(x) MAX ((x), -(x)) #define SIGN(x) (((x) < 0) ? -1 : 1) /* ** Handling of generic types. */ #if (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_UINT_T)) #define UINT32 uint32_t #else /* (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_UINT_T)) */ #define UINT32 u_int32_t #endif /* (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_UINT_T)) */ #ifndef INT /* If type not externally overriden */ #ifdef INTSIZE32 #define INT int32_t #define UINT UINT32 #define COMM_INT MPI_INTEGER4 #define INTSTRING "%d" #else /* INTSIZE32 */ #ifdef INTSIZE64 #define INT int64_t #if (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_UINT_T)) #define UINT uint64_t #else /* (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_UINT_T)) */ #define UINT u_int64_t #endif /* (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_UINT_T)) */ #define COMM_INT MPI_LONG_LONG #define INTSTRING "%lld" #else /* INTSIZE64 */ #ifdef LONG /* Better not use it */ #define INT long /* Long integer type */ #define UINT unsigned long #define COMM_INT MPI_LONG #define INTSTRING "%ld" #else /* LONG */ #define INT int /* Default integer type */ #define UINT unsigned int #define COMM_INT MPI_INT /* Generic MPI integer type */ #define INTSTRING "%d" #endif /* LONG */ #endif /* INTSIZE64 */ #endif /* INTSIZE32 */ #endif /* INT */ #ifndef IDX /* If type not externally overriden */ #ifdef IDXSIZE32 #define IDX int32_t #else /* IDXSIZE32 */ #ifdef IDXSIZE64 #define IDX int64_t #else /* IDXSIZE64 */ #define IDX INT #endif /* IDXSIZE64 */ #endif /* IDXSIZE32 */ #endif /* IDX */ #ifndef INTSIZEBITS #define INTSIZEBITS (sizeof (INT) << 3) #endif /* INTSIZEBITS */ #define INTVALMAX ((INT) (((UINT) 1 << (INTSIZEBITS - 1)) - 1)) #define byte unsigned char /* Byte type */ #ifndef BYTE #define BYTE byte #endif /* BYTE */ #ifndef COMM_BYTE #define COMM_BYTE MPI_BYTE #endif /* COMM_BYTE */ #define COMM_PART COMM_BYTE /* ** Handling of pseudo-random numbers. */ /* The pseudo-random state structure. It is based on a Mersenne twister generator, also referred to as MT19937. */ typedef struct IntRandState_ { UINT32 randtab[624]; /* State vector */ int randnum; /* Index value */ } IntRandState; /* ** Handling of flag arrays. */ #define flagSize(n) (((n) + (sizeof (int) << 3) - 1) / (sizeof (int) << 3)) #define flagVal(a,n) (((a)[(n) / (sizeof (int) << 3)] >> ((n) & ((sizeof (int) << 3) - 1))) & 1) #define flagSet(a,n) (a)[(n) / (sizeof (int) << 3)] |= (1 << ((n) & ((sizeof (int) << 3) - 1))) /* ** Handling of timers. */ /** The clock type. **/ typedef struct Clock_ { double time[2]; /*+ The start and accumulated times +*/ } Clock; /* ** Handling of Windows constructs. */ #if defined COMMON_WINDOWS #define pipe(fd) _pipe (fd, 32768, O_BINARY) #endif /* COMMON_WINDOWS */ /* ** Handling of threads. */ /** The thread creation flags **/ #define THREADNONE 0x0000 /* Thread capabilities */ #define THREADHASBARRIER 0x0001 #define THREADCANBARRIER THREADHASBARRIER #define THREADCANSCAN THREADHASBARRIER #define THREADCANREDUCE THREADHASBARRIER /** The thread barrier structure and routines **/ #ifdef COMMON_PTHREAD_BARRIER #ifndef PTHREAD_BARRIER_SERIAL_THREAD #define PTHREAD_BARRIER_SERIAL_THREAD -1 #endif /* PTHREAD_BARRIER_SERIAL_THREAD */ typedef struct ThreadBarrier_ { int thrdnbr; /*+ Number of threads to wait for +*/ volatile int thrdcur; /*+ Number of threads currently blocked +*/ volatile int instnum; /*+ Number of barrier instance +*/ pthread_mutex_t mutedat; pthread_cond_t conddat; } ThreadBarrier; int threadBarrierDestroy (ThreadBarrier *); int threadBarrierInit (ThreadBarrier *, void *, int); /* Thread attribute not used */ int threadBarrierWait (ThreadBarrier *); #else /* COMMON_PTHREAD_BARRIER */ #define ThreadBarrier pthread_barrier_t #define threadBarrierDestroy pthread_barrier_destroy #define threadBarrierInit pthread_barrier_init #define threadBarrierWait pthread_barrier_wait #endif /* COMMON_PTHREAD_BARRIER */ #define threadBarrier(t) threadBarrierWait (&(((ThreadGroupHeader *) (((ThreadHeader *) (void *) (t))->grouptr))->barrdat)) /** The thread service routines auxiliary function types **/ typedef int (* ThreadLaunchJoinFunc) (void * const, void * const); typedef int (* ThreadLaunchStartFunc) (void * const); typedef void (* ThreadReduceFunc) (void * const, void * const, void * const); typedef void (* ThreadScanFunc) (void * const, void * const, void * const, const int); /** The thread group header block. **/ typedef struct ThreadGroupHeader_ { #if ((defined COMMON_PTHREAD) || (defined SCOTCH_PTHREAD)) int flagval; /*+ Thread block flags +*/ size_t datasiz; /*+ Size of data array cell +*/ int thrdnbr; /*+ Number of threads +*/ ThreadLaunchStartFunc stafptr; /*+ Pointer to start routine +*/ ThreadLaunchJoinFunc joifptr; /*+ Pointer to join routine +*/ ThreadBarrier barrdat; /*+ Barrier data structure +*/ #endif /* ((defined COMMON_PTHREAD) || (defined SCOTCH_PTHREAD)) */ } ThreadGroupHeader; /** The thread header block. **/ typedef struct ThreadHeader_ { void * grouptr; /*+ Pointer to thread group +*/ #if ((defined COMMON_PTHREAD) || (defined SCOTCH_PTHREAD)) pthread_t thidval; /*+ Thread ID +*/ int thrdnum; /*+ Thread instance number +*/ #endif /* ((defined COMMON_PTHREAD) || (defined SCOTCH_PTHREAD)) */ } ThreadHeader; /** The number of threads **/ #ifdef SCOTCH_PTHREAD #ifndef SCOTCH_PTHREAD_NUMBER #define SCOTCH_PTHREAD_NUMBER 1 #endif /* SCOTCH_PTHREAD_NUMBER */ #else /* SCOTCH_PTHREAD */ #ifdef SCOTCH_PTHREAD_NUMBER #undef SCOTCH_PTHREAD_NUMBER #endif /* SCOTCH_PTHREAD_NUMBER */ #define SCOTCH_PTHREAD_NUMBER 1 #endif /* SCOTCH_PTHREAD */ /* ** Handling of files. */ /** The file structure. **/ typedef struct File_ { char * modeptr; /*+ Opening mode +*/ char * nameptr; /*+ File name +*/ FILE * fileptr; /*+ File pointer +*/ char * dataptr; /*+ Array to free +*/ } File; /* ** Function prototypes. */ void * memAllocGroup (void **, ...); void * memReallocGroup (void *, ...); void * memOffset (void *, ...); #ifdef COMMON_MEMORY_TRACE void * memAllocRecord (size_t); void * memReallocRecord (void * const, size_t); void memFreeRecord (void * const); IDX memCur (); /* What is internally an intptr_t has to be turned into an interface type */ IDX memMax (); #endif /* COMMON_MEMORY_TRACE */ void usagePrint (FILE * const, const char (* [])); void fileBlockInit (File * const, const int); int fileBlockOpen (File * const, const int); int fileBlockOpenDist (File * const, const int, const int, const int, const int); void fileBlockClose (File * const, const int); FILE * fileCompress (FILE * const, const int); int fileCompressType (const char * const); FILE * fileUncompress (FILE * const, const int); int fileUncompressType (const char * const); int fileNameDistExpand (char ** const, const int, const int, const int); void errorProg (const char * const); void errorPrint (const char * const, ...); void errorPrintW (const char * const, ...); int intLoad (FILE * const, INT * const); int intSave (FILE * const, const INT); void intAscn (INT * const, const INT, const INT); void intPerm (INT * const, const INT); void intRandInit (void); void intRandProc (int); void intRandReset (void); void intRandSeed (INT); #ifndef COMMON_RANDOM_SYSTEM INT intRandVal (INT); #endif /* COMMON_RANDOM_SYSTEM */ void intSort1asc1 (void * const, const INT); void intSort2asc1 (void * const, const INT); void intSort2asc2 (void * const, const INT); void intSort3asc1 (void * const, const INT); void intSort3asc2 (void * const, const INT); INT intSearchDicho (const INT * const, const INT, const INT, const INT); INT intGcd (INT, INT); void clockInit (Clock * const); void clockStart (Clock * const); void clockStop (Clock * const); double clockVal (Clock * const); double clockGet (void); void stringSubst (char * const, const char * const, const char * const); #ifdef COMMON_PTHREAD int threadLaunch (void * const, void * const, const size_t, int (*) (void *), int (*) (void *, void *), const int, const int); void threadReduce (void * const, void * const, ThreadReduceFunc const, const int); void threadScan (void * const, void * const, ThreadScanFunc const); #endif /* COMMON_PTHREAD */ /* ** Macro definitions. */ #define clockInit(clk) ((clk)->time[0] = (clk)->time[1] = 0) #define clockStart(clk) ((clk)->time[0] = clockGet ()) #define clockStop(clk) ((clk)->time[1] += (clockGet () - (clk)->time[0])) #define clockVal(clk) ((clk)->time[1]) #define fileBlockFile(b,i) ((b)[i].fileptr) #define fileBlockMode(b,i) ((b)[i].modeptr) #define fileBlockName(b,i) ((b)[i].nameptr) #ifdef COMMON_RANDOM_SYSTEM #ifdef COMMON_RANDOM_RAND #define intRandVal(ival) ((INT) (((UINT) rand ()) % ((UINT) (ival)))) #else /* COMMON_RANDOM_RAND */ #define intRandVal(ival) ((INT) (((UINT) random ()) % ((UINT) (ival)))) #endif /* COMMON_RANDOM_RAND */ #endif /* COMMON_RANDOM_SYSTEM */ #define DATASIZE(n,p,i) ((INT) (((n) + ((p) - 1 - (i))) / (p))) #define DATASCAN(n,p,i) ((i) * ((INT) (n) / (INT) (p)) + (((i) > ((n) % (p))) ? ((n) % (p)) : (i))) #define FORTRAN(nu,nl,pl,pc) FORTRAN2(REPLACE(nu),REPLACE(nl),pl,pc) #define FORTRAN2(nu,nl,pl,pc) \ void nu pl; \ void nl pl \ { nu pc; } \ void GLUE(nl,_) pl \ { nu pc; } \ void GLUE(nl,__) pl \ { nu pc; } \ void nu pl #define REPLACE(s) s #define GLUE(p,s) p##s #define STRINGIFY2(n) #n #define STRINGIFY(n) STRINGIFY2(n) scotch-6.0.4.dfsg/src/libscotch/bgraph_bipart_st.h0000644002563400244210000000763211631447170025331 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bgraph_bipart_st.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the strategy and method **/ /** tables and the generic entry point for **/ /** the graph bipartitioning methods. **/ /** **/ /** DATES : # Version 3.2 : from : 08 oct 1996 **/ /** to 13 sep 1998 **/ /** # Version 4.0 : from : 15 jan 2002 **/ /** to 15 jan 2002 **/ /** # Version 5.0 : from : 27 nov 2006 **/ /** to 13 jan 2007 **/ /** **/ /************************************************************/ /* ** The type definitions. */ /** Method types. **/ typedef enum BgraphBipartStMethodType_ { BGRAPHBIPARTSTMETHBD = 0, /*+ Band +*/ BGRAPHBIPARTSTMETHDF, /*+ Diffusion +*/ BGRAPHBIPARTSTMETHEX, /*+ Exactifying +*/ BGRAPHBIPARTSTMETHFM, /*+ Fiduccia-Mattheyses +*/ BGRAPHBIPARTSTMETHGG, /*+ Greedy Graph Growing +*/ BGRAPHBIPARTSTMETHGP, /*+ Gibbs-Poole-Stockmeyer +*/ BGRAPHBIPARTSTMETHML, /*+ Multi-level (strategy) +*/ BGRAPHBIPARTSTMETHZR, /*+ Move all to part zero +*/ BGRAPHBIPARTSTMETHNBR /*+ Number of methods +*/ } BgraphBipartStMethodType; /* ** The external declarations. */ extern StratTab bgraphbipartststratab; /* ** The function prototypes. */ #ifndef BGRAPH_BIPART_ST #define static #endif int bgraphBipartSt (Bgraph * restrict const, const Strat * restrict const); #undef static scotch-6.0.4.dfsg/src/libscotch/parser.h0000644002563400244210000002655612412577125023323 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : parser.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the declarations for **/ /** the strategy lexical and syntactic **/ /** analyzer. **/ /** **/ /** DATES : # Version 3.1 : from : 07 nov 1995 **/ /** to 02 may 1996 **/ /** # Version 3.2 : from : 07 oct 1996 **/ /** to 19 oct 1996 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 4.0 : from : 20 dec 2001 **/ /** to 11 jun 2004 **/ /** # Version 5.1 : from : 20 feb 2008 **/ /** to 20 feb 2008 **/ /** # Version 6.0 : from : 30 sep 2014 **/ /** to 30 sep 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ #define PARSERSTRINGLEN 256 /*+ Length of parser strings +*/ /* ** The type definitions. */ /*+ Strategy node types. +*/ typedef enum StratNodeType_ { STRATNODECONCAT, /*+ Concatenation node +*/ STRATNODECOND, /*+ Condition node +*/ STRATNODEEMPTY, /*+ Empty strategy +*/ STRATNODEMETHOD, /*+ Method +*/ STRATNODESELECT, /*+ Selection node +*/ STRATNODENBR /*+ Number of strategy nodes +*/ } StratNodeType; /*+ Method and graph parameter types. +*/ typedef int StratParamType; /*+ Same type as enum +*/ #define STRATPARAMCASE 0 /*+ Character; TRICK: FIRST +*/ #define STRATPARAMDOUBLE 1 /*+ Double floating-point +*/ #define STRATPARAMINT 2 /*+ Integer +*/ #define STRATPARAMLOG 3 /*+ Logical value +*/ #define STRATPARAMSTRAT 4 /*+ Strategy +*/ #define STRATPARAMSTRING 5 /*+ String of characters +*/ #define STRATPARAMDEPRECATED 8 /*+ Indicates deprecated parameter; can be merged with the above +*/ /*+ Test types, ordered by ascending priority, for proper writing of parentheses. Initial value should be zero for proper indexing. +*/ typedef enum StratTestType_ { STRATTESTOR = 0, /*+ Or operator +*/ STRATTESTAND, /*+ And operator +*/ STRATTESTNOT, /*+ Not operator +*/ STRATTESTEQ, /*+ Equal-to operator +*/ STRATTESTGT, /*+ Greater-than operator +*/ STRATTESTLT, /*+ Less-than operator +*/ STRATTESTADD, /*+ Addition operator +*/ STRATTESTSUB, /*+ Subtraction operator +*/ STRATTESTMUL, /*+ Multiplication operator +*/ STRATTESTMOD, /*+ Modulus operator +*/ STRATTESTVAL, /*+ Constant value +*/ STRATTESTVAR, /*+ Variable +*/ STRATTESTNBR /*+ Number of test nodes +*/ } StratTestType; /*+ Method characteristics. +*/ typedef struct StratMethodTab_ { int meth; /*+ Method number in method table +*/ char * name; /*+ Method name +*/ int (* func) (); /*+ Pointer to bipartitioning method +*/ void * data; /*+ Pointer to default parameters +*/ } StratMethodTab; /*+ Method parameter characteristics. +*/ typedef struct StratParamTab_ { int meth; /*+ Method number in method table +*/ StratParamType type; /*+ Parameter type +*/ char * name; /*+ Parameter name +*/ byte * database; /*+ Pointer to data base in method +*/ byte * dataofft; /*+ Pointer to data offset in method +*/ void * datasltr; /*+ Pointer to data selector +*/ } StratParamTab; /*+ Strategy characteristics. +*/ typedef struct StratTab_ { StratMethodTab * methtab; /*+ Pointer to method table +*/ StratParamTab * paratab; /*+ Pointer to parameter table +*/ StratParamTab * condtab; /*+ Pointer to condition table +*/ } StratTab; /*+ Concatenation strategy node. +*/ typedef struct StratNodeConcat_ { /*+ Concatenation node +*/ struct Strat_ * strat[2]; /*+ Pointers to the two strategies to combine +*/ } StratNodeConcat; /*+ Condition and test strategy nodes. +*/ typedef union StratTestVal_ { /*+ Constant value +*/ double valdbl; /*+ Double value +*/ INT valint; /*+ Integer value +*/ int vallog; /*+ Logical value +*/ } StratTestVal; typedef struct StratTestVar_ { /*+ Condition variable +*/ const StratTab * datatab; /*+ Pointer to data parameter table +*/ int datadisp; /*+ Displacement with respect to beginning +*/ } StratTestVar; typedef struct StratTest_ { /*+ Test node +*/ StratTestType typetest; /*+ Test type +*/ StratParamType typenode; /*+ Node type +*/ union { struct StratTest_ * test[2]; /*+ Logical/relational branches +*/ StratTestVal val; /*+ Value +*/ StratTestVar var; /*+ Variable +*/ } data; } StratTest; typedef struct StratNodeCond_ { /*+ Test node +*/ StratTest * test; /*+ Test condition +*/ struct Strat_ * strat[2]; /*+ Then/else strategies +*/ } StratNodeCond; /*+ Data structure of the empty strategy operator node. +*/ typedef struct StratNodeEmpty_ { /*+ Empty node +*/ byte dummy; /*+ Dummy data +*/ } StratNodeEmpty; /*+ Data structure of the empty strategy operator node. +*/ typedef double StratNodeMethodData[10]; /*+ Reserved padded space for method data */ typedef struct StratNodeMethod_ { /*+ Method node +*/ int meth; /*+ Index in method table +*/ StratNodeMethodData data; /*+ Method data +*/ } StratNodeMethod; /*+ Data structure of the selection strategy operator node. +*/ typedef struct StratNodeSelect_ { /*+ Selection node +*/ struct Strat_ * strat[2]; /*+ Pointers to the two strategies to test +*/ } StratNodeSelect; /*+ The strategy node data structure. +*/ typedef struct Strat_ { const StratTab * tabl; /*+ Pointer to parsing strategy table +*/ StratNodeType type; /*+ Method type +*/ union { /*+ Method data +*/ double padding; /*+ Padding for double alignment +*/ StratNodeConcat concat; /*+ Concatenation node data +*/ StratNodeCond cond; /*+ Condition node data +*/ StratNodeEmpty empty; /*+ Empty node data +*/ StratNodeMethod method; /*+ Method node data +*/ StratNodeSelect select; /*+ Selection node data +*/ } data; } Strat; /* ** The external declarations. */ extern Strat stratdummy; /*+ Dummy empty strategy node +*/ /* ** The function prototypes. */ #ifndef PARSER #define static #endif Strat * stratInit (const StratTab * const , const char * const); int stratExit (Strat * const); int stratSave (const Strat * const, FILE * const); int stratTestEval (const StratTest * const, StratTest * const, const void * const); static int stratTestEvalCast (StratTest * const, StratTest * const); int stratTestExit (StratTest * const); int stratTestSave (const StratTest * const, FILE * const); #undef static scotch-6.0.4.dfsg/src/libscotch/dgraph_io_load.c0000644002563400244210000011261112052162606024733 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2009,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_io_load.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the input/output routines for **/ /** distributed graphs. **/ /** **/ /** # Version 5.0 : from : 28 apr 2007 **/ /** to : 24 mar 2008 **/ /** # Version 5.1 : from : 23 jun 2008 **/ /** to : 27 jan 2009 **/ /** # Version 6.0 : from : 25 aug 2012 **/ /** to : 18 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DGRAPH_IO_LOAD #include "module.h" #include "common.h" #include "graph.h" #include "dgraph.h" #include "dgraph_allreduce.h" #include "dgraph_io_load.h" /* This routine loads a distributed source ** graph from the given stream(s). Either ** one processor holds a non-NULL stream ** of a centralized graph, or all of them ** hold valid streams to either a centralized ** or a distributed graph. ** It returns: ** - 0 : on success. ** - !0 : on error. */ DGRAPHALLREDUCEMAXSUMOP (6, 3) DGRAPHALLREDUCEMAXSUMOP (10, 2) int dgraphLoad ( Dgraph * restrict const grafptr, /* Not const since halo may update structure */ FILE * const stream, /* One single centralized stream or distributed ones */ const Gnum baseval, /* Base value (-1 means keep file base) */ const DgraphFlag flagval) /* Graph loading flags */ { Gnum reduloctab[12]; Gnum reduglbtab[12]; Gnum versval; #ifdef SCOTCH_DEBUG_DGRAPH2 if (MPI_Barrier (grafptr->proccomm) != MPI_SUCCESS) { /* Synchronize for debugging */ errorPrint ("dgraphLoad: communication error (1)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ reduloctab[0] = baseval; /* Exchange baseval to check it is the same for all */ reduloctab[1] = - baseval; reduloctab[2] = flagval; /* Exchange flagval to check it is the same for all */ reduloctab[3] = - flagval; reduloctab[4] = 0; /* Set uneffective values for versval */ reduloctab[5] = -2; reduloctab[6] = /* Assume everything will be fine */ reduloctab[7] = /* Assume does not have a stream */ reduloctab[8] = 0; if (stream != NULL) { if (intLoad (stream, &versval) != 1) { /* Read version number */ errorPrint ("dgraphLoad: bad input (1)"); versval = 0; reduloctab[6] = 1; } else if ((versval != 0) && (versval != 2)) { /* If not a graph format */ errorPrint ("dgraphLoad: not a graph format"); reduloctab[6] = 1; } reduloctab[4] = versval; reduloctab[5] = - versval; reduloctab[7] = 1; /* One more process involved in loading */ reduloctab[8] = grafptr->proclocnum; } if (dgraphAllreduceMaxSum (reduloctab, reduglbtab, 6, 3, grafptr->proccomm) != 0) { errorPrint ("dgraphLoad: communication error (2)"); return (1); } if (reduglbtab[6] != 0) /* Return from previous errors */ return (1); if ((reduglbtab[0] != - reduglbtab[1])) { errorPrint ("dgraphLoad: inconsistent base value"); return (1); } if ((reduglbtab[2] != - reduglbtab[3])) { errorPrint ("dgraphLoad: inconsistent flag value"); return (1); } if ((reduglbtab[7] != 0) && (reduglbtab[4] != - reduglbtab[5])) { errorPrint ("dgraphLoad: inconsistent graph file version value"); return (1); } if (reduglbtab[4] == 2) { /* If distributed graph format */ if (reduglbtab[7] == grafptr->procglbnbr) /* If as many input streams as processors */ return (dgraphLoadDist (grafptr, stream, baseval, flagval)); /* Read distributed graph */ } else { /* If centralized graph format */ if (reduglbtab[7] == 1) /* If only one reader stream */ return (dgraphLoadCent (grafptr, stream, baseval, flagval, reduglbtab[8])); /* Distribute centralized graph from known root */ else if (reduglbtab[7] == grafptr->procglbnbr) return (dgraphLoadMulti (grafptr, stream, baseval, flagval)); /* Read multi-centralized graph */ } errorPrint ((reduglbtab[7] == 0) ? "dgraphLoad: no input stream provided" : "dgraphLoad: invalid number of input streams"); return (1); } /* This routine loads a centralized source ** graph from a single stream. ** It returns: ** - 0 : on success. ** - !0 : on error. */ static int dgraphLoadCent ( Dgraph * restrict const grafptr, /* Distributed graph to load */ FILE * const stream, /* One single centralized stream */ Gnum baseval, /* Base value (-1 means keep file base) */ const DgraphFlag flagval, /* Graph loading flags */ const int protnum) /* Root process number */ { Gnum vertglbnbr; Gnum vertglbmax; Gnum vertlocnbr; Gnum * vertloctax; /* [norestrict:async] */ Gnum * vertlocptr; Gnum * restrict vertredtax; Gnum velolocnbr; Gnum velolocsum; Gnum * veloloctax; Gnum * restrict veloredtax; Gnum vlbllocnbr; Gnum * vlblloctax; Gnum * restrict vlblredtax; Gnum edgelocnbr; Gnum * edgeloctax; Gnum edgeredmnd; Gnum * restrict edgeredtax; Gnum * edloloctax; Gnum * restrict edloredtax; Gnum degrglbmax; Gnum baseadj; Gnum reduglbtab[5]; char proptab[4]; /* Property string array */ int cheklocval; int chekglbval; int o; #ifdef SCOTCH_DEBUG_DGRAPH2 if (((stream != NULL) && (protnum != grafptr->proclocnum)) || /* Enforce single stream */ ((stream == NULL) && (protnum == grafptr->proclocnum))) { errorPrint ("dgraphLoadCent: invalid parameter (1)"); return (1); } if ((protnum < 0) || (protnum >= grafptr->procglbnbr)) { errorPrint ("dgraphLoadCent: invalid parameter (2)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ reduglbtab[0] = 0; /* Assume everything will be fine */ if (stream != NULL) { if ((intLoad (stream, &reduglbtab[1]) != 1) || /* Read rest of header */ (intLoad (stream, &reduglbtab[2]) != 1) || (intLoad (stream, &reduglbtab[3]) != 1) || (intLoad (stream, &reduglbtab[4]) != 1) || (reduglbtab[4] < 0) || (reduglbtab[4] > 111)) { errorPrint ("dgraphLoadCent: bad input (1)"); cheklocval = 1; } } if (MPI_Bcast (&reduglbtab[0], 5, GNUM_MPI, protnum, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphLoadCent: communication error (1)"); return (1); } if (reduglbtab[0] != 0) return (1); if (baseval == -1) { /* If keep file graph base */ baseval = reduglbtab[3]; /* Set graph base as file base */ baseadj = 0; /* No base adjustment needed */ } else /* If set graph base */ baseadj = baseval - reduglbtab[3]; /* Update base adjust */ vertglbnbr = reduglbtab[1]; vertglbmax = DATASIZE (vertglbnbr, grafptr->procglbnbr, 0); vertlocnbr = DATASIZE (vertglbnbr, grafptr->procglbnbr, grafptr->proclocnum); sprintf (proptab, "%3.3d", (int) reduglbtab[4]); /* Compute file properties */ proptab[0] -= '0'; /* Vertex labels flag */ proptab[1] -= '0'; /* Edge weights flag */ proptab[2] -= '0'; /* Vertex loads flag */ velolocnbr = ((proptab[2] != 0) && ((flagval & GRAPHIONOLOADVERT) == 0)) ? vertglbmax : 0; vlbllocnbr = (proptab[0] != 0) ? vertglbmax : 0; vlblloctax = veloloctax = vertloctax = edgeloctax = /* Send arrays not allocated yet for root process */ edgeredtax = NULL; /* No read edge array yet */ cheklocval = 0; if ((vertlocptr = memAlloc ((vertglbmax + 2 + velolocnbr + vlbllocnbr) * sizeof (Gnum))) == NULL) { /* TRICK: "+2" for space for velolocsum */ errorPrint ("dgraphLoadCent: out of memory (1)"); cheklocval = 1; } else { vertloctax = vertlocptr -= baseval; vertlocptr += vertglbmax + 2; /* TRICK: "+2" for space for velolocsum */ if (proptab[2] != 0) { veloloctax = vertlocptr; vertlocptr += vertglbmax; } if (proptab[0] != 0) { vlblloctax = vertlocptr; baseadj = 0; /* No vertex adjustments if vertex labels */ } if (stream != NULL) { /* Allocate read edge array */ Gnum edgeredmax; Gnum edloredmax; edgeredmax = reduglbtab[2] / grafptr->procglbnbr + 1; edgeredmax += (edgeredmax >> 2) + 4; /* Add 25% more space for edges than average */ edloredmax = ((proptab[1] != 0) && ((flagval & GRAPHIONOLOADEDGE) == 0)) ? edgeredmax : 0; if ((edgeredtax = memAlloc ((edgeredmax + edloredmax) * sizeof (Gnum))) == NULL) { errorPrint ("dgraphLoadCent: out of memory (2)"); cheklocval = 1; } else { edgeredtax -= baseval; edloredtax = (edloredmax != 0) ? (edgeredtax + edgeredmax) : NULL; vertredtax = vertloctax; /* Prepare read vertex arrays, which will never move */ veloredtax = veloloctax; vlblredtax = vlblloctax; } edgeredmnd = edgeredmax + baseval; } } if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphLoadCent: communication error (2)"); chekglbval = 1; } if (chekglbval != 0) { if (edgeredtax != NULL) memFree (edgeredtax + baseval); if (vertloctax != NULL) memFree (vertloctax + baseval); return (1); } degrglbmax = 0; /* No maximum degree yet */ if (stream != NULL) { Gnum procnum; for (procnum = 0; procnum < grafptr->procglbnbr; procnum ++) { Gnum vertrednnd; Gnum vertrednum; Gnum edgerednum; Gnum veloredsum; for (vertrednum = edgerednum = baseval, veloredsum = 0, vertrednnd = DATASIZE (vertglbnbr, grafptr->procglbnbr, procnum) + baseval; vertrednum < vertrednnd; vertrednum ++) { Gnum degrredval; if (vlblredtax != NULL) { /* If must read label */ Gnum vlblredval; /* Vertex label value to be read */ if (intLoad (stream, &vlblredval) != 1) { /* Read label data */ errorPrint ("dgraphLoadCent: bad input (2)"); cheklocval = 1; break; } vlblredtax[vertrednum] = vlblredval; } if (proptab[2] != 0) { /* If must read vertex load */ Gnum veloredval; if (intLoad (stream, &veloredval) != 1) { /* Read vertex load data */ errorPrint ("dgraphLoadCent: bad input (3)"); cheklocval = 1; break; } if (veloredtax != NULL) veloredsum += veloredtax[vertrednum] = veloredval; } if (intLoad (stream, °rredval) != 1) { /* Read vertex degree */ errorPrint ("dgraphLoadCent: bad input (4)"); cheklocval = 1; break; } if (degrglbmax < degrredval) /* Set maximum degree */ degrglbmax = degrredval; vertredtax[vertrednum] = edgerednum; /* Set index in edge array */ degrredval += edgerednum; if (degrredval > edgeredmnd) { /* Check if edge array overflows */ Gnum edgeredmax; Gnum edgenewmax; Gnum edgenewsiz; Gnum * restrict edgenewtab; edgenewmax = edgeredmax = edgeredmnd - baseval; do /* Increase edge array size by 25 % */ edgenewmax += (edgenewmax >> 2) + 4; while (edgenewmax < (degrredval - baseval)); edgenewsiz = (edloredtax != NULL) ? (2 * edgenewmax) : edgenewmax; if ((edgenewtab = memRealloc (edgeredtax + baseval, edgenewsiz * sizeof (Gnum))) == NULL) { errorPrint ("dgraphLoadCent: out of memory (3)"); cheklocval = 1; break; } edgeredtax = edgenewtab - baseval; edgeredmnd = edgenewmax + baseval; if (edloredtax != NULL) { /* Move edge load array if present */ memMov (edgenewtab + edgenewmax, edgenewtab + edgeredmax, (edgerednum - baseval) * sizeof (Gnum)); edloredtax = edgeredtax + edgenewmax; } } for ( ; edgerednum < degrredval; edgerednum ++) { Gnum edgeredval; /* Value where to read edge end */ if (proptab[1] != 0) { /* If must read edge load */ Gnum edloredval; /* Value where to read edge load */ if (intLoad (stream, &edloredval) != 1) { /* Read edge load data */ errorPrint ("dgraphLoadCent: bad input (5)"); cheklocval = 1; break; } if (edloredtax != NULL) edloredtax[edgerednum] = edloredval; } if (intLoad (stream, &edgeredval) != 1) { /* Read edge data */ errorPrint ("dgraphLoadCent: bad input (6)"); cheklocval = 1; break; } edgeredtax[edgerednum] = edgeredval + baseadj; } if (cheklocval != 0) break; } vertredtax[vertrednum ++] = edgerednum; /* Set end of edge array */ if (cheklocval == 0) { if (procnum != grafptr->proclocnum) { /* If arrays have to be sent */ MPI_Request requtab[5]; MPI_Status stattab[5]; int requnbr; vertredtax[baseval] = edgerednum - baseval; /* First slot is number of edges */ vertredtax[vertrednum] = (veloredtax != NULL) ? veloredsum : (vertrednnd - baseval); /* Add vertex load sum to send vertex array */ if (MPI_Isend (vertredtax + baseval, vertrednnd - baseval + 2, /* TRICK: "+2" and not "+1" because of space for velolocsum */ GNUM_MPI, procnum, TAGVERTLOCTAB, grafptr->proccomm, &requtab[0]) != MPI_SUCCESS) { errorPrint ("dgraphLoadCent: communication error (5)"); return (1); /* Dirty exit as we can do nothing */ } requnbr = 1; if (veloredtax != NULL) { if (MPI_Isend (veloredtax + baseval, vertrednnd - baseval, GNUM_MPI, procnum, TAGVELOLOCTAB, grafptr->proccomm, &requtab[requnbr ++]) != MPI_SUCCESS) { errorPrint ("dgraphLoadCent: communication error (6)"); return (1); } } if (vlblredtax != NULL) { if (MPI_Isend (vlblredtax + baseval, vertrednnd - baseval, GNUM_MPI, procnum, TAGVLBLLOCTAB, grafptr->proccomm, &requtab[requnbr ++]) != MPI_SUCCESS) { errorPrint ("dgraphLoadCent: communication error (7)"); return (1); } } if (MPI_Recv (&reduglbtab[0], 0, MPI_INT, procnum, MPI_ANY_TAG, grafptr->proccomm, &stattab[0]) != MPI_SUCCESS) { errorPrint ("dgraphLoadCent: communication error (8)"); return (1); } if (stattab[0].MPI_TAG != TAGOK) /* If receiver could not allocate memory for edge arrays */ cheklocval = 1; else { if (MPI_Isend (edgeredtax + baseval, edgerednum - baseval, GNUM_MPI, procnum, TAGEDGELOCTAB, grafptr->proccomm, &requtab[requnbr ++]) != MPI_SUCCESS) { errorPrint ("dgraphLoadCent: communication error (9)"); return (1); } if (edloredtax != NULL) { if (MPI_Isend (edloredtax + baseval, edgerednum - baseval, GNUM_MPI, procnum, TAGEDLOLOCTAB, grafptr->proccomm, &requtab[requnbr ++]) != MPI_SUCCESS) { errorPrint ("dgraphLoadCent: communication error (10)"); return (1); } } MPI_Waitall (requnbr, &requtab[0], &stattab[0]); } } else { /* Arrays are local */ velolocsum = (veloredtax != NULL) ? veloredsum : vertlocnbr; /* Save accumulated values as local data */ edgelocnbr = edgerednum - baseval; if (edgeredmnd - edgerednum > 10000) { /* If array can be compacted */ if (edloredtax != NULL) { memMov (edgeredtax + edgerednum, edloredtax + baseval, edgelocnbr * sizeof (Gnum)); edgeredtax = memRealloc (edgeredtax + baseval, edgelocnbr * 2 * sizeof (Gnum)); edgeredtax -= baseval; edloredtax = edgeredtax + edgelocnbr; } else { edgeredtax = memRealloc (edgeredtax + baseval, edgelocnbr * sizeof (Gnum)); edgeredtax -= baseval; } } edgeloctax = edgeredtax; /* Keep read edge array as local edge array */ edloloctax = edloredtax; if (grafptr->proclocnum == (grafptr->procglbnbr - 1)) { /* If root process is last process */ vertredtax = /* No need to reallocate read arrays */ edgeredtax = NULL; break; /* And we can exit now */ } if ((vertlocptr = memAlloc ((vertglbmax + 2 + velolocnbr + vlbllocnbr) * sizeof (Gnum))) == NULL) { /* TRICK: "+2" for space for velolocsum */ errorPrint ("dgraphLoadCent: out of memory (4)"); cheklocval = 1; } else { Gnum edgeredmax; Gnum edloredmax; vertredtax = vertlocptr -= baseval; vertlocptr += vertglbmax + 2; /* TRICK: "+2" for space for velolocsum */ if (veloredtax != NULL) { veloredtax = vertlocptr; vertlocptr += vertglbmax; } if (vlblredtax != NULL) vlblredtax = vertlocptr; edgeredmax = edgeredmnd - baseval; edloredmax = (edloloctax != NULL) ? edgeredmax : 0; if ((edgeredtax = memAlloc ((edgeredmax + edloredmax) * sizeof (Gnum))) == NULL) { errorPrint ("dgraphLoadCent: out of memory (5)"); cheklocval = 1; } else { edgeredtax -= baseval; if (edloredtax != NULL) edloredtax = edgeredtax + edgeredmax; } } } } if (cheklocval != 0) { /* If error encountered */ for ( ; procnum < grafptr->procglbnbr; procnum ++) { /* Send abortion messages */ if (procnum != grafptr->proclocnum) { /* Abortion messages complete vertloctab receives */ if (MPI_Send (vertredtax + baseval, 0, GNUM_MPI, procnum, TAGVERTLOCTAB, grafptr->proccomm) != MPI_SUCCESS) errorPrint ("dgraphLoadCent: communication error (11)"); } } break; } } if (vertredtax != NULL) { /* Free reader arrays if reallocated */ if (vertredtax != vertloctax) /* If equal, vertloctax will be deallocated afterwards */ memFree (vertredtax + baseval); memFree (edgeredtax + baseval); } } else { /* Process is not reader */ MPI_Request requtab[5]; MPI_Status stattab[5]; int requnbr; int vertrcvnbr; /* int because of the MPI API */ if (MPI_Irecv (vertloctax + baseval, vertlocnbr + 2, GNUM_MPI, /* TRICK: "+2" and not "+1" because of velolocsum */ protnum, TAGVERTLOCTAB, grafptr->proccomm, &requtab[2]) != MPI_SUCCESS) { /* requtab[2] is first surely available slot */ errorPrint ("dgraphLoadCent: communication error (10)"); return (1); /* Dirty exit as we can do nothing */ } requnbr = 0; if (veloloctax != NULL) { if (MPI_Irecv (veloloctax + baseval, vertlocnbr, GNUM_MPI, protnum, TAGVELOLOCTAB, grafptr->proccomm, &requtab[requnbr ++]) != MPI_SUCCESS) { errorPrint ("dgraphLoadCent: communication error (11)"); return (1); } } if (vlblloctax != NULL) { if (MPI_Irecv (vlblloctax + baseval, vertlocnbr, GNUM_MPI, protnum, TAGVLBLLOCTAB, grafptr->proccomm, &requtab[requnbr ++]) != MPI_SUCCESS) { errorPrint ("dgraphLoadCent: communication error (12)"); return (1); } } MPI_Wait (&requtab[2], &stattab[2]); /* Wait until vertloctab received */ MPI_Get_count (&stattab[2], GNUM_MPI, &vertrcvnbr); /* Get size of received array */ #ifdef SCOTCH_DEBUG_DGRAPH2 if (((Gnum) vertrcvnbr != 0) && /* vertrcvnbr == 0 in the case of abortion message */ ((Gnum) vertrcvnbr != (vertlocnbr + 2))) { /* TRICK: "+2" and not "+1" because of velolocsum */ errorPrint ("dgraphLoadCent: invalid vertex array size"); vertrcvnbr = 0; } #endif /* SCOTCH_DEBUG_DGRAPH2 */ if (vertrcvnbr == 0) { /* Empty message means abortion wanted */ while (requnbr > 0) { /* Cancel all pending requests */ requnbr --; MPI_Cancel (&requtab[requnbr]); MPI_Request_free (&requtab[requnbr]); } /* No more pending requests */ } else { Gnum edlolocnbr; edgelocnbr = vertloctax[baseval]; /* edgelocnbr is first cell */ vertloctax[baseval] = baseval; /* First cell is always baseval */ velolocsum = vertloctax[vertlocnbr + baseval + 1]; /* TRICK: get velolocsum */ edlolocnbr = ((proptab[1] != 0) && ((flagval & GRAPHIONOLOADEDGE) == 0)) ? edgelocnbr : 0; edloloctax = NULL; /* Assume no edge load array */ if ((edgeloctax = memAlloc ((edgelocnbr + edlolocnbr) * sizeof (Gnum))) == NULL) { errorPrint ("dgraphLoadCent: out of memory (6)"); MPI_Send (&cheklocval, 0, MPI_INT, protnum, TAGBAD, grafptr->proccomm); /* Memory could not be allocated */ cheklocval = 1; } else { if (MPI_Irecv (edgeloctax, edgelocnbr, GNUM_MPI, protnum, TAGEDGELOCTAB, grafptr->proccomm, &requtab[requnbr ++]) != MPI_SUCCESS) { errorPrint ("dgraphLoadCent: communication error (13)"); return (1); } if (edlolocnbr != 0) { edloloctax = edgeloctax + edgelocnbr; if (MPI_Irecv (edloloctax, edgelocnbr, GNUM_MPI, protnum, TAGEDLOLOCTAB, grafptr->proccomm, &requtab[requnbr ++]) != MPI_SUCCESS) { errorPrint ("dgraphLoadCent: communication error (14)"); return (1); } edloloctax -= baseval; } edgeloctax -= baseval; MPI_Isend (&cheklocval, 0, MPI_INT, protnum, TAGOK, grafptr->proccomm, &requtab[requnbr ++]); /* Send ready to receive */ } } MPI_Waitall (requnbr, &requtab[0], &stattab[0]); /* Wait until all pending communications completed and all arrays received */ } if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphLoadCent: communication error (15)"); chekglbval = 1; } if (chekglbval != 0) { if (edgeloctax != NULL) memFree (edgeloctax + baseval); memFree (vertloctax + baseval); return (1); } o = dgraphBuild2 (grafptr, baseval, /* Build distributed graph */ vertlocnbr, vertlocnbr, vertloctax, vertloctax + 1, veloloctax, velolocsum, NULL, vlblloctax, edgelocnbr, edgelocnbr, edgeloctax, NULL, edloloctax, degrglbmax); /* Non-readers will have degrglbmax set to 0 */ grafptr->flagval |= DGRAPHFREETABS | DGRAPHVERTGROUP | DGRAPHEDGEGROUP; return (o); } /* This routine loads a distributed source ** graph from a distributed source graph ** file spread across all of the streams. ** It returns: ** - 0 : on success. ** - !0 : on error. */ static int dgraphLoadDist ( Dgraph * restrict const grafptr, /* Distributed graph to load */ FILE * const stream, /* One single centralized stream */ Gnum baseval, /* Base value (-1 means keep file base) */ const DgraphFlag flagval) /* Graph loading flags */ { Gnum proclocnum; Gnum vertlocnbr; Gnum vertlocnnd; Gnum vertlocnum; Gnum * restrict vertloctax; Gnum * vertlocptr; Gnum velolocnbr; Gnum velolocsum; Gnum * restrict veloloctax; Gnum vlbllocnbr; Gnum * restrict vlblloctax; Gnum edgelocnbr; Gnum edgelocnnd; Gnum edgelocnum; Gnum * restrict edgeloctax; Gnum * restrict edloloctax; Gnum degrlocmax; Gnum baseadj; Gnum reduloctab[12]; Gnum reduglbtab[12]; char proptab[4]; /* Property string array */ int cheklocval; int chekglbval; int o; #ifdef SCOTCH_DEBUG_DGRAPH2 if (stream == NULL) { errorPrint ("dgraphLoadDist: invalid parameter"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ reduloctab[0] = 0; /* Assume everything will be fine */ o = intLoad (stream, &reduloctab[1]); /* Read rest of header */ o += intLoad (stream, &proclocnum); o += intLoad (stream, &reduloctab[3]); o += intLoad (stream, &reduloctab[5]); o += intLoad (stream, &reduloctab[10]); o += intLoad (stream, &reduloctab[11]); o += intLoad (stream, &reduloctab[7]); o += intLoad (stream, &reduloctab[9]); if ((o != 8) || (reduloctab[9] < 0) || (reduloctab[9] > 111)) { errorPrint ("dgraphLoadDist: bad input (1)"); reduloctab[0] = 2; /* Immediate abort has maximum value so as to be propagated by MAX reduce */ } reduloctab[2] = - reduloctab[1]; reduloctab[4] = - reduloctab[3]; reduloctab[6] = - reduloctab[5]; reduloctab[8] = - reduloctab[7]; if ((int) proclocnum != grafptr->proclocnum) /* If fragment is not read by proper process */ reduloctab[0] |= 1; if ((int) reduloctab[1] != grafptr->procglbnbr) { errorPrint ("dgraphLoadDist: wrong number of processors to read distributed graph"); reduloctab[0] = 2; } if (dgraphAllreduceMaxSum (reduloctab, reduglbtab, 10, 2, grafptr->proccomm) != 0) { errorPrint ("dgraphLoadDist: communication error (1)"); reduglbtab[0] = 2; } if (reduglbtab[0] >= 2) /* If has to abort immediately */ return (1); if ((reduglbtab[2] != - reduglbtab[1]) || (reduglbtab[4] != - reduglbtab[3]) || (reduglbtab[6] != - reduglbtab[5]) || (reduglbtab[8] != - reduglbtab[7])) { errorPrint ("dgraphLoadDist: inconsistent distributed graph headers"); return (1); } if (reduloctab[0] == 1) errorPrint ("dgraphLoadDist: distributed graph file not read by proper process"); if (reduglbtab[0] != 0) /* If cannot go on anyway */ return (1); if ((reduglbtab[10] != reduloctab[3]) || (reduglbtab[11] != reduloctab[5])) errorPrint ("dgraphLoadDist: bad input (2)"); if ((reduglbtab[10] != reduglbtab[3]) || (reduglbtab[11] != reduglbtab[5])) return (1); if (baseval == -1) { /* If keep file graph base */ baseval = reduglbtab[7]; /* Set graph base as file base */ baseadj = 0; /* No base adjustment needed */ } else /* If set graph base */ baseadj = baseval - reduglbtab[7]; /* Update base adjust */ vertlocnbr = reduloctab[10]; edgelocnbr = reduloctab[11]; sprintf (proptab, "%3.3d", (int) reduglbtab[9]); /* Compute file properties */ proptab[0] -= '0'; /* Vertex labels flag */ proptab[1] -= '0'; /* Edge weights flag */ proptab[2] -= '0'; /* Vertex loads flag */ velolocnbr = ((proptab[2] != 0) && ((flagval & GRAPHIONOLOADVERT) == 0)) ? vertlocnbr : 0; vlbllocnbr = (proptab[0] != 0) ? vertlocnbr : 0; vlblloctax = veloloctax = vertloctax = edgeloctax = NULL; cheklocval = 0; if ((vertlocptr = memAlloc ((vertlocnbr + 1 + velolocnbr + vlbllocnbr) * sizeof (Gnum))) == NULL) { errorPrint ("dgraphLoadDist: out of memory (1)"); cheklocval = 1; } else { Gnum edlolocnbr; vertloctax = vertlocptr -= baseval; vertlocptr += vertlocnbr + 1; if ((proptab[2] != 0) && ((flagval & GRAPHIONOLOADVERT) == 0)) { veloloctax = vertlocptr; vertlocptr += vertlocnbr; } if (proptab[0] != 0) { vlblloctax = vertlocptr; baseadj = 0; /* No vertex adjustments if vertex labels */ } edlolocnbr = ((proptab[1] != 0) && ((flagval & GRAPHIONOLOADEDGE) == 0)) ? edgelocnbr : 0; if ((edgeloctax = memAlloc ((edgelocnbr + edlolocnbr) * sizeof (Gnum))) == NULL) { errorPrint ("dgraphLoadDist: out of memory (2)"); cheklocval = 1; } else { edgeloctax -= baseval; edloloctax = ((proptab[1] != 0) && ((flagval & GRAPHIONOLOADEDGE) == 0)) ? (edgeloctax + edgelocnbr) : NULL; } } if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphLoadDist: communication error (2)"); chekglbval = 1; } if (chekglbval != 0) { if (edgeloctax != NULL) memFree (edgeloctax + baseval); if (vertloctax != NULL) memFree (vertloctax + baseval); return (1); } degrlocmax = 0; /* No maximum degree yet */ velolocsum = (veloloctax != NULL) ? 0 : vertlocnbr; for (vertlocnum = edgelocnum = baseval, vertlocnnd = vertlocnbr + baseval, edgelocnnd = edgelocnbr + baseval; vertlocnum < vertlocnnd; vertlocnum ++) { Gnum degrlocval; if (vlblloctax != NULL) { /* If must read label */ Gnum vlbllocval; /* Vertex label value to be read */ if (intLoad (stream, &vlbllocval) != 1) { /* Read label data */ errorPrint ("dgraphLoadDist: bad input (2)"); cheklocval = 1; break; } vlblloctax[vertlocnum] = vlbllocval; } if (proptab[2] != 0) { /* If must read vertex load */ Gnum velolocval; if (intLoad (stream, &velolocval) != 1) { /* Read vertex load data */ errorPrint ("dgraphLoadDist: bad input (3)"); cheklocval = 1; break; } if (veloloctax != NULL) velolocsum += veloloctax[vertlocnum] = velolocval; } if (intLoad (stream, °rlocval) != 1) { /* Read vertex degree */ errorPrint ("dgraphLoadDist: bad input (4)"); cheklocval = 1; break; } if (degrlocmax < degrlocval) /* Set maximum degree */ degrlocmax = degrlocval; vertloctax[vertlocnum] = edgelocnum; /* Set index in edge array */ degrlocval += edgelocnum; if (degrlocval > edgelocnnd) { /* Check if edge array overflows */ errorPrint ("dgraphLoadDist: invalid arc count (1)"); cheklocval = 1; break; } for ( ; edgelocnum < degrlocval; edgelocnum ++) { Gnum edgelocval; /* Value where to read edge end */ if (proptab[1] != 0) { /* If must read edge load */ Gnum edlolocval; /* Value where to read edge load */ if (intLoad (stream, &edlolocval) != 1) { /* Read edge load data */ errorPrint ("dgraphLoadDist: bad input (5)"); cheklocval = 1; break; } if (edloloctax != NULL) edloloctax[edgelocnum] = edlolocval; } if (intLoad (stream, &edgelocval) != 1) { /* Read edge data */ errorPrint ("dgraphLoadDist: bad input (6)"); cheklocval = 1; break; } edgeloctax[edgelocnum] = edgelocval + baseadj; } if (cheklocval != 0) break; } vertloctax[vertlocnum] = edgelocnum; /* Set end of edge array */ if (edgelocnum != edgelocnnd) { /* Check if number of edges is valid */ errorPrint ("dgraphLoadDist: invalid arc count (2)"); cheklocval = 1; } if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphLoadDist: communication error (17)"); chekglbval = 1; } if (chekglbval != 0) { memFree (edgeloctax + baseval); memFree (vertloctax + baseval); return (1); } o = dgraphBuild2 (grafptr, baseval, /* Build distributed graph */ vertlocnbr, vertlocnbr, vertloctax, vertloctax + 1, veloloctax, velolocsum, NULL, vlblloctax, edgelocnbr, edgelocnbr, edgeloctax, NULL, edloloctax, degrlocmax); grafptr->flagval |= DGRAPHFREETABS | DGRAPHVERTGROUP | DGRAPHEDGEGROUP; return (o); } /* This routine loads a distributed source ** graph from a centralized source graph ** file replicated on all of the streams. ** It returns: ** - 0 : on success. ** - !0 : on error. */ static int dgraphLoadMulti ( Dgraph * restrict const grafptr, /* Distributed graph to load */ FILE * const stream, /* One single centralized stream */ Gnum baseval, /* Base value (-1 means keep file base) */ const DgraphFlag flagval) /* Graph loading flags */ { errorPrint ("dgraphLoadMulti: not implemented"); return (1); } scotch-6.0.4.dfsg/src/libscotch/library_mapping.c0000644002563400244210000000617711631447170025174 0ustar trophimeutilisateurs du domaine/* Copyright 2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_mapping.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains miscellaneous **/ /** routines for handling centralized **/ /** graph mappings. **/ /** **/ /** DATES : # Version 5.1 : from : 17 nov 2010 **/ /** to 17 nov 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /****************************************/ /* */ /* These routines are the C API for */ /* mapping structure handling routines. */ /* */ /****************************************/ /*+ This routine reserves a memory area *** of a size sufficient to store a *** graph mapping structure. *** It returns: *** - !NULL : if the initialization succeeded. *** - NULL : on error. +*/ SCOTCH_Mapping * SCOTCH_mapAlloc () { return ((SCOTCH_Mapping *) memAlloc (sizeof (SCOTCH_Mapping))); } scotch-6.0.4.dfsg/src/libscotch/dgraph_build.c0000644002563400244210000006173712344022231024431 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2010,2013,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_build.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Francois CHATENET (P0.0) **/ /** Sebastien FOUCAULT (P0.0) **/ /** Nicolas GICQUEL (P0.1) **/ /** Jerome LACOSTE (P0.1) **/ /** Cedric CHEVALIER **/ /** **/ /** FUNCTION : These lines are the distributed source **/ /** graph building routines. **/ /** **/ /** DATES : # Version P0.1 : from : 01 apr 1997 **/ /** to : 20 jun 1997 **/ /** # Version P0.2 : from : 02 feb 2000 **/ /** to : 02 feb 2000 **/ /** # Version 5.0 : from : 22 jul 2005 **/ /** to : 10 sep 2007 **/ /** # Version 5.1 : from : 30 jul 2010 **/ /** to : 03 nov 2010 **/ /** # Version 6.0 : from : 23 dec 2013 **/ /** to : 05 jun 2014 **/ /** **/ /************************************************************/ #define DGRAPH #include "module.h" #include "common.h" #include "dgraph.h" #include "dgraph_allreduce.h" #include "dgraph_build.h" /* This routine builds a distributed graph from ** the local arrays that are passed to it. If ** a vertex label array is given, it is assumed ** that edge ends are given with respect to these ** labels, and thus they are updated so as to be ** given with respect to the implicit (based) ** global numbering. ** As for all routines that build graphs, the private ** fields of the Dgraph structure have to be initialized ** if they are not already. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int dgraphBuild ( Dgraph * restrict const grafptr, /* Graph */ const Gnum baseval, /* Base for indexing */ const Gnum vertlocnbr, /* Number of local vertices */ const Gnum vertlocmax, /* Maximum number of local vertices */ Gnum * const vertloctax, /* Local vertex begin array */ Gnum * const vendloctax, /* Local vertex end array */ Gnum * const veloloctax, /* Local vertex load array (if any) */ Gnum * const vnumloctax, /* Local vertex number array (if any) */ Gnum * const vlblloctax, /* Local vertex label array (if any) */ const Gnum edgelocnbr, /* Number of local edges */ const Gnum edgelocsiz, /* Size of local edge array */ Gnum * const edgeloctax, /* Local edge array */ Gnum * const edgegsttax, /* Ghost edge array (if any); not const */ Gnum * const edloloctax) /* Local edge load array (if any) */ { Gnum vertlocnum; Gnum vertlocnnd; Gnum velolocsum; Gnum degrlocmax; /* Local maximum degree */ for (vertlocnum = baseval, vertlocnnd = vertlocnbr + baseval, degrlocmax = 0; vertlocnum < vertlocnnd; vertlocnum ++) { Gnum degrval; degrval = vendloctax[vertlocnum] - vertloctax[vertlocnum]; if (degrlocmax < degrval) degrlocmax = degrval; } if (veloloctax == NULL) /* Get local vertex load sum */ velolocsum = vertlocnbr; else { Gnum vertlocnum; for (vertlocnum = baseval, velolocsum = 0; vertlocnum < vertlocnnd; vertlocnum ++) velolocsum += veloloctax[vertlocnum]; } return (dgraphBuild2 (grafptr, baseval, vertlocnbr, vertlocmax, vertloctax, vendloctax, veloloctax, velolocsum, vnumloctax, vlblloctax, edgelocnbr, edgelocsiz, edgeloctax, edgegsttax, edloloctax, degrlocmax)); } /* This routine builds a distributed graph from ** the local arrays that are passed to it. If ** a vertex label array is given, it is assumed ** that edge ends are given with respect to these ** labels, and thus they are updated so as to be ** given with respect to the implicit (based) ** global numbering. ** As for all routines that build graphs, the private ** fields of the Dgraph structure have to be initialized ** if they are not already. ** These graphs do not have holes, since procvrttab ** points to procdsptab. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int dgraphBuild2 ( Dgraph * restrict const grafptr, /* Graph */ const Gnum baseval, /* Base for indexing */ const Gnum vertlocnbr, /* Number of local vertices */ const Gnum vertlocmax, /* Maximum number of local vertices */ Gnum * const vertloctax, /* Local vertex begin array */ Gnum * const vendloctax, /* Local vertex end array */ Gnum * const veloloctax, /* Local vertex load array (if any) */ const Gnum velolocsum, /* Local sum of vertex loads */ Gnum * const vnumloctax, /* Local vertex number array (if any) */ Gnum * const vlblloctax, /* Local vertex label array (if any) */ const Gnum edgelocnbr, /* Number of local edges */ const Gnum edgelocsiz, /* Size of local edge array */ Gnum * const edgeloctax, /* Local edge array */ Gnum * const edgegsttax, /* Ghost edge array (if any); not const */ Gnum * const edloloctax, /* Local edge load array (if any) */ const Gnum degrlocmax) { Gnum procnum; int reduloctab[2]; int cheklocval; /* Local consistency flag */ #ifdef SCOTCH_DEBUG_DGRAPH2 if ((vertlocmax < vertlocnbr) || (edgelocsiz < edgelocnbr)) { errorPrint ("dgraphBuild2: invalid parameters"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ cheklocval = 0; if (grafptr->procdsptab == NULL) { /* If private data not yet allocated */ int procglbnbr; procglbnbr = grafptr->procglbnbr; if (memAllocGroup ((void **) (void *) /* Allocate distributed graph private data */ &grafptr->procdsptab, (size_t) ((procglbnbr + 1) * sizeof (Gnum)), &grafptr->procvrttab, (size_t) ((procglbnbr + 1) * sizeof (Gnum)), &grafptr->proccnttab, (size_t) (procglbnbr * sizeof (Gnum)), &grafptr->procngbtab, (size_t) (procglbnbr * sizeof (int)), &grafptr->procrcvtab, (size_t) (procglbnbr * sizeof (int)), &grafptr->procsndtab, (size_t) (procglbnbr * sizeof (int)), NULL) == NULL) { int * dummtab; errorPrint ("dgraphBuild2: out of memory"); if ((dummtab = memAlloc ((procglbnbr * 2) * sizeof (int))) != NULL) { reduloctab[0] = reduloctab[1] = -1; if (MPI_Allgather (reduloctab, 2, MPI_INT, /* Use dummy receive array (if can be allocated too) */ dummtab, 2, MPI_INT, grafptr->proccomm) != MPI_SUCCESS) errorPrint ("dgraphBuild2: communication error (1)"); memFree (dummtab); } return (1); } } reduloctab[0] = (int) vertlocnbr; reduloctab[1] = (int) vertlocmax; if (MPI_Allgather (reduloctab, 2, MPI_INT, /* Use procngbtab and procrcvtab as a joint allreduce receive array */ grafptr->procngbtab, 2, MPI_INT, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphBuild2: communication error (2)"); return (1); } grafptr->procdsptab[0] = /* Build vertex-to-process array */ grafptr->procvrttab[0] = baseval; for (procnum = 0; procnum < grafptr->procglbnbr; procnum ++) { if (grafptr->procngbtab[procnum] < 0) { /* If error notified by another process during memory allocation */ memFree (grafptr->procdsptab); grafptr->procdsptab = NULL; /* Free memory that has just been allocated */ return (1); } grafptr->procdsptab[procnum + 1] = grafptr->procdsptab[procnum] + (Gnum) grafptr->procngbtab[2 * procnum]; grafptr->procvrttab[procnum + 1] = grafptr->procvrttab[procnum] + (Gnum) grafptr->procngbtab[2 * procnum + 1]; grafptr->proccnttab[procnum] = grafptr->procdsptab[procnum + 1] - grafptr->procdsptab[procnum]; } grafptr->flagval |= DGRAPHFREEPRIV; return (dgraphBuild3 (grafptr, baseval, vertlocnbr, vertloctax, vendloctax, veloloctax, velolocsum, vnumloctax, vlblloctax, edgelocnbr, edgelocsiz, edgeloctax, edgegsttax, edloloctax, degrlocmax)); } /* This routine builds a distributed graph from ** the local arrays that are passed to it. If ** a vertex label array is given, it is assumed ** that edge ends are given with respect to these ** labels, and thus they are updated so as to be ** given with respect to the implicit (based) ** global numbering. ** This alternate interface assumes that the private ** fields of the Dgraph structure have already been ** initialized. ** It returns: ** - 0 : on success. ** - !0 : on error. */ DGRAPHALLREDUCEMAXSUMOP (17, 3) int dgraphBuild3 ( Dgraph * restrict const grafptr, /* Graph */ const Gnum baseval, /* Base for indexing */ const Gnum vertlocnbr, /* Number of local vertices */ Gnum * const vertloctax, /* Local vertex begin array */ Gnum * const vendloctax, /* Local vertex end array */ Gnum * const veloloctax, /* Local vertex load array (if any) */ const Gnum velolocsum, /* Local sum of vertex loads */ Gnum * const vnumloctax, /* Local vertex number array (if any) */ Gnum * const vlblloctax, /* Local vertex label array (if any) */ const Gnum edgelocnbr, /* Number of local edges */ const Gnum edgelocsiz, /* Minimum useful size of local edge array */ Gnum * const edgeloctax, /* Local edge array */ Gnum * const edgegsttax, /* Ghost edge array (if any); not const */ Gnum * const edloloctax, /* Local edge load array (if any) */ const Gnum degrlocmax) { int procglbnbr; /* Number of processes sharing graph data */ int procrcvnum; /* Number of process from which to receive */ int procsndnum; /* Number of process to which to send */ int procngbnbr; /* Number of neighbors processed */ int procngbnum; /* Number of current neighbor process */ int procngbsel; /* Value of the currently used neighbor buffers */ Gnum vertngbmin; /* Smallest vertex number of neighbor process */ Gnum vertlocnum; Gnum edgelocnum; const Gnum * vlbllocptr; /* Pointer to current vertex label */ DgraphLablSortVert * vesongbptr; /* Pointer to current sort cell */ DgraphLablSortVert * vesongbtnd; /* Pointer to end of current sort array */ DgraphLablSortVert * vesongbtab[2]; /* Neighbor vertex sorting array [norestrict:async] */ int vesongbnbr[2]; /* Sizes of both vertex sort arrays */ DgraphLablSortEdge * edsoloctab; /* Local edge sorting array */ DgraphLablSortEdge * edsoloctnd; /* Pointer to end of edge sort array */ DgraphLablSortEdge * edsolocptr; /* Pointer to current sort edge */ MPI_Request requloctab[2]; /* Arrays for pipelined communication */ MPI_Status statloctab[2]; int cheklocval; /* Local consistency flag */ int chekglbval; /* Global consistency flag */ Gnum reduloctab[20]; /* Arrays for reductions */ Gnum reduglbtab[20]; reduloctab[0] = baseval; /* Check argument consistency */ reduloctab[1] = - baseval; reduloctab[2] = (veloloctax != NULL) ? 1 : 0; reduloctab[3] = - reduloctab[2]; reduloctab[4] = (vnumloctax != NULL) ? 1 : 0; reduloctab[5] = - reduloctab[4]; reduloctab[6] = (vlblloctax != NULL) ? 1 : 0; reduloctab[7] = - reduloctab[6]; reduloctab[8] = (edloloctax != NULL) ? 1 : 0; reduloctab[9] = - reduloctab[8]; reduloctab[10] = (edgegsttax != NULL) ? 1 : 0; reduloctab[11] = - reduloctab[10]; reduloctab[12] = vertlocnbr; /* Get maximum number of local vertices */ reduloctab[13] = edgelocnbr; reduloctab[14] = edgelocsiz; reduloctab[15] = degrlocmax; reduloctab[16] = (grafptr->procdsptab == NULL) ? 1 : 0; /* Error if private data not yet allocated */ reduloctab[17] = vertlocnbr; /* Sum local sizes */ reduloctab[18] = velolocsum; reduloctab[19] = edgelocnbr; if (dgraphAllreduceMaxSum (reduloctab, reduglbtab, 17, 3, grafptr->proccomm) != 0) { errorPrint ("dgraphBuild3: cannot compute reductions"); return (1); } if (reduglbtab[16] != 0) { errorPrint ("dgraphBuild3: no private data"); return (1); } if ((reduglbtab[1] != - reduglbtab[0]) || (reduglbtab[3] != - reduglbtab[2]) || (reduglbtab[5] != - reduglbtab[4]) || (reduglbtab[7] != - reduglbtab[6]) || (reduglbtab[9] != - reduglbtab[8]) || (reduglbtab[11] != - reduglbtab[10])) { errorPrint ("dgraphBuild3: inconsistent parameters"); return (1); } grafptr->vertglbmax = reduglbtab[12]; /* Set maximum number of local vertices */ grafptr->edgeglbmax = reduglbtab[13]; /* Set maximum number of local edges */ grafptr->edgeglbsmx = reduglbtab[14]; /* Set maximum size of local edge arrays */ grafptr->degrglbmax = reduglbtab[15]; /* Set maximum degree */ grafptr->baseval = baseval; grafptr->vertglbnbr = reduglbtab[17]; /* Set global and local data */ grafptr->vertlocnbr = vertlocnbr; grafptr->vertlocnnd = vertlocnbr + baseval; grafptr->velolocsum = velolocsum; grafptr->veloglbsum = reduglbtab[18]; grafptr->vertloctax = vertloctax; grafptr->vendloctax = vendloctax; grafptr->veloloctax = veloloctax; grafptr->vnumloctax = vnumloctax; grafptr->vlblloctax = vlblloctax; grafptr->edgeglbnbr = reduglbtab[19]; grafptr->edgelocnbr = edgelocnbr; grafptr->edgelocsiz = edgelocsiz; grafptr->edgegsttax = edgegsttax; grafptr->edgeloctax = edgeloctax; grafptr->edloloctax = edloloctax; #ifdef SCOTCH_DEBUG_DGRAPH2 if ((grafptr->procdsptab[grafptr->procglbnbr] - baseval) < grafptr->vertglbnbr) { errorPrint ("dgraphBuild3: invalid process vertex array"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ if (vlblloctax != NULL) { /* If vertex labels given */ procglbnbr = grafptr->procglbnbr; if (memAllocGroup ((void **) (void *) &vesongbtab[0], (size_t) (grafptr->vertglbmax * sizeof (DgraphLablSortVert)), &vesongbtab[1], (size_t) (grafptr->vertglbmax * sizeof (DgraphLablSortVert)), &edsoloctab, (size_t) (grafptr->edgeglbmax * sizeof (DgraphLablSortEdge)), NULL) == NULL) { errorPrint ("dgraphBuild3: out of memory"); return (1); } for (vertlocnum = 0, vesongbptr = vesongbtab[0], vlbllocptr = vlblloctax + baseval; vertlocnum < vertlocnbr; vertlocnum ++, vesongbptr ++, vlbllocptr ++) { vesongbptr->vlblglbnum = *vlbllocptr; /* Build vertex sort array */ vesongbptr->vertlocnum = vertlocnum; /* Local index is not based */ } intSort2asc1 (vesongbtab[0], vertlocnbr); vesongbnbr[0] = vertlocnbr; /* Set array size */ cheklocval = 0; for (vesongbptr = vesongbtab[0] + 1, vesongbtnd = vesongbtab[0] + vertlocnbr; vesongbptr < vesongbtnd; vesongbptr ++) { if (vesongbptr[0].vlblglbnum == vesongbptr[-1].vlblglbnum) { cheklocval = 1; break; } } #ifdef SCOTCH_DEBUG_DGRAPH1 /* Communication cannot be merged with a useful one */ MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, grafptr->proccomm); #else /* SCOTCH_DEBUG_DGRAPH1 */ chekglbval = cheklocval; #endif /* SCOTCH_DEBUG_DGRAPH1 */ if (chekglbval != 0) { errorPrint ("dgraphBuild3: duplicate vertex label (1)"); memFree (vesongbtab[0]); return (1); } for (edsolocptr = edsoloctab, edsoloctnd = edsoloctab + edgelocnbr, edgelocnum = baseval; edsolocptr < edsoloctnd; edsolocptr ++, edgelocnum ++) { edsolocptr->vlblglbnum = edgeloctax[edgelocnum]; edsolocptr->edgelocnum = edgelocnum; } intSort2asc2 (edsoloctab, grafptr->edgelocnbr); procrcvnum = (grafptr->proclocnum + 1) % procglbnbr; /* Compute indices of neighbors */ procsndnum = (grafptr->proclocnum - 1 + procglbnbr) % procglbnbr; for (procngbnbr = 0, procngbsel = 0; /* For all processes */ procngbnbr < procglbnbr; procngbnbr ++, procngbsel = 1 - procngbsel) { procngbnum = (grafptr->proclocnum + procngbnbr) % procglbnbr; /* Get neighbor process */ vertngbmin = grafptr->procvrttab[procngbnum]; /* Get neighbor vertex number range */ if (procngbnbr < (procglbnbr - 1)) { /* If not last iteration */ MPI_Irecv (vesongbtab[1 - procngbsel], 2 * grafptr->vertglbmax, GNUM_MPI, procrcvnum, TAGVLBLLOCTAB, grafptr->proccomm, &requloctab[0]); MPI_Isend (vesongbtab[procngbsel], 2 * vesongbnbr[procngbsel], GNUM_MPI, procsndnum, TAGVLBLLOCTAB, grafptr->proccomm, &requloctab[1]); } if (vesongbnbr[procngbsel] > 0) { /* If neighbor vertex sort array not empty */ for (edsolocptr = edsoloctab, /* Replace label by global vertex number */ vesongbptr = vesongbtab[procngbsel], vesongbtnd = vesongbptr + vesongbnbr[procngbsel]; edsolocptr < edsoloctnd; ) { if (edsolocptr->vlblglbnum == vesongbptr->vlblglbnum) { if (edsolocptr->edgelocnum == -1) /* If edge label already replaced */ cheklocval = 1; /* Set error flag */ else { edgeloctax[edsolocptr->edgelocnum] = vertngbmin + vesongbptr->vertlocnum; edsolocptr->edgelocnum = -1; /* Edge has been processed */ } edsolocptr ++; /* One more edge processed */ continue; /* Go on as quickly as possible */ } if (edsolocptr->vlblglbnum < vesongbptr->vlblglbnum) { edsolocptr ++; /* One more edge processed */ continue; /* Go on as quickly as possible */ } while (edsolocptr->vlblglbnum > vesongbptr->vlblglbnum) { if (++ vesongbptr >= vesongbtnd) { /* Break if all labels processed */ edsolocptr = edsoloctnd; break; } } } } if (procngbnbr < (procglbnbr - 1)) { /* If not last iteration */ MPI_Waitall (2, requloctab, statloctab); /* Wait for communication completion */ MPI_Get_count (&statloctab[0], GNUM_MPI, &vesongbnbr[1 - procngbsel]); vesongbnbr[1 - procngbsel] /= 2; /* Count items, not fields */ } } memFree (vesongbtab[0]); #ifdef SCOTCH_DEBUG_DGRAPH1 /* Communication cannot be merged with a useful one */ MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, grafptr->proccomm); #else /* SCOTCH_DEBUG_DGRAPH1 */ chekglbval = cheklocval; #endif /* SCOTCH_DEBUG_DGRAPH1 */ if (chekglbval != 0) { errorPrint ("dgraphBuild3: duplicate vertex label (2)"); return (1); } } return (0); } /* This subroutine computes the reduced values ** of all of the distributed graph fields. ** It does not deal with vertex labels, nor with ** the ghost edge array. ** It returns: ** - 0 : on success. ** - !0 : on error. */ DGRAPHALLREDUCEMAXSUMOP (4, 3) int dgraphBuild4 ( Dgraph * restrict const grafptr) /* Distributed graph */ { Gnum reduloctab[7]; /* Arrays for reductions */ Gnum reduglbtab[7]; reduloctab[0] = grafptr->vertlocnbr; /* Get maximum over all processes */ reduloctab[1] = grafptr->edgelocnbr; reduloctab[2] = grafptr->edgelocsiz; reduloctab[3] = grafptr->degrglbmax; /* Here, degrglbmax may store only a local maximum degree before calling */ reduloctab[4] = grafptr->vertlocnbr; /* Sum local sizes */ reduloctab[5] = grafptr->velolocsum; reduloctab[6] = grafptr->edgelocnbr; if (dgraphAllreduceMaxSum (reduloctab, reduglbtab, 4, 3, grafptr->proccomm) != 0) { errorPrint ("dgraphBuild4: cannot compute reductions"); return (1); } grafptr->vertglbmax = reduglbtab[0]; /* Set maximum number of local vertices */ grafptr->edgeglbmax = reduglbtab[1]; /* Set maximum number of local edges */ grafptr->edgeglbsmx = reduglbtab[2]; /* Set maximum size of local edge arrays */ grafptr->degrglbmax = reduglbtab[3]; /* Set maximum degree */ grafptr->vertglbnbr = reduglbtab[4]; grafptr->veloglbsum = reduglbtab[5]; grafptr->edgeglbnbr = reduglbtab[6]; #ifdef SCOTCH_DEBUG_DGRAPH2 if ((grafptr->procdsptab[grafptr->procglbnbr] - grafptr->baseval) < grafptr->vertglbnbr) { errorPrint ("dgraphBuild4: invalid process vertex array"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/library_mesh_f.c0000644002563400244210000002255011631447170024773 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_mesh_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API for **/ /** the source mesh handling routines of **/ /** the libSCOTCH library. **/ /** **/ /** DATES : # Version 4.0 : from : 23 sep 2002 **/ /** to 13 dec 2005 **/ /** # Version 5.1 : from : 27 mar 2010 **/ /** to 15 apr 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the mesh handling routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFMESHINIT, scotchfmeshinit, ( \ SCOTCH_Mesh * const meshptr, \ int * const revaptr), \ (meshptr, revaptr)) { *revaptr = SCOTCH_meshInit (meshptr); } /* ** */ FORTRAN ( \ SCOTCHFMESHEXIT, scotchfmeshexit, ( \ SCOTCH_Mesh * const meshptr), \ (meshptr)) { SCOTCH_meshExit (meshptr); } /* When an input stream is built from the given ** file handle, it is set as unbuffered, so as to ** allow for multiple stream reads from the same ** file handle. If it were buffered, too many ** input characters would be read on the first ** block read. */ FORTRAN ( \ SCOTCHFMESHLOAD, scotchfmeshload, ( \ SCOTCH_Mesh * const meshptr, \ int * const fileptr, \ const SCOTCH_Num * const baseptr, \ int * const revaptr), \ (meshptr, fileptr, baseptr, revaptr)) { FILE * stream; /* Stream to build from handle */ int filenum; /* Duplicated handle */ int o; if ((filenum = dup (*fileptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFMESHLOAD: cannot duplicate handle"); *revaptr = 1; /* Indicate error */ return; } if ((stream = fdopen (filenum, "r")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFMESHLOAD: cannot open input stream"); close (filenum); *revaptr = 1; return; } setbuf (stream, NULL); /* Do not buffer on input */ o = SCOTCH_meshLoad (meshptr, stream, *baseptr); fclose (stream); /* This closes filenum too */ *revaptr = o; } /* ** */ FORTRAN ( \ SCOTCHFMESHSAVE, scotchfmeshsave, ( \ const SCOTCH_Mesh * const meshptr, \ int * const fileptr, \ int * const revaptr), \ (meshptr, fileptr, revaptr)) { FILE * stream; /* Stream to build from handle */ int filenum; /* Duplicated handle */ int o; if ((filenum = dup (*fileptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFMESHSAVE: cannot duplicate handle"); *revaptr = 1; /* Indicate error */ return; } if ((stream = fdopen (filenum, "w")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFMESHSAVE: cannot open output stream"); close (filenum); *revaptr = 1; return; } o = SCOTCH_meshSave (meshptr, stream); fclose (stream); /* This closes filenum too */ *revaptr = o; } /* ** */ FORTRAN ( \ SCOTCHFMESHBUILD, scotchfmeshbuild, ( \ SCOTCH_Mesh * const meshptr, \ const SCOTCH_Num * const velmbas, \ const SCOTCH_Num * const vnodbas, \ const SCOTCH_Num * const velmnbr, \ const SCOTCH_Num * const vnodnbr, \ const SCOTCH_Num * const verttab, \ const SCOTCH_Num * const vendtab, \ const SCOTCH_Num * const velotab, \ const SCOTCH_Num * const vnlotab, \ const SCOTCH_Num * const vlbltab, \ const SCOTCH_Num * const edgenbr, \ const SCOTCH_Num * const edgetab, \ int * const revaptr), \ (meshptr, velmbas, vnodbas, velmnbr, vnodnbr, \ verttab, vendtab, velotab, vnlotab, vlbltab, \ edgenbr, edgetab, revaptr)) { *revaptr = SCOTCH_meshBuild (meshptr, *velmnbr, *vnodnbr, *velmbas, *vnodbas, verttab, vendtab, velotab, vnlotab, vlbltab, *edgenbr, edgetab); } /* ** */ FORTRAN ( \ SCOTCHFMESHCHECK, scotchfmeshcheck, ( \ const SCOTCH_Mesh * const meshptr, \ int * const revaptr), \ (meshptr, revaptr)) { *revaptr = SCOTCH_meshCheck (meshptr); } /* ** */ FORTRAN ( \ SCOTCHFMESHSIZE, scotchfmeshsize, ( \ const SCOTCH_Mesh * const meshptr, \ SCOTCH_Num * const velmnbr, \ SCOTCH_Num * const vnodnbr, \ SCOTCH_Num * const edgenbr), \ (meshptr, velmnbr, vnodnbr, edgenbr)) { SCOTCH_meshSize (meshptr, velmnbr, vnodnbr, edgenbr); } /* ** */ FORTRAN ( \ SCOTCHFMESHDATA, scotchfmeshdata, ( \ const SCOTCH_Mesh * const meshptr, \ const SCOTCH_Num * const indxptr, \ SCOTCH_Num * const velmbas, \ SCOTCH_Num * const vnodbas, \ SCOTCH_Num * const velmnbr, \ SCOTCH_Num * const vnodnbr, \ SCOTCH_Idx * const vertidx, \ SCOTCH_Idx * const vendidx, \ SCOTCH_Idx * const veloidx, \ SCOTCH_Idx * const vnloidx, \ SCOTCH_Idx * const vlblidx, \ SCOTCH_Num * const edgenbr, \ SCOTCH_Idx * const edgeidx, \ SCOTCH_Num * const degrnbr), \ (meshptr, indxptr, velmbas, vnodbas, velmnbr, vnodnbr, \ vertidx, vendidx, veloidx, vnloidx, vlblidx, \ edgenbr, edgeidx, degrnbr)) { SCOTCH_Num * verttab; /* Pointer to mesh arrays */ SCOTCH_Num * vendtab; SCOTCH_Num * velotab; SCOTCH_Num * vnlotab; SCOTCH_Num * vlbltab; SCOTCH_Num * edgetab; SCOTCH_meshData (meshptr, velmbas, vnodbas, velmnbr, vnodnbr, &verttab, &vendtab, &velotab, &vnlotab, &vlbltab, edgenbr, &edgetab, degrnbr); *vertidx = (verttab - indxptr) + 1; /* Add 1 since Fortran indices start at 1 */ *vendidx = (vendtab - indxptr) + 1; *veloidx = (velotab != NULL) ? (velotab - indxptr) + 1 : *vertidx; *vnloidx = (vnlotab != NULL) ? (vnlotab - indxptr) + 1 : *vertidx; *vlblidx = (vlbltab != NULL) ? (vlbltab - indxptr) + 1 : *vertidx; *edgeidx = (edgetab - indxptr) + 1; } scotch-6.0.4.dfsg/src/libscotch/mesh_induce_sepa.h0000644002563400244210000000573311631447171025313 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mesh_induce_sepa.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the improved Fiduccia-Mattheyses **/ /** graph separation routine. **/ /** **/ /** DATES : # Version 4.0 : from : 04 feb 2003 **/ /** to 09 feb 2003 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ Prime number for hashing vertex numbers. +*/ #define MESHINDUCESEPAHASHPRIME 17 /*+ Prime number for hashing +*/ /* ** The type and structure definitions. */ /*+ The hash vertex structure. +*/ typedef struct MeshInduceSepaHash_ { Gnum orgvelmnum; /*+ Number of element in original mesh +*/ Gnum indvnodnum; /*+ Number of neighbor node vertex in induced mesh +*/ } MeshInduceSepaHash; scotch-6.0.4.dfsg/src/libscotch/arch_deco.h0000644002563400244210000002015312354532105023713 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : arch_deco.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the decomposition-defined target **/ /** architecture functions. **/ /** **/ /** DATES : # Version 0.0 : from : 01 dec 1992 **/ /** to : 24 mar 1993 **/ /** # Version 1.2 : from : 04 feb 1994 **/ /** to : 11 feb 1994 **/ /** # Version 1.3 : from : 20 apr 1994 **/ /** to : 20 apr 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to : 12 nov 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to : 30 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 24 jul 1995 **/ /** # Version 3.1 : from : 20 jul 1996 **/ /** to 20 jul 1996 **/ /** # Version 3.2 : from : 11 sep 1996 **/ /** to 28 sep 1998 **/ /** # Version 4.0 : from : 29 nov 2003 **/ /** to 14 jun 2004 **/ /** # Version 5.1 : from : 21 jan 2008 **/ /** to 27 sep 2008 **/ /** # Version 6.0 : from : 14 fev 2011 **/ /** to 01 jul 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ #ifndef ARCH_DECO_H_STRUCT #define ARCH_DECO_H_STRUCT /*+ Decomposition architecture flags. +*/ #define ARCHDECONONE 0x0000 /*+ No options set +*/ #define ARCHDECOFREE 0x0001 /*+ Free arrays +*/ /* ** The type and structure definitions. */ /*+ The decomposition-described terminal vertex definition. +*/ typedef struct ArchDecoTermVert_ { ArchDomNum labl; /*+ Number for terminals, or ARCHDOMNOTTERM +*/ Anum wght; /*+ Weight of the domain (processor load) +*/ Anum num; /*+ Number of the terminal +*/ } ArchDecoTermVert; /*+ The decomposition-described architecture definitions. +*/ typedef struct ArchDecoVert_ { ArchDomNum labl; /*+ Smallest number of included terminal +*/ Anum size; /*+ Number of processors in the domain +*/ Anum wght; /*+ Weight of the domain (processor load) +*/ } ArchDecoVert; typedef struct ArchDeco_ { int flagval; /*+ Flag value +*/ Anum domtermnbr; /*+ Number of terminal domains +*/ Anum domvertnbr; /*+ Number of domains +*/ ArchDecoVert * domverttab; /*+ Table of domain "vertices" +*/ Anum * domdisttab; /*+ Table of domain distances +*/ } ArchDeco; typedef struct ArchDecoDom_ { Anum num; /*+ Domain number in the decomposition +*/ } ArchDecoDom; #endif /* ARCH_DECO_H_STRUCT */ /* ** The function prototypes. */ #ifndef ARCH_NOPROTO #ifndef ARCH_DECO_H_PROTO #define ARCH_DECO_H_PROTO #ifndef ARCH_DECO #define static #endif int archDecoArchBuild (ArchDeco * const, const Anum, const Anum, const ArchDecoTermVert * const, const Anum * const); int archDecoArchLoad (ArchDeco * const, FILE * restrict const); int archDecoArchSave (const ArchDeco * const, FILE * restrict const); int archDecoArchFree (ArchDeco * const); Anum archDecoArchSize (ArchDeco * const, const Anum); Anum archDecoArchDist (ArchDeco * const, const Anum, const Anum); Anum archDecoArchDistE (ArchDeco * const, const Anum, const Anum); ArchDomNum archDecoDomNum (const ArchDeco * const, const ArchDecoDom * const); int archDecoDomTerm (const ArchDeco * const, ArchDecoDom * restrict const, const ArchDomNum); Anum archDecoDomSize (const ArchDeco * const, const ArchDecoDom * const); Anum archDecoDomWght (const ArchDeco * const, const ArchDecoDom * const); Anum archDecoDomDist (const ArchDeco * const, const ArchDecoDom * const, const ArchDecoDom * const); int archDecoDomFrst (const ArchDeco * const, ArchDecoDom * restrict const); int archDecoDomLoad (const ArchDeco * const, ArchDecoDom * restrict const, FILE * restrict const); int archDecoDomSave (const ArchDeco * const, const ArchDecoDom * const, FILE * restrict const); int archDecoDomBipart (const ArchDeco * const, const ArchDecoDom * const, ArchDecoDom * restrict const, ArchDecoDom * restrict const); int archDecoDomIncl (const ArchDeco * const, const ArchDecoDom * const, const ArchDecoDom * const); #ifdef SCOTCH_PTSCOTCH int archDecoDomMpiType (const ArchDeco * const, MPI_Datatype * const); #endif /* SCOTCH_PTSCOTCH */ #undef static /* ** The macro definitions. */ #define archDecoArchSize(d,i) ((d)->domverttab[(i) - 1].size) #define archDecoArchDist(d,i,j) ((d)->domdisttab[((i) >= (j)) ? (((i) - 1) * ((i) - 2)) / 2 + (j) - 1 \ : (((j) - 1) * ((j) - 2)) / 2 + (i) - 1]) #define archDecoArchDistE(d,i,j) (((i) == (j)) ? 0 : archDecoArchDist ((d), (i), (j))) #endif /* ARCH_DECO_H_PROTO */ #endif /* ARCH_NOPROTO */ scotch-6.0.4.dfsg/src/libscotch/library_mesh_graph_f.c0000644002563400244210000000623611631447170026157 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_mesh_graph_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API for **/ /** the mesh-to-graph converter of the **/ /** libSCOTCH library. **/ /** **/ /** DATES : # Version 4.0 : from : 21 jan 2004 **/ /** to 21 jan 2004 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the mesh handling routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFMESHGRAPH, scotchfmeshgraph, ( \ const SCOTCH_Mesh * const meshptr, \ SCOTCH_Graph * const grafptr, \ int * const revaptr), \ (meshptr, grafptr, revaptr)) { *revaptr = SCOTCH_meshGraph (meshptr, grafptr); } scotch-6.0.4.dfsg/src/libscotch/library_random.c0000644002563400244210000000705412416704313025011 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_random.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the random **/ /** generator control routine. **/ /** **/ /** DATES : # Version 4.0 : from : 15 jan 2005 **/ /** to 15 jun 2005 **/ /** # Version 6.0 : from : 08 oct 2012 **/ /** to 03 oct 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /************************************/ /* */ /* These routines are the C API for */ /* the random handling routines. */ /* */ /************************************/ /*+ This routine sets the process number that *** is used to generate a different seed across *** all processes. *** It returns: *** - void : in all cases. +*/ void SCOTCH_randomProc ( int procnum) { intRandProc (procnum); } /*+ This routine resets the random generator *** to simulate a start from scratch. *** It returns: *** - void : in all cases. +*/ void SCOTCH_randomReset () { intRandReset (); } /*+ This routine resets the random generator *** to simulate a start from scratch. *** It returns: *** - void : in all cases. +*/ void SCOTCH_randomSeed ( INT seedval) { intRandSeed (seedval); } scotch-6.0.4.dfsg/src/libscotch/vgraph_separate_st.h0000644002563400244210000001013211631447170025665 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vgraph_separate_st.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the global separation **/ /** strategy and method tables. **/ /** **/ /** DATES : # Version 3.2 : from : 24 oct 1996 **/ /** to 14 nov 1997 **/ /** # Version 3.3 : from : 31 may 1999 **/ /** to 31 may 1999 **/ /** # Version 4.0 : from : 06 jan 2002 **/ /** to 19 aug 2004 **/ /** # Version 5.0 : from : 12 sep 2006 **/ /** to : 17 feb 2007 **/ /** # Version 5.1 : from : 30 oct 2007 **/ /** to : 30 oct 2007 **/ /** **/ /************************************************************/ /* ** The type definitions. */ /*+ Method types. +*/ typedef enum VgraphSeparateStMethodType_ { VGRAPHSEPASTMETHBD = 0, /*+ Banding strategy +*/ VGRAPHSEPASTMETHES, /*+ Edge separation strategy +*/ VGRAPHSEPASTMETHFM, /*+ Fiduccia-Mattheyses +*/ VGRAPHSEPASTMETHGG, /*+ Greedy Graph Growing +*/ VGRAPHSEPASTMETHGP, /*+ Gibbs-Poole-Stockmeyer +*/ VGRAPHSEPASTMETHML, /*+ Multi-level separation +*/ VGRAPHSEPASTMETHVW, /*+ Partition viewer +*/ VGRAPHSEPASTMETHZR, /*+ Zero method +*/ VGRAPHSEPASTMETHNBR /*+ Number of methods +*/ } VgraphSeparateStMethodType; /* ** The external declarations. */ extern StratTab vgraphseparateststratab; /* ** The function prototypes. */ #ifndef VGRAPH_SEPARATE_ST #define static #endif int vgraphSeparateSt (Vgraph * const, const Strat * const); #undef static scotch-6.0.4.dfsg/src/libscotch/library_arch_f.c0000644002563400244210000002560011631447170024753 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010,2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_arch_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API for **/ /** the source graph handling routines of **/ /** the libSCOTCH library. **/ /** **/ /** DATES : # Version 3.4 : from : 02 dec 1999 **/ /** to 15 nov 2001 **/ /** # Version 4.0 : from : 13 jan 2004 **/ /** to 13 jan 2004 **/ /** # Version 5.1 : from : 27 mar 2010 **/ /** to 13 feb 2011 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /*************************************/ /* */ /* These routines are the Fortran */ /* API for the architecture handling */ /* routines. */ /* */ /*************************************/ /* ** */ FORTRAN ( \ SCOTCHFARCHINIT, scotchfarchinit, ( \ SCOTCH_Arch * const archptr, \ int * const revaptr), \ (archptr, revaptr)) { *revaptr = SCOTCH_archInit (archptr); } /* ** */ FORTRAN ( \ SCOTCHFARCHEXIT, scotchfarchexit, ( \ SCOTCH_Arch * const archptr), \ (archptr)) { SCOTCH_archExit (archptr); } /* When an input stream is built from the given ** file handle, it is set as unbuffered, so as to ** allow for multiple stream reads from the same ** file handle. If it were buffered, too many ** input characters would be read on the first ** block read. */ FORTRAN ( \ SCOTCHFARCHLOAD, scotchfarchload, ( \ SCOTCH_Arch * const archptr, \ int * const fileptr, \ int * const revaptr), \ (archptr, fileptr, revaptr)) { FILE * stream; /* Stream to build from handle */ int filenum; /* Duplicated handle */ int o; if ((filenum = dup (*fileptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFARCHLOAD: cannot duplicate handle"); *revaptr = 1; /* Indicate error */ return; } if ((stream = fdopen (filenum, "r")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFARCHLOAD: cannot open input stream"); close (filenum); *revaptr = 1; return; } setbuf (stream, NULL); /* Do not buffer on input */ o = SCOTCH_archLoad (archptr, stream); fclose (stream); /* This closes filenum too */ *revaptr = o; } /* ** */ FORTRAN ( \ SCOTCHFARCHSAVE, scotchfarchsave, ( \ const SCOTCH_Arch * const archptr, \ int * const fileptr, \ int * const revaptr), \ (archptr, fileptr, revaptr)) { FILE * stream; /* Stream to build from handle */ int filenum; /* Duplicated handle */ int o; if ((filenum = dup (*fileptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFARCHSAVE: cannot duplicate handle"); *revaptr = 1; /* Indicate error */ return; } if ((stream = fdopen (filenum, "w")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFARCHSAVE: cannot open output stream"); close (filenum); *revaptr = 1; return; } o = SCOTCH_archSave (archptr, stream); fclose (stream); /* This closes filenum too */ *revaptr = o; } /* ** */ FORTRAN ( \ SCOTCHFARCHNAME, scotchfarchname, ( \ const SCOTCH_Arch * const archptr, \ char * const chartab, \ int * const charptr), \ (archptr, chartab, charptr)) { char * nameptr; /* Name string */ nameptr = SCOTCH_archName (archptr); /* Get architecture name */ strncpy (chartab, nameptr, *charptr); /* Copy architecture name */ } /* ** */ FORTRAN ( \ SCOTCHFARCHSIZE, scotchfarchsize, ( \ const SCOTCH_Arch * const archptr, \ int * const sizeptr), \ (archptr, sizeptr)) { *sizeptr = SCOTCH_archSize (archptr); } /* ** */ FORTRAN ( \ SCOTCHFARCHVAR, scotchfarchvar, ( \ const SCOTCH_Arch * const archptr, \ int * const flagptr), \ (archptr, flagptr)) { *flagptr = SCOTCH_archVar (archptr); } /* ** */ FORTRAN ( \ SCOTCHFARCHCMPLT, scotchfarchcmplt, ( \ SCOTCH_Arch * const archptr, \ const SCOTCH_Num * const archnbr, \ int * const revaptr), \ (archptr, archnbr, revaptr)) { *revaptr = SCOTCH_archCmplt (archptr, *archnbr); } /* ** */ FORTRAN ( \ SCOTCHFARCHCMPLTW, scotchfarchcmpltw, ( \ SCOTCH_Arch * const archptr, \ const SCOTCH_Num * const vertnbr, \ const SCOTCH_Num * const velotab, \ int * const revaptr), \ (archptr, vertnbr, velotab, revaptr)) { *revaptr = SCOTCH_archCmpltw (archptr, *vertnbr, velotab); } /* ** */ FORTRAN ( \ SCOTCHFARCHHCUB, scotchfarchhcub, ( \ SCOTCH_Arch * const archptr, \ const SCOTCH_Num * const dimmax, \ int * const revaptr), \ (archptr, dimmax, revaptr)) { *revaptr = SCOTCH_archHcub (archptr, *dimmax); } /* ** */ FORTRAN ( \ SCOTCHFARCHMESH2, scotchfarchmesh2, ( \ SCOTCH_Arch * const archptr, \ const SCOTCH_Num * const dimxval, \ const SCOTCH_Num * const dimyval, \ int * const revaptr), \ (archptr, dimxval, dimyval, revaptr)) { *revaptr = SCOTCH_archMesh2 (archptr, *dimxval, *dimyval); } /* ** */ FORTRAN ( \ SCOTCHFARCHMESH3, scotchfarchmesh3, ( \ SCOTCH_Arch * const archptr, \ const SCOTCH_Num * const dimxval, \ const SCOTCH_Num * const dimyval, \ const SCOTCH_Num * const dimzval, \ int * const revaptr), \ (archptr, dimxval, dimyval, dimzval, revaptr)) { *revaptr = SCOTCH_archMesh3 (archptr, *dimxval, *dimyval, *dimzval); } /* ** */ FORTRAN ( \ SCOTCHFARCHTLEAF, scotchfarchtleaf, ( \ SCOTCH_Arch * const archptr, \ const SCOTCH_Num * const levlnbr, \ const SCOTCH_Num * const sizetab, \ const SCOTCH_Num * const linktab, \ int * const revaptr), \ (archptr, levlnbr, sizetab, linktab, revaptr)) { *revaptr = SCOTCH_archTleaf (archptr, *levlnbr, sizetab, linktab); } /* ** */ FORTRAN ( \ SCOTCHFARCHTORUS2, scotchfarchtorus2, ( \ SCOTCH_Arch * const archptr, \ const SCOTCH_Num * const dimxval, \ const SCOTCH_Num * const dimyval, \ int * const revaptr), \ (archptr, dimxval, dimyval, revaptr)) { *revaptr = SCOTCH_archTorus2 (archptr, *dimxval, *dimyval); } /* ** */ FORTRAN ( \ SCOTCHFARCHTORUS3, scotchfarchtorus3, ( \ SCOTCH_Arch * const archptr, \ const SCOTCH_Num * const dimxval, \ const SCOTCH_Num * const dimyval, \ const SCOTCH_Num * const dimzval, \ int * const revaptr), \ (archptr, dimxval, dimyval, dimzval, revaptr)) { *revaptr = SCOTCH_archTorus3 (archptr, *dimxval, *dimyval, *dimzval); } /* ** */ FORTRAN ( \ SCOTCHFARCHVCMPLT, scotchfarchvcmplt, ( \ SCOTCH_Arch * const archptr, \ int * const revaptr), \ (archptr, revaptr)) { *revaptr = SCOTCH_archVcmplt (archptr); } /* ** */ FORTRAN ( \ SCOTCHFARCHVHCUB, scotchfarchvhcub, ( \ SCOTCH_Arch * const archptr, \ int * const revaptr), \ (archptr, revaptr)) { *revaptr = SCOTCH_archVhcub (archptr); } scotch-6.0.4.dfsg/src/libscotch/dmapping_io.c0000644002563400244210000002766112473137713024310 0ustar trophimeutilisateurs du domaine/* Copyright 2008,2010,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dmapping_io.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles distributed **/ /** mappings. **/ /** **/ /** DATES : # Version 5.1 : from : 13 jun 2008 **/ /** to 11 aug 2010 **/ /** # Version 6.0 : from : 29 oct 2014 **/ /** to 29 oct 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DORDER #include "module.h" #include "common.h" #include "comm.h" #include "dgraph.h" #include "dgraph_allreduce.h" #include "arch.h" #include "dmapping.h" /************************************/ /* */ /* These routines handle orderings. */ /* */ /************************************/ DGRAPHALLREDUCEMAXSUMOP (1, 5) /* This routine saves a distributed mapping. ** The distributed graph structure is provided ** to access the distribution of vertex labels, ** whenever present. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int dmapSave ( const Dmapping * restrict const dmapptr, const Dgraph * restrict const grafptr, FILE * restrict const stream) { const DmappingFrag * restrict fragptr; Gnum fragglbnbr; Gnum * restrict termloctab; Gnum * restrict termrcvtab; Gnum vertrcvmax; Gnum vertglbnbr; Gnum * restrict vlbltax; Gnum reduloctab[6]; Gnum reduglbtab[6]; int protnum; reduloctab[0] = dmapptr->vertlocmax; reduloctab[1] = dmapptr->vertlocnbr; reduloctab[2] = dmapptr->fragnbr; if (stream != NULL) { /* If file provided */ reduloctab[3] = 1; /* This process is the root */ reduloctab[4] = grafptr->proclocnum; /* Get its rank */ } else { reduloctab[3] = /* This process is not the root */ reduloctab[4] = 0; } reduloctab[5] = (grafptr->vlblloctax != NULL) ? 1 : 0; /* See if vertex labels provided */ if (dgraphAllreduceMaxSum (reduloctab, reduglbtab, 1, 5, grafptr->proccomm) != 0) { errorPrint ("dmapSave: communication error (1)"); return (1); } if (reduglbtab[3] != 1) { errorPrint ("dmapSave: should have only one root"); return (1); } if ((reduglbtab[5] != 0) && (reduglbtab[5] != grafptr->procglbnbr)) { errorPrint ("dmapSave: inconsistent parameters"); return (1); } if ((reduglbtab[1] < 0) && (reduglbtab[1] > grafptr->procglbnbr)) { errorPrint ("dmapSave: invalid mapping (1)"); return (1); } vertrcvmax = reduglbtab[0]; /* Size of largest fragment to receive */ vertglbnbr = reduglbtab[1]; fragglbnbr = reduglbtab[2]; protnum = (int) reduglbtab[4]; /* Get rank of root process */ reduloctab[0] = 0; if (protnum == grafptr->proclocnum) { Gnum vlblnbr; vlblnbr = (grafptr->vlblloctax != NULL) ? grafptr->vertglbnbr : 0; if ((termloctab = memAllocGroup ((void **) (void *) /* termloctab not used on root processor, but used only for freeing the block */ &termrcvtab, (size_t) (vertrcvmax * 2 * sizeof (Gnum)), /* TRICK: "*2" as vnumrcvtab is sent after termrcvtab */ &vlbltax, (size_t) (vlblnbr * sizeof (Gnum)), NULL)) == NULL) { errorPrint ("dmapSave: out of memory (1)"); reduloctab[0] = 1; } else if (fprintf (stream, GNUMSTRING "\n", (Gnum) vertglbnbr) == EOF) { errorPrint ("dmapSave: bad output (1)"); reduloctab[0] = 1; } } else { vlbltax = NULL; /* Prevent Valgrind from yelling */ if ((termloctab = memAlloc (dmapptr->vertlocmax * sizeof (Gnum))) == NULL) { errorPrint ("dmapSave: out of memory (2)"); reduloctab[0] = 1; } } #ifdef SCOTCH_DEBUG_DMAP1 /* This communication cannot be covered by a useful one */ if (MPI_Allreduce (reduloctab, reduglbtab, 1, GNUM_MPI, MPI_SUM, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dmapSave: communication error (2)"); reduglbtab[0] = 1; } #else /* SCOTCH_DEBUG_DMAP1 */ reduglbtab[0] = reduloctab[0]; #endif /* SCOTCH_DEBUG_DMAP1 */ if (reduglbtab[0] != 0) { if (termloctab != NULL) memFree (termloctab); /* Free group leader */ return (1); } if (grafptr->vlblloctax != NULL) { if (commGatherv (grafptr->vlblloctax + grafptr->baseval, grafptr->vertlocnbr, GNUM_MPI, vlbltax, grafptr->proccnttab, grafptr->procdsptab, GNUM_MPI, protnum, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dmapSave: communication error (3)"); return (1); } vlbltax -= grafptr->baseval; /* Base label array */ } if (protnum == grafptr->proclocnum) { Gnum vertrcvnbr; Gnum * restrict vnumrcvptr; Gnum * restrict termrcvptr; for (fragptr = dmapptr->fragptr; fragptr != NULL; fragptr = fragptr->nextptr) { /* Output local fragments */ Gnum fraglocnum; for (fraglocnum = 0; fraglocnum < fragptr->vertnbr; fraglocnum ++) { Gnum vnumnum; Gnum termnum; vnumnum = fragptr->vnumtab[fraglocnum]; #ifdef SCOTCH_DEBUG_DMAP2 if ((vnumnum < 0) || (vnumnum >= (grafptr->vertglbnbr + grafptr->baseval))) { errorPrint ("dmapSave: invalid mapping (2)"); return (1); } #endif /* SCOTCH_DEBUG_DMAP2 */ termnum = archDomNum (&dmapptr->archdat, &fragptr->domntab[fragptr->parttab[fraglocnum]]); if (fprintf (stream, GNUMSTRING "\t" GNUMSTRING "\n", (Gnum) ((grafptr->vlblloctax != NULL) ? vlbltax[vnumnum] : vnumnum), (Gnum) termnum) == EOF) { errorPrint ("dmapSave: bad output (2)"); reduloctab[0] = 1; break; } } } for (fragglbnbr -= dmapptr->fragnbr; fragglbnbr > 0; fragglbnbr --) { /* For all non-local fragments */ Gnum * restrict termrcvnnd; MPI_Status statdat; int recvnbr; if (MPI_Recv (termrcvtab, (int) (vertrcvmax * 2), GNUM_MPI, MPI_ANY_SOURCE, MPI_ANY_TAG, grafptr->proccomm, &statdat) != MPI_SUCCESS) { errorPrint ("dmapSave: communication error (4)"); /* TRICK: "*2" as vnumrcvtab is sent after termrcvtab */ return (1); } if (reduloctab[0] != 0) continue; MPI_Get_count (&statdat, GNUM_MPI, &recvnbr); vertrcvnbr = (Gnum) (recvnbr / 2); /* We received a composite message made of both vectors */ vnumrcvptr = termrcvtab + vertrcvnbr; /* Vertex index array is just after terminal number array */ for (termrcvptr = termrcvtab, termrcvnnd = termrcvtab + vertrcvnbr; termrcvptr < termrcvnnd; termrcvptr ++, vnumrcvptr ++) { if (fprintf (stream, GNUMSTRING "\t" GNUMSTRING "\n", (Gnum) ((grafptr->vlblloctax != NULL) ? vlbltax[*vnumrcvptr] : *vnumrcvptr), (Gnum) *termrcvptr) == EOF) { errorPrint ("dmapSave: bad output (3)"); reduloctab[0] = 1; break; } } } } else { int typecnttab[2]; MPI_Aint typedsptab[2]; MPI_Datatype typedat; for (fragptr = dmapptr->fragptr; fragptr != NULL; fragptr = fragptr->nextptr) { /* Output local fragments */ Gnum fraglocnum; for (fraglocnum = 0; fraglocnum < fragptr->vertnbr; fraglocnum ++) { #ifdef SCOTCH_DEBUG_DMAP2 Gnum vnumnum; vnumnum = fragptr->vnumtab[fraglocnum]; if ((vnumnum < 0) || (vnumnum >= (grafptr->vertglbnbr + grafptr->baseval))) { errorPrint ("dmapSave: invalid mapping (3)"); return (1); } #endif /* SCOTCH_DEBUG_DMAP2 */ termloctab[fraglocnum] = archDomNum (&dmapptr->archdat, &fragptr->domntab[fragptr->parttab[fraglocnum]]); } #if ((defined COMMON_MPI_VERSION) && (COMMON_MPI_VERSION <= 100)) MPI_Address (termloctab, &typedsptab[0]); MPI_Address (fragptr->vnumtab, &typedsptab[1]); #else /* ((defined COMMON_MPI_VERSION) && (COMMON_MPI_VERSION <= 100)) */ MPI_Get_address (termloctab, &typedsptab[0]); MPI_Get_address (fragptr->vnumtab, &typedsptab[1]); #endif /* ((defined COMMON_MPI_VERSION) && (COMMON_MPI_VERSION <= 100)) */ typedsptab[1] -= typedsptab[0]; typedsptab[0] = 0; typecnttab[0] = typecnttab[1] = (int) fragptr->vertnbr; #if ((defined COMMON_MPI_VERSION) && (COMMON_MPI_VERSION <= 100)) MPI_Type_hindexed (2, typecnttab, typedsptab, GNUM_MPI, &typedat); #else /* ((defined COMMON_MPI_VERSION) && (COMMON_MPI_VERSION <= 100)) */ MPI_Type_create_hindexed (2, typecnttab, typedsptab, GNUM_MPI, &typedat); #endif /* ((defined COMMON_MPI_VERSION) && (COMMON_MPI_VERSION <= 100)) */ MPI_Type_commit (&typedat); if (MPI_Send (termloctab, 1, typedat, protnum, 0, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dmapSave: communication error (5)"); return (1); } MPI_Type_free (&typedat); } } memFree (termloctab); /* Free group leader */ #ifdef SCOTCH_DEBUG_DMAP1 /* This communication cannot be covered by a useful one */ if (MPI_Allreduce (reduloctab, reduglbtab, 1, GNUM_MPI, MPI_SUM, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dmapSave: communication error (6)"); reduglbtab[0] = 1; } #else /* SCOTCH_DEBUG_DMAP1 */ reduglbtab[0] = reduloctab[0]; #endif /* SCOTCH_DEBUG_DMAP1 */ return ((int) reduglbtab[0]); } scotch-6.0.4.dfsg/src/libscotch/parser_ll.l0000644002563400244210000002234311631447171024003 0ustar trophimeutilisateurs du domaine%{ /* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : parser_ll.l **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the lexical parser **/ /** which processes strategy strings. **/ /** **/ /** DATES : # Version 3.1 : from : 07 nov 1995 **/ /** to 23 aug 1996 **/ /** # Version 3.2 : from : 24 sep 1996 **/ /** to 05 jun 1997 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 11 sep 2001 **/ /** # Version 4.0 : from : 20 dec 2001 **/ /** to 23 dec 2001 **/ /** # Version 5.1 : from : 09 jun 2009 **/ /** to 24 jul 2011 **/ /** **/ /** NOTES : # In order for flex to read its input **/ /** with getc() instead of fread, we set **/ /** YY_ALWAYS_INTERACTIVE to 1. This may **/ /** not always work with future releases. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define PARSER_LL #include "module.h" #include "common.h" #undef INTEGER /* In case someone defined them */ #undef DOUBLE #include "parser.h" #include "parser_ll.h" #include "parser_yy.h" #include "parser_ly.h" /*+ Definitions produced by yacc +*/ /* Assume no interactive parsing. */ #ifdef X_OSDOS /* Available only with MKS LEX */ #ifdef YY_INTERACTIVE #undef YY_INTERACTIVE #endif /* YY_INTERACTIVE */ #define YY_INTERACTIVE 0 #endif /* X_OSDOS */ #ifdef FLEX_SCANNER #define YY_ALWAYS_INTERACTIVE 1 /* Set the parser as interactive and read one char at a time */ #define YY_INPUT(buf,result,max_size) { int c = stratParserInput (); result = (c == 0) ? YY_NULL : ((buf)[0] = c, 1); } #else /* FLEX_SCANNER */ #undef getc /* Redirect I/O functions */ #define getc yygetc #undef yygetc #define yygetc(stream) stratParserInput () #endif /* FLEX_SCANNER */ #define YY_NO_UNPUT /* No prototype for yyunput as not defined */ #define YY_SKIP_YYWRAP /* No prototype for yywrap as defined as macro */ #define yywrap() (1) /* Always return end-of-file on end-of-string */ /* ** The static variables. */ static const char * stratparserstringptr; /* Pointer to the string to parse */ %} IDENT [A-Za-z][0-9A-Za-z]* INTEGER [0-9]+ FLOAT [0-9]+(\.[0-9]+)?([Ee][-+]?[0-9]+)? STRING \"[^\"]*\" %s lstrat %s lparam %s lparamcase %s lparamdouble %s lparamint %s lparamstring %s ltest %% [0-9A-Za-z] { strncpy (yylval.STRING, yytext, PARSERSTRINGLEN); yylval.STRING[PARSERSTRINGLEN - 1] = '\0'; return (METHODNAME); } {IDENT} { strncpy (yylval.STRING, yytext, PARSERSTRINGLEN); yylval.STRING[PARSERSTRINGLEN - 1] = '\0'; return (PARAMNAME); } [0-9A-Za-z] { yylval.CASEVAL = yytext[0]; return (VALCASE); } ({FLOAT}|{INTEGER}) { yylval.DOUBLE = atof (yytext); return (VALDOUBLE); } {INTEGER} { yylval.INTEGER = (INT) atol (yytext); return (VALINT); } {FLOAT} { yylval.INTEGER = (INT) atof (yytext); /* FLOAT is put after so that INTEGER can be matched */ return (VALINT); } {STRING} { yytext[yyleng - 1] = '\0'; /* Remove the heading and trailing \" */ strncpy (yylval.STRING, yytext + 1, PARSERSTRINGLEN); yylval.STRING[PARSERSTRINGLEN - 1] = '\0'; return (VALSTRING); } {INTEGER} { yylval.INTEGER = (INT) atol (yytext); return (VALINT); } {FLOAT} { yylval.DOUBLE = atof (yytext); return (VALDOUBLE); } {IDENT} { strncpy (yylval.STRING, yytext, PARSERSTRINGLEN); yylval.STRING[PARSERSTRINGLEN - 1] = '\0'; return (PARAMNAME); } [ \t\n]* ; . return (yytext[0]); %% /*******************************************/ /* */ /* These routines handle data input to the */ /* lexical analyzer. */ /* */ /*******************************************/ /* This routine initializes the ** lexical analyzer. ** It returns: ** - VOID : in all cases. */ void stratParserInit ( const char * const string) /*+ Strategy string to parse +*/ { #ifdef FLEX_SCANNER yyrestart (yyin); /* (Re-)initialize the parser */ #endif /* FLEX_SCANNER */ stratParserSelect (VALSTRAT); /* Begin with a strategy */ stratparserstringptr = string; /* Point to beginning of string */ } /* This routine reads a single character ** from the input string. ** It returns: ** - 0 : if end of string reached. ** - !0 : character from string. */ static int stratParserInput () { if (*stratparserstringptr == '\0') /* If end-of-string reached */ return (0); /* Return end-of-file token */ else /* Else return the character */ return ((int) (unsigned char) *stratparserstringptr ++); } /* This routine returns the pointer to the ** remaining part of the string. */ const char * stratParserRemain () { return (stratparserstringptr); } /* This routine selects the sub-parser ** to parse the input. ** It returns: ** - VOID : in all cases. */ void stratParserSelect ( unsigned int type) { switch (type) { case VALCASE : BEGIN lparamcase; break; case VALDOUBLE : BEGIN lparamdouble; break; case VALINT : BEGIN lparamint; break; case VALSTRING : BEGIN lparamstring; break; case VALPARAM : BEGIN lparam; break; case VALSTRAT : BEGIN lstrat; break; case VALTEST : BEGIN ltest; break; } } scotch-6.0.4.dfsg/src/libscotch/graph_io.c0000644002563400244210000004013311631447170023573 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : graph_io.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles the source graph **/ /** input/output functions. **/ /** **/ /** DATES : # Version 0.0 : from : 01 dec 1992 **/ /** to 18 may 1993 **/ /** # Version 1.3 : from : 30 apr 1994 **/ /** to 18 may 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to 31 oct 1994 **/ /** # Version 3.0 : from : 07 jul 1995 **/ /** to 28 sep 1995 **/ /** # Version 3.1 : from : 28 nov 1995 **/ /** to 08 jun 1996 **/ /** # Version 3.2 : from : 07 sep 1996 **/ /** to 15 mar 1999 **/ /** # Version 4.0 : from : 25 nov 2001 **/ /** to 21 jan 2004 **/ /** # Version 5.0 : from : 13 dec 2006 **/ /** to 10 sep 2007 **/ /** # Version 5.1 : from : 11 aug 2010 **/ /** to 11 aug 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GRAPH_IO #include "module.h" #include "common.h" #include "graph.h" #include "graph_io.h" /*******************************************/ /* */ /* These routines handle source graph I/O. */ /* */ /*******************************************/ /* This routine loads a source graph from ** the given stream. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int graphLoad ( Graph * restrict const grafptr, /* Graph structure to fill */ FILE * const stream, /* Stream from which to read graph data */ const Gnum baseval, /* Base value (-1 means keep file base) */ const GraphFlag flagval) /* Graph loading flags */ { Gnum edgenum; /* Number of edges really allocated */ Gnum edgennd; Gnum vlblnbr; /* = vertnbr if vertex labels */ Gnum vlblmax; /* Maximum vertex label number */ Gnum velonbr; /* = vertnbr if vertex loads wanted */ Gnum velosum; /* Sum of vertex loads */ Gnum edlonbr; /* = edgenbr if edge loads wanted */ Gnum edlosum; /* Sum of edge loads */ Gnum edgeval; /* Value where to read edge end */ Gnum baseadj; Gnum versval; Gnum degrmax; Gnum propval; char proptab[4]; Gnum vertnum; memSet (grafptr, 0, sizeof (Graph)); if (intLoad (stream, &versval) != 1) { /* Read version number */ errorPrint ("graphLoad: bad input (1)"); return (1); } if (versval != 0) { /* If version not zero */ errorPrint ("graphLoad: old-style graph format no longer supported"); return (1); } if ((intLoad (stream, &grafptr->vertnbr) != 1) || /* Read rest of header */ (intLoad (stream, &grafptr->edgenbr) != 1) || (intLoad (stream, &baseadj) != 1) || (intLoad (stream, &propval) != 1) || (propval < 0) || (propval > 111)) { errorPrint ("graphLoad: bad input (2)"); return (1); } sprintf (proptab, "%3.3d", (int) propval); /* Compute file properties */ proptab[0] -= '0'; /* Vertex labels flag */ proptab[1] -= '0'; /* Edge weights flag */ proptab[2] -= '0'; /* Vertex loads flag */ grafptr->flagval = GRAPHFREETABS | GRAPHVERTGROUP | GRAPHEDGEGROUP; if (baseval == -1) { /* If keep file graph base */ grafptr->baseval = baseadj; /* Set graph base as file base */ baseadj = 0; /* No base adjustment needed */ } else { /* If set graph base */ grafptr->baseval = baseval; /* Set wanted graph base */ baseadj = baseval - baseadj; /* Update base adjust */ } if (proptab[0] != 0) /* If vertex labels, no base adjust */ baseadj = 0; velonbr = ((proptab[2] != 0) && ((flagval & GRAPHIONOLOADVERT) == 0)) ? grafptr->vertnbr : 0; vlblnbr = (proptab[0] != 0) ? grafptr->vertnbr : 0; edlonbr = ((proptab[1] != 0) && ((flagval & GRAPHIONOLOADEDGE) == 0)) ? grafptr->edgenbr : 0; if ((memAllocGroup ((void **) (void *) &grafptr->verttax, (size_t) ((grafptr->vertnbr + 1) * sizeof (Gnum)), &grafptr->velotax, (size_t) (velonbr * sizeof (Gnum)), &grafptr->vlbltax, (size_t) (vlblnbr * sizeof (Gnum)), NULL) == NULL) || (memAllocGroup ((void **) (void *) &grafptr->edgetax, (size_t) (grafptr->edgenbr * sizeof (Gnum)), &grafptr->edlotax, (size_t) (edlonbr * sizeof (Gnum)), NULL) == NULL)) { if (grafptr->verttax != NULL) memFree (grafptr->verttax); errorPrint ("graphLoad: out of memory"); graphFree (grafptr); return (1); } grafptr->vertnnd = grafptr->vertnbr + grafptr->baseval; grafptr->verttax -= grafptr->baseval; grafptr->vendtax = grafptr->verttax + 1; /* Use compact vertex array */ grafptr->velotax = (velonbr != 0) ? (grafptr->velotax - grafptr->baseval) : NULL; grafptr->vlbltax = (vlblnbr != 0) ? (grafptr->vlbltax - grafptr->baseval) : NULL; grafptr->edgetax -= grafptr->baseval; grafptr->edlotax = (edlonbr != 0) ? (grafptr->edlotax - grafptr->baseval) : NULL; vlblmax = grafptr->vertnnd - 1; /* No vertex labels known */ velosum = (grafptr->velotax == NULL) ? grafptr->vertnbr : 0; edlosum = (grafptr->edlotax == NULL) ? grafptr->edgenbr : 0; edgennd = grafptr->edgenbr + grafptr->baseval; degrmax = 0; /* No maximum degree yet */ for (vertnum = edgenum = grafptr->baseval; vertnum < grafptr->vertnnd; vertnum ++) { Gnum degrval; if (grafptr->vlbltax != NULL) { /* If must read label */ Gnum vlblval; /* Value where to read vertex label */ if (intLoad (stream, &vlblval) != 1) { /* Read label data */ errorPrint ("graphLoad: bad input (3)"); graphFree (grafptr); return (1); } grafptr->vlbltax[vertnum] = vlblval; if (grafptr->vlbltax[vertnum] > vlblmax) /* Get maximum vertex label */ vlblmax = grafptr->vlbltax[vertnum]; } if (proptab[2] != 0) { /* If must read vertex load */ Gnum veloval; /* Value where to read vertex load */ if (intLoad (stream, &veloval) != 1) { /* Read vertex load data */ errorPrint ("graphLoad: bad input (4)"); graphFree (grafptr); return (1); } if (grafptr->velotax != NULL) velosum += grafptr->velotax[vertnum] = veloval; } if (intLoad (stream, °rval) != 1) { /* Read vertex degree */ errorPrint ("graphLoad: bad input (5)"); graphFree (grafptr); return (1); } if (degrmax < degrval) /* Set maximum degree */ degrmax = degrval; grafptr->verttax[vertnum] = edgenum; /* Set index in edge array */ degrval += edgenum; if (degrval > edgennd) { /* Check if edge array overflows */ errorPrint ("graphLoad: invalid arc count (1)"); graphFree (grafptr); return (1); } for ( ; edgenum < degrval; edgenum ++) { if (proptab[1] != 0) { /* If must read edge load */ Gnum edloval; /* Value where to read edge load */ if (intLoad (stream, &edloval) != 1) { /* Read edge load data */ errorPrint ("graphLoad: bad input (6)"); graphFree (grafptr); return (1); } if (grafptr->edlotax != NULL) edlosum += grafptr->edlotax[edgenum] = (Gnum) edloval; } if (intLoad (stream, &edgeval) != 1) { /* Read edge data */ errorPrint ("graphLoad: bad input (7)"); graphFree (grafptr); return (1); } grafptr->edgetax[edgenum] = edgeval + baseadj; } } grafptr->verttax[vertnum] = edgenum; /* Set end of edge array */ if (edgenum != edgennd) { /* Check if number of edges is valid */ errorPrint ("graphLoad: invalid arc count (2)"); graphFree (grafptr); return (1); } grafptr->velosum = velosum; grafptr->edlosum = edlosum; grafptr->degrmax = degrmax; if (grafptr->vlbltax != NULL) { /* If vertex label renaming necessary */ if (graphLoad2 (grafptr->baseval, grafptr->vertnnd, grafptr->verttax, /* Rename edge ends */ grafptr->vendtax, grafptr->edgetax, vlblmax, grafptr->vlbltax) != 0) { errorPrint ("graphLoad: cannot relabel vertices"); graphFree (grafptr); return (1); } } #ifdef SCOTCH_DEBUG_GRAPH2 if (graphCheck (grafptr) != 0) { /* Check graph consistency */ errorPrint ("graphLoad: inconsistent graph data"); graphFree (grafptr); return (1); } #endif /* SCOTCH_DEBUG_GRAPH2 */ return (0); } int graphLoad2 ( const Gnum baseval, const Gnum vertnnd, const Gnum * const verttax, const Gnum * const vendtax, Gnum * restrict const edgetax, const Gnum vlblmax, const Gnum * const vlbltax) { Gnum vertnum; /* Number of current vertex */ Gnum * restrict indxtab; /* Vertex label/number index table */ if ((indxtab = (Gnum *) memAlloc ((vlblmax + 1) * sizeof (Gnum))) == NULL) { errorPrint ("graphLoad2: out of memory"); return (1); } memSet (indxtab, ~0, (vlblmax + 1) * sizeof (Gnum)); /* Assume labels not used */ for (vertnum = baseval; vertnum < vertnnd; vertnum ++) { if (indxtab[vlbltax[vertnum]] != ~0) { /* If vertex label already used */ errorPrint ("graphLoad2: duplicate vertex label"); memFree (indxtab); return (1); } indxtab[vlbltax[vertnum]] = vertnum; /* Set vertex number index */ } for (vertnum = baseval; vertnum < vertnnd; vertnum ++) { Gnum edgenum; /* Number of current edge */ for (edgenum = verttax[vertnum]; edgenum < vendtax[vertnum]; edgenum ++) { if (edgetax[edgenum] > vlblmax) { /* If invalid edge end number */ errorPrint ("graphLoad2: invalid arc end number (1)"); memFree (indxtab); return (1); } if (indxtab[edgetax[edgenum]] == ~0) { /* If unused edge end number */ errorPrint ("graphLoad2: invalid arc end number (2)"); memFree (indxtab); return (1); } edgetax[edgenum] = indxtab[edgetax[edgenum]]; /* Replace label by number */ } } memFree (indxtab); /* Free index array */ return (0); } /* This routine saves a source graph to ** the given stream, in the new-style ** graph format. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int graphSave ( const Graph * const grafptr, FILE * const stream) { Gnum vertnum; char propstr[4]; /* Property string */ int o; propstr[0] = (grafptr->vlbltax != NULL) ? '1' : '0'; /* Set property string */ propstr[1] = (grafptr->edlotax != NULL) ? '1' : '0'; propstr[2] = (grafptr->velotax != NULL) ? '1' : '0'; propstr[3] = '\0'; if (fprintf (stream, "0\n" GNUMSTRING "\t" GNUMSTRING "\n" GNUMSTRING "\t%3s\n", /* Write file header */ (Gnum) grafptr->vertnbr, (Gnum) grafptr->edgenbr, (Gnum) grafptr->baseval, propstr) == EOF) { errorPrint ("graphSave: bad output (1)"); return (1); } for (vertnum = grafptr->baseval, o = 0; (vertnum < grafptr->vertnnd) && (o == 0); vertnum ++) { Gnum edgenum; if (grafptr->vlbltax != NULL) /* Write vertex label if necessary */ o = (fprintf (stream, GNUMSTRING "\t", (Gnum) grafptr->vlbltax[vertnum]) == EOF); if (grafptr->velotax != NULL) /* Write vertex load if necessary */ o |= (fprintf (stream, GNUMSTRING "\t", (Gnum) grafptr->velotax[vertnum]) == EOF); o |= (fprintf (stream, GNUMSTRING, (Gnum) (grafptr->vendtax[vertnum] - grafptr->verttax[vertnum])) == EOF); /* Write vertex degree */ for (edgenum = grafptr->verttax[vertnum]; (edgenum < grafptr->vendtax[vertnum]) && (o == 0); edgenum ++) { Gnum vertend; o |= (putc ('\t', stream) == EOF); if (grafptr->edlotax != NULL) /* Write edge load if necessary */ o |= (fprintf (stream, GNUMSTRING "\t", (Gnum) grafptr->edlotax[edgenum]) == EOF); vertend = grafptr->edgetax[edgenum]; o |= (fprintf (stream, GNUMSTRING, (Gnum) ((grafptr->vlbltax != NULL) ? grafptr->vlbltax[vertend] : vertend)) == EOF); /* Write edge end */ } o |= (putc ('\n', stream) == EOF); } if (o != 0) errorPrint ("graphSave: bad output (2)"); return (o); } scotch-6.0.4.dfsg/src/libscotch/library_graph_io_mmkt.c0000644002563400244210000001003111631447170026341 0ustar trophimeutilisateurs du domaine/* Copyright 2008,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_io_mmkt.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the Matrix **/ /** Market geometry and graph handling **/ /** routines of the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 13 mar 2008 **/ /** to 13 mar 2008 **/ /** # Version 5.1 : from : 27 apr 2010 **/ /** to 27 apr 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "geom.h" #include "graph.h" #include "scotch.h" /*************************************/ /* */ /* These routines are the C API for */ /* the Matrix Market graph and */ /* geometry handling routines. */ /* */ /*************************************/ /*+ This routine loads the given opaque geom *** structure with the data of the given stream. *** - 0 : if loading succeeded. *** - !0 : on error. +*/ int SCOTCH_graphGeomLoadMmkt ( SCOTCH_Graph * restrict const grafptr, SCOTCH_Geom * restrict const geomptr, FILE * const filegrfptr, FILE * const filegeoptr, const char * const dataptr) { return (graphGeomLoadMmkt ((Graph *) grafptr, (Geom *) geomptr, filegrfptr, filegeoptr, dataptr)); } /*+ This routine saves the contents of the given *** opaque graph structure to the given stream. *** It returns: *** - 0 : if the saving succeeded. *** - !0 : on error. +*/ int SCOTCH_graphGeomSaveMmkt ( const SCOTCH_Graph * restrict const grafptr, const SCOTCH_Geom * restrict const geomptr, FILE * const filegrfptr, FILE * const filegeoptr, const char * const dataptr) { return (graphGeomSaveMmkt ((Graph *) grafptr, (Geom *) geomptr, filegrfptr, filegeoptr, dataptr)); } scotch-6.0.4.dfsg/src/libscotch/library_graph_color.c0000644002563400244210000001350412374704437026037 0ustar trophimeutilisateurs du domaine/* Copyright 2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_color.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the graph **/ /** coloring routine of the libSCOTCH **/ /** library. **/ /** **/ /** DATES : # Version 6.0 : from : 02 jan 2012 **/ /** to 19 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "arch.h" #include "graph.h" #include "graph_coarsen.h" #include "scotch.h" /*********************************/ /* */ /* This routine is the C API for */ /* the graph coloring routine. */ /* */ /*********************************/ /*+ This routine creates a color array for the *** given graph. *** It returns: *** - 0 : if the graph has been coarsened. *** - 1 : if the graph could not be coarsened. *** - 2 : on error. +*/ int SCOTCH_graphColor ( const SCOTCH_Graph * restrict const grafptr, /* Graph to color */ SCOTCH_Num * restrict const colotab, /* Pointer to color array */ SCOTCH_Num * restrict const coloptr, /* Pointer to number of colors */ const SCOTCH_Num flagval) /* Flag value (not used) */ { Gnum baseval; Gnum vertnum; Gnum vertnbr; Gnum vertnnd; Gnum queunnd; Gnum * restrict queutax; Gnum * restrict randtax; Gnum colonum; Gnum * restrict colotax; const Gnum * restrict const verttax = ((Graph *) grafptr)->verttax; const Gnum * restrict const vendtax = ((Graph *) grafptr)->vendtax; const Gnum * restrict const edgetax = ((Graph *) grafptr)->edgetax; baseval = ((Graph *) grafptr)->baseval; vertnbr = ((Graph *) grafptr)->vertnbr; vertnnd = vertnbr + baseval; memSet (colotab, ~0, vertnbr * sizeof (Gnum)); colotax = ((Gnum *) colotab) - baseval; if (memAllocGroup ((void **) (void *) &queutax, (size_t) (vertnbr * sizeof (Gnum)), &randtax, (size_t) (vertnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("SCOTCH_graphColor: out of memory"); return (1); } queutax -= baseval; randtax -= baseval; intRandInit (); /* Check that random number generator is initialized */ for (vertnum = baseval; vertnum < vertnnd; vertnum ++) randtax[vertnum] = intRandVal (32768); queunnd = vertnnd; for (colonum = 0; queunnd > baseval; colonum ++) { /* Color numbers are not based */ Gnum queuold; Gnum queunew; for (queunew = queuold = baseval; queuold < queunnd; queuold ++) { Gnum vertnum; Gnum edgenum; Gnum edgennd; Gnum randval; vertnum = (queunnd == vertnnd) ? queuold : queutax[queuold]; randval = randtax[vertnum]; for (edgenum = verttax[vertnum], edgennd = vendtax[vertnum]; edgenum < edgennd; edgenum ++) { Gnum vertend; Gnum randend; vertend = edgetax[edgenum]; if (colotax[vertend] >= 0) continue; randend = randtax[vertend]; if ((randend > randval) || ((randend == randval) && (vertend > vertnum))) /* Tie breaking when same random value */ break; } if (edgenum >= edgennd) colotax[vertnum] = colonum; else queutax[queunew ++] = vertnum; } queunnd = queunew; } *coloptr = colonum; /* Set number of colors found */ memFree (queutax + baseval); return (0); } scotch-6.0.4.dfsg/src/libscotch/library_error_exit.c0000644002563400244210000001447711631447170025725 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007-2009,2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_error_exit.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module provides error handling **/ /** routines to process errors generated by **/ /** the routines of the libSCOTCH library. **/ /** **/ /** DATES : # Version 3.3 : from : 02 oct 1998 **/ /** to 02 oct 1998 **/ /** # Version 3.4 : from : 01 nov 2001 **/ /** to 01 nov 2001 **/ /** # Version 5.0 : from : 06 mar 2008 **/ /** to 24 may 2008 **/ /** # Version 5.1 : from : 27 sep 2008 **/ /** to 17 jul 2011 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY_ERROR #include "module.h" #include "common.h" #include "scotch.h" /********************************/ /* */ /* The error handling routines. */ /* */ /********************************/ static char _SCOTCHerrorProgName[32] = ""; /* This routine sets the program name for ** error reporting. ** It returns: ** - VOID : in all cases. */ void SCOTCH_errorProg ( const char * const progstr) /*+ Program name +*/ { int charnbr; const char * nsrcptr; char * ndstptr; nsrcptr = progstr; ndstptr = _SCOTCHerrorProgName; charnbr = strlen (progstr); if (charnbr > 31) { _SCOTCHerrorProgName[0] = _SCOTCHerrorProgName[1] = _SCOTCHerrorProgName[2] = '.'; ndstptr += 3; nsrcptr += charnbr - 28; charnbr = 28; } strncpy (ndstptr, nsrcptr, charnbr); _SCOTCHerrorProgName[31] = '\0'; } /* This routine prints an error message with ** a variable number of arguments, as printf () ** does, and exits. ** It returns: ** - EXIT : in all cases. */ void SCOTCH_errorPrint ( const char * const errstr, /*+ printf-like variable argument list */ ...) { va_list errlist; /* The argument list of the call */ #ifdef SCOTCH_PTSCOTCH int proclocnum; #endif /* SCOTCH_PTSCOTCH */ fprintf (stderr, "%s", _SCOTCHerrorProgName); #ifdef SCOTCH_PTSCOTCH if ((MPI_Initialized (&proclocnum) == MPI_SUCCESS) && (proclocnum != 0) && (MPI_Comm_rank (MPI_COMM_WORLD, &proclocnum) == MPI_SUCCESS)) fprintf (stderr, "(%d): ", proclocnum); else fprintf (stderr, ": "); #else /* SCOTCH_PTSCOTCH */ if (_SCOTCHerrorProgName[0] != '\0') fprintf (stderr, ": "); #endif /* SCOTCH_PTSCOTCH */ fprintf (stderr, "ERROR: "); va_start (errlist, errstr); vfprintf (stderr, errstr, errlist); /* Print arguments */ va_end (errlist); fprintf (stderr, "\n"); fflush (stderr); /* In case it has been set to buffered mode */ #ifdef SCOTCH_ERROR_SLEEP sleep (SCOTCH_ERROR_SLEEP); /* Wait for messages to be propagated */ #endif /* SCOTCH_ERROR_SLEEP */ exit (1); } /* This routine prints a warning message with ** a variable number of arguments, as printf () ** does. ** It returns: ** - VOID : in all cases. */ void SCOTCH_errorPrintW ( const char * const errstr, /*+ printf-like variable argument list */ ...) { va_list errlist; /* The argument list of the call */ #ifdef SCOTCH_PTSCOTCH int proclocnum; #endif /* SCOTCH_PTSCOTCH */ fprintf (stderr, "%s", _SCOTCHerrorProgName); #ifdef SCOTCH_PTSCOTCH if ((MPI_Initialized (&proclocnum) == MPI_SUCCESS) && (proclocnum != 0) && (MPI_Comm_rank (MPI_COMM_WORLD, &proclocnum) == MPI_SUCCESS)) fprintf (stderr, "(%d): ", proclocnum); else fprintf (stderr, ": "); #else /* SCOTCH_PTSCOTCH */ if (_SCOTCHerrorProgName[0] != '\0') fprintf (stderr, ": "); #endif /* SCOTCH_PTSCOTCH */ fprintf (stderr, "WARNING: "); va_start (errlist, errstr); vfprintf (stderr, errstr, errlist); /* Print arguments */ va_end (errlist); fprintf (stderr, "\n"); fflush (stderr); /* In case it has been set to buffered mode */ } scotch-6.0.4.dfsg/src/libscotch/bdgraph_bipart_bd.c0000644002563400244210000005357612400671305025431 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2010,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bdgraph_bipart_bd.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module computes a bipartition of **/ /** the given distributed separator graph **/ /** by creating a band graph of given witdh **/ /** around the current frontier, computing **/ /** an improved bipartition of the band **/ /** graph, and projecting back the obtained **/ /** frontier to the original graph. **/ /** **/ /** DATES : # Version 5.1 : from : 11 nov 2007 **/ /** to : 14 apr 2011 **/ /** # Version 6.0 : from : 11 sep 2011 **/ /** to : 31 aug 2014 **/ /** **/ /** NOTES : # Since only edges from local vertices **/ /** to local anchors are created in **/ /** dgraphBand(), the communication const **/ /** might be wrong if a local vertex of **/ /** the last layer is linked to a remote **/ /** vertex of different part which was **/ /** not in the band graph. Hence, commun- **/ /** ication costs have to be recomputed **/ /** from scratch. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define BDGRAPH_BIPART_BD #include "module.h" #include "common.h" #include "parser.h" #include "arch.h" #include "dgraph.h" #include "dgraph_halo.h" #include "bdgraph.h" #include "bdgraph_bipart_bd.h" #include "bdgraph_bipart_st.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine computes a distributed band graph ** of given width around the current frontier and ** applies distributed bipartitioning routines to it. ** The distributed graph is not guaranteed to be ** balanced at at all. ** It returns: ** - 0 : if the distributed band graph could be computed. ** - !0 : on error. */ int bdgraphBipartBd ( Bdgraph * const orggrafptr, /*+ Distributed graph +*/ const BdgraphBipartBdParam * const paraptr) /*+ Method parameters +*/ { Bdgraph bndgrafdat; /* Bipartitioning band graph structure */ Gnum bndvertancnnd; /* End of local vertex array, without anchors */ Gnum bndvertlocnbr1; /* Number of band graph vertices in part 1 except anchor 1 */ Gnum bndvertlocnum; Gnum bndvertlvlnum; /* Based number of first band vertex in last layer */ Gnum bndvertlocancadj; /* Flag set when anchor(s) represent unexistent vertices */ Gnum bndvertglbancadj; /* Global adjustment of anchor vertices */ Gnum bndveexlocsum; /* Local sum of veexloctax array cells for band graph */ Gnum bndveexlocsum0; /* Local sum of veexloctax array cells in part 0 for band graph */ Gnum bndedlolocval; Gnum bndfronlocnum; Gnum orgfronlocnum; int * restrict orgflagloctab; Gnum orgvertlocnum; Gnum orgedlolocval; const int * restrict orgprocsidtab; int orgprocsidnbr; int orgprocsidnum; int orgprocsidval; Gnum complocsizeadj0; Gnum commlocloadintn; Gnum commlocloadintn2; /* Twice twice (4 times) the internal communication load of last layer */ Gnum commlocloadextn; Gnum commlocgainextn; Gnum reduloctab[7]; Gnum reduglbtab[7]; DgraphHaloRequest requdat; if (orggrafptr->fronglbnbr == 0) /* If no separator vertices, apply strategy to full (original) graph */ return (bdgraphBipartSt (orggrafptr, paraptr->stratorg)); if (dgraphBand (&orggrafptr->s, orggrafptr->fronlocnbr, orggrafptr->fronloctab, orggrafptr->partgsttax, orggrafptr->complocload0, orggrafptr->s.velolocsum - orggrafptr->complocload0, paraptr->distmax, &bndgrafdat.s, &bndgrafdat.fronloctab, &bndgrafdat.partgsttax, &bndvertlvlnum, &bndvertlocnbr1, &bndvertlocancadj) != 0) { errorPrint ("bdgraphBipartBd: cannot create band graph"); return (1); } bndvertancnnd = bndgrafdat.s.vertlocnnd - 2; reduloctab[0] = 0; /* Assume no memory allocation problem */ bndveexlocsum = bndveexlocsum0 = 0; bndgrafdat.veexloctax = NULL; /* Assume no external gains */ if (orggrafptr->veexloctax != NULL) { if ((bndgrafdat.veexloctax = memAlloc (bndgrafdat.s.vertlocnbr * sizeof (Gnum))) == NULL) { errorPrint ("bdgraphBipartBd: out of memory (1)"); reduloctab[0] = 1; /* Memory error */ } else { Gnum bndvertlocnum; bndgrafdat.veexloctax -= bndgrafdat.s.baseval; for (bndvertlocnum = bndgrafdat.s.baseval; bndvertlocnum < bndvertancnnd; bndvertlocnum ++) { Gnum veexval; veexval = orggrafptr->veexloctax[bndgrafdat.s.vnumloctax[bndvertlocnum]]; bndgrafdat.veexloctax[bndvertlocnum] = veexval; bndveexlocsum += veexval; bndveexlocsum0 += veexval & (((Gnum) bndgrafdat.partgsttax[bndvertlocnum]) - 1); } } } reduloctab[1] = bndgrafdat.s.vendloctax[bndvertancnnd] - bndgrafdat.s.vertloctax[bndvertancnnd] - (orggrafptr->s.procglbnbr - 1); /* Anchor degrees */ reduloctab[2] = bndgrafdat.s.vendloctax[bndvertancnnd + 1] - bndgrafdat.s.vertloctax[bndvertancnnd + 1] - (orggrafptr->s.procglbnbr - 1); bndgrafdat.complocsize0 = bndgrafdat.s.vertlocnbr - (bndvertlocnbr1 + 1); /* Add 1 for anchor vertex 1 */ complocsizeadj0 = orggrafptr->complocsize0 - bndgrafdat.complocsize0; /* -1 less because of anchor 0 */ reduloctab[3] = bndgrafdat.complocsize0; reduloctab[4] = bndvertlocancadj; /* Sum increases in size and load */ reduloctab[5] = bndveexlocsum; reduloctab[6] = bndveexlocsum0; if (MPI_Allreduce (reduloctab, reduglbtab, 7, GNUM_MPI, MPI_SUM, orggrafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphBipartBd: communication error (1)"); return (1); } if (reduglbtab[0] != 0) { bdgraphExit (&bndgrafdat); return (1); } if ((reduglbtab[1] == 0) || /* If graph is too small to have any usable anchors */ (reduglbtab[2] == 0)) { bdgraphExit (&bndgrafdat); return (bdgraphBipartSt (orggrafptr, paraptr->stratorg)); } bndvertglbancadj = reduglbtab[4]; bndgrafdat.veexglbsum = orggrafptr->veexglbsum; /* All external gains preserved */ bndgrafdat.fronlocnbr = orggrafptr->fronlocnbr; /* All separator vertices are kept in band graph */ bndgrafdat.fronglbnbr = orggrafptr->fronglbnbr; bndgrafdat.complocload0 = orggrafptr->complocload0 + bndvertlocancadj; /* All loads are kept in band graph */ bndgrafdat.compglbload0 = orggrafptr->compglbload0 + bndvertglbancadj; bndgrafdat.compglbload0min = orggrafptr->compglbload0min + bndvertglbancadj; /* Tilt extrema loads according to adjustments */ bndgrafdat.compglbload0max = orggrafptr->compglbload0max + bndvertglbancadj; bndgrafdat.compglbload0avg = orggrafptr->compglbload0avg + bndvertglbancadj; /* Tilt average load according to adjustments */ bndgrafdat.compglbload0dlt = orggrafptr->compglbload0dlt; bndgrafdat.compglbsize0 = reduglbtab[3]; bndgrafdat.commglbload = orggrafptr->commglbload; bndgrafdat.commglbgainextn = orggrafptr->commglbgainextn; bndgrafdat.commglbloadextn0 = orggrafptr->commglbloadextn0; bndgrafdat.commglbgainextn0 = orggrafptr->commglbgainextn0; bndgrafdat.bbalglbval = orggrafptr->bbalglbval; bndgrafdat.domndist = orggrafptr->domndist; bndgrafdat.domnwght[0] = orggrafptr->domnwght[0]; bndgrafdat.domnwght[1] = orggrafptr->domnwght[1]; bndgrafdat.levlnum = orggrafptr->levlnum; if (bndgrafdat.veexloctax != NULL) { Gnum bndveexglbanc0; Gnum bndveexglbanc1; bndveexglbanc0 = (orggrafptr->veexglbsum + orggrafptr->commglbgainextn) / 2 - reduglbtab[6]; /* Compute global external gains of anchors */ bndveexglbanc1 = (orggrafptr->veexglbsum - bndveexglbanc0) - reduglbtab[5]; bndgrafdat.veexloctax[bndvertancnnd] = DATASIZE (bndveexglbanc0, bndgrafdat.s.procglbnbr, bndgrafdat.s.proclocnum); /* Spread gains across local anchors */ bndgrafdat.veexloctax[bndvertancnnd + 1] = DATASIZE (bndveexglbanc1, bndgrafdat.s.procglbnbr, bndgrafdat.s.proclocnum); } #ifdef SCOTCH_DEBUG_BDGRAPH2 if (bdgraphCheck (&bndgrafdat) != 0) { errorPrint ("bdgraphBipartBd: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_BDGRAPH2 */ if (bdgraphBipartSt (&bndgrafdat, paraptr->stratbnd) != 0) { /* Separate distributed band graph */ errorPrint ("bdgraphBipartBd: cannot separate band graph"); bdgraphExit (&bndgrafdat); return (1); } reduloctab[0] = (Gnum) bndgrafdat.partgsttax[bndvertancnnd]; /* Check if anchor vertices remain in their parts */ reduloctab[1] = (Gnum) bndgrafdat.partgsttax[bndvertancnnd + 1]; reduloctab[2] = complocsizeadj0; reduloctab[3] = 0; /* Assume memory allocation is all right */ if ((orgflagloctab = memAlloc (flagSize (orggrafptr->s.vertlocnnd) * sizeof (int))) == NULL) { /* Eventually keep space for based indices */ errorPrint ("bdgraphBipartBd: out of memory (2)"); reduloctab[3] = 1; } if (MPI_Allreduce (&reduloctab[0], &reduglbtab[0], 4, GNUM_MPI, MPI_SUM, orggrafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphBipartBd: communication error (2)"); return (1); } if (((reduglbtab[0] + reduglbtab[1]) != orggrafptr->s.procglbnbr) || /* If not all anchors of initial same parts in same parts */ ((reduglbtab[0] != 0) && (reduglbtab[0] != orggrafptr->s.procglbnbr)) || (reduglbtab[3] != 0)) { if (orgflagloctab != NULL) memFree (orgflagloctab); bdgraphExit (&bndgrafdat); /* Apply original strategy to full graph */ return (bdgraphBipartSt (orggrafptr, paraptr->stratorg)); } if (dgraphGhst (&bndgrafdat.s) != 0) { /* Compute ghost edge array if not already present */ errorPrint ("bdgraphBipartBd: cannot compute ghost edge array"); return (1); } if (reduglbtab[0] == orggrafptr->s.procglbnbr) { /* If all anchors swapped parts, swap all parts of original vertices */ Gnum orgvertnum; orggrafptr->complocsize0 = orggrafptr->s.vertlocnbr - reduloctab[2] - bndgrafdat.s.vertlocnbr + bndgrafdat.complocsize0; orggrafptr->compglbsize0 = orggrafptr->s.vertglbnbr - reduglbtab[2] - bndgrafdat.s.vertglbnbr + bndgrafdat.compglbsize0; for (orgvertnum = orggrafptr->s.baseval; orgvertnum < orggrafptr->s.vertlocnnd; orgvertnum ++) orggrafptr->partgsttax[orgvertnum] ^= 1; } else { orggrafptr->complocsize0 = reduloctab[2] + bndgrafdat.complocsize0; orggrafptr->compglbsize0 = reduglbtab[2] + bndgrafdat.compglbsize0; } for (bndvertlocnum = bndgrafdat.s.baseval; bndvertlocnum < bndvertancnnd; bndvertlocnum ++) /* Update part array of all vertices except anchors */ orggrafptr->partgsttax[bndgrafdat.s.vnumloctax[bndvertlocnum]] = bndgrafdat.partgsttax[bndvertlocnum]; dgraphHaloAsync (&orggrafptr->s, (byte *) (orggrafptr->partgsttax + orggrafptr->s.baseval), GRAPHPART_MPI, &requdat); /* Share part array of full graph */ commlocloadintn = commlocloadextn = commlocgainextn = 0; bndedlolocval = 1; /* Assume no edge loads */ for (bndvertlocnum = bndgrafdat.s.baseval; bndvertlocnum < bndvertlvlnum; bndvertlocnum ++) { /* For all vertices of band graph save for last layer */ Gnum bndedgelocnum; Gnum bndedgelocnnd; Gnum bndpartval; bndpartval = (Gnum) bndgrafdat.partgsttax[bndvertlocnum]; if (bndgrafdat.veexloctax != NULL) { commlocloadextn += bndgrafdat.veexloctax[bndvertlocnum] * bndpartval; commlocgainextn += bndgrafdat.veexloctax[bndvertlocnum] * (1 - bndpartval * 2); } for (bndedgelocnum = bndgrafdat.s.vertloctax[bndvertlocnum], bndedgelocnnd = bndgrafdat.s.vendloctax[bndvertlocnum]; bndedgelocnum < bndedgelocnnd; bndedgelocnum ++) { Gnum bndvertlocend; Gnum bndpartend; bndvertlocend = bndgrafdat.s.edgegsttax[bndedgelocnum]; bndpartend = bndgrafdat.partgsttax[bndvertlocend]; if (bndgrafdat.s.edloloctax != NULL) bndedlolocval = bndgrafdat.s.edloloctax[bndedgelocnum]; commlocloadintn += (bndpartval ^ bndpartend) * bndedlolocval; /* Internal load is accounted for twice */ } } for ( ; bndvertlocnum < bndvertancnnd; bndvertlocnum ++) { /* For all vertices of last layer, remove internal loads to band vertices once */ Gnum bndedgelocnum; Gnum bndedgelocnnd; Gnum bndpartval; bndpartval = (Gnum) bndgrafdat.partgsttax[bndvertlocnum]; if (bndgrafdat.veexloctax != NULL) { commlocloadextn += bndgrafdat.veexloctax[bndvertlocnum] * bndpartval; commlocgainextn += bndgrafdat.veexloctax[bndvertlocnum] * (1 - bndpartval * 2); } for (bndedgelocnum = bndgrafdat.s.vertloctax[bndvertlocnum], bndedgelocnnd = bndgrafdat.s.vendloctax[bndvertlocnum] - 1; /* "-1" to avoid anchor edges */ bndedgelocnum < bndedgelocnnd; bndedgelocnum ++) { Gnum bndvertlocend; Gnum bndpartend; bndvertlocend = bndgrafdat.s.edgegsttax[bndedgelocnum]; bndpartend = bndgrafdat.partgsttax[bndvertlocend]; if (bndgrafdat.s.edloloctax != NULL) bndedlolocval = bndgrafdat.s.edloloctax[bndedgelocnum]; commlocloadintn -= (bndpartval ^ bndpartend) * bndedlolocval; /* Remove internal loads to band graph vertices once because afterwards they will be accounted for twice */ } } memSet (orgflagloctab, 0, flagSize (orggrafptr->s.vertlocnnd) * sizeof (int)); /* Set vertices as not already considered */ for (bndfronlocnum = orgfronlocnum = 0; bndfronlocnum < bndgrafdat.fronlocnbr; bndfronlocnum ++) { /* Project back separator except for last layer */ Gnum bndvertlocnum; bndvertlocnum = bndgrafdat.fronloctab[bndfronlocnum]; if (bndvertlocnum < bndvertlvlnum) { /* If vertex does not belong to last layer */ Gnum orgvertlocnum; orgvertlocnum = bndgrafdat.s.vnumloctax[bndvertlocnum]; flagSet (orgflagloctab, orgvertlocnum); /* Set vertex as processed */ orggrafptr->fronloctab[orgfronlocnum ++] = orgvertlocnum; } } if (dgraphHaloWait (&requdat) != 0) { errorPrint ("bdgraphBipartBd: cannot complete asynchronous halo exchange"); return (1); } orgedlolocval = 1; /* Assume no edge loads */ commlocloadintn2 = 0; for (bndvertlocnum = bndvertlvlnum; bndvertlocnum < bndvertancnnd; bndvertlocnum ++) { /* For all vertices of last layer */ Gnum orgedgelocnum; Gnum orgedgelocnnd; Gnum orgvertlocnum; GraphPart orgpartval; Gnum orgflagval; orgvertlocnum = bndgrafdat.s.vnumloctax[bndvertlocnum]; orgpartval = bndgrafdat.partgsttax[bndvertlocnum]; orgflagval = 0; /* Assume vertex does not belong to the frontier */ for (orgedgelocnum = orggrafptr->s.vertloctax[orgvertlocnum], orgedgelocnnd = orggrafptr->s.vendloctax[orgvertlocnum]; orgedgelocnum < orgedgelocnnd; orgedgelocnum ++) { Gnum orgvertlocend; Gnum orgpartend; Gnum orgflagtmp; orgvertlocend = orggrafptr->s.edgegsttax[orgedgelocnum]; orgpartend = orggrafptr->partgsttax[orgvertlocend]; orgflagtmp = orgpartval ^ orgpartend; if (bndgrafdat.s.edloloctax != NULL) orgedlolocval = orggrafptr->s.edloloctax[orgedgelocnum]; orgflagval |= orgflagtmp; commlocloadintn2 += orgflagtmp * orgedlolocval; /* Internal load to band and original graph vertices are accounted for twice */ if ((orgflagtmp != 0) && (orgvertlocend < orggrafptr->s.vertlocnnd) && (flagVal (orgflagloctab, orgvertlocend) == 0)) { orggrafptr->fronloctab[orgfronlocnum ++] = orgvertlocend; flagSet (orgflagloctab, orgvertlocend); } } if ((orgflagval != 0) && (flagVal (orgflagloctab, orgvertlocnum) == 0)) orggrafptr->fronloctab[orgfronlocnum ++] = orgvertlocnum; flagSet (orgflagloctab, orgvertlocnum); /* Set vertex as processed anyway */ } commlocloadintn += 2 * commlocloadintn2; /* Add twice the internal load of original graph edges and once the one of band edges (one removed before) */ orggrafptr->complocload0 = bndgrafdat.complocload0 - bndvertlocancadj; orggrafptr->compglbload0 = bndgrafdat.compglbload0 - bndvertglbancadj; orggrafptr->compglbload0dlt = orggrafptr->compglbload0 - orggrafptr->compglbload0avg; orgprocsidnbr = orggrafptr->s.procsidnbr; if (orgprocsidnbr == 0) goto loop_exit; orgvertlocnum = orggrafptr->s.baseval; orgprocsidnum = 0; orgprocsidtab = orggrafptr->s.procsidtab; orgprocsidval = orgprocsidtab[orgprocsidnum ++]; while (1) { /* Scan all vertices which have foreign neighbors */ while (orgprocsidval < 0) { orgvertlocnum -= (Gnum) orgprocsidval; orgprocsidval = orgprocsidtab[orgprocsidnum ++]; } if (flagVal (orgflagloctab, orgvertlocnum) == 0) { /* If vertex not already processed */ Gnum orgedgelocnum; Gnum orgedgelocnnd; GraphPart orgpartval; orgpartval = orggrafptr->partgsttax[orgvertlocnum]; for (orgedgelocnum = orggrafptr->s.vertloctax[orgvertlocnum], orgedgelocnnd = orggrafptr->s.vendloctax[orgvertlocnum]; orgedgelocnum < orgedgelocnnd; orgedgelocnum ++) { if (orggrafptr->partgsttax[orggrafptr->s.edgegsttax[orgedgelocnum]] != orgpartval) { orggrafptr->fronloctab[orgfronlocnum ++] = orgvertlocnum; break; } } } do { if (orgprocsidnum >= orgprocsidnbr) goto loop_exit; } while ((orgprocsidval = orgprocsidtab[orgprocsidnum ++]) >= 0); } loop_exit : memFree (orgflagloctab); reduloctab[0] = commlocloadintn; /* Twice the internal load; sum globally before dividing by two */ reduloctab[1] = commlocloadextn; reduloctab[2] = commlocgainextn; reduloctab[3] = orgfronlocnum; if (MPI_Allreduce (&reduloctab[0], &reduglbtab[0], 4, GNUM_MPI, MPI_SUM, orggrafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphBipartBd: communication error (3)"); return (1); } orggrafptr->fronlocnbr = orgfronlocnum; orggrafptr->fronglbnbr = reduglbtab[3]; orggrafptr->commglbload = (reduglbtab[0] / 2) * orggrafptr->domndist + reduglbtab[1]; orggrafptr->commglbgainextn = reduglbtab[2]; orggrafptr->bbalglbval = (double) ((orggrafptr->compglbload0dlt < 0) ? (- orggrafptr->compglbload0dlt) : orggrafptr->compglbload0dlt) / (double) orggrafptr->compglbload0avg; #ifdef SCOTCH_DEBUG_BDGRAPH2 if (bdgraphCheck (orggrafptr) != 0) { errorPrint ("bdgraphBipartBd: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_BDGRAPH2 */ bdgraphExit (&bndgrafdat); return (0); } scotch-6.0.4.dfsg/src/libscotch/library_dgraph_build_grid3d.c0000644002563400244210000000757412055776035027431 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_build_grid3d.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Cedric CHEVALIER (v5.0) **/ /** **/ /** FUNCTION : These lines are the distributed source **/ /** graph building routines for 3D grid **/ /** graphs. **/ /** **/ /** DATES : # Version 5.0 : from : 21 jul 2005 **/ /** to : 10 sep 2007 **/ /** # Version 5.1 : from : 05 jun 2010 **/ /** to : 06 jun 2010 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ #define LIBRARY #include "module.h" #include "common.h" #include "dgraph.h" #include "ptscotch.h" /************************************/ /* */ /* These routines are the C API for */ /* the graph handling routines. */ /* */ /************************************/ /*+ This routine builds a distributed *** 3D grid or torus graph structure. *** It returns: *** - 0 : if the creation succeeded. *** - !0 : on error. +*/ int SCOTCH_dgraphBuildGrid3D ( SCOTCH_Dgraph * const grafptr, const SCOTCH_Num baseval, /* Base value */ const SCOTCH_Num dimx, /* First dimension */ const SCOTCH_Num dimy, /* Second dimension */ const SCOTCH_Num dimz, /* Third dimension */ const SCOTCH_Num incrval, /* Increment value */ const int flagval) /* Flag value */ { return (dgraphBuildGrid3D ((Dgraph *) grafptr, baseval, dimx, dimy, dimz, incrval, flagval)); } scotch-6.0.4.dfsg/src/libscotch/bgraph_bipart_zr.h0000644002563400244210000000570611631447170025336 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bgraph_bipart_zr.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a static mapper. **/ /** These lines are the data declarations **/ /** for the move-all-to-first-subdomain **/ /** bipartitioning module. **/ /** **/ /** DATES : # Version 3.2 : from : 23 aug 1996 **/ /** to 19 oct 1996 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 4.0 : from : 01 nov 2003 **/ /** to 01 nov 2003 **/ /** **/ /************************************************************/ /* ** The function prototypes. */ #ifndef BGRAPH_BIPART_ZR #define static #endif int bgraphBipartZr (Bgraph * restrict const); #undef static scotch-6.0.4.dfsg/src/libscotch/dgraph_gather.c0000644002563400244210000001300611631447170024601 0ustar trophimeutilisateurs du domaine/* Copyright 2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_gather.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** Francois CHATENET (0.0) **/ /** Sebastien FOUCAULT (0.0) **/ /** **/ /** FUNCTION : This module contains the routine which **/ /** builds a centralized graph by gathering **/ /** the pieces of a distributed graph. **/ /** **/ /** DATES : # Version 0.0 : from : 01 apr 1997 **/ /** to : 20 jun 1997 **/ /** # Version 0.1 : from : 14 apr 1998 **/ /** to : 20 jun 1998 **/ /** # Version 0.2 : from : 20 may 1999 **/ /** to : 20 may 1999 **/ /** # Version 5.0 : from : 07 feb 2006 **/ /** to : 16 jul 2007 **/ /** **/ /** NOTES : # The definitions of MPI_Gather and **/ /** MPI_Gatherv indicate that elements in **/ /** the receive array should not be **/ /** written more than once. Great care **/ /** should be taken to enforce this rule, **/ /** especially when the number of **/ /** vertices in the centralized graph is **/ /** smaller than the number of **/ /** processors. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DGRAPH_GATHER #include "module.h" #include "common.h" #include "graph.h" #include "dgraph.h" /* This function gathers the pieces of ** a distributed graph to build a ** centralized graph. ** It returns: ** - 0 : if graph data are consistent. ** - !0 : on error. */ int dgraphGather ( const Dgraph * restrict const dgrfptr, /* Distributed graph */ Graph * restrict cgrfptr) /* Centralized graph */ { Gnum reduloctab[3]; Gnum reduglbtab[3]; if (dgrfptr->edloloctax == NULL) /* Compute sum of edge loads */ reduloctab[2] = dgrfptr->edgelocnbr; else { Gnum vertlocnum; Gnum edlolocsum; for (vertlocnum = dgrfptr->baseval, edlolocsum = 0; vertlocnum < dgrfptr->vertlocnnd; vertlocnum ++) { Gnum edgelocnum; Gnum edgelocnnd; for (edgelocnum = dgrfptr->vertloctax[vertlocnum], edgelocnnd = dgrfptr->vendloctax[vertlocnum]; edgelocnum < edgelocnnd; edgelocnum ++) edlolocsum += dgrfptr->edloloctax[edgelocnum]; } reduloctab[2] = edlolocsum; } if (cgrfptr != NULL) { /* If centralized graph provided */ reduloctab[0] = 1; /* This process is the root */ reduloctab[1] = (Gnum) dgrfptr->proclocnum; /* Get its number */ } else { reduloctab[0] = /* This process is not the root */ reduloctab[1] = 0; } if (MPI_Allreduce (reduloctab, reduglbtab, 3, GNUM_MPI, MPI_SUM, dgrfptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphGather: communication error"); return (1); } if (reduglbtab[0] != 1) { errorPrint ("dgraphGather: should have only one root"); return (1); } return (dgraphGatherAll2 (dgrfptr, cgrfptr, reduglbtab[2], (int) reduglbtab[1])); } scotch-6.0.4.dfsg/src/libscotch/library_f.h0000644002563400244210000001252212412035044023751 0ustar trophimeutilisateurs du domaine!* Copyright 2004,2007,2009,2010,2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS !* !* This file is part of the Scotch software package for static mapping, !* graph partitioning and sparse matrix ordering. !* !* This software is governed by the CeCILL-C license under French law !* and abiding by the rules of distribution of free software. You can !* use, modify and/or redistribute the software under the terms of the !* CeCILL-C license as circulated by CEA, CNRS and INRIA at the following !* URL: "http://www.cecill.info". !* !* As a counterpart to the access to the source code and rights to copy, !* modify and redistribute granted by the license, users are provided !* only with a limited warranty and the software's author, the holder of !* the economic rights, and the successive licensors have only limited !* liability. !* !* In this respect, the user's attention is drawn to the risks associated !* with loading, using, modifying and/or developing or reproducing the !* software by the user in light of its specific status of free software, !* that may mean that it is complicated to manipulate, and that also !* therefore means that it is reserved for developers and experienced !* professionals having in-depth computer knowledge. Users are therefore !* encouraged to load and test the software's suitability as regards !* their requirements in conditions enabling the security of their !* systems and/or data to be ensured and, more generally, to use and !* operate it in the same conditions as regards security. !* !* The fact that you are presently reading this means that you have had !* knowledge of the CeCILL-C license and that you accept its terms. !* !*********************************************************** !* ** !* NAME : library_f.h ** !* ** !* AUTHOR : Francois PELLEGRINI ** !* ** !* FUNCTION : FORTRAN declaration file for the ** !* LibScotch static mapping and sparse ** !* matrix block ordering sequential ** !* library. ** !* ** !* DATES : # Version 3.4 : from : 04 feb 2000 ** !* to 22 oct 2001 ** !* # Version 4.0 : from : 16 jan 2004 ** !* to 16 jan 2004 ** !* # Version 5.0 : from : 26 apr 2006 ** !* to 26 apr 2006 ** !* # Version 5.1 : from : 26 mar 2009 ** !* to 12 feb 2011 ** !* # Version 6.0 : from : 22 oct 2011 ** !* to 28 sep 2014 ** !* ** !*********************************************************** !* Flag definitions for the coarsening !* routines. INTEGER SCOTCH_COARSENNONE INTEGER SCOTCH_COARSENFOLD INTEGER SCOTCH_COARSENFOLDDUP INTEGER SCOTCH_COARSENNOMERGE PARAMETER (SCOTCH_COARSENNONE = 0) PARAMETER (SCOTCH_COARSENFOLD = 4096) PARAMETER (SCOTCH_COARSENFOLDDUP = 12288) PARAMETER (SCOTCH_COARSENNOMERGE = 16384) !* Flag definitions for the strategy !* string selection routines. INTEGER SCOTCH_STRATDEFAULT INTEGER SCOTCH_STRATQUALITY INTEGER SCOTCH_STRATSPEED INTEGER SCOTCH_STRATBALANCE INTEGER SCOTCH_STRATSAFETY INTEGER SCOTCH_STRATSCALABILITY INTEGER SCOTCH_STRATRECURSIVE INTEGER SCOTCH_STRATREMAP INTEGER SCOTCH_STRATLEVELMAX INTEGER SCOTCH_STRATLEVELMIN INTEGER SCOTCH_STRATLEAFSIMPLE INTEGER SCOTCH_STRATSEPASIMPLE PARAMETER (SCOTCH_STRATDEFAULT = 0) PARAMETER (SCOTCH_STRATQUALITY = 1) PARAMETER (SCOTCH_STRATSPEED = 2) PARAMETER (SCOTCH_STRATBALANCE = 4) PARAMETER (SCOTCH_STRATSAFETY = 8) PARAMETER (SCOTCH_STRATSCALABILITY = 16) PARAMETER (SCOTCH_STRATRECURSIVE = 256) PARAMETER (SCOTCH_STRATREMAP = 512) PARAMETER (SCOTCH_STRATLEVELMAX = 4096) PARAMETER (SCOTCH_STRATLEVELMIN = 8192) PARAMETER (SCOTCH_STRATLEAFSIMPLE = 16384) PARAMETER (SCOTCH_STRATSEPASIMPLE = 32768) !* Size definitions for the SCOTCH opaque !* structures. These structures must be !* allocated as arrays of DOUBLEPRECISION !* values for proper padding. The dummy !* sizes are computed at compile-time by !* program "dummysizes". INTEGER SCOTCH_ARCHDIM INTEGER SCOTCH_GEOMDIM INTEGER SCOTCH_GRAPHDIM INTEGER SCOTCH_MAPDIM INTEGER SCOTCH_MESHDIM INTEGER SCOTCH_ORDERDIM INTEGER SCOTCH_STRATDIM PARAMETER (SCOTCH_ARCHDIM = DUMMYSIZEARCH) PARAMETER (SCOTCH_GEOMDIM = DUMMYSIZEGEOM) PARAMETER (SCOTCH_GRAPHDIM = DUMMYSIZEGRAPH) PARAMETER (SCOTCH_MAPDIM = DUMMYSIZEMAP) PARAMETER (SCOTCH_MESHDIM = DUMMYSIZEMESH) PARAMETER (SCOTCH_ORDERDIM = DUMMYSIZEORDER) PARAMETER (SCOTCH_STRATDIM = DUMMYSIZESTRAT) scotch-6.0.4.dfsg/src/libscotch/graph_io_mmkt.c0000644002563400244210000003050611631447171024627 0ustar trophimeutilisateurs du domaine/* Copyright 2008,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : graph_io_mmkt.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** Cedric CHEVALIER (v5.0) **/ /** **/ /** FUNCTION : This module contains the input/output **/ /** routines for handling the Matrix Market **/ /** format. **/ /** **/ /** DATES : # Version 5.0 : from : 17 jan 2008 **/ /** to : 21 mar 2008 **/ /** # Version 5.1 : from : 27 apr 2010 **/ /** to : 11 aug 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GRAPH_IO_MMKT #include "module.h" #include "common.h" #include "geom.h" #include "graph.h" #include "graph_io_mmkt.h" /********************************************************/ /* */ /* These routines handle source Matrix Market matrices. */ /* */ /********************************************************/ /* This routine loads a source graph from ** the given stream, corresponding to a MatrixMarket file. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int graphGeomLoadMmkt ( Graph * restrict const grafptr, /* Graph to load */ Geom * restrict const geomptr, /* Geometry to load */ FILE * const filesrcptr, /* Topological data */ FILE * const filegeoptr, /* No use */ const char * const dataptr) /* Fake base value */ { Gnum baseval; Gnum mrownbr; Gnum mcolnbr; Gnum linenbr; Gnum linenum; Gnum vertnum; Gnum verttmp; GraphGeomMmktEdge * sorttab; Gnum sortnbr; Gnum sortnum; Gnum * edgetax; Gnum edgenum; Gnum edgetmp; Gnum degrmax; char linetab[1025]; char * lineptr; char c; baseval = 1; /* Regular MatrixMarket indices start from 1 */ if ((dataptr != NULL) && /* If base value provided */ (dataptr[0] != '\0') && ((baseval = (Gnum) atol (dataptr)) == 0) && /* Get base value */ (dataptr[0] != '0')) { errorPrint ("graphGeomLoadMmkt: invalid parameter"); return (1); } if (fgets (linetab, 1025, filesrcptr) == NULL) { /* Read header lines */ errorPrint ("graphGeomLoadMmkt: bad input (1)"); return (1); } if (strncmp (linetab, "%%MatrixMarket", 14) != 0) { errorPrint ("graphGeomLoadMmkt: invalid header"); return (1); } for (lineptr = linetab + 14; *lineptr != '\0'; lineptr ++) *lineptr = tolower (*lineptr); if (strstr (linetab + 14, "matrix") == NULL) { errorPrint ("graphGeomLoadMmkt: only matrix types supported"); return (1); } while ((c = fgetc (filesrcptr)) == '%') { /* Skip additional comment lines */ if (fgets (linetab, 1025, filesrcptr) == NULL) { errorPrint ("graphGeomLoadMmkt: bad input (2)"); return (1); } } ungetc (c, filesrcptr); if ((intLoad (filesrcptr, &mrownbr) != 1) || /* Read number of rows */ (intLoad (filesrcptr, &mcolnbr) != 1) || /* Read number of columns */ (intLoad (filesrcptr, &linenbr) != 1)) { /* Read number of lines */ errorPrint ("graphGeomLoadMmkt: bad input (3)"); return (1); } if (mrownbr != mcolnbr) { /* If not a square matrix */ errorPrint ("graphGeomLoadMmkt: not a square matrix"); return (1); } memSet (grafptr, 0, sizeof (Graph)); grafptr->flagval = GRAPHFREETABS | GRAPHVERTGROUP | GRAPHEDGEGROUP; grafptr->baseval = baseval; grafptr->vertnbr = mrownbr; grafptr->vertnnd = grafptr->vertnbr + baseval; if ((grafptr->verttax = memAlloc ((grafptr->vertnbr + 1) * sizeof (Gnum))) == NULL) { errorPrint ("graphGeomLoadMmkt: out of memory (1)"); graphExit (grafptr); return (1); } grafptr->verttax -= baseval; grafptr->vendtax = grafptr->verttax + 1; grafptr->velosum = grafptr->vertnbr; if ((sorttab = (GraphGeomMmktEdge *) memAlloc (2 * linenbr * sizeof (GraphGeomMmktEdge))) == NULL) { /* Twice the space for symmetric edges */ errorPrint ("graphGeomLoadMmkt: out of memory (2)"); graphExit (grafptr); return (1); } grafptr->edgetax = ((Gnum *) sorttab) - baseval; /* TRICK: will be freed if graph is freed */ for (linenum = sortnbr = 0; linenum < linenbr; linenum ++) { if ((intLoad (filesrcptr, &sorttab[sortnbr].vertnum[0]) != 1) || /* Read edge ends */ (intLoad (filesrcptr, &sorttab[sortnbr].vertnum[1]) != 1) || (fgets (linetab, 1025, filesrcptr) == NULL)) { /* Skip end of line */ errorPrint ("graphGeomLoadMmkt: bad input (4)"); graphExit (grafptr); return (1); } if ((sorttab[sortnbr].vertnum[0] < baseval) || (sorttab[sortnbr].vertnum[0] >= (mrownbr + baseval)) || (sorttab[sortnbr].vertnum[1] < baseval) || (sorttab[sortnbr].vertnum[1] >= (mrownbr + baseval))) { errorPrint ("graphGeomLoadMmkt: bad input (5)"); graphExit (grafptr); return (1); } if (sorttab[sortnbr].vertnum[0] != sorttab[sortnbr].vertnum[1]) { /* If not loop edge */ sorttab[sortnbr + 1].vertnum[0] = sorttab[sortnbr].vertnum[1]; /* Add symmetric edge */ sorttab[sortnbr + 1].vertnum[1] = sorttab[sortnbr].vertnum[0]; sortnbr += 2; } } intSort2asc2 (sorttab, sortnbr); /* Sort edges by increasing indices */ edgetax = grafptr->edgetax; /* TRICK: point to beginning of sorted edge array for re-use */ for (sortnum = degrmax = 0, vertnum = baseval - 1, edgetmp = edgenum = baseval; sortnum < sortnbr; sortnum ++) { Gnum vertend; if (vertnum < sorttab[sortnum].vertnum[0]) { /* If change of vertex index, that is, first edge end */ edgetmp = edgenum - edgetmp; /* Compute degree and see if it is maximum degree */ if (edgetmp > degrmax) degrmax = edgetmp; edgetmp = edgenum; grafptr->verttax[++ vertnum] = edgenum; /* Set beginning of new edge sub-array */ while (vertnum < sorttab[sortnum].vertnum[0]) /* Fill gaps with isolated vertices */ grafptr->verttax[++ vertnum] = edgenum; verttmp = baseval - 1; /* Make sure next edge will be considered as never seen before */ } vertend = sorttab[sortnum].vertnum[1]; /* Get end of current edge */ if (vertend != verttmp) /* If edge differs from previous one */ edgetax[edgenum ++] = verttmp = vertend; /* Add it to array and prevent duplicates */ } edgetmp = edgenum - edgetmp; /* Compute degree and see if it is maximum degree */ if (edgetmp > degrmax) degrmax = edgetmp; while (vertnum < mrownbr) /* Fill gaps with isolated vertices and mark beginning of new one */ grafptr->verttax[++ vertnum] = edgenum; grafptr->verttax[++ vertnum] = edgenum; /* Mark end of array */ #ifdef SCOTCH_DEBUG_GRAPH2 if (vertnum != grafptr->vertnnd) { errorPrint ("graphGeomLoadMmkt: internal error (1)"); graphExit (grafptr); return (1); } #endif /* SCOTCH_DEBUG_GRAPH2 */ grafptr->edgenbr = edgenum - baseval; grafptr->edgetax = ((Gnum *) memRealloc (edgetax + baseval, grafptr->edgenbr * sizeof (Gnum))) - baseval; /* TRICK: keep only useful space in re-used array */ grafptr->edlotax = NULL; grafptr->edlosum = grafptr->edgenbr; grafptr->degrmax = degrmax; #ifdef SCOTCH_DEBUG_GRAPH2 if (graphCheck (grafptr) != 0) { /* Check graph consistency */ errorPrint ("graphGeomLoadMmkt: internal error (2)"); graphExit (grafptr); return (1); } #endif /* SCOTCH_DEBUG_GRAPH2 */ return (0); } /* This routine saves the geometrical graph ** in the Matrix Market symmetric graph format. ** It returns: ** - 0 : on succes ** - !0 : on error. */ int graphGeomSaveMmkt ( const Graph * restrict const grafptr, /* Graph to save */ const Geom * restrict const geomptr, /* Geometry to save */ FILE * const filesrcptr, /* Topological data */ FILE * const filegeoptr, /* No use */ const char * const dataptr) /* No use */ { Gnum baseadj; /* Base adjustment */ Gnum vertnum; /* Current vertex */ Gnum edgenum; /* Current edge */ int o; baseadj = 1 - grafptr->baseval; /* Output base is always 1 */ o = (fprintf (filesrcptr, "%%%%MatrixMarket matrix coordinate pattern symmetric\n%% Produced by Scotch graphGeomSaveMmkt\n" GNUMSTRING " " GNUMSTRING " " GNUMSTRING "\n", /* Write graph header */ (Gnum) grafptr->vertnbr, (Gnum) grafptr->vertnbr, (Gnum) ((grafptr->edgenbr / 2) + grafptr->vertnbr)) == EOF); for (vertnum = grafptr->baseval; (o == 0) && (vertnum < grafptr->vertnnd); vertnum ++) { Gnum vlblnum; /* Vertex label to output */ vlblnum = ((grafptr->vlbltax != NULL) ? grafptr->vlbltax[vertnum] : vertnum) + baseadj; if (fprintf (filesrcptr, GNUMSTRING " " GNUMSTRING "\n", /* Write diagonal term */ (Gnum) vlblnum, (Gnum) vlblnum) < 0) { o = 1; break; } for (edgenum = grafptr->verttax[vertnum]; edgenum < grafptr->vendtax[vertnum]; edgenum ++) { Gnum vlblend; /* End vertex label to output */ vlblend = grafptr->edgetax[edgenum]; if (grafptr->vlbltax != NULL) vlblend = grafptr->vlbltax[vlblend]; vlblend += baseadj; if (vlblend < vlblnum) { if (fprintf (filesrcptr, GNUMSTRING " " GNUMSTRING "\n", (Gnum) vlblnum, (Gnum) vlblend) < 0) { o = 1; break; } } } } if (o != 0) errorPrint ("graphGeomSaveMmkt: bad output"); return (o); } scotch-6.0.4.dfsg/src/libscotch/kgraph_map_df.h0000644002563400244210000001356412045043544024577 0ustar trophimeutilisateurs du domaine/* Copyright 2009-2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph_map_ml.h **/ /** **/ /** AUTHOR : Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module contains the function **/ /** declarations for the diffusion scheme **/ /** k-partitioning method. **/ /** **/ /** DATES : # Version 6.0 : from : 22 dec 2009 **/ /** to 02 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines. */ /* Small non-zero float value. */ #define KGRAPHMAPDFEPSILON (1.0F / (float) (GNUMMAX)) /*+ Sign masking operator. +*/ #define KGRAPHMAPDFGNUMSGNMSK(i) ((Gnum) 0 - (((Gunum) (i)) >> (sizeof (Gnum) * 8 - 1))) /* ** The type and structure definitions. */ /*+ Method parameters. +*/ typedef struct KgraphMapDfParam_ { INT passnbr; /*+ Number of passes to do +*/ double cdifval; /*+ Coefficient of diffused load +*/ double cremval; /*+ Coefficient of remaining load +*/ } KgraphMapDfParam; /*+ The complementary vertex structure. +*/ typedef struct KgraphMapDfVertex_ { Anum partval; /*+ Type of liquid in barrel +*/ float diffval; /*+ Value to be diffused to everybody +*/ float fdifval; /*+ Value to be diffused to other parts for mapping +*/ float mdisval; /*+ Value to be diffused to vertnum if parotax[vertnum] == partval +*/ float mdidval; /*= Value to be diffused to vertnum else +*/ } KgraphMapDfVertex; /*+ The sort structure. +*/ typedef struct KgraphMapDfSort_ { Anum partval; /*+ Type of liquid in barrel +*/ float diffval; /*+ Value to be diffused +*/ Anum distval; /*+ Distance value +*/ Gnum edlosum; /*+ Sum of edge loads +*/ } KgraphMapDfSort; /*+ The loop routine parameter structure. It contains the thread-independent data. +*/ typedef struct KgraphMapDfData_ { ThreadGroupHeader thrddat; const Kgraph * grafptr; /*+ Graph to work on +*/ float * vanctab; float * valotab; /*+ Fraction of load to leak +*/ Gnum * velstax; /*+ Vertex edge load sum array +*/ KgraphMapDfVertex * difntax; /*+ New diffusion value array +*/ KgraphMapDfVertex * difotax; /*+ Old diffusion value array +*/ int passnbr; /*+ Number of passes +*/ #ifdef KGRAPHMAPDFTHREAD int abrtval; /*+ Abort value +*/ #endif /* KGRAPHMAPDFTHREAD */ } KgraphMapDfData; /*+ The thread-specific data block. +*/ typedef struct KgraphMapDfThread_ { ThreadHeader thrddat; /*+ Thread management data +*/ Gnum vertbas; /*+ Minimum regular vertex index +*/ Gnum vertnnd; /*+ After-last regular vertex index +*/ Anum domnbas; /*+ Minimum anchor vertex index +*/ Anum domnnnd; /*+ After-last anchor vertex index +*/ } KgraphMapDfThread; /* ** The function prototypes. */ #ifndef KGRAPH_MAP_DF #define static #endif int kgraphMapDf (Kgraph * restrict const, const KgraphMapDfParam * const); static void kgraphMapDfSort (void * const, const INT); #undef static scotch-6.0.4.dfsg/src/libscotch/library_graph_coarsen.c0000644002563400244210000001344312474554132026351 0ustar trophimeutilisateurs du domaine/* Copyright 2011,2012,2014,2015 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_coarsen.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the graph **/ /** coarsening routine of the libSCOTCH **/ /** library. **/ /** **/ /** DATES : # Version 5.1 : from : 07 aug 2011 **/ /** to 07 aug 2011 **/ /** # Version 6.0 : from : 06 sep 2011 **/ /** to 28 feb 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "arch.h" #include "graph.h" #include "graph_coarsen.h" #include "scotch.h" /*********************************/ /* */ /* This routine is the C API for */ /* the graph coarsening routine. */ /* */ /*********************************/ /*+ This routine creates a coarse graph from the *** given fine graph, unless the coarse graph is *** smaller than some threshold size or the *** coarsening ratio is above some other threshold. *** If the coarse graph is created, a coarse-to-fine *** vertex array is created, that contains a pair of *** fine indices for each coarse index. The contents *** of the Scotch internal array are copied to the *** array provided by the user. *** It returns: *** - 0 : if the graph has been coarsened. *** - 1 : if the graph could not be coarsened. *** - 2 : on error. +*/ int SCOTCH_graphCoarsen ( const SCOTCH_Graph * restrict const finegrafptr, /* Fine graph structure to fill */ SCOTCH_Graph * restrict const coargrafptr, /* Coarse graph */ SCOTCH_Num * restrict const coarmulttab, /* Pointer to multinode array */ const SCOTCH_Num coarnbr, /* Minimum number of coarse vertices */ const double coarval) /* Maximum contraction ratio */ { GraphCoarsenMulti * restrict coarmultptr; /* Un-based pointer to created, grouped multinode array */ int o; intRandInit (); /* Check that random number generator is initialized */ coarmultptr = (GraphCoarsenMulti *) coarmulttab; /* Indicate multinode array is user-provided */ return (graphCoarsen ((const Graph * restrict const) finegrafptr, (Graph * restrict const) coargrafptr, &coarmultptr, coarnbr, coarval, NULL, NULL, 0, NULL)); } /*+ This routine creates a coarse graph from the *** given fine graph and the provided multinode *** array. *** It returns: *** - 0 : if the graph has been coarsened. *** - 1 : on error. +*/ int SCOTCH_graphCoarsenBuild ( const SCOTCH_Graph * restrict const finegrafptr, /* Fine graph structure to fill */ SCOTCH_Graph * restrict const coargrafptr, /* Coarse graph */ SCOTCH_Num * restrict const coarmulttab, /* Pointer to user-provided multinode array */ const SCOTCH_Num coarvertnbr, /* Number of coarse vertices */ SCOTCH_Num * restrict const finematetab) /* Mating array */ { GraphCoarsenMulti * restrict coarmultptr; /* Un-based pointer to created, grouped multinode array */ int o; intRandInit (); /* Check that random number generator is initialized */ coarmultptr = (GraphCoarsenMulti *) coarmulttab; /* Indicate multinode array is user-provided */ return (graphCoarsenBuild ((const Graph * restrict const) finegrafptr, (Graph * restrict const) coargrafptr, &coarmultptr, coarvertnbr, finematetab)); } scotch-6.0.4.dfsg/src/libscotch/bgraph_bipart_ex.c0000644002563400244210000001176211631447170025311 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bgraph_bipart_ex.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module tries to balance the **/ /** subgraphs of the partition as best as **/ /** it can. **/ /** **/ /** DATES : # Version 2.0 : from : 25 oct 1994 **/ /** to 03 nov 1994 **/ /** # Version 3.0 : from : 18 nov 1995 **/ /** to 18 nov 1995 **/ /** # Version 3.1 : from : 20 nov 1995 **/ /** to 29 nov 1995 **/ /** # Version 3.2 : from : 15 sep 1996 **/ /** to 13 sep 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 3.4 : from : 01 jun 2001 **/ /** to 01 jun 2001 **/ /** # Version 4.0 : from : 11 dec 2003 **/ /** to 11 dec 2003 **/ /** # Version 5.1 : from : 30 nov 2007 **/ /** to 30 nov 2007 **/ /** **/ /************************************************************/ /* ** The defines and includes */ #define BGRAPH_BIPART_EX #include "module.h" #include "common.h" #include "gain.h" #include "graph.h" #include "arch.h" #include "bgraph.h" #include "bgraph_bipart_ex.h" #include "bgraph_bipart_fm.h" #include "bgraph_bipart_gg.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the bipartitioning. ** It returns: ** - 0 : if bipartitioning could be computed. ** - 1 : on error. */ int bgraphBipartEx ( Bgraph * restrict const grafptr) { BgraphBipartFmParam parafmdat; /* Parameter area for the Fiduccia-Mattheyses algorithm */ if (grafptr->compload0dlt == 0) /* Return if nothing to do */ return (0); parafmdat.movenbr = grafptr->s.vertnbr; parafmdat.passnbr = ~0; parafmdat.deltval = 0.0L; /* Exact balance required */ if (bgraphBipartFm (grafptr, ¶fmdat) != 0) /* Return if error */ return (1); if ((grafptr->s.vertnbr > 1) && /* If graph has several vertices but is completely imbalanced */ ((grafptr->compload0 == 0) || (grafptr->compload0 == grafptr->s.velosum))) { BgraphBipartGgParam paraggdat; /* Parameter area for the Greedy Graph Growing algorithm */ paraggdat.passnbr = 4; if (bgraphBipartGg (grafptr, ¶ggdat) != 0) /* Return if error */ return (1); } #ifdef SCOTCH_DEBUG_BGRAPH2 if (bgraphCheck (grafptr) != 0) { errorPrint ("bgraphBipartEx: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/dgraph_match.h0000644002563400244210000001135012051223164024420 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2009,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_match.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Cedric CHEVALIER (v5.0) **/ /** **/ /** FUNCTION : This file provides the structure **/ /** definitions for the coasening phase of **/ /** the multi-level method. **/ /** **/ /** DATES : # Version 5.0 : from : 04 may 2006 **/ /** to : 21 jun 2007 **/ /** # Version 5.1 : from : 23 nov 2008 **/ /** to : 04 apr 2009 **/ /** # Version 6.0 : from : 03 oct 2012 **/ /** to : 03 oct 2012 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /* This structure contains all the tables describing the matching state */ typedef struct DgraphMatchData_ { DgraphCoarsenData c; /*+ Coarsening structure +*/ Gnum * mategsttax; /*+ Mating table for local and ghost vertices +*/ Gnum matelocnbr; /*+ Number of local matchings +*/ Gnum * queuloctab; /*+ Queue of unmated local vertex +*/ Gnum queulocnbr; /*+ Number of enqueued unmated vertices +*/ Gnum * procvgbtab; /*+ Global vertex number bounds for neighboring processors [+1] +*/ float probval; /*+ Vertex mating probability (1.0 is certain) +*/ } DgraphMatchData; /* ** The function prototypes. */ int dgraphMatchInit (DgraphMatchData * restrict const, const float); void dgraphMatchExit (DgraphMatchData * restrict const); int dgraphMatchSync (DgraphMatchData * restrict const); int dgraphMatchSyncColl (DgraphMatchData * restrict const); int dgraphMatchSyncPtop (DgraphMatchData * restrict const); int dgraphMatchCheck (DgraphMatchData * restrict const); void dgraphMatchHl (DgraphMatchData * restrict const); void dgraphMatchSc (DgraphMatchData * restrict const); void dgraphMatchHy (DgraphMatchData * restrict const); void dgraphMatchLc (DgraphMatchData * restrict const); void dgraphMatchLy (DgraphMatchData * restrict const); scotch-6.0.4.dfsg/src/libscotch/hmesh_order_hx.c0000644002563400244210000001664011631447170025007 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh_order_hx.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains service routines **/ /** for the hmeshOrderH{d|f} ordering **/ /** routines. **/ /** **/ /** DATES : # Version 4.0 : from : 09 dec 2003 **/ /** to : 24 jan 2004 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HMESH_ORDER_HX #include "module.h" #include "common.h" #include "graph.h" #include "mesh.h" #include "hmesh.h" #include "hmesh_order_hx.h" /***********************************/ /* */ /* These are the service routines. */ /* */ /***********************************/ /* This routine fills the input arrays for ** the mesh ordering routines. ** It returns: ** - void : in all cases. */ int hmeshOrderHxFill ( const Hmesh * restrict const meshptr, Gnum * restrict const petab, Gnum * restrict const lentab, Gnum * restrict const iwtab, Gnum * restrict const elentab, Gnum * restrict const pfreptr) { Gnum * restrict petax; Gnum * restrict iwtax; Gnum * restrict lentax; Gnum * restrict elentax; HmeshOrderHxHash * restrict hashtab; /* Neighbor hash table */ Gnum hashsiz; Gnum hashmsk; Gnum n; /* Number of nodes to order */ Gnum velmadj; /* Index adjustment for element indices */ Gnum vnodadj; /* Index adjustment for node indices */ Gnum velmnum; Gnum vnodnum; Gnum degrval; Gnum vertnum; Gnum edgenum; n = meshptr->m.velmnbr + meshptr->m.vnodnbr; for (hashsiz = 16, degrval = meshptr->m.degrmax * (meshptr->m.degrmax - 1); /* Compute hash table size */ hashsiz < degrval; hashsiz <<= 1) ; hashsiz <<= 1; hashmsk = hashsiz - 1; if ((hashtab = memAlloc (hashsiz * sizeof (HmeshOrderHxHash))) == NULL) { errorPrint ("hmeshOrderHxFill: out of memory"); return (1); } memSet (hashtab, ~0, hashsiz * sizeof (HmeshOrderHxHash)); petax = petab - 1; /* Base HAMF arrays at base 1 */ iwtax = iwtab - 1; lentax = lentab - 1; elentax = elentab - 1; velmadj = 1 + meshptr->m.vnodnbr - meshptr->m.velmbas; for (vnodnum = meshptr->m.vnodbas, vertnum = edgenum = 1; /* Copy non-halo node data with base 1 */ vnodnum < meshptr->vnohnnd; vertnum ++, vnodnum ++) { Gnum enodnum; Gnum nghbnbr; petax[vertnum] = edgenum; lentax[vertnum] = meshptr->m.vendtax[vnodnum] - meshptr->m.verttax[vnodnum]; for (enodnum = meshptr->m.verttax[vnodnum], nghbnbr = -1; /* -1 since loop edge will be processed in the main loop */ enodnum < meshptr->m.vendtax[vnodnum]; enodnum ++) { Gnum velmnum; Gnum eelmnum; velmnum = meshptr->m.edgetax[enodnum]; iwtax[edgenum ++] = velmnum + velmadj; /* Adjust end element index */ for (eelmnum = meshptr->m.verttax[velmnum]; eelmnum < meshptr->m.vendtax[velmnum]; eelmnum ++) { Gnum vnodend; Gnum hnodend; vnodend = meshptr->m.edgetax[eelmnum]; for (hnodend = (vnodend * HMESHORDERHXHASHPRIME) & hashmsk; ; hnodend = (hnodend + 1) & hashmsk) { if (hashtab[hnodend].vertnum != vnodnum) { hashtab[hnodend].vertnum = vnodnum; hashtab[hnodend].vertend = vnodend; nghbnbr ++; } if (hashtab[hnodend].vertend == vnodend) /* If end vertex already present */ break; /* Skip to next end vertex */ } } elentax[vertnum] = nghbnbr; } } for ( ; vnodnum < meshptr->m.vnodnnd; vnodnum ++, vertnum ++) { /* Copy halo vertices with base 1 */ Gnum degrval; Gnum enodnum; degrval = meshptr->m.verttax[vnodnum] - meshptr->m.vendtax[vnodnum]; petax[vertnum] = edgenum; lentax[vertnum] = (degrval != 0) ? degrval : - (n + 1); elentax[vertnum] = 0; for (enodnum = meshptr->m.verttax[vnodnum]; enodnum < meshptr->m.vendtax[vnodnum]; enodnum ++) iwtax[edgenum ++] = meshptr->m.edgetax[enodnum] + velmadj; /* Adjust end element index */ } vnodadj = 1 - meshptr->m.vnodbas; /* Base nodes at 1 */ for (velmnum = meshptr->m.velmbas; velmnum < meshptr->m.velmnnd; velmnum ++, vertnum ++) { Gnum eelmnum; petax[vertnum] = edgenum; lentax[vertnum] = meshptr->m.vendtax[velmnum] - meshptr->m.verttax[velmnum]; elentax[vertnum] = - (n + 1); for (eelmnum = meshptr->m.verttax[velmnum]; eelmnum < meshptr->m.vendtax[velmnum]; eelmnum ++) iwtax[edgenum ++] = meshptr->m.edgetax[eelmnum] + vnodadj; /* Adjust end node index */ } *pfreptr = edgenum; /* Set index to first free area */ memFree (hashtab); return (0); } scotch-6.0.4.dfsg/src/libscotch/library_dgraph_order_tree_dist.c0000644002563400244210000001020712055777725030245 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_order_tree_dist.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the distri- **/ /** buted ordering distributed tree **/ /** building routine of the libSCOTCH **/ /** library. **/ /** **/ /** DATES : # Version 5.1 : from : 30 nov 2007 **/ /** to 30 nov 2007 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "dgraph.h" #include "dorder.h" #include "ptscotch.h" /************************************/ /* */ /* These routines are the C API for */ /* the distributed ordering */ /* handling routines. */ /* */ /************************************/ /*+ This routine returns the number of *** distributed column blocks contained *** in the given distributed ordering. *** It returns: *** - >=0 : on success. *** - <0 : on error. +*/ SCOTCH_Num SCOTCH_dgraphOrderCblkDist ( const SCOTCH_Dgraph * const grafptr, /*+ Graph to order +*/ const SCOTCH_Dordering * const ordeptr) /*+ Computed ordering +*/ { return (dorderCblkDist ((Dorder *) ordeptr)); } /*+ This routine fills the given distributed *** permutation array with the permutation *** stored in the given distributed ordering. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_dgraphOrderTreeDist ( const SCOTCH_Dgraph * const grafptr, /*+ Graph to order +*/ const SCOTCH_Dordering * const ordeptr, /*+ Computed ordering +*/ SCOTCH_Num * const treeglbtab, /*+ Father array +*/ SCOTCH_Num * const sizeglbtab) /*+ Size array +*/ { return (dorderTreeDist ((Dorder *) ordeptr, (Dgraph *) grafptr, treeglbtab, sizeglbtab)); } scotch-6.0.4.dfsg/src/libscotch/library_geom.c0000644002563400244210000001163711631447170024465 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_geom.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the geom **/ /** graph handling routines of the **/ /** libSCOTCH library. **/ /** **/ /** DATES : # Version 3.4 : from : 10 oct 1999 **/ /** to 01 nov 2001 **/ /** # Version 4.0 : from : 18 dec 2001 **/ /** to 19 jan 2004 **/ /** # Version 5.1 : from : 17 nov 2010 **/ /** to 17 nov 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "geom.h" #include "graph.h" #include "scotch.h" /****************************************/ /* */ /* These routines are the C API for the */ /* graph geometry handling routines. */ /* */ /****************************************/ /*+ This routine reserves a memory area *** of a size sufficient to store a *** geometry structure. *** It returns: *** - !NULL : if the initialization succeeded. *** - NULL : on error. +*/ SCOTCH_Geom * SCOTCH_geomAlloc () { return ((SCOTCH_Geom *) memAlloc (sizeof (SCOTCH_Geom))); } /*+ This routine initializes the opaque *** geom structure used to handle graph *** geometry in the Scotch library. *** It returns: *** - 0 : if the initialization succeeded. *** - !0 : on error. +*/ int SCOTCH_geomInit ( SCOTCH_Geom * const geomptr) { if (sizeof (SCOTCH_Num) != sizeof (Gnum)) { errorPrint ("SCOTCH_geomInit: internal error (1)"); return (1); } if (sizeof (SCOTCH_Geom) < sizeof (Geom)) { errorPrint ("SCOTCH_geomInit: internal error (2)"); return (1); } return (geomInit ((Geom *) geomptr)); } /*+ This routine frees the contents of the *** given opaque geometry structure. *** It returns: *** - VOID : in all cases. +*/ void SCOTCH_geomExit ( SCOTCH_Geom * const geomptr) { geomExit ((Geom *) geomptr); } /*+ This routine accesses all of the geometry data. *** NULL pointers on input indicate unwanted *** data. NULL pointers on output indicate *** unexisting arrays. *** It returns: *** - VOID : in all cases. +*/ void SCOTCH_geomData ( const SCOTCH_Geom * const geomptr, /* Geometry structure to read */ SCOTCH_Num * const dimnptr, /* Number of dimensions */ double ** const geomtab) /* Geometry array [vertnbr] */ { const Geom * srcgeomptr; /* Pointer to source geometry structure */ srcgeomptr = (const Geom *) geomptr; if (dimnptr != NULL) *dimnptr = srcgeomptr->dimnnbr; if (geomtab != NULL) *geomtab = (double *) srcgeomptr->geomtab; } scotch-6.0.4.dfsg/src/libscotch/library_errcom.c0000644002563400244210000001230311631447170025014 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_errcom.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module redirects the errors **/ /** generated by the routines of the **/ /** libSCOTCH library to the standard **/ /** error processing routines. **/ /** **/ /** DATES : # Version 3.3 : from : 06 oct 1998 **/ /** to 13 oct 1998 **/ /** # Version 3.4 : from : 01 nov 2001 **/ /** to 01 nov 2001 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY_ERRCOM #ifndef SCOTCH_COMMON_EXTERNAL #define SCOTCH_COMMON_EXTERNAL /* Do not redefine errorPrint */ #endif /* SCOTCH_COMMON_EXTERNAL */ #include "module.h" #include "common.h" #include "scotch.h" /********************************/ /* */ /* The error handling routines. */ /* */ /********************************/ /* This routine prints an error message with ** a variable number of arguments, as printf () ** does, and exits. ** It returns: ** - EXIT : in all cases. */ void SCOTCH_errorPrint ( const char * const errstr, /*+ printf-like variable argument list */ ...) { va_list errlist; /* Argument list of the call */ char errbuf[1024]; /* Error buffer */ va_start (errlist, errstr); /* Open variable-argument list */ #if ((defined X_ARCHi586_pc_linux2) || (defined X_ARCHi686_pc_linux2)) vsnprintf (errbuf, 1023, errstr, errlist); /* Write result to buffer */ #else vsprintf (errbuf, errstr, errlist); /* Write result to buffer */ #endif /* X_ARCHi586_pc_linux2 */ va_end (errlist); /* Close variable-argument list */ errbuf[1023] = '\0'; /* Set end of string */ errorPrint (errbuf); /* Print arguments */ exit (1); } /* This routine prints a warning message with ** a variable number of arguments, as printf () ** does. ** It returns: ** - VOID : in all cases. */ void SCOTCH_errorPrintW ( const char * const errstr, /*+ printf-like variable argument list */ ...) { va_list errlist; /* Argument list of the call */ char errbuf[1024]; /* Error buffer */ va_start (errlist, errstr); /* Open variable-argument list */ #if ((defined X_ARCHi586_pc_linux2) || (defined X_ARCHi686_pc_linux2)) vsnprintf (errbuf, 1023, errstr, errlist); /* Write result to buffer */ #else vsprintf (errbuf, errstr, errlist); /* Write result to buffer */ #endif /* X_ARCHi586_pc_linux2 */ va_end (errlist); /* Close variable-argument list */ errbuf[1023] = '\0'; /* Set end of string */ errorPrintW (errbuf); /* Print arguments */ } scotch-6.0.4.dfsg/src/libscotch/arch_dist.c0000644002563400244210000002217712354601477023760 0ustar trophimeutilisateurs du domaine/* Copyright 2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : arch_dist.c **/ /** **/ /** AUTHOR : Sebastien FOURESTIER (v6.0) **/ /** Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles the distance **/ /** multiplicator pseudo-architecture **/ /** functions. This pseudo-architecture is **/ /** used by graph repartitioning routines **/ /** to handle floating-point migration **/ /** costs. **/ /** **/ /** DATES : # Version 6.0 : from : 14 fev 2011 **/ /** to : 30 jun 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define ARCH_DIST #include "module.h" #include "common.h" #include "arch.h" #include "arch_dist.h" /**************************************/ /* */ /* These are the entry points for the */ /* distance graph routines. They are */ /* used only in debugging mode, to */ /* provide breakpoints for routines */ /* which are else implemented as */ /* macros for the sake of efficiency. */ /* */ /**************************************/ /* This routine loads the distance ** graph architecture. ** It returns: ** - 0 : if the architecture has been successfully read. ** - !0 : on error. */ int archDistArchLoad ( ArchDist * restrict const archptr, FILE * restrict const stream) { #ifdef SCOTCH_DEBUG_ARCH1 if (sizeof (ArchDist) > sizeof (ArchDummy)) { errorPrint ("archDistArchLoad: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ if (intLoad (stream, &archptr->crloval) != 1) { errorPrint ("archDistArchLoad: bad input"); return (1); } return (archLoad (archptr->archptr, stream)); /* Load sub-architecture */ } /* This routine saves the ** distance graph architecture. ** It returns: ** - 0 : if the architecture has been successfully written. ** - !0 : on error. */ int archDistArchSave ( const ArchDist * const archptr, FILE * restrict const stream) { #ifdef SCOTCH_DEBUG_ARCH1 if (sizeof (ArchDist) > sizeof (ArchDummy)) { errorPrint ("archDistArchSave: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ if (fprintf (stream, ANUMSTRING "\t", (Anum) archptr->crloval) == EOF) { errorPrint ("archDistArchSave: bad output"); return (1); } return (archSave (archptr->archptr, stream)); /* Save sub-architecture */ } /* This routine build the ** distance graph architecture of ** an original one. ** It returns: ** - 0 : if the architecture has been successfully built. ** - !0 : on error. */ int archDistArchBuild ( Arch * const archptr, Arch * const orgarchptr, const Anum crloval) { ArchDist * archdataptr; archInit (archptr); /* Initialize architecture body */ archptr->class = archClass ("dist"); /* Set architecture class */ archptr->flagval = orgarchptr->flagval; /* Set architecture flag */ archdataptr = (ArchDist *) (void *) &archptr->data; archdataptr->archptr = orgarchptr; archdataptr->crloval = crloval; return (0); } /* This function returns the smallest number ** of terminal domain included in the given ** domain. */ ArchDomNum archDistDomNum ( const ArchDist * const archptr, const ArchDom * const domptr) { return (archDomNum (archptr->archptr, domptr)); /* Call proper routine */ } /* This function returns the terminal domain associated ** with the given terminal number in the architecture. ** It returns: ** - 0 : if label is valid and domain has been updated. ** - 1 : if label is invalid. ** - 2 : on error. */ int archDistDomTerm ( const ArchDist * const archptr, ArchDom * const domptr, const ArchDomNum domnum) { return (archDomTerm (archptr->archptr, domptr, domnum)); /* Call proper routine */ } /* This function returns the number of ** elements in the distance domain. */ Anum archDistDomSize ( const ArchDist * const archptr, const ArchDom * const domptr) { return (archDomSize (archptr->archptr, domptr)); /* Call proper routine */ } /* This function returns the weight of ** the given distance domain. */ Anum archDistDomWght ( const ArchDist * const archptr, const ArchDom * const domptr) { return (archDomWght (archptr->archptr, domptr)); /* Call proper routine */ } /* This function returns the average ** distance between two distance ** subdomains. */ Anum archDistDomDist ( const ArchDist * const archptr, const ArchDom * const dom0ptr, const ArchDom * const dom1ptr) { return (archptr->crloval * archDomDist (archptr->archptr, dom0ptr, dom1ptr)); } /* This function sets the biggest ** domain available for this ** architecture. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archDistDomFrst ( const ArchDist * const archptr, ArchDom * restrict const domptr) { return (archDomFrst (archptr->archptr, domptr)); /* Call proper routine */ } /* This routine reads domain information ** from the given stream. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archDistDomLoad ( const ArchDist * const archptr, ArchDom * restrict const domptr, FILE * const stream) { return (archDomLoad (archptr->archptr, domptr, stream)); /* Call proper routine */ } /* This routine saves domain information ** to the given stream. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archDistDomSave ( const ArchDist * const archptr, const ArchDom * const domptr, FILE * const stream) { return (archDomSave (archptr->archptr, domptr, stream)); /* Call proper routine */ } /* This function tries to split a distance ** graph domain into two subdomains. ** It returns: ** - 0 : if bipartitioning succeeded. ** - 1 : if bipartitioning could not be performed. ** - 2 : on error. */ int archDistDomBipart ( const ArchDist * const archptr, const ArchDom * const domptr, ArchDom * restrict const dom0ptr, ArchDom * restrict const dom1ptr) { return (archDomBipart (archptr->archptr, domptr, dom0ptr, dom1ptr)); /* Call proper routine */ } /* This function checks if dom1 is ** included in dom0. ** It returns: ** - 0 : if dom1 is not included in dom0. ** - 1 : if dom1 is included in dom0. ** - 2 : on error. */ int archDistDomIncl ( const ArchDist * const archptr, const ArchDom * const dom0ptr, const ArchDom * const dom1ptr) { return (archDomIncl (archptr->archptr, dom0ptr, dom1ptr)); /* Call proper routine */ } /* This function creates the MPI_Datatype for ** distance graph domains. ** It returns: ** - 0 : if type could be created. ** - 1 : on error. */ #ifdef SCOTCH_PTSCOTCH int archDistDomMpiType ( const ArchDist * const archptr, MPI_Datatype * const typeptr) { return (archDomMpiType (archptr->archptr, typeptr)); /* Call proper routine as we don't add any parameter */ } #endif /* SCOTCH_PTSCOTCH */ scotch-6.0.4.dfsg/src/libscotch/bdgraph_bipart_st.h0000644002563400244210000000714311631447170025472 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bdgraph_bipart_st.h **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the strategy and method **/ /** tables and the generic entry point for **/ /** the distributed graph bipartitioning **/ /** methods. **/ /** **/ /** DATES : # Version 5.1 : from : 10 sep 2007 **/ /** to 16 jul 2010 **/ /** **/ /************************************************************/ /* ** The type definitions. */ /*+ Method types. +*/ typedef enum BdgraphBipartStMethodType_ { BDGRAPHBIPARTSTMETHBD = 0, /*+ Band (strategy) +*/ BDGRAPHBIPARTSTMETHDF, /*+ Diffusion +*/ BDGRAPHBIPARTSTMETHEX, /*+ Exactifier +*/ BDGRAPHBIPARTSTMETHML, /*+ Multi-level (strategy) +*/ BDGRAPHBIPARTSTMETHSQ, /*+ Sequential Method +*/ BDGRAPHBIPARTSTMETHZR, /*+ Move all to part zero +*/ BDGRAPHBIPARTSTMETHNBR /*+ Number of methods +*/ } BdgraphBipartStMethodType; /* ** The external declarations. */ extern StratTab bdgraphbipartststratab; /* ** The function prototypes. */ #ifndef BDGRAPH_BIPART_ST #define static #endif int bdgraphBipartSt (Bdgraph * const, const Strat * const); #undef static scotch-6.0.4.dfsg/src/libscotch/arch_deco.c0000644002563400244210000005355612354555674023743 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010,2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : arch_deco.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module handles the decomposition- **/ /** defined target architecture. **/ /** **/ /** DATES : # Version 0.0 : from : 01 dec 1992 **/ /** to : 24 mar 1993 **/ /** # Version 1.2 : from : 04 feb 1994 **/ /** to : 11 feb 1994 **/ /** # Version 1.3 : from : 20 apr 1994 **/ /** to : 20 apr 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to : 23 dec 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to : 29 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 14 sep 1995 **/ /** # Version 3.1 : from : 20 jul 1996 **/ /** to 23 jul 1996 **/ /** # Version 3.2 : from : 11 sep 1996 **/ /** to 28 sep 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 17 may 1999 **/ /** # Version 4.0 : from : 29 nov 2003 **/ /** to 10 mar 2005 **/ /** # Version 5.0 : from : 10 sep 2007 **/ /** to 28 feb 2008 **/ /** # Version 5.1 : from : 21 jan 2008 **/ /** to 11 aug 2010 **/ /** # Version 6.0 : from : 14 fev 2011 **/ /** to 14 fev 2011 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define ARCH_DECO #include "module.h" #include "common.h" #include "arch.h" #include "arch_deco.h" /***************************************/ /* */ /* These are the decomposition-defined */ /* architecture routines. */ /* */ /***************************************/ /* This routine builds a compiled ** decomposition-defined architecture ** from the raw terminal tables that are ** passed to it. ** It returns: ** - 0 : if the decomposition has been successfully computed. ** - !0 : on error. */ int archDecoArchBuild ( ArchDeco * restrict const archptr, /*+ Architecture to build +*/ const Anum termdomnbr, /*+ Number of terminal domains (ie processors) +*/ const Anum termdommax, /*+ Maximum domain number given to a terminal domain +*/ const ArchDecoTermVert * const termverttab, /*+ Terminal vertex array +*/ const Anum * const termdisttab) /*+ Terminal distance map +*/ { Anum i, j, k; #ifdef SCOTCH_DEBUG_ARCH1 if ((sizeof (ArchDeco) > sizeof (ArchDummy)) || (sizeof (ArchDecoDom) > sizeof (ArchDomDummy))) { errorPrint ("archDecoArchBuild: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ if (memAllocGroup ((void **) (void *) &archptr->domverttab, (size_t) (termdommax * sizeof (ArchDecoVert)), &archptr->domdisttab, (size_t) ((((termdommax * (termdommax - 1)) / 2) + 1) * sizeof (Anum)), NULL) == NULL) { errorPrint ("archDecoArchBuild: out of memory"); return (1); } archptr->flagval = ARCHDECOFREE; archptr->domtermnbr = termdomnbr; archptr->domvertnbr = termdommax; for (i = 0; i < termdommax; i ++) { archptr->domverttab[i].labl = ARCHDOMNOTTERM; /* Assume domain is not a terminal */ archptr->domverttab[i].size = 0; /* Assume domain is not used (yet) */ archptr->domverttab[i].wght = 0; /* Assume domain is not used (yet) */ } for (i = 0; i < termdomnbr; i ++) { /* Set terminal data of all declared terminals */ #ifdef SCOTCH_DEBUG_ARCH1 if (termverttab[i].num > termdommax) { /* If incorrect maximum terminal number */ errorPrint ("archDecoArchBuild: bad maximum terminal"); archDecoArchFree (archptr); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ archptr->domverttab[termverttab[i].num - 1].labl = termverttab[i].labl; archptr->domverttab[termverttab[i].num - 1].size = 1; archptr->domverttab[termverttab[i].num - 1].wght = termverttab[i].wght; } for (i = termdommax - 1; i > 0; i --) { /* Accumulate data from terminals to root */ j = ((i - 1) >> 1); if (archptr->domverttab[i].labl != ARCHDOMNOTTERM) { if ((archptr->domverttab[j].labl == ARCHDOMNOTTERM) || /* Get smallest label */ (archptr->domverttab[j].labl > archptr->domverttab[i].labl)) archptr->domverttab[j].labl = archptr->domverttab[i].labl; archptr->domverttab[j].size += archptr->domverttab[i].size; archptr->domverttab[j].wght += archptr->domverttab[i].wght; } } #ifdef SCOTCH_DEBUG_ARCH1 if (archptr->domverttab[0].size != termdomnbr) { /* If incorrect accumulation */ errorPrint ("archDecoArchBuild: bad terminal count"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ memSet (archptr->domdisttab, 0, termdommax * (termdommax - 1) * sizeof (Anum) / 2); /* Assume distance is not known */ for (i = 1, k = 0; i < termdomnbr; i ++) { /* Read the terminal distance map */ for (j = 0; j < i; j ++, k ++) archDecoArchDist (archptr, termverttab[i].num, termverttab[j].num) = termdisttab[k]; } for (j = termdommax; j > 0; j --) { /* Loop on domains */ if (archDecoArchSize (archptr, j) == 0) /* If domain is unused, skip it */ continue; for (i = termdommax; i > j; i --) { /* Double loop on distance array values */ if (archDecoArchSize (archptr, i) == 0) /* If domain is unused, skip it */ continue; if (archDecoArchSize (archptr, i) > 1) { /* If domain i has subdomains */ if (archDecoArchSize (archptr, j) > 1) /* If domain j has subdomains */ archDecoArchDist (archptr, i, j) = (archDecoArchDistE (archptr, 2 * i, 2 * j) + archDecoArchDistE (archptr, 2 * i, 2 * j + 1) + archDecoArchDistE (archptr, 2 * i + 1, 2 * j) + archDecoArchDistE (archptr, 2 * i + 1, 2 * j + 1) + 2) / 4; else /* If domain j is a terminal */ archDecoArchDist (archptr, i, j) = (archDecoArchDistE (archptr, 2 * i, j) + archDecoArchDistE (archptr, 2 * i + 1, j) + 1) / 2; } else { /* If domain i is a terminal */ if (archDecoArchSize (archptr, j) > 1) /* If domain j has subdomains */ archDecoArchDist (archptr, i, j) = (archDecoArchDistE (archptr, i, 2 * j) + archDecoArchDistE (archptr, i, 2 * j + 1) + 1) / 2; #ifdef SCOTCH_DEBUG_ARCH1 else { /* If both domain are terminals */ if (archDecoArchDist (archptr, i, j) == 0) { /* Distance value must be greater than zero */ errorPrint ("archDecoArchBuild: invalid null distance"); archDecoArchFree (archptr); return (1); } } #endif /* SCOTCH_DEBUG_ARCH1 */ } } } return (0); } /* This routine loads and computes the ** decomposition-defined architecture ** tables. ** It returns: ** - 0 : if the decomposition has been successfully read. ** - !0 : on error. */ int archDecoArchLoad ( ArchDeco * restrict const archptr, FILE * restrict const stream) { INT decotype; /* Type of decomposition */ INT termdomnbr; /* Number of terminal domains (ie processors) */ INT termdommax; /* Maximum domain number given to a terminal domain */ ArchDecoTermVert * restrict termverttab; /* Table of terminal vertex data */ Anum * restrict termdisttab; /* Table of terminal-to-terminal distances */ INT i, j; #ifdef SCOTCH_DEBUG_ARCH1 if ((sizeof (ArchDeco) > sizeof (ArchDummy)) || (sizeof (ArchDecoDom) > sizeof (ArchDomDummy))) { errorPrint ("archDecoArchLoad: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ if ((intLoad (stream, &decotype) != 1) || /* Read header */ (intLoad (stream, &termdomnbr) != 1) || (intLoad (stream, &termdommax) != 1) || (decotype < 0) || (decotype > 1) || (termdommax < termdomnbr) || (termdomnbr < 1)) { errorPrint ("archDecoArchLoad: bad input (1)"); return (1); } if (decotype == 0) { /* If raw decomposition */ if (memAllocGroup ((void **) (void *) &termverttab, (size_t) (termdomnbr * sizeof (ArchDecoTermVert)), &termdisttab, (size_t) ((((termdommax * (termdommax - 1)) / 2) + 1) * sizeof (Anum)), NULL) == NULL) { errorPrint ("archDecoArchLoad: out of memory (1)"); return (1); } for (i = 0; i < termdomnbr; i ++) { /* For all declared terminals */ INT termvertlabl; INT termvertwght; INT termvertnum; if ((intLoad (stream, &termvertlabl) != 1) || /* Read terminal data */ (intLoad (stream, &termvertwght) != 1) || (intLoad (stream, &termvertnum) != 1) || (termvertnum < 1) || (termvertnum > termdommax)) { errorPrint ("archDecoArchLoad: bad input (2)"); memFree (termverttab); /* Free group leader */ return (1); } termverttab[i].labl = (ArchDomNum) termvertlabl; termverttab[i].wght = (Anum) termvertwght; termverttab[i].num = (Anum) termvertnum; } for (i = 0, j = (termdomnbr * (termdomnbr - 1)) / 2; i < j; i ++) { /* Read terminal distance map */ INT termdistval; if ((intLoad (stream, &termdistval) != 1) || (termdistval < 1)) { errorPrint ("archDecoArchLoad: bad input (3)"); memFree (termverttab); /* Free group leader */ return (1); } termdisttab[i] = (Anum) termdistval; } archDecoArchBuild (archptr, termdomnbr, termdommax, termverttab, termdisttab); memFree (termverttab); /* Free group leader */ } else { /* If it is a compiled decomposition */ if (memAllocGroup ((void **) (void *) &archptr->domverttab, (size_t) (termdommax * sizeof (ArchDecoVert)), &archptr->domdisttab, (size_t) ((((termdommax * (termdommax - 1)) / 2) + 1) * sizeof (Anum)), NULL) == NULL) { errorPrint ("archDecoArchLoad: out of memory (2)"); return (1); } archptr->flagval = ARCHDECOFREE; archptr->domtermnbr = (Anum) termdomnbr; archptr->domvertnbr = (Anum) termdommax; for (i = 0; i < termdommax; i ++) { /* Read domain array */ INT domvertlabl; INT domvertsize; INT domvertwght; if ((intLoad (stream, &domvertlabl) != 1) || (intLoad (stream, &domvertsize) != 1) || (intLoad (stream, &domvertwght) != 1)) { errorPrint ("archDecoArchLoad: bad input (4)"); archDecoArchFree (archptr); return (1); } archptr->domverttab[i].labl = (ArchDomNum) domvertlabl; archptr->domverttab[i].size = (Anum) domvertsize; archptr->domverttab[i].wght = (Anum) domvertwght; } for (i = 0; i < (termdommax * (termdommax - 1)) / 2; i ++) { /* Read distance array */ INT domdistval; if (intLoad (stream, &domdistval) != 1) { errorPrint ("archDecoArchLoad: bad input (5)"); archDecoArchFree (archptr); return (1); } archptr->domdisttab[i] = domdistval; } } return (0); } /* This routine frees the decomposition ** architecture structures. ** It returns: ** - 0 : if the decomposition has been successfully freed. ** - !0 : on error. */ int archDecoArchFree ( ArchDeco * const archptr) { #ifdef SCOTCH_DEBUG_ARCH1 if ((sizeof (ArchDeco) > sizeof (ArchDummy)) || (sizeof (ArchDecoDom) > sizeof (ArchDomDummy))) { errorPrint ("archDecoArchFree: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ if (((archptr->flagval & ARCHDECOFREE) != 0) && (archptr->domverttab != NULL)) memFree (archptr->domverttab); /* Free group leader */ archptr->domtermnbr = archptr->domvertnbr = 0; archptr->domverttab = NULL; archptr->domdisttab = NULL; return (0); } /* This routine saves the given target architecture ** as compiled decomposition tables. ** It returns: ** - 0 : if the decomposition has been successfully written. ** - !0 : on error. */ int archDecoArchSave ( const ArchDeco * const archptr, FILE * restrict const stream) { Anum i, j; #ifdef SCOTCH_DEBUG_ARCH1 if ((sizeof (ArchDeco) > sizeof (ArchDummy)) || (sizeof (ArchDecoDom) > sizeof (ArchDomDummy))) { errorPrint ("archDecoArchSave: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ if (fprintf (stream, "1\n" ANUMSTRING "\t" ANUMSTRING "\n", /* Write number of domains */ (Anum) archptr->domtermnbr, (Anum) archptr->domvertnbr) == EOF) { errorPrint ("archDecoArchSave: bad output (1)"); return (1); } for (i = 0; i < archptr->domvertnbr; i ++) { /* Write domain array */ if (fprintf (stream, ANUMSTRING "\t" ANUMSTRING "\t" ANUMSTRING "\n", (Anum) archptr->domverttab[i].labl, (Anum) archptr->domverttab[i].size, (Anum) archptr->domverttab[i].wght) == EOF) { errorPrint ("archDecoArchSave: bad output (2)"); return (1); } } j = (archptr->domvertnbr * (archptr->domvertnbr - 1)) / 2; for (i = 0; i < j; i ++) { /* Write distance array */ if (fprintf (stream, ANUMSTRING "%c", (Anum) archptr->domdisttab[i], (((i % 8) == 7) && (i != (j - 1))) ? '\n' : '\t') == EOF) { errorPrint ("archDecoArchSave: bad output (3)"); return (1); } } return (0); } /* This function returns the smallest number ** of terminal domain included in the given ** domain. */ ArchDomNum archDecoDomNum ( const ArchDeco * const archptr, const ArchDecoDom * const domptr) { return (archptr->domverttab[domptr->num - 1].labl); } /* This function returns the terminal domain associated ** with the given terminal number in the architecture. ** It returns: ** - 0 : if label is valid and domain has been updated. ** - 1 : if label is invalid. ** - 2 : on error. */ int archDecoDomTerm ( const ArchDeco * const archptr, ArchDecoDom * const domptr, const ArchDomNum domnum) { Anum domtermnum; Anum domvertnum; for (domtermnum = archptr->domtermnbr, domvertnum = archptr->domvertnbr - 1; (domtermnum > 0) && (domvertnum != (Anum) (-1)); domvertnum --) { if (archptr->domverttab[domvertnum].size == 1) { /* If terminal vertex */ domtermnum --; /* One more terminal scanned */ if (archptr->domverttab[domvertnum].labl == domnum) { /* If terminal domain number found */ domptr->num = domvertnum; /* Set domain number */ return (0); } } } return (1); /* Cannot set domain */ } /* This function returns the number of ** elements in the given domain. */ Anum archDecoDomSize ( const ArchDeco * const archptr, const ArchDecoDom * const domptr) { return (archptr->domverttab[domptr->num - 1].size); } /* This function returns the weight of ** the given domain. */ Anum archDecoDomWght ( const ArchDeco * const archptr, const ArchDecoDom * const domptr) { return (archptr->domverttab[domptr->num - 1].wght); } /* This function returns the average distance ** between two domains, which is extracted ** from the table. */ Anum archDecoDomDist ( const ArchDeco * const archptr, const ArchDecoDom * const dom0ptr, const ArchDecoDom * const dom1ptr) { return (archDecoArchDistE (archptr, dom0ptr->num, dom1ptr->num)); } /* This function sets the biggest ** domain available for this ** architecture. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archDecoDomFrst ( const ArchDeco * const archptr, ArchDecoDom * restrict const domptr) { domptr->num = 1; return (0); } /* This routine reads domain information ** from the given stream. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archDecoDomLoad ( const ArchDeco * const archptr, ArchDecoDom * restrict const domptr, FILE * restrict const stream) { if ((intLoad (stream, &domptr->num) != 1) || (domptr->num < 1) || (domptr->num > archptr->domvertnbr)) { errorPrint ("archDecoDomLoad: bad input"); return (1); } return (0); } /* This routine saves domain information ** to the given stream. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archDecoDomSave ( const ArchDeco * const archptr, const ArchDecoDom * const domptr, FILE * restrict const stream) { if (fprintf (stream, ANUMSTRING " ", (Anum) domptr->num) == EOF) { errorPrint ("archDecoDomSave: bad output"); return (1); } return (0); } /* This function tries to split a ** decomposition domain into two ** subdomains. ** It returns: ** - 0 : if bipartitioning succeeded. ** - 1 : if bipartitioning could not be performed. ** - 2 : on error. */ int archDecoDomBipart ( const ArchDeco * const archptr, const ArchDecoDom * const domptr, ArchDecoDom * restrict const dom0ptr, ArchDecoDom * restrict const dom1ptr) { if (archptr->domverttab[domptr->num - 1].size <= 1) /* Return if cannot bipartition more */ return (1); dom0ptr->num = domptr->num << 1; /* Compute subdomain numbers from domain number */ dom1ptr->num = dom0ptr->num + 1; return (0); } /* This function checks if dom1 is ** included in dom0. ** It returns: ** - 0 : if dom1 is not included in dom0. ** - 1 : if dom1 is included in dom0. ** - 2 : on error. */ int archDecoDomIncl ( const ArchDeco * const archptr, const ArchDecoDom * const dom0ptr, const ArchDecoDom * const dom1ptr) { Anum dom0num; Anum dom1num; for (dom1num = dom1ptr->num, dom0num = dom0ptr->num; dom1num != 0; dom1num >>= 1) if (dom1num == dom0ptr->num) return (1); return (0); } /* This function creates the MPI_Datatype for ** decomposition-described domains. ** It returns: ** - 0 : if type could be created. ** - 1 : on error. */ #ifdef SCOTCH_PTSCOTCH int archDecoDomMpiType ( const ArchDeco * const archptr, MPI_Datatype * const typeptr) { *typeptr = ANUM_MPI; return (0); } #endif /* SCOTCH_PTSCOTCH */ scotch-6.0.4.dfsg/src/libscotch/mapping_io.h0000644002563400244210000001120111631447171024125 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mapping_io.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the declarations for **/ /** the mapping handling routines. **/ /** **/ /** DATES : # Version 0.0 : from : 15 dec 1992 **/ /** to 01 apr 1993 **/ /** # Version 1.0 : from : 04 oct 1993 **/ /** to 06 oct 1993 **/ /** # Version 1.1 : from : 15 oct 1993 **/ /** to 15 oct 1993 **/ /** # Version 1.3 : from : 09 apr 1994 **/ /** to 11 may 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to 02 nov 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to 18 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 04 jul 1995 **/ /** # Version 3.1 : from : 30 oct 1995 **/ /** to 06 jun 1996 **/ /** # Version 3.2 : from : 23 aug 1996 **/ /** to 26 may 1998 **/ /** # Version 3.3 : from : 19 oct 1998 **/ /** to 30 mar 1999 **/ /** # Version 4.0 : from : 11 dec 2001 **/ /** to 13 nov 2005 **/ /** # Version 5.0 : from : 13 sep 2006 **/ /** to 13 sep 2006 **/ /** **/ /************************************************************/ #define MAPPING_H /* ** The defines. */ /*+ Ordering option flags. +*/ #define MAPNONE 0x0000 /* No options set */ #define MAPFREEPART 0x0001 /* Free partition array */ /* ** The type definitions. */ /*+ This structure defines a source label to target label mapping element. +*/ typedef struct MappingLoadMap_ { Gnum slblnum; /*+ Source graph vertex label: FIRST +*/ Gnum tlblnum; /*+ Target architecture vertex label +*/ } MappingLoadMap; /*+ The source graph sort structure, used to sort vertices by increasing label value. +*/ typedef struct MappingLoadPerm { Gnum vlblnum; /*+ Vertex label: FIRST +*/ Gnum vertnum; /*+ Vertex number +*/ } MappingLoadPerm; scotch-6.0.4.dfsg/src/libscotch/bdgraph.c0000644002563400244210000002002712400671217023406 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bdgraph.c **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the distributed **/ /** bipartitioning graph data structure **/ /** handling routines. **/ /** **/ /** DATES : # Version 5.1 : from : 10 sep 2007 **/ /** to 14 apr 2011 **/ /** # Version 6.0 : from : 11 sep 2011 **/ /** to 31 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define BDGRAPH #include "module.h" #include "common.h" #include "arch.h" #include "dgraph.h" #include "dmapping.h" #include "bdgraph.h" /*************************************/ /* */ /* These routines handle distributed */ /* bipartition graphs. */ /* */ /*************************************/ /* This routine builds the active graph ** corresponding to the given bipartitioning ** job parameters. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int bdgraphInit ( Bdgraph * restrict const actgrafptr, /* Active graph */ const Dgraph * restrict const indgrafptr, /* Induced source subdgraph */ const Dgraph * restrict const srcgrafptr, /* Original source graph */ const Arch * restrict const archptr, /* Current mapping of halo vertices */ const ArchDom domnsubtab[]) /* Subdomains */ { Anum domndist; /* Distance between both subdomains */ Anum domnwght0; /* Processor workforce in each domain */ Anum domnwght1; domndist = archDomDist (archptr, &domnsubtab[0], &domnsubtab[1]); /* Get distance between subdomains */ domnwght0 = archDomWght (archptr, &domnsubtab[0]); /* Get weights of subdomains */ domnwght1 = archDomWght (archptr, &domnsubtab[1]); actgrafptr->s = *indgrafptr; /* Get source graph data */ actgrafptr->s.flagval &= ~DGRAPHFREEALL; /* Do not free contents of separation graph */ actgrafptr->s.vlblloctax = NULL; /* Never mind about vertex labels in the future */ actgrafptr->veexloctax = NULL; /* No external gain (yet) */ actgrafptr->veexglbsum = 0; actgrafptr->partgsttax = NULL; /* Do not allocate frontier arrays yet */ actgrafptr->fronloctab = NULL; bdgraphInit2 (actgrafptr, domndist, domnwght0, domnwght1); /* TODO: Compute external gains */ #ifdef SCOTCH_DEBUG_BDGRAPH2 if (bdgraphCheck (actgrafptr) != 0) { errorPrint ("bdgraphInit: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_BDGRAPH2 */ return (0); } void bdgraphInit2 ( Bdgraph * restrict const actgrafptr, /* Active graph */ const Anum domndist, /* Distance between both subdomains */ const Anum domnwght0, /* Processor workforce in each domain */ const Anum domnwght1) { actgrafptr->fronlocnbr = /* No frontier vertices */ actgrafptr->fronglbnbr = 0; actgrafptr->complocload0 = actgrafptr->s.velolocsum; actgrafptr->compglbload0 = actgrafptr->s.veloglbsum; actgrafptr->compglbload0min = 0; /* No external constraints on bipartition (yet) */ actgrafptr->compglbload0max = actgrafptr->s.veloglbsum; actgrafptr->compglbload0avg = (Gnum) (((double) actgrafptr->s.veloglbsum * (double) domnwght0) / (double) (domnwght0 + domnwght1)); actgrafptr->compglbload0dlt = actgrafptr->s.veloglbsum - actgrafptr->compglbload0avg; actgrafptr->complocsize0 = actgrafptr->s.vertlocnbr; actgrafptr->compglbsize0 = actgrafptr->s.vertglbnbr; actgrafptr->commglbload = 0; actgrafptr->commglbloadextn0 = 0; actgrafptr->commglbgainextn = 0; actgrafptr->commglbgainextn0 = 0; actgrafptr->bbalglbval = (double) actgrafptr->compglbload0dlt / (double) actgrafptr->compglbload0avg; actgrafptr->domndist = domndist; actgrafptr->domnwght[0] = domnwght0; actgrafptr->domnwght[1] = domnwght1; actgrafptr->levlnum = 0; } /* This routine frees the contents ** of the given distributed active graph. ** It returns: ** - VOID : in all cases. */ void bdgraphExit ( Bdgraph * const grafptr) { if (grafptr->partgsttax != NULL) memFree (grafptr->partgsttax + grafptr->s.baseval); if (grafptr->fronloctab != NULL) memFree (grafptr->fronloctab); if (grafptr->veexloctax != NULL) memFree (grafptr->veexloctax + grafptr->s.baseval); dgraphExit (&grafptr->s); /* Free distributed source graph and its private data (flagval may be corrupted afterwards) */ #ifdef SCOTCH_DEBUG_BDGRAPH2 memSet (grafptr, ~0, sizeof (Bdgraph)); #endif /* SCOTCH_DEBUG_BDGRAPH2 */ } /* This routine moves all of the graph ** vertices to the first part. ** It returns: ** - VOID : in all cases. */ void bdgraphZero ( Bdgraph * const grafptr) { if (grafptr->partgsttax != NULL) memSet (grafptr->partgsttax + grafptr->s.baseval, 0, grafptr->s.vertgstnbr * sizeof (GraphPart)); /* Set all local and ghost vertices to part 0 */ grafptr->fronlocnbr = /* No frontier vertices */ grafptr->fronglbnbr = 0; grafptr->complocload0 = grafptr->s.velolocsum; grafptr->compglbload0 = grafptr->s.veloglbsum; grafptr->compglbload0dlt = grafptr->s.veloglbsum - grafptr->compglbload0avg; grafptr->complocsize0 = grafptr->s.vertlocnbr; grafptr->compglbsize0 = grafptr->s.vertglbnbr; grafptr->commglbload = grafptr->commglbloadextn0; grafptr->commglbgainextn = grafptr->commglbgainextn0; } scotch-6.0.4.dfsg/src/libscotch/kgraph_map_rb.c0000644002563400244210000010270212377667525024620 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2011,2013,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph_map_rb.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module performs the Dual Recursive **/ /** Bipartitioning mapping algorithm. **/ /** It is now a branching routine. **/ /** **/ /** DATES : # Version 0.0 : from : 31 mar 1993 **/ /** to 31 mar 1993 **/ /** # Version 1.0 : from : 04 oct 1993 **/ /** to 06 oct 1993 **/ /** # Version 1.1 : from : 15 oct 1993 **/ /** to 15 oct 1993 **/ /** # Version 1.3 : from : 09 apr 1994 **/ /** to 11 may 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to 17 nov 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to 18 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 19 oct 1995 **/ /** # Version 3.1 : from : 30 oct 1995 **/ /** to 14 jun 1996 **/ /** # Version 3.2 : from : 23 aug 1996 **/ /** to 07 sep 1998 **/ /** # Version 3.3 : from : 19 oct 1998 **/ /** to 08 dec 1998 **/ /** # Version 3.4 : from : 01 jun 2001 **/ /** to 07 nov 2001 **/ /** # Version 4.0 : from : 12 jan 2004 **/ /** to 06 mar 2005 **/ /** # Version 5.1 : from : 22 nov 2007 **/ /** to 07 oct 2008 **/ /** # Version 6.0 : from : 03 mar 2011 **/ /** to 28 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define KGRAPH_MAP_RB #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "arch.h" #include "arch_dist.h" #include "mapping.h" #include "bgraph.h" #include "bgraph_bipart_st.h" #include "kgraph.h" #include "kgraph_map_rb.h" #include "kgraph_map_rb_map.h" #include "kgraph_map_rb_part.h" /********************************************/ /* */ /* This is the entry point for the Dual */ /* Recursive Bipartitioning mapping method. */ /* */ /********************************************/ /* This routine runs the Dual Recursive ** Bipartitioning algorithm. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int kgraphMapRb ( Kgraph * const grafptr, const KgraphMapRbParam * restrict const paraptr) { KgraphMapRbData datadat; /* Data passed to each bipartitioning job */ Graph indgrafdat; /* Induced graph without fixed vertices */ Graph * restrict indgrafptr; /* Pointer to top-level graph without fixed vertices */ KgraphMapRbVflo * restrict vflotab; /* Array of fixed vertex load slots */ Anum vflonbr; /* Number of fixed vertex load slots */ Gnum vertnum; int o; Gnum * const frontab = grafptr->frontab; const Gnum * restrict const verttax = grafptr->s.verttax; const Gnum * restrict const vendtax = grafptr->s.vendtax; const Gnum * restrict const edgetax = grafptr->s.edgetax; grafptr->kbalval = paraptr->kbalval; /* Store last k-way imbalance ratio */ datadat.grafptr = &grafptr->s; datadat.mappptr = &grafptr->m; datadat.r.mappptr = (grafptr->r.m.parttax != NULL) ? &grafptr->r.m : NULL; datadat.r.vmlotax = grafptr->r.vmlotax; datadat.r.cmloval = grafptr->r.cmloval; datadat.r.crloval = grafptr->r.crloval; datadat.pfixtax = grafptr->pfixtax; datadat.paraptr = paraptr; datadat.comploadrat = grafptr->comploadrat; datadat.comploadmin = (1.0 - paraptr->kbalval) * grafptr->comploadrat; /* Ratio can have been tilted when working on subgraph */ datadat.comploadmax = (1.0 + paraptr->kbalval) * grafptr->comploadrat; if (grafptr->pfixtax == NULL) { indgrafptr = &grafptr->s; /* Work on the original graph */ vflonbr = 0; /* No fixed vertex load slots */ vflotab = NULL; } else { if (kgraphMapRbVfloBuild (grafptr->m.archptr, &grafptr->s, grafptr->vfixnbr, grafptr->pfixtax, &indgrafdat, &vflonbr, &vflotab) != 0) { errorPrint ("kgraphMapRb: cannot create induced graph"); return (1); } indgrafptr = &indgrafdat; } o = ((archPart (grafptr->m.archptr) != 0) ? kgraphMapRbPart : kgraphMapRbMap) (&datadat, indgrafptr, vflonbr, vflotab); /* Compute recursive bipartitioning */ if (grafptr->pfixtax != NULL) { /* If fixed vertices */ memFree (vflotab); /* Not used any longer */ graphExit (&indgrafdat); if (kgraphMapRbVfloMerge (&grafptr->m, grafptr->vfixnbr, grafptr->pfixtax, vflonbr) != 0) { errorPrint ("kgraphMapRb: cannot merge fixed vertex domains"); return (1); } } if (memReallocGroup (grafptr->comploadavg, /* Reallocate cost array according to potential new size */ &grafptr->comploadavg, (size_t) (grafptr->m.domnmax * sizeof (Gnum)), /* TRICK: can send both compload arrays in one piece */ &grafptr->comploaddlt, (size_t) (grafptr->m.domnmax * sizeof (Gnum)), NULL) == NULL) { errorPrint ("kgraphMapRb: out of memory (3)"); return (1); } kgraphFron (grafptr); kgraphCost (grafptr); /* Compute cost of full k-way partition */ #ifdef SCOTCH_DEBUG_KGRAPH2 if (kgraphCheck (grafptr) != 0) { errorPrint ("kgraphMapRb: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ return (o); } /*******************************************/ /* */ /* These routines handle fixed vertex load */ /* arrays and fixed vertices. */ /* */ /*******************************************/ /* If the given graph has fixed vertices, this ** routine builds simultaneously an induced subgraph ** from which such vertices have been removed, and ** a list of these fixed vertices. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int kgraphMapRbVfloBuild ( const Arch * restrict const archptr, /*+ Target architecture +*/ const Graph * restrict const orggrafptr, /*+ Original graph with fixed vertices +*/ const Gnum orgvfixnbr, /*+ Number of fixed vertices in graph +*/ const Anum * restrict const orgpfixtax, /*+ Array of fixed vertex terminal domains +*/ Graph * restrict const indgrafptr, /*+ Induced subgraph without fixed vertices +*/ Anum * restrict const vflonbrptr, /*+ Pointer to number of fixed vertex slots +*/ KgraphMapRbVflo * restrict * restrict const vflotabptr) /*+ Pointer to fixed vertex load array pointer +*/ { ArchDom domndat; Gnum orgvertnum; GraphPart * restrict orgparttax; /* Part array for induced graph */ KgraphMapRbVflo * restrict hashtab; /* Hash table for merging fixed vertices */ Gnum hashnbr; /* Prospective number of cells in table */ Gnum hashsiz; /* Size of hash table */ Gnum hashnum; Gnum hashmsk; /* Mask for access to hash table */ Gnum velomsk; /* Zero if all fixed vertex loads are zero */ Anum vflonbr; const Gnum * restrict const orgvelotax = orggrafptr->velotax; if (archVar (archptr) == 0) { /* If fixed size architecture */ archDomFrst (archptr, &domndat); hashnbr = archDomSize (archptr, &domndat); /* Get maximum size of distinct terminal domains */ if (orgvfixnbr < hashnbr) hashnbr = orgvfixnbr; } else hashnbr = orgvfixnbr; for (hashsiz = 0, hashmsk = hashnbr; hashmsk != 0; hashsiz ++, hashmsk >>= 1) ; /* Get upper power of two */ hashsiz = 1 << (hashsiz + 2); /* Fill hash table at 25% maximum */ hashmsk = hashsiz - 1; if (memAllocGroup ((void **) (void *) &hashtab, (size_t) (hashsiz * sizeof (KgraphMapRbVflo)), /* Use fixed vertex load slots as hash slots */ &orgparttax, (size_t) (orggrafptr->vertnbr * sizeof (GraphPart)), NULL) == NULL) { errorPrint ("kgraphMapRbVfloBuild: out of memory"); return (1); } orgparttax -= orggrafptr->baseval; memSet (hashtab, ~0, hashsiz * sizeof (KgraphMapRbVflo)); /* Set all vertex numbers to ~0 */ velomsk = 0; /* Assume all fixed vertex loads are zero */ for (orgvertnum = orggrafptr->baseval; orgvertnum < orggrafptr->vertnnd; orgvertnum ++) { Anum orgpfixval; orgpfixval = orgpfixtax[orgvertnum]; if (orgpfixval >= 0) { /* If vertex is a fixed vertex */ Gnum hashnum; Gnum veloval; veloval = (orgvelotax == NULL) ? 1 : orgvelotax[orgvertnum]; /* Get fixed vertex load */ velomsk |= veloval; /* See if all fixed vertex loads are zero */ for (hashnum = (orgpfixval * KGRAPHMAPRBVFLOHASHPRIME) & hashmsk; ; hashnum = (hashnum + 1) & hashmsk) { if (hashtab[hashnum].termnum == orgpfixval) { /* If hash slot found */ hashtab[hashnum].veloval += veloval; /* Add contribution to slot */ break; } if (hashtab[hashnum].termnum == ~0) { /* If hash slot empty */ hashtab[hashnum].termnum = orgpfixval; /* Create slot */ hashtab[hashnum].veloval = veloval; break; } } orgparttax[orgvertnum] = 1; /* Fixed vertex will not be kept in induced subgraph */ } else orgparttax[orgvertnum] = 0; /* Keep non-fixed vertex in induced subgraph */ } if (graphInducePart (orggrafptr, orgparttax, orggrafptr->vertnbr - orgvfixnbr, 0, indgrafptr) != 0) { /* Keep non-fixed vertices in induced graph */ errorPrint ("kgraphMapRbVfloBuild: cannot build induced subgraph"); memFree (hashtab); return (1); } if (velomsk == 0) { /* If all fixed vertex loads are zero */ memFree (hashtab); /* No need to allocate a table */ *vflonbrptr = 0; *vflotabptr = NULL; return (0); } for (hashnum = vflonbr = 0; hashnum < hashsiz; hashnum ++) { /* Recycle hash table into fixed vertex load table */ if (hashtab[hashnum].termnum != ~0) { hashtab[vflonbr] = hashtab[hashnum]; vflonbr ++; } } *vflonbrptr = vflonbr; *vflotabptr = memRealloc (hashtab, vflonbr * sizeof (KgraphMapRbVflo)); return (0); } /* This routine splits the fixed vertex load ** array in two parts, one for each of the two ** provided subdomains. ** It returns: ** - void : in all cases. */ void kgraphMapRbVfloSplit ( const Arch * restrict const archptr, /*+ Target architecture +*/ const ArchDom * restrict const domnsubtab, /*+ Array of the two subdomains +*/ const Anum vflonbr, /*+ Number of fixed vertex load slots +*/ KgraphMapRbVflo * restrict const vflotab, /*+ Fixed vertex load array +*/ Anum * restrict const vflonbrtab, /*+ Number of slots in each subdomain +*/ Gnum * restrict const vflowgttab) /*+ Fixed vertex load in each subdomain +*/ { KgraphMapRbVflo vflodat; /* Temporary swap area */ ArchDom domndat; /* Terminal domain attached to fixed vertex */ Gnum compload0; /* Load of slots in first subdomain */ Gnum compload1; /* Load of slots in second subdomain */ Gnum vflomax; Gnum vflonum; Gnum vflonnd; compload0 = compload1 = 0; vflomax = vflonbr; if (archVar (archptr) == 0) { for (vflonum = 0, vflonnd = vflonbr - 1; vflonum < vflonnd; ) { while (1) { #ifdef SCOTCH_DEBUG_KGRAPH2 int o; o = #endif /* SCOTCH_DEBUG_KGRAPH2 */ archDomTerm (archptr, &domndat, vflotab[vflonum].termnum); #ifdef SCOTCH_DEBUG_KGRAPH2 if (o != 0) { errorPrint ("kgraphMapRbVfloSplit: internal error (1)"); return; } #endif /* SCOTCH_DEBUG_KGRAPH2 */ if (archDomIncl (archptr, &domnsubtab[0], &domndat) == 1) { /* If terminal vertex subdomain included in first subdomain */ compload0 += vflotab[vflonum].veloval; /* Fixed vertex belongs to first subdomain */ if (++ vflonum > vflonnd) /* If passed beyond the limit of the second subdomain */ goto quit; } else { #ifdef SCOTCH_DEBUG_KGRAPH2 if (archDomIncl (archptr, &domnsubtab[1], &domndat) != 1) { /* If terminal vertex subdomain not included in second subdomain */ errorPrint ("kgraphMapRbVfloSplit: internal error (2)"); return; } #endif /* SCOTCH_DEBUG_KGRAPH2 */ break; /* We have found a candidate for swapping */ } } while (1) { archDomTerm (archptr, &domndat, vflotab[vflonnd].termnum); if (archDomIncl (archptr, &domnsubtab[1], &domndat) == 1) { /* If terminal vertex subdomain included in second subdomain */ compload1 += vflotab[vflonnd].veloval; /* Fixed vertex belongs to second subdomain */ if (-- vflonnd <= vflonum) { /* If matched the location of a slot that also belongs to second subdomain */ compload1 += vflotab[vflonnd].veloval; /* Add load of reached slot to second subdomain */ goto quit; } } else { #ifdef SCOTCH_DEBUG_KGRAPH2 if (archDomIncl (archptr, &domnsubtab[0], &domndat) != 1) { /* If terminal vertex subdomain not included in first subdomain */ errorPrint ("kgraphMapRbVfloSplit: internal error (3)"); return; } #endif /* SCOTCH_DEBUG_KGRAPH2 */ break; /* We have found a candidate for swapping */ } } vflodat = vflotab[vflonum]; /* Swap slots */ vflotab[vflonum] = vflotab[vflonnd]; vflotab[vflonnd] = vflodat; compload0 += vflotab[vflonum ++].veloval; compload1 += vflotab[vflonnd --].veloval; } } else { /* If variable-sized architecture, pseudo-terminals may not always be included */ for (vflonum = 0, vflonnd = vflonbr - 1; vflonum <= vflonnd; ) { #ifdef SCOTCH_DEBUG_KGRAPH2 int o; o = #endif /* SCOTCH_DEBUG_KGRAPH2 */ archDomTerm (archptr, &domndat, vflotab[vflonum].termnum); #ifdef SCOTCH_DEBUG_KGRAPH2 if (o != 0) { errorPrint ("kgraphMapRbVfloSplit: internal error (4)"); return; } #endif /* SCOTCH_DEBUG_KGRAPH2 */ if (archDomIncl (archptr, &domnsubtab[0], &domndat) == 1) { /* If vertex subdomain included in first subdomain */ compload0 += vflotab[vflonum].veloval; /* Fixed vertex belongs to first subdomain */ vflonum ++; continue; /* Keep it in place */ } if (archDomIncl (archptr, &domnsubtab[1], &domndat) == 1) { /* If vertex subdomain included in second subdomain */ compload1 += vflotab[vflonum].veloval; /* Fixed vertex belongs to second subdomain */ vflodat = vflotab[vflonum]; /* Swap slots */ vflotab[vflonum] = vflotab[vflonnd]; vflotab[vflonnd] = vflodat; } else { /* Fixed vertex is more generic than the two subdomains */ vflomax --; /* One less slot to consider in the future */ vflodat = vflotab[vflonum]; /* Swap slots */ vflotab[vflonum] = vflotab[vflonnd]; vflotab[vflonnd] = vflotab[vflomax]; vflotab[vflomax] = vflodat; } vflonnd --; /* One less slot to consider */ } } quit: vflonbrtab[0] = vflonum; vflonbrtab[1] = vflomax - vflonum; vflowgttab[0] = compload0; vflowgttab[1] = compload1; } /* This routine prolongs the given mapping ** with fixed vertices, by merging back with ** regular domains. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int kgraphMapRbVfloMerge ( Mapping * restrict const mappptr, /*+ Mapping to prolong +*/ const Gnum vfixnbr, /*+ Number of fixed vertices in graph +*/ const Anum * restrict const pfixtax, /*+ Array of fixed vertex terminal domains +*/ const Anum vflonbr) /*+ Number of fixed vertex load slots +*/ { ArchDom domndat; Anum domnmax; Anum domnnum; Gnum vertnum; Gnum vertnnd; KgraphMapRbVfloHash * restrict hashtab; /* Hash table for merging fixed vertices */ Gnum hashnbr; /* Prospective number of cells in table */ Gnum hashsiz; /* Size of hash table */ Gnum hashnum; Gnum hashmsk; /* Mask for access to hash table */ const Arch * restrict const archptr = mappptr->archptr; Anum * restrict const parttax = mappptr->parttax; hashnbr = mappptr->domnnbr + vflonbr; for (hashsiz = 0, hashmsk = hashnbr; hashmsk != 0; hashsiz ++, hashmsk >>= 1) ; /* Get upper power of two */ hashsiz = 1 << (hashsiz + 2); /* Fill hash table at 25% maximum */ hashmsk = hashsiz - 1; if ((hashtab = memAlloc (hashsiz * sizeof (KgraphMapRbVfloHash))) == NULL) { /* Use fixed vertex load slots as hash slots */ errorPrint ("kgraphMapRbVfloMerge: out of memory (1)"); return (1); } memSet (hashtab, ~0, hashsiz * sizeof (KgraphMapRbVfloHash)); /* Set all vertex numbers to ~0 */ for (domnnum = 0; domnnum < mappptr->domnnbr; domnnum ++) { /* Load all existing domains into hash table */ Anum termnum; termnum = archDomNum (archptr, &mappptr->domntab[domnnum]); for (hashnum = (termnum * KGRAPHMAPRBVFLOHASHPRIME) & hashmsk; ; hashnum = (hashnum + 1) & hashmsk) { if (hashtab[hashnum].termnum == termnum) /* If domain found */ break; if (hashtab[hashnum].termnum == ~0) { /* If empty slot found */ hashtab[hashnum].termnum = termnum; /* Fill it */ hashtab[hashnum].domnnum = domnnum; break; } } } domnmax = mappptr->domnmax; for (vertnum = mappptr->grafptr->baseval, vertnnd = mappptr->grafptr->vertnnd; vertnum < vertnnd; vertnum ++) { Anum pfixval; pfixval = pfixtax[vertnum]; if (pfixval < 0) { /* If vertex is not a fixed vertex */ #ifdef SCOTCH_DEBUG_KGRAPH2 if (mappptr->parttax[vertnum] < 0) { /* If vertex has not been mapped */ errorPrint ("kgraphMapRbVfloMerge: internal error (1)"); return; } #endif /* SCOTCH_DEBUG_KGRAPH2 */ continue; /* Skip to next vertex */ } #ifdef SCOTCH_DEBUG_KGRAPH2 if (mappptr->parttax[vertnum] >= 0) { /* If fixed vertex has been mapped */ errorPrint ("kgraphMapRbVfloMerge: internal error (2)"); return; } #endif /* SCOTCH_DEBUG_KGRAPH2 */ for (hashnum = (pfixval * KGRAPHMAPRBVFLOHASHPRIME) & hashmsk; ; hashnum = (hashnum + 1) & hashmsk) { if (hashtab[hashnum].termnum == pfixval) /* If hash slot found */ break; if (hashtab[hashnum].termnum == ~0) { /* If hash slot empty */ if (domnnum >= mappptr->domnmax) { if (mapResize (mappptr, mappptr->domnmax + (mappptr->domnmax >> 2) + 8) != 0) { /* Increase size by 25% */ errorPrint ("kgraphMapRbVfloMerge: out of memory (2)"); return (1); } } archDomTerm (archptr, &mappptr->domntab[domnnum], pfixval); /* Add new domain to domain array */ hashtab[hashnum].termnum = pfixval; /* Create slot */ hashtab[hashnum].domnnum = domnnum; domnnum ++; /* One more domain created */ break; } } parttax[vertnum] = hashtab[hashnum].domnnum; /* Assign fixed vertex to existing domain */ } mappptr->domnnbr = domnnum; memFree (hashtab); return (0); } /*****************************************/ /* */ /* This routine computes external gains. */ /* */ /*****************************************/ /* This routines computes the three kinds of ** external loads and gains that can be associated ** with a bipartitioning job: regular external ** gains arising from former bipartitions, fixed ** vertex gains and remapping gains. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int kgraphMapRbBgraph ( const KgraphMapRbData * restrict const dataptr, /*+ Global data +*/ Bgraph * restrict const actgrafptr, /*+ Graph to build +*/ const Graph * restrict const srcgrafptr, /*+ Source graph +*/ const Mapping * restrict const srcmappptr, /*+ Current mapping +*/ const ArchDom * restrict const domnsubtab, /*+ Array of the two subdomains +*/ const Gnum * restrict const vflowgttab) /*+ Array of vertex weight biases +*/ { Gnum actvertnum; /* Number of current active vertex */ Gnum commloadextn0; /* External communication load */ Gnum commgainextn0; /* External communication gain */ Gnum * restrict veextax; /* External gain array */ Gnum veexmsk; /* Flag set if external array useful */ int flagval; int o; const Arch * restrict const archptr = dataptr->mappptr->archptr; const Gnum * restrict const orgverttax = dataptr->grafptr->verttax; const Gnum * restrict const orgvendtax = dataptr->grafptr->vendtax; const Gnum * restrict const orgvelotax = dataptr->grafptr->velotax; const Gnum * restrict const orgedgetax = dataptr->grafptr->edgetax; const Gnum * restrict const orgedlotax = dataptr->grafptr->edlotax; const Mapping * restrict const oldmappptr = dataptr->r.mappptr; const Gnum * restrict const orgvmlotax = dataptr->r.vmlotax; const Anum * restrict const orgpfixtax = dataptr->pfixtax; const Gnum * restrict const actverttax = srcgrafptr->verttax; /* Get pointers from source graph before bgraphInit() */ const Gnum * restrict const actvendtax = srcgrafptr->vendtax; const Gnum * restrict const actedgetax = srcgrafptr->edgetax; const Gnum * restrict const actvnumtax = srcgrafptr->vnumtax; if (bgraphInit (actgrafptr, srcgrafptr, srcmappptr->archptr, domnsubtab, vflowgttab) != 0) { errorPrint ("kgraphMapRbBgraph: cannot create bipartition graph"); return (1); } flagval = KGRAPHMAPRBVEEXNONE; /* Assume no processing */ if ((! archPart (archptr)) && (actvnumtax != NULL)) flagval |= KGRAPHMAPRBVEEXMAPP; if (orgpfixtax != NULL) /* Fixed vertices always imply (actvnumtax != NULL) */ flagval |= KGRAPHMAPRBVEEXVFIX; if (dataptr->r.mappptr != NULL) flagval |= KGRAPHMAPRBVEEXREMA; if (flagval == KGRAPHMAPRBVEEXNONE) /* If nothing to do */ return (0); if ((veextax = (Gnum *) memAlloc (actgrafptr->s.vertnbr * sizeof (Gnum))) == NULL) { errorPrint ("kgraphMapRbBgraph: out of memory"); return (1); } veextax -= actgrafptr->s.baseval; o = 1; /* Assume failure */ veexmsk = 0; /* No useful array entry yet */ commloadextn0 = /* No external communication yet */ commgainextn0 = 0; for (actvertnum = actgrafptr->s.baseval; /* Compute external loads */ actvertnum < actgrafptr->s.vertnnd; actvertnum ++) { Gnum commloadextn; /* External communication load for current vertex */ Gnum commgainextn; /* External communication gain for current vertex */ Gnum orgvertnum; /* Number of current original vertex */ commloadextn = /* Assume no external loads */ commgainextn = 0; if (actvnumtax == NULL) /* If active graph is not a subgraph */ orgvertnum = actvertnum; /* Its number is that of original graph */ else { /* Else we have external edges to process */ orgvertnum = actvnumtax[actvertnum]; /* Get vertex number in original graph */ if ((flagval & KGRAPHMAPRBVEEXEDGE) != 0) { /* If edge-based gains have to be computed */ Gnum orgedgenum; Gnum orgedgennd; Gnum actedgenum; Gnum actedgennd; orgedgenum = orgverttax[orgvertnum]; orgedgennd = orgvendtax[orgvertnum]; actedgenum = actverttax[actvertnum]; actedgennd = actvendtax[actvertnum]; if ((orgedgennd - orgedgenum) != (actedgennd - actedgenum)) { /* If vertex has external edges */ Gnum orgedloval; Gnum actvertend; /* Next internal end vertex index to find in original edge array */ orgedloval = 1; /* Assume no edge loads */ actvertend = (actedgenum >= actedgennd) ? ~0 : actvnumtax[actedgetax[actedgenum]]; for ( ; orgedgenum < orgedgennd; orgedgenum ++) { Gnum orgvertend; orgvertend = orgedgetax[orgedgenum]; if (orgvertend == actvertend) { /* If internal edge found */ actedgenum ++; /* Skip internal active edge */ actvertend = (actedgenum >= actedgennd) ? ~0 : actvnumtax[actedgetax[actedgenum]]; /* Set next internal end vertex index to fetch */ continue; /* Skip internal original edge */ } if (orgedlotax != NULL) orgedloval = orgedlotax[orgedgenum]; if (orgpfixtax != NULL) { ArchDom domndat; Anum pfixval; pfixval = orgpfixtax[orgvertend]; if (pfixval >= 0) { /* If end vertex is fixed */ #ifdef SCOTCH_DEBUG_KGRAPH2 if (dataptr->mappptr->parttax[orgvertend] != ~0) { /* If original vertex has a current part */ errorPrint ("kgraphMapRbBgraph: internal error"); goto fail; } #endif /* SCOTCH_DEBUG_KGRAPH2 */ if (archDomTerm (archptr, &domndat, pfixval) != 0) { /* Get its domain */ errorPrint ("kgraphMapRbBgraph: invalid fixed part array"); goto fail; } commloadextn += (archDomIncl (archptr, &domnsubtab[0], &domndat) != 0) ? 0 : (orgedloval * archDomDist (archptr, &domnsubtab[0], &domndat)); commgainextn += (archDomIncl (archptr, &domnsubtab[1], &domndat) != 0) ? 0 : (orgedloval * archDomDist (archptr, &domnsubtab[1], &domndat)); continue; /* Process next edge */ } } if ((flagval & KGRAPHMAPRBVEEXMAPP) != 0) { /* If mapping */ ArchDom * domnptr; domnptr = mapDomain (srcmappptr, orgvertend); commloadextn += orgedloval * archDomDist (archptr, &domnsubtab[0], domnptr); commgainextn += orgedloval * archDomDist (archptr, &domnsubtab[1], domnptr); } } commloadextn *= dataptr->r.crloval; /* Scale regular, non-remapping gains */ commgainextn *= dataptr->r.crloval; } } } if (oldmappptr != NULL) { /* If remapping gains have to be computed */ ArchDom * domnptr; Gnum edloval; edloval = dataptr->r.cmloval; if (orgvmlotax != NULL) edloval *= orgvmlotax[orgvertnum]; domnptr = mapDomain (oldmappptr, orgvertnum); commloadextn += (archDomIncl (archptr, &domnsubtab[0], domnptr) != 0) ? 0 : (edloval * archDomDist (archptr, &domnsubtab[0], domnptr)); commgainextn += (archDomIncl (archptr, &domnsubtab[1], domnptr) != 0) ? 0 : (edloval * archDomDist (archptr, &domnsubtab[1], domnptr)); } commgainextn -= commloadextn; /* Compute vertex gain */ commloadextn0 += commloadextn; /* Account for external edges */ commgainextn0 += commgainextn; veextax[actvertnum] = commgainextn; /* Record external gain value */ veexmsk |= commgainextn; /* Accumulate non-zero values */ } o = 0; /* Computations succeeded */ fail: if ((o != 0) || (veexmsk == 0)) { /* If external gain array is useless */ memFree (veextax + actgrafptr->s.baseval); /* Forget about it */ return (o); /* Return error code */ } actgrafptr->s.flagval |= BGRAPHFREEVEEX; /* Keep external gain array */ actgrafptr->veextax = veextax; actgrafptr->commload = commloadextn0; /* Account for external gains in future computations */ actgrafptr->commgainextn = commgainextn0; actgrafptr->commloadextn0 = commloadextn0; actgrafptr->commgainextn0 = commgainextn0; #ifdef SCOTCH_DEBUG_KGRAPH2 if (bgraphCheck (actgrafptr) != 0) { errorPrint ("kgraphMapRbBgraph: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/library_graph_order.c0000644002563400244210000005217412473175350026036 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010,2012-2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_order.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the graph **/ /** ordering routines of the libSCOTCH **/ /** library. **/ /** **/ /** DATES : # Version 3.2 : from : 19 aug 1998 **/ /** to 22 aug 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 27 mar 1999 **/ /** # Version 4.0 : from : 29 jan 2002 **/ /** to 08 sep 2006 **/ /** # Version 5.0 : from : 19 dec 2006 **/ /** to 04 aug 2007 **/ /** # Version 5.1 : from : 30 oct 2007 **/ /** to 14 aug 2010 **/ /** # Version 6.0 : from : 08 jan 2012 **/ /** to 15 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "order.h" #include "hgraph.h" #include "hgraph_order_st.h" #include "library_order.h" #include "scotch.h" /************************************/ /* */ /* These routines are the C API for */ /* the graph ordering routines. */ /* */ /************************************/ /*+ This routine initializes an API ordering *** with respect to the given source graph *** and the locations of output parameters. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphOrderInit ( const SCOTCH_Graph * const grafptr, /*+ Graph to order +*/ SCOTCH_Ordering * const ordeptr, /*+ Ordering structure to initialize +*/ SCOTCH_Num * const permtab, /*+ Direct permutation array +*/ SCOTCH_Num * const peritab, /*+ Inverse permutation array +*/ SCOTCH_Num * const cblkptr, /*+ Pointer to number of column blocks +*/ SCOTCH_Num * const rangtab, /*+ Column block range array +*/ SCOTCH_Num * const treetab) /*+ Separator tree array +*/ { const Graph * srcgrafptr; LibOrder * libordeptr; #ifdef SCOTCH_DEBUG_LIBRARY1 if (sizeof (SCOTCH_Ordering) < sizeof (LibOrder)) { errorPrint ("SCOTCH_graphOrderInit: internal error"); return (1); } #endif /* SCOTCH_DEBUG_LIBRARY1 */ srcgrafptr = (Graph *) grafptr; /* Use structure as source graph */ libordeptr = (LibOrder *) ordeptr; libordeptr->permtab = ((permtab == NULL) || ((void *) permtab == (void *) grafptr)) ? NULL : (Gnum *) permtab; libordeptr->peritab = ((peritab == NULL) || ((void *) peritab == (void *) grafptr)) ? NULL : (Gnum *) peritab; libordeptr->cblkptr = ((cblkptr == NULL) || ((void *) cblkptr == (void *) grafptr)) ? NULL : (Gnum *) cblkptr; libordeptr->rangtab = ((rangtab == NULL) || ((void *) rangtab == (void *) grafptr)) ? NULL : (Gnum *) rangtab; libordeptr->treetab = ((treetab == NULL) || ((void *) treetab == (void *) grafptr)) ? NULL : (Gnum *) treetab; return (orderInit (&libordeptr->o, srcgrafptr->baseval, srcgrafptr->vertnbr, libordeptr->peritab)); } /*+ This routine frees an API ordering. *** It returns: *** - VOID : in all cases. +*/ void SCOTCH_graphOrderExit ( const SCOTCH_Graph * const grafptr, SCOTCH_Ordering * const ordeptr) { orderExit (&((LibOrder *) ordeptr)->o); } /*+ This routine loads the contents of *** the given ordering from the given stream. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphOrderLoad ( const SCOTCH_Graph * const grafptr, /*+ Graph to order +*/ SCOTCH_Ordering * restrict const ordeptr, /*+ Ordering to load +*/ FILE * restrict const stream) /*+ Output stream +*/ { const Graph * srcgrafptr; LibOrder * libordeptr; srcgrafptr = (Graph *) grafptr; libordeptr = (LibOrder *) ordeptr; if (orderLoad (&libordeptr->o, srcgrafptr->vlbltax, stream) != 0) return (1); if (libordeptr->permtab != NULL) /* Build inverse permutation if wanted */ orderPeri (libordeptr->o.peritab, srcgrafptr->baseval, libordeptr->o.vnodnbr, libordeptr->permtab, srcgrafptr->baseval); return (0); } /*+ This routine saves the contents of *** the given ordering to the given stream. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphOrderSave ( const SCOTCH_Graph * const grafptr, /*+ Graph to order +*/ const SCOTCH_Ordering * const ordeptr, /*+ Ordering to save +*/ FILE * const stream) /*+ Output stream +*/ { return (orderSave (&((LibOrder *) ordeptr)->o, ((Graph *) grafptr)->vlbltax + ((Graph *) grafptr)->baseval, stream)); } /*+ This routine saves to the given stream *** the mapping data associated with the *** given ordering. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphOrderSaveMap ( const SCOTCH_Graph * const grafptr, /*+ Graph to order +*/ const SCOTCH_Ordering * const ordeptr, /*+ Ordering to save +*/ FILE * const stream) /*+ Output stream +*/ { return (orderSaveMap (&((LibOrder *) ordeptr)->o, ((Graph *) grafptr)->vlbltax + ((Graph *) grafptr)->baseval, stream)); } /*+ This routine saves to the given stream *** the separator tree data associated with *** the given ordering. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphOrderSaveTree ( const SCOTCH_Graph * const grafptr, /*+ Graph to order +*/ const SCOTCH_Ordering * const ordeptr, /*+ Ordering to save +*/ FILE * const stream) /*+ Output stream +*/ { return (orderSaveTree (&((LibOrder *) ordeptr)->o, ((Graph *) grafptr)->vlbltax + ((Graph *) grafptr)->baseval, stream)); } /*+ This routine computes an ordering *** of the API ordering structure with *** respect to the given strategy. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphOrderCompute ( SCOTCH_Graph * const grafptr, /*+ Graph to order +*/ SCOTCH_Ordering * const ordeptr, /*+ Ordering to compute +*/ SCOTCH_Strat * const stratptr) /*+ Ordering strategy +*/ { return (SCOTCH_graphOrderComputeList (grafptr, ordeptr, ((Graph *) grafptr)->vertnbr, NULL, stratptr)); } /*+ This routine computes a partial ordering *** of the listed vertices of the API ordering *** structure graph with respect to the given *** strategy. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphOrderComputeList ( SCOTCH_Graph * const grafptr, /*+ Graph to order +*/ SCOTCH_Ordering * const ordeptr, /*+ Ordering to compute +*/ const SCOTCH_Num listnbr, /*+ Number of vertices in list +*/ const SCOTCH_Num * const listtab, /*+ List of vertex indices to order +*/ SCOTCH_Strat * const stratptr) /*+ Ordering strategy +*/ { const Graph * restrict srcgrafptr; LibOrder * libordeptr; /* Pointer to ordering */ Hgraph halgrafdat; /* Halo source graph structure */ Hgraph halgraftmp; /* Halo source graph structure */ Hgraph * halgrafptr; /* Pointer to halo graph structure */ const Strat * ordstratptr; /* Pointer to ordering strategy */ OrderCblk * cblkptr; srcgrafptr = (Graph *) grafptr; libordeptr = (LibOrder *) ordeptr; /* Get ordering */ #ifdef SCOTCH_DEBUG_LIBRARY1 if ((listnbr < 0) || (listnbr > srcgrafptr->vertnbr)) { errorPrint ("SCOTCH_graphOrderComputeList: invalid parameters (1)"); return (1); } #endif /* SCOTCH_DEBUG_LIBRARY1 */ #ifdef SCOTCH_DEBUG_LIBRARY2 if (graphCheck (srcgrafptr) != 0) { errorPrint ("SCOTCH_graphOrderComputeList: invalid input graph"); return (1); } #endif /* SCOTCH_DEBUG_LIBRARY2 */ if (listnbr == 0) { /* If empty list, return identity peremutation */ intAscn (libordeptr->o.peritab, srcgrafptr->vertnbr, srcgrafptr->baseval); return (0); } if (*((Strat **) stratptr) == NULL) /* Set default ordering strategy if necessary */ SCOTCH_stratGraphOrderBuild (stratptr, SCOTCH_STRATQUALITY, 0, 0.2); ordstratptr = *((Strat **) stratptr); if (ordstratptr->tabl != &hgraphorderststratab) { errorPrint ("SCOTCH_graphOrderComputeList: not an ordering strategy"); return (1); } memCpy (&halgrafdat.s, grafptr, sizeof (Graph)); /* Copy non-halo graph data */ halgrafdat.s.flagval &= ~GRAPHFREETABS; /* Do not allow to free arrays */ halgrafdat.s.edlotax = NULL; /* Don't mind about edge loads */ halgrafdat.vnohnbr = halgrafdat.s.vertnbr; /* All vertices are non-halo */ halgrafdat.vnohnnd = halgrafdat.s.vertnnd; /* No halo present */ halgrafdat.vnhdtax = halgrafdat.s.vendtax; /* End of non-halo vertices */ halgrafdat.vnlosum = halgrafdat.s.velosum; /* Sum of node vertex weights */ halgrafdat.enohnbr = halgrafdat.s.edgenbr; /* No halo present */ halgrafdat.enohsum = halgrafdat.s.edlosum; halgrafdat.levlnum = 0; /* No nested dissection yet */ if (listnbr == srcgrafptr->vertnbr) { /* If work on full graph */ halgrafptr = &halgrafdat; cblkptr = &libordeptr->o.cblktre; } else { VertList listdat; Gnum * restrict peritax; Gnum listnum; Gnum vertnum; Gnum halonum; if ((cblkptr = (OrderCblk *) memAlloc (2 * sizeof (OrderCblk))) == NULL) { errorPrint ("SCOTCH_graphOrderComputeList: out of memory"); return (1); } libordeptr->o.treenbr = 3; libordeptr->o.cblknbr = 2; libordeptr->o.cblktre.typeval = ORDERCBLKNEDI; /* Node becomes a (fake) nested dissection node */ libordeptr->o.cblktre.vnodnbr = srcgrafptr->vertnbr; libordeptr->o.cblktre.cblknbr = 2; libordeptr->o.cblktre.cblktab = cblkptr; cblkptr[0].typeval = ORDERCBLKOTHR; /* Build column blocks */ cblkptr[0].vnodnbr = listnbr; cblkptr[0].cblknbr = 0; cblkptr[0].cblktab = NULL; cblkptr[1].typeval = ORDERCBLKOTHR; cblkptr[1].vnodnbr = srcgrafptr->vertnbr - listnbr; cblkptr[1].cblknbr = 0; cblkptr[1].cblktab = NULL; memSet (libordeptr->o.peritab, 0, srcgrafptr->vertnbr * sizeof (Gnum)); /* Fill inverse permutation with dummy values */ for (listnum = 0, peritax = libordeptr->o.peritab - srcgrafptr->baseval; listnum < listnbr; listnum ++) { #ifdef SCOTCH_DEBUG_LIBRARY2 if ((listtab[listnum] < srcgrafptr->baseval) || (listtab[listnum] >= srcgrafptr->vertnnd)) { errorPrint ("SCOTCH_graphOrderComputeList: invalid parameters (2)"); return (1); } #endif /* SCOTCH_DEBUG_LIBRARY2 */ peritax[listtab[listnum]] = ~0; /* TRICK: use peritab as flag array to mark used vertices */ } for (vertnum = halonum = srcgrafptr->vertnnd - 1; vertnum >= srcgrafptr->baseval; vertnum --) { if (peritax[vertnum] == 0) peritax[halonum --] = vertnum; } #ifdef SCOTCH_DEBUG_LIBRARY2 if (halonum != (listnbr + srcgrafptr->baseval - 1)) { errorPrint ("SCOTCH_graphOrderComputeList: internal error"); return (1); } #endif /* SCOTCH_DEBUG_LIBRARY2 */ listdat.vnumnbr = listnbr; listdat.vnumtab = (Gnum * const) listtab; if (hgraphInduceList (&halgrafdat, &listdat, srcgrafptr->vertnbr - listnbr, &halgraftmp) != 0) { errorPrint ("SCOTCH_graphOrderComputeList: cannot create induced subgraph"); return (1); } halgrafptr = &halgraftmp; } intRandInit (); /* Check that random number generator is initialized */ hgraphOrderSt (halgrafptr, &libordeptr->o, 0, cblkptr, ordstratptr); if (halgrafptr != &halgrafdat) /* If induced subgraph created */ hgraphExit (halgrafptr); /* Free it */ #ifdef SCOTCH_DEBUG_LIBRARY2 if (orderCheck (&libordeptr->o) != 0) return (1); #endif /* SCOTCH_DEBUG_LIBRARY2 */ if (libordeptr->permtab != NULL) /* Build direct permutation if wanted */ orderPeri (libordeptr->o.peritab, srcgrafptr->baseval, libordeptr->o.vnodnbr, libordeptr->permtab, srcgrafptr->baseval); if (libordeptr->rangtab != NULL) /* Build range array if column block data wanted */ orderRang (&libordeptr->o, libordeptr->rangtab); if (libordeptr->treetab != NULL) /* Build separator tree array if wanted */ orderTree (&libordeptr->o, libordeptr->treetab); if (libordeptr->cblkptr != NULL) /* Set number of column blocks if wanted */ *(libordeptr->cblkptr) = libordeptr->o.cblknbr; return (0); } /*+ This routine computes an ordering *** of the API ordering structure with *** respect to the given strategy. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphOrder ( SCOTCH_Graph * const grafptr, /*+ Graph to order +*/ SCOTCH_Strat * const stratptr, /*+ Ordering strategy +*/ SCOTCH_Num * const permtab, /*+ Ordering permutation +*/ SCOTCH_Num * const peritab, /*+ Inverse permutation array +*/ SCOTCH_Num * const cblkptr, /*+ Pointer to number of column blocks +*/ SCOTCH_Num * const rangtab, /*+ Column block range array +*/ SCOTCH_Num * const treetab) /*+ Separator tree array +*/ { SCOTCH_Ordering ordedat; int o; if (SCOTCH_graphOrderInit (grafptr, &ordedat, permtab, peritab, cblkptr, rangtab, treetab) != 0) return (1); o = SCOTCH_graphOrderCompute (grafptr, &ordedat, stratptr); SCOTCH_graphOrderExit (grafptr, &ordedat); return (o); } /*+ This routine computes an ordering *** of the subgraph of the API ordering *** structure graph induced by the given *** vertex list, with respect to the given *** strategy. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphOrderList ( SCOTCH_Graph * const grafptr, /*+ Graph to order +*/ const SCOTCH_Num listnbr, /*+ Number of vertices in list +*/ const SCOTCH_Num * const listtab, /*+ List of vertex indices to order +*/ SCOTCH_Strat * const stratptr, /*+ Ordering strategy +*/ SCOTCH_Num * const permtab, /*+ Ordering permutation +*/ SCOTCH_Num * const peritab, /*+ Inverse permutation array +*/ SCOTCH_Num * const cblkptr, /*+ Pointer to number of column blocks +*/ SCOTCH_Num * const rangtab, /*+ Column block range array +*/ SCOTCH_Num * const treetab) /*+ Column block range array +*/ { SCOTCH_Ordering ordedat; int o; SCOTCH_graphOrderInit (grafptr, &ordedat, permtab, peritab, cblkptr, rangtab, treetab); o = SCOTCH_graphOrderComputeList (grafptr, &ordedat, listnbr, listtab, stratptr); SCOTCH_graphOrderExit (grafptr, &ordedat); return (o); } /*+ This routine checks the consistency *** of the given graph ordering. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphOrderCheck ( const SCOTCH_Graph * const grafptr, const SCOTCH_Ordering * const ordeptr) /*+ Ordering to check +*/ { return (orderCheck (&((LibOrder *) ordeptr)->o)); } /*+ This routine parses the given *** graph ordering strategy. *** It returns: *** - 0 : if string successfully scanned. *** - !0 : on error. +*/ int SCOTCH_stratGraphOrder ( SCOTCH_Strat * const stratptr, const char * const string) { if (*((Strat **) stratptr) != NULL) stratExit (*((Strat **) stratptr)); if ((*((Strat **) stratptr) = stratInit (&hgraphorderststratab, string)) == NULL) { errorPrint ("SCOTCH_stratGraphOrder: error in ordering strategy"); return (1); } return (0); } /*+ This routine provides predefined *** ordering strategies. *** It returns: *** - 0 : if string successfully initialized. *** - !0 : on error. +*/ int SCOTCH_stratGraphOrderBuild ( SCOTCH_Strat * const stratptr, /*+ Strategy to create +*/ const SCOTCH_Num flagval, /*+ Desired characteristics +*/ const SCOTCH_Num levlnbr, /*+ Number of nested dissection levels +*/ const double balrat) /*+ Desired imbalance ratio +*/ { char bufftab[8192]; /* Should be enough */ char levltab[32]; char bbaltab[32]; char * sepaptr; char * tstsptr; char * oleaptr; char * osepptr; sprintf (bbaltab, "%lf", balrat); sprintf (levltab, GNUMSTRING, levlnbr); strcpy (bufftab, "c{rat=0.7,cpr=n{sep=/()?m{rat=0.7,vert=100,low=h{pass=10},asc=b{width=3,bnd=f{bal=},org=(|h{pass=10})f{bal=}}};,ole=,ose=},unc=n{sep=/()?m{rat=0.7,vert=100,low=h{pass=10},asc=b{width=3,bnd=f{bal=},org=(|h{pass=10})f{bal=}}};,ole=,ose=}}"); switch (flagval & (SCOTCH_STRATLEVELMIN | SCOTCH_STRATLEVELMAX)) { case SCOTCH_STRATLEVELMIN : tstsptr = "(levl<)|(vert>240)"; break; case SCOTCH_STRATLEVELMAX : tstsptr = "(levl<)&(vert>240)"; break; case (SCOTCH_STRATLEVELMIN | SCOTCH_STRATLEVELMAX) : tstsptr = "levl<"; break; default : tstsptr = "vert>240"; break; } sepaptr = ((flagval & SCOTCH_STRATSPEED) != 0) ? "" : "|m{rat=0.7,vert=100,low=h{pass=10},asc=b{width=3,bnd=f{bal=},org=(|h{pass=10})f{bal=}}}"; oleaptr = ((flagval & SCOTCH_STRATLEAFSIMPLE) != 0) ? "s" : "f{cmin=15,cmax=100000,frat=0.0}"; osepptr = ((flagval & SCOTCH_STRATSEPASIMPLE) != 0) ? "s" : "g"; stringSubst (bufftab, "", sepaptr); stringSubst (bufftab, "", tstsptr); stringSubst (bufftab, "", levltab); stringSubst (bufftab, "", oleaptr); stringSubst (bufftab, "", osepptr); stringSubst (bufftab, "", bbaltab); if (SCOTCH_stratGraphOrder (stratptr, bufftab) != 0) { errorPrint ("SCOTCH_stratGraphOrderBuild: error in sequential ordering strategy"); return (1); } return (0); } scotch-6.0.4.dfsg/src/libscotch/kgraph_map_ml.h0000644002563400244210000000752712342605432024620 0ustar trophimeutilisateurs du domaine/* Copyright 2010,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph_map_ml.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the multi-level graph mapping **/ /** routines. **/ /** **/ /** DATES : # Version 5.1 : from : 10 jul 2010 **/ /** to 10 jul 2010 **/ /** # Version 6.0 : from : 03 mar 2011 **/ /** to 01 jun 2014 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct KgraphMapMlParam_ { INT coarnbr; /*+ Minimum number of vertices +*/ double coarval; /*+ Coarsening ratio +*/ Strat * stratlow; /*+ Strategy at lowest level +*/ Strat * stratasc; /*+ Strategy at ascending levels +*/ int typeval; /*+ Not used +*/ } KgraphMapMlParam; /* ** The function prototypes. */ #ifndef KGRAPH_MAP_ML #define static #endif static int kgraphMapMlCoarsen (Kgraph * const, Kgraph * restrict const, GraphCoarsenMulti * restrict * const, const KgraphMapMlParam * const); static int kgraphMapMlUncoarsen (Kgraph * restrict const, Kgraph * const, const GraphCoarsenMulti * const); int kgraphMapMl (Kgraph * restrict const, const KgraphMapMlParam * const); static int kgraphMapMl2 (Kgraph * restrict const, const KgraphMapMlParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/dorder_io.c0000644002563400244210000002507411631447170023760 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dorder_io.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles distributed **/ /** orderings. **/ /** **/ /** DATES : # Version 5.0 : from : 27 apr 2006 **/ /** to 13 jun 2008 **/ /** # Version 5.1 : from : 30 jul 2010 **/ /** to 11 aug 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DORDER #include "module.h" #include "common.h" #include "comm.h" #include "dgraph.h" #include "dorder.h" #include "order.h" /************************************/ /* */ /* These routines handle orderings. */ /* */ /************************************/ /* This routine saves a distributed ordering. ** The distributed graph structure is provided ** to access the distribution of vertex labels, ** whenever present. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int dorderSave ( const Dorder * restrict const ordeptr, const Dgraph * restrict const grafptr, FILE * restrict const stream) { Gnum * restrict peritab; Gnum * restrict permtab; Gnum * restrict vlbltax; int procglbnbr; int reduloctab[3]; int reduglbtab[3]; int protnum; if (stream != NULL) { /* If file provided */ reduloctab[0] = 1; /* This process is the root */ reduloctab[1] = ordeptr->proclocnum; /* Get its rank */ } else { reduloctab[0] = /* This process is not the root */ reduloctab[1] = 0; } reduloctab[2] = (grafptr->vlblloctax != NULL) ? 1 : 0; /* See if vertex labels provided */ if (MPI_Allreduce (reduloctab, reduglbtab, 3, MPI_INT, MPI_SUM, ordeptr->proccomm) != MPI_SUCCESS) { errorPrint ("dorderSave: communication error (1)"); return (1); } if (reduglbtab[0] != 1) { errorPrint ("dorderSave: should have only one root"); return (1); } MPI_Comm_size (ordeptr->proccomm, &procglbnbr); if ((reduglbtab[2] != 0) && (reduglbtab[2] != procglbnbr)) { errorPrint ("dorderSave: inconsistent parameters"); return (1); } protnum = (int) reduglbtab[1]; /* Get rank of root process */ reduloctab[0] = 0; permtab = NULL; if (protnum == ordeptr->proclocnum) { Gnum vlblnbr; vlblnbr = (grafptr->vlblloctax != NULL) ? ordeptr->vnodglbnbr : 0; if (memAllocGroup ((void **) (void *) &permtab, (size_t) (ordeptr->vnodglbnbr * sizeof (Gnum)), &peritab, (size_t) (ordeptr->vnodglbnbr * sizeof (Gnum)), &vlbltax, (size_t) (vlblnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("dorderSave: out of memory"); #ifdef SCOTCH_DEBUG_DORDER1 reduloctab[0] = 1; #else /* SCOTCH_DEBUG_DORDER1 */ return (1); #endif /* SCOTCH_DEBUG_DORDER1 */ } } #ifdef SCOTCH_DEBUG_DORDER1 /* This communication cannot be covered by a useful one */ if (MPI_Bcast (&reduloctab[0], 1, MPI_INT, protnum, ordeptr->proccomm) != MPI_SUCCESS) { errorPrint ("dorderSave: communication error (2)"); if (permtab != NULL); memFree (permtab); /* Free group leader */ return (1); } if (reduloctab[0] != 0) return (1); #endif /* SCOTCH_DEBUG_DORDER1 */ if (grafptr->vlblloctax != NULL) { if (commGatherv (grafptr->vlblloctax + grafptr->baseval, grafptr->vertlocnbr, GNUM_MPI, vlbltax, grafptr->proccnttab, grafptr->procdsptab, GNUM_MPI, protnum, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dorderSave: communication error (3)"); return (1); } } if (protnum == ordeptr->proclocnum) { Gnum vertnum; for (vertnum = 0; vertnum < ordeptr->vnodglbnbr; ) { /* Till all inverse permutation indices collected */ const DorderLink * linkptr; for (linkptr = ordeptr->linkdat.nextptr; linkptr != &ordeptr->linkdat; linkptr = linkptr->nextptr) { const DorderCblk * cblkptr; cblkptr = (DorderCblk *) linkptr; /* TRICK: FIRST */ if (((cblkptr->typeval & DORDERCBLKLEAF) != 0) && (cblkptr->data.leaf.ordelocval == vertnum) && /* If column block fragment starts at proper index */ (cblkptr->data.leaf.vnodlocnbr > 0)) { /* And is not an empty local block with relevent data elsewhere */ memCpy (peritab + vertnum, cblkptr->data.leaf.periloctab, cblkptr->data.leaf.vnodlocnbr * sizeof (Gnum)); vertnum += cblkptr->data.leaf.vnodlocnbr; break; } } if (linkptr == &ordeptr->linkdat) { /* If fragment not found locally */ MPI_Status statdat; int recvnbr; if (MPI_Bcast (&vertnum, 1, GNUM_MPI, protnum, ordeptr->proccomm) != MPI_SUCCESS) { /* Broadcast missing fragment */ errorPrint ("dorderSave: communication error (4)"); memFree (permtab); /* Free group leader */ return (1); } if (MPI_Recv (peritab + vertnum, ordeptr->vnodglbnbr - vertnum, GNUM_MPI, MPI_ANY_SOURCE, DORDERTAGPERI, ordeptr->proccomm, &statdat) != MPI_SUCCESS) { errorPrint ("dorderSave: communication error (5)"); return (1); } MPI_Get_count (&statdat, GNUM_MPI, &recvnbr); vertnum += recvnbr; } } vertnum = -1; /* Indicate termination */ if (MPI_Bcast (&vertnum, 1, GNUM_MPI, protnum, ordeptr->proccomm) != MPI_SUCCESS) { errorPrint ("dorderSave: communication error (6)"); memFree (permtab); /* Free group leader */ return (1); } if (fprintf (stream, GNUMSTRING "\n", (Gnum) ordeptr->vnodglbnbr) == EOF) { errorPrint ("dorderSave: bad output (1)"); memFree (permtab); return (1); } orderPeri (peritab, ordeptr->baseval, ordeptr->vnodglbnbr, permtab, ordeptr->baseval); /* Compute direct permutation */ if (grafptr->vlblloctax != NULL) { /* If ordering has label array */ vlbltax -= ordeptr->baseval; /* Base label array */ for (vertnum = 0; vertnum < ordeptr->vnodglbnbr; vertnum ++) { if (fprintf (stream, GNUMSTRING "\t" GNUMSTRING "\n", (Gnum) vlbltax[vertnum + ordeptr->baseval], (Gnum) vlbltax[permtab[vertnum]]) == EOF) { errorPrint ("dorderSave: bad output (2)"); memFree (permtab); return (1); } } } else { for (vertnum = 0; vertnum < ordeptr->vnodglbnbr; vertnum ++) { if (fprintf (stream, GNUMSTRING "\t" GNUMSTRING "\n", (Gnum) (vertnum + ordeptr->baseval), (Gnum) permtab[vertnum]) == EOF) { errorPrint ("dorderSave: bad output (3)"); memFree (permtab); return (1); } } } memFree (permtab); /* Free group leader */ } else { while (1) { const DorderLink * linkptr; Gnum vertnum; if (MPI_Bcast (&vertnum, 1, GNUM_MPI, protnum, ordeptr->proccomm) != MPI_SUCCESS) { errorPrint ("dorderSave: communication error (7)"); return (1); } if (vertnum == -1) /* If asked to quit */ break; /* Finish */ for (linkptr = ordeptr->linkdat.nextptr; linkptr != &ordeptr->linkdat; linkptr = linkptr->nextptr) { const DorderCblk * cblkptr; cblkptr = (DorderCblk *) linkptr; /* TRICK: FIRST */ if (((cblkptr->typeval & DORDERCBLKLEAF) != 0) && /* If matching column block fragment found */ (cblkptr->data.leaf.ordelocval == vertnum) && (cblkptr->data.leaf.vnodlocnbr > 0)) { /* And is not an empty local block with relevent data elsewhere */ if (MPI_Send (cblkptr->data.leaf.periloctab, cblkptr->data.leaf.vnodlocnbr, GNUM_MPI, protnum, DORDERTAGPERI, ordeptr->proccomm) != MPI_SUCCESS) { errorPrint ("dorderSave: communication error (8)"); return (1); } break; } } } } return (0); } scotch-6.0.4.dfsg/src/libscotch/library_dgraph_halo_f.c0000644002563400244210000001131712055776411026312 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2009,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_halo_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API for **/ /** the distributed source graph handling **/ /** routines of the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 17 jul 2007 **/ /** to 02 aug 2007 **/ /** # Version 5.1 : from : 09 may 2009 **/ /** to 10 may 2009 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "ptscotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the distributed graph handling */ /* routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFDGRAPHGHST, scotchfdgraphghst, ( \ SCOTCH_Dgraph * const grafptr, \ int * const revaptr), \ (grafptr, revaptr)) { *revaptr = SCOTCH_dgraphGhst (grafptr); } /* ** */ FORTRAN ( \ SCOTCHFDGRAPHHALO, scotchfdgraphhalo, ( \ SCOTCH_Dgraph * const grafptr, \ void * const datatab, \ MPI_Fint * const typeptr, \ int * const revaptr), \ (grafptr, datatab, typeptr, revaptr)) { MPI_Datatype typeval; typeval = MPI_Type_f2c (*typeptr); *revaptr = SCOTCH_dgraphHalo (grafptr, datatab, typeval); } /* ** */ FORTRAN ( \ SCOTCHFDGRAPHHALOASYNC, scotchfdgraphhaloasync, ( \ SCOTCH_Dgraph * const grafptr, \ void * const datatab, \ MPI_Fint * const typeptr, \ SCOTCH_DgraphHaloReq * const requptr, \ int * const revaptr), \ (grafptr, datatab, typeptr, requptr, revaptr)) { MPI_Datatype typeval; typeval = MPI_Type_f2c (*typeptr); *revaptr = SCOTCH_dgraphHaloAsync (grafptr, datatab, typeval, requptr); } /* ** */ FORTRAN ( \ SCOTCHFDGRAPHHALOWAIT, scotchfdgraphhalowait, ( \ SCOTCH_DgraphHaloReq * const requptr, \ int * const revaptr), \ (requptr, revaptr)) { *revaptr = SCOTCH_dgraphHaloWait (requptr); } scotch-6.0.4.dfsg/src/libscotch/library_memory.c0000644002563400244210000000622012410344531025027 0ustar trophimeutilisateurs du domaine/* Copyright 2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_memory.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the memory **/ /** handling routines. **/ /** **/ /** DATES : # Version 6.0 : from : 21 sep 2014 **/ /** to 23 sep 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /************************************/ /* */ /* These routines are the C API for */ /* the memory management routines. */ /* */ /************************************/ /*+ This routine frees a structure allocated *** by a SCOTCH_*Alloc () routine. *** It returns: *** - void : in all cases. +*/ void SCOTCH_memFree ( void * const dataptr) { memFree (dataptr); } /*+ This routine returns the size, in bytes, *** of a SCOTCH_Num. *** It returns: *** - void : in all cases. +*/ int SCOTCH_numSizeof () { return (sizeof (SCOTCH_Num)); } scotch-6.0.4.dfsg/src/libscotch/library_graph_map_io.h0000644002563400244210000000527111631447170026165 0ustar trophimeutilisateurs du domaine/* Copyright 2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_map_io.h **/ /** **/ /** AUTHOR : Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : These lines are the declarations for **/ /** the API mapping handling routines. **/ /** **/ /** DATES : # Version 6.0 : from : 17 apr 2011 **/ /** to 17 apr 2011 **/ /** **/ /************************************************************/ /* ** The type definitions. */ /*+ The sort structure, used to sort graph vertices by label. +*/ typedef struct VertSort_ { Gnum labl; /*+ Vertex label +*/ Gnum num; /*+ Vertex number +*/ } VertSort; scotch-6.0.4.dfsg/src/libscotch/library_graph_map_view.c0000644002563400244210000006540612474564511026536 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2011,2015 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_map_view.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module is the API for the mapping **/ /** routines of the libSCOTCH library. **/ /** **/ /** DATES : # Version 3.2 : from : 19 aug 1998 **/ /** to 20 aug 1998 **/ /** # Version 3.3 : from : 19 oct 1998 **/ /** to 30 mar 1999 **/ /** # Version 3.4 : from : 01 nov 2001 **/ /** to 01 nov 2001 **/ /** # Version 4.0 : from : 13 jan 2004 **/ /** to 30 nov 2006 **/ /** # Version 5.0 : from : 04 feb 2007 **/ /** to 03 apr 2008 **/ /** # Version 5.1 : from : 27 jul 2008 **/ /** to 11 aug 2010 **/ /** # Version 6.0 : from : 03 mar 2011 **/ /** to 01 mar 2015 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #define LIBRARY_GRAPH_MAP_VIEW #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "arch.h" #include "mapping.h" #include "kgraph.h" #include "library_mapping.h" #include "library_graph_map_view.h" #include "scotch.h" /************************************/ /* */ /* These routines are the C API for */ /* the mapping routines. */ /* */ /************************************/ /*+ This routine writes standard or raw *** mapping or remapping statistics to *** the given stream. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ static int graphMapView2 ( const SCOTCH_Graph * const libgrafptr, /*+ Ordered graph +*/ const SCOTCH_Mapping * const libmappptr, /*+ Computed mapping +*/ const SCOTCH_Mapping * const libmapoptr, /*+ Old mapping (equal to NULL if no repartitioning) +*/ const double emraval, /*+ Edge migration ratio +*/ SCOTCH_Num * vmlotab, /*+ Vertex migration cost array +*/ Gnum flagval, /*+ 0 : standard output, !0 : raw output for curves +*/ FILE * const stream) /*+ Output stream +*/ { const Graph * restrict grafptr; const Arch * restrict archptr; LibMapping * restrict lmapptr; LibMapping * restrict lmaoptr; Mapping mappdat; Anum * restrict parttax; /* Part array */ Anum * restrict parotax; /* Old part array */ MappingSort * restrict domntab; /* Pointer to domain sort array */ ArchDom domnfrst; /* Largest domain in architecture */ ArchDom domnorg; /* Vertex domain */ ArchDom domnend; /* End domain */ ArchDom domnold; /* Vertex old domain */ Anum tgtnbr; /* Number of processors in target topology */ Anum mapnbr; /* Number of processors effectively used */ Anum mapnum; double mapavg; /* Average mapping weight */ Gnum mapmin; Gnum mapmax; Gnum mapsum; /* (Partial) sum of vertex loads */ double mapdlt; double mapmmy; /* Maximum / average ratio */ Anum * restrict nghbtab; /* Table storing neighbors of current subdomain */ Anum nghbnbr; Anum nghbmin; Anum nghbmax; Anum nghbsum; Gnum vertnum; Gnum veloval; Gnum edloval; Gnum commdist[256]; /* Array of load distribution */ Gnum commload; /* Total edge load (edge sum) */ Gnum commdilat; /* Total edge dilation */ Gnum commexpan; /* Total edge expansion */ Anum distmax; Anum distval; Gnum diammin; Gnum diammax; Gnum diamsum; Gnum migrnbr; double migrloadavg; double migrdistavg; double migrcostsum; Gnum * restrict vmlotax; const Gnum * restrict const verttax = ((Graph *) libgrafptr)->verttax; const Gnum * restrict const vendtax = ((Graph *) libgrafptr)->vendtax; const Gnum * restrict const velotax = ((Graph *) libgrafptr)->velotax; const Gnum * restrict const edgetax = ((Graph *) libgrafptr)->edgetax; const Gnum * restrict const edlotax = ((Graph *) libgrafptr)->edlotax; #ifdef SCOTCH_DEBUG_LIBRARY1 if (sizeof (SCOTCH_Mapping) < sizeof (LibMapping)) { errorPrint ("SCOTCH_graphMapView: internal error"); return (1); } #endif /* SCOTCH_DEBUG_LIBRARY1 */ lmapptr = (LibMapping *) libmappptr; grafptr = lmapptr->grafptr; #ifdef SCOTCH_DEBUG_LIBRARY1 if ((Graph *) libgrafptr != grafptr) { errorPrint ("SCOTCH_graphMapView: input graph must be the same as mapping graph"); return (1); } #endif /* SCOTCH_DEBUG_LIBRARY1 */ if ((grafptr->vertnbr == 0) || /* Return if nothing to do */ (grafptr->edgenbr == 0)) return (0); if (libmapoptr != NULL) { lmaoptr = (LibMapping *) libmapoptr; parotax = lmaoptr->parttab; } else { lmaoptr = NULL; parotax = NULL; } if (vmlotab != NULL) vmlotax = (Gnum *) vmlotab - grafptr->baseval; else vmlotax = NULL; #ifdef SCOTCH_DEBUG_LIBRARY1 if (lmapptr->parttab == NULL) { errorPrint ("SCOTCH_graphMapView: the mapping given in input must contain a valid partition array"); return (1); } #endif /* SCOTCH_DEBUG_LIBRARY1 */ archptr = lmapptr->archptr; parttax = lmapptr->parttab; if (memAllocGroup ((void **) (void *) &domntab, (size_t) ((grafptr->vertnbr + 1) * sizeof (MappingSort)), &nghbtab, (size_t) ((grafptr->vertnbr + 2) * sizeof (Anum)), NULL) == NULL) { errorPrint ("SCOTCH_graphMapView: out of memory"); return (1); } for (vertnum = 0; vertnum < grafptr->vertnbr; vertnum ++) { domntab[vertnum].labl = parttax[vertnum]; domntab[vertnum].peri = vertnum + grafptr->baseval; /* Build inverse permutation */ } parttax -= grafptr->baseval; domntab[grafptr->vertnbr].labl = ARCHDOMNOTTERM; /* TRICK: avoid testing (i+1) */ domntab[grafptr->vertnbr].peri = ~0; /* Prevent Valgrind from yelling */ intSort2asc2 (domntab, grafptr->vertnbr); /* Sort domain label array by increasing target labels */ archDomFrst (archptr, &domnfrst); /* Get architecture domain */ tgtnbr = archDomSize (archptr, &domnfrst); /* Get architecture size */ mapsum = 0; mapnbr = 0; veloval = 1; /* Assume unweighted vertices */ for (vertnum = 0; domntab[vertnum].labl != ARCHDOMNOTTERM; vertnum ++) { parttax[domntab[vertnum].peri] = mapnbr; /* Build map of partition parts starting from 0 */ if (domntab[vertnum].labl != domntab[vertnum + 1].labl) /* TRICK: if new (or end) domain label */ mapnbr ++; if (velotax != NULL) veloval = velotax[domntab[vertnum].peri]; mapsum += veloval; } mapavg = (mapnbr == 0) ? 0.0L : (double) mapsum / (double) mapnbr; mapsum = 0; mapmin = GNUMMAX; mapmax = 0; mapdlt = 0.0L; for (vertnum = 0; domntab[vertnum].labl != ARCHDOMNOTTERM; vertnum ++) { if (velotax != NULL) veloval = velotax[domntab[vertnum].peri]; mapsum += veloval; if (domntab[vertnum].labl != domntab[vertnum + 1].labl) { /* TRICK: if new (or end) domain label */ if (mapsum < mapmin) mapmin = mapsum; if (mapsum > mapmax) mapmax = mapsum; mapdlt += fabs ((double) mapsum - mapavg); mapsum = 0; /* Reset domain load sum */ } } mapdlt = (mapnbr != 0) ? mapdlt / ((double) mapnbr * mapavg) : 0.0L; mapmmy = (mapnbr != 0) ? (double) mapmax / (double) mapavg : 0.0L; if (mapnbr > tgtnbr) { /* If more subdomains than architecture size */ #ifdef SCOTCH_DEBUG_MAP2 if (! archVar (archptr)) { /* If not a variable-sized architecture */ errorPrint ("SCOTCH_graphMapView: invalid mapping"); memFree (domntab); /* Free group leader */ return (1); } #endif /* SCOTCH_DEBUG_MAP2 */ tgtnbr = mapnbr; /* Assume it is a variable-sized architecture */ } if (flagval == 0) { fprintf (stream, "M\tProcessors " GNUMSTRING "/" GNUMSTRING " (%g)\n", (Gnum) mapnbr, (Gnum) tgtnbr, (double) mapnbr / (double) tgtnbr); fprintf (stream, "M\tTarget min=" GNUMSTRING "\tmax=" GNUMSTRING "\tavg=%g\tdlt=%g\tmaxavg=%g\n", (Gnum) mapmin, (Gnum) mapmax, mapavg, mapdlt, mapmmy); } nghbnbr = 0; nghbmin = ANUMMAX; nghbmax = 0; nghbsum = 0; nghbnbr = 0; nghbtab[0] = -2; for (vertnum = 0; domntab[vertnum].labl != ARCHDOMNOTTERM; vertnum ++) { Gnum edgenum; Gnum edgennd; Anum partnum; partnum = parttax[domntab[vertnum].peri]; for (edgenum = verttax[domntab[vertnum].peri], edgennd = vendtax[domntab[vertnum].peri]; edgenum < edgennd; edgenum ++) { Anum partend; partend = parttax[edgetax[edgenum]]; if ((partend != partnum) && /* If edge is not internal */ (partend != nghbtab[nghbnbr])) { /* And neighbor is not sole neighbor or has not just been found */ Anum partmin; Anum partmax; partmin = 0; partmax = nghbnbr; while ((partmax - partmin) > 1) { Anum partmed; partmed = (partmax + partmin) >> 1; if (nghbtab[partmed] > partend) partmax = partmed; else partmin = partmed; } if (nghbtab[partmin] == partend) /* If neighboring part found, skip to next neighbor */ continue; #ifdef SCOTCH_DEBUG_MAP2 if (nghbnbr >= (grafptr->vertnbr + 1)) { errorPrint ("SCOTCH_graphMapView: internal error"); return (1); } #endif /* SCOTCH_DEBUG_MAP2 */ nghbnbr ++; for (partmax = nghbnbr; partmax > (partmin + 1); partmax --) nghbtab[partmax] = nghbtab[partmax - 1]; nghbtab[partmin + 1] = partend; /* Add new neighbor part in the right place */ } } if (domntab[vertnum].labl != domntab[vertnum + 1].labl) { /* TRICK: if new (or end) domain label */ if (nghbnbr < nghbmin) nghbmin = nghbnbr; if (nghbnbr > nghbmax) nghbmax = nghbnbr; nghbsum += nghbnbr; nghbnbr = 0; } } if (flagval == 0) { fprintf (stream, "M\tNeighbors min=" GNUMSTRING "\tmax=" GNUMSTRING "\tsum=" GNUMSTRING "\n", (Gnum) nghbmin, (Gnum) nghbmax, (Gnum) nghbsum); } memSet (commdist, 0, 256 * sizeof (Gnum)); /* Initialize the data */ commload = commdilat = commexpan = 0; edloval = 1; for (vertnum = grafptr->baseval; vertnum < grafptr->vertnnd; vertnum ++) { Gnum edgenum; if (parttax[vertnum] == ~0) /* Skip unmapped vertices */ continue; for (edgenum = verttax[vertnum]; edgenum < vendtax[vertnum]; edgenum ++) { if (parttax[edgetax[edgenum]] == ~0) continue; archDomTerm (archptr, &domnorg, parttax[vertnum]); /* Get terminal domains */ archDomTerm (archptr, &domnend, parttax[edgetax[edgenum]]); distval = archDomDist (archptr, &domnorg, &domnend); if (edlotax != NULL) /* Get edge weight if any */ edloval = edlotax[edgenum]; commdist[(distval > 255) ? 255 : distval] += edloval; commload += edloval; commdilat += distval; commexpan += distval * edloval; } } if (lmaoptr != NULL) { migrnbr = 0; migrdistavg = 0; migrloadavg = 0; migrcostsum = 0; for (vertnum = grafptr->baseval; vertnum < grafptr->vertnnd; vertnum ++) { if ((parttax[vertnum] == -1) || (parotax[vertnum] == -1)) continue; if (parotax[vertnum] != parttax[vertnum]) { migrnbr ++; archDomTerm (archptr, &domnorg, parotax[vertnum]); /* Get terminal domains */ archDomTerm (archptr, &domnold, parotax[vertnum]); migrdistavg += archDomDist (archptr, &domnorg, &domnold); migrloadavg += (grafptr->velotax == NULL) ? 1 : grafptr->velotax[vertnum]; migrcostsum += emraval * ((vmlotax != NULL) ? vmlotax[vertnum] : 1); } } if (migrnbr > 0) { migrdistavg /= migrnbr; migrloadavg /= migrnbr; } } if (flagval == 0) { fprintf (stream, "M\tCommDilat=%f\t(" GNUMSTRING ")\n", /* Print expansion parameters */ (double) commdilat / grafptr->edgenbr, (Gnum) (commdilat / 2)); fprintf (stream, "M\tCommExpan=%f\t(" GNUMSTRING ")\n", ((commload == 0) ? (double) 0.0L : (double) commexpan / (double) commload), (Gnum) (commexpan / 2)); fprintf (stream, "M\tCommCutSz=%f\t(" GNUMSTRING ")\n", ((commload == 0) ? (double) 0.0L : (double) (commload - commdist[0]) / (double) commload), (Gnum) ((commload - commdist[0]) / 2)); fprintf (stream, "M\tCommDelta=%f\n", (((double) commload * (double) commdilat) == 0.0L) ? (double) 0.0L : ((double) commexpan * (double) grafptr->edgenbr) / ((double) commload * (double) commdilat)); } for (distmax = 255; distmax != -1; distmax --) /* Find longest distance */ if (commdist[distmax] != 0) break; if (flagval == 0) { for (distval = 0; distval <= distmax; distval ++) /* Print distance histogram */ fprintf (stream, "M\tCommLoad[" ANUMSTRING "]=%f\n", (Anum) distval, (double) commdist[distval] / (double) commload); } diammin = GNUMMAX; diammax = 0; diamsum = 0; for (mapnum = 0; mapnum < mapnbr; mapnum ++) { Gnum diamval; diamval = graphMapView3 (grafptr, parttax, mapnum); diamsum += diamval; if (diamval < diammin) diammin = diamval; if (diamval > diammax) diammax = diamval; } if (flagval == 0) { fprintf (stream, "M\tPartDiam\tmin=" GNUMSTRING "\tmax=" GNUMSTRING "\tavg=%lf\n", (Gnum) diammin, (Gnum) diammax, (double) diamsum / (double) mapnbr); } if ((flagval == 0) && (lmaoptr != NULL)) { fprintf (stream, "M\tMigrNbr=" GNUMSTRING "(%lf %%)\n", migrnbr, (((double) migrnbr) / ((double) grafptr->vertnbr))*100); fprintf (stream, "M\tAvgMigrDist=%lf\n", (double) migrdistavg); fprintf (stream, "M\tAvgMigrLoad=%lf\n", (double) migrloadavg); fprintf (stream, "M\tMigrCost=%lf\n", (double) migrcostsum); } if (flagval != 0) { /* If raw output */ fprintf (stream, "" GNUMSTRING "\t" GNUMSTRING "\t" GNUMSTRING "\t" GNUMSTRING "\t%g\t%g\t%g\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf", /* Print standard data */ (Gnum) mapnbr, (Gnum) tgtnbr, (Gnum) mapmin, (Gnum) mapmax, mapavg, mapdlt, mapmmy, (double) commload, (double) commexpan, (double) commdilat / grafptr->edgenbr, ((commload == 0) ? (double) 0.0L : (double) commexpan / (double) commload), ((commload == 0) ? (double) 0.0L : (double) (commload - commdist[0]) / (double) commload), (((double) commload * (double) commdilat) == 0.0L) ? (double) 0.0L : ((double) commexpan * (double) grafptr->edgenbr) / ((double) commload * (double) commdilat)); if (lmaoptr != NULL) /* If we are doing repartitioning */ fprintf (stream, "\t%lf\t%lf\t%lf\t%lf\t%lf", /* Print repartitioning data */ (double) emraval, (double) migrnbr / (double) grafptr->vertnbr, (double) migrdistavg, (double) migrloadavg, (double) migrcostsum); fprintf (stream, "\n"); } memFree (domntab); /* Free group leader */ return (0); } /*+ This routine writes mapping statistics *** to the given stream. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphMapView ( const SCOTCH_Graph * const libgrafptr, /*+ Ordered graph +*/ const SCOTCH_Mapping * const libmappptr, /*+ Computed mapping +*/ FILE * const stream) /*+ Output stream +*/ { return (graphMapView2 (libgrafptr, libmappptr, NULL, 0, NULL, 0, stream)); } /*+ This routine writes remapping statistics *** to the given stream. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphRemapView ( const SCOTCH_Graph * const libgrafptr, /*+ Ordered graph +*/ const SCOTCH_Mapping * const libmappptr, /*+ Computed mapping +*/ const SCOTCH_Mapping * const libmapoptr, /*+ Old mapping (equal to NULL if no repartitioning) +*/ const double emraval, /*+ Edge migration ratio +*/ SCOTCH_Num * vmlotab, /*+ Vertex migration cost array +*/ FILE * const stream) /*+ Output stream +*/ { return (graphMapView2 (libgrafptr, libmappptr, libmapoptr, emraval, vmlotab, 0, stream)); } /*+ This routine writes raw mapping statistics *** to the given stream. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphMapViewRaw ( const SCOTCH_Graph * const libgrafptr, /*+ Ordered graph +*/ const SCOTCH_Mapping * const libmappptr, /*+ Computed mapping +*/ FILE * const stream) /*+ Output stream +*/ { return (graphMapView2 (libgrafptr, libmappptr, NULL, 0, NULL, 1, stream)); } /*+ This routine writes raw remapping statistics *** to the given stream. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphRemapViewRaw ( const SCOTCH_Graph * const libgrafptr, /*+ Ordered graph +*/ const SCOTCH_Mapping * const libmappptr, /*+ Computed mapping +*/ const SCOTCH_Mapping * const libmapoptr, /*+ Old mapping (equal to NULL if no repartitioning) +*/ const double emraval, /*+ Edge migration ratio +*/ SCOTCH_Num * vmlotab, /*+ Vertex migration cost array +*/ FILE * const stream) /*+ Output stream +*/ { return (graphMapView2 (libgrafptr, libmappptr, libmapoptr, emraval, vmlotab, 1, stream)); } /*+ This routine computes the pseudo-diameter of *** the given part. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ static Gnum graphMapView3 ( const Graph * const grafptr, /*+ Graph +*/ const Anum * const parttax, /*+ Part array +*/ const Anum partval) /*+ Part value +*/ { GraphMapViewQueue queudat; /* Neighbor queue */ GraphMapViewVertex * restrict vexxtax; /* Based access to vexxtab */ Gnum rootnum; /* Number of current root vertex */ Gnum vertdist; /* Vertex distance */ int diamflag; /* Flag set if diameter changed */ Gnum diambase; /* Base distance for connected components */ Gnum diamdist; /* Current diameter distance */ Gnum diamnum; /* Vertex which achieves diameter */ Gnum passnum; /* Pass number */ const Gnum * restrict verttax; /* Based access to vertex array */ const Gnum * restrict vendtax; /* Based access to vertex end array */ const Gnum * restrict edgetax; if (memAllocGroup ((void **) (void *) &queudat.qtab, (size_t) (grafptr->vertnbr * sizeof (Gnum)), &vexxtax, (size_t) (grafptr->vertnbr * sizeof (GraphMapViewVertex)), NULL) == NULL) { errorPrint ("graphMapView3: out of memory"); return (-1); } memSet (vexxtax, 0, grafptr->vertnbr * sizeof (GraphMapViewVertex)); /* Initialize pass numbers */ edgetax = grafptr->edgetax; verttax = grafptr->verttax; vendtax = grafptr->vendtax; vexxtax -= grafptr->baseval; diamnum = 0; /* Start distances from zero */ diamdist = 0; for (passnum = 1, rootnum = grafptr->baseval; ; passnum ++) { /* For all connected components */ while ((rootnum < grafptr->vertnbr) && ((vexxtax[rootnum].passnum != 0) || /* Find first unallocated vertex */ (parttax[rootnum] != partval))) rootnum ++; if (rootnum >= grafptr->vertnbr) /* Exit if all of graph processed */ break; diambase = ++ diamdist; /* Start from previous distance */ diamnum = rootnum; /* Start from found root */ for (diamflag = 1; diamflag -- != 0; passnum ++) { /* Loop if modifications */ graphMapViewQueueFlush (&queudat); /* Flush vertex queue */ graphMapViewQueuePut (&queudat, diamnum); /* Start from diameter vertex */ vexxtax[diamnum].passnum = passnum; /* It has been enqueued */ vexxtax[diamnum].vertdist = diambase; /* It is at base distance */ do { /* Loop on vertices in queue */ Gnum vertnum; Gnum edgenum; vertnum = graphMapViewQueueGet (&queudat); /* Get vertex from queue */ vertdist = vexxtax[vertnum].vertdist; /* Get vertex distance */ if ((vertdist > diamdist) || /* If vertex increases diameter */ ((vertdist == diamdist) && /* Or is at diameter distance */ ((vendtax[vertnum] - verttax[vertnum]) < /* With smaller degree */ (vendtax[diamnum] - verttax[diamnum])))) { diamnum = vertnum; /* Set it as new diameter vertex */ diamdist = vertdist; diamflag = 1; } vertdist ++; /* Set neighbor distance */ for (edgenum = verttax[vertnum]; edgenum < vendtax[vertnum]; edgenum ++) { Gnum vertend; vertend = edgetax[edgenum]; if ((vexxtax[vertend].passnum < passnum) && /* If vertex not queued yet */ (parttax[vertend] == partval)) { /* And of proper part */ graphMapViewQueuePut (&queudat, vertend); /* Enqueue neighbor vertex */ vexxtax[vertend].passnum = passnum; vexxtax[vertend].vertdist = vertdist; } } } while (! graphMapViewQueueEmpty (&queudat)); /* As long as queue is not empty */ } } memFree (queudat.qtab); /* Free group leader */ return (diamdist); } scotch-6.0.4.dfsg/src/libscotch/hmesh_order_bl.c0000644002563400244210000001216111631447170024757 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh_order_bl.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module resizes block data using **/ /** the block splitting post-processing **/ /** algorithm. **/ /** **/ /** DATES : # Version 4.0 : from : 28 sep 2002 **/ /** to 09 feb 2005 **/ /** # Version 5.0 : from : 25 jul 2007 **/ /** to : 25 jul 2007 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HMESH_ORDER_BL #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "order.h" #include "mesh.h" #include "hmesh.h" #include "hmesh_order_bl.h" #include "hmesh_order_st.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the ordering. ** It returns: ** - 0 : if the ordering could be computed. ** - !0 : on error. */ int hmeshOrderBl ( const Hmesh * restrict const meshptr, Order * restrict const ordeptr, const Gnum ordenum, /*+ Zero-based ordering number +*/ OrderCblk * restrict const cblkptr, /*+ Single column-block +*/ const HmeshOrderBlParam * restrict const paraptr) { Gnum cblknbr; /* Number of old column blocks before splitting */ Gnum cblknum; /* Number of current column block */ if (paraptr->cblkmin <= 0) { errorPrint ("hmeshOrderBl: invalid minimum block size"); return (1); } if (hmeshOrderSt (meshptr, ordeptr, ordenum, cblkptr, paraptr->strat) != 0) /* Perform ordering strategy */ return (1); if (cblkptr->cblktab == NULL) { /* If single column block */ if (cblkptr->vnodnbr < (2 * paraptr->cblkmin)) /* If block cannot be split */ return (0); cblknbr = cblkptr->vnodnbr / paraptr->cblkmin; /* Get new number of blocks */ if ((cblkptr->cblktab = (OrderCblk *) memAlloc (cblknbr * sizeof (OrderCblk))) == NULL) { errorPrint ("hgraphOrderBl: out of memory"); return (1); } ordeptr->treenbr += cblknbr; /* These more number of tree nodes */ ordeptr->cblknbr += cblknbr - 1; /* These more number of column blocks */ cblkptr->cblknbr = cblknbr; for (cblknum = 0; cblknum < cblknbr; cblknum ++) { cblkptr->cblktab[cblknum].typeval = ORDERCBLKOTHR; cblkptr->cblktab[cblknum].vnodnbr = ((cblkptr->vnodnbr + cblknbr - 1) - cblknum) / cblknbr; cblkptr->cblktab[cblknum].cblknbr = 0; cblkptr->cblktab[cblknum].cblktab = NULL; } } else { /* Block already partitioned */ for (cblknum = 0; cblknum < cblkptr->cblknbr; cblknum ++) { if (hmeshOrderBl (meshptr, ordeptr, ordenum, cblkptr->cblktab + cblknum, paraptr) != 0) return (1); } } return (0); } scotch-6.0.4.dfsg/src/libscotch/arch_torus.h0000644002563400244210000002275012354533552024171 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2011,2013,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : arch_torus.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the tori graph target architecture **/ /** functions. **/ /** **/ /** DATES : # Version 0.0 : from : 01 dec 1992 **/ /** to : 24 mar 1993 **/ /** # Version 1.2 : from : 04 feb 1994 **/ /** to : 11 feb 1994 **/ /** # Version 1.3 : from : 20 apr 1994 **/ /** to : 20 apr 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to : 12 nov 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to : 30 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 17 aug 1995 **/ /** # Version 3.1 : from : 22 jul 1996 **/ /** to 23 jul 1996 **/ /** # Version 3.2 : from : 16 oct 1996 **/ /** to 14 may 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 4.0 : from : 05 nov 2003 **/ /** to 05 nov 2003 **/ /** # Version 5.1 : from : 21 jan 2008 **/ /** to 21 jan 2008 **/ /** # Version 6.0 : from : 14 fev 2011 **/ /** to 01 jul 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ #ifndef ARCH_TORUS_H_STRUCT #define ARCH_TORUS_H_STRUCT /*+ Maximum dimension. +*/ #define ARCHTORUSDIMMAX 5 /* Maximum dimension (at least 3) */ /*+ Data structure equivalence for target architecture array. +*/ #ifdef ARCH #define ArchTorus2Dom ArchTorusXDom #define ArchTorus3Dom ArchTorusXDom #endif /* ARCH */ /* ** The type and structure definitions. */ /*+ The xD-torus definitions. +*/ typedef struct ArchTorusX_ { Anum dimmax; /*+ Number of torus dimensions +*/ Anum c[ARCHTORUSDIMMAX]; /*+ Mesh dimensions +*/ } ArchTorusX; typedef struct ArchTorusXDom_ { Anum c[ARCHTORUSDIMMAX][2]; /*+ Inclusive X and Y coordinates +*/ } ArchTorusXDom; #endif /* ARCH_TORUS_H_STRUCT */ /* ** The function prototypes. */ #ifndef ARCH_NOPROTO #ifndef ARCH_TORUS_H_PROTO #define ARCH_TORUS_H_PROTO #ifndef ARCH_TORUS #define static #endif int archTorus2ArchLoad (ArchTorusX * restrict const, FILE * restrict const); int archTorus2ArchSave (const ArchTorusX * const, FILE * restrict const); #define archTorus2ArchFree NULL ArchDomNum archTorus2DomNum (const ArchTorusX * const, const ArchTorusXDom * const); int archTorus2DomTerm (const ArchTorusX * const, ArchTorusXDom * restrict const, const ArchDomNum); Anum archTorus2DomSize (const ArchTorusX * const, const ArchTorusXDom * const); #define archTorus2DomWght archTorus2DomSize Anum archTorus2DomDist (const ArchTorusX * const, const ArchTorusXDom * const, const ArchTorusXDom * const); #define archTorus2DomFrst archTorusXDomFrst #define archTorus2DomLoad archTorusXDomLoad #define archTorus2DomSave archTorusXDomSave int archTorus2DomBipart (const ArchTorusX * const, const ArchTorusXDom * const, ArchTorusXDom * restrict const, ArchTorusXDom * restrict const); int archTorus2DomBipartO (const ArchTorusX * const, const ArchTorusXDom * const, ArchTorusXDom * restrict const, ArchTorusXDom * restrict const); int archTorus2DomBipartU (const ArchTorusX * const, const ArchTorusXDom * const, ArchTorusXDom * restrict const, ArchTorusXDom * restrict const); int archTorus2DomIncl (const ArchTorusX * const, const ArchTorusXDom * const, const ArchTorusXDom * const); #ifdef SCOTCH_PTSCOTCH #define archTorus2DomMpiType archTorusXDomMpiType #endif /* SCOTCH_PTSCOTCH */ int archTorus3ArchLoad (ArchTorusX * restrict const, FILE * restrict const); int archTorus3ArchSave (const ArchTorusX * const, FILE * restrict const); #define archTorus3ArchFree NULL ArchDomNum archTorus3DomNum (const ArchTorusX * const, const ArchTorusXDom * const); int archTorus3DomTerm (const ArchTorusX * const, ArchTorusXDom * restrict const, const ArchDomNum); Anum archTorus3DomSize (const ArchTorusX * const, const ArchTorusXDom * const); #define archTorus3DomWght archTorus3DomSize Anum archTorus3DomDist (const ArchTorusX * const, const ArchTorusXDom * const, const ArchTorusXDom * const); #define archTorus3DomFrst archTorusXDomFrst #define archTorus3DomLoad archTorusXDomLoad #define archTorus3DomSave archTorusXDomSave int archTorus3DomBipart (const ArchTorusX * const, const ArchTorusXDom * const, ArchTorusXDom * restrict const, ArchTorusXDom * restrict const); int archTorus3DomIncl (const ArchTorusX * const, const ArchTorusXDom * const, const ArchTorusXDom * const); #ifdef SCOTCH_PTSCOTCH #define archTorus3DomMpiType archTorusXDomMpiType #endif /* SCOTCH_PTSCOTCH */ int archTorusXArchLoad (ArchTorusX * restrict const, FILE * restrict const); int archTorusXArchSave (const ArchTorusX * const, FILE * restrict const); #define archTorusXArchFree NULL ArchDomNum archTorusXDomNum (const ArchTorusX * const, const ArchTorusXDom * const); int archTorusXDomTerm (const ArchTorusX * const, ArchTorusXDom * restrict const, const ArchDomNum); Anum archTorusXDomSize (const ArchTorusX * const, const ArchTorusXDom * const); #define archTorusXDomWght archTorusXDomSize Anum archTorusXDomDist (const ArchTorusX * const, const ArchTorusXDom * const, const ArchTorusXDom * const); int archTorusXDomFrst (const ArchTorusX * const, ArchTorusXDom * const); int archTorusXDomLoad (const ArchTorusX * const, ArchTorusXDom * const, FILE * restrict const); int archTorusXDomSave (const ArchTorusX * const, const ArchTorusXDom * const, FILE * restrict const); int archTorusXDomBipart (const ArchTorusX * const, const ArchTorusXDom * const, ArchTorusXDom * restrict const, ArchTorusXDom * restrict const); int archTorusXDomIncl (const ArchTorusX * const, const ArchTorusXDom * const, const ArchTorusXDom * const); #ifdef SCOTCH_PTSCOTCH int archTorusXDomMpiType (const ArchTorusX * const, MPI_Datatype * const); #endif /* SCOTCH_PTSCOTCH */ #undef static #endif /* ARCH_TORUS_H_PROTO */ #endif /* ARCH_NOPROTO */ scotch-6.0.4.dfsg/src/libscotch/library_dgraph_map_view.c0000644002563400244210000004000012055777004026657 0ustar trophimeutilisateurs du domaine/* Copyright 2008-2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_map_view.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the distri- **/ /** buted mapping routines of the libSCOTCH **/ /** library. **/ /** **/ /** DATES : # Version 5.1 : from : 26 jul 2008 **/ /** to 11 aug 2010 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #define LIBRARY_DGRAPH_MAP_VIEW #include "module.h" #include "common.h" #include "parser.h" #include "dgraph.h" #include "dgraph_halo.h" #include "arch.h" #include "dmapping.h" #include "kdgraph.h" #include "library_dmapping.h" #include "ptscotch.h" /************************************/ /* */ /* These routines are the C API for */ /* the mapping routines. */ /* */ /************************************/ /*+ This routine writes distributed mapping *** statistics to the given stream. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_dgraphMapView ( SCOTCH_Dgraph * const libgrafptr, const SCOTCH_Dmapping * const libmappptr, FILE * const stream) { Dgraph * restrict grafptr; const LibDmapping * restrict mappptr; ArchDom domnfrst; /* Largest domain in architecture */ unsigned int * restrict nmskloctab; /* Local neighbor bitfield */ unsigned int * restrict nmskglbtab; /* Local neighbor bitfield */ int nmskidxnbr; /* Size of bitfield; int since sent by MPI */ Gnum * restrict tgloloctab; /* Local array of terminal domain loads */ Gnum * restrict tgloglbtab; /* Global array of terminal domain loads */ Gnum * restrict termgsttax; /* Terminal domain ghost mapping array */ Anum tgtnbr; /* Number of processors in target topology */ Anum tgtnum; Anum mapnbr; /* Number of processors effectively used */ double mapavg; /* Average mapping weight */ Gnum mapmin; Gnum mapmax; Gnum mapsum; /* (Partial) sum of vertex loads */ double mapdlt; double mapmmy; /* Maximum / average ratio */ Anum ngbsum; Anum ngbmin; Anum ngbmax; Gnum vertlocnum; Gnum veloval; Gnum edloval; Gnum commlocdist[256 + 3]; /* Array of local load distribution */ Gnum commglbdist[256 + 3]; Gnum commlocload; /* Total local edge load (edge sum) */ Gnum commlocdilat; /* Total edge dilation */ Gnum commlocexpan; /* Total edge expansion */ Anum distmax; Anum distval; int cheklocval; int chekglbval; DgraphHaloRequest requdat; grafptr = (Dgraph *) libgrafptr; mappptr = (LibDmapping *) libmappptr; if ((grafptr->vertglbnbr == 0) || /* Return if nothing to do */ (grafptr->edgeglbnbr == 0)) return (0); archDomFrst (&mappptr->m.archdat, &domnfrst); /* Get architecture domain */ tgtnbr = archDomSize (&mappptr->m.archdat, &domnfrst); /* Get architecture size */ if (archVar (&mappptr->m.archdat)) { errorPrint ("SCOTCH_dgraphMapView: not implemented"); return (1); } if (dgraphGhst (grafptr) != 0) { /* Compute ghost edge array if not already present */ errorPrint ("SCOTCH_dgraphMapView: cannot compute ghost edge array"); return (1); } nmskidxnbr = (tgtnbr + 1 + ((sizeof (int) << 3) - 1)) / (sizeof (int) << 3); /* Size of neighbor subdomain bitfield; TRICK: "+1" to have a "-1" cell for unmapped vertices */ cheklocval = 0; if (memAllocGroup ((void **) (void *) &nmskloctab, (size_t) (nmskidxnbr * sizeof (unsigned int)), &nmskglbtab, (size_t) (nmskidxnbr * sizeof (unsigned int)), &tgloloctab, (size_t) ((tgtnbr + 1) * sizeof (Gnum)), /* TRICK: "+1" to have a "-1" cell for unmapped vertices */ &tgloglbtab, (size_t) (tgtnbr * sizeof (Gnum)), &termgsttax, (size_t) (grafptr->vertgstnbr * sizeof (Gnum)), NULL) == NULL) { cheklocval = 1; } if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("SCOTCH_dgraphMapView: communication error (1)"); return (1); } if (chekglbval != 0) { if (nmskloctab != NULL) memFree (nmskloctab); errorPrint ("SCOTCH_dgraphMapView: out of memory"); return (1); } if (dmapTerm (&mappptr->m, grafptr, termgsttax) != 0) { errorPrint ("SCOTCH_dgraphMapView: cannot build local terminal array"); memFree (nmskloctab); return (1); } dgraphHaloAsync (grafptr, termgsttax, GNUM_MPI, &requdat); termgsttax -= grafptr->baseval; memSet (tgloloctab, 0, (tgtnbr + 1) * sizeof (Gnum)); tgloloctab ++; /* TRICK: trim array for "-1" cell */ veloval = 1; for (vertlocnum = grafptr->baseval; vertlocnum < grafptr->vertlocnnd; vertlocnum ++) { #ifdef SCOTCH_DEBUG_DMAP2 if ((termgsttax[vertlocnum] < -1) || (termgsttax[vertlocnum] >= tgtnbr)) { errorPrint ("SCOTCH_dgraphMapView: invalid local terminal array"); memFree (nmskloctab); /* Free group leader */ return (1); } #endif /* SCOTCH_DEBUG_DMAP2 */ if (grafptr->veloloctax != NULL) veloval = grafptr->veloloctax[vertlocnum]; tgloloctab[termgsttax[vertlocnum]] += veloval; /* One more vertex of given weight assigned to this target */ } if (MPI_Allreduce (tgloloctab, tgloglbtab, tgtnbr, GNUM_MPI, MPI_SUM, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("SCOTCH_dgraphMapView: communication error (2)"); memFree (nmskloctab); /* Free group leader */ return (1); } mapmin = GNUMMAX; mapmax = 0; mapsum = 0; mapnbr = 0; for (tgtnum = 0; tgtnum < tgtnbr; tgtnum ++) { Gnum tgtsum; tgtsum = tgloglbtab[tgtnum]; if (tgtsum != 0) { mapnbr ++; mapsum += tgtsum; if (tgtsum < mapmin) mapmin = tgtsum; if (tgtsum > mapmax) mapmax = tgtsum; } } mapavg = (mapnbr == 0) ? 0.0L : ((double) mapsum / (double) mapnbr); mapdlt = 0.0L; for (tgtnum = 0; tgtnum < tgtnbr; tgtnum ++) mapdlt += fabs ((double) tgloglbtab[tgtnum] - mapavg); mapdlt = (mapnbr != 0) ? mapdlt / ((double) mapnbr * mapavg) : 0.0L; mapmmy = (mapnbr != 0) ? (double) mapmax / (double) mapavg : 0.0L; if (stream != NULL) { fprintf (stream, "M\tProcessors " GNUMSTRING "/" GNUMSTRING "(%g)\n", (Gnum) mapnbr, (Gnum) tgtnbr, (double) mapnbr / (double) tgtnbr); fprintf (stream, "M\tTarget min=" GNUMSTRING "\tmax=" GNUMSTRING "\tavg=%g\tdlt=%g\tmaxavg=%g\n", (Gnum) mapmin, (Gnum) mapmax, mapavg, mapdlt, mapmmy); } if (dgraphHaloWait (&requdat) != 0) { /* Wait for ghost terminal data to be exchanged */ errorPrint ("SCOTCH_dgraphMapView: cannot complete asynchronous halo exchange"); memFree (nmskloctab); /* Free group leader */ return (1); } ngbmin = ANUMMAX; ngbmax = 0; ngbsum = 0; for (tgtnum = 0; tgtnum < tgtnbr; tgtnum ++) { /* For all subdomain indices */ int nmskidxnum; Gnum vertlocnum; Anum ngbnbr; if (tgloglbtab[tgtnum] <= 0) /* If empty subdomain, skip it */ continue; memSet (nmskloctab, 0, nmskidxnbr * sizeof (int)); /* Reset neighbor bit mask */ for (vertlocnum = grafptr->baseval; vertlocnum < grafptr->vertlocnnd; vertlocnum ++) { /* For all local vertices */ Gnum termnum; Gnum edgelocnum; Gnum edgelocnnd; termnum = termgsttax[vertlocnum]; if (termnum != tgtnum) /* If vertex does not belong to current part or is not mapped, skip it */ continue; for (edgelocnum = grafptr->vertloctax[vertlocnum], edgelocnnd = grafptr->vendloctax[vertlocnum]; edgelocnum < edgelocnnd; edgelocnum ++) { Gnum termend; termend = termgsttax[grafptr->edgegsttax[edgelocnum]]; if (termend != tgtnum) { /* If edge is not internal */ termend ++; /* TRICK: turn unmapped to 0 and so on */ nmskloctab[termend / (sizeof (int) << 3)] |= 1 << (termend & ((sizeof (int) << 3) - 1)); /* Flag neighbor in bit array */ } } } nmskloctab[0] &= ~1; /* Do not account for unmapped vertices (terminal domain 0 because of "+1") */ if (MPI_Allreduce (nmskloctab, nmskglbtab, nmskidxnbr, MPI_INT, MPI_BOR, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("SCOTCH_dgraphMapView: communication error (3)"); memFree (nmskloctab); /* Free group leader */ return (1); } for (nmskidxnum = 0, ngbnbr = 0; nmskidxnum < nmskidxnbr; nmskidxnum ++) { unsigned int nmskbitval; for (nmskbitval = nmskglbtab[nmskidxnum]; nmskbitval != 0; nmskbitval >>= 1) ngbnbr += nmskbitval & 1; } ngbsum += ngbnbr; if (ngbnbr < ngbmin) ngbmin = ngbnbr; if (ngbnbr > ngbmax) ngbmax = ngbnbr; } if (stream != NULL) { fprintf (stream, "M\tNeighbors min=" GNUMSTRING "\tmax=" GNUMSTRING "\tsum=" GNUMSTRING "\n", (Gnum) ngbmin, (Gnum) ngbmax, (Gnum) ngbsum); } memSet (commlocdist, 0, 256 * sizeof (Gnum)); /* Initialize the data */ commlocload = commlocdilat = commlocexpan = 0; edloval = 1; for (vertlocnum = grafptr->baseval; vertlocnum < grafptr->vertlocnnd; vertlocnum ++) { /* For all local vertices */ Gnum termlocnum; ArchDom termdomdat; Gnum edgelocnum; Gnum edgelocnnd; termlocnum = termgsttax[vertlocnum]; if (termlocnum == ~0) /* Skip unmapped vertices */ continue; archDomTerm (&mappptr->m.archdat, &termdomdat, termlocnum); for (edgelocnum = grafptr->vertloctax[vertlocnum], edgelocnnd = grafptr->vendloctax[vertlocnum]; edgelocnum < edgelocnnd; edgelocnum ++) { ArchDom termdomend; Gnum termgstend; Anum distval; termgstend = termgsttax[grafptr->edgegsttax[edgelocnum]]; if (termgstend == ~0) /* Skip unmapped end vertices */ continue; distval = 0; if (grafptr->edloloctax != NULL) /* Get edge weight if any */ edloval = grafptr->edloloctax[edgelocnum]; if (termgstend != termlocnum) { /* If not same domain, compute distance */ archDomTerm (&mappptr->m.archdat, &termdomend, termgstend); distval = archDomDist (&mappptr->m.archdat, &termdomdat, &termdomend); } commlocdist[(distval > 255) ? 255 : distval] += edloval; commlocload += edloval; commlocdilat += distval; commlocexpan += distval * edloval; } } commlocdist[256] = commlocload; commlocdist[256 + 1] = commlocdilat; commlocdist[256 + 2] = commlocexpan; if (MPI_Allreduce (commlocdist, commglbdist, 256 + 3, GNUM_MPI, MPI_SUM, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("SCOTCH_dgraphMapView: communication error (4)"); memFree (nmskloctab); /* Free group leader */ return (1); } if (stream != NULL) { Gnum commglbload; commglbload = commglbdist[256]; fprintf (stream, "M\tCommDilat=%f\t(" GNUMSTRING ")\n", /* Print expansion parameters */ (double) commglbdist[256 + 1] / grafptr->edgeglbnbr, (Gnum) (commglbdist[256 + 1] / 2)); fprintf (stream, "M\tCommExpan=%f\t(" GNUMSTRING ")\n", ((commglbload == 0) ? (double) 0.0L : (double) commglbdist[256 + 2] / (double) commglbload), (Gnum) (commglbdist[256 + 2] / 2)); fprintf (stream, "M\tCommCutSz=%f\t(" GNUMSTRING ")\n", ((commglbload == 0) ? (double) 0.0L : (double) (commglbload - commglbdist[0]) / (double) commglbload), (Gnum) ((commglbload - commglbdist[0]) / 2)); fprintf (stream, "M\tCommDelta=%f\n", (((double) commglbload * (double) commglbdist[256 + 1]) == 0.0L) ? (double) 0.0L : ((double) commglbdist[256 + 2] * (double) grafptr->edgeglbnbr) / ((double) commglbload * (double) commglbdist[256 + 2])); for (distmax = 255; distmax != -1; distmax --) /* Find longest distance */ if (commglbdist[distmax] != 0) break; for (distval = 0; distval <= distmax; distval ++) /* Print distance histogram */ fprintf (stream, "M\tCommLoad[" ANUMSTRING "]=%f\n", (Anum) distval, (double) commglbdist[distval] / (double) commglbload); } memFree (nmskloctab); /* Free group leader */ return (0); } scotch-6.0.4.dfsg/src/libscotch/kgraph_map_rb_part.c0000644002563400244210000003667012406131702025630 0ustar trophimeutilisateurs du domaine/* Copyright 2008,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph_map_rb_part.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module performs the Dual Recursive **/ /** Bipartitioning mapping algorithm for **/ /** (eventually weighted) complete graph **/ /** target architectures. **/ /** **/ /** DATES : # Version 5.1 : from : 16 sep 2008 **/ /** to 31 aug 2011 **/ /** # Version 6.0 : from : 03 mar 2011 **/ /** to 16 sep 2014 **/ /** **/ /** NOTES : # This is a rewrite of kgraphMapRb() **/ /** for complete-graph target topologies. **/ /** Its advantage over kgraphMapRbMap() **/ /** is that no job arrays are allocated, **/ /** which can save space for instance for **/ /** using the variable-sized complete **/ /** graph architecture. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define KGRAPH_MAP_RB_PART #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "arch.h" #include "mapping.h" #include "bgraph.h" #include "bgraph_bipart_st.h" #include "kgraph.h" #include "kgraph_map_rb.h" #include "kgraph_map_rb_part.h" /********************************************/ /* */ /* This is the entry point for the Dual */ /* Recursive Bipartitioning mapping method. */ /* */ /********************************************/ /* This routine updates partial mappings ** according to the result of the recursive ** bipartitioning process. ** It returns: ** - 0 : on success. ** - !0 : on error. */ static void kgraphMapRbPart3 ( const Graph * restrict const srcgrafptr, /* Graph to induce and bipartition */ const GraphPart * restrict const srcparttax, /* Part array of original graph */ const GraphPart indpartval, /* Part of graph to consider */ const int domnnum, /* Index of domain onto which map the part */ Mapping * restrict const mappptr) /* Final mapping */ { Gnum vertnum; const Gnum * restrict const srcvnumtax = srcgrafptr->vnumtax; Anum * restrict const mapparttax = mappptr->parttax; if (srcparttax == NULL) { /* If graph is full graph */ #ifdef SCOTCH_DEBUG_KGRAPH2 if (domnnum != 0) { errorPrint ("kgraphMapRbPart3: internal error (1)"); return; } #endif /* SCOTCH_DEBUG_KGRAPH2 */ if (srcvnumtax == NULL) /* If full graph doesn't have fixed vertices */ memSet (mapparttax + srcgrafptr->baseval, 0, srcgrafptr->vertnbr * sizeof (Anum)); else { Gnum vertnnd; for (vertnum = srcgrafptr->baseval, vertnnd = srcgrafptr->vertnnd; vertnum < vertnnd; vertnum ++) { #ifdef SCOTCH_DEBUG_KGRAPH2 if (mapparttax[srcvnumtax[vertnum]] == ~0) { errorPrint ("kgraphMapRbPart3: internal error (2)"); return; } #endif /* SCOTCH_DEBUG_KGRAPH2 */ mapparttax[srcvnumtax[vertnum]] = domnnum; } } } else { /* Graph to consider is a subgraph of the original graph */ if (srcvnumtax == NULL) { /* If original graph is not itself a subgraph */ Gnum vertnnd; for (vertnum = srcgrafptr->baseval, vertnnd = srcgrafptr->vertnnd; vertnum < vertnnd; vertnum ++) { if (srcparttax[vertnum] == indpartval) { /* If vertex belongs to the right part */ #ifdef SCOTCH_DEBUG_KGRAPH2 if (mapparttax[vertnum] == ~0) { errorPrint ("kgraphMapRbPart3: internal error (3)"); return; } #endif /* SCOTCH_DEBUG_KGRAPH2 */ mapparttax[vertnum] = domnnum; } } } else { Gnum vertnnd; for (vertnum = srcgrafptr->baseval, vertnnd = srcgrafptr->vertnnd; vertnum < vertnnd; vertnum ++) { if (srcparttax[vertnum] == indpartval) { /* If vertex belongs to the right part */ #ifdef SCOTCH_DEBUG_KGRAPH2 if (mapparttax[srcvnumtax[vertnum]] == ~0) { errorPrint ("kgraphMapRbPart3: internal error (4)"); return; } #endif /* SCOTCH_DEBUG_KGRAPH2 */ mapparttax[srcvnumtax[vertnum]] = domnnum; } } } } } /* This routine is the core of the degenerated, ** graph partitioning version of the Dual Recursive ** Bipartitioning algorithm. ** It returns: ** - 0 : on success. ** - !0 : on error. */ static int kgraphMapRbPart2 ( const KgraphMapRbData * restrict const dataptr, /*+ Global mapping data +*/ const Graph * restrict const srcgrafptr, /*+ Graph to induce and bipartition +*/ const GraphPart * restrict const srcparttax, /*+ Part array of original graph to consider +*/ const GraphPart indpartval, /*+ Part of graph to consider +*/ const Gnum indvertnbr, /*+ Number of vertices in part or in graph +*/ const Anum domnnum, /*+ Index of domain onto which to map the part +*/ const Anum vflonbr, /*+ Number of fixed vertex load slots +*/ KgraphMapRbVflo * restrict const vflotab) /*+ Array of fixed vertex load slots +*/ { Graph indgrafdat; const Graph * indgrafptr; Bgraph actgrafdat; Anum domnsubidx; Anum domnsubdlt; ArchDom domnsubtab[2]; /* Target subdomains */ Anum domnidxtab[2]; /* Index of subdomains in mapping */ Gnum vertnbrtab[2]; /* Number of vertices in subgraphs */ Anum vflonbrtab[2]; /* Number of fixed vertex slots in subdomains */ Gnum vflowgttab[2]; /* Weights of fixed vertex slots in subdomains */ Mapping * restrict mappptr; int avarval; /* Flag set if variable-sized */ int i; int o; mappptr = dataptr->mappptr; avarval = archVar (mappptr->archptr); o = (avarval && /* If architecture is variable-sized */ (indvertnbr <= 1)) /* And source subgraph of minimal size */ ? 1 /* Then do not bipartition target more */ : archDomBipart (mappptr->archptr, &mappptr->domntab[domnnum], &domnsubtab[0], &domnsubtab[1]); switch (o) { case 1 : /* If target domain is terminal */ kgraphMapRbPart3 (srcgrafptr, srcparttax, indpartval, domnnum, mappptr); /* Update mapping and return */ return (0); case 2 : /* On error */ errorPrint ("kgraphMapRbPart2: cannot bipartition domain"); return (1); } indgrafptr = srcgrafptr; /* Assume we will work on the original graph */ if ((srcparttax != NULL) && /* If not the case, build induced subgraph */ (indvertnbr < srcgrafptr->vertnbr)) { indgrafptr = &indgrafdat; if (graphInducePart (srcgrafptr, srcparttax, indvertnbr, indpartval, &indgrafdat) != 0) { errorPrint ("kgraphMapRbPart2: cannot induce graph"); return (1); } } kgraphMapRbVfloSplit (mappptr->archptr, domnsubtab, vflonbr, vflotab, vflonbrtab, vflowgttab); if (kgraphMapRbBgraph (dataptr, &actgrafdat, indgrafptr, mappptr, domnsubtab, vflowgttab) != 0) { /* Create active graph */ errorPrint ("kgraphMapRbPart2: cannot create bipartition graph"); return (1); } if (! avarval) { /* If not variable-sized, impose constraints on bipartition */ double comploadavg; comploadavg = (double) (actgrafdat.s.velosum + vflowgttab[0] + vflowgttab[1]) / (double) archDomWght (mappptr->archptr, &mappptr->domntab[domnnum]); actgrafdat.compload0min = actgrafdat.compload0avg - (Gnum) MIN ((dataptr->comploadmax - comploadavg) * (double) actgrafdat.domnwght[0], (comploadavg - dataptr->comploadmin) * (double) actgrafdat.domnwght[1]); actgrafdat.compload0max = actgrafdat.compload0avg + (Gnum) MIN ((comploadavg - dataptr->comploadmin) * (double) actgrafdat.domnwght[0], (dataptr->comploadmax - comploadavg) * (double) actgrafdat.domnwght[1]); } if (bgraphBipartSt (&actgrafdat, dataptr->paraptr->strat) != 0) { /* Perform bipartitioning */ errorPrint ("kgraphMapRbPart2: cannot bipartition graph"); bgraphExit (&actgrafdat); return (1); } memFree (actgrafdat.frontab); /* Frontier array of bipartitioning graph is no longer necessary */ actgrafdat.s.flagval &= ~BGRAPHFREEFRON; if (archVar (mappptr->archptr)) { /* If architecture is variable-sized */ if ((actgrafdat.compsize0 == 0) || /* If bipartition failed */ (actgrafdat.compsize0 == actgrafdat.s.vertnbr)) { bgraphExit (&actgrafdat); /* Free bipartition graph (that is, parttax) */ if (indgrafptr == &indgrafdat) /* If an induced subgraph had been created */ graphExit (&indgrafdat); /* Free it */ kgraphMapRbPart3 (srcgrafptr, srcparttax, indpartval, domnnum, mappptr); /* Update mapping with original domain */ return (0); } } domnsubdlt = mappptr->domnnbr - domnnum; /* Increment in domain number */ domnsubidx = domnnum - domnsubdlt; /* Place where to insert subdomain */ mappptr->domnnbr --; /* One less subdomain as for now */ vertnbrtab[0] = actgrafdat.compsize0; vertnbrtab[1] = actgrafdat.s.vertnbr - actgrafdat.compsize0; o = 0; for (i = 1; i >= 0; i --) { /* For all subparts */ if (vertnbrtab[i] <= 0) /* If subpart is empty, skip it */ continue; mappptr->domnnbr ++; /* One more subdomain to account for */ if (mappptr->domnnbr > mappptr->domnmax) { if ((o = mapResize (mappptr, mappptr->domnmax + (mappptr->domnmax >> 2) + 8)) != 0) { /* Increase size by 25% */ errorPrint ("kgraphMapRbPart: cannot resize structures"); break; } } domnsubidx += domnsubdlt; /* Compute location of subdomain */ domnidxtab[i] = domnsubidx; /* Record it before recursion */ mappptr->domntab[domnsubidx] = domnsubtab[i]; /* Write it at this (new) place */ } if (o == 0) { for (i = 1; i >= 0; i --) { /* For all subparts */ if (vertnbrtab[i] <= 0) /* If subpart is empty, skip it */ continue; if ((o = kgraphMapRbPart2 (dataptr, indgrafptr, actgrafdat.parttax, (GraphPart) i, vertnbrtab[i], domnidxtab[i], vflonbrtab[i], vflotab + (i * vflonbrtab[0]))) != 0) return (1); /* If problem in recursion, stop */ } } bgraphExit (&actgrafdat); /* Free bipartition graph (that is, parttax) */ if (indgrafptr == &indgrafdat) /* If an induced subgraph had been created */ graphExit (&indgrafdat); /* Free it */ return (o); } /* This routine is the entry point for ** the degenerated, graph partitioning ** version, of the Dual Recursive ** Bipartitioning algorithm. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int kgraphMapRbPart ( const KgraphMapRbData * restrict const dataptr, /*+ Global mapping data +*/ const Graph * restrict const grafptr, /*+ Graph to map, without fixed vertices +*/ const Anum vflonbr, /*+ Number of fixed vertex load slots +*/ KgraphMapRbVflo * restrict const vflotab) /*+ Array of fixed vertex load slots +*/ { Mapping * restrict const mappptr = dataptr->mappptr; #ifdef SCOTCH_DEBUG_KGRAPH2 if (dataptr->pfixtax != NULL) { /* In debug mode, fixed vertex parts are set to ~0 */ Gnum vertnum; for (vertnum = dataptr->grafptr->baseval; vertnum < dataptr->grafptr->vertnnd; vertnum ++) mappptr->parttax[vertnum] = (dataptr->pfixtax[vertnum] >= 0) ? ~0 : 0; } else memSet (mappptr->parttax + dataptr->grafptr->baseval, 0, dataptr->grafptr->vertnbr * sizeof (Anum)); #endif /* SCOTCH_DEBUG_KGRAPH2 */ mappptr->domntab[0] = mappptr->domnorg; /* Initialize mapping */ mappptr->domnnbr = 1; return (kgraphMapRbPart2 (dataptr, grafptr, NULL, 0, grafptr->vertnbr, 0, vflonbr, vflotab)); } scotch-6.0.4.dfsg/src/libscotch/library_graph_map.c0000644002563400244210000006574612473175170025511 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_map.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module is the API for the mapping **/ /** routines of the libSCOTCH library. **/ /** **/ /** DATES : # Version 3.2 : from : 19 aug 1998 **/ /** to 20 aug 1998 **/ /** # Version 3.3 : from : 19 oct 1998 **/ /** to 30 mar 1999 **/ /** # Version 3.4 : from : 01 nov 2001 **/ /** to 01 nov 2001 **/ /** # Version 4.0 : from : 13 jan 2004 **/ /** to 13 nov 2005 **/ /** # Version 5.1 : from : 29 oct 2007 **/ /** to 24 jul 2011 **/ /** # Version 6.0 : from : 03 mar 2011 **/ /** to 29 oct 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "arch.h" #include "arch_dist.h" #include "mapping.h" #include "kgraph.h" #include "kgraph_map_st.h" #include "library_mapping.h" #include "scotch.h" /************************************/ /* */ /* These routines are the C API for */ /* the mapping routines. */ /* */ /************************************/ /*+ This routine initializes an API opaque *** mapping with respect to the given source *** graph and the locations of output parameters. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphMapInit ( const SCOTCH_Graph * const grafptr, /*+ Graph to map +*/ SCOTCH_Mapping * const mappptr, /*+ Mapping structure to initialize +*/ const SCOTCH_Arch * const archptr, /*+ Target architecture used to map +*/ SCOTCH_Num * const parttab) /*+ Mapping array +*/ { LibMapping * restrict lmapptr; lmapptr = (LibMapping *) mappptr; lmapptr->flagval = LIBMAPPINGNONE; /* No options set */ lmapptr->grafptr = (Graph *) grafptr; lmapptr->archptr = (Arch *) archptr; if (parttab == NULL) { if ((lmapptr->parttab = (Gnum *) memAlloc (lmapptr->grafptr->vertnbr * sizeof (Gnum))) == NULL) { errorPrint ("SCOTCH_graphMapInit: out of memory"); return (1); } memSet (lmapptr->parttab, 0, lmapptr->grafptr->vertnbr * sizeof (Anum)); /* All vertices mapped to first domain */ lmapptr->flagval |= LIBMAPPINGFREEPART; /* The user did not provided the partition array, so we will free it */ } else lmapptr->parttab = (Gnum *) parttab; return (0); } /*+ This routine frees an API mapping. *** It returns: *** - VOID : in all cases. +*/ void SCOTCH_graphMapExit ( const SCOTCH_Graph * const grafptr, SCOTCH_Mapping * const mappptr) { LibMapping * restrict lmapptr; lmapptr = (LibMapping *) mappptr; if (((lmapptr->flagval & LIBMAPPINGFREEPART) != 0) && /* If parttab must be freed */ (lmapptr->parttab != NULL)) /* And if exists */ memFree (lmapptr->parttab); /* Free it */ memSet (lmapptr, 0, sizeof (LibMapping)); } /*+ This routine computes a mapping or a *** remapping, with or without fixed *** vertices, of the API mapping *** structures given in input, with *** respect to the given strategy. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ static int graphMapCompute2 ( SCOTCH_Graph * const grafptr, /*+ Graph to order +*/ SCOTCH_Mapping * const mappptr, /*+ Mapping to compute +*/ SCOTCH_Mapping * const mapoptr, /*+ Old mapping +*/ const double emraval, /*+ Edge migration ratio +*/ const SCOTCH_Num * vmlotab, /*+ Vertex migration cost array +*/ const Gnum vfixnbr, /*+ Number of fixed vertices in part array +*/ SCOTCH_Strat * const straptr) /*+ Mapping strategy +*/ { Kgraph mapgrafdat; /* Effective mapping graph */ const Strat * mapstraptr; /* Pointer to mapping strategy */ LibMapping * restrict lmapptr; Anum * pfixtax; Gnum baseval; Anum * parttax; /* Partition array */ Anum * parotax; /* Old partition array */ Gnum crloval; /* Coefficient load for regular edges */ Gnum cmloval; /* Coefficient load for migration edges */ const Gnum * vmlotax; /* Vertex migration cost array */ Gnum vertnum; Gnum vertnnd; Gnum vertnbr; int o; lmapptr = (LibMapping *) mappptr; #ifdef SCOTCH_DEBUG_LIBRARY1 if ((Graph *) grafptr != lmapptr->grafptr) { errorPrint ("graphMapCompute2: output mapping does not correspond to input graph"); return (1); } #endif /* SCOTCH_DEBUG_LIBRARY1 */ #ifdef SCOTCH_DEBUG_LIBRARY2 if (graphCheck ((Graph *) grafptr) != 0) { /* Vertex loads can be 0 if we have fixed vertices */ errorPrint ("graphMapCompute2: invalid input graph"); return (1); } #endif /* SCOTCH_DEBUG_LIBRARY2 */ if (*((Strat **) straptr) == NULL) { /* Set default mapping strategy if necessary */ ArchDom domnorg; archDomFrst (lmapptr->archptr, &domnorg); SCOTCH_stratGraphMapBuild (straptr, SCOTCH_STRATDEFAULT, archDomSize (lmapptr->archptr, &domnorg), 0.01); } mapstraptr = *((Strat **) straptr); #ifdef SCOTCH_DEBUG_LIBRARY1 if (mapstraptr->tabl != &kgraphmapststratab) { errorPrint ("graphMapCompute2: not a graph mapping strategy"); return (1); } #endif /* SCOTCH_DEBUG_LIBRARY1 */ baseval = lmapptr->grafptr->baseval; vertnbr = lmapptr->grafptr->vertnbr; if (vfixnbr != 0) { /* We have fixed vertices */ #ifdef SCOTCH_DEBUG_LIBRARY1 ArchDom domndat; Gnum vertnum; if (lmapptr->parttab == NULL) { /* We must have fixed vertex information */ errorPrint ("graphMapCompute2: missing output mapping part array"); return (1); } for (vertnum = 0; vertnum < vertnbr; vertnum ++) { if ((lmapptr->parttab[vertnum] >= 0) && (archDomTerm (lmapptr->archptr, &domndat, lmapptr->parttab[vertnum]) != 0)) { errorPrint ("graphMapCompute2: invalid fixed partition"); return (1); } } #endif /* SCOTCH_DEBUG_LIBRARY1 */ pfixtax = lmapptr->parttab - baseval; } else pfixtax = NULL; if (mapoptr != NULL) { /* We are doing a repartitioning */ const LibMapping * restrict lmaoptr; Gnum numeval; Gnum denoval; #ifdef SCOTCH_DEBUG_LIBRARY1 ArchDom domndat; Gnum vertnum; #endif /* SCOTCH_DEBUG_LIBRARY1 */ lmaoptr = (LibMapping *) mapoptr; #ifdef SCOTCH_DEBUG_LIBRARY1 if (lmapptr->grafptr != lmaoptr->grafptr) { errorPrint ("graphMapCompute2: output and old mappings must correspond to same graph"); return (1); } if (lmapptr->archptr != lmaoptr->archptr) { errorPrint ("graphMapCompute2: output and old mappings must correspond to same architecture"); return (1); } for (vertnum = 0; vertnum < vertnbr; vertnum ++) { if ((lmaoptr->parttab[vertnum] >= 0) && (archDomTerm (lmapptr->archptr, &domndat, lmaoptr->parttab[vertnum]) != 0)) { errorPrint ("graphMapCompute2: invalid old partition"); return (1); } } #endif /* SCOTCH_DEBUG_LIBRARY1 */ parotax = lmaoptr->parttab - baseval; vmlotax = (vmlotab != NULL) ? vmlotab - baseval : NULL; numeval = (INT) ((emraval * 100.0) + 0.5); denoval = intGcd (numeval, 100); cmloval = numeval / denoval; crloval = 100 / denoval; } else { parotax = NULL; vmlotax = NULL; cmloval = crloval = 1; } intRandInit (); /* Check that random number generator is initialized */ if (kgraphInit (&mapgrafdat, (Graph *) grafptr, lmapptr->archptr, NULL, vfixnbr, pfixtax, parotax, crloval, cmloval, vmlotax) != 0) return (1); o = 0; if (mapgrafdat.vfixnbr < mapgrafdat.s.vertnbr) { /* Perform mapping if not all fixed vertices */ o = kgraphMapSt (&mapgrafdat, mapstraptr); mapTerm (&mapgrafdat.m, lmapptr->parttab - baseval); /* Propagate mapping result to part array */ } kgraphExit (&mapgrafdat); return (o); } /*+ This routine computes a mapping *** of the API mapping structure with *** respect to the given strategy. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphMapCompute ( SCOTCH_Graph * const grafptr, /*+ Graph to order +*/ SCOTCH_Mapping * const mappptr, /*+ Mapping to compute +*/ SCOTCH_Strat * const straptr) /*+ Mapping strategy +*/ { return (graphMapCompute2 (grafptr, mappptr, NULL, 1, NULL, 0, straptr)); } /*+ This routine computes a mapping *** with fixed vertices of the API *** mapping structure with respect *** to the given strategy. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphMapFixedCompute ( SCOTCH_Graph * const grafptr, /*+ Graph to order +*/ SCOTCH_Mapping * const mappptr, /*+ Mapping to compute +*/ SCOTCH_Strat * const straptr) /*+ Mapping strategy +*/ { return (SCOTCH_graphRemapFixedCompute (grafptr, mappptr, NULL, 1, NULL, straptr)); } /*+ This routine computes a remapping *** of the API mapping structure with *** respect to the given strategy. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphRemapCompute ( SCOTCH_Graph * const grafptr, /*+ Graph to order +*/ SCOTCH_Mapping * const mappptr, /*+ Mapping to compute +*/ SCOTCH_Mapping * const mapoptr, /*+ Old mapping +*/ const double emraval, /*+ Edge migration ratio +*/ const SCOTCH_Num * vmlotab, /*+ Vertex migration cost array +*/ SCOTCH_Strat * const straptr) /*+ Mapping strategy +*/ { return (graphMapCompute2 (grafptr, mappptr, mapoptr, emraval, vmlotab, 0, straptr)); } /*+ This routine computes a remapping *** with fixed vertices of the API *** mapping structure with respect *** to the given strategy. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphRemapFixedCompute ( SCOTCH_Graph * const grafptr, /*+ Graph to order +*/ SCOTCH_Mapping * const mappptr, /*+ Mapping to compute +*/ SCOTCH_Mapping * const mapoptr, /*+ Old mapping +*/ const double emraval, /*+ Edge migration ratio +*/ const SCOTCH_Num * vmlotab, /*+ Vertex migration cost array +*/ SCOTCH_Strat * const straptr) /*+ Mapping strategy +*/ { Gnum vfixnbr; Gnum vertnbr; Gnum vertnum; const Anum * restrict const pfixtab = ((LibMapping *) mappptr)->parttab; for (vertnum = 0, vertnbr = ((Graph *) grafptr)->vertnbr, vfixnbr = 0; /* Compute number of fixed vertices */ vertnum < vertnbr; vertnum ++) { if (pfixtab[vertnum] != ~0) vfixnbr ++; } return (graphMapCompute2 (grafptr, mappptr, mapoptr, emraval, vmlotab, vfixnbr, straptr)); } /*+ This routine computes a mapping of the *** given graph structure onto the given *** target architecture with respect to the *** given strategy. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphMap ( SCOTCH_Graph * const grafptr, /*+ Graph to map +*/ const SCOTCH_Arch * const archptr, /*+ Target architecture +*/ SCOTCH_Strat * const straptr, /*+ Mapping strategy +*/ SCOTCH_Num * const parttab) /*+ Partition array +*/ { SCOTCH_Mapping mappdat; int o; SCOTCH_graphMapInit (grafptr, &mappdat, archptr, parttab); o = SCOTCH_graphMapCompute (grafptr, &mappdat, straptr); SCOTCH_graphMapExit (grafptr, &mappdat); return (o); } /*+ This routine computes a mapping of the *** given graph structure onto the given *** target architecture with respect to the *** given strategy and the fixed vertices in *** maptab. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphMapFixed ( SCOTCH_Graph * const grafptr, /*+ Graph to map +*/ const SCOTCH_Arch * const archptr, /*+ Target architecture +*/ SCOTCH_Strat * const straptr, /*+ Mapping strategy +*/ SCOTCH_Num * const parttab) /*+ Partition array +*/ { SCOTCH_Mapping mappdat; int o; SCOTCH_graphMapInit (grafptr, &mappdat, archptr, parttab); o = SCOTCH_graphMapFixedCompute (grafptr, &mappdat, straptr); SCOTCH_graphMapExit (grafptr, &mappdat); return (o); } /*+ This routine computes a remapping of the *** given graph structure onto the given *** target architecture with respect to the *** given strategy. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphRemap ( SCOTCH_Graph * const grafptr, /*+ Graph to map +*/ const SCOTCH_Arch * const archptr, /*+ Target architecture +*/ SCOTCH_Num * const parotab, /*+ Old partition array +*/ const double emraval, /*+ Edge migration ratio +*/ const SCOTCH_Num * vmlotab, /*+ Vertex migration cost array +*/ SCOTCH_Strat * const straptr, /*+ Mapping strategy +*/ SCOTCH_Num * const parttab) /*+ Partition array +*/ { SCOTCH_Mapping mappdat; SCOTCH_Mapping mapodat; int o; SCOTCH_graphMapInit (grafptr, &mappdat, archptr, parttab); SCOTCH_graphMapInit (grafptr, &mapodat, archptr, parotab); o = SCOTCH_graphRemapCompute (grafptr, &mappdat, &mapodat, emraval, vmlotab, straptr); SCOTCH_graphMapExit (grafptr, &mapodat); SCOTCH_graphMapExit (grafptr, &mappdat); return (o); } /*+ This routine computes a remapping of the *** given graph structure onto the given *** target architecture with respect to the *** given strategy and the fixed vertices in *** maptab. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphRemapFixed ( SCOTCH_Graph * const grafptr, /*+ Graph to map +*/ const SCOTCH_Arch * const archptr, /*+ Target architecture +*/ SCOTCH_Num * const parotab, /*+ Old partition array +*/ const double emraval, /*+ Edge migration ratio +*/ const SCOTCH_Num * vmlotab, /*+ Vertex migration cost array +*/ SCOTCH_Strat * const straptr, /*+ Mapping strategy +*/ SCOTCH_Num * const parttab) /*+ Partition array +*/ { SCOTCH_Mapping mappdat; SCOTCH_Mapping mapodat; int o; SCOTCH_graphMapInit (grafptr, &mappdat, archptr, parttab); SCOTCH_graphMapInit (grafptr, &mapodat, archptr, parotab); o = SCOTCH_graphRemapFixedCompute (grafptr, &mappdat, &mapodat, emraval, vmlotab, straptr); SCOTCH_graphMapExit (grafptr, &mapodat); SCOTCH_graphMapExit (grafptr, &mappdat); return (o); } /*+ This routine computes a partition of *** the given graph structure with respect *** to the given strategy. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphPart ( SCOTCH_Graph * const grafptr, /*+ Graph to map +*/ const SCOTCH_Num partnbr, /*+ Number of parts +*/ SCOTCH_Strat * const straptr, /*+ Mapping strategy +*/ SCOTCH_Num * const parttab) /*+ Partition array +*/ { SCOTCH_Arch archdat; int o; SCOTCH_archInit (&archdat); SCOTCH_archCmplt (&archdat, partnbr); o = SCOTCH_graphMap (grafptr, &archdat, straptr, parttab); SCOTCH_archExit (&archdat); return (o); } /*+ This routine computes a partition of *** the given graph structure with respect *** to the given strategy and the fixed *** vertices in maptab. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphPartFixed ( SCOTCH_Graph * const grafptr, /*+ Graph to map +*/ const SCOTCH_Num partnbr, /*+ Number of parts +*/ SCOTCH_Strat * const straptr, /*+ Mapping strategy +*/ SCOTCH_Num * const parttab) /*+ Partition array +*/ { SCOTCH_Arch archdat; int o; SCOTCH_archInit (&archdat); SCOTCH_archCmplt (&archdat, partnbr); o = SCOTCH_graphMapFixed (grafptr, &archdat, straptr, parttab); SCOTCH_archExit (&archdat); return (o); } /*+ This routine computes a repartitionning *** of the given graph structure with *** respect to the given strategy. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphRepart ( SCOTCH_Graph * const grafptr, /*+ Graph to map +*/ const SCOTCH_Num partnbr, /*+ Number of parts +*/ SCOTCH_Num * const parotab, /*+ Old partition array +*/ const double emraval, /*+ Edge migration ratio +*/ const SCOTCH_Num * const vmlotab, /*+ Vertex migration cost array +*/ SCOTCH_Strat * const straptr, /*+ Mapping strategy +*/ SCOTCH_Num * const parttab) /*+ Partition array +*/ { SCOTCH_Arch archdat; int o; SCOTCH_archInit (&archdat); SCOTCH_archCmplt (&archdat, partnbr); o = SCOTCH_graphRemap (grafptr, &archdat, parotab, emraval, vmlotab, straptr, parttab); SCOTCH_archExit (&archdat); return (o); } /*+ This routine computes a repartitionning *** of the given graph structure with *** respect to the given strategy and the *** fixed vertices in maptab. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphRepartFixed ( SCOTCH_Graph * const grafptr, /*+ Graph to map +*/ const SCOTCH_Num partnbr, /*+ Number of parts +*/ SCOTCH_Num * const parotab, /*+ Old partition array +*/ const double emraval, /*+ Edge migration ratio +*/ const SCOTCH_Num * vmlotab, /*+ Vertex migration cost array +*/ SCOTCH_Strat * const straptr, /*+ Mapping strategy +*/ SCOTCH_Num * const parttab) /*+ Partition array +*/ { SCOTCH_Arch archdat; int o; SCOTCH_archInit (&archdat); SCOTCH_archCmplt (&archdat, partnbr); o = SCOTCH_graphRemapFixed (grafptr, &archdat, parotab, emraval, vmlotab, straptr, parttab); SCOTCH_archExit (&archdat); return (o); } /*+ This routine parses the given *** mapping strategy. *** It returns: *** - 0 : if string successfully scanned. *** - !0 : on error. +*/ int SCOTCH_stratGraphMap ( SCOTCH_Strat * const straptr, const char * const string) { if (*((Strat **) straptr) != NULL) stratExit (*((Strat **) straptr)); if ((*((Strat **) straptr) = stratInit (&kgraphmapststratab, string)) == NULL) { errorPrint ("SCOTCH_stratGraphMap: error in mapping strategy"); return (1); } return (0); } /*+ This routine provides predefined *** mapping strategies. *** It returns: *** - 0 : if string successfully initialized. *** - !0 : on error. +*/ int SCOTCH_stratGraphMapBuild ( SCOTCH_Strat * const straptr, /*+ Strategy to create +*/ const SCOTCH_Num flagval, /*+ Desired characteristics +*/ const SCOTCH_Num partnbr, /*+ Number of expected parts/size +*/ const double kbalval) /*+ Desired imbalance ratio +*/ { char bufftab[8192]; /* Should be enough */ char bbaltab[64]; char kbaltab[64]; char kmovtab[64]; char mvrttab[64]; Gunum parttmp; /* "Unsigned" so that ">>" will always insert "0"s */ const char * difkptr; const char * difsptr; const char * exasptr; const char * exaxptr; sprintf (bbaltab, "%lf", kbalval); sprintf (kbaltab, "%lf", kbalval); sprintf (kmovtab, GNUMSTRING, (Gnum) (((flagval & SCOTCH_STRATQUALITY) != 0) ? 200 : 80)); sprintf (mvrttab, GNUMSTRING, (Gnum) (MAX ((20 * partnbr), 10000))); strcpy (bufftab, ((flagval & SCOTCH_STRATRECURSIVE) != 0) ? "" /* Use only the recursive bipartitioning framework */ : "m{vert=,low=,asc=b{bnd=f{bal=,move=},org=f{bal=,move=}}}"); stringSubst (bufftab, "", "r{job=t,map=t,poli=S,bal=,sep=}"); stringSubst (bufftab, "", ((flagval & SCOTCH_STRATQUALITY) != 0) ? "||" : "|"); stringSubst (bufftab, "", "m{vert=120,low=h{pass=10}f{bal=,move=120},asc=b{bnd=f{bal=,move=120},org=f{bal=,move=120}}}"); if ((flagval & SCOTCH_STRATSAFETY) != 0) difsptr = ""; else difsptr = "d{pass=40}"; difkptr = "d{pass=40}"; if ((flagval & SCOTCH_STRATBALANCE) != 0) { exasptr = "f{bal=}"; exaxptr = "x{bal=}f{bal=,move=}"; } else { exasptr = ""; exaxptr = ""; } stringSubst (bufftab, "", mvrttab); stringSubst (bufftab, "", exaxptr); stringSubst (bufftab, "", exasptr); stringSubst (bufftab, "", difsptr); stringSubst (bufftab, "", difkptr); stringSubst (bufftab, "", kmovtab); stringSubst (bufftab, "", kbaltab); stringSubst (bufftab, "", bbaltab); if (SCOTCH_stratGraphMap (straptr, bufftab) != 0) { errorPrint ("SCOTCH_stratGraphMapBuild: error in sequential mapping strategy"); return (1); } return (0); } /*+ This routine provides predefined *** clustering strategies. *** It returns: *** - 0 : if string successfully initialized. *** - !0 : on error. +*/ int SCOTCH_stratGraphClusterBuild ( SCOTCH_Strat * const straptr, /*+ Strategy to create +*/ const SCOTCH_Num flagval, /*+ Desired characteristics +*/ const SCOTCH_Num pwgtval, /*+ Threshold part weight +*/ const double densval, /*+ Threshold density value +*/ const double bbalval) /*+ Maximum imbalance ratio +*/ { char bufftab[8192]; /* Should be enough */ char bbaltab[32]; char pwgttab[32]; char denstab[32]; char * difsptr; char * exasptr; sprintf (bbaltab, "%lf", bbalval); sprintf (denstab, "%lf", densval); sprintf (pwgttab, GNUMSTRING, pwgtval); strcpy (bufftab, "r{job=u,map=t,poli=L,sep=/((load>)&!(edge>vert**(vert-1)))?(m{vert=80,low=h{pass=10}f{bal=,move=80},asc=b{bnd=f{bal=,move=80},org=f{bal=,move=80}}});}"); stringSubst (bufftab, "", ((flagval & SCOTCH_STRATSPEED) != 0) ? "" : "m{vert=80,low=h{pass=10}f{bal=,move=80},asc=b{bnd=f{bal=,move=80},org=f{bal=,move=80}}}|"); if ((flagval & SCOTCH_STRATBALANCE) != 0) exasptr = "f{bal=0}"; else exasptr = ""; if ((flagval & SCOTCH_STRATSAFETY) != 0) difsptr = ""; else difsptr = "(d{pass=40}|)"; stringSubst (bufftab, "", exasptr); stringSubst (bufftab, "", difsptr); stringSubst (bufftab, "", bbaltab); stringSubst (bufftab, "", denstab); stringSubst (bufftab, "", pwgttab); if (SCOTCH_stratGraphMap (straptr, bufftab) != 0) { errorPrint ("SCOTCH_stratGraphClusterBuild: error in sequential mapping strategy"); return (1); } return (0); } scotch-6.0.4.dfsg/src/libscotch/parser_yy.y0000644002563400244210000007367512412577125024071 0ustar trophimeutilisateurs du domaine%{ /* Copyright 2004,2007,2008,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : parser_yy.y **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the syntactic parser **/ /** which processes strategy strings. **/ /** **/ /** DATES : # Version 3.1 : from : 07 nov 1995 **/ /** to 13 jun 1996 **/ /** # Version 3.2 : from : 24 sep 1996 **/ /** to 27 feb 1997 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 4.0 : from : 20 dec 2001 **/ /** to 11 jun 2004 **/ /** # Version 5.1 : from : 30 oct 2007 **/ /** to 24 jul 2011 **/ /** # Version 6.0 : from : 30 sep 2014 **/ /** to 30 sep 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define PARSER_YY #include "module.h" #include "common.h" #undef INTEGER /* In case someone defined them */ #undef DOUBLE #include "parser.h" #include "parser_ll.h" #include "parser_yy.h" /* #define SCOTCH_DEBUG_PARSER3 */ #ifdef SCOTCH_DEBUG_PARSER3 extern int yydebug; #define YYDEBUG 1 #endif /* SCOTCH_DEBUG_PARSER3 */ /* ** The static and global definitions. ** See also at the end of this file. */ static const StratTab * parserstrattab; /* Pointer to parsing tables */ static Strat * parserstratcurr = NULL; /* Pointer to current strategy node */ static StratParamTab * parserparamcurr = NULL; /* Pointer to current parameter */ extern unsigned int parsermethtokentab[]; /* Pre-definition for stupid compilers */ %} %union { char CASEVAL; /* Case value */ StratTest * TEST; /* Test type */ StratTestType TESTOP; /* Relational type */ double DOUBLE; /* Double-precision */ INT INTEGER; /* Integer */ char STRING[PARSERSTRINGLEN]; /* Character string */ struct { const StratTab * tabl; /* Current tables */ Strat * strat; /* Current method */ StratParamTab * param; /* Current parameter */ } SAVE; /* Parameter type */ Strat * STRAT; /* Strategy tree */ } %token METHODNAME %token PARAMNAME %token VALCASE VALDOUBLE VALINT VALSTRING %token VALSTRAT VALPARAM VALTEST %type TEST TESTOR TESTAND TESTNOT %type TESTREL TESTEXPR1 TESTEXPR2 TESTEXPR3 %type TESTEXPR4 TESTVAL TESTVAR %type TESTRELOP TESTEXPR1OP TESTEXPR2OP TESTEXPR3OP %type VALCASE %type VALDOUBLE VALSDOUBLE %type VALINT VALSINT %type VALSTRING %type STRATCONCAT STRATTEST STRATTESTELSE STRATEMPTY %type STRATGROUP STRATMETHOD STRATSELECT %type METHODNAME PARAMNAME %start STRAT %% /* ** These rules define the strategy grammar. */ STRAT : STRATSELECT { parserstratcurr = ($1); /* Save pointer to root of tree */ } ; STRATSELECT : STRATSELECT '|' STRATEMPTY { Strat * strat; if ((strat = (Strat *) memAlloc (sizeof (Strat))) == NULL) { errorPrint ("stratParserParse: out of memory (2)"); stratExit ($1); stratExit ($3); YYABORT; } strat->tabl = parserstrattab; strat->type = STRATNODESELECT; strat->data.select.strat[0] = ($1); strat->data.select.strat[1] = ($3); ($$) = strat; } | STRATEMPTY ; STRATEMPTY : STRATCONCAT | { Strat * strat; if ((strat = (Strat *) memAlloc (sizeof (Strat))) == NULL) { errorPrint ("stratParserParse: out of memory (3)"); YYABORT; } strat->tabl = parserstrattab; strat->type = STRATNODEEMPTY; ($$) = strat; } ; STRATCONCAT : STRATCONCAT STRATTEST { Strat * strat; if ((strat = (Strat *) memAlloc (sizeof (Strat))) == NULL) { errorPrint ("stratParserParse: out of memory (4)"); stratExit ($1); stratExit ($2); YYABORT; } strat->tabl = parserstrattab; strat->type = STRATNODECONCAT; strat->data.concat.strat[0] = ($1); strat->data.concat.strat[1] = ($2); ($$) = strat; } | STRATTEST ; STRATTEST : { stratParserSelect (VALTEST); /* Parse parameter tokens */ } '/' TEST { stratParserSelect (VALSTRAT); /* Parse strategy tokens */ } '?' STRATSELECT STRATTESTELSE ';' { Strat * strat; if ((strat = (Strat *) memAlloc (sizeof (Strat))) == NULL) { errorPrint ("stratParserParse: out of memory (1)"); stratExit ($6); if (($7) != NULL) stratExit ($7); stratTestExit ($3); YYABORT; } strat->tabl = parserstrattab; strat->type = STRATNODECOND; strat->data.cond.test = ($3); strat->data.cond.strat[0] = ($6); strat->data.cond.strat[1] = ($7); ($$) = strat; } | STRATGROUP ; STRATTESTELSE : ':' STRATSELECT { ($$) = ($2); } | { ($$) = NULL; } ; STRATGROUP : '(' STRATSELECT ')' { ($$) = ($2); } | STRATMETHOD ; STRATMETHOD : METHODNAME { Strat * strat; int meth; int methlen; StratMethodTab * methtab; int i, j; meth = methlen = 0; /* No method recognized yet */ methtab = parserstrattab->methtab; /* Point to the method table */ for (i = 0; methtab[i].name != NULL; i ++) { if ((strncasecmp (($1), /* Find longest matching code name */ methtab[i].name, j = strlen (methtab[i].name)) == 0) && (j > methlen)) { meth = methtab[i].meth; methlen = j; } } if (methlen == 0) { /* If method name not known */ errorPrint ("stratParserParse: invalid method name \"%s\", before \"%s\"", ($1), stratParserRemain ()); YYABORT; } if ((strat = (Strat *) memAlloc (sizeof (Strat))) == NULL) { errorPrint ("stratParserParse: out of memory (5)"); YYABORT; } strat->tabl = parserstrattab; strat->type = STRATNODEMETHOD; strat->data.method.meth = meth; /* Set method type */ if (methtab[meth].data != NULL) /* If default values exist */ memcpy (&strat->data.method.data, /* Set values to default */ methtab[meth].data, sizeof (StratNodeMethodData)); parserstratcurr = strat; /* Structure available for parameter processing */ } METHODPARAM { StratParamTab * paratab; int i; paratab = parserstrattab->paratab; /* Point to the parameter table */ for (i = 0; paratab[i].name != NULL; i ++) { if ((paratab[i].meth == parserstratcurr->data.method.meth) && /* If a strategy parameter found for this method */ (paratab[i].type == STRATPARAMSTRAT)) { if (*((Strat **) ((byte *) &parserstratcurr->data.method.data + /* And this parameter has not been set */ (paratab[i].dataofft - paratab[i].database))) == NULL) errorPrintW ("stratParserParse: strategy parameter \"%s\" of method \"%s\" not set, before \"%s\"", paratab[i].name, parserstrattab->methtab[parserstratcurr->data.method.meth].name, stratParserRemain ()); } } ($$) = parserstratcurr; /* Return current structure */ parserstratcurr = NULL; /* No current structure */ } ; METHODPARAM : { stratParserSelect (VALPARAM); /* Parse parameter tokens */ } '{' PARAMLIST { stratParserSelect (VALSTRAT); /* Parse strategy tokens */ } '}' | /* No parameters at all */ ; PARAMLIST : PARAMLIST ',' PARAMPARAM | PARAMPARAM ; PARAMPARAM : PARAMNAME { int para; int paralen; StratParamTab * paratab; int i, j; para = paralen = 0; /* No parameter recognized yet */ paratab = parserstrattab->paratab; /* Point to the parameter table */ for (i = 0; paratab[i].name != NULL; i ++) { if ((paratab[i].meth == parserstratcurr->data.method.meth) && (strncasecmp (($1), /* Find longest matching parameter name */ paratab[i].name, j = strlen (paratab[i].name)) == 0) && (j > paralen)) { para = i; paralen = j; } } if (paralen == 0) { errorPrint ("stratParserParse: invalid method parameter name \"%s\", before \"%s\"", ($1), stratParserRemain ()); YYABORT; } ($$).tabl = parserstrattab; /* Save current strategy tables */ parserparamcurr = ¶tab[para]; /* Save current parameter value */ stratParserSelect (parsermethtokentab[parserparamcurr->type & ~STRATPARAMDEPRECATED]); /* Get non-deprecated type */ if (parserparamcurr->type == STRATPARAMSTRAT) /* If parameter is a strategy */ parserstrattab = (StratTab *) parserparamcurr->datasltr; /* Use new strategy tables */ } '=' PARAMVAL { stratParserSelect (VALPARAM); /* Go-on reading parameters */ parserstrattab = ($2).tabl; /* Restore current strategy tables */ } ; PARAMVAL : VALCASE { char c; /* Character read */ char * p; /* Pointer to selector string */ int i; /* Index in selector string */ if ((parserparamcurr->type & STRATPARAMDEPRECATED) == 0) { /* If parameter is not deprecated */ c = ($1); /* First, use char as is */ for (p = (char *) parserparamcurr->datasltr, i = 0; (*p != '\0') && (*p != c); p ++, i ++) ; if (*p == '\0') { /* Char was not found */ c = tolower (c); /* Convert char to lower case */ for (p = (char *) parserparamcurr->datasltr, i = 0; (*p != '\0') && (*p != c); p ++, i ++) ; if (*p == '\0') { errorPrint ("stratParserParse: invalid method parameter switch \"%s=%c\", before \"%s\"", parserparamcurr->name, ($1), stratParserRemain ()); YYABORT; } } #ifdef SCOTCH_DEBUG_PARSER2 if ((parserparamcurr->dataofft - parserparamcurr->database + sizeof (int)) > sizeof (StratNodeMethodData)) { errorPrint ("stratParserParse: internal error (1)"); YYABORT; } #endif /* SCOTCH_DEBUG_PARSER2 */ *((int *) ((byte *) &parserstratcurr->data.method.data + (parserparamcurr->dataofft - parserparamcurr->database))) = i; } } | VALSDOUBLE { if ((parserparamcurr->type & STRATPARAMDEPRECATED) == 0) { /* If parameter is not deprecated */ #ifdef SCOTCH_DEBUG_PARSER2 if ((parserparamcurr->dataofft - parserparamcurr->database + sizeof (double)) > sizeof (StratNodeMethodData)) { errorPrint ("stratParserParse: internal error (2)"); YYABORT; } #endif /* SCOTCH_DEBUG_PARSER2 */ *((double *) ((byte *) &parserstratcurr->data.method.data + (parserparamcurr->dataofft - parserparamcurr->database))) = ($1); } } | VALSINT { if ((parserparamcurr->type & STRATPARAMDEPRECATED) == 0) { /* If parameter is not deprecated */ #ifdef SCOTCH_DEBUG_PARSER2 if ((parserparamcurr->dataofft - parserparamcurr->database + sizeof (INT)) > sizeof (StratNodeMethodData)) { errorPrint ("stratParserParse: internal error (3)"); YYABORT; } #endif /* SCOTCH_DEBUG_PARSER2 */ *((INT *) ((byte *) &parserstratcurr->data.method.data + (parserparamcurr->dataofft - parserparamcurr->database))) = (INT) ($1); } } | VALSTRING { if ((parserparamcurr->type & STRATPARAMDEPRECATED) == 0) { /* If parameter is not deprecated */ #ifdef SCOTCH_DEBUG_PARSER2 if ((parserparamcurr->dataofft - parserparamcurr->database + strlen ($1) + 1) > sizeof (StratNodeMethodData)) { errorPrint ("stratParserParse: internal error (4)"); YYABORT; } #endif /* SCOTCH_DEBUG_PARSER2 */ strcpy ((char *) ((byte *) &parserstratcurr->data.method.data + (parserparamcurr->dataofft - parserparamcurr->database)), ($1)); } } | { ($$).strat = parserstratcurr; ($$).param = parserparamcurr; parserstratcurr = NULL; parserparamcurr = NULL; } STRATSELECT { parserstratcurr = ($1).strat; /* Restore current method */ parserparamcurr = ($1).param; /* Restore current parameter */ if ((parserparamcurr->type & STRATPARAMDEPRECATED) == 0) { /* If parameter is not deprecated */ #ifdef SCOTCH_DEBUG_PARSER2 if ((parserparamcurr->dataofft - parserparamcurr->database + sizeof (Strat *)) > sizeof (StratNodeMethodData)) { errorPrint ("stratParserParse: internal error (5)"); YYABORT; } #endif /* SCOTCH_DEBUG_PARSER2 */ *((Strat **) ((byte *) &parserstratcurr->data.method.data + (parserparamcurr->dataofft - parserparamcurr->database))) = ($2); } } | error { errorPrint ("stratParserParse: invalid value for parameter \"%s\" of method \"%s\", before \"%s\"", parserparamcurr->name, parserstratcurr->tabl->methtab[parserstratcurr->data.method.meth].name, stratParserRemain ()); YYABORT; } ; TEST : TESTOR ; TESTOR : TESTOR '|' TESTAND { StratTest * test; if ((test = (StratTest *) memAlloc (sizeof (StratTest))) == NULL) { errorPrint ("stratParserParse: out of memory (6)"); stratTestExit ($1); stratTestExit ($3); YYABORT; } test->typetest = STRATTESTOR; test->typenode = STRATPARAMLOG; test->data.test[0] = ($1); test->data.test[1] = ($3); ($$) = test; } | TESTAND ; TESTAND : TESTAND '&' TESTNOT { StratTest * test; if ((test = (StratTest *) memAlloc (sizeof (StratTest))) == NULL) { errorPrint ("stratParserParse: out of memory (7)"); stratTestExit ($1); stratTestExit ($3); YYABORT; } test->typetest = STRATTESTAND; test->typenode = STRATPARAMLOG; test->data.test[0] = ($1); test->data.test[1] = ($3); ($$) = test; } | TESTNOT ; TESTNOT : '!' TESTNOT { StratTest * test; if ((test = (StratTest *) memAlloc (sizeof (StratTest))) == NULL) { errorPrint ("stratParserParse: out of memory (8)"); stratTestExit ($2); YYABORT; } test->typetest = STRATTESTNOT; test->typenode = STRATPARAMLOG; test->data.test[0] = ($2); ($$) = test; } | '(' TESTOR ')' { ($$) = ($2); } | TESTREL ; TESTREL : TESTEXPR1 TESTRELOP TESTEXPR1 { StratTest * test; if ((test = (StratTest *) memAlloc (sizeof (StratTest))) == NULL) { errorPrint ("stratParserParse: out of memory (9)"); stratTestExit ($1); stratTestExit ($3); YYABORT; } test->typetest = ($2); test->typenode = STRATPARAMLOG; test->data.test[0] = ($1); test->data.test[1] = ($3); ($$) = test; } ; TESTRELOP : '<' { ($$) = STRATTESTLT; } | '=' { ($$) = STRATTESTEQ; } | '>' { ($$) = STRATTESTGT; } ; TESTEXPR1 : TESTEXPR1 TESTEXPR1OP TESTEXPR2 { StratTest * test; if ((test = (StratTest *) memAlloc (sizeof (StratTest))) == NULL) { errorPrint ("stratParserParse: out of memory (10)"); stratTestExit ($1); stratTestExit ($3); YYABORT; } test->typetest = ($2); test->data.test[0] = ($1); test->data.test[1] = ($3); ($$) = test; } | TESTEXPR2 ; TESTEXPR1OP : '+' { ($$) = STRATTESTADD; } | '-' { ($$) = STRATTESTSUB; } ; TESTEXPR2 : TESTEXPR2 TESTEXPR2OP TESTEXPR3 { StratTest * test; if ((test = (StratTest *) memAlloc (sizeof (StratTest))) == NULL) { stratTestExit ($1); stratTestExit ($3); errorPrint ("stratParserParse: out of memory (11)"); YYABORT; } test->typetest = ($2); test->data.test[0] = ($1); test->data.test[1] = ($3); ($$) = test; } | TESTEXPR3 ; TESTEXPR2OP : '*' { ($$) = STRATTESTMUL; } ; TESTEXPR3 : TESTEXPR3 TESTEXPR3OP TESTEXPR4 { StratTest * test; if ((test = (StratTest *) memAlloc (sizeof (StratTest))) == NULL) { errorPrint ("stratParserParse: out of memory (12)"); stratTestExit ($1); stratTestExit ($3); YYABORT; } test->typetest = ($2); test->data.test[0] = ($1); test->data.test[1] = ($3); ($$) = test; } | TESTEXPR4 ; TESTEXPR3OP : '%' { ($$) = STRATTESTMOD; } ; TESTEXPR4 : '(' TESTEXPR1 ')' { ($$) = ($2); } | TESTVAL | TESTVAR ; TESTVAL : VALSDOUBLE { StratTest * test; if ((test = (StratTest *) memAlloc (sizeof (StratTest))) == NULL) { errorPrint ("stratParserParse: out of memory (13)"); YYABORT; } test->typetest = STRATTESTVAL; test->typenode = STRATPARAMDOUBLE; test->data.val.valdbl = ($1); ($$) = test; } | VALSINT { StratTest * test; if ((test = (StratTest *) memAlloc (sizeof (StratTest))) == NULL) { errorPrint ("stratParserParse: out of memory (14)"); YYABORT; } test->typetest = STRATTESTVAL; test->typenode = STRATPARAMINT; test->data.val.valint = ($1); ($$) = test; } ; TESTVAR : PARAMNAME { StratTest * test; StratParamTab * condtab; int para; int paralen; int i, j; para = paralen = 0; /* No parameter recognized yet */ condtab = parserstrattab->condtab; /* Point to parameter table */ for (i = 0; condtab[i].name != NULL; i ++) { if ((strncasecmp (($1), /* Find longest matching parameter name */ condtab[i].name, j = strlen (condtab[i].name)) == 0) && (j > paralen)) { para = i; paralen = j; } } if (paralen == 0) { errorPrint ("stratParserParse: invalid graph parameter name \"%s\", before \"%s\"", ($1), stratParserRemain ()); YYABORT; } if ((test = (StratTest *) memAlloc (sizeof (StratTest))) == NULL) { errorPrint ("stratParserParse: out of memory (15)"); YYABORT; } test->typetest = STRATTESTVAR; test->typenode = condtab[para].type; test->data.var.datatab = parserstrattab; test->data.var.datadisp = condtab[para].dataofft - condtab[para].database; ($$) = test; } ; VALSDOUBLE : TESTEXPR1OP VALDOUBLE { ($$) = (($1) == STRATTESTSUB) ? - ($2) : ($2); } | VALDOUBLE ; VALSINT : TESTEXPR1OP VALINT { ($$) = (($1) == STRATTESTSUB) ? - ($2) : ($2); } | VALINT ; %% /* ** The static and global definitions (bis). ** These are put at the end of the file because ** the token values that they use are not yet ** defined in the first section of the file. */ unsigned int parsermethtokentab[] = { /* Table for parameter/token type conversion */ VALCASE, VALDOUBLE, VALINT, -1, /* No logical parameters */ VALSTRAT, VALSTRING, -1 /* One more value to detect array overflow */ }; /************************************/ /* */ /* These routines drive the parser. */ /* */ /************************************/ /* This routine is the entry point for ** the strategy parser. ** It returns: ** - !NULL : pointer to the strategy. ** - NULL : on error. */ Strat * stratParserParse ( const StratTab * const strattab, /*+ Pointer to parsing tables +*/ const char * const string) /*+ Strategy string to parse +*/ { yyclearin; /* Reset the parser state */ #ifdef SCOTCH_DEBUG_PARSER3 yydebug = 1; /* Set debugging if needed */ #endif /* SCOTCH_DEBUG_PARSER3 */ stratParserInit (string); /* Initialize the lexical parser */ parserstrattab = strattab; /* Point to the parsing tables */ parserstratcurr = NULL; /* Clear up the temporary strategy pointer */ if (stratParserParse2 () != 0) { /* Parse the strategy string */ if (parserstratcurr != NULL) stratExit (parserstratcurr); return (NULL); } return (parserstratcurr); /* Return strategy pointer */ } /* This routine displays the parser error message. ** It returns: ** - 1 : in all cases. */ static int stratParserError ( const char * const errstr) { errorPrint ("stratParserParse: invalid strategy string, before \"%s\"", stratParserRemain ()); return (1); } scotch-6.0.4.dfsg/src/libscotch/bdgraph_check.c0000644002563400244210000003201412400671554024546 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2011,2013,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bdgraph_check.c **/ /** **/ /** AUTHORS : Jun-Ho HER (v6.0) **/ /** Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the distributed **/ /** bipartition graph consistency checking **/ /** routine. **/ /** **/ /** DATES : # Version 5.1 : from : 10 sep 2007 **/ /** to 22 jul 2008 **/ /** # Version 6.0 : from : 03 sep 2011 **/ /** to 31 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #include "module.h" #include "common.h" #include "arch.h" #include "dgraph.h" #include "bdgraph.h" int bdgraphCheck ( const Bdgraph * restrict const grafptr) { Dgraph grafdat; /* Dummy graph for ghost edge array */ MPI_Comm proccomm; /* Graph communicator */ int * restrict flagloctax; /* Frontier flag array */ GraphPart * restrict partgsttax; Gnum fronlocnum; Gnum vertlocnum; /* Number of current vertex */ Gnum complocload[2]; Gnum complocsize[2]; Gnum commcut[2]; Gnum commlocloadintn; Gnum commlocloadextn; Gnum commlocgainextn; Gnum edlolocval; Gnum reduloctab[21]; /* Arrays for reductions */ Gnum reduglbtab[21]; int chekglbval; /* Global consistency flag */ int cheklocval; /* Local consistency flag */ proccomm = grafptr->s.proccomm; if (MPI_Barrier (proccomm) != MPI_SUCCESS) { /* Synchronize */ errorPrint ("bdgraphCheck: communication error (1)"); return (1); } cheklocval = 0; /* Assume everything is all right */ if ((grafptr->compglbload0min < 0) || (grafptr->compglbload0max > grafptr->s.veloglbsum)) { errorPrint ("bdgraphCheck: invalid extrema loads"); cheklocval = 1; } if (grafptr->compglbload0 != (grafptr->compglbload0avg + grafptr->compglbload0dlt)) { errorPrint ("bdgraphCheck: invalid global balance"); cheklocval |= 2; } if ((grafptr->fronlocnbr < 0) || (grafptr->fronlocnbr > grafptr->s.vertlocnbr)) { errorPrint ("bdgraphCheck: invalid number of local frontier vertices"); cheklocval |= 4; } if (grafptr->partgsttax != NULL) { for (vertlocnum = grafptr->s.baseval; vertlocnum < grafptr->s.vertlocnnd; vertlocnum ++) { if ((grafptr->partgsttax[vertlocnum] | 1) != 1) { /* If part is neither 0 nor 1 */ errorPrint ("bdgraphCheck: invalid local part array"); cheklocval |= 8; break; } } } grafdat = grafptr->s; /* Copy minimal distributed graph data */ if (dgraphGhst (&grafdat) != 0) { /* Create ghost edge array if did not exist */ errorPrint ("bdgraphCheck: cannot compute ghost edge array"); cheklocval |= 16; } if (memAllocGroup ((void **) (void *) &partgsttax, (size_t) (grafdat.vertgstnbr * sizeof (GraphPart)), &flagloctax, (size_t) (grafptr->s.vertlocnbr * sizeof (int)), NULL) == NULL) { errorPrint ("bdgraphCheck: out of memory"); cheklocval |= 32; } else { memSet (flagloctax, ~0, grafptr->s.vertlocnbr * sizeof (int)); flagloctax -= grafptr->s.baseval; for (fronlocnum = 0; fronlocnum < grafptr->fronlocnbr; fronlocnum ++) { Gnum vertlocnum; vertlocnum = grafptr->fronloctab[fronlocnum]; if ((vertlocnum < grafptr->s.baseval) || (vertlocnum >= grafptr->s.vertlocnnd)) { errorPrint ("bdgraphCheck: invalid vertex index in frontier array"); cheklocval |= 64; break; } if (flagloctax[vertlocnum] != ~0) { errorPrint ("bdgraphCheck: duplicate vertex in frontier array"); cheklocval |= 128; break; } flagloctax[vertlocnum] = 0; } } reduloctab[0] = grafptr->commglbload; reduloctab[1] = - grafptr->commglbload; reduloctab[2] = grafptr->compglbload0; reduloctab[3] = - grafptr->compglbload0; reduloctab[4] = grafptr->s.veloglbsum - grafptr->compglbload0; reduloctab[5] = - grafptr->s.veloglbsum + grafptr->compglbload0; reduloctab[6] = grafptr->compglbsize0; reduloctab[7] = - grafptr->compglbsize0; reduloctab[8] = grafptr->s.vertglbnbr - grafptr->compglbsize0; reduloctab[9] = - grafptr->s.vertglbnbr + grafptr->compglbsize0; reduloctab[10] = grafptr->commglbgainextn; reduloctab[11] = - grafptr->commglbgainextn; reduloctab[12] = grafptr->commglbgainextn0; reduloctab[13] = - grafptr->commglbgainextn0; reduloctab[14] = grafptr->commglbloadextn0; reduloctab[15] = - grafptr->commglbloadextn0; reduloctab[16] = grafptr->fronglbnbr; reduloctab[17] = - grafptr->fronglbnbr; reduloctab[18] = grafptr->levlnum; reduloctab[19] = - grafptr->levlnum; reduloctab[20] = cheklocval; if (MPI_Allreduce (reduloctab, reduglbtab, 21, GNUM_MPI, MPI_MAX, proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphCheck: communication error (2)"); return (1); } if (reduglbtab[20] != 0) { /* Exit and Return information of previous errors */ if (partgsttax != NULL) memFree (partgsttax); /* Free yet unbased group leader */ return ((int) reduglbtab[20]); } if ((reduglbtab[1] != - reduglbtab[0]) || (reduglbtab[3] != - reduglbtab[2]) || (reduglbtab[5] != - reduglbtab[4]) || (reduglbtab[7] != - reduglbtab[6]) || (reduglbtab[9] != - reduglbtab[8]) || (reduglbtab[11] != - reduglbtab[10]) || (reduglbtab[13] != - reduglbtab[12]) || (reduglbtab[15] != - reduglbtab[14]) || (reduglbtab[17] != - reduglbtab[16]) || (reduglbtab[19] != - reduglbtab[18])) { errorPrint ("bdgraphCheck: inconsistent global graph data"); return (1); } if (grafptr->partgsttax != NULL) memCpy (partgsttax, grafptr->partgsttax + grafptr->s.baseval, grafptr->s.vertlocnbr * sizeof (GraphPart)); /* Copy local part data */ else memSet (partgsttax, 0, grafptr->s.vertlocnbr * sizeof (GraphPart)); dgraphHaloSync (&grafdat, partgsttax, GRAPHPART_MPI); /* Spread yet unbased halo part data across neighboring processes */ partgsttax -= grafptr->s.baseval; cheklocval = 0; for (fronlocnum = 0; fronlocnum < grafptr->fronlocnbr; fronlocnum ++) { Gnum vertlocnum; Gnum edgelocnum; GraphPart commcut; GraphPart partval; vertlocnum = grafptr->fronloctab[fronlocnum]; partval = partgsttax[vertlocnum]; for (edgelocnum = grafptr->s.vertloctax[vertlocnum], commcut = 0; edgelocnum < grafptr->s.vendloctax[vertlocnum]; edgelocnum ++) { GraphPart partdlt; partdlt = partgsttax[grafdat.edgegsttax[edgelocnum]] ^ partval; commcut |= partdlt; } if (commcut == 0) { errorPrint ("bdgraphCheck: invalid vertex in frontier array"); cheklocval |= 1; break; } } complocload[0] = complocload[1] = 0; complocsize[0] = complocsize[1] = 0; commlocloadintn = 0; commlocloadextn = 0; commlocgainextn = 0; edlolocval = 1; /* Assume edges are not weighted */ for (vertlocnum = grafptr->s.baseval; vertlocnum < grafptr->s.vertlocnnd; vertlocnum ++) { Gnum partval; /* Part of current vertex */ Gnum edgelocnum; /* Number of current edge */ partval = (Gnum) partgsttax[vertlocnum]; if (grafptr->veexloctax != NULL) { Gnum veexval; veexval = grafptr->veexloctax[vertlocnum]; commlocloadextn += veexval * partval; commlocgainextn += veexval * (1 - 2 * partval); } complocload[partval] += (grafptr->s.veloloctax == NULL) ? 1 : grafptr->s.veloloctax[vertlocnum]; complocsize[partval] ++; commcut[0] = commcut[1] = 0; for (edgelocnum = grafptr->s.vertloctax[vertlocnum]; edgelocnum < grafptr->s.vendloctax[vertlocnum]; edgelocnum ++) { int partend; int partdlt; if (grafptr->s.edloloctax != NULL) edlolocval = grafptr->s.edloloctax[edgelocnum]; partend = partgsttax[grafdat.edgegsttax[edgelocnum]]; partdlt = partval ^ partend; commcut[partend] ++; commlocloadintn += partdlt * edlolocval; /* Internal load is accounted for twice */ } if ((commcut[0] != 0) && (commcut[1] != 0) && /* If vertex should be in separator */ (flagloctax[vertlocnum] != 0)) { errorPrint ("bdgraphCheck: vertex should be in separator"); cheklocval |= 2; } } if (grafptr->s.edgegsttax != grafdat.edgegsttax) /* If ghost edge array was allocated here, free it manually */ memFree (grafdat.edgegsttax + grafptr->s.baseval); if (grafptr->s.procsidtab != grafdat.procsidtab) /* The same for procsidtab */ memFree (grafdat.procsidtab); memFree (partgsttax + grafptr->s.baseval); /* Free group leader */ if ((cheklocval == 0) && ((complocsize[0] != grafptr->complocsize0) || (complocsize[1] != (grafptr->s.vertlocnbr - grafptr->complocsize0)))) { errorPrint ("bdgraphCheck: invalid local part size"); cheklocval |= 4; } reduloctab[0] = complocload[0]; reduloctab[1] = complocsize[0]; reduloctab[2] = commlocloadintn; /* Twice the internal load; sum globally before dividing by two */ reduloctab[3] = commlocloadextn; reduloctab[4] = commlocgainextn; reduloctab[5] = cheklocval; if (MPI_Allreduce (reduloctab, reduglbtab, 6, GNUM_MPI, MPI_SUM, proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphCheck: communication error (3)"); return (1); } if (reduglbtab[5] != 0) /* Return from previous errors */ return (1); if (grafptr->compglbload0 != reduglbtab[0]) { errorPrint ("bdgraphCheck: invalid global part loads"); cheklocval |= 8; } if (grafptr->compglbsize0 != reduglbtab[1]) { errorPrint ("bdgraphCheck: invalid global part sizes"); cheklocval |= 16; } if (grafptr->commglbload != ((reduglbtab[2] / 2) * grafptr->domndist + reduglbtab[3] + grafptr->commglbloadextn0)) { errorPrint ("bdgraphCheck: invalid global communication loads"); cheklocval |= 32; } if (grafptr->commglbgainextn != reduglbtab[4]) { errorPrint ("bdgraphCheck: invalid global communication gains"); cheklocval |= 64; } if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphCheck: communication error (4)"); return (1); } return (chekglbval); } scotch-6.0.4.dfsg/src/libscotch/dgraph_build_hcub.c0000644002563400244210000002221311631447170025427 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_build_hcub.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Cedric CHEVALIER **/ /** **/ /** FUNCTION : These lines are the distributed source **/ /** graph building routines for hypercube **/ /** graphs. **/ /** **/ /** DATES : # Version P0.1 : from : 19 may 1999 **/ /** to : 19 may 1999 **/ /** # Version P0.2 : from : 02 feb 2000 **/ /** to : 02 feb 2000 **/ /** # Version 5.0 : from : 20 jul 2005 **/ /** to : 10 sep 2007 **/ /** # Version 5.1 : from : 12 nov 2008 **/ /** to : 12 nov 2008 **/ /** **/ /************************************************************/ #define DGRAPH #include "module.h" #include "common.h" #include "dgraph.h" /*******************************************/ /* */ /* The distributed graph building routine. */ /* */ /*******************************************/ /* This routine builds a distributed hypercube of ** given dimension. ** Since this routine calls dgraphBuild, the private ** data of the Dgraph structure will be initialized ** by the latter, if needed. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int dgraphBuildHcub ( Dgraph * restrict const grafptr, /* Graph */ const Gnum hcubdim, /* Hypercube dimension */ const Gnum baseval, /* Base value */ const Gnum flagval) /* Flags */ { Gnum procngbnum; Gnum vertglbnbr; /* Total number of vertices */ Gnum vertglbnum; /* Global number of current vertex */ Gnum vertlocnbr; /* Number of local vertices */ Gnum velolocnbr; /* Number of local vertex loads */ Gnum vertlocnnd; Gnum vertlocnum; Gnum * restrict vertloctax; Gnum * restrict veloloctax; #ifdef SCOTCH_DEBUG_DGRAPH3 Gnum * restrict vlblloctax; #endif /* SCOTCH_DEBUG_DGRAPH3 */ Gnum edgelocnbr; Gnum * restrict edgeloctax; Gnum edgelocnum; Gnum edlolocnbr; Gnum * restrict edloloctax; int cheklocval; Gnum reduloctab[7]; Gnum reduglbtab[7]; vertglbnbr = 1 << hcubdim; vertlocnbr = DATASIZE (vertglbnbr, grafptr->procglbnbr, grafptr->proclocnum); velolocnbr = ((flagval & 1) != 0) ? vertlocnbr : 0; edgelocnbr = vertlocnbr * hcubdim; /* Set local number of arcs */ edlolocnbr = ((flagval & 2) != 0) ? edgelocnbr : 0; for (procngbnum = 0, vertglbnum = 0; /* Compute index of first local vertex */ procngbnum < grafptr->proclocnum; procngbnum ++) vertglbnum += DATASIZE (vertglbnbr, grafptr->procglbnbr, procngbnum); cheklocval = 0; vertloctax = edgeloctax = NULL; if (memAllocGroup ((void **) (void *) &vertloctax, (size_t) ((vertlocnbr + 1) * sizeof (Gnum)), /* Compact vertex array */ #ifdef SCOTCH_DEBUG_DGRAPH3 &vlblloctax, (size_t) (vertlocnbr * sizeof (Gnum)), #endif /* SCOTCH_DEBUG_DGRAPH3 */ &veloloctax, (size_t) (vertlocnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("dgraphBuildHcub: out of memory (1)"); cheklocval = 1; } else if (memAllocGroup ((void **) (void *) &edgeloctax, (size_t) (edgelocnbr * sizeof (Gnum)), &edloloctax, (size_t) (edlolocnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("dgraphBuildHcub: out of memory (2)"); cheklocval = 1; } reduloctab[0] = hcubdim; reduloctab[1] = - hcubdim; reduloctab[2] = baseval; reduloctab[3] = - baseval; reduloctab[4] = flagval; reduloctab[5] = - flagval; reduloctab[6] = cheklocval; if (MPI_Allreduce (reduloctab, reduglbtab, 7, GNUM_MPI, MPI_MAX, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphBuildHcub: communication error"); return (1); } if (reduglbtab[6] != 0) { if (vertloctax != NULL) { if (edgeloctax != NULL) memFree (edgeloctax); memFree (vertloctax); } return (1); } if ((reduglbtab[1] != - reduglbtab[0]) || (reduglbtab[3] != - reduglbtab[2]) || (reduglbtab[5] != - reduglbtab[4])) { errorPrint ("dgraphBuildHcub: inconsistent parameters"); return (1); } vertloctax -= baseval; veloloctax = ((flagval & 1) != 0) ? (veloloctax - baseval) : NULL; edgeloctax -= baseval; edloloctax = ((flagval & 2) != 0) ? (edloloctax - baseval) : NULL; #ifdef SCOTCH_DEBUG_DGRAPH3 vlblloctax -= baseval; #endif /* SCOTCH_DEBUG_DGRAPH3 */ for (vertlocnum = baseval, vertlocnnd = vertlocnbr + baseval, edgelocnum = baseval; vertlocnum < vertlocnnd; vertlocnum ++, vertglbnum ++) { Gnum vertngbbit; /* Bit that differs between neighbors */ if (veloloctax != NULL) veloloctax[vertlocnum] = 1 + (vertglbnum & 3); /* Pseudo random weight (1 to 5) */ #ifdef SCOTCH_DEBUG_DGRAPH3 vlblloctax[vertlocnum] = ((vertglbnum * COARHASHPRIME) % vertglbnbr) + baseval; /* Hash vertices to spread labels */ #endif /* SCOTCH_DEBUG_DGRAPH3 */ vertloctax[vertlocnum] = edgelocnum; for (vertngbbit = 1; vertngbbit < vertglbnbr; vertngbbit <<= 1, edgelocnum ++) { #ifdef SCOTCH_DEBUG_DGRAPH3 edgeloctax[edgelocnum] = (((vertglbnum ^ vertngbbit) * COARHASHPRIME) % vertglbnbr) + baseval; #else /* SCOTCH_DEBUG_DGRAPH3 */ edgeloctax[edgelocnum] = (vertglbnum ^ vertngbbit) + baseval; #endif /* SCOTCH_DEBUG_DGRAPH3 */ if (edloloctax != NULL) edloloctax[edgelocnum] = ((vertglbnum + edgeloctax[edgelocnum]) % 16) + 1; /* Pseudo random weight (1 to 16) */ } } vertloctax[vertlocnum] = edgelocnum; /* Mark end of local vertex array */ #ifdef SCOTCH_DEBUG_DGRAPH2 if (edgelocnum != edgelocnbr + baseval) { errorPrint ("dgraphBuildHcub: internal error"); memFree (vertloctax + baseval); /* Free memory group leader */ return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ if (dgraphBuild2 (grafptr, baseval, /* Build the distributed graph */ #ifdef SCOTCH_DEBUG_DGRAPH3 vertlocnbr, vertlocnbr, vertloctax, vertloctax + 1, NULL, vertlocnbr, NULL, vlblloctax, #else /* SCOTCH_DEBUG_DGRAPH3 */ vertlocnbr, vertlocnbr, vertloctax, vertloctax + 1, NULL, vertlocnbr, NULL, NULL, #endif /* SCOTCH_DEBUG_DGRAPH3 */ edgelocnbr, edgelocnbr, edgeloctax, NULL, edloloctax, hcubdim) != 0) { memFree (edgeloctax + baseval); /* Free memory group leaders */ memFree (vertloctax + baseval); return (1); } grafptr->flagval |= DGRAPHFREETABS | DGRAPHVERTGROUP | DGRAPHEDGEGROUP; /* Arrays created by the routine itself */ return (0); } scotch-6.0.4.dfsg/src/libscotch/vmesh_separate_fm.h0000644002563400244210000001613611631447171025507 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vmesh_separate_fm.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the improved Fiduccia-Mattheyses **/ /** mesh element separation routine. **/ /** **/ /** DATES : # Version 4.0 : from : 26 feb 2003 **/ /** to 06 may 2004 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ Gain table subbits. +*/ #define VMESHSEPAFMGAINBITS 4 /*+ Prime number for hashing vertex numbers. +*/ #define VMESHSEPAFMHASHPRIME 11 /*+ Prime number for hashing +*/ /*+ Gain table vertex status. +*/ #define VMESHSEPAFMSTATEFREE ((GainLink *) 0) /*+ Element is free or separator-chained +*/ #define VMESHSEPAFMSTATEUSED ((GainLink *) 1) /*+ Element already swapped +*/ #define VMESHSEPAFMSTATELINK ((GainLink *) 2) /*+ Currently in gain table if higher +*/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct VmeshSeparateFmParam_ { INT movenbr; /*+ Maximum number of uneffective moves that can be done +*/ INT passnbr; /*+ Number of passes to be performed (-1 : infinite) +*/ double deltrat; /*+ Maximum weight imbalance ratio +*/ } VmeshSeparateFmParam; /*+ The hash element structure. The goal of both hash arrays is to record partition data that supercedes the one contained in the calling Vmesh structure, until the newly computed partition is written back to the Vmesh. +*/ typedef struct VmeshSeparateFmElement_ { GainLink gainlink; /*+ Gain link if moved to other part; FIRST +*/ Gnum velmnum; /*+ Number of vertex in hash table +*/ int vertpart; /*+ Vertex part +*/ Gnum ncmpcut2; /*+ Number of neighbor nodes in separator +*/ Gnum ncmpgain2; /*+ Separator gain if moved to given part +*/ Gnum ncmpgaindlt; /*+ Node load imbalance if element swapped +*/ Gnum mswpnum; /*+ Number of move sweep when data recorded +*/ } VmeshSeparateFmElement; /*+ The hash node structure. +*/ typedef struct VmeshSeparateFmNode_ { Gnum vnodnum; /*+ Number of vertex in hash table +*/ Gnum vnloval; /*+ Vertex load +*/ int vertpart; /*+ Vertex part +*/ Gnum ecmpsize0; /*+ Number of element neighbors in part 0 +*/ Gnum mswpnum; /*+ Number of move sweep when data recorded +*/ } VmeshSeparateFmNode; /*+ The move recording structure. +*/ typedef struct VmeshSeparateFmSave_ { Gnum hertnum; /*+ Hash index of vertex, (helmnum) or (-1 - hnodnum) +*/ union { /*+ Stored data to recover +*/ struct { /*+ Recovery data for element +*/ int vertpart; /*+ Vertex part +*/ Gnum ncmpcut2; /*+ Number of neighbor nodes in separator +*/ Gnum ncmpgain2; /*+ Separator gain if moved to given part +*/ Gnum ncmpgaindlt; /*+ Node load imbalance if element swapped +*/ } elem; struct { /*+ Recovery data for node +*/ int vertpart; /*+ Vertex part +*/ Gnum ecmpsize0; /*+ Number of element neighbors in part 0 +*/ } node; } data; } VmeshSeparateFmSave; /* ** The function prototypes. */ #ifndef VMESH_SEPARATE_FM #define static #endif int vmeshSeparateFm (Vmesh * restrict const, const VmeshSeparateFmParam * restrict const); static VmeshSeparateFmElement * vmeshSeparateFmTablGet (GainTabl * const, const Gnum, const Gnum); static int vmeshSeparateFmResize (GainTabl * restrict const, VmeshSeparateFmElement * restrict * const, VmeshSeparateFmNode * restrict * const, VmeshSeparateFmSave * restrict * const, const Gnum, VmeshSeparateFmElement **, VmeshSeparateFmElement **, const Gnum); #ifdef SCOTCH_DEBUG_VMESH3 static int vmeshSeparateFmCheck (const Vmesh * const, const VmeshSeparateFmElement * restrict, const VmeshSeparateFmNode * restrict, const Gnum, const Gnum, const Gnum); #endif /* SCOTCH_DEBUG_VMESH3 */ #undef static scotch-6.0.4.dfsg/src/libscotch/common_file.c0000644002563400244210000003210712473137627024304 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : common_file.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles files and file **/ /** names. **/ /** **/ /** DATES : # Version 5.0 : from : 21 may 2007 **/ /** to : 16 mar 2008 **/ /** # Version 5.1 : from : 27 jun 2010 **/ /** to 27 jun 2010 **/ /** # Version 6.0 : from : 10 nov 2014 **/ /** to 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define COMMON_FILE #ifndef COMMON_NOMODULE #include "module.h" #endif /* COMMON_NOMODULE */ #include "common.h" #include "common_file.h" /*********************************/ /* */ /* Basic routines for filenames. */ /* */ /*********************************/ /* This routine expands distributed filenames ** according to process numbers and the root ** process number. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int fileNameDistExpand ( char ** const nameptr, /*+ Pointer to name string pointer +*/ const int procnbr, /*+ Number of processes +*/ const int procnum, /*+ Number of current process +*/ const int protnum) /*+ Root process number +*/ { int namemax; int namenum; char * naexptr; int naexmax; int naexnum; int flagval; /* Flag set if expansion took place */ namemax = strlen (*nameptr); naexmax = namemax + FILENAMEDISTEXPANDNBR * 2; if ((naexptr = memAlloc ((naexmax + 1) * sizeof (char))) == NULL) /* "+ 1" for terminating character */ return (1); #ifdef COMMON_DEBUG sprintf (naexptr, FILENAMEDISTEXPANDSTR, procnbr); /* TRICK: Test if FILENAMEDISTEXPANDNBR is a size large enough */ if (atoi (naexptr) != procnbr) { errorPrint ("fileNameDistExpand: undersized integer string size"); memFree (naexptr); return (1); } #endif /* COMMON_DEBUG */ for (namenum = naexnum = flagval = 0; namenum < namemax; ) { char charval; int dataval = 0; int datasiz; charval = (*nameptr)[namenum ++]; /* Get current characted */ datasiz = 1; /* Assume individual expanded character */ if (charval == '%') { char chnxval; /* Value of next char */ switch (chnxval = (*nameptr)[namenum ++]) { case 'p' : /* "%p" translates into number of processes */ flagval = 1; datasiz = FILENAMEDISTEXPANDNBR; dataval = procnbr; break; case 'r' : /* "%r" translates into process rank */ flagval = 1; datasiz = FILENAMEDISTEXPANDNBR; dataval = procnum; break; case '-' : /* "%-" translates into nothing but indicates distributed file */ datasiz = 0; flagval = 1; break; case '%' : /* "%%" translates into '%' */ break; default : charval = chnxval; /* Unrecognized character */ } } if (datasiz > 0) { if ((naexnum + datasiz) > naexmax) { char * nanwptr; naexmax += datasiz + FILENAMEDISTEXPANDNBR; if ((nanwptr = memRealloc (naexptr, (naexmax + 1) * sizeof (char))) == NULL) { /* "+ 1" for terminating character */ memFree (naexptr); return (1); } naexptr = nanwptr; } if (datasiz == 1) naexptr[naexnum ++] = charval; else { sprintf (&naexptr[naexnum], FILENAMEDISTEXPANDSTR, dataval); /* TRICK: Change format string if FILENAMEDISTEXPANDNBR changes */ naexptr[naexnum + FILENAMEDISTEXPANDNBR] = ' '; naexnum = strchr (&naexptr[naexnum], ' ') - naexptr; } } } naexptr[naexnum] = '\0'; /* Set terminating character as there is always room for it */ if ((flagval != 0) || (procnum == protnum)) /* If file name is a distributed one or we are the root process */ *nameptr = naexptr; /* Replace new string by old one */ else { memFree (naexptr); /* No need for the expanded string */ *nameptr = NULL; } return (0); } /* This routine initializes a block of ** file descriptor structures. ** It returns: ** - void : in all cases. */ void fileBlockInit ( File * const filetab, const int filenbr) { int i; for (i = 0; i < filenbr; i ++) { /* For all file names */ filetab[i].nameptr = "-"; /* Assume standard stream */ filetab[i].fileptr = (filetab[i].modeptr[0] == 'r') ? stdin : stdout; filetab[i].dataptr = NULL; /* Assume nothing to free */ } } /* This routine opens a block of file ** descriptor structures. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int fileBlockOpen ( File * const filetab, const int filenbr) { int i, j; for (i = 0; i < filenbr; i ++) { /* For all file names */ if (filetab[i].fileptr == NULL) /* If unwanted stream, do nothing */ continue; for (j = 0; j < i; j ++) { if ((filetab[i].modeptr[0] == filetab[j].modeptr[0]) && /* If very same name with same opening mode */ (filetab[j].nameptr != NULL) && (strcmp (filetab[i].nameptr, filetab[j].nameptr) == 0)) { filetab[i].fileptr = filetab[j].fileptr; /* Share pointer to already processed stream */ filetab[i].nameptr = NULL; /* Do not close this stream multiple times */ break; } } if (j == i) { /* If original stream */ int compval; /* Compression type */ FILE * compptr; /* Processed ((un)compressed) stream */ if (filetab[i].nameptr[0] != '-') { /* If not standard stream, open it */ if ((filetab[i].fileptr = fopen (filetab[i].nameptr, filetab[i].modeptr)) == NULL) { /* Open the file */ errorPrint ("fileBlockOpen: cannot open file (%d)", i); return (1); } } compval = (filetab[i].modeptr[0] == 'r') ? fileUncompressType (filetab[i].nameptr) : fileCompressType (filetab[i].nameptr); if (compval < 0) { errorPrint ("fileBlockOpen: (un)compression type not implemented"); return (1); } compptr = (filetab[i].modeptr[0] == 'r') ? fileUncompress (filetab[i].fileptr, compval) : fileCompress (filetab[i].fileptr, compval); if (compptr == NULL) { errorPrint ("fileBlockOpen: cannot create (un)compression subprocess"); return (1); } filetab[i].fileptr = compptr; /* Use processed stream instead of original stream */ } } return (0); } /* This routine opens a block of eventually ** distributed file descriptor structures. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int fileBlockOpenDist ( File * const filetab, const int filenbr, const int procglbnbr, const int proclocnum, const int protglbnum) { int i, j; for (i = 0; i < filenbr; i ++) { /* For all file names */ if (filetab[i].fileptr == NULL) { /* If unwanted stream, do nothing */ filetab[i].nameptr = NULL; /* Do nothing on closing, too */ continue; } if (fileNameDistExpand (&filetab[i].nameptr, procglbnbr, proclocnum, protglbnum) != 0) { /* If cannot allocate new name */ errorPrint ("fileBlockOpenDist: cannot create file name (%d)", i); return (1); } if (filetab[i].nameptr == NULL) { /* If inexisting stream because not root process and centralized stream */ filetab[i].fileptr = NULL; continue; } filetab[i].dataptr = filetab[i].nameptr; /* From now on, we will have to free it anyway */ for (j = 0; j < i; j ++) { if ((filetab[i].modeptr[0] == filetab[j].modeptr[0]) && /* If very same name with same opening mode */ (filetab[j].nameptr != NULL) && (strcmp (filetab[i].nameptr, filetab[j].nameptr) == 0)) { filetab[i].fileptr = filetab[j].fileptr; /* Share pointer to already processed stream */ filetab[i].nameptr = NULL; /* Do not close this stream multiple times */ break; } } if (j == i) { /* If original stream */ int compval; /* Compression type */ FILE * compptr; /* Processed ((un)compressed) stream */ if (filetab[i].nameptr[0] != '-') { /* If not standard stream, open it */ if ((filetab[i].fileptr = fopen (filetab[i].nameptr, filetab[i].modeptr)) == NULL) { /* Open the file */ errorPrint ("fileBlockOpenDist: cannot open file (%d)", i); return (1); } } compval = (filetab[i].modeptr[0] == 'r') ? fileUncompressType (filetab[i].nameptr) : fileCompressType (filetab[i].nameptr); if (compval < 0) { errorPrint ("fileBlockOpenDist: (un)compression type not implemented"); return (1); } compptr = (filetab[i].modeptr[0] == 'r') ? fileUncompress (filetab[i].fileptr, compval) : fileCompress (filetab[i].fileptr, compval); if (compptr == NULL) { errorPrint ("fileBlockOpenDist: cannot create (un)compression subprocess"); return (1); } filetab[i].fileptr = compptr; /* Use processed stream instead of original stream */ } } return (0); } /* This routine opens a block of file ** descriptor structures. ** It returns: ** - 0 : on success. ** - !0 : on error. */ void fileBlockClose ( File * const filetab, const int filenbr) { int i; for (i = 0; i < filenbr; i ++) { /* For all file names */ if ((filetab[i].fileptr != NULL) && /* If stream exists */ (filetab[i].nameptr != NULL) && /* And it has a name */ (filetab[i].nameptr[0] != '-')) /* Which is not default */ fclose (filetab[i].fileptr); /* Close the stream */ if (filetab[i].dataptr != NULL) /* If file name data to free */ memFree (filetab[i].dataptr); } } scotch-6.0.4.dfsg/src/libscotch/library_parser.c0000644002563400244210000001146012262647746025040 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_parser.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the generic **/ /** strategy handling routines of the **/ /** libSCOTCH library. **/ /** **/ /** DATES : # Version 3.2 : from : 19 aug 1998 **/ /** to 19 aug 1998 **/ /** DATES : # Version 3.3 : from : 01 oct 1998 **/ /** to 31 may 1999 **/ /** # Version 3.4 : from : 01 nov 2001 **/ /** to 01 nov 2001 **/ /** # Version 4.0 : from : 23 dec 2001 **/ /** to : 23 dec 2001 **/ /** # Version 6.0 : from : 07 jan 2014 **/ /** to 07 jan 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "parser.h" #include "scotch.h" /************************************/ /* */ /* These routines are the C API for */ /* the strategy handling routines. */ /* */ /************************************/ /* This routine initializes a strategy ** structure. ** It returns: ** - 0 : in all cases. */ int SCOTCH_stratInit ( SCOTCH_Strat * const stratptr) { if (sizeof (SCOTCH_Strat) < sizeof (Strat *)) { errorPrint ("SCOTCH_stratInit: internal error (1)"); return (1); } *((Strat **) stratptr) = NULL; /* Initialize pointer to strategy */ return (0); } /* This routine frees a strategy structure. ** It returns: ** - VOID : in all cases. */ void SCOTCH_stratExit ( SCOTCH_Strat * const stratptr) { if (*((Strat **) stratptr) != NULL) /* If strategy is not null */ stratExit (*((Strat **) stratptr)); /* Free strategy structure */ } /* This routine frees the contents of a ** strategy structure and cleans it for ** future use. ** It returns: ** - VOID : in all cases. */ void SCOTCH_stratFree ( SCOTCH_Strat * const stratptr) { if (*((Strat **) stratptr) != NULL) { /* If strategy is not null */ stratExit (*((Strat **) stratptr)); /* Free strategy structure */ *((Strat **) stratptr) = NULL; /* Initialize pointer to strategy */ } } /* This routine outputs the contents of the ** given strategy to the given stream. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int SCOTCH_stratSave ( const SCOTCH_Strat * const stratptr, FILE * const stream) { return (stratSave (*((Strat **) stratptr), stream)); } scotch-6.0.4.dfsg/src/libscotch/bgraph.h0000644002563400244210000002035312371141733023253 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bgraph.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the job control routines of the **/ /** Dual Recursive Bipartitioning method. **/ /** **/ /** DATES : # Version 0.0 : from : 23 mar 1993 **/ /** to 12 may 1993 **/ /** # Version 1.3 : from : 06 apr 1994 **/ /** to 09 apr 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to 04 nov 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to 30 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 28 sep 1995 **/ /** # Version 3.1 : from : 15 nov 1995 **/ /** to 15 nov 1995 **/ /** # Version 3.2 : from : 24 aug 1996 **/ /** to 03 nov 1997 **/ /** # Version 3.3 : from : 01 dec 1998 **/ /** to 02 dec 1998 **/ /** # Version 4.0 : from : 18 dec 2001 **/ /** to 05 may 2006 **/ /** # Version 5.0 : from : 30 nov 2006 **/ /** to 30 nov 2006 **/ /** # Version 5.1 : from : 08 jan 2008 **/ /** to 18 mar 2011 **/ /** # Version 6.0 : from : 03 mar 2011 **/ /** to 08 aug 2014 **/ /** **/ /************************************************************/ #define BGRAPH_H /* ** The type and structure definitions. */ /*+ Graph option flags. +*/ #define BGRAPHFREEFRON (GRAPHBITSNOTUSED) /* Free frontier array */ #define BGRAPHFREEPART (GRAPHBITSNOTUSED << 1) /* Free part array */ #define BGRAPHFREEVEEX (GRAPHBITSNOTUSED << 2) /* Free external gain array */ #define BGRAPHHASANCHORS (GRAPHBITSNOTUSED << 3) /* If graph has anchor vertices */ /*+ The bipartition graph structure. +*/ typedef struct Bgraph_ { Graph s; /*+ Source graph data +*/ Gnum * veextax; /*+ Array of vertex external gain if moved to part 1 +*/ GraphPart * parttax; /*+ Array of parts for every vertex +*/ Gnum * frontab; /*+ Array of frontier vertex numbers +*/ Gnum fronnbr; /*+ Number of frontier vertices +*/ Gnum compload0min; /*+ Minimum allowed load in part 0 (strategy variable) +*/ Gnum compload0max; /*+ Maximum allowed load in part 0 (strategy variable) +*/ Gnum compload0avg; /*+ Average load of part 0 +*/ Gnum compload0dlt; /*+ Difference from the average +*/ Gnum compload0; /*+ Load in part 0 (strategy variable) +*/ Gnum compsize0; /*+ Number of vertices in part 0 +*/ Gnum commload; /*+ Communication load +*/ Gnum commloadextn0; /*+ Communication load if all moved to part 0 +*/ Gnum commgainextn0; /*+ External gain if all swapped from part 0 +*/ Gnum commgainextn; /*+ External gain if all swapped +*/ double bbalval; /*+ Bipartitioning imbalance ratio (strategy variable) +*/ Anum domndist; /*+ Distance between subdomains +*/ Gnum domnwght[2]; /*+ Weights of the two subdomains +*/ Gnum vfixload[2]; /*+ Vertex load biases of the two subdomains +*/ INT levlnum; /*+ Coarsening level +*/ } Bgraph; /*+ The save graph structure. +*/ typedef struct BgraphStore_ { Gnum fronnbr; /*+ Number of frontier nodes +*/ Gnum compload0dlt; /*+ Difference from the average +*/ Gnum compsize0; /*+ Number of vertices in part 0 +*/ Gnum commload; /*+ Communication load +*/ Gnum commgainextn; /*+ External gain if all swapped +*/ byte * datatab; /*+ Variable-sized data array +*/ } BgraphStore; /* ** The function prototypes. */ #ifndef BGRAPH #define static #endif int bgraphInit (Bgraph * restrict const, const Graph * restrict const, const Arch * restrict const, const ArchDom * restrict const, const Gnum * restrict const); void bgraphInit2 (Bgraph * restrict const, const Anum, const Anum, const Anum, const Gnum, const Gnum); void bgraphExit (Bgraph * restrict const); void bgraphSwal (Bgraph * restrict const); void bgraphZero (Bgraph * restrict const); int bgraphCheck (const Bgraph * restrict const); int bgraphStoreInit (const Bgraph * const, BgraphStore * const); void bgraphStoreExit (BgraphStore * const); void bgraphStoreSave (const Bgraph * const, BgraphStore * const); void bgraphStoreUpdt (Bgraph * const, const BgraphStore * const); #undef static scotch-6.0.4.dfsg/src/libscotch/library_dgraph_order_io_block.c0000644002563400244210000000716012055777476030053 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_order_io_block.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the distri- **/ /** buted ordering distributed tree **/ /** building routine of the libSCOTCH **/ /** library. **/ /** **/ /** DATES : # Version 5.1 : from : 28 may 2008 **/ /** to 28 may 2008 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "dgraph.h" #include "dorder.h" #include "ptscotch.h" /************************************/ /* */ /* These routines are the C API for */ /* the distributed ordering */ /* handling routines. */ /* */ /************************************/ /*+ This routine saves the contents of *** the given ordering to the given stream *** on the form of a block ordering. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_dgraphOrderSaveBlock ( const SCOTCH_Dgraph * const grafptr, /*+ Graph to order +*/ const SCOTCH_Dordering * const ordeptr, /*+ Ordering to save +*/ FILE * const stream) /*+ Output stream +*/ { return (dorderSaveBlock ((Dorder *) ordeptr, (Dgraph *) grafptr, stream)); } scotch-6.0.4.dfsg/src/libscotch/arch_torus.c0000644002563400244210000006545012246406644024171 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010,2011,2013 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : arch_torus.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module handles the torus graph **/ /** target architectures. **/ /** **/ /** DATES : # Version 0.0 : from : 01 dec 1992 **/ /** to : 24 mar 1993 **/ /** # Version 1.2 : from : 04 feb 1994 **/ /** to : 11 feb 1994 **/ /** # Version 1.3 : from : 20 apr 1994 **/ /** to : 20 apr 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to : 23 dec 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to : 29 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 08 sep 1995 **/ /** # Version 3.1 : from : 07 may 1996 **/ /** to 22 jul 1996 **/ /** # Version 3.2 : from : 16 oct 1996 **/ /** to 14 may 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 4.0 : from : 05 nov 2003 **/ /** to 10 mar 2005 **/ /** # Version 5.1 : from : 21 jan 2008 **/ /** to 11 aug 2010 **/ /** # Version 6.0 : from : 14 fev 2011 **/ /** to 30 nov 2013 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define ARCH_TORUS #include "module.h" #include "common.h" #include "arch.h" #include "arch_torus.h" /***********************************************/ /* */ /* These are the 2-dimensional torus routines. */ /* */ /***********************************************/ /* This routine loads the ** bidimensional torus architecture. ** It returns: ** - 0 : if the architecture has been successfully read. ** - !0 : on error. */ int archTorus2ArchLoad ( ArchTorusX * restrict const archptr, FILE * restrict const stream) { #ifdef SCOTCH_DEBUG_ARCH1 if ((ARCHTORUSDIMMAX < 2) || (sizeof (ArchTorusX) > sizeof (ArchDummy)) || (sizeof (ArchTorusXDom) > sizeof (ArchDomDummy))) { errorPrint ("archTorus2ArchLoad: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ if ((intLoad (stream, &archptr->c[0]) != 1) || (intLoad (stream, &archptr->c[1]) != 1) || (archptr->c[0] < 1) || (archptr->c[1] < 1)) { errorPrint ("archTorus2ArchLoad: bad input"); return (1); } archptr->dimmax = 2; return (0); } /* This routine saves the ** bidimensional torus architecture. ** It returns: ** - 0 : if the architecture has been successfully written. ** - !0 : on error. */ int archTorus2ArchSave ( const ArchTorusX * const archptr, FILE * restrict const stream) { #ifdef SCOTCH_DEBUG_ARCH1 if ((ARCHTORUSDIMMAX < 2) || (sizeof (ArchTorusX) > sizeof (ArchDummy)) || (sizeof (ArchTorusXDom) > sizeof (ArchDomDummy))) { errorPrint ("archTorus2ArchSave: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ if (fprintf (stream, ANUMSTRING " " ANUMSTRING " ", (Anum) archptr->c[0], (Anum) archptr->c[1]) == EOF) { errorPrint ("archTorus2ArchSave: bad output"); return (1); } return (0); } /* This function returns the smallest number ** of terminal domain included in the given ** domain. */ ArchDomNum archTorus2DomNum ( const ArchTorusX * const archptr, const ArchTorusXDom * const domptr) { return ((domptr->c[1][0] * archptr->c[0]) + domptr->c[0][0]); /* Return vertex number */ } /* This function returns the terminal domain associated ** with the given terminal number in the architecture. ** It returns: ** - 0 : if label is valid and domain has been updated. ** - 1 : if label is invalid. ** - 2 : on error. */ int archTorus2DomTerm ( const ArchTorusX * const archptr, ArchTorusXDom * const domptr, const ArchDomNum domnum) { if (domnum < (archptr->c[0] * archptr->c[1])) { /* If valid label */ domptr->c[0][0] = /* Set the domain */ domptr->c[0][1] = domnum % archptr->c[0]; domptr->c[1][0] = domptr->c[1][1] = domnum / archptr->c[0]; return (0); } return (1); /* Cannot set domain */ } /* This function returns the number of ** elements in the rectangular domain. */ Anum archTorus2DomSize ( const ArchTorusX * const archptr, const ArchTorusXDom * const domptr) { return ((domptr->c[0][1] - domptr->c[0][0] + 1) * (domptr->c[1][1] - domptr->c[1][0] + 1)); } /* This function returns the average ** distance between two rectangular ** domains (in fact the distance between ** the centers of the domains). */ Anum archTorus2DomDist ( const ArchTorusX * const archptr, const ArchTorusXDom * const dom0ptr, const ArchTorusXDom * const dom1ptr) { Anum dc0, dc1; Anum ds0, ds1; dc0 = abs (dom0ptr->c[0][0] + dom0ptr->c[0][1] - dom1ptr->c[0][0] - dom1ptr->c[0][1]); ds0 = (dc0 > archptr->c[0]) ? (2 * archptr->c[0] - dc0) : dc0; dc1 = abs (dom0ptr->c[1][0] + dom0ptr->c[1][1] - dom1ptr->c[1][0] - dom1ptr->c[1][1]); ds1 = (dc1 > archptr->c[1]) ? (2 * archptr->c[1] - dc1) : dc1; return ((ds0 + ds1) >> 1); } /* This function tries to split a rectangular ** domain into two subdomains. ** It returns: ** - 0 : if bipartitioning succeeded. ** - 1 : if bipartitioning could not be performed. ** - 2 : on error. */ int archTorus2DomBipart ( const ArchTorusX * const archptr, const ArchTorusXDom * const domptr, ArchTorusXDom * restrict const dom0ptr, ArchTorusXDom * restrict const dom1ptr) { Anum dimsiz0; Anum dimsiz1; int dimnum; /* Dimension along which to split */ dimsiz0 = domptr->c[0][1] - domptr->c[0][0]; dimsiz1 = domptr->c[1][1] - domptr->c[1][0]; if ((dimsiz0 | dimsiz1) == 0) /* Return if cannot bipartition more */ return (1); dimnum = 1; if ((dimsiz0 > dimsiz1) || /* Split domain in two along largest dimension */ ((dimsiz0 == dimsiz1) && (archptr->c[0] > archptr->c[1]))) dimnum = 0; dom0ptr->c[0][0] = domptr->c[0][0]; dom1ptr->c[1][1] = domptr->c[1][1]; if (dimnum == 0) { /* Split across the X dimension */ dom0ptr->c[0][1] = (domptr->c[0][0] + domptr->c[0][1]) / 2; dom1ptr->c[0][0] = dom0ptr->c[0][1] + 1; dom1ptr->c[0][1] = domptr->c[0][1]; dom0ptr->c[1][0] = dom1ptr->c[1][0] = domptr->c[1][0]; dom0ptr->c[1][1] = domptr->c[1][1]; } else { /* Split across the Y dimension */ dom1ptr->c[0][0] = domptr->c[0][0]; dom0ptr->c[0][1] = dom1ptr->c[0][1] = domptr->c[0][1]; dom0ptr->c[1][0] = domptr->c[1][0]; dom0ptr->c[1][1] = (domptr->c[1][0] + domptr->c[1][1]) / 2; dom1ptr->c[1][0] = dom0ptr->c[1][1] + 1; } return (0); } /* This function checks if dom1 is ** included in dom0. ** It returns: ** - 0 : if dom1 is not included in dom0. ** - 1 : if dom1 is included in dom0. ** - 2 : on error. */ int archTorus2DomIncl ( const ArchTorusX * const archptr, const ArchTorusXDom * const dom0ptr, const ArchTorusXDom * const dom1ptr) { if ((dom0ptr->c[0][0] <= dom1ptr->c[0][0]) && (dom0ptr->c[0][1] >= dom1ptr->c[0][1]) && (dom0ptr->c[1][0] <= dom1ptr->c[1][0]) && (dom0ptr->c[1][1] >= dom1ptr->c[1][1])) return (1); return (0); } /***********************************************/ /* */ /* These are the 3-dimensional torus routines. */ /* */ /***********************************************/ /* This routine loads the ** tridimensional torus architecture. ** It returns: ** - 0 : if the architecture has been successfully read. ** - !0 : on error. */ int archTorus3ArchLoad ( ArchTorusX * restrict const archptr, FILE * restrict const stream) { #ifdef SCOTCH_DEBUG_ARCH1 if ((ARCHTORUSDIMMAX < 3) || (sizeof (ArchTorusX) > sizeof (ArchDummy)) || (sizeof (ArchTorusXDom) > sizeof (ArchDomDummy))) { errorPrint ("archTorus3ArchLoad: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ if ((intLoad (stream, &archptr->c[0]) != 1) || (intLoad (stream, &archptr->c[1]) != 1) || (intLoad (stream, &archptr->c[2]) != 1) || (archptr->c[0] < 1) || (archptr->c[1] < 1) || (archptr->c[2] < 1)) { errorPrint ("archTorus3ArchLoad: bad input"); return (1); } archptr->dimmax = 3; return (0); } /* This routine saves the ** tridimensional torus architecture. ** It returns: ** - 0 : if the architecture has been successfully written. ** - !0 : on error. */ int archTorus3ArchSave ( const ArchTorusX * const archptr, FILE * restrict const stream) { #ifdef SCOTCH_DEBUG_ARCH1 if ((sizeof (ArchTorusX) > sizeof (ArchDummy)) || (sizeof (ArchTorusXDom) > sizeof (ArchDomDummy))) { errorPrint ("archTorus3ArchSave: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ if (fprintf (stream, ANUMSTRING " " ANUMSTRING " " ANUMSTRING " ", (Anum) archptr->c[0], (Anum) archptr->c[1], (Anum) archptr->c[2]) == EOF) { errorPrint ("archTorus3ArchSave: bad output"); return (1); } return (0); } /* This function returns the smallest number ** of terminal domain included in the given ** domain. */ ArchDomNum archTorus3DomNum ( const ArchTorusX * const archptr, const ArchTorusXDom * const domptr) { return ((((domptr->c[2][0] * archptr->c[1]) + /* Return vertex number */ domptr->c[1][0]) * archptr->c[0]) + domptr->c[0][0]); } /* This function returns the terminal domain associated ** with the given terminal number in the architecture. ** It returns: ** - 0 : if label is valid and domain has been updated. ** - 1 : if label is invalid. ** - 2 : on error. */ int archTorus3DomTerm ( const ArchTorusX * const archptr, ArchTorusXDom * const domptr, const ArchDomNum domnum) { if (domnum < (archptr->c[0] * archptr->c[1] * archptr->c[2])) { /* If valid label */ domptr->c[0][0] = /* Set the domain */ domptr->c[0][1] = domnum % archptr->c[0]; domptr->c[1][0] = domptr->c[1][1] = (domnum / archptr->c[0]) % archptr->c[1]; domptr->c[2][0] = domptr->c[2][1] = domnum / (archptr->c[0] * archptr->c[1]); return (0); } return (1); /* Cannot set domain */ } /* This function returns the number of ** elements in the cubic domain. */ Anum archTorus3DomSize ( const ArchTorusX * const archptr, const ArchTorusXDom * const domptr) { return ((domptr->c[0][1] - domptr->c[0][0] + 1) * (domptr->c[1][1] - domptr->c[1][0] + 1) * (domptr->c[2][1] - domptr->c[2][0] + 1)); } /* This function returns the average distance ** between two cubic domains (in fact the ** distance between the centers of the domains). */ Anum archTorus3DomDist ( const ArchTorusX * const archptr, const ArchTorusXDom * const dom0ptr, const ArchTorusXDom * const dom1ptr) { Anum dc0, dc1, dc2; Anum ds0, ds1, ds2; dc0 = abs (dom0ptr->c[0][0] + dom0ptr->c[0][1] - dom1ptr->c[0][0] - dom1ptr->c[0][1]); ds0 = (dc0 > archptr->c[0]) ? (2 * archptr->c[0] - dc0) : dc0; dc1 = abs (dom0ptr->c[1][0] + dom0ptr->c[1][1] - dom1ptr->c[1][0] - dom1ptr->c[1][1]); ds1 = (dc1 > archptr->c[1]) ? (2 * archptr->c[1] - dc1) : dc1; dc2 = abs (dom0ptr->c[2][0] + dom0ptr->c[2][1] - dom1ptr->c[2][0] - dom1ptr->c[2][1]); ds2 = (dc2 > archptr->c[2]) ? (2 * archptr->c[2] - dc2) : dc2; return ((ds0 + ds1 + ds2) >> 1); } /* This function tries to split a cubic ** domain into two subdomains. ** It returns: ** - 0 : if bipartitioning succeeded. ** - 1 : if bipartitioning could not be performed. ** - 2 : on error. */ int archTorus3DomBipart ( const ArchTorusX * const archptr, const ArchTorusXDom * const domptr, ArchTorusXDom * restrict const dom0ptr, ArchTorusXDom * restrict const dom1ptr) { Anum dimsiz[3]; int dimnum; dimsiz[0] = domptr->c[0][1] - domptr->c[0][0]; dimsiz[1] = domptr->c[1][1] - domptr->c[1][0]; dimsiz[2] = domptr->c[2][1] - domptr->c[2][0]; if ((dimsiz[0] | dimsiz[1] | dimsiz[2]) == 0) /* Return if cannot bipartition more */ return (1); dimnum = ((dimsiz[1] > dimsiz[2]) || /* Find largest or priviledged subdomain dimension */ ((dimsiz[1] == dimsiz[2]) && (archptr->c[1] > archptr->c[2]))) ? 1 : 2; if ((dimsiz[0] > dimsiz[dimnum]) || ((dimsiz[0] == dimsiz[dimnum]) && (archptr->c[0] > archptr->c[dimnum]))) dimnum = 0; dom0ptr->c[0][0] = domptr->c[0][0]; dom1ptr->c[2][1] = domptr->c[2][1]; if (dimnum == 0) { /* Split domain in two along largest dimension */ dom0ptr->c[0][1] = (domptr->c[0][0] + domptr->c[0][1]) / 2; dom1ptr->c[0][0] = dom0ptr->c[0][1] + 1; dom1ptr->c[0][1] = domptr->c[0][1]; dom0ptr->c[1][0] = dom1ptr->c[1][0] = domptr->c[1][0]; dom0ptr->c[1][1] = dom1ptr->c[1][1] = domptr->c[1][1]; dom0ptr->c[2][0] = dom1ptr->c[2][0] = domptr->c[2][0]; dom0ptr->c[2][1] = domptr->c[2][1]; } else if (dimnum == 1) { dom1ptr->c[0][0] = domptr->c[0][0]; dom0ptr->c[0][1] = dom1ptr->c[0][1] = domptr->c[0][1]; dom0ptr->c[1][0] = domptr->c[1][0]; dom0ptr->c[1][1] = (domptr->c[1][0] + domptr->c[1][1]) / 2; dom1ptr->c[1][0] = dom0ptr->c[1][1] + 1; dom1ptr->c[1][1] = domptr->c[1][1]; dom0ptr->c[2][0] = dom1ptr->c[2][0] = domptr->c[2][0]; dom0ptr->c[2][1] = domptr->c[2][1]; } else { dom1ptr->c[0][0] = domptr->c[0][0]; dom0ptr->c[0][1] = dom1ptr->c[0][1] = domptr->c[0][1]; dom0ptr->c[1][0] = dom1ptr->c[1][0] = domptr->c[1][0]; dom0ptr->c[1][1] = dom1ptr->c[1][1] = domptr->c[1][1]; dom0ptr->c[2][0] = domptr->c[2][0]; dom0ptr->c[2][1] = (domptr->c[2][0] + domptr->c[2][1]) / 2; dom1ptr->c[2][0] = dom0ptr->c[2][1] + 1; } return (0); } /* This function checks if dom1 is ** included in dom0. ** It returns: ** - 0 : if dom1 is not included in dom0. ** - 1 : if dom1 is included in dom0. ** - 2 : on error. */ int archTorus3DomIncl ( const ArchTorusX * const archptr, const ArchTorusXDom * const dom0ptr, const ArchTorusXDom * const dom1ptr) { if ((dom0ptr->c[0][0] <= dom1ptr->c[0][0]) && (dom0ptr->c[0][1] >= dom1ptr->c[0][1]) && (dom0ptr->c[1][0] <= dom1ptr->c[1][0]) && (dom0ptr->c[1][1] >= dom1ptr->c[1][1]) && (dom0ptr->c[2][0] <= dom1ptr->c[2][0]) && (dom0ptr->c[2][1] >= dom1ptr->c[2][1])) return (1); return (0); } /***********************************************/ /* */ /* These are the x-dimensional torus routines. */ /* */ /***********************************************/ /* This routine loads the ** tridimensional torus architecture. ** It returns: ** - 0 : if the architecture has been successfully read. ** - !0 : on error. */ int archTorusXArchLoad ( ArchTorusX * restrict const archptr, FILE * restrict const stream) { Anum dimnum; #ifdef SCOTCH_DEBUG_ARCH1 if ((sizeof (ArchTorusX) > sizeof (ArchDummy)) || (sizeof (ArchTorusXDom) > sizeof (ArchDomDummy))) { errorPrint ("archTorusXArchLoad: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ if ((intLoad (stream, &archptr->dimmax) != 1) || (archptr->dimmax > ARCHTORUSDIMMAX)) { errorPrint ("archTorusXArchLoad: bad input (1)"); return (1); } for (dimnum = 0; dimnum < archptr->dimmax; dimnum ++) { if ((intLoad (stream, &archptr->c[dimnum]) != 1) || (archptr->c[dimnum] < 1)) { errorPrint ("archTorusXArchLoad: bad input (2)"); return (1); } } return (0); } /* This routine saves the ** tridimensional torus architecture. ** It returns: ** - 0 : if the architecture has been successfully written. ** - !0 : on error. */ int archTorusXArchSave ( const ArchTorusX * const archptr, FILE * restrict const stream) { Anum dimnum; #ifdef SCOTCH_DEBUG_ARCH1 if ((sizeof (ArchTorusX) > sizeof (ArchDummy)) || (sizeof (ArchTorusXDom) > sizeof (ArchDomDummy))) { errorPrint ("archTorusXArchSave: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ if (fprintf (stream, ANUMSTRING " ", (Anum) archptr->dimmax) == EOF) { errorPrint ("archTorusXArchSave: bad output (1)"); return (1); } for (dimnum = 0; dimnum < archptr->dimmax; dimnum ++) { if (fprintf (stream, ANUMSTRING " ", (Anum) archptr->c[dimnum]) == EOF) { errorPrint ("archTorusXArchSave: bad output (2)"); return (1); } } return (0); } /* This function returns the smallest number ** of terminal domain included in the given ** domain. */ ArchDomNum archTorusXDomNum ( const ArchTorusX * const archptr, const ArchTorusXDom * const domptr) { Anum dimnum; Anum domnum; for (dimnum = archptr->dimmax - 2, domnum = domptr->c[archptr->dimmax - 1][0]; dimnum >= 0; dimnum --) domnum = (domnum * archptr->c[dimnum]) + domptr->c[dimnum][0]; return (domnum); /* Return vertex number */ } /* This function returns the terminal domain associated ** with the given terminal number in the architecture. ** It returns: ** - 0 : if label is valid and domain has been updated. ** - 1 : if label is invalid. ** - 2 : on error. */ int archTorusXDomTerm ( const ArchTorusX * const archptr, ArchTorusXDom * const domptr, const ArchDomNum domnum) { Anum dimnum; Anum domtmp; for (dimnum = 0, domtmp = domnum; dimnum < archptr->dimmax; dimnum ++) { /* Set the domain */ domptr->c[dimnum][0] = domptr->c[dimnum][1] = domtmp % archptr->c[dimnum]; domtmp /= archptr->c[dimnum]; } if (domtmp > 0) /* If residual is not zero, terminal domain number is invalid since too high */ return (1); return (0); } /* This function returns the number of ** elements in the cubic domain. */ Anum archTorusXDomSize ( const ArchTorusX * const archptr, const ArchTorusXDom * const domptr) { Anum dimnum; Anum domsiz; for (dimnum = 0, domsiz = 1; dimnum < archptr->dimmax; dimnum ++) domsiz *= domptr->c[dimnum][1] - domptr->c[dimnum][0] + 1; return (domsiz); } /* This function returns the average distance ** between two cubic domains (in fact the ** distance between the centers of the domains). */ Anum archTorusXDomDist ( const ArchTorusX * const archptr, const ArchTorusXDom * const dom0ptr, const ArchTorusXDom * const dom1ptr) { Anum dimnum; Anum distval; Anum disttmp; for (dimnum = 0, distval = 0; dimnum < archptr->dimmax; dimnum ++) { disttmp = abs (dom0ptr->c[dimnum][0] + dom0ptr->c[dimnum][1] - dom1ptr->c[dimnum][0] - dom1ptr->c[dimnum][1]); distval += (disttmp > archptr->c[dimnum]) ? (2 * archptr->c[dimnum] - disttmp) : disttmp; } return (distval >> 1); } /* This function sets the biggest ** domain available for this ** architecture. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archTorusXDomFrst ( const ArchTorusX * const archptr, ArchTorusXDom * restrict const domptr) { Anum dimnum; for (dimnum = 0; dimnum < archptr->dimmax; dimnum ++) { domptr->c[dimnum][0] = 0; domptr->c[dimnum][1] = archptr->c[dimnum] - 1; } return (0); } /* This routine reads domain information ** from the given stream. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archTorusXDomLoad ( const ArchTorusX * const archptr, ArchTorusXDom * restrict const domptr, FILE * restrict const stream) { Anum dimnum; for (dimnum = 0; dimnum < archptr->dimmax; dimnum ++) { if ((intLoad (stream, &domptr->c[dimnum][0]) != 1) || (intLoad (stream, &domptr->c[dimnum][1]) != 1) || (domptr->c[dimnum][0] > domptr->c[dimnum][1]) || (domptr->c[dimnum][0] < 0)) { errorPrint ("archTorusXDomLoad: bad input"); return (1); } } return (0); } /* This routine saves domain information ** to the given stream. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archTorusXDomSave ( const ArchTorusX * const archptr, const ArchTorusXDom * const domptr, FILE * restrict const stream) { Anum dimnum; for (dimnum = 0; dimnum < archptr->dimmax; dimnum ++) { if (fprintf (stream, ANUMSTRING " " ANUMSTRING " ", (Anum) domptr->c[dimnum][0], (Anum) domptr->c[dimnum][1]) == EOF) { errorPrint ("archTorusXDomSave: bad output"); return (1); } } return (0); } /* This function tries to split a cubic ** domain into two subdomains. ** It returns: ** - 0 : if bipartitioning succeeded. ** - 1 : if bipartitioning could not be performed. ** - 2 : on error. */ int archTorusXDomBipart ( const ArchTorusX * const archptr, const ArchTorusXDom * const domptr, ArchTorusXDom * restrict const dom0ptr, ArchTorusXDom * restrict const dom1ptr) { Anum archdimsizmax; /* Maximum span on largest architecture dimension */ Anum domndimsizmax; /* Maximum span on largest domain dimension */ Anum domndimval; /* Dimension to be split */ Anum domndimflg; /* Flag set if subdomain can be bipartitioned */ Anum domndimtmp; Anum dimnum; for (dimnum = domndimval = archptr->dimmax - 1, archdimsizmax = domndimflg = 0, domndimsizmax = -1; dimnum >= 0; dimnum --) { Anum archdimsiz; Anum domndimsiz; Anum domndim0; Anum domndim1; dom0ptr->c[dimnum][0] = /* Set up subdomain data as copy of original domain data */ dom1ptr->c[dimnum][0] = domndim0 = domptr->c[dimnum][0]; dom0ptr->c[dimnum][1] = dom1ptr->c[dimnum][1] = domndim1 = domptr->c[dimnum][1]; domndimsiz = domndim1 - domndim0; /* Span on current dimension */ domndimflg |= domndimsiz; /* Flag set if at least one is not zero */ if (domndimsiz < domndimsizmax) /* If dimension is too small, skip it */ continue; archdimsiz = archptr->c[dimnum]; if ((domndimsiz == domndimsizmax) && /* If dimension to split is not priviledged, skip it */ (archdimsiz <= archdimsizmax)) continue; archdimsizmax = archdimsiz; /* Record dimension to split */ domndimsizmax = domndimsiz; domndimval = dimnum; } if (domndimflg == 0) /* Return if cannot bipartition more */ return (1); domndimtmp = (domptr->c[domndimval][0] + domptr->c[domndimval][1]) / 2; dom0ptr->c[domndimval][1] = domndimtmp; dom1ptr->c[domndimval][0] = domndimtmp + 1; return (0); } /* This function checks if dom1 is ** included in dom0. ** It returns: ** - 0 : if dom1 is not included in dom0. ** - 1 : if dom1 is included in dom0. ** - 2 : on error. */ int archTorusXDomIncl ( const ArchTorusX * const archptr, const ArchTorusXDom * const dom0ptr, const ArchTorusXDom * const dom1ptr) { Anum dimnum; for (dimnum = 0; dimnum < archptr->dimmax; dimnum ++) { if ((dom1ptr->c[dimnum][0] < dom0ptr->c[dimnum][0]) || (dom1ptr->c[dimnum][1] > dom1ptr->c[dimnum][1])) return (0); } return (1); } /* This function creates the MPI_Datatype for ** xD torus domains. ** It returns: ** - 0 : if type could be created. ** - 1 : on error. */ #ifdef SCOTCH_PTSCOTCH int archTorusXDomMpiType ( const ArchTorusX * const archptr, MPI_Datatype * const typeptr) { MPI_Type_contiguous (2 * archptr->dimmax, ANUM_MPI, typeptr); return (0); } #endif /* SCOTCH_PTSCOTCH */ scotch-6.0.4.dfsg/src/libscotch/arch_mesh.h0000644002563400244210000002025412354532556023751 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : arch_mesh.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the mesh graph target architecture **/ /** functions. **/ /** **/ /** DATES : # Version 0.0 : from : 01 dec 1992 **/ /** to : 24 mar 1993 **/ /** # Version 1.2 : from : 04 feb 1994 **/ /** to : 11 feb 1994 **/ /** # Version 1.3 : from : 20 apr 1994 **/ /** to : 20 apr 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to : 12 nov 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to : 30 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 17 aug 1995 **/ /** # Version 3.1 : from : 22 jul 1996 **/ /** to 23 jul 1996 **/ /** # Version 3.2 : from : 16 oct 1996 **/ /** to 14 may 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 4.0 : from : 09 jan 2004 **/ /** to 09 jan 2004 **/ /** # Version 5.1 : from : 21 jan 2008 **/ /** to 21 jan 2008 **/ /** # Version 6.0 : from : 14 fev 2011 **/ /** to 01 jul 2014 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ #ifndef ARCH_MESH_H_STRUCT #define ARCH_MESH_H_STRUCT /*+ The 2D-mesh definitions. +*/ typedef struct ArchMesh2_ { Anum c[2]; /*+ Mesh dimensions +*/ } ArchMesh2; typedef struct ArchMesh2Dom_ { Anum c[2][2]; /*+ Inclusive X and Y coordinates +*/ } ArchMesh2Dom; /*+ The 3D-mesh definitions. +*/ typedef struct ArchMesh3_ { Anum c[3]; /*+ Mesh dimensions +*/ } ArchMesh3; typedef struct ArchMesh3Dom_ { Anum c[3][2]; /*+ Inclusive X, Y, and Z coordinates +*/ } ArchMesh3Dom; #endif /* ARCH_MESH_H_STRUCT */ /* ** The function prototypes. */ #ifndef ARCH_NOPROTO #ifndef ARCH_MESH_H_PROTO #define ARCH_MESH_H_PROTO #ifndef ARCH_MESH #define static #endif int archMesh2ArchLoad (ArchMesh2 * restrict const, FILE * restrict const); int archMesh2ArchSave (const ArchMesh2 * const, FILE * restrict const); #define archMesh2ArchFree NULL ArchDomNum archMesh2DomNum (const ArchMesh2 * const, const ArchMesh2Dom * const); int archMesh2DomTerm (const ArchMesh2 * const, ArchMesh2Dom * restrict const, const ArchDomNum); Anum archMesh2DomSize (const ArchMesh2 * const, const ArchMesh2Dom * const); #define archMesh2DomWght archMesh2DomSize Anum archMesh2DomDist (const ArchMesh2 * const, const ArchMesh2Dom * const, const ArchMesh2Dom * const); int archMesh2DomFrst (const ArchMesh2 * const, ArchMesh2Dom * const); int archMesh2DomLoad (const ArchMesh2 * const, ArchMesh2Dom * const, FILE * restrict const); int archMesh2DomSave (const ArchMesh2 * const, const ArchMesh2Dom * const, FILE * restrict const); int archMesh2DomBipart (const ArchMesh2 * const, const ArchMesh2Dom * const, ArchMesh2Dom * restrict const, ArchMesh2Dom * restrict const); int archMesh2DomBipartO (const ArchMesh2 * const, const ArchMesh2Dom * const, ArchMesh2Dom * restrict const, ArchMesh2Dom * restrict const); int archMesh2DomBipartU (const ArchMesh2 * const, const ArchMesh2Dom * const, ArchMesh2Dom * restrict const, ArchMesh2Dom * restrict const); int archMesh2DomIncl (const ArchMesh2 * const, const ArchMesh2Dom * const, const ArchMesh2Dom * const); #ifdef SCOTCH_PTSCOTCH int archMesh2DomMpiType (const ArchMesh2 * const, MPI_Datatype * const); #endif /* SCOTCH_PTSCOTCH */ int archMesh3ArchLoad (ArchMesh3 * restrict const, FILE * restrict const); int archMesh3ArchSave (const ArchMesh3 * const, FILE * restrict const); #define archMesh3ArchFree NULL ArchDomNum archMesh3DomNum (const ArchMesh3 * const, const ArchMesh3Dom * const); int archMesh3DomTerm (const ArchMesh3 * const, ArchMesh3Dom * restrict const, const ArchDomNum); Anum archMesh3DomSize (const ArchMesh3 * const, const ArchMesh3Dom * const); #define archMesh3DomWght archMesh3DomSize Anum archMesh3DomDist (const ArchMesh3 * const, const ArchMesh3Dom * const, const ArchMesh3Dom * const); int archMesh3DomFrst (const ArchMesh3 * const, ArchMesh3Dom * const); int archMesh3DomLoad (const ArchMesh3 * const, ArchMesh3Dom * const, FILE * restrict const); int archMesh3DomSave (const ArchMesh3 * const, const ArchMesh3Dom * const, FILE * restrict const); int archMesh3DomBipart (const ArchMesh3 * const, const ArchMesh3Dom * const, ArchMesh3Dom * restrict const, ArchMesh3Dom * restrict const); int archMesh3DomIncl (const ArchMesh3 * const, const ArchMesh3Dom * const, const ArchMesh3Dom * const); #ifdef SCOTCH_PTSCOTCH int archMesh3DomMpiType (const ArchMesh3 * const, MPI_Datatype * const); #endif /* SCOTCH_PTSCOTCH */ #undef static #endif /* ARCH_MESH_H_PROTO */ #endif /* ARCH_NOPROTO */ scotch-6.0.4.dfsg/src/libscotch/bgraph_bipart_st.c0000644002563400244210000004464312052372410025317 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2009-2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bgraph_bipart_st.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module contains the strategy and **/ /** method tables for graph bipartitioning **/ /** methods. **/ /** **/ /** DATES : # Version 3.2 : from : 08 oct 1996 **/ /** to 13 sep 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 12 mar 1999 **/ /** # Version 3.4 : from : 01 jun 2001 **/ /** to 01 jun 2001 **/ /** # Version 4.0 : from : 12 jan 2004 **/ /** to 20 aug 2004 **/ /** # Version 5.0 : from : 27 nov 2006 **/ /** to 29 may 2007 **/ /** # Version 5.1 : from : 26 oct 2009 **/ /** to 15 apr 2011 **/ /** # Version 6.0 : from : 23 fev 2011 **/ /** to 19 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define BGRAPH_BIPART_ST #include "module.h" #include "common.h" #include "fibo.h" #include "gain.h" #include "parser.h" #include "graph.h" #include "arch.h" #include "mapping.h" #include "graph_coarsen.h" #include "bgraph.h" #include "bgraph_bipart_bd.h" #include "bgraph_bipart_df.h" #include "bgraph_bipart_ex.h" #include "bgraph_bipart_fm.h" #include "bgraph_bipart_gg.h" #include "bgraph_bipart_gp.h" #include "bgraph_bipart_ml.h" #include "bgraph_bipart_zr.h" #include "bgraph_bipart_st.h" /* ** The static and global variables. */ static Bgraph bgraphdummy; /*+ Dummy active graph for offset computations +*/ static union { BgraphBipartBdParam param; StratNodeMethodData padding; } bgraphbipartstdefaultbd = { { 3, &stratdummy } }; static union { BgraphBipartDfParam param; StratNodeMethodData padding; } bgraphbipartstdefaultdf = { { 40, BGRAPHBIPARTDFTYPEBAL } }; static union { /* Default parameters for bipartitioning methods */ BgraphBipartFmParam param; /* Parameter zone */ StratNodeMethodData padding; /* To avoid reading out of structure */ } bgraphbipartstdefaultfm = { { 80, ~0, 0.01L, BGRAPHBIPARTFMTYPEBOUNDARY } }; static union { BgraphBipartGgParam param; StratNodeMethodData padding; } bgraphbipartstdefaultgg = { { 5 } }; static union { BgraphBipartGpParam param; StratNodeMethodData padding; } bgraphbipartstdefaultgp = { { 5 } }; static union { BgraphBipartMlParam param; StratNodeMethodData padding; } bgraphbipartstdefaultml = { { 100, 0.8L, &stratdummy, &stratdummy } }; static StratMethodTab bgraphbipartstmethtab[] = { /* Bipartitioning methods array */ { BGRAPHBIPARTSTMETHBD, "b", bgraphBipartBd, &bgraphbipartstdefaultbd }, { BGRAPHBIPARTSTMETHDF, "d", bgraphBipartDf, &bgraphbipartstdefaultdf }, { BGRAPHBIPARTSTMETHEX, "x", bgraphBipartEx, NULL }, { BGRAPHBIPARTSTMETHFM, "f", bgraphBipartFm, &bgraphbipartstdefaultfm }, { BGRAPHBIPARTSTMETHGG, "h", bgraphBipartGg, &bgraphbipartstdefaultgg }, { BGRAPHBIPARTSTMETHGP, "g", bgraphBipartGp, &bgraphbipartstdefaultgp }, { BGRAPHBIPARTSTMETHML, "m", bgraphBipartMl, &bgraphbipartstdefaultml }, { BGRAPHBIPARTSTMETHZR, "z", bgraphBipartZr, NULL }, { -1, NULL, NULL, NULL } }; static StratParamTab bgraphbipartstparatab[] = { /* Method parameter list */ { BGRAPHBIPARTSTMETHBD, STRATPARAMSTRAT, "bnd", (byte *) &bgraphbipartstdefaultbd.param, (byte *) &bgraphbipartstdefaultbd.param.stratbnd, (void *) &bgraphbipartststratab }, { BGRAPHBIPARTSTMETHBD, STRATPARAMSTRAT, "org", (byte *) &bgraphbipartstdefaultbd.param, (byte *) &bgraphbipartstdefaultbd.param.stratorg, (void *) &bgraphbipartststratab }, { BGRAPHBIPARTSTMETHBD, STRATPARAMINT, "width", (byte *) &bgraphbipartstdefaultbd.param, (byte *) &bgraphbipartstdefaultbd.param.distmax, NULL }, { BGRAPHBIPARTSTMETHDF, STRATPARAMINT, "pass", (byte *) &bgraphbipartstdefaultdf.param, (byte *) &bgraphbipartstdefaultdf.param.passnbr, NULL }, { BGRAPHBIPARTSTMETHDF, STRATPARAMCASE, "type", (byte *) &bgraphbipartstdefaultdf.param, (byte *) &bgraphbipartstdefaultdf.param.typeval, (void *) "bk" }, { BGRAPHBIPARTSTMETHFM, STRATPARAMINT, "move", (byte *) &bgraphbipartstdefaultfm.param, (byte *) &bgraphbipartstdefaultfm.param.movenbr, NULL }, { BGRAPHBIPARTSTMETHFM, STRATPARAMINT, "pass", (byte *) &bgraphbipartstdefaultfm.param, (byte *) &bgraphbipartstdefaultfm.param.passnbr, NULL }, { BGRAPHBIPARTSTMETHFM, STRATPARAMDOUBLE, "bal", (byte *) &bgraphbipartstdefaultfm.param, (byte *) &bgraphbipartstdefaultfm.param.deltval, NULL }, { BGRAPHBIPARTSTMETHFM, STRATPARAMCASE, "type", (byte *) &bgraphbipartstdefaultfm.param, (byte *) &bgraphbipartstdefaultfm.param.typeval, (void *) "ab" }, { BGRAPHBIPARTSTMETHGG, STRATPARAMINT, "pass", (byte *) &bgraphbipartstdefaultgg.param, (byte *) &bgraphbipartstdefaultgg.param.passnbr, NULL }, { BGRAPHBIPARTSTMETHML, STRATPARAMSTRAT, "asc", (byte *) &bgraphbipartstdefaultml.param, (byte *) &bgraphbipartstdefaultml.param.stratasc, (void *) &bgraphbipartststratab }, { BGRAPHBIPARTSTMETHML, STRATPARAMSTRAT, "low", (byte *) &bgraphbipartstdefaultml.param, (byte *) &bgraphbipartstdefaultml.param.stratlow, (void *) &bgraphbipartststratab }, { BGRAPHBIPARTSTMETHML, STRATPARAMINT, "vert", (byte *) &bgraphbipartstdefaultml.param, (byte *) &bgraphbipartstdefaultml.param.coarnbr, NULL }, { BGRAPHBIPARTSTMETHML, STRATPARAMDOUBLE, "rat", (byte *) &bgraphbipartstdefaultml.param, (byte *) &bgraphbipartstdefaultml.param.coarrat, NULL }, { BGRAPHBIPARTSTMETHNBR, STRATPARAMINT, NULL, NULL, NULL, NULL } }; static StratParamTab bgraphbipartstcondtab[] = { /* Active graph condition parameter table */ { STRATNODECOND, STRATPARAMDOUBLE, "bal", (byte *) &bgraphdummy, (byte *) &bgraphdummy.bbalval, NULL }, { STRATNODECOND, STRATPARAMINT, "edge", (byte *) &bgraphdummy, (byte *) &bgraphdummy.s.edgenbr, NULL }, { STRATNODECOND, STRATPARAMINT, "levl", (byte *) &bgraphdummy, (byte *) &bgraphdummy.levlnum, NULL }, { STRATNODECOND, STRATPARAMINT, "lmin0", (byte *) &bgraphdummy, (byte *) &bgraphdummy.compload0min, NULL }, { STRATNODECOND, STRATPARAMINT, "lmax0", (byte *) &bgraphdummy, (byte *) &bgraphdummy.compload0max, NULL }, { STRATNODECOND, STRATPARAMINT, "load", (byte *) &bgraphdummy, (byte *) &bgraphdummy.s.velosum, NULL }, { STRATNODECOND, STRATPARAMINT, "load0", (byte *) &bgraphdummy, (byte *) &bgraphdummy.compload0, NULL }, { STRATNODECOND, STRATPARAMINT, "vert", (byte *) &bgraphdummy, (byte *) &bgraphdummy.s.vertnbr, NULL }, { STRATNODENBR, STRATPARAMINT, NULL, NULL, NULL, NULL } }; StratTab bgraphbipartststratab = { /* Strategy tables for graph bipartitioning methods */ bgraphbipartstmethtab, bgraphbipartstparatab, bgraphbipartstcondtab }; /***********************************************/ /* */ /* This is the generic bipartitioning routine. */ /* */ /***********************************************/ /* This routine performs the bipartitioning of ** the given active graph according to the ** given strategy. ** It returns: ** - 0 : if bipartitioning could be computed. ** - 1 : on error. */ int bgraphBipartSt ( Bgraph * restrict const grafptr, /*+ Active graph to bipartition +*/ const Strat * restrict const strat) /*+ Bipartitioning strategy +*/ { StratTest val; /* Result of condition evaluation */ BgraphStore savetab[2]; /* Results of the two strategies */ int o; int o2; #ifdef SCOTCH_DEBUG_BGRAPH2 if (sizeof (Gnum) != sizeof (INT)) { errorPrint ("bgraphBipartSt: invalid type specification for parser variables"); return (1); } if ((sizeof (BgraphBipartFmParam) > sizeof (StratNodeMethodData)) || (sizeof (BgraphBipartGgParam) > sizeof (StratNodeMethodData)) || (sizeof (BgraphBipartMlParam) > sizeof (StratNodeMethodData))) { errorPrint ("bgraphBipartSt: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH2 */ #ifdef SCOTCH_DEBUG_BGRAPH1 if (strat->tabl != &bgraphbipartststratab) { errorPrint ("bgraphBipartSt: invalid parameter (1)"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH1 */ o = 0; switch (strat->type) { case STRATNODECONCAT : o = bgraphBipartSt (grafptr, strat->data.concat.strat[0]); /* Apply the first strategy */ if (o == 0) /* If it worked all right */ o |= bgraphBipartSt (grafptr, strat->data.concat.strat[1]); /* Then apply second strategy */ break; case STRATNODECOND : o = stratTestEval (strat->data.cond.test, &val, (void *) grafptr); /* Evaluate expression */ if (o == 0) { /* If evaluation was correct */ #ifdef SCOTCH_DEBUG_VGRAPH2 if ((val.typetest != STRATTESTVAL) || (val.typenode != STRATPARAMLOG)) { errorPrint ("bgraphBipartSt: invalid test result"); o = 1; break; } #endif /* SCOTCH_DEBUG_VGRAPH2 */ if (val.data.val.vallog == 1) /* If expression is true */ o = bgraphBipartSt (grafptr, strat->data.cond.strat[0]); /* Apply first strategy */ else { /* Else if expression is false */ if (strat->data.cond.strat[1] != NULL) /* And if there is an else statement */ o = bgraphBipartSt (grafptr, strat->data.cond.strat[1]); /* Apply second strategy */ } } break; case STRATNODEEMPTY : break; case STRATNODESELECT : if (((bgraphStoreInit (grafptr, &savetab[0])) != 0) || /* Allocate save areas */ ((bgraphStoreInit (grafptr, &savetab[1])) != 0)) { errorPrint ("bgraphBipartSt: out of memory"); bgraphStoreExit (&savetab[0]); return (1); } bgraphStoreSave (grafptr, &savetab[1]); /* Save initial bipartition */ o = bgraphBipartSt (grafptr, strat->data.select.strat[0]); /* Apply first strategy */ bgraphStoreSave (grafptr, &savetab[0]); /* Save its result */ bgraphStoreUpdt (grafptr, &savetab[1]); /* Restore initial bipartition */ o2 = bgraphBipartSt (grafptr, strat->data.select.strat[1]); /* Apply second strategy */ if ((o == 0) || (o2 == 0)) { /* If at least one method did bipartition */ Gnum compload0; int b0; int b1; compload0 = grafptr->compload0avg + savetab[0].compload0dlt; b0 = ((compload0 < grafptr->compload0min) || (compload0 > grafptr->compload0max)) ? 1 : o; compload0 = grafptr->compload0avg + savetab[1].compload0dlt; b1 = ((compload0 < grafptr->compload0min) || (compload0 > grafptr->compload0max)) ? 1 : o2; do { /* Do we want to restore partition 0 ? */ if (b0 > b1) break; if (b0 == b1) { /* If both are valid or invalid */ if (b0 == 0) { /* If both are valid */ if ( (savetab[0].commload > grafptr->commload) || /* Compare on cut */ ((savetab[0].commload == grafptr->commload) && (abs (savetab[0].compload0dlt) > abs (grafptr->compload0dlt)))) break; } else { /* If both are invalid */ if ( (abs (savetab[0].compload0dlt) > abs (grafptr->compload0dlt)) || /* Compare on imbalance */ ((abs (savetab[0].compload0dlt) == abs (grafptr->compload0dlt)) && (savetab[0].commload > grafptr->commload))) break; } } bgraphStoreUpdt (grafptr, &savetab[0]); /* Restore its result */ } while (0); } if (o2 < o) /* o = min(o,o2): if one biparts, then bipart */ o = o2; /* Else if one stops, then stop, else error */ bgraphStoreExit (&savetab[0]); /* Free both save areas */ bgraphStoreExit (&savetab[1]); break; #ifdef SCOTCH_DEBUG_BGRAPH2 case STRATNODEMETHOD : #else /* SCOTCH_DEBUG_BGRAPH2 */ default : #endif /* SCOTCH_DEBUG_BGRAPH2 */ return (strat->tabl->methtab[strat->data.method.meth].func (grafptr, (void *) &strat->data.method.data)); #ifdef SCOTCH_DEBUG_BGRAPH2 default : errorPrint ("bgraphBipartSt: invalid parameter (2)"); return (1); #endif /* SCOTCH_DEBUG_BGRAPH2 */ } return (o); } scotch-6.0.4.dfsg/src/libscotch/hdgraph_order_sq.c0000644002563400244210000002024211631447170025315 0ustar trophimeutilisateurs du domaine/* Copyright 2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hdgraph_order_sq.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module orders distributed graphs **/ /** by centralizing them on a single **/ /** process and running a sequential **/ /** ordering strategy. **/ /** **/ /** DATES : # Version 5.1 : from : 11 nov 2008 **/ /** to 11 nov 2008 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HDGRAPH_ORDER_SQ #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "order.h" #include "hgraph.h" #include "hgraph_order_st.h" #include "dgraph.h" #include "dorder.h" #include "hdgraph.h" #include "hdgraph_order_sq.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the ordering. ** It returns: ** - 0 : if the ordering could be computed. ** - !0 : on error. */ int hdgraphOrderSq ( Hdgraph * restrict const grafptr, DorderCblk * restrict const cblkptr, const HdgraphOrderSqParam * restrict const paraptr) { Hgraph cgrfdat; /* Centralized halo graph data */ Hgraph * cgrfptr; /* Pointer to centralized halo graph */ int o; cgrfptr = (grafptr->s.proclocnum == 0) ? &cgrfdat : NULL; /* Set root process */ if (hdgraphGather (grafptr, cgrfptr) != 0) { /* Gather centralized subgraph */ errorPrint ("hdgraphOrderSq: cannot create centralized graph"); return (1); } o = 0; if (cgrfptr != NULL) { o = hdgraphOrderSq2 (&cgrfdat, cblkptr, paraptr->ordstratseq); hgraphFree (&cgrfdat); } return (o); } int hdgraphOrderSq2 ( Hgraph * restrict const grafptr, DorderCblk * restrict const cblkptr, const Strat * restrict const stratptr) { Order corddat; /* Centralized ordering structure */ Gnum * restrict vnumtax; Gnum * restrict peritab; int o; if (orderInit (&corddat, grafptr->s.baseval, cblkptr->vnodglbnbr, NULL) != 0) { errorPrint ("hdgraphOrderSq2: cannot initialize centralized ordering"); return (1); } vnumtax = grafptr->s.vnumtax; /* Save number array of subgraph to order */ grafptr->s.vnumtax = NULL; /* Assume graph does not have one (fake original graph) */ if (hgraphOrderSt (grafptr, &corddat, 0, &corddat.cblktre, stratptr) != 0) { /* Compute sequential ordering */ orderExit (&corddat); return (1); } #ifdef SCOTCH_DEBUG_HDGRAPH2 if (orderCheck (&corddat) != 0) { errorPrint ("hdgraphOrderSq2: invalid centralized ordering"); orderExit (&corddat); return (1); } #endif /* SCOTCH_DEBUG_HDGRAPH2 */ peritab = corddat.peritab; /* Get permutation array */ if (vnumtax != NULL) { Gnum perinum; grafptr->s.vnumtax = vnumtax; /* Restore vertex number array */ for (perinum = 0; perinum < grafptr->vnohnbr; perinum ++) /* Adjust inverse permutation */ peritab[perinum] = vnumtax[peritab[perinum]]; } cblkptr->typeval = DORDERCBLKLEAF; /* Fill node as leaf */ cblkptr->data.leaf.ordelocval = cblkptr->ordeglbval; cblkptr->data.leaf.vnodlocnbr = cblkptr->vnodglbnbr; cblkptr->data.leaf.periloctab = peritab; cblkptr->data.leaf.nodelocnbr = corddat.treenbr - 1; /* Get number of tree nodes, save for root */ o = 0; if (corddat.treenbr > 1) { cblkptr->data.leaf.cblklocnum = dorderNewSequIndex (cblkptr, corddat.treenbr - 1); /* Reserve local indices for local nodes */ if ((cblkptr->data.leaf.nodeloctab = hdgraphOrderSqTree (&corddat)) == NULL) { errorPrint ("hdgraphOrderSq2: cannot import centralized separation tree"); o = 1; } if (corddat.cblktre.typeval == ORDERCBLKNEDI) /* If root of centralized tree is a nested dissection node */ cblkptr->typeval |= DORDERCBLKNEDI; /* Distributed leaf is also a nested dissection node */ } else cblkptr->data.leaf.nodeloctab = NULL; corddat.flagval = ORDERNONE; /* Do not free permutation array */ orderExit (&corddat); /* Free permutation tree */ return (o); } /* This routine builds the distributed part of ** a distributed halo graph. This is a distinct ** routine to allow for multi-threading. */ static DorderNode * hdgraphOrderSqTree ( const Order * const cordptr) { DorderNode * nodetab; Gnum nodenum; Gnum cblknum; if ((nodetab = memAlloc ((cordptr->treenbr - 1) * sizeof (DorderNode))) == NULL) { /* "- 1" as root of tree will not be copied */ errorPrint ("hdgraphOrderSqTree: out of memory"); return (NULL); } nodenum = 0; /* Start labeling nodes from 0 */ for (cblknum = 0; cblknum < cordptr->cblktre.cblknbr; cblknum ++) hdgraphOrderSqTree2 (nodetab, &nodenum, &cordptr->cblktre.cblktab[cblknum], -1, cblknum); /* Root of tree is labeled "-1" */ #ifdef SCOTCH_DEBUG_HDGRAPH2 if (nodenum != (cordptr->treenbr - 1)) { errorPrint ("hdgraphOrderSqTree: internal error"); return (NULL); } #endif /* SCOTCH_DEBUG_HDGRAPH2 */ return (nodetab); } static void hdgraphOrderSqTree2 ( DorderNode * const nodetab, Gnum * const nodeptr, const OrderCblk * const cblkptr, const Gnum fathnum, const Gnum fcbknum) { Gnum nodenum; DorderNode * nodetmp; Gnum cblknum; nodenum = (*nodeptr) ++; nodetmp = &nodetab[nodenum]; nodetmp->fathnum = fathnum; nodetmp->typeval = (Gnum) cblkptr->typeval; nodetmp->vnodnbr = cblkptr->vnodnbr; nodetmp->cblknum = fcbknum; for (cblknum = 0; cblknum < cblkptr->cblknbr; cblknum ++) hdgraphOrderSqTree2 (nodetab, nodeptr, &cblkptr->cblktab[cblknum], nodenum, cblknum); } scotch-6.0.4.dfsg/src/libscotch/arch_cmpltw.c0000644002563400244210000004064112410344531024303 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2010,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : arch_cmpltw.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module handles the weighted **/ /** complete graph target architecture. **/ /** **/ /** DATES : # Version 5.1 : from : 11 dec 2007 **/ /** to 11 aug 2010 **/ /** # Version 6.0 : from : 14 fev 2011 **/ /** to 23 sep 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define ARCH_CMPLTW #include "module.h" #include "common.h" #include "graph.h" #include "arch.h" #include "arch_cmpltw.h" /******************************************/ /* */ /* These are the complete graph routines. */ /* */ /******************************************/ /* This routine builds a complete weighted ** graph architecture from the given load array. ** It returns: ** - 0 : if the architecture has been successfully built. ** - !0 : on error. */ static void archCmpltwArchBuild3 ( ArchCmpltwLoad * restrict const velotab, ArchCmpltwLoad * restrict const vesotab, Anum vertnbr, Anum velosum) { Anum velosum0; Anum velosum1; Anum vertnbr0; Anum vertnbr1; Anum vertnum0; Anum vertnum1; Anum vertnum; vertnum0 = vertnum1 = vertnbr - 1; velosum0 = velotab[vertnum0 --].veloval; velosum1 = 0; for (vertnum = vertnum0; vertnum >= 0; vertnum --) { if (velosum1 < velosum0) { velosum1 += velotab[vertnum].veloval; vesotab[vertnum1 --] = velotab[vertnum]; } else { velosum0 += velotab[vertnum].veloval; velotab[vertnum0 --] = velotab[vertnum]; } } if (velosum0 >= velosum1) { vertnbr0 = vertnbr - vertnum0 - 1; vertnbr1 = vertnbr - vertnbr0; memMov (velotab, velotab + vertnbr1, vertnbr0 * sizeof (ArchCmpltwLoad)); memCpy (velotab + vertnbr0, vesotab + vertnbr0, vertnbr1 * sizeof (ArchCmpltwLoad)); } else { Anum velotmp; vertnbr0 = vertnbr - vertnum1 - 1; vertnbr1 = vertnbr - vertnbr0; memCpy (velotab, vesotab + vertnbr1, vertnbr0 * sizeof (ArchCmpltwLoad)); velotmp = velosum0; velosum0 = velosum1; velosum1 = velotmp; } if (vertnbr0 > 2) archCmpltwArchBuild3 (velotab, vesotab, vertnbr0, velosum0); if (vertnbr1 > 2) archCmpltwArchBuild3 (velotab + vertnbr0, vesotab + vertnbr0, vertnbr1, velosum1); } static int archCmpltwArchBuild2 ( ArchCmpltw * restrict const archptr) { ArchCmpltwLoad * restrict vesotab; /* Auxiliary sort array for weighted vertices */ if (archptr->vertnbr < 3) /* No need to sort if less than 3 vertices */ return (0); if ((vesotab = (ArchCmpltwLoad *) memAlloc (archptr->vertnbr * sizeof (ArchCmpltwLoad))) == NULL) { errorPrint ("archCmpltwArchBuild2: out of memory"); memFree (archptr->velotab); archptr->velotab = NULL; return (1); } intSort2asc2 (archptr->velotab, archptr->vertnbr); /* Sort load array by both keys to be portable across sorting implementations */ archCmpltwArchBuild3 (archptr->velotab, vesotab, archptr->vertnbr, archptr->velosum); memFree (vesotab); return (0); } int archCmpltwArchBuild ( ArchCmpltw * restrict const archptr, const Anum vertnbr, const Anum * restrict const velotab) { Anum vertnum; Anum velosum; #ifdef SCOTCH_DEBUG_ARCH1 if ((sizeof (ArchCmpltw) > sizeof (ArchDummy)) || (sizeof (ArchCmpltwDom) > sizeof (ArchDomDummy))) { errorPrint ("archCmpltwArchBuild: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ if (vertnbr <= 0) { errorPrint ("archCmpltwArchBuild: invalid parameters"); return (1); } archptr->vertnbr = (Anum) vertnbr; if ((archptr->velotab = (ArchCmpltwLoad *) memAlloc (archptr->vertnbr * sizeof (ArchCmpltwLoad))) == NULL) { errorPrint ("archCmpltwArchBuild: out of memory"); return (1); } for (vertnum = 0, velosum = 0; vertnum < archptr->vertnbr; vertnum ++) { /* Fill vertex load array */ Anum veloval; veloval = velotab[vertnum]; velosum += veloval; archptr->velotab[vertnum].veloval = veloval; archptr->velotab[vertnum].vertnum = vertnum; } archptr->velosum = (Anum) velosum; return (archCmpltwArchBuild2 (archptr)); } /* This routine loads the weighted complete ** graph architecture. ** It returns: ** - 0 : if the architecture has been successfully read. ** - !0 : on error. */ int archCmpltwArchLoad ( ArchCmpltw * restrict const archptr, FILE * restrict const stream) { long vertnbr; Anum velosum; Anum vertnum; #ifdef SCOTCH_DEBUG_ARCH1 if ((sizeof (ArchCmpltw) > sizeof (ArchDummy)) || (sizeof (ArchCmpltwDom) > sizeof (ArchDomDummy))) { errorPrint ("archCmpltwArchLoad: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ if ((fscanf (stream, "%ld", &vertnbr) != 1) || (vertnbr < 1)) { errorPrint ("archCmpltwArchLoad: bad input (1)"); return (1); } archptr->vertnbr = (Anum) vertnbr; if ((archptr->velotab = (ArchCmpltwLoad *) memAlloc (archptr->vertnbr * sizeof (ArchCmpltwLoad))) == NULL) { errorPrint ("archCmpltwArchLoad: out of memory"); return (1); } for (vertnum = 0, velosum = 0; vertnum < archptr->vertnbr; vertnum ++) { long veloval; Anum velotmp; if ((fscanf (stream, "%ld", &veloval) != 1) || (veloval < 1)) { errorPrint ("archCmpltwArchLoad: bad input (2)"); return (1); } velotmp = (Anum) veloval; velosum += velotmp; archptr->velotab[vertnum].veloval = velotmp; archptr->velotab[vertnum].vertnum = vertnum; } archptr->velosum = (Anum) velosum; return (archCmpltwArchBuild2 (archptr)); } /* This routine saves the weighted ** complete graph architecture. ** It returns: ** - 0 : if the architecture has been successfully written. ** - !0 : on error. */ int archCmpltwArchSave ( const ArchCmpltw * const archptr, FILE * restrict const stream) { Anum vertnum; #ifdef SCOTCH_DEBUG_ARCH1 if ((sizeof (ArchCmpltw) > sizeof (ArchDummy)) || (sizeof (ArchCmpltwDom) > sizeof (ArchDomDummy))) { errorPrint ("archCmpltwArchSave: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ if (fprintf (stream, ANUMSTRING, (Anum) archptr->vertnbr) == EOF) { errorPrint ("archCmpltwArchSave: bad output (1)"); return (1); } for (vertnum = 0; vertnum < archptr->vertnbr; vertnum ++) { /* For all weights to output */ Anum verttmp; for (verttmp = 0; verttmp < archptr->vertnbr; verttmp ++) { /* For all vertex indices: O(n^2) loop but we don't really care */ if (archptr->velotab[verttmp].vertnum == vertnum) { if (fprintf (stream, " " ANUMSTRING, (Anum) archptr->velotab[verttmp].veloval) == EOF) { errorPrint ("archCmpltwArchSave: bad output (2)"); return (1); } break; } if (verttmp == archptr->vertnbr) { errorPrint ("archCmpltwArchSave: internal error"); return (1); } } } return (0); } /* This routine frees the weighted complete ** graph architecture data structures. ** It returns: ** - 0 : if the architecture has been successfully freed. ** - !0 : on error. */ int archCmpltwArchFree ( ArchCmpltw * const archptr) { #ifdef SCOTCH_DEBUG_ARCH1 if ((sizeof (ArchCmpltw) > sizeof (ArchDummy)) || (sizeof (ArchCmpltwDom) > sizeof (ArchDomDummy))) { errorPrint ("archCmpltwArchFree: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_ARCH1 */ if (archptr->velotab != NULL) { memFree (archptr->velotab); archptr->velotab = NULL; } return (0); } /* This function returns the smallest number ** of terminal domain included in the given ** domain. */ ArchDomNum archCmpltwDomNum ( const ArchCmpltw * const archptr, const ArchCmpltwDom * const domptr) { return (archptr->velotab[domptr->vertmin].vertnum); /* Return vertex number */ } /* This function returns the terminal domain associated ** with the given terminal number in the architecture. ** ** It returns: ** - 0 : if label is valid and domain has been updated. ** - 1 : if label is invalid. ** - 2 : on error. */ int archCmpltwDomTerm ( const ArchCmpltw * const archptr, ArchCmpltwDom * const domptr, const ArchDomNum domnum) { if (domnum < archptr->vertnbr) { /* If valid label */ Anum vertnum; for (vertnum = 0; vertnum < archptr->vertnbr; vertnum ++) { /* Search for terminal domain index matching vertex label */ if (archptr->velotab[vertnum].vertnum == domnum) break; } #ifdef SCOTCH_DEBUG_ARCH2 if (vertnum == archptr->vertnbr) { /* If index not found */ errorPrint ("archCmpltwDomTerm: internal error"); return (2); } #endif /* SCOTCH_DEBUG_ARCH2 */ domptr->vertmin = vertnum; /* Set the domain */ domptr->vertnbr = 1; domptr->veloval = archptr->velotab[vertnum].veloval; return (0); } return (1); /* Cannot set domain */ } /* This function returns the number of ** elements in the complete domain. */ Anum archCmpltwDomSize ( const ArchCmpltw * const archptr, const ArchCmpltwDom * const domptr) { return (domptr->vertnbr); } /* This function returns the weight of ** the complete domain. */ Anum archCmpltwDomWght ( const ArchCmpltw * const archptr, const ArchCmpltwDom * const domptr) { return (domptr->veloval); } /* This function returns the average ** distance between two complete ** subdomains. */ Anum archCmpltwDomDist ( const ArchCmpltw * const archptr, const ArchCmpltwDom * const dom0ptr, const ArchCmpltwDom * const dom1ptr) { return (((dom0ptr->vertmin == dom1ptr->vertmin) && /* All domains are at distance 1 */ (dom0ptr->vertnbr == dom1ptr->vertnbr)) ? 0 : 1); /* If they are different */ } /* This function sets the biggest ** domain available for this ** architecture. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archCmpltwDomFrst ( const ArchCmpltw * const archptr, ArchCmpltwDom * restrict const domptr) { domptr->vertmin = 0; domptr->vertnbr = archptr->vertnbr; domptr->veloval = archptr->velosum; return (0); } /* This routine reads domain information ** from the given stream. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archCmpltwDomLoad ( const ArchCmpltw * const archptr, ArchCmpltwDom * restrict const domptr, FILE * const stream) { long vertmin; long vertnbr; Anum vertnum; Anum vertnnd; Anum velosum; if ((fscanf (stream, "%ld%ld", &vertmin, &vertnbr) != 2) || (vertnbr < 1) || (vertnbr + vertmin > (long) archptr->vertnbr)) { errorPrint ("archCmpltwDomLoad: bad input"); return (1); } domptr->vertmin = (Anum) vertmin; domptr->vertnbr = (Anum) vertnbr; for (vertnum = domptr->vertmin, vertnnd = vertnum + domptr->vertnbr, velosum = 0; vertnum < vertnnd; vertnum ++) velosum += archptr->velotab[vertnum].veloval; domptr->veloval += velosum; return (0); } /* This routine saves domain information ** to the given stream. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archCmpltwDomSave ( const ArchCmpltw * const archptr, const ArchCmpltwDom * const domptr, FILE * const stream) { if (fprintf (stream, ANUMSTRING " " ANUMSTRING " ", (Anum) domptr->vertmin, (Anum) domptr->vertnbr) == EOF) { errorPrint ("archCmpltwDomSave: bad output"); return (1); } return (0); } /* This function tries to split a complete ** graph domain into two subdomains. ** It returns: ** - 0 : if bipartitioning succeeded. ** - 1 : if bipartitioning could not be performed. ** - 2 : on error. */ int archCmpltwDomBipart ( const ArchCmpltw * const archptr, const ArchCmpltwDom * const domptr, ArchCmpltwDom * restrict const dom0ptr, ArchCmpltwDom * restrict const dom1ptr) { Anum vertnum; Anum velosum1; Anum velosum2; /* Half of overall load sum */ if (domptr->vertnbr <= 1) /* Return if cannot bipartition more */ return (1); vertnum = domptr->vertmin + domptr->vertnbr - 1; velosum1 = (Anum) archptr->velotab[vertnum].veloval; velosum2 = domptr->veloval / 2; for (vertnum --; vertnum > domptr->vertmin; vertnum --) { Anum velotmp; velotmp = velosum1 + (Anum) archptr->velotab[vertnum].veloval; if (velotmp > velosum2) /* Domain 1 is always the least loaded */ break; velosum1 = velotmp; } dom0ptr->vertmin = domptr->vertmin; /* Bipartition vertices */ dom1ptr->vertmin = vertnum + 1; dom0ptr->vertnbr = dom1ptr->vertmin - domptr->vertmin; dom1ptr->vertnbr = domptr->vertnbr - dom0ptr->vertnbr; dom0ptr->veloval = domptr->veloval - velosum1; dom1ptr->veloval = velosum1; return (0); } /* This function checks if dom1 is ** included in dom0. ** It returns: ** - 0 : if dom1 is not included in dom0. ** - 1 : if dom1 is included in dom0. ** - 2 : on error. */ int archCmpltwDomIncl ( const ArchCmpltw * const archptr, const ArchCmpltwDom * const dom0ptr, const ArchCmpltwDom * const dom1ptr) { if ((dom1ptr->vertmin >= dom0ptr->vertmin) && ((dom1ptr->vertmin + dom1ptr->vertnbr) <= (dom0ptr->vertmin + dom0ptr->vertnbr))) return (1); return (0); } /* This function creates the MPI_Datatype for ** weighted complete graph domains. ** It returns: ** - 0 : if type could be created. ** - 1 : on error. */ #ifdef SCOTCH_PTSCOTCH int archCmpltwDomMpiType ( const ArchCmpltw * const archptr, MPI_Datatype * const typeptr) { MPI_Type_contiguous (3, ANUM_MPI, typeptr); return (0); } #endif /* SCOTCH_PTSCOTCH */ scotch-6.0.4.dfsg/src/libscotch/graph.h0000644002563400244210000002577012371372231023120 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : graph.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the source graph functions. **/ /** **/ /** DATES : # Version 0.0 : from : 02 dec 1992 **/ /** to 18 may 1993 **/ /** # Version 1.3 : from : 30 apr 1994 **/ /** to 18 may 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to 18 aug 1994 **/ /** # Version 3.0 : from : 07 jul 1995 **/ /** to 28 sep 1995 **/ /** # Version 3.1 : from : 28 nov 1995 **/ /** to 28 nov 1995 **/ /** # Version 3.2 : from : 07 sep 1996 **/ /** to 15 sep 1998 **/ /** # Version 3.3 : from : 28 sep 1998 **/ /** to 23 mar 1999 **/ /** # Version 3.4 : from : 20 mar 2000 **/ /** to 20 mar 2000 **/ /** # Version 4.0 : from : 24 nov 2001 **/ /** to 03 mar 2006 **/ /** # Version 5.0 : from : 03 mar 2006 **/ /** to 01 jun 2008 **/ /** # Version 5.1 : from : 11 aug 2010 **/ /** to 04 nov 2010 **/ /** # Version 6.0 : from : 03 mar 2011 **/ /** to 09 aug 2014 **/ /** **/ /************************************************************/ #define GRAPH_H /* ** The defines. */ /*+ Graph option flags. +*/ #define GRAPHNONE 0x0000 /* No options set */ #define GRAPHFREEEDGE 0x0001 /* Free edgetab array */ #define GRAPHFREEVERT 0x0002 /* Free verttab array */ #define GRAPHFREEVNUM 0x0004 /* Free vnumtab array */ #define GRAPHFREEOTHR 0x0008 /* Free all other arrays */ #define GRAPHFREETABS 0x000F /* Free all graph arrays */ #define GRAPHVERTGROUP 0x0010 /* All vertex arrays grouped */ #define GRAPHEDGEGROUP 0x0020 /* All edge arrays grouped */ #define GRAPHBITSUSED 0x003F /* Significant bits for plain graph routines */ #define GRAPHBITSNOTUSED 0x0040 /* Value above which bits not used by plain graph routines */ #define GRAPHIONOLOADVERT 1 /* Remove vertex loads on loading */ #define GRAPHIONOLOADEDGE 2 /* Remove edge loads on loading */ /* ** The type and structure definitions. */ #ifndef GNUMMAX /* If dgraph.h not included */ typedef INT Gnum; /* Vertex and edge numbers */ typedef UINT Gunum; /* Unsigned type of same width */ #define GNUMMAX (INTVALMAX) /* Maximum signed Gnum value */ #define GNUMSTRING INTSTRING /* String to printf a Gnum */ #endif /* GNUMMAX */ /*+ The vertex part type, in compressed form. +*/ typedef byte GraphPart; /*+ The vertex list structure. Since a vertex list always refers to a given graph, vertex indices contained in the vertex list array are based with respect to the base value of the associated graph. However, the array itself is not based. +*/ typedef struct VertList_ { Gnum vnumnbr; /*+ Number of vertices in list +*/ Gnum * vnumtab; /*+ Pointer to vertex array +*/ } VertList; /*+ The graph flag type. +*/ typedef int GraphFlag; /*+ Graph property flags +*/ /*+ The graph parallel context structure. +*/ typedef struct GraphProc_ { #ifdef SCOTCH_PTSCOTCH MPI_Comm proccomm; /*+ Communicator used for parallel algorithm +*/ int procglbnbr; /*+ Number of processes in communicator +*/ int proclocnum; /*+ Rank of process in current communicator +*/ #endif /* SCOTCH_PTSCOTCH */ } GraphProc; /*+ The graph structure. +*/ typedef struct Graph_ { GraphFlag flagval; /*+ Graph properties +*/ Gnum baseval; /*+ Base index for edge/vertex arrays +*/ Gnum vertnbr; /*+ Number of vertices in graph +*/ Gnum vertnnd; /*+ Number of vertices in graph, plus baseval +*/ Gnum * verttax; /*+ Vertex array [based] +*/ Gnum * vendtax; /*+ End vertex array [based] +*/ Gnum * velotax; /*+ Vertex load array (if present) +*/ Gnum velosum; /*+ Overall graph vertex load +*/ Gnum * vnumtax; /*+ Vertex number in ancestor graph +*/ Gnum * vlbltax; /*+ Vertex label (from file) +*/ Gnum edgenbr; /*+ Number of edges (arcs) in graph +*/ Gnum * edgetax; /*+ Edge array [based] +*/ Gnum * edlotax; /*+ Edge load array (if present) +*/ Gnum edlosum; /*+ Sum of edge (in fact arc) loads +*/ Gnum degrmax; /*+ Maximum degree +*/ GraphProc * procptr; /*+ Pointer to parallel context (if any) +*/ } Graph; /* ** The function prototypes. */ #ifndef GRAPH #define static #endif int listInit (VertList *); void listExit (VertList *); int listAlloc (VertList *, Gnum); int listFree (VertList *); int listLoad (VertList *, FILE *); int listSave (VertList *, FILE *); void listSort (VertList *); int listCopy (VertList *, VertList *); int graphInit (Graph * const); void graphExit (Graph * const); void graphFree (Graph * const); Gnum graphBase (Graph * const, const Gnum); int graphBand (const Graph * restrict const, const Gnum, Gnum * restrict const, const Gnum, Gnum * restrict * restrict const, Gnum * restrict const, Gnum * restrict const, Gnum * restrict const, const Gnum * restrict const, Gnum * restrict const); int graphCheck (const Graph *); int graphInduceList (const Graph * const, const VertList * const, Graph * const); int graphInducePart (const Graph * const, const GraphPart *, const Gnum, const GraphPart, Graph * const); int graphLoad (Graph * const, FILE * const, const Gnum, const GraphFlag); int graphLoad2 (const Gnum, const Gnum, const Gnum * const, const Gnum * const, Gnum * restrict const, const Gnum, const Gnum * const); int graphSave (const Graph * const, FILE * const); #ifdef GEOM_H int graphGeomLoadChac (Graph * restrict const, Geom * restrict const, FILE * const, FILE * const, const char * const); int graphGeomSaveChac (const Graph * restrict const, const Geom * restrict const, FILE * const, FILE * const, const char * const); int graphGeomLoadHabo (Graph * restrict const, Geom * restrict const, FILE * const, FILE * const, const char * const); int graphGeomLoadMmkt (Graph * restrict const, Geom * restrict const, FILE * const, FILE * const, const char * const); int graphGeomSaveMmkt (const Graph * restrict const, const Geom * restrict const, FILE * const, FILE * const, const char * const); int graphGeomLoadScot (Graph * restrict const, Geom * restrict const, FILE * const, FILE * const, const char * const); int graphGeomSaveScot (const Graph * restrict const, const Geom * restrict const, FILE * const, FILE * const, const char * const); #endif /* GEOM_H */ #undef static scotch-6.0.4.dfsg/src/libscotch/wgraph_part_st.h0000644002563400244210000000744211631447170025042 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : wgraph_part_st.h **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Charles-Edmond BICHOT (v5.1b) **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for vertex overlapped graph par- **/ /** titioning strategy and method tables. **/ /** **/ /** DATES : # Version 5.1 : from : 01 dec 2007 **/ /** to : 01 jul 2008 **/ /** # Version 6.0 : from : 05 nov 2009 **/ /** to : 14 mar 2010 **/ /** **/ /************************************************************/ /* ** The type definitions. */ /** Method types. **/ typedef enum WgraphPartStMethodType_ { WGRAPHSEPASTMETHGG = 0, /*+ Greedy Graph Growing +*/ WGRAPHSEPASTMETHGP, /*+ Gibbs-Poole-Stockmeyer +*/ WGRAPHSEPASTMETHFM, /*+ Fiduccia-Mattheyses +*/ WGRAPHSEPASTMETHML, /*+ Multi-level separation +*/ WGRAPHSEPASTMETHRB, /*+ Recursive bisection +*/ WGRAPHSEPASTMETHZR, /*+ Zero method +*/ WGRAPHSEPASTMETHES, /*+ Edge separation strategy +*/ WGRAPHSEPASTMETHVW, /*+ Partition viewer +*/ WGRAPHSEPASTMETHNBR /*+ Number of methods +*/ } WgraphPartStMethodType; /* ** The external declarations. */ extern StratTab wgraphpartststratab; /* ** The function prototypes. */ #ifndef WGRAPH_PART_ST #define static #endif int wgraphPartSt (Wgraph * restrict const, const Strat * restrict const); #undef static scotch-6.0.4.dfsg/src/libscotch/bdgraph_bipart_zr.h0000644002563400244210000000530711631447170025477 0ustar trophimeutilisateurs du domaine/* Copyright 2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bdgraph_bipart_zr.h **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** **/ /** FUNCTION : Part of a static mapper. **/ /** These lines are the data declarations **/ /** for the move-all-to-first-subdomain **/ /** distributed bipartitioning module. **/ /** **/ /** DATES : # Version 5.1 : from : 10 sep 2007 **/ /** to 26 oct 2007 **/ /** **/ /************************************************************/ /* ** The function prototypes. */ #ifndef BDGRAPH_BIPART_ZR #define static #endif int bdgraphBipartZr (Bdgraph * restrict const); #undef static scotch-6.0.4.dfsg/src/libscotch/hdgraph_order_si.h0000644002563400244210000000523011631447170025312 0ustar trophimeutilisateurs du domaine/* Copyright 2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hdgraph_order_si.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the simple halo graph **/ /** ordering routine. **/ /** **/ /** DATES : # Version 5.0 : from : 15 apr 2006 **/ /** to 15 apr 2006 **/ /** **/ /************************************************************/ /* ** The function prototypes. */ #ifndef HDGRAPH_ORDER_SI #define static #endif int hdgraphOrderSi (const Hdgraph * const, DorderCblk * const); #undef static scotch-6.0.4.dfsg/src/libscotch/bdgraph_bipart_ex.c0000644002563400244210000005430512400671442025451 0ustar trophimeutilisateurs du domaine/* Copyright 2010,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bdgraph_bipart_ex.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module bipartitions a distributed **/ /** active graph using a parallel gradient **/ /** method to balance the two parts as **/ /** evenly as possible. **/ /** **/ /** DATES : # Version 5.1 : from : 16 jul 2010 **/ /** to : 15 apr 2011 **/ /** # Version 6.0 : from : 11 sep 2011 **/ /** to : 31 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define BDGRAPH_BIPART_EX #include "module.h" #include "common.h" #include "dgraph.h" #include "arch.h" #include "bdgraph.h" #include "bdgraph_bipart_ex.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the bipartitioning. ** It returns: ** - 0 : if bipartitioning could be computed. ** - 1 : on error. */ int bdgraphBipartEx ( Bdgraph * restrict const grafptr, /*+ Active graph +*/ const BdgraphBipartExParam * restrict const paraptr) /*+ Method parameters +*/ { int sbbtnbr; /* Number of subbits */ Gnum sbbtmsk; /* Subbit mask */ int gainsiz; /* Size of gain array */ int gainidx; Gnum * restrict gainloctab; Gnum * restrict gainglbtab; Gnum * restrict frstloctab; Gnum * restrict nextloctab; Gnum * restrict loadglbtab; const Gnum * restrict edgegsttax; Gnum edlolocval; Gnum fronlocnum; Gnum vertgstnum; Gnum vertlocnnd; Gnum complocsizedlt; /* Count of vertices moved locally */ Gnum complocloaddlt; /* Load of vertices moved locally */ Gnum compglbloaddlt; Gnum compglbloaddltmax; Gnum compglbloaddltmat; Gnum commlocgain; Gnum commlocgainextn; Gnum fronlocnbr; int * restrict movegsttab; int * restrict flagloctab; int cheklocval; int chekglbval; BdgraphBipartExSort * sorttab; size_t sortsiz; Gnum reduloctab[5]; Gnum reduglbtab[5]; Gnum domndist; Gnum partval; const Gnum * restrict const vertloctax = grafptr->s.vertloctax; /* Fast accesses */ const Gnum * restrict const vendloctax = grafptr->s.vendloctax; const Gnum * restrict const veloloctax = grafptr->s.veloloctax; const Gnum * restrict const veexloctax = grafptr->veexloctax; const Gnum * restrict const edloloctax = grafptr->s.edloloctax; Gnum * restrict const fronloctab = grafptr->fronloctab; GraphPart * restrict const partgsttax = grafptr->partgsttax; partval = (grafptr->compglbload0dlt > 0) ? 1 : 0; /* Get number of underloaded part to receive vertices */ compglbloaddltmax = (Gnum) ((double) grafptr->compglbload0avg * paraptr->deltval); compglbloaddltmat = (partval == 0) ? (grafptr->compglbload0avg - grafptr->compglbload0min) : (grafptr->compglbload0max - grafptr->compglbload0avg); if (compglbloaddltmax > compglbloaddltmat) compglbloaddltmax = compglbloaddltmat; if ((abs (grafptr->compglbload0dlt) < compglbloaddltmax) || /* If nothing to do */ (grafptr->fronglbnbr == 0)) /* Or if no current frontier */ return (0); /* This algorithm is useless */ if (dgraphGhst (&grafptr->s) != 0) { /* Compute ghost edge array if not already present */ errorPrint ("bdgraphBipartEx: cannot compute ghost edge array"); return (1); } sbbtnbr = (int) paraptr->sbbtnbr; sbbtmsk = (1 << sbbtnbr) - 1; gainsiz = ((sizeof (Gnum) << 3) - sbbtnbr) << (sbbtnbr + 1); /* Compute gain array size */ sortsiz = MAX ((grafptr->s.procglbnbr * sizeof (BdgraphBipartExSort)), /* TRICK: recycle */ (grafptr->fronlocnbr * sizeof (BdgraphBipartExMove))); cheklocval = 0; if (memAllocGroup ((void **) (void *) &gainglbtab, (size_t) (gainsiz * sizeof (Gnum)), &gainloctab, (size_t) (gainsiz * sizeof (Gnum)), &frstloctab, (size_t) (gainsiz * sizeof (Gnum)), &nextloctab, (size_t) (grafptr->fronlocnbr * sizeof (Gnum)), &loadglbtab, (size_t) (grafptr->s.procglbnbr * sizeof (Gnum)), &movegsttab, (size_t) (flagSize (grafptr->s.vertgstnbr + grafptr->s.baseval) * sizeof (int)), /* TRICK: use based vertices as flag array indices */ &flagloctab, (size_t) (flagSize (grafptr->s.vertlocnbr + grafptr->s.baseval) * sizeof (int)), &sorttab, (size_t) (sortsiz), NULL) == NULL) { errorPrint ("bdgraphBipartEx: out of memory"); cheklocval = 1; } else { memSet (gainloctab, 0, gainsiz * sizeof (Gnum)); /* Initialize gain array */ memSet (frstloctab, ~0, gainsiz * sizeof (Gnum)); /* Initialize linked list */ memSet (nextloctab, ~0, grafptr->fronlocnbr * sizeof (Gnum)); memSet (movegsttab, 0, flagSize (grafptr->s.vertgstnbr + grafptr->s.baseval) * sizeof (int)); /* TRICK: based sizes */ memSet (flagloctab, 0, flagSize (grafptr->s.vertlocnbr + grafptr->s.baseval) * sizeof (int)); } #ifdef SCOTCH_DEBUG_BDGRAPH1 if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, grafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphBipartEx: communication error (1)"); return (1); } #else /* SCOTCH_DEBUG_BDGRAPH1 */ chekglbval = cheklocval; #endif /* SCOTCH_DEBUG_BDGRAPH1 */ if (chekglbval != 0) { if (gainglbtab != NULL) memFree (gainglbtab); /* Free group leader */ return (1); } domndist = (Gnum) grafptr->domndist; edgegsttax = grafptr->s.edgegsttax; edlolocval = 1; /* Assume no edge loads */ for (fronlocnum = 0; fronlocnum < grafptr->fronlocnbr; fronlocnum ++) { Gnum vertlocnum; Gnum velolocval; Gnum edgelocnum; Gnum commgain; int gainidx; int i; Gnum j; vertlocnum = fronloctab[fronlocnum]; if ((Gnum) partgsttax[vertlocnum] == partval) /* If vertex belongs to lighter part, skip it */ continue; for (edgelocnum = vertloctax[vertlocnum], commgain = 0; edgelocnum < vendloctax[vertlocnum]; edgelocnum ++) { Gnum vertlocend; Gnum partend; Gnum partdlt; vertlocend = edgegsttax[edgelocnum]; partend = (Gnum) partgsttax[vertlocend]; if (edloloctax != NULL) edlolocval = edloloctax[edgelocnum]; partdlt = partval ^ partend; /* Inverse of partdlt, because "partval" is the opposite */ commgain += (2 * partdlt - 1) * edlolocval; /* Since partdlt has reversed meaning, reverse gain too */ } commgain *= domndist; /* Adjust internal gains with respect to external gains */ if (veexloctax != NULL) commgain += (2 * partval - 1) * veexloctax[vertlocnum]; /* Partval has reversed meaning */ velolocval = (veloloctax != NULL) ? veloloctax[vertlocnum] : 1; if (commgain >= 0) { /* Compute table entry for gain */ for (i = 0, j = commgain; j > sbbtmsk; i ++, j >>= 1) ; i = (i << sbbtnbr) + (int) j; } else { for (i = 0, j = - (commgain + 1); j > sbbtmsk; i ++, j >>= 1) ; i = - ((i << sbbtnbr) + (int) j + 1); } gainidx = (gainsiz >> 1) + i; #ifdef SCOTCH_DEBUG_BDGRAPH2 if ((gainidx < 0) || (gainidx >= gainsiz)) { errorPrint ("bdgraphBipartEx: internal error"); return (1); } #endif /* SCOTCH_DEBUG_BDGRAPH2 */ gainloctab[gainidx] += velolocval; /* Accumulate gain in proper cell */ nextloctab[fronlocnum] = frstloctab[gainidx]; /* Chain frontier vertex in gain list */ frstloctab[gainidx] = fronlocnum; } if (MPI_Allreduce (gainloctab, gainglbtab, gainsiz, GNUM_MPI, MPI_SUM, grafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphBipartEx: communication error (2)"); return (1); } complocloaddlt = 0; /* No moved vertices yet */ compglbloaddlt = abs (grafptr->compglbload0dlt); /* We want to reduce the absolute value of imbalance */ for (gainidx = 0; gainidx < gainsiz; gainidx ++) { Gnum compglbloadtmp; Gnum gainglbval; Gnum fronlocnum; gainglbval = gainglbtab[gainidx]; if (gainglbval <= 0) continue; compglbloadtmp = compglbloaddlt - gainglbval; if (compglbloadtmp < compglbloaddltmax) break; compglbloaddlt = compglbloadtmp; complocloaddlt += gainloctab[gainidx]; /* We moved that much load locally */ for (fronlocnum = frstloctab[gainidx]; fronlocnum != ~0; /* For all vertices in swapped gain slot */ fronlocnum = nextloctab[fronlocnum]) partgsttax[fronloctab[fronlocnum]] = (GraphPart) (partval | 2); /* Swap vertex part and flag vertex */ } if ((gainidx < gainsiz) && /* If we can make further adjustments */ (compglbloaddlt > compglbloaddltmax)) { /* And if there are some to make */ Gnum loadglbmax; int procglbnbr; int proclocnum; int procnum; int procmax; int sortnbr; int sortnum; if (MPI_Allgather (gainloctab + gainidx, 1, GNUM_MPI, loadglbtab, 1, GNUM_MPI, grafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphBipartEx: communication error (3)"); return (1); } for (procnum = procmax = sortnbr = 0, loadglbmax = 0; /* For all potential contributions */ procnum < grafptr->s.procglbnbr; procnum ++) { if (loadglbtab[procnum] > 0) { if (loadglbtab[procnum] > loadglbmax) { /* Find maximum contribution index as starting point */ loadglbmax = loadglbtab[procnum]; procmax = procnum; } sorttab[sortnbr].veloval = loadglbtab[procnum]; sorttab[sortnbr].procnum = (Gnum) procnum; sortnbr ++; } } procglbnbr = grafptr->s.procglbnbr; for (sortnum = 0; sortnum < sortnbr; sortnum ++) /* Increase priority value from found maximum */ sorttab[sortnum].prioval = (sorttab[sortnum].procnum + procglbnbr - procmax) % procglbnbr; intSort3asc2 (sorttab, sortnbr); /* Sort contributions array unambiguously */ proclocnum = grafptr->s.proclocnum; for (sortnum = sortnbr - 1; sortnum >= 0; sortnum --) { /* Process contributions by descending load */ Gnum compglbloadtmp; compglbloadtmp = compglbloaddlt - sorttab[sortnum].veloval; if (compglbloadtmp < compglbloaddltmax) { /* If entire move would cause imbalance */ Gnum fronlocnum; BdgraphBipartExMove * movetab; Gnum movenbr; Gnum movenum; if (sorttab[sortnum].procnum != proclocnum) /* If this is not our job to handle it */ break; /* Nothing more to do for us */ movetab = (BdgraphBipartExMove *) sorttab; /* TRICK: recycle sorttab array as move array */ for (fronlocnum = frstloctab[gainidx], movenbr = 0; /* For all vertices in swapped gain slot */ fronlocnum != ~0; fronlocnum = nextloctab[fronlocnum], movenbr ++) { Gnum vertlocnum; vertlocnum = fronloctab[fronlocnum]; movetab[movenbr].veloval = (veloloctax != NULL) ? veloloctax[vertlocnum] : 1; movetab[movenbr].vertnum = vertlocnum; } intSort2asc1 (movetab, movenbr); /* Sort local moves by ascending load order */ for (movenum = movenbr - 1; movenum >= 0; movenum --) { /* For all potential moves by descending weight */ Gnum compglbloadtmp; compglbloadtmp = compglbloaddlt - movetab[movenum].veloval; if (compglbloadtmp >= compglbloaddltmax) { /* If move reduces imbalance */ partgsttax[movetab[movenum].vertnum] = (GraphPart) (partval | 2); /* Swap vertex part and flag vertex */ compglbloaddlt = compglbloadtmp; complocloaddlt += movetab[movenum].veloval; /* We moved that much load locally */ if (compglbloaddlt <= compglbloaddltmax) /* If nothing more to do, exit loop */ break; } } break; /* Nothing more to do */ } compglbloaddlt = compglbloadtmp; /* Accept move entirely */ if (sorttab[sortnum].procnum == proclocnum) { /* If we are the process to do it */ Gnum fronlocnum; complocloaddlt += sorttab[sortnum].veloval; /* We moved all of our local load for this gain */ for (fronlocnum = frstloctab[gainidx]; fronlocnum != ~0; /* For all vertices in swapped gain slot */ fronlocnum = nextloctab[fronlocnum]) partgsttax[fronloctab[fronlocnum]] = (GraphPart) (partval | 2); /* Swap vertex part and flag vertex */ break; /* We did our job; don't care about the rest */ } } } grafptr->complocload0 -= (2 * partval - 1) * complocloaddlt; /* Update according to load of moved vertices */ if (dgraphHaloSync (&grafptr->s, partgsttax + grafptr->s.baseval, GRAPHPART_MPI) != 0) { errorPrint ("bdgraphBipartEx: communication error (4)"); return (1); } for (vertgstnum = grafptr->s.vertlocnnd; /* For all received ghosts */ vertgstnum < grafptr->s.vertgstnnd; vertgstnum ++) { if ((partgsttax[vertgstnum] & 2) != 0) { /* If ghost vertex changed part */ partgsttax[vertgstnum] &= 1; /* Put it back in normal state */ flagSet (movegsttab, vertgstnum); /* While recording state change */ } } complocsizedlt = 0; /* No difference to number of vertices yet */ for (fronlocnum = 0, fronlocnbr = grafptr->fronlocnbr; fronlocnum < fronlocnbr; fronlocnum ++) { Gnum vertlocnum; vertlocnum = fronloctab[fronlocnum]; flagSet (flagloctab, vertlocnum); /* Record vertex as already seen */ if ((partgsttax[vertlocnum] & 2) != 0) { /* If frontier vertex changed part */ partgsttax[vertlocnum] &= 1; /* Put it back in normal state */ flagSet (movegsttab, vertlocnum); /* While recording state change */ complocsizedlt ++; /* One more vertex changed of part */ } } grafptr->complocsize0 -= (2 * partval - 1) * complocsizedlt; /* Update according to number of moved vertices */ if (grafptr->s.procsidnbr != 0) { /* Add potential new frontiers to frontier array */ Gnum vertlocnum; Gnum procsidnbr; Gnum procsidnum; int procsidval; const int * restrict const procsidtab = grafptr->s.procsidtab; vertlocnum = grafptr->s.baseval; procsidnbr = grafptr->s.procsidnbr; procsidnum = 0; procsidval = procsidtab[procsidnum ++]; while (1) { /* Scan all vertices which have foreign neighbors */ while (procsidval < 0) { vertlocnum -= (Gnum) procsidval; procsidval = procsidtab[procsidnum ++]; } if (flagVal (flagloctab, vertlocnum) == 0) { /* If vertex not already processed */ flagSet (flagloctab, vertlocnum); fronloctab[fronlocnbr ++] = vertlocnum; /* Record candidate frontier vertex */ } do { if (procsidnum >= procsidnbr) goto loop_exit; } while ((procsidval = procsidtab[procsidnum ++]) >= 0); } loop_exit : ; } edlolocval = 1; /* Assume no edge loads */ commlocgain = commlocgainextn = 0; for (fronlocnum = 0, vertlocnnd = grafptr->s.vertlocnnd; /* For all potential frontier vertices */ fronlocnum < fronlocnbr; ) { Gnum vertlocnum; Gnum edgelocnum; Gnum commcut; Gnum flagval; vertlocnum = fronloctab[fronlocnum]; partval = partgsttax[vertlocnum]; flagval = flagVal (movegsttab, vertlocnum); for (edgelocnum = vertloctax[vertlocnum], commcut = 0; edgelocnum < vendloctax[vertlocnum]; edgelocnum ++) { Gnum vertlocend; Gnum flagend; Gnum partend; Gnum partdlt; vertlocend = edgegsttax[edgelocnum]; partend = (Gnum) partgsttax[vertlocend]; flagend = (Gnum) flagVal (movegsttab, vertlocend); if (edloloctax != NULL) edlolocval = edloloctax[edgelocnum]; partdlt = partval ^ partend; /* Compute difference between new parts */ commcut |= partdlt; /* Accumulate difference */ if ((partdlt != 0) && /* If vertices belong to different parts */ (vertlocend < vertlocnnd) && /* And end vertex is local */ (flagVal (flagloctab, vertlocend) == 0)) { /* And end vertex not already queued */ fronloctab[fronlocnbr ++] = vertlocend; /* Add end vertex to frontier queue */ flagSet (flagloctab, vertlocend); /* Flag it to avoid multiple insertions */ } commlocgain += (((- partdlt) & edlolocval) - /* Compute difference between new and old communication loads */ ((- (partdlt ^ flagval ^ flagend)) & edlolocval)); } if (veexloctax != NULL) commlocgainextn += (partval - (partval ^ flagval)) * veexloctax[vertlocnum]; /* Compute half of difference in external load */ if (commcut == 0) { /* If vertex no longer belongs to frontier */ fronloctab[fronlocnum] = fronloctab[-- fronlocnbr]; /* Replace it by another one */ continue; /* Process replacement vertex */ } fronlocnum ++; /* Process next vertex */ } grafptr->fronlocnbr = fronlocnbr; /* Set new number of frontier vertices */ memFree (gainglbtab); /* Free group leader */ reduloctab[0] = grafptr->fronlocnbr; reduloctab[1] = grafptr->complocload0; reduloctab[2] = grafptr->complocsize0; reduloctab[3] = commlocgain * domndist; /* Send internal gain */ reduloctab[4] = commlocgainextn * 2; /* Send external gain */ if (MPI_Allreduce (reduloctab, reduglbtab, 5, GNUM_MPI, MPI_SUM, grafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphBipartEx: communication error (5)"); return (1); } grafptr->fronglbnbr = reduglbtab[0]; grafptr->compglbload0 = reduglbtab[1]; grafptr->compglbload0dlt = reduglbtab[1] - grafptr->compglbload0avg; grafptr->compglbsize0 = reduglbtab[2]; grafptr->commglbload += reduglbtab[3] / 2 + reduglbtab[4]; /* Add modifications, counted twice for internal gain */ grafptr->commglbgainextn -= reduglbtab[4]; /* Account for modifications in external gain */ grafptr->bbalglbval = (double) ((grafptr->compglbload0dlt < 0) ? (- grafptr->compglbload0dlt) : grafptr->compglbload0dlt) / (double) grafptr->compglbload0avg; #ifdef SCOTCH_DEBUG_BDGRAPH2 if (bdgraphCheck (grafptr) != 0) { errorPrint ("bdgraphBipartEx: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_BDGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/wgraph_check.c0000644002563400244210000001602211631447170024430 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : wgraph_check.c **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Charles-Edmond BICHOT (v5.1b) **/ /** **/ /** FUNCTION : This module check the graph consistency **/ /** for the vertex overlapped graph partit- **/ /** ioning. **/ /** **/ /** DATES : # Version 5.1 : from : 01 dec 2007 **/ /** to : 01 jul 2008 **/ /** # Version 6.0 : from : 05 nov 2009 **/ /** to : 10 mar 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define WGRAPH_CHECK #include "module.h" #include "common.h" #include "graph.h" #include "wgraph.h" /* ** The static variables. */ static const Gnum wgraphcheckloadone = 1; /*************************/ /* */ /* These routines handle */ /* separator graphs. */ /* */ /*************************/ /* This routine checks the consistency ** of the given separator graph. ** It returns: ** - 0 : if graph data are consistent. ** - !0 : on error. */ int wgraphCheck ( const Wgraph * const grafptr) { Gnum vertnbr; /* number of vertex */ Gnum vertnum; /* Number of current vertex */ const Gnum * restrict velobax; /* Data for handling of optional arrays */ Gnum velomsk; Gnum edgenum; Gnum partnum; Gnum fronnum; /* Current number of frontier vertex */ Gnum fronload; Gnum * restrict compload; Gnum * restrict compsize; Gnum * restrict flagtab; vertnbr = grafptr->s.vertnbr; if (memAllocGroup ((void **) (void *) &flagtab, (size_t) (grafptr->partnbr * sizeof (Gnum)), &compload, (size_t) (grafptr->partnbr * sizeof (Gnum)), &compsize, (size_t) (grafptr->partnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("wgraphCheck: out of memory (1)"); return (1); } if (grafptr->s.velotax == NULL) { /* Set accesses to optional arrays */ velobax = &wgraphcheckloadone; /* In case vertices not weighted (least often) */ velomsk = 0; } else { velobax = grafptr->s.velotax; velomsk = ~((Gnum) 0); } fronnum = fronload = 0; memSet (compload, 0, grafptr->partnbr * sizeof (Gnum)); /* Reset loads */ memSet (compsize, 0, grafptr->partnbr * sizeof (Gnum)); memSet (flagtab, ~0, grafptr->partnbr * sizeof (Gnum)); /* Reset flag array */ for (vertnum = grafptr->s.baseval; vertnum < grafptr->s.vertnnd; vertnum ++) { if ((grafptr->parttax[vertnum] >= grafptr->partnbr) || (grafptr->parttax[vertnum] < -1)) { errorPrint ("wgraphCheck: invalid part array"); memFree (flagtab); /* Free group leader */ return (1); } if (grafptr->parttax[vertnum] == -1) { fronnum ++; fronload += velobax[vertnum & velomsk]; for (edgenum = grafptr->s.verttax[vertnum]; edgenum < grafptr->s.vendtax[vertnum]; edgenum ++) { Gnum vertend; vertend = grafptr->s.edgetax[edgenum]; if ((grafptr->parttax[vertend] != -1) && (flagtab[grafptr->parttax[vertend]] != vertnum)) { compload[grafptr->parttax[vertend]] += velobax[vertnum & velomsk]; compsize[grafptr->parttax[vertend]] ++; flagtab[grafptr->parttax[vertend]] = vertnum; } } } else { compload[grafptr->parttax[vertnum]] += velobax[vertnum & velomsk]; compsize[grafptr->parttax[vertnum]] ++; } } for (partnum = 0; partnum < grafptr->partnbr; partnum ++) { if (grafptr->compsize[partnum] != compsize[partnum]) { errorPrint ("wgraphCheck: invalid part size %d %d %d", grafptr->compsize[partnum], compsize[partnum], partnum); memFree (flagtab); return (1); } if (grafptr->compload[partnum] != compload[partnum]) { errorPrintW ("wgraphCheck: invalid part load %d %d %d", grafptr->compload[partnum], compload[partnum], partnum); memFree (flagtab); return (1); } } if (grafptr->fronload != fronload) { errorPrint ("wgraphCheck: invalid frontier load %d %d", grafptr->fronload, fronload); memFree (flagtab); return (1); } if (grafptr->fronnbr != fronnum) { errorPrint ("wgraphCheck: invalid frontier size %d %d", grafptr->fronnbr, fronnum); memFree (flagtab); return (1); } for(fronnum = 0; fronnum < grafptr->fronnbr; fronnum++) { vertnum = grafptr->frontab[fronnum]; if (grafptr->parttax[vertnum] != -1) { errorPrint ("wgraphCheck: invalid frontab"); memFree (flagtab); return (1); } } memFree (flagtab); return (0); } scotch-6.0.4.dfsg/src/libscotch/library_dgraph_coarsen.c0000644002563400244210000001300012412035044026466 0ustar trophimeutilisateurs du domaine/* Copyright 2011,2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_coarsen.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the **/ /** distributed graph coarsening routine of **/ /** the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.1 : from : 07 aug 2011 **/ /** to 07 aug 2011 **/ /** # Version 6.0 : from : 11 sep 2012 **/ /** to 28 sep 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "dgraph.h" #include "dgraph_coarsen.h" #include "ptscotch.h" /************************************/ /* */ /* This routine is the C API for */ /* the distributed graph coarsening */ /* routine. */ /* */ /************************************/ /*+ This routine creates a distributed coarse graph *** from the given fine graph, unless the coarse graph *** is smaller than some threshold size or the *** coarsening ratio is above some other threshold. *** If the coarse graph is created, a coarse-to-fine *** vertex array is created, that contains a pair of *** fine indices for each coarse index. It is the *** user's responsibility to free this array when it *** is no longer needed. *** It returns: *** - 0 : if the graph has been coarsened. *** - 1 : if the graph could not be coarsened. *** - 2 : if folded graph not present *** - 3 : on error. +*/ int SCOTCH_dgraphCoarsen ( SCOTCH_Dgraph * restrict const finegrafptr, /* Fine graph structure to fill */ const SCOTCH_Num coarnbr, /* Minimum number of coarse vertices */ const double coarrat, /* Maximum contraction ratio */ const SCOTCH_Num flagval, /* Flag value */ SCOTCH_Dgraph * restrict const coargrafptr, /* Coarse graph */ SCOTCH_Num * restrict const multloctab) /* Pointer to multinode array */ { DgraphCoarsenMulti * restrict multlocptr; #ifdef SCOTCH_DEBUG_LIBRARY1 int o; MPI_Comm_compare (((Dgraph * restrict const) coargrafptr)->proccomm, ((Dgraph * restrict const) finegrafptr)->proccomm, &o); if ((o != MPI_IDENT) && (o != MPI_CONGRUENT)) { errorPrint ("SCOTCH_dgraphCoarsen: communicators are not congruent"); return (3); } #endif /* SCOTCH_DEBUG_LIBRARY1 */ intRandInit (); /* Check that random number generator is initialized */ multlocptr = (DgraphCoarsenMulti * restrict) multloctab; /* User-provided multinode array */ switch (dgraphCoarsen ((Dgraph * restrict const) finegrafptr, (Dgraph * restrict const) coargrafptr, &multlocptr, 5, coarnbr, coarrat, (int) flagval)) { case 1 : return (1); case 2 : return (3); } if (multlocptr != (DgraphCoarsenMulti * restrict) multloctab) { /* If folding occurred */ if (multlocptr == NULL) return (2); memCpy (multloctab, multlocptr, /* Update array with folded multinode data */ ((Dgraph * restrict const) coargrafptr)->vertlocnbr * sizeof (DgraphCoarsenMulti)); memFree (multlocptr); /* Free allocated folded multinode array */ } return (0); } scotch-6.0.4.dfsg/src/libscotch/vgraph_separate_df.c0000644002563400244210000003031512256265351025633 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2013 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vgraph_separate_df.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module computes a separator of **/ /** a separation graph by using a diffusion **/ /** scheme. **/ /** **/ /** NOTES : # This algorithm has been designed to **/ /** work on band graphs only, for which **/ /** the two anchor vertices are the two **/ /** last vertices, the before-last as **/ /** anchor of part 0, and the last as **/ /** anchor of part 1. **/ /** **/ /** DATES : # Version 5.1 : from : 29 oct 2007 **/ /** to 24 may 2008 **/ /** # Version 6.0 : from : 24 dec 2013 **/ /** to 24 dec 2013 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VGRAPH_SEPARATE_DF #include "module.h" #include "common.h" #include "graph.h" #include "vgraph.h" #include "vgraph_separate_df.h" /* ** The static variables. */ static const Gnum vgraphseparatedfloadone = 1; /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the separation. ** It returns: ** - 0 : if the separator could be computed. ** - 1 : on error. */ int vgraphSeparateDf ( Vgraph * restrict const grafptr, /*+ Active graph +*/ const VgraphSeparateDfParam * const paraptr) /*+ Method parameters +*/ { float * restrict edlstax; /* Degree array */ float * restrict difotax; /* Old diffusion value array */ float * restrict difntax; /* New diffusion value array */ float * restrict difttax; /* Temporary swap value */ float cdifval; float cremval; Gnum fronnum; Gnum compload0avg; Gnum compload2; Gnum compsize1; float veloval; float vanctab[2]; INT movenum; INT passnum; const Gnum * restrict const verttax = grafptr->s.verttax; /* Fast accesses */ const Gnum * restrict const vendtax = grafptr->s.vendtax; const Gnum * restrict const edgetax = grafptr->s.edgetax; Gnum * restrict const frontab = grafptr->frontab; GraphPart * restrict const parttax = grafptr->parttax; if (memAllocGroup ((void **) (void *) &edlstax, (size_t) (grafptr->s.vertnbr * sizeof (float)), &difotax, (size_t) (grafptr->s.vertnbr * sizeof (float)), &difntax, (size_t) (grafptr->s.vertnbr * sizeof (float)), NULL) == NULL) { errorPrint ("vgraphSeparateDf: out of memory"); return (1); } edlstax -= grafptr->s.baseval; /* Base access to edlstax and diffusion arrays */ difotax -= grafptr->s.baseval; difntax -= grafptr->s.baseval; if (grafptr->s.edlotax == NULL) { /* If graph has no edge weights */ Gnum vertnum; for (vertnum = grafptr->s.baseval; vertnum < grafptr->s.vertnnd; vertnum ++) edlstax[vertnum] = (float) (vendtax[vertnum] - verttax[vertnum]); } else { /* If graph has edge weights */ Gnum vertnum; for (vertnum = grafptr->s.baseval; vertnum < grafptr->s.vertnnd; vertnum ++) { Gnum edgenum; Gnum edlosum; for (edgenum = verttax[vertnum], edlosum = 0; edgenum < vendtax[vertnum]; edgenum ++) edlosum += grafptr->s.edlotax[edgenum]; edlstax[vertnum] = (float) edlosum; } } compload0avg = grafptr->compload[0] + grafptr->compload[2] / 2; passnum = 0; do { const Gnum * restrict velobax; Gnum velomsk; Gnum vertnum; Gnum compload0; Gnum compload1; int rootval; /* Root part for separator vertices */ compload0 = compload0avg - grafptr->compload[2] / 2; compload1 = grafptr->s.velosum - compload0avg - (grafptr->compload[2] + 1) / 2; vanctab[0] = (float) (- compload0); /* Values to be injected to anchor vertices at every iteration */ vanctab[1] = (float) compload1 - VGRAPHSEPARATEDFEPSILON; /* Slightly tilt value to add to part 1 */ rootval = (paraptr->partval + passnum) & 1; /* Compute index of part which will receive separator vertices */ if (rootval == 0) /* If separator must be aggregated to part 0 */ vanctab[0] -= (float) grafptr->compload[2]; else vanctab[1] += (float) grafptr->compload[2]; for (vertnum = grafptr->s.baseval; vertnum < grafptr->s.vertnnd - 2; vertnum ++) difotax[vertnum] = 0.0F; difotax[grafptr->s.vertnnd - 2] = vanctab[0] / edlstax[grafptr->s.vertnnd - 2]; /* Load anchor vertices for first move */ difotax[grafptr->s.vertnnd - 1] = vanctab[1] / edlstax[grafptr->s.vertnnd - 1]; veloval = 1.0F; /* Assume no vertex loads */ cdifval = paraptr->cdifval; cremval = paraptr->cremval; for (movenum = 0; movenum < paraptr->movenbr; movenum ++) { /* For all moves */ Gnum vertnum; Gnum vertnnd; float vancval; /* Value to load vertex with if anchor */ vancval = 0.0F; /* At first vertices are not anchors */ vertnum = grafptr->s.baseval; vertnnd = grafptr->s.vertnnd - 2; while (1) { for ( ; vertnum < vertnnd; vertnum ++) { Gnum edgenum; Gnum edgennd; float diffval; edgenum = verttax[vertnum]; edgennd = vendtax[vertnum]; diffval = 0.0F; if (grafptr->s.edlotax != NULL) for ( ; edgenum < edgennd; edgenum ++) diffval += difotax[edgetax[edgenum]] * (float) grafptr->s.edlotax[edgenum]; else for ( ; edgenum < edgennd; edgenum ++) diffval += difotax[edgetax[edgenum]]; if (grafptr->s.velotax != NULL) veloval = (float) grafptr->s.velotax[vertnum]; diffval *= cdifval; diffval += difotax[vertnum] * cremval * edlstax[vertnum]; if (diffval >= 0.0F) { diffval -= veloval; if (diffval <= 0.0F) diffval = +VGRAPHSEPARATEDFEPSILON; } else { diffval += veloval; if (diffval >= 0.0F) diffval = -VGRAPHSEPARATEDFEPSILON; } if (isnan (diffval)) /* If overflow occured */ goto abort; /* Exit main loop without swapping arrays so as to keep last valid iteration */ difntax[vertnum] = diffval / edlstax[vertnum]; /* Prepare vertex for diffusion */ } if (vertnum == grafptr->s.vertnnd) /* If all vertices processed, exit intermediate infinite loop */ break; vertnnd ++; /* Prepare to go only for one more run */ vancval = vanctab[vertnum - grafptr->s.vertnnd + 2]; /* Load variable with anchor value */ } difttax = difntax; /* Swap old and new diffusion arrays */ difntax = difotax; difotax = difttax; } abort : /* If overflow occured, resume here */ for (vertnum = grafptr->s.baseval; vertnum < grafptr->s.vertnnd; vertnum ++) /* Pre-set parts without separator */ parttax[vertnum] = (difotax[vertnum] <= 0.0F) ? 0 : 1; if (grafptr->s.velotax != NULL) { velobax = grafptr->s.velotax; velomsk = ~((Gnum) 0); } else { velobax = &vgraphseparatedfloadone; velomsk = 0; } veloval = 1.0F; /* Assume no vertex loads */ for (vertnum = grafptr->s.baseval, fronnum = compsize1 = compload1 = compload2 = 0; vertnum < grafptr->s.vertnnd; vertnum ++) { Gnum partval; GraphPart partend; Gnum veloval; partend = parttax[vertnum] ^ 1; partval = (Gnum) parttax[vertnum]; veloval = velobax[vertnum & velomsk]; compsize1 += partval; /* Here, part is 0 or 1 only */ compload1 += partval * veloval; if (partval == (Gnum) rootval) { /* Only vertices of aggregated part can be in separator */ Gnum edgenum; for (edgenum = verttax[vertnum]; edgenum < vendtax[vertnum]; edgenum ++) { if (parttax[edgetax[edgenum]] == partend) { /* If end vertex is in other part (and not in separator) */ frontab[fronnum ++] = vertnum; /* Record it */ parttax[vertnum] = 2; compload2 += veloval; break; /* No need to go further */ } } } } grafptr->compload[0] = grafptr->s.velosum - compload1; grafptr->compload[1] = compload1; grafptr->compload[2] = compload2; grafptr->compload[rootval] -= compload2; grafptr->comploaddlt = grafptr->compload[0] - grafptr->compload[1]; grafptr->compsize[0] = grafptr->s.vertnbr - compsize1; grafptr->compsize[1] = compsize1; grafptr->compsize[rootval] -= fronnum; grafptr->fronnbr = fronnum; } while (++ passnum < paraptr->passnbr); /* As long as not all passes performed */ memFree (edlstax + grafptr->s.baseval); /* Free group leader */ #ifdef SCOTCH_DEBUG_VGRAPH2 if (vgraphCheck (grafptr) != 0) { errorPrint ("vgraphSeparateDf: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/library_graph_base_f.c0000644002563400244210000000623711631447170026136 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_base_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API for **/ /** the source graph handling routines of **/ /** the libSCOTCH library. **/ /** **/ /** DATES : # Version 4.0 : from : 22 apr 2004 **/ /** to 23 apr 2004 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the graph handling routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFGRAPHBASE, scotchfgraphbase, ( \ SCOTCH_Graph * const grafptr, \ const SCOTCH_Num * const basenew, \ SCOTCH_Num * const baseold), \ (grafptr, basenew, baseold)) { *baseold = SCOTCH_graphBase (grafptr, *basenew); } scotch-6.0.4.dfsg/src/libscotch/vmesh.h0000644002563400244210000001177111631447170023140 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vmesh.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for mesh vertex separation **/ /** routines. **/ /** **/ /** DATES : # Version 4.0 : from : 10 sep 2002 **/ /** to : 10 sep 2002 **/ /** # Version 5.1 : from : 04 nov 2010 **/ /** to : 04 nov 2010 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ Active graph structure. +*/ typedef struct Vmesh_ { Mesh m; /*+ Source mesh +*/ GraphPart * parttax; /*+ Based part array: 0,1: part; 2: separator +*/ Gnum ecmpsize[2]; /*+ Number of elements in each part (not in separator) +*/ Gnum ncmpload[3]; /*+ Loads of nodes in both parts and separator +*/ Gnum ncmploaddlt; /*+ Node load difference between both parts +*/ Gnum ncmpsize[2]; /*+ Number of nodes in parts (separator is fronnbr) +*/ Gnum fronnbr; /*+ Number of frontier nodes; TRICK: ncmpsize[2] +*/ Gnum * frontab; /*+ Array of frontier node numbers +*/ Gnum levlnum; /*+ Nested dissection or coarsening level +*/ } Vmesh; /*+ The graph separator storing structure. +*/ typedef struct VmeshStore_ { Gnum ecmpsize[2]; /*+ Number of elements in each part +*/ Gnum ncmpload[3]; /*+ Loads of nodes in both parts and separator +*/ Gnum ncmploaddlt; /*+ Node load difference between both parts +*/ Gnum ncmpsize[2]; /*+ Number of nodes in parts (separator is fronnbr) +*/ Gnum fronnbr; /*+ Number of frontier nodes; TRICK: ncmpsize[2] +*/ byte * datatab; /*+ Variable-sized data array +*/ } VmeshStore; /* ** The function prototypes. */ #ifndef VMESH #define static #endif void vmeshExit (Vmesh * const); void vmeshZero (Vmesh * const); int vmeshCheck (const Vmesh * const); int vmeshStoreInit (const Vmesh * const, VmeshStore * const); void vmeshStoreExit (VmeshStore * const); void vmeshStoreSave (const Vmesh * const , VmeshStore * const); void vmeshStoreUpdt (Vmesh * const, const VmeshStore * const); #undef static scotch-6.0.4.dfsg/src/libscotch/vdgraph.h0000644002563400244210000001270611631447170023450 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vdgraph.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for distributed vertex separation **/ /** routines. **/ /** **/ /** DATES : # Version 5.0 : from : 06 feb 2006 **/ /** to : 29 apr 2006 **/ /** # Version 5.1 : from : 07 nov 2007 **/ /** to : 04 nov 2010 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ Active graph structure. +*/ typedef struct Vdgraph_ { Dgraph s; /*+ Source distributed graph +*/ GraphPart * partgsttax; /*+ Based local part array: 0,1: part; 2: separator +*/ Gnum compglbloaddlt; /*+ Load difference between both parts +*/ Gnum compglbload[3]; /*+ Global loads of both parts and of separator; TRICK: before compglbsize[] +*/ Gnum compglbsize[3]; /*+ Number of vertices in parts; compglbsize[2] is fronglbnbr, the separator +*/ Gnum complocload[3]; /*+ Local loads of both parts and of separator; TRICK: before complocsize[] +*/ Gnum complocsize[3]; /*+ Number of vertices in parts; complocsize[2] is fronlocnbr, the separator +*/ Gnum * fronloctab; /*+ Array of local frontier vertex numbers +*/ Gnum levlnum; /*+ Nested dissection or coarsening level +*/ } Vdgraph; /*+ The graph separator storing structure. +*/ typedef struct VdgraphStore_ { Gnum fronglbnbr; /*+ Number of frontier nodes +*/ Gnum compglbloaddlt; /*+ Difference from the average +*/ Gnum compglbload[2]; /*+ Load in both parts +*/ Gnum compglbsize0; /*+ Number of vertices in part 0 +*/ Gnum complocsize0; /*+ Number of vertices in parts +*/ Gnum fronlocnbr; /*+ Number of local frontier vertices +*/ byte * datatab; /*+ Variable-sized data array +*/ } VdgraphStore; /* ** The function prototypes. */ #ifndef VDGRAPH #define static #endif int vdgraphInit (Vdgraph * restrict const, MPI_Comm); void vdgraphExit (Vdgraph * const); void vdgraphZero (Vdgraph * const); int vdgraphCheck (const Vdgraph * const); #ifdef VGRAPH_H int vdgraphGatherAll (const Vdgraph * restrict const, Vgraph * restrict); #endif /* VGRAPH_H */ int vdgraphStoreInit (const Vdgraph * const, VdgraphStore * const); void vdgraphStoreExit (VdgraphStore * const); void vdgraphStoreSave (const Vdgraph * const , VdgraphStore * const); void vdgraphStoreUpdt (Vdgraph * const, const VdgraphStore * const); #undef static scotch-6.0.4.dfsg/src/libscotch/vdgraph_separate_df.c0000644002563400244210000004267311631447171026007 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vdgraph_separate_df.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module computes a separator of the **/ /** given distributed separator graph by **/ /** applying a diffusion method to what is **/ /** assumed to be a distributed band graph. **/ /** **/ /** DATES : # Version 5.1 : from : 05 nov 2007 **/ /** to : 09 nov 2008 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VDGRAPH_SEPARATE_DF #include "module.h" #include "common.h" #include "dgraph.h" #include "vdgraph.h" #include "vdgraph_separate_df.h" /* ** The static variables. */ static const Gnum vdgraphseparatedfloadone = 1; /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine computes a distributed separator ** by diffusion across what is assumed to be a ** distributed band graph. ** It returns: ** - 0 : if the separator could be computed. ** - !0 : on error. */ int vdgraphSeparateDf ( Vdgraph * const grafptr, /*+ Distributed graph +*/ const VdgraphSeparateDfParam * const paraptr) /*+ Method parameters +*/ { float * restrict ielsloctax; /* Inverse of degree array */ float * restrict difogsttax; /* Old diffusion value array */ float * restrict difngsttax; /* New diffusion value array */ const Gnum * restrict edgegsttax; Gnum fronlocnum; float compglbavg; Gnum complocload1; Gnum complocload2; Gnum complocsize1; const Gnum * restrict velolocbax; Gnum velolocmsk; float vanclocval[2]; float valolocval[2]; /* Fraction of load to remove from anchor vertices at each step */ Gnum vanclocnnd; Gnum vertlocnum; Gnum reduloctab[4]; /* Local degree of both anchor vertices, minus edges to other anchors, and their loads */ Gnum reduglbtab[4]; Gnum passnum; float cdifval; float cremval; Gnum psepval; /* Separator part */ int ovflval; /* Overflow flag value */ if (dgraphGhst (&grafptr->s) != 0) { /* Compute ghost edge array if not already present */ errorPrint ("vdgraphSeparateDf: cannot compute ghost edge array"); return (1); } reduloctab[0] = grafptr->s.vendloctax[grafptr->s.vertlocnnd - 2] - grafptr->s.vertloctax[grafptr->s.vertlocnnd - 2] - (grafptr->s.procglbnbr - 1); reduloctab[1] = grafptr->s.vendloctax[grafptr->s.vertlocnnd - 1] - grafptr->s.vertloctax[grafptr->s.vertlocnnd - 1] - (grafptr->s.procglbnbr - 1); if (grafptr->s.veloloctax == NULL) reduloctab[2] = reduloctab[3] = 1; else { reduloctab[2] = grafptr->s.veloloctax[grafptr->s.vertlocnnd - 2]; reduloctab[3] = grafptr->s.veloloctax[grafptr->s.vertlocnnd - 1]; } if (memAllocGroup ((void **) (void *) &ielsloctax, (size_t) (grafptr->s.vertlocnbr * sizeof (float)), &difogsttax, (size_t) (grafptr->s.vertgstnbr * sizeof (float)), &difngsttax, (size_t) (grafptr->s.vertgstnbr * sizeof (float)), NULL) == NULL) { errorPrint ("vdgraphSeparateDf: out of memory"); reduloctab[0] = -1; } else { ielsloctax -= grafptr->s.baseval; difogsttax -= grafptr->s.baseval; difngsttax -= grafptr->s.baseval; } if (MPI_Allreduce (reduloctab, reduglbtab, 4, GNUM_MPI, MPI_SUM, grafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("vdgraphSeparateDf: communication error (1)"); return (1); } if (reduglbtab[0] < 0) { /* If memory error */ if (ielsloctax != NULL) memFree (ielsloctax + grafptr->s.baseval); /* Free group leader */ } if ((reduglbtab[0] == 0) || /* If graph is too small to have any usable anchors, leave partition as is */ (reduglbtab[1] == 0)) { memFree (ielsloctax + grafptr->s.baseval); /* Free group leader */ return (0); } psepval = paraptr->partval & 1; /* Coerce part in the {0,1} range */ compglbavg = (float) (grafptr->compglbload[0] + grafptr->compglbload[1]) * 0.5F; vanclocval[0] = (float) grafptr->compglbload[0]; if (vanclocval[0] < (compglbavg * (1.0F - (float) paraptr->deltval))) /* Enforce balance constraint */ vanclocval[0] = compglbavg * (1.0F - (float) paraptr->deltval); else if (vanclocval[0] > (compglbavg * (1.0F + (float) paraptr->deltval))) vanclocval[0] = compglbavg * (1.0F + (float) paraptr->deltval); vanclocval[1] = (float) (grafptr->compglbload[0] + grafptr->compglbload[1]) - vanclocval[0]; valolocval[0] = (float) reduglbtab[2]; /* Compute values to remove from anchor vertices */ valolocval[1] = (float) reduglbtab[3]; if (vanclocval[0] < valolocval[0]) /* If anchor in part 0 too large to reduce imbalance */ psepval = 1; /* Separator must be taken from part 1 to stick to anchor 0 */ else if (vanclocval[1] < valolocval[1]) /* Else if anchor in part 1 too large to reduce imbalance */ psepval = 0; /* It is from part 0 that separator must be extracted */ vanclocval[psepval] += (float) grafptr->compglbload[2]; /* Aggregate separator to proper part */ vanclocval[0] = - vanclocval[0]; /* Part 0 holds negative values */ vanclocval[1] -= VDGRAPHSEPARATEDFEPSILON; /* Slightly tilt value to add to part 1 */ for (vertlocnum = grafptr->s.baseval, vanclocnnd = grafptr->s.vertlocnnd - 2; /* Do not account for anchor vertices in diffusion computations */ vertlocnum < vanclocnnd; vertlocnum ++) { #ifdef SCOTCH_DEBUG_VDGRAPH2 if ((grafptr->s.vendloctax[vertlocnum] - grafptr->s.vertloctax[vertlocnum]) == 0) { errorPrint ("vdgraphSeparateDf: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_VDGRAPH2 */ ielsloctax[vertlocnum] = 1.0F / (float) (grafptr->s.vendloctax[vertlocnum] - grafptr->s.vertloctax[vertlocnum]); difogsttax[vertlocnum] = 0.0F; } ielsloctax[vanclocnnd] = 1.0F / (float) reduglbtab[0]; ielsloctax[vanclocnnd + 1] = 1.0F / (float) reduglbtab[1]; difogsttax[vanclocnnd] = vanclocval[0] * ielsloctax[vanclocnnd]; /* Load anchor vertices for first pass */ difogsttax[vanclocnnd + 1] = vanclocval[1] * ielsloctax[vanclocnnd + 1]; difngsttax[vanclocnnd] = /* In case of isolated anchors, do not risk overflow because of NaN */ difngsttax[vanclocnnd + 1] = 0.0F; if (dgraphHaloSync (&grafptr->s, (byte *) (void *) (difogsttax + grafptr->s.baseval), MPI_FLOAT) != 0) { /* Perform initial diffusion (and build communication structures) */ errorPrint ("vdgraphSeparateDf: cannot propagate diffusion data (1)"); memFree (ielsloctax + grafptr->s.baseval); /* Free group leader */ return (1); } ovflval = 0; cdifval = paraptr->cdifval; cremval = paraptr->cremval; edgegsttax = grafptr->s.edgegsttax; for (passnum = 0; ; ) { /* For all passes */ if (ovflval == 0) { /* If no overflow occured */ Gnum vertlocnum; float * diftgsttax; /* Temporary swap value */ float veloval; veloval = 1.0F; /* Assume no vertex loads */ for (vertlocnum = grafptr->s.baseval; vertlocnum < vanclocnnd; vertlocnum ++) { Gnum edgelocnum; Gnum edgelocnnd; float diffval; diffval = 0.0F; for (edgelocnum = grafptr->s.vertloctax[vertlocnum], edgelocnnd = grafptr->s.vendloctax[vertlocnum]; edgelocnum < edgelocnnd; edgelocnum ++) diffval += difogsttax[edgegsttax[edgelocnum]]; diffval *= cdifval; diffval += (difogsttax[vertlocnum] * cremval) / ielsloctax[vertlocnum]; if (grafptr->s.veloloctax != NULL) veloval = (float) grafptr->s.veloloctax[vertlocnum]; if (diffval >= 0.0F) { diffval = (diffval - veloval) * ielsloctax[vertlocnum]; if (diffval <= 0.0F) diffval = +VDGRAPHSEPARATEDFEPSILON; } else { diffval = (diffval + veloval) * ielsloctax[vertlocnum]; if (diffval >= 0.0F) diffval = -VDGRAPHSEPARATEDFEPSILON; } if (isnan (diffval)) { /* If overflow occured */ ovflval = 1; /* We are in state of overflow */ goto abort; /* Exit this loop without swapping arrays */ } difngsttax[vertlocnum] = diffval; } for ( ; vertlocnum < grafptr->s.vertlocnnd; vertlocnum ++) { /* For the two local anchor vertices */ Gnum edgelocnum; Gnum edgelocnnd; float diffval; diffval = 0.0F; edgelocnum = grafptr->s.vertloctax[vertlocnum] + grafptr->s.procglbnbr - 1; /* Skip links to other anchors */ edgelocnnd = grafptr->s.vendloctax[vertlocnum]; if (edgelocnum == edgelocnnd) /* If isolated anchor */ continue; /* Barrel is empty */ for ( ; edgelocnum < edgelocnnd; edgelocnum ++) diffval += difogsttax[edgegsttax[edgelocnum]]; diffval *= cdifval; diffval += vanclocval[vertlocnum - vanclocnnd] + (difogsttax[vertlocnum] * cremval) / ielsloctax[vertlocnum]; if (diffval >= 0.0F) { diffval = (diffval - valolocval[vertlocnum - vanclocnnd]) * ielsloctax[vertlocnum]; if (diffval <= 0.0F) diffval = +VDGRAPHSEPARATEDFEPSILON; } else { diffval = (diffval + valolocval[vertlocnum - vanclocnnd]) * ielsloctax[vertlocnum]; if (diffval >= 0.0F) diffval = -VDGRAPHSEPARATEDFEPSILON; } if (isnan (diffval)) { /* If overflow occured */ ovflval = 1; /* We are in state of overflow */ goto abort; /* Exit this loop without swapping arrays */ } difngsttax[vertlocnum] = diffval; } diftgsttax = (float *) difngsttax; /* Swap old and new diffusion arrays */ difngsttax = (float *) difogsttax; /* Casts to prevent IBM compiler from yelling */ difogsttax = (float *) diftgsttax; } abort : /* If overflow occured, resume here */ if (++ passnum >= paraptr->passnbr) /* If maximum number of passes reached */ break; /* Exit main loop */ if (dgraphHaloSync (&grafptr->s, (byte *) (void *) (difogsttax + grafptr->s.baseval), MPI_FLOAT) != 0) { errorPrint ("vdgraphSeparateDf: cannot propagate diffusion data (2)"); memFree (ielsloctax + grafptr->s.baseval); /* Free group leader */ return (1); } } for (vertlocnum = grafptr->s.baseval; vertlocnum < vanclocnnd; vertlocnum ++) /* Pre-set parts without separator */ grafptr->partgsttax[vertlocnum] = (difogsttax[vertlocnum] <= 0.0F) ? 0 : 1; grafptr->partgsttax[vanclocnnd] = 0; /* Set up parts in case anchors are isolated */ grafptr->partgsttax[vanclocnnd + 1] = 1; if (grafptr->s.veloloctax != NULL) { velolocbax = grafptr->s.veloloctax; velolocmsk = ~((Gnum) 0); } else { velolocbax = &vdgraphseparatedfloadone; velolocmsk = 0; } memFree (ielsloctax + grafptr->s.baseval); /* Free group leader */ if (dgraphHaloSync (&grafptr->s, (byte *) (void *) (grafptr->partgsttax + grafptr->s.baseval), GRAPHPART_MPI) != 0) { errorPrint ("vdgraphSeparateDf: cannot propagate part data"); return (1); } for (vertlocnum = grafptr->s.baseval, fronlocnum = complocsize1 = complocload1 = complocload2 = 0; vertlocnum < grafptr->s.vertlocnnd; vertlocnum ++) { Gnum partval; GraphPart partend; Gnum veloval; #ifdef SCOTCH_DEBUG_VDGRAPH2 if (grafptr->partgsttax[vertlocnum] > 1) { errorPrint ("vdgraphSeparateDf: internal error (2)"); break; /* Do not break upcoming collective communications */ } #endif /* SCOTCH_DEBUG_VDGRAPH2 */ partend = grafptr->partgsttax[vertlocnum] ^ 1; partval = (Gnum) grafptr->partgsttax[vertlocnum]; veloval = velolocbax[vertlocnum & velolocmsk]; complocsize1 += partval; /* Here, part is 0 or 1 only */ complocload1 += partval * veloval; if (partval == psepval) { /* Only vertices of aggregated part can be in separator */ Gnum edgelocnum; for (edgelocnum = grafptr->s.vertloctax[vertlocnum]; edgelocnum < grafptr->s.vendloctax[vertlocnum]; edgelocnum ++) { #ifdef SCOTCH_DEBUG_VDGRAPH2 if (grafptr->partgsttax[edgegsttax[edgelocnum]] > 2) { errorPrint ("vdgraphSeparateDf: internal error (3)"); vertlocnum = grafptr->s.vertlocnnd; break; /* Do not break upcoming collective communications */ } #endif /* SCOTCH_DEBUG_VDGRAPH2 */ if (grafptr->partgsttax[edgegsttax[edgelocnum]] == partend) { /* If end vertex is in other part (and not in separator) */ grafptr->fronloctab[fronlocnum ++] = vertlocnum; /* Record it as member of the separator */ grafptr->partgsttax[vertlocnum] = 2; complocload2 += veloval; break; /* No need to go further */ } } } } grafptr->complocload[0] = grafptr->s.velolocsum - complocload1; grafptr->complocload[1] = complocload1; grafptr->complocload[2] = complocload2; grafptr->complocload[psepval] -= complocload2; grafptr->complocsize[0] = grafptr->s.vertlocnbr - complocsize1; grafptr->complocsize[1] = complocsize1; grafptr->complocsize[psepval] -= fronlocnum; grafptr->complocsize[2] = fronlocnum; if (MPI_Allreduce (&grafptr->complocload[0], &grafptr->compglbload[0], 6, GNUM_MPI, MPI_SUM, grafptr->s.proccomm) != MPI_SUCCESS) { /* TRICK: all arrays */ errorPrint ("vdgraphSeparateDf: communication error (2)"); return (1); } grafptr->compglbloaddlt = grafptr->compglbload[0] - grafptr->compglbload[1]; #ifdef SCOTCH_DEBUG_VDGRAPH2 if (vdgraphCheck (grafptr) != 0) { errorPrint ("vdgraphSeparateDf: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_VDGRAPH2 */ if (grafptr->s.proclocnum == 0) fprintf (stderr, "BROL " GNUMSTRING "," GNUMSTRING "," GNUMSTRING "(" GNUMSTRING ")\n", (Gnum) grafptr->compglbload[0], (Gnum) grafptr->compglbload[1], (Gnum) grafptr->compglbload[2], (Gnum) grafptr->compglbloaddlt); return (0); } scotch-6.0.4.dfsg/src/libscotch/bdgraph_store.c0000644002563400244210000001731111633143620024623 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bdgraph_store.c **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the save data **/ /** structure handling routines for dis- **/ /** tributed bipartition graphs. **/ /** **/ /** DATES : # Version 5.1 : from : 10 sep 2007 **/ /** to 22 oct 2008 **/ /** # Version 6.0 : from : 11 sep 2011 **/ /** to 11 sep 2011 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define BDGRAPH_STORE #include "module.h" #include "common.h" #include "arch.h" #include "dgraph.h" #include "bdgraph.h" /**********************************/ /* */ /* Store graph handling routines. */ /* */ /**********************************/ /* This routine builds a save structure ** for the given active graph. ** It returns: ** - 0 : if allocation succeeded. ** - !0 : on error. */ int bdgraphStoreInit ( const Bdgraph * restrict const grafptr, BdgraphStore * restrict const storptr) { Gnum savsize; savsize = grafptr->s.vertlocnbr * (sizeof (GraphPart) + sizeof (Gnum)); /* Compute size for frontier and part arrays */ if ((storptr->datatab = (byte *) memAlloc (savsize)) == NULL) { /* Allocate save structure */ errorPrint ("bdgraphStoreInit: out of memory"); return (1); } return (0); } /* This routine frees a save structure. ** It returns: ** - VOID : in all cases. */ void bdgraphStoreExit ( BdgraphStore * const storptr) { memFree (storptr->datatab); #ifdef SCOTCH_DEBUG_BDGRAPH2 storptr->datatab = NULL; #endif /* SCOTCH_DEBUG_BDGRAPH2 */ } /* This routine saves partition data from the ** given active graph to the given save structure. ** It returns: ** - VOID : in all cases. */ void bdgraphStoreSave ( const Bdgraph * const grafptr, BdgraphStore * const storptr) { byte * partloctab; /* Pointer to part data save area */ byte * fronloctab; /* Pointer to frontier data save area */ storptr->fronlocnbr = grafptr->fronlocnbr; /* Save partition parameters */ storptr->fronglbnbr = grafptr->fronglbnbr; storptr->complocload0 = grafptr->complocload0; storptr->compglbload0 = grafptr->compglbload0; storptr->compglbload0dlt = grafptr->compglbload0dlt; storptr->complocsize0 = grafptr->complocsize0; storptr->compglbsize0 = grafptr->compglbsize0; storptr->commglbload = grafptr->commglbload; storptr->commglbgainextn = grafptr->commglbgainextn; fronloctab = storptr->datatab; /* Compute data offsets within save structure */ partloctab = fronloctab + grafptr->fronlocnbr * sizeof (Gnum); if (grafptr->fronloctab != NULL) /* If frontier array allocated */ memCpy (fronloctab, grafptr->fronloctab, grafptr->fronlocnbr * sizeof (Gnum)); #ifdef SCOTCH_DEBUG_BDGRAPH2 else if (grafptr->fronglbnbr != 0) errorPrint ("bdgraphStoreSave: inconsistent graph data (1)"); #endif /* SCOTCH_DEBUG_BDGRAPH2 */ if (grafptr->partgsttax != NULL) memCpy (partloctab, grafptr->partgsttax + grafptr->s.baseval, grafptr->s.vertlocnbr * sizeof (GraphPart)); else { #ifdef SCOTCH_DEBUG_BDGRAPH2 if (grafptr->compglbload0 != grafptr->s.veloglbsum) errorPrint ("bdgraphStoreSave: inconsistent graph data (2)"); #endif /* SCOTCH_DEBUG_BDGRAPH2 */ memSet (partloctab, 0, grafptr->s.vertlocnbr * sizeof (GraphPart)); /* In case part array is allocated before update */ } } /* This routine updates partition data of the ** given active graph, using the given save graph. ** It returns: ** - VOID : in all cases. */ void bdgraphStoreUpdt ( Bdgraph * const grafptr, const BdgraphStore * const storptr) { byte * fronloctab; /* Pointer to frontier data save area */ byte * partloctab; /* Pointer to part data save area */ grafptr->fronlocnbr = storptr->fronlocnbr; /* Save partition parameters */ grafptr->fronglbnbr = storptr->fronglbnbr; grafptr->complocload0 = storptr->complocload0; grafptr->compglbload0 = storptr->compglbload0; grafptr->compglbload0dlt = storptr->compglbload0dlt; grafptr->complocsize0 = storptr->complocsize0; grafptr->compglbsize0 = storptr->compglbsize0; grafptr->commglbload = storptr->commglbload; grafptr->commglbgainextn = storptr->commglbgainextn; grafptr->bbalglbval = (double) ((grafptr->compglbload0dlt < 0) ? (- grafptr->compglbload0dlt) : grafptr->compglbload0dlt) / (double) grafptr->compglbload0avg; fronloctab = storptr->datatab; /* Compute data offsets within save structure */ partloctab = fronloctab + grafptr->fronlocnbr * sizeof (Gnum); if (grafptr->fronloctab != NULL) memCpy (grafptr->fronloctab, fronloctab, grafptr->fronlocnbr * sizeof (Gnum)); #ifdef SCOTCH_DEBUG_BDGRAPH2 else if (grafptr->fronglbnbr != 0) errorPrint ("bdgraphStoreUpdt: inconsistent graph data (1)"); #endif /* SCOTCH_DEBUG_BDGRAPH2 */ if (grafptr->partgsttax != NULL) memCpy (grafptr->partgsttax + grafptr->s.baseval, partloctab, grafptr->s.vertlocnbr * sizeof (GraphPart)); #ifdef SCOTCH_DEBUG_BDGRAPH2 else if (grafptr->compglbload0 != grafptr->s.veloglbsum) errorPrint ("bdgraphStoreUpdt: inconsistent graph data (2)"); #endif /* SCOTCH_DEBUG_BDGRAPH2 */ #ifdef SCOTCH_DEBUG_BDGRAPH2 if (bdgraphCheck (grafptr) != 0) errorPrint ("bdgraphStoreUpdt: inconsistent graph data (3)"); #endif /* SCOTCH_DEBUG_BDGRAPH2 */ } scotch-6.0.4.dfsg/src/libscotch/kgraph.h0000644002563400244210000002340512376156600023271 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : Part of a static mapper. **/ /** These lines are the data declarations **/ /** for the k-way graph mapping structures **/ /** and routines. **/ /** **/ /** DATES : # Version 3.2 : from : 12 sep 1997 **/ /** to 26 may 1998 **/ /** # Version 3.3 : from : 19 oct 1998 **/ /** to 12 mar 1999 **/ /** # Version 4.0 : from : 11 dec 2001 **/ /** to 16 feb 2005 **/ /** # Version 5.0 : from : 17 jun 2008 **/ /** to 17 jun 2008 **/ /** # Version 5.1 : from : 13 jul 2010 **/ /** to 31 aug 2011 **/ /** # Version 6.0 : from : 03 mar 2011 **/ /** to 23 aug 2014 **/ /** **/ /** NOTES : # The comploadavg and comploaddlt **/ /** should always be allocated together, **/ /** with comploaddlt just after **/ /** comploadavg. **/ /** **/ /** # To date, the only k-way graph mapping **/ /** method is recursive bipartitioning, **/ /** which does not use the comploadavg, **/ /** comploaddlt and frontab parameters. **/ /** Consequently, although allocated, **/ /** these parameters are not set by this **/ /** method. However, when coupled with **/ /** the kdgraphMapSq() parallel static **/ /** mapping routine, these parameters **/ /** have to be computed. This is why the **/ /** kgraphCost() routine is called within **/ /** kdgraphMapSq(). When other sequential **/ /** mapping routines are proposed, it may **/ /** be more interesting to move **/ /** kgraphCost() to kgraphMapRb(). **/ /** **/ /** # When (pfixtax != NULL), we are **/ /** handling fixed vertices. **/ /** **/ /** # When (r.m.parttax != NULL), we are **/ /** doing repartitioning. **/ /** **/ /************************************************************/ #define KGRAPH_H /* ** The defines. */ /*+ Graph option flags. +*/ #define KGRAPHFREEFRON (GRAPHBITSNOTUSED) /*+ Free frontier array +*/ #define KGRAPHFREECOMP (GRAPHBITSNOTUSED << 1) /*+ Free computational loads array +*/ #define KGRAPHFREEPFIX (GRAPHBITSNOTUSED << 2) /*+ Free fixed vertex array +*/ #define KGRAPHFREEVMLO (GRAPHBITSNOTUSED << 3) /*+ Free vertex migration cost array +*/ #define KGRAPHHASANCHORS (GRAPHBITSNOTUSED << 4) /*+ The graph is a band graph +*/ /* ** The type and structure definitions. */ /*+ The graph structure. +*/ typedef struct Kgraph_ { Graph s; /*+ Current graph +*/ Arch a; /*+ Current architecture +*/ Mapping m; /*+ Current mapping of graph vertices +*/ struct { /*+ Remapping structure +*/ Mapping m; /*+ Old mapping +*/ Gnum crloval; /*+ Coefficient load for regular edges +*/ Gnum cmloval; /*+ Coefficient load for migration edges; may be zero +*/ const Gnum * vmlotax; /*+ Vertex migration cost array +*/ } r; Gnum vfixnbr; /*+ Number of fixed vertices +*/ const Anum * pfixtax; /*+ Fixed terminal part array +*/ Gnum fronnbr; /*+ Number of frontier vertices +*/ Gnum * frontab; /*+ Array of frontier vertex numbers +*/ Gnum * comploadavg; /*+ Array of target average loads +*/ Gnum * comploaddlt; /*+ Array of target imbalances +*/ double comploadrat; /*+ Ideal load balance per weight unit +*/ double kbalval; /*+ Last k-way imbalance ratio +*/ Gnum commload; /*+ Communication load +*/ Gnum levlnum; /*+ Graph coarsening level +*/ } Kgraph; /*+ The save graph structure. +*/ typedef struct KgraphStore_ { Gnum partnbr; /*+ Number of parts +*/ int mflaval; /*+ Mapping properties +*/ Anum * parttab; /*+ Mapping array [vertnbr] +*/ ArchDom * domntab; /*+ Array of domains [termmax] +*/ Anum domnnbr; /*+ Current number of domains +*/ Gnum fronnbr; /*+ Number of frontier vertices +*/ Gnum * frontab; /*+ Array of frontier vertex numbers +*/ Gnum * comploadavg; /*+ Array of target average loads +*/ Gnum * comploaddlt; /*+ Array of target imbalances +*/ double kbalval; /*+ Last k-way imbalance ratio +*/ Gnum commload; /*+ Communication load +*/ } KgraphStore; /* ** The function prototypes. */ #ifndef KGRAPH #define static #endif int kgraphInit (Kgraph * restrict const, const Graph * restrict const, const Arch * restrict const, const ArchDom * restrict const, const Gnum, const Anum * restrict const, const Anum * restrict const, const Gnum, const Gnum, const Gnum * restrict const); void kgraphExit (Kgraph * const); void kgraphFrst (Kgraph * const); int kgraphCheck (const Kgraph * const); void kgraphCost (Kgraph * const); void kgraphFron (Kgraph * const); int kgraphBand (Kgraph * restrict const, const Gnum, Kgraph * restrict const, Gnum * const, Gnum * restrict * restrict const); int kgraphStoreInit (const Kgraph * const, KgraphStore * const); void kgraphStoreExit (KgraphStore * const); void kgraphStoreSave (const Kgraph * const, KgraphStore * const); void kgraphStoreUpdt (Kgraph * const, const KgraphStore * const); #undef static scotch-6.0.4.dfsg/src/libscotch/kdgraph_gather.c0000644002563400244210000000705011631447170024756 0ustar trophimeutilisateurs du domaine/* Copyright 2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kdgraph_gather.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the routine which **/ /** builds a centralized mapping graph by **/ /** gathering the pieces of a distributed **/ /** mapping graph. **/ /** **/ /** DATES : # Version 5.1 : from : 17 jun 2008 **/ /** to : 17 jun 2008 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define KDGRAPH_GATHER #include "module.h" #include "common.h" #include "arch.h" #include "graph.h" #include "mapping.h" #include "kgraph.h" #include "dgraph.h" #include "dmapping.h" #include "kdgraph.h" /******************************/ /* */ /* These routines handle */ /* distributed source graphs. */ /* */ /******************************/ /* This function gathers the pieces of ** a distributed mapping graph to build a ** centralized mapping graph. ** There is no gathered vnumtab array if ** the original graph did not have one, as ** vertices are gathered in global order, or ** else the original vnumloctab is gathered. ** It returns: ** - 0 : if graph data are consistent. ** - !0 : on error. */ int kdgraphGather ( Kdgraph * restrict const dgrfptr, /* Distributed halo graph */ Kgraph * restrict const cgrfptr) /* Centralized halo graph */ { return (dgraphGather (&dgrfptr->s, &cgrfptr->s)); } scotch-6.0.4.dfsg/src/libscotch/hdgraph_order_nd.c0000644002563400244210000004675412024162634025307 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2012 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hdgraph_order_nd.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module orders distributed graphs **/ /** using the nested dissection algorithm. **/ /** **/ /** DATES : # Version 5.0 : from : 16 apr 2006 **/ /** to 01 mar 2008 **/ /** # Version 5.1 : from : 27 sep 2008 **/ /** to 11 nov 2008 **/ /** # Version 6.0 : from : 12 sep 2012 **/ /** to 12 sep 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HDGRAPH_ORDER_ND #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "order.h" #include "hgraph.h" #include "hgraph_order_st.h" #include "dgraph.h" #include "dorder.h" #include "hdgraph.h" #include "hdgraph_order_nd.h" #include "hdgraph_order_sq.h" #include "hdgraph_order_st.h" #include "vdgraph.h" #include "vdgraph_separate_st.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine builds either a centralized or a ** distributed subgraph, according to the number ** of processes in the given part. The calling ** conventions of this routine have been designed ** so as to allow for multi-threading. */ static void * hdgraphOrderNdFold2 ( void * const dataptr) /* Pointer to thread data */ { HdgraphOrderNdData * fldthrdptr; /* Thread input parameters */ HdgraphOrderNdGraph * restrict fldgrafptr; /* Pointer to folded graph area */ Hdgraph indgrafdat; /* Induced distributed halo graph */ void * o; fldthrdptr = (HdgraphOrderNdData *) dataptr; fldgrafptr = fldthrdptr->fldgrafptr; if (hdgraphInduceList (fldthrdptr->orggrafptr, fldthrdptr->indlistnbr, /* Compute unfinished induced subgraph on all processes */ fldthrdptr->indlisttab, &indgrafdat) != 0) return ((void *) 1); o = ((void *) 0); if (fldthrdptr->fldprocnbr > 1) { /* If subpart has several processes, fold a distributed graph */ if (hdgraphFold2 (&indgrafdat, fldthrdptr->fldpartval, /* Fold temporary induced subgraph from all processes */ &fldgrafptr->data.dgrfdat, fldthrdptr->fldproccomm) != 0) o = ((void *) 1); } else { /* Create a centralized graph */ Hgraph * restrict fldcgrfptr; fldcgrfptr = (fldthrdptr->fldprocnum == 0) ? &fldgrafptr->data.cgrfdat : NULL; /* See if we are the receiver */ if (hdgraphGather (&indgrafdat, fldcgrfptr) != 0) /* Gather centralized subgraph from all other processes */ o = ((void *) 1); } hdgraphExit (&indgrafdat); /* Free temporary induced graph */ return (o); } static int hdgraphOrderNdFold ( Hdgraph * restrict const orggrafptr, const Gnum indlistnbr0, /* Number of vertices in subgraph 0 */ const Gnum * restrict const indlisttab0, /* List of vertices in subgraph 0 */ const Gnum indlistnbr1, /* Number of vertices in subgraph 1 */ const Gnum * restrict const indlisttab1, /* List of vertices in subgraph 1 */ HdgraphOrderNdGraph * restrict const fldgrafptr) { HdgraphOrderNdData fldthrdtab[2]; MPI_Comm fldproccomm; int fldprocnbr; int fldprocnum; int fldproccol; int fldpartval; #ifdef SCOTCH_PTHREAD Hdgraph orggrafdat; /* Structure for copying graph fields except communicator */ pthread_t thrdval; /* Data of second thread */ #endif /* SCOTCH_PTHREAD */ int o; if (dgraphGhst (&orggrafptr->s) != 0) { /* Compute ghost edge array if not already present, before copying graph fields */ errorPrint ("hdgraphOrderNdFold: cannot compute ghost edge array"); return (1); } fldprocnbr = (orggrafptr->s.procglbnbr + 1) / 2; /* Median cut on number of processors */ fldthrdtab[0].fldprocnbr = fldprocnbr; fldthrdtab[1].fldprocnbr = orggrafptr->s.procglbnbr - fldprocnbr; if (orggrafptr->s.proclocnum < fldprocnbr) { /* Compute color and rank in two subparts */ fldpartval = 0; fldprocnum = orggrafptr->s.proclocnum; fldthrdtab[0].fldprocnum = fldprocnum; fldthrdtab[1].fldprocnum = -1; fldthrdtab[1].fldproccomm = MPI_COMM_NULL; } else { fldpartval = 1; fldprocnum = orggrafptr->s.proclocnum - fldprocnbr; fldprocnbr = orggrafptr->s.procglbnbr - fldprocnbr; fldthrdtab[0].fldproccomm = MPI_COMM_NULL; fldthrdtab[0].fldprocnum = -1; fldthrdtab[1].fldprocnum = fldprocnum; } fldgrafptr->typeval = HDGRAPHORDERNDTYPEDIST; /* Assume we belong to a distributed subpart */ fldproccol = fldpartval; /* Split color is the part value */ if (fldprocnbr <= 1) { /* If our part will have only one processor */ fldproccol = MPI_UNDEFINED; /* Do not create any sub-communicator for it */ fldgrafptr->typeval = HDGRAPHORDERNDTYPECENT; /* We will host a centralized subgraph */ } if (MPI_Comm_split (orggrafptr->s.proccomm, fldproccol, fldprocnum, &fldproccomm) != MPI_SUCCESS) { errorPrint ("hdgraphOrderNdFold: communication error"); return (1); } fldthrdtab[fldpartval].fldproccomm = fldproccomm; /* Assign folded communicator to proper part */ fldthrdtab[0].orggrafptr = orggrafptr; /* Load data to pass to the subgraph building routines */ fldthrdtab[0].indlistnbr = indlistnbr0; fldthrdtab[0].indlisttab = indlisttab0; fldthrdtab[0].fldgrafptr = fldgrafptr; fldthrdtab[0].fldpartval = 0; fldthrdtab[1].indlistnbr = indlistnbr1; fldthrdtab[1].indlisttab = indlisttab1; fldthrdtab[1].fldgrafptr = fldgrafptr; fldthrdtab[1].fldpartval = 1; #ifdef SCOTCH_PTHREAD orggrafdat = *orggrafptr; /* Create a separate graph structure to change its communicator */ fldthrdtab[1].orggrafptr = &orggrafdat; MPI_Comm_dup (orggrafptr->s.proccomm, &orggrafdat.s.proccomm); /* Duplicate communicator to avoid interferences in communications */ if (pthread_create (&thrdval, NULL, hdgraphOrderNdFold2, (void *) &fldthrdtab[1]) != 0) /* If could not create thread */ o = ((int) (intptr_t) hdgraphOrderNdFold2 ((void *) &fldthrdtab[0])) || /* Perform inductions in sequence */ ((int) (intptr_t) hdgraphOrderNdFold2 ((void *) &fldthrdtab[1])); else { /* Newly created thread is processing subgraph 1, so let's process subgraph 0 */ void * o2; o = (int) (intptr_t) hdgraphOrderNdFold2 ((void *) &fldthrdtab[0]); /* Work on copy with private communicator */ pthread_join (thrdval, &o2); o |= (int) (intptr_t) o2; } MPI_Comm_free (&orggrafdat.s.proccomm); #else /* SCOTCH_PTHREAD */ fldthrdtab[1].orggrafptr = orggrafptr; o = ((int) (intptr_t) hdgraphOrderNdFold2 ((void *) &fldthrdtab[0])) || /* Perform inductions in sequence */ ((int) (intptr_t) hdgraphOrderNdFold2 ((void *) &fldthrdtab[1])); #endif /* SCOTCH_PTHREAD */ return (o); } /* This routine performs the ordering. ** It returns: ** - 0 : if the ordering could be computed. ** - !0 : on error. */ int hdgraphOrderNd ( Hdgraph * restrict const grafptr, DorderCblk * restrict const cblkptr, const HdgraphOrderNdParam * restrict const paraptr) { Vdgraph vspgrafdat; /* Vertex separation graph data */ Gnum vspvertlocnum; /* Current vertex in separation graph */ Gnum * restrict vspvnumtab[2]; /* Lists of separated parts */ Gnum * restrict vspvnumptr0; Gnum * restrict vspvnumptr1; Gnum ordeglbval; Gnum vnodglbnbr; Gnum cblkfthnum; HdgraphOrderNdGraph indgrafdat01; /* Induced folded graph area */ DorderCblk * cblkptr01; int partmax; /* Induced part having most vertices */ int procnbr0; /* Number of processes in first part */ int cheklocval; int chekglbval; int o; #ifdef SCOTCH_DEBUG_HDGRAPH2 if (cblkptr->vnodglbnbr != grafptr->s.vertglbnbr) { errorPrint ("hdgraphOrderNd: inconsistent parameters"); return (1); } #endif /* SCOTCH_DEBUG_HDGRAPH2 */ if (grafptr->s.procglbnbr == 1) { /* If we are running on a single process */ HdgraphOrderSqParam paradat; paradat.ordstratseq = paraptr->ordstratseq; return (hdgraphOrderSq (grafptr, cblkptr, ¶dat)); /* Run sequentially */ } if (dgraphGhst (&grafptr->s) != 0) { /* Compute ghost edge array if not already present, to have vertgstnbr (and procsidtab) */ errorPrint ("hdgraphOrderNd: cannot compute ghost edge array"); return (1); } vspgrafdat.s = grafptr->s; /* Get non-halo part of halo distributed graph */ vspgrafdat.s.flagval &= ~DGRAPHFREEALL; /* Do not free contents of separation graph */ vspgrafdat.s.vlblloctax = NULL; /* Never mind about vertex labels in the future */ cheklocval = 0; if ((vspgrafdat.fronloctab = (Gnum *) memAlloc (vspgrafdat.s.vertlocnbr * sizeof (Gnum))) == NULL) { errorPrint ("hdgraphOrderNd: out of memory (1)"); vspgrafdat.partgsttax = NULL; cheklocval = 1; } else if ((vspgrafdat.partgsttax = (GraphPart *) memAlloc (vspgrafdat.s.vertgstnbr * sizeof (GraphPart))) == NULL) { errorPrint ("hdgraphOrderNd: out of memory (2)"); cheklocval = 1; } #ifdef SCOTCH_DEBUG_HDGRAPH1 /* Communication cannot be merged with a useful one */ if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, grafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("hdgraphOrderNd: communication error (1)"); return (1); } #else /* SCOTCH_DEBUG_HDGRAPH1 */ chekglbval = cheklocval; #endif /* SCOTCH_DEBUG_HDGRAPH1 */ if (chekglbval != 0) { if (vspgrafdat.fronloctab != NULL) { if (vspgrafdat.partgsttax != NULL) memFree (vspgrafdat.partgsttax); memFree (vspgrafdat.fronloctab); } return (1); } vspgrafdat.partgsttax -= vspgrafdat.s.baseval; vspgrafdat.levlnum = grafptr->levlnum; /* Set level of separation graph as level of halo graph */ vdgraphZero (&vspgrafdat); /* Set all local vertices to part 0 */ if (vdgraphSeparateSt (&vspgrafdat, paraptr->sepstrat) != 0) { /* Separate vertex-separation graph */ memFree (vspgrafdat.partgsttax + vspgrafdat.s.baseval); memFree (vspgrafdat.fronloctab); return (1); } if ((vspgrafdat.compglbsize[0] == 0) || /* If could not separate more */ (vspgrafdat.compglbsize[1] == 0)) { memFree (vspgrafdat.partgsttax + vspgrafdat.s.baseval); /* Free useless space */ memFree (vspgrafdat.fronloctab); hdgraphOrderSt (grafptr, cblkptr, paraptr->ordstratlea); /* Order this leaf */ return (0); /* Leaf has been processed */ } vspvnumtab[0] = vspgrafdat.fronloctab + vspgrafdat.complocsize[2]; /* Build vertex lists within frontier array */ vspvnumtab[1] = vspvnumtab[0] + vspgrafdat.complocsize[0]; vspvnumptr0 = vspvnumtab[0]; vspvnumptr1 = vspvnumtab[1]; for (vspvertlocnum = vspgrafdat.s.baseval; vspvertlocnum < vspgrafdat.s.vertlocnnd; vspvertlocnum ++) { /* Fill lists */ GraphPart partval; partval = vspgrafdat.partgsttax[vspvertlocnum]; if (partval == 0) *vspvnumptr0 ++ = vspvertlocnum; else if (partval == 1) *vspvnumptr1 ++ = vspvertlocnum; } memFree (vspgrafdat.partgsttax + vspgrafdat.s.baseval); /* Free useless space */ #ifdef SCOTCH_DEBUG_HDGRAPH2 vspgrafdat.partgsttax = NULL; /* Will cause bug if re-read */ if ((vspvnumptr0 != vspvnumtab[0] + vspgrafdat.complocsize[0]) || (vspvnumptr1 != vspvnumtab[1] + vspgrafdat.complocsize[1])) { errorPrint ("hdgraphOrderNd: internal error (1)"); memFree (vspgrafdat.fronloctab); /* Free useless space */ return (1); } #endif /* SCOTCH_DEBUG_HDGRAPH2 */ cblkptr->typeval = DORDERCBLKNEDI; /* Node becomes a nested dissection node */ o = 0; if (vspgrafdat.compglbsize[2] != 0) { /* If separator not empty */ DorderCblk * cblkptr2; Hdgraph indgrafdat2; cblkptr2 = dorderNew (cblkptr, grafptr->s.proccomm); /* Create separator node */ cblkptr2->ordeglbval = cblkptr->ordeglbval + grafptr->s.vertglbnbr - vspgrafdat.compglbsize[2]; cblkptr2->vnodglbnbr = vspgrafdat.compglbsize[2]; cblkptr2->cblkfthnum = 2; cblkptr->data.nedi.cblkglbnbr = 3; /* It is a three-cell node */ dgraphInit (&indgrafdat2.s, grafptr->s.proccomm); /* Re-use original graph communicator */ if (dgraphInduceList (&grafptr->s, vspgrafdat.complocsize[2], /* Perform non-halo induction for separator, as it will get highest numbers */ vspgrafdat.fronloctab, &indgrafdat2.s) != 0) { errorPrint ("hdgraphOrderNd: cannot build induced subgraph (1)"); memFree (vspgrafdat.fronloctab); /* Free remaining space */ return (1); } indgrafdat2.vhallocnbr = 0; /* No halo on graph */ indgrafdat2.vhndloctax = indgrafdat2.s.vendloctax; indgrafdat2.ehallocnbr = 0; indgrafdat2.levlnum = 0; /* Separator graph is at level zero not to be suppressed as an intermediate graph */ o = hdgraphOrderSt (&indgrafdat2, cblkptr2, paraptr->ordstratsep); hdgraphExit (&indgrafdat2); dorderDispose (cblkptr2); /* Dispose of separator column block (may be kept as leaf) */ if (o != 0) { memFree (vspgrafdat.fronloctab); /* Free remaining space */ return (1); } } else /* Separator is empty */ cblkptr->data.nedi.cblkglbnbr = 2; /* It is a two-cell tree node */ partmax = (vspgrafdat.compglbsize[0] >= vspgrafdat.compglbsize[1]) ? 0 : 1; /* Get part of largest subgraph */ procnbr0 = (grafptr->s.procglbnbr + 1) / 2; /* Get number of processes in part 0 (always more than in part 1) */ if (grafptr->s.proclocnum < procnbr0) { /* If process will handle part 0 (bigger part if odd number of processes) */ ordeglbval = cblkptr->ordeglbval; vnodglbnbr = vspgrafdat.compglbsize[partmax]; cblkfthnum = 0; } else { /* If process will handle part 1 (smaller part if odd number of processes) */ ordeglbval = cblkptr->ordeglbval + vspgrafdat.compglbsize[partmax]; vnodglbnbr = vspgrafdat.compglbsize[partmax ^ 1]; cblkfthnum = 1; } o = hdgraphOrderNdFold (grafptr, vspgrafdat.complocsize[partmax], vspvnumtab[partmax], vspgrafdat.complocsize[partmax ^ 1], vspvnumtab[partmax ^ 1], &indgrafdat01); if (o == 0) { switch (indgrafdat01.typeval) { case HDGRAPHORDERNDTYPECENT : if ((cblkptr01 = dorderNewSequ (cblkptr)) == NULL) { o = 1; break; } if (grafptr->levlnum > 0) { /* If intermediate level nested dissection graph */ hdgraphExit (grafptr); /* Free graph before going to next level */ dorderDispose (cblkptr); /* Dispose of column block node too */ } cblkptr01->ordeglbval = ordeglbval; cblkptr01->vnodglbnbr = vnodglbnbr; cblkptr01->cblkfthnum = cblkfthnum; o = hdgraphOrderSq2 (&indgrafdat01.data.cgrfdat, cblkptr01, paraptr->ordstratseq); hgraphExit (&indgrafdat01.data.cgrfdat); /* Free centralized graph here as it is last level */ break; /* No need to dispose of final column block as locally created by dorderNewSequ */ #ifdef SCOTCH_DEBUG_HDGRAPH2 case HDGRAPHORDERNDTYPEDIST : #else /* SCOTCH_DEBUG_HDGRAPH2 */ default : #endif /* SCOTCH_DEBUG_HDGRAPH2 */ if ((cblkptr01 = dorderNew (cblkptr, indgrafdat01.data.dgrfdat.s.proccomm)) == NULL) { o = 1; break; } if (grafptr->levlnum > 0) { /* If intermediate level nested dissection graph */ hdgraphExit (grafptr); /* Free graph before going to next level */ dorderDispose (cblkptr); /* Dispose of column block node too */ } cblkptr01->ordeglbval = ordeglbval; cblkptr01->vnodglbnbr = vnodglbnbr; cblkptr01->cblkfthnum = cblkfthnum; o = hdgraphOrderNd (&indgrafdat01.data.dgrfdat, cblkptr01, paraptr); break; #ifdef SCOTCH_DEBUG_HDGRAPH2 default : errorPrint ("hdgraphOrderNd: internal error (2)"); o = 1; #endif /* SCOTCH_DEBUG_HDGRAPH2 */ } } memFree (vspgrafdat.fronloctab); /* Free remaining space */ return (o); } scotch-6.0.4.dfsg/src/libscotch/hmesh_hgraph.h0000644002563400244210000000606711631447171024456 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh_hgraph.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the source halo mesh to source halo **/ /** graph building routine. **/ /** **/ /** DATES : # Version 4.0 : from : 30 nov 2003 **/ /** to 30 nov 2003 **/ /** **/ /************************************************************/ /* ** The defines. */ /** Prime number for cache-friendly perturbations. **/ #define HMESHHGRAPHHASHPRIME 37 /* Prime number */ /* ** The type and structure definitions. */ /*+ A table made of such elements is used during graph building to build the edge array of the graph from the one of the mesh. +*/ typedef struct HmeshHgraphHash_ { Gnum vertnum; /*+ Origin vertex (i.e. pass) number in mesh +*/ Gnum vertend; /*+ End vertex number in mesh +*/ } HmeshHgraphHash; scotch-6.0.4.dfsg/src/libscotch/arch_build.c0000644002563400244210000005031312370202126024067 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : arch_build.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module builds a decomposition- **/ /** based architecture from a source graph. **/ /** **/ /** DATES : # Version 3.2 : from : 29 may 1997 **/ /** to 30 aug 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 3.4 : from : 30 oct 2001 **/ /** to 08 nov 2001 **/ /** # Version 4.0 : from : 29 nov 2003 **/ /** to 10 mar 2005 **/ /** # Version 5.0 : from : 10 sep 2007 **/ /** to 03 apr 2008 **/ /** # Version 5.1 : from : 28 sep 2008 **/ /** to 28 jun 2011 **/ /** # Version 6.0 : from : 28 jun 2011 **/ /** to 05 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define ARCH_BUILD #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "arch.h" #include "arch_deco.h" #include "arch_vcmplt.h" #include "mapping.h" #include "bgraph.h" #include "bgraph_bipart_st.h" #include "arch_build.h" /************************************/ /* */ /* These routines handle job pools. */ /* */ /************************************/ /* This routine frees the contents of ** the given job pool. ** It returns: ** - VOID : in all cases. */ static void archBuildJobExit ( ArchBuildJob * const jobtab) { ArchBuildJob * jobptr; jobptr = jobtab; do { graphExit (&jobptr->grafdat); jobptr = jobptr->joblink; } while (jobptr != NULL); } /********************************************/ /* */ /* The main routine, which computes the */ /* decomposition-based target architecture. */ /* */ /********************************************/ /* ** This routine builds a target architecture from ** the given source graph and the optional vertex ** list. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int archBuild ( Arch * restrict const tgtarchptr, /*+ Decomposition architecture to build +*/ const Graph * const tgtgrafptr, /*+ Source graph modeling the architecture +*/ const VertList * const tgtlistptr, /*+ Subset of source graph vertices +*/ const Strat * const mapstrat) /*+ Bipartitioning strategy +*/ { Gnum * restrict mapparttax; /* Based access to mapping part array */ Arch archdat; /* Variable-sized architecture for bipartitioning */ ArchDom domsub0; /* Temporary space for subdomain 0 */ Gnum termdomnbr; /* Number of terminal domains */ Gnum termdommax; /* Maximum terminal number */ ArchDecoTermVert * restrict termverttab; /* Terminal vertex table */ Anum * restrict termdisttab; /* Vertex distance table */ ArchBuildDistElem * restrict disttax; /* Distance table */ ArchBuildQueuElem * restrict queutab; /* Distance queue table */ Gnum queuhead; /* Head-of-queue index */ Gnum queutail; /* Tail-of-queue index */ Mapping mappdat; /* Partial and final mapping data */ ArchBuildJob * restrict jobtab; /* Job array */ ArchBuildJob * joblink; /* Linked list of jobs to process */ ArchBuildJob * joborgptr; /* Pointer to original job and first subjob */ ArchBuildJob * jobsubptr; /* Pointer to second subjob */ Bgraph actgrafdat; /* Active graph for bipartitioning */ Gnum invedlosiz; /* Size of inversed edge load array */ Gnum * restrict invedlotax; /* Inversed edge load array for cutting */ Gnum * restrict actfrontab; /* Frontier array for all bipartitionings */ GraphPart * restrict actparttax; /* Part array for all bipartitionings */ GraphPart actpartval; /* Part value to put to subjob */ Gnum actpartnbr; /* Size of part value to put to subjob */ Gnum termdomnum; const Gnum * restrict const tgtverttax = tgtgrafptr->verttax; const Gnum * restrict const tgtvendtax = tgtgrafptr->vendtax; const Gnum * restrict const tgtedgetax = tgtgrafptr->edgetax; const Gnum * restrict const tgtedlotax = tgtgrafptr->edlotax; archInit (tgtarchptr); /* Initialize architecture body */ tgtarchptr->class = archClass ("deco"); /* Set architecture class */ termdomnbr = (tgtlistptr != NULL) ? tgtlistptr->vnumnbr : tgtgrafptr->vertnbr; if (termdomnbr == 0) /* If nothing to do */ return (0); intRandInit (); /* Initialize random generator */ invedlosiz = (tgtedlotax != NULL) ? tgtgrafptr->edgenbr : 0; if ((memAllocGroup ((void **) (void *) &jobtab, (size_t) (termdomnbr * sizeof (ArchBuildJob)), &actfrontab, (size_t) (termdomnbr * sizeof (Gnum)), &actparttax, (size_t) (termdomnbr * sizeof (GraphPart)), &invedlotax, (size_t) (invedlosiz * sizeof (Gnum)), NULL) == NULL) || ((mappdat.parttax = memAlloc (tgtgrafptr->vertnbr * sizeof (ArchDomNum))) == NULL) || /* Final mapping array is for all graph vertices */ ((mappdat.domntab = memAlloc (termdomnbr * sizeof (ArchDom))) == NULL)) { errorPrint ("archBuild: out of memory (1)"); if (jobtab != NULL) { memFree (jobtab); if (mappdat.parttax != NULL) memFree (mappdat.parttax); } return (1); } memSet (mappdat.parttax, 0, termdomnbr * sizeof (ArchDomNum)); actparttax -= tgtgrafptr->baseval; mappdat.flagval = MAPPINGFREEPART | MAPPINGFREEDOMN; mappdat.grafptr = tgtgrafptr; mappdat.archptr = &archdat; mappdat.parttax -= tgtgrafptr->baseval; mappdat.domnmax = termdomnbr; archInit (&archdat); /* Initialize terminal architecture */ archdat.class = archClass ("varcmplt"); /* Set architecture class */ archDomFrst (&archdat, &mappdat.domntab[0]); /* Get initial domain */ mappdat.domnnbr = 1; jobtab[0].domnum = 0; /* All vertices mapped to first domain */ if ((tgtlistptr != NULL) && (tgtlistptr->vnumtab != NULL)) /* If vertex list given */ graphInduceList (tgtgrafptr, tgtlistptr, &jobtab[0].grafdat); /* Restrict initial job */ else { /* If no vertex list given */ memCpy (&jobtab[0].grafdat, tgtgrafptr, sizeof (Graph)); /* Job takes whole graph */ jobtab[0].grafdat.flagval &= ~GRAPHFREETABS; /* Graph is a clone */ jobtab[0].grafdat.vnumtax = NULL; /* Assume we have no vertex index array */ } if (tgtedlotax != NULL) { /* If architecture graph has edge loads */ Gnum vertnum; Gnum vertnnd; Gnum edlomin; Gnum edlomax; float prodval; const Gnum * restrict const indverttax = jobtab[0].grafdat.verttax; const Gnum * restrict const indvendtax = jobtab[0].grafdat.vendtax; const Gnum * restrict const indedlotax = jobtab[0].grafdat.edlotax; /* Point to possibly induced original edge array */ invedlotax -= tgtgrafptr->baseval; /* Base inversed edge load array */ edlomin = GNUMMAX; edlomax = 1; for (vertnum = jobtab[0].grafdat.baseval, vertnnd = jobtab[0].grafdat.vertnnd; /* Handle non-compact graphs as well as compact graphs */ vertnum < vertnnd; vertnum ++) { Gnum edgenum; Gnum edgennd; for (edgenum = indverttax[vertnum], edgennd = indvendtax[vertnum]; edgenum < edgennd; edgenum ++) { Gnum edloval; edloval = indedlotax[edgenum]; if (edloval < edlomin) edlomin = edloval; if (edloval > edlomax) edlomax = edloval; } } prodval = (float) edlomin * (float) edlomax; for (vertnum = jobtab[0].grafdat.baseval; vertnum < vertnnd; vertnum ++) { Gnum edgenum; Gnum edgennd; for (edgenum = indverttax[vertnum], edgennd = indvendtax[vertnum]; edgenum < edgennd; edgenum ++) { Gnum edloval; edloval = indedlotax[edgenum]; if (edloval == edlomin) edloval = edlomax; else if (edloval == edlomax) edloval = edlomin; else edloval = (Gnum) (prodval / (float) edloval + 0.49F); #ifdef SCOTCH_DEBUG_ARCH2 if ((edloval < edlomin) || (edloval > edlomax)) { errorPrint ("archBuild: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_ARCH2 */ invedlotax[edgenum] = edloval; /* Write inversed cost in working array */ } } jobtab[0].grafdat.edlotax = invedlotax; /* Replace potentially induced edge array with inversed one */ } /* Edge array will be freed along with jobtab group leader */ mapparttax = mappdat.parttax; actgrafdat.veextax = NULL; /* No external gain array */ actgrafdat.parttax = actparttax; /* Set global auxiliary arrays */ actgrafdat.frontab = actfrontab; joblink = NULL; /* Initialize job list */ if (jobtab[0].grafdat.vertnbr > 1) { /* If job is worth bipartitioning */ jobtab[0].joblink = joblink; /* Add initial job to list */ joblink = &jobtab[0]; } while (joblink != NULL) { /* For all jobs in list */ joborgptr = joblink; /* Get job */ joblink = joblink->joblink; /* Remove job from list */ joborgptr->joblink = NULL; /* In case of freeing */ memCpy (&actgrafdat.s, &joborgptr->grafdat, sizeof (Graph)); actgrafdat.s.flagval = joborgptr->grafdat.flagval & ~GRAPHFREETABS; bgraphInit2 (&actgrafdat, 1, 1, 1, 0, 0); /* Create active graph */ if (bgraphBipartSt (&actgrafdat, mapstrat) != 0) { /* Perform bipartitioning */ errorPrint ("archBuild: internal error (2)"); archBuildJobExit (joborgptr); archBuildJobExit (joblink); archExit (&archdat); mapExit (&mappdat); memFree (jobtab); return (1); } if ((actgrafdat.compsize0 == 0) || /* If one of the jobs is empty */ (actgrafdat.compsize0 == actgrafdat.s.vertnbr)) { errorPrint ("archBuild: strategy leads to empty domains"); graphExit (&actgrafdat.s); /* Only free graph part, global arrays kept */ archBuildJobExit (joborgptr); archBuildJobExit (joblink); archExit (&archdat); mapExit (&mappdat); memFree (jobtab); return (1); } archVcmpltDomBipart ((const ArchVcmplt * const) (void *) &archdat, /* Update mapping domains */ (const ArchVcmpltDom * const) (void *) &mappdat.domntab[joborgptr->domnum], (ArchVcmpltDom * const) (void *) &domsub0, (ArchVcmpltDom * const) (void *) &mappdat.domntab[mappdat.domnnbr]); mappdat.domntab[joborgptr->domnum] = domsub0; actpartval = actgrafdat.parttax[actgrafdat.s.baseval]; /* Always keep first vertex in sub0 */ actpartnbr = (actpartval == 0) ? actgrafdat.compsize0 : (actgrafdat.s.vertnbr - actgrafdat.compsize0); if (actgrafdat.s.vnumtax != NULL) { /* Update mapping fraction */ Gnum actvertnum; for (actvertnum = actgrafdat.s.baseval; actvertnum < actgrafdat.s.vertnnd; actvertnum ++) { if (actgrafdat.parttax[actvertnum] != actpartval) mappdat.parttax[actgrafdat.s.vnumtax[actvertnum]] = mappdat.domnnbr; } } else { Gnum actvertnum; for (actvertnum = actgrafdat.s.baseval; actvertnum < actgrafdat.s.vertnnd; actvertnum ++) { if (actgrafdat.parttax[actvertnum] != actpartval) mappdat.parttax[actvertnum] = mappdat.domnnbr; } } jobsubptr = jobtab + mappdat.domnnbr; /* Point to new subjob */ jobsubptr->domnum = mappdat.domnnbr ++; /* Build subjobs */ actgrafdat.s.flagval = joborgptr->grafdat.flagval; /* Active is now main copy */ if (actpartnbr < (actgrafdat.s.vertnbr - 1)) { /* If part 1 splittable */ graphInducePart (&actgrafdat.s, actgrafdat.parttax, actgrafdat.s.vertnbr - actpartnbr, 1 - actpartval, &jobsubptr->grafdat); jobsubptr->joblink = joblink; /* Link subjobs in list */ joblink = jobsubptr; } if (actpartnbr > 1) { /* If part 0 splittable */ graphInducePart (&actgrafdat.s, actgrafdat.parttax, actpartnbr, actpartval, &joborgptr->grafdat); joborgptr->joblink = joblink; /* Link subjobs in list */ joblink = joborgptr; } graphExit (&actgrafdat.s); /* Only free graph part, global arrays kept */ } memFree (jobtab); /* Free group leader */ if (memAllocGroup ((void **) (void *) &termverttab, (size_t) (termdomnbr * sizeof (ArchDecoTermVert)), &termdisttab, (size_t) (((termdomnbr * (termdomnbr - 1)) / 2) * sizeof (Anum)), &disttax, (size_t) (tgtgrafptr->vertnbr * sizeof (ArchBuildDistElem)), &queutab, (size_t) (tgtgrafptr->vertnbr * sizeof (ArchBuildQueuElem)), NULL) == NULL) { errorPrint ("archBuild: out of memory (2)"); mapExit (&mappdat); archExit (&archdat); return (1); } for (termdomnum = 0, termdommax = 0; termdomnum < termdomnbr; termdomnum ++) { /* Set terminal vertex array */ Gnum tgtvertnum; tgtvertnum = (tgtlistptr != NULL) ? tgtlistptr->vnumtab[termdomnum] : (termdomnum + tgtgrafptr->baseval); termverttab[termdomnum].labl = tgtvertnum; termverttab[termdomnum].wght = (tgtgrafptr->velotax != NULL) ? tgtgrafptr->velotax[tgtvertnum] : 1; termverttab[termdomnum].num = archDomNum (&archdat, mapDomain (&mappdat, tgtvertnum - tgtgrafptr->baseval)); if (termverttab[termdomnum].num > termdommax) /* Find maximum terminal number */ termdommax = termverttab[termdomnum].num; } disttax -= tgtgrafptr->baseval; for (termdomnum = 1; termdomnum < termdomnbr; termdomnum ++) { /* For all active terminal vertices except the first */ Gnum termdomend; Gnum tgtvertnum; for (tgtvertnum = tgtgrafptr->baseval; tgtvertnum < (tgtgrafptr->vertnbr + tgtgrafptr->baseval); tgtvertnum ++) { disttax[tgtvertnum].queued = 0; /* Vertex not queued */ disttax[tgtvertnum].distval = INTVALMAX; /* Assume maximum distance */ } queuhead = /* Reset the queue */ queutail = 0; tgtvertnum = termverttab[termdomnum].labl; queutab[queutail].vertnum = tgtvertnum; /* Insert root vertex */ queutab[queutail ++].distval = 0; disttax[tgtvertnum].queued = 1; /* Mark vertex as queued */ disttax[tgtvertnum].distval = 0; while (queuhead < queutail) { /* As long as there are vertices in queue */ Gnum vertnum; /* Number of current vertex */ Gnum vertdist; /* Current distance value */ Gnum edgenum; vertnum = queutab[queuhead].vertnum; /* Retrieve vertex from queue */ vertdist = queutab[queuhead ++].distval; for (edgenum = tgtverttax[vertnum]; /* For all vertex edges */ edgenum < tgtvendtax[vertnum]; edgenum ++) { Gnum vertend; vertend = tgtedgetax[edgenum]; if (disttax[vertend].queued == 0) { /* If end vertex not queued */ queutab[queutail].vertnum = vertend; /* Queue the vertex */ queutab[queutail ++].distval = disttax[vertend].distval = vertdist + ((tgtedlotax != NULL) ? tgtedlotax[edgenum] : 1); disttax[vertend].queued = 1; /* Mark vertex as queued */ } } } for (termdomend = 0; termdomend < termdomnum; termdomend ++) /* For all previous terminal domains */ termdisttab[((termdomnum * (termdomnum - 1)) / 2) + termdomend] = /* Retrieve distance */ disttax[termverttab[termdomend].labl].distval; } archDecoArchBuild ((ArchDeco *) (void *) &tgtarchptr->data, termdomnbr, termdommax, termverttab, termdisttab); memFree (termverttab); /* Free group leader */ mapExit (&mappdat); archExit (&archdat); return (0); } scotch-6.0.4.dfsg/src/libscotch/gain.h0000644002563400244210000001432011660505571022727 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gain.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the definitions of **/ /** the generic gain tables. **/ /** **/ /** DATES : # Version 0.0 : from : 26 oct 1996 **/ /** to 17 nov 1997 **/ /** # Version 0.1 : from : 10 may 1999 **/ /** to 18 mar 2005 **/ /** # Version 5.0 : from : 24 mar 2008 **/ /** to 01 jun 2008 **/ /** **/ /** NOTES : # Most of the contents of this module **/ /** comes from "map_b_fm" of the SCOTCH **/ /** project. **/ /** **/ /************************************************************/ /* ** The defines. */ #define GAINMAX ((INT) (((UINT) 1 << ((sizeof (INT) << 3) - 1)) - 2)) #define GAIN_LINMAX 1024 /* ** The type and structure definitions. */ /* The gain link data structure. This must be the first item of objects that are linked into gain tables. */ typedef struct GainLink_ { struct GainLink_ * next; /*+ Pointer to next element: FIRST +*/ struct GainLink_ * prev; /*+ Pointer to previous element +*/ struct GainEntr_ * tabl; /*+ Index into the gain table +*/ } GainLink; /* Gain table entry structure. */ typedef struct GainEntr_ { GainLink * next; /*+ Pointer to first element: FIRST +*/ } GainEntr; /* The gain table structure, built from table entries. For trick reasons, the pointer to the first entry must be the first field of the structure. */ typedef struct GainTabl_ { void (* tablAdd) (struct GainTabl_ * const, GainLink * const, const INT); /*+ Add method +*/ INT subbits; /*+ Number of subbits +*/ INT submask; /*+ Subbit mask +*/ INT totsize; /*+ Total table size +*/ GainEntr * tmin; /*+ Non-empty entry of minimum gain +*/ GainEntr * tmax; /*+ Non-empty entry of maximum gain +*/ GainEntr * tend; /*+ Point after last valid gain entry +*/ GainEntr * tabl; /*+ Gain table structure is.. [SIZE - ADJ] +*/ GainEntr tabk[1]; /*+ Split in two for relative access [ADJ] +*/ } GainTabl; /* ** The function prototypes. */ #ifndef GAIN #define static #endif GainTabl * gainTablInit (const INT, const INT); void gainTablExit (GainTabl * const); void gainTablFree (GainTabl * const); void gainTablAddLin (GainTabl * const, GainLink * const, const INT); void gainTablAddLog (GainTabl * const, GainLink * const, const INT); void gainTablDel (GainTabl * const, GainLink * const); GainLink * gainTablFrst (GainTabl * const); GainLink * gainTablNext (GainTabl * const, const GainLink * const); #ifdef SCOTCH_DEBUG_GAIN3 int gainTablCheck (GainEntr * const); static int gainTablCheck2 (GainEntr * const, GainLink * const); #endif /* SCOTCH_DEBUG_GAIN3 */ #undef static /* ** The marco definitions. */ #define gainTablEmpty(tabl) ((tabl)->tmin == (tabl)->tend) #define gainTablAdd(tabl,link,gain) ((tabl)->tablAdd ((tabl), (link), (gain))) #if ((! defined GAIN) && (! defined SCOTCH_DEBUG_GAIN1)) #define gainTablDel(tabl,link) (((GainLink *) (link))->next->prev = ((GainLink *) (link))->prev, \ ((GainLink *) (link))->prev->next = ((GainLink *) (link))->next) #endif /* ((! defined GAIN) && (! defined SCOTCH_DEBUG_GAIN1)) */ scotch-6.0.4.dfsg/src/libscotch/hall_order_hx.c0000644002563400244210000003635511631447170024630 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hall_order_hx.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains service routines **/ /** for interfacing the halo ordering **/ /** routines provided by Patrick Amestoy **/ /** with the ones of libScotch. **/ /** **/ /** DATES : # Version 4.0 : from : 13 jan 2003 **/ /** to : 28 dec 2004 **/ /** # Version 5.0 : from : 25 jul 2007 **/ /** to : 29 may 2008 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HALL_ORDER_HX #include "module.h" #include "common.h" #include "graph.h" #include "order.h" #include "hgraph.h" #include "hall_order_hx.h" /*********************/ /* */ /* Service routines. */ /* */ /*********************/ /* This routine post-processes the elimination tree ** produced by Amestoy's halo ordering routines. ** On input, the elimination tree is described by ** nvtab and petab. ** On output, we build an un-based elimination tree ** (that is, based to 0), structured as follows: ** - cblknbr : number of column blocks (that is, ** principal variables). ** - sizetab : sizetab[i] holds the total number of ** variables (principal and secondary) if i is ** a principal variable, or ~0 if i is a secondary ** variable or in halo. (sizetab = lentab) ** - petab : petab[i] holds the father of principal ** variable i, or ~0 if i is a root. ** - frsttab : when i is a principal variable, ** frsttab[i] holds the number of the first principal ** son variable of principal variable i, or ~0 if none. ** If i is a secondary variable or in halo, frsttab[i] ** holds ~0 too. ** - nexttab : linked list of principal son variables. ** When i is a principal variable, j=frsttab[i] is ** its first son (if any), and k=nexttab[j] is the ** second son, and l=nexttab[k] is its third son, and ** so on, or ~0 if none. ** - secntab : linked list of secondary variables. ** When i is a principal variable, secntab[i] holds ** the number of the first secondary variable of ** principal variable i, or ~0 if none. When i is ** a secondary variable, secntab[i] holds the next ** secondary variable in linked list, or ~0 if none. ** It returns: ** - 0 : if data structures have been initialized. ** - !0 : on error. */ int hallOrderHxBuild ( const Gnum baseval, /*+ Base value of graph and permutation +*/ const Gnum vertnbr, /*+ Number of vertices in considered graph +*/ const Gnum vnohnbr, /*+ Number of non-halo vertices in considered graph +*/ const Gnum * restrict const vnumtax, /*+ Vertex number array of subgraph, if subgraph +*/ Order * restrict const ordeptr, /*+ Ordering to update +*/ OrderCblk * restrict const cblkptr, /*+ Multiple column-block of ordering +*/ Gnum * restrict const nvartax, Gnum * restrict const sizetax, Gnum * restrict const fathtax, /*+ Was petab +*/ Gnum * restrict const frsttax, Gnum * restrict const nexttax, Gnum * restrict const secntax, Gnum * restrict const desctax, /*+ Was iwtab +*/ Gnum * restrict const permtax, /*+ Based direct permutation array +*/ Gnum * restrict const peritab, /*+ Un-based inverse permutation array +*/ Gnum * restrict const leaftab, /*+ Un-based array for storage of leaves +*/ const Gnum colmin, const Gnum colmax, const float fillrat) { Gnum vnohnnd; Gnum cblknbr; Gnum cblknum; Gnum leafnbr; Gnum leafnum; Gnum rootnum; Gnum ordetmp; Gnum i, j, k; memSet (desctax + baseval, 0, vertnbr * sizeof (Gnum)); memSet (sizetax + baseval, 0, vertnbr * sizeof (Gnum)); memSet (frsttax + baseval, ~0, vertnbr * sizeof (Gnum)); memSet (secntax + baseval, ~0, vertnbr * sizeof (Gnum)); vnohnnd = vnohnbr + baseval; #ifdef SCOTCH_DEBUG_ORDER2 for (i = baseval; i < vnohnnd; i ++) { if ((fathtax[i] > 0) || (fathtax[i] < - vertnbr)) { errorPrint ("hallOrderHxBuild: elimination tree out of bounds"); return (1); } } #endif /* SCOTCH_DEBUG_ORDER2 */ for (i = baseval, cblknbr = 0, rootnum = ~0; /* Assume no root found yet */ i < vnohnnd; i ++) { if (nvartax[i] != 0) { /* If principal variable */ cblknbr ++; /* One more column block */ sizetax[i] ++; /* One more column */ if ((fathtax[i] < 0) && /* If not root of tree */ (fathtax[i] > - (vnohnbr + 1))) { /* And father not in halo */ fathtax[i] = baseval - (fathtax[i] + 1); /* Re-base father number */ nexttax[i] = frsttax[fathtax[i]]; /* Link vertex to tree */ frsttax[fathtax[i]] = i; /* Variable is first son */ desctax[fathtax[i]] ++; /* Father has one more son */ } else { fathtax[i] = ~0; /* Father is (pseudo-)root */ rootnum = i; /* Record (last) root */ } } else { /* If secondary variable */ fathtax[i] = baseval - (fathtax[i] + 1); /* Re-base father number */ if (fathtax[i] >= vnohnnd) { /* If father in halo */ if (frsttax[fathtax[i]] == ~0) { /* If first such vertex */ cblknbr ++; /* One more column block */ sizetax[i] = 1; /* One more column */ nvartax[i] = 1; /* Make it principal */ frsttax[fathtax[i]] = i; /* Record it as root */ fathtax[i] = ~0; /* Make it (pseudo-)root */ rootnum = i; /* Record (last) root */ continue; /* Skip to next vertex */ } else { fathtax[i] = frsttax[fathtax[i]]; /* Get first such vertex as root */ nvartax[fathtax[i]] ++; /* Record us as secondary variable */ } } sizetax[fathtax[i]] ++; /* One more column */ secntax[i] = secntax[fathtax[i]]; /* Link secondary variable */ secntax[fathtax[i]] = i; } } for (i = baseval, leafnbr = 0; /* Build leaf list for amalgamation */ i < vnohnnd; i ++) { if ((fathtax[i] != ~0) && /* If node has a father */ (nvartax[i] != 0) && /* And is a principal variable */ (frsttax[i] == ~0)) /* And is a leaf */ leaftab[leafnbr ++] = i; /* Add it to leaf list */ } for (leafnum = 0; leafnum < leafnbr; leafnum ++) { /* As long as candidate leaves exist */ i = leaftab[leafnum]; j = fathtax[i]; if ((sizetax[i] + sizetax[j]) <= colmax) { /* If will not be too large */ if ((sizetax[i] < colmin) || /* If column block too small */ (((float) (2 * sizetax[i]) * (float) (nvartax[j] - nvartax[i] + sizetax[i])) < (float) nvartax[j] * (float) nvartax[j] * fillrat)) { nvartax[j] += sizetax[i]; sizetax[j] += sizetax[i]; nvartax[i] = 0; if (secntax[i] == ~0) /* If node had no secondary variables */ secntax[i] = secntax[j]; /* Make it take the ones of its father */ else if (secntax[j] != ~0) { /* Else if there is something to append */ for (k = secntax[i]; secntax[k] != ~0; k = secntax[k]) ; /* Find last node */ secntax[k] = secntax[j]; /* Append father list to node list */ } secntax[j] = i; /* Now he is a secondary variable of it */ if (frsttax[j] == i) { /* If node is first son of father */ if (frsttax[i] == ~0) /* If node has no sons */ frsttax[j] = nexttax[i]; /* First son is now next node */ else { frsttax[j] = frsttax[i]; for (k = frsttax[i]; nexttax[k] != ~0; k = nexttax[k]) fathtax[k] = j; fathtax[k] = j; nexttax[k] = nexttax[i]; } } else { /* Else unlink node from son chain */ for (k = frsttax[j]; nexttax[k] != i; k = nexttax[k]) ; if (frsttax[i] == ~0) /* If node has no sons */ nexttax[k] = nexttax[i]; else { nexttax[k] = frsttax[i]; for (k = frsttax[i]; nexttax[k] != ~0; k = nexttax[k]) fathtax[k] = j; fathtax[k] = j; nexttax[k] = nexttax[i]; } } cblknbr --; /* One less column block */ } } if (((-- desctax[j]) <= 0) && /* If all descendents processed */ (fathtax[j] != ~0)) /* And node has a father */ leaftab[leafnbr ++] = j; /* Enqueue father */ } #ifdef SCOTCH_DEBUG_ORDER2 memSet (peritab, ~0, vnohnbr * sizeof (Gnum)); #endif /* SCOTCH_DEBUG_ORDER2 */ ordetmp = hallOrderHxTree (frsttax, nexttax, secntax, peritab, 0, rootnum); if (ordetmp < vnohnbr) { /* If not all nodes ordered */ for (i = baseval; i < rootnum; i ++) { /* For all potential remaining roots */ if (fathtax[i] == ~0) /* If node is a pseudo-root */ ordetmp = hallOrderHxTree (frsttax, nexttax, secntax, peritab, ordetmp, i); } } #ifdef SCOTCH_DEBUG_ORDER2 if (ordetmp != vnohnbr) { errorPrint ("hallOrderHxBuild: incomplete elimination tree"); return (1); } memSet (permtax + baseval, ~0, vnohnbr * sizeof (Gnum)); for (i = 0; i < vnohnbr; i ++) { if ((peritab[i] < baseval) || (peritab[i] >= vnohnnd)) { errorPrint ("hallOrderHxBuild: permutation out of bounds"); return (1); } if (permtax[peritab[i]] != ~0) { errorPrint ("hallOrderHxBuild: duplicate permutation index"); return (1); } permtax[peritab[i]] = i; } for (i = baseval; i < vnohnnd; i ++) { if (permtax[i] == ~0) { errorPrint ("hallOrderHxBuild: unused permutation index"); return (1); } } #endif /* SCOTCH_DEBUG_ORDER2 */ if (cblknbr != 1) { /* If more than one column block in the end, create subtree */ if ((cblkptr->cblktab = (OrderCblk *) memAlloc (cblknbr * sizeof (OrderCblk))) == NULL) { errorPrint ("hallOrderHxBuild: out of memory"); return (1); } cblkptr->cblknbr = cblknbr; ordeptr->cblknbr += cblknbr - 1; /* These more column blocks created */ ordeptr->treenbr += cblknbr; /* These more tree nodes created */ for (i = 0, cblknum = 0; i < vnohnbr; i ++) { if (nvartax[peritab[i]] == 0) /* If secondary variable */ continue; /* Skip to next vertex */ cblkptr->cblktab[cblknum].typeval = ORDERCBLKOTHR; /* Build column blocks */ cblkptr->cblktab[cblknum].vnodnbr = sizetax[peritab[i]]; cblkptr->cblktab[cblknum].cblknbr = 0; cblkptr->cblktab[cblknum].cblktab = NULL; cblknum ++; /* One more column block created */ } } if (vnumtax != NULL) { /* If graph is not original graph */ for (i = 0; i < vnohnbr; i ++) /* Finalize inverse permutation */ peritab[i] = vnumtax[peritab[i]]; } return (0); } /*+ This routine computes the inverse *** permutation according to the *** elimination tree. *** It returns: *** - >0 : next index to be used to order, in all cases. +*/ Gnum hallOrderHxTree ( const Gnum * restrict const frsttax, const Gnum * restrict const nexttax, const Gnum * restrict const secntax, Gnum * restrict const peritab, const Gnum ordenum, const Gnum nodenum) { Gnum ordetmp; Gnum nodetmp; ordetmp = ordenum; for (nodetmp = frsttax[nodenum]; nodetmp != ~0; nodetmp = nexttax[nodetmp]) ordetmp = hallOrderHxTree (frsttax, nexttax, secntax, peritab, ordetmp, nodetmp); peritab[ordetmp ++] = nodenum; /* Order principal variable */ for (nodetmp = secntax[nodenum]; nodetmp != ~0; nodetmp = secntax[nodetmp]) { peritab[ordetmp ++] = nodetmp; /* Order secondary variables */ } return (ordetmp); } scotch-6.0.4.dfsg/src/libscotch/dorder.c0000644002563400244210000003036511631447170023270 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dorder.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles distributed **/ /** orderings. **/ /** **/ /** DATES : # Version 5.0 : from : 18 apr 2006 **/ /** to 28 jul 2006 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DORDER #include "module.h" #include "common.h" #include "dgraph.h" #include "dorder.h" /************************************/ /* */ /* These routines handle orderings. */ /* */ /************************************/ /* This routine initializes a distributed ** ordering with respect to the given parameters. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int dorderInit ( Dorder * restrict const ordeptr, const Gnum baseval, const Gnum vnodglbnbr, MPI_Comm proccomm) { ordeptr->baseval = baseval; ordeptr->vnodglbnbr = vnodglbnbr; ordeptr->cblklocnbr = 0; ordeptr->linkdat.nextptr = &ordeptr->linkdat; /* Loop double-chained list */ ordeptr->linkdat.prevptr = &ordeptr->linkdat; MPI_Comm_dup (proccomm, &ordeptr->proccomm); /* Duplicate communicator to avoid lifespan problems */ MPI_Comm_rank (ordeptr->proccomm, &ordeptr->proclocnum); #ifdef SCOTCH_PTHREAD pthread_mutex_init (&ordeptr->mutelocdat, NULL); /* Initialize local mutex */ #endif /* SCOTCH_PTHREAD */ return (0); } /* This routine frees the column blocks ** of the given distributed ordering. ** It returns: ** - void : in all cases. */ static void dorderFreeCblk ( DorderCblk * restrict const cblkptr) { #ifdef SCOTCH_DEBUG_DORDER2 if ((cblkptr->typeval < DORDERCBLKNEDI) || (cblkptr->typeval > (DORDERCBLKNEDI | DORDERCBLKLEAF))) errorPrint ("dorderFreeCblk: invalid column block type"); #endif /* SCOTCH_DEBUG_DORDER2 */ if ((cblkptr->typeval & DORDERCBLKLEAF) != 0) { memFree (cblkptr->data.leaf.periloctab); if (cblkptr->data.leaf.nodeloctab != NULL) memFree (cblkptr->data.leaf.nodeloctab); } memFree (cblkptr); /* Free column block structure */ } void dorderFree ( Dorder * restrict const ordeptr) { DorderCblk * cblkptr; DorderLink * linkptr; for (linkptr = ordeptr->linkdat.nextptr; linkptr != &ordeptr->linkdat; ) { cblkptr = (DorderCblk *) linkptr; /* TRICK: FIRST */ linkptr = linkptr->nextptr; dorderFreeCblk (cblkptr); } ordeptr->linkdat.nextptr = /* Loop double-chained list */ ordeptr->linkdat.prevptr = &ordeptr->linkdat; } /* This routine frees the contents ** of the given ordering. ** It returns: ** - void : in all cases. */ void dorderExit ( Dorder * restrict const ordeptr) { dorderFree (ordeptr); MPI_Comm_free (&ordeptr->proccomm); /* Free duplicated communicator */ #ifdef SCOTCH_PTHREAD pthread_mutex_destroy (&ordeptr->mutelocdat); /* Destroy local mutex */ #endif /* SCOTCH_PTHREAD */ #ifdef SCOTCH_DEBUG_DORDER2 memSet (ordeptr, ~0, sizeof (Dorder)); #endif /* SCOTCH_DEBUG_DORDER2 */ } /* This routine creates the root column ** block slot in the given distributed ** ordering structure. ** It returns: ** - !NULL : root column block. ** - NULL : on error. */ DorderCblk * dorderFrst ( Dorder * const ordeptr) { DorderCblk cblkdat; DorderCblk * cblkptr; cblkdat.ordelocptr = ordeptr; /* Fake father node */ cblkdat.cblknum.proclocnum = 0; /* Belongs to process 0 to ease displacement computations */ cblkdat.cblknum.cblklocnum = -1; if ((cblkptr = dorderNew (&cblkdat, ordeptr->proccomm)) == NULL) return (NULL); cblkptr->ordeglbval = 0; /* Un-based inverse permutation index */ cblkptr->vnodglbnbr = ordeptr->vnodglbnbr; cblkptr->cblkfthnum = 0; return (cblkptr); } /* This routine gives back a new distributed ** column block slot in the same ordering ** structure as the given column block. ** It returns: ** - !NULL : new column block. ** - NULL : on error. */ DorderCblk * dorderNew ( DorderCblk * const cblkptr, /* One of the column blocks */ MPI_Comm proccomm) /* Communicator sharing the block */ { Dorder * restrict ordeptr; DorderCblk * restrict cblknewptr; Gnum reduloctab[3]; Gnum reduglbtab[3]; int proclocnum; MPI_Comm_rank (proccomm, &proclocnum); ordeptr = cblkptr->ordelocptr; reduloctab[1] = /* Assume process is not root for this column block */ reduloctab[2] = 0; if ((cblknewptr = (DorderCblk *) memAlloc (sizeof (DorderCblk))) == NULL) { errorPrint ("dorderNew: out of memory"); reduloctab[0] = 2; /* Indicate error without doubt */ } else { reduloctab[0] = 0; if (proclocnum == 0) { /* If root of sub-tree */ reduloctab[0] = 1; /* Indicate it is the root */ reduloctab[1] = ordeptr->proclocnum; /* Broadcast global rank of block root */ #ifdef SCOTCH_PTHREAD pthread_mutex_lock (&ordeptr->mutelocdat); /* Lock local mutex */ #endif /* SCOTCH_PTHREAD */ reduloctab[2] = ordeptr->cblklocnbr ++; /* One more root block in local ordering */ #ifdef SCOTCH_PTHREAD pthread_mutex_unlock (&ordeptr->mutelocdat); /* Unlock local mutex */ #endif /* SCOTCH_PTHREAD */ } } if (MPI_Allreduce (&reduloctab, &reduglbtab, 3, GNUM_MPI, MPI_SUM, proccomm) != MPI_SUCCESS) { errorPrint ("dorderNew: communication error"); return (NULL); } if (reduglbtab[0] != 1) { errorPrint ("dorderNew: cannot create new node"); if (cblknewptr != NULL) memFree (cblknewptr); return (NULL); } cblknewptr->ordelocptr = ordeptr; cblknewptr->typeval = DORDERCBLKNONE; cblknewptr->fathnum = cblkptr->cblknum; cblknewptr->cblknum.proclocnum = (int) reduglbtab[1]; cblknewptr->cblknum.cblklocnum = reduglbtab[2]; #ifdef SCOTCH_PTHREAD pthread_mutex_lock (&ordeptr->mutelocdat); /* Lock local mutex */ #endif /* SCOTCH_PTHREAD */ cblknewptr->linkdat.nextptr = &ordeptr->linkdat; /* Link new block at end of local ordering node list */ cblknewptr->linkdat.prevptr = ordeptr->linkdat.prevptr; ordeptr->linkdat.prevptr->nextptr = &cblknewptr->linkdat; ordeptr->linkdat.prevptr = &cblknewptr->linkdat; #ifdef SCOTCH_PTHREAD pthread_mutex_unlock (&ordeptr->mutelocdat); /* Unlock local mutex */ #endif /* SCOTCH_PTHREAD */ return (cblknewptr); } /* This routine gives back a new centralized ** column block slot in the same ordering ** structure as the given column block. ** It returns: ** - !NULL : new column block. ** - NULL : on error. */ DorderCblk * dorderNewSequ ( DorderCblk * const cblkptr) /* One of the column blocks */ { Dorder * restrict ordeptr; DorderCblk * restrict cblknewptr; if ((cblknewptr = (DorderCblk *) memAlloc (sizeof (DorderCblk))) == NULL) { errorPrint ("dorderNewSequ: out of memory"); return (NULL); } ordeptr = cblkptr->ordelocptr; cblknewptr->ordelocptr = ordeptr; cblknewptr->typeval = DORDERCBLKNONE; cblknewptr->fathnum = cblkptr->cblknum; cblknewptr->cblknum.proclocnum = ordeptr->proclocnum; /* Node belongs to this process */ #ifdef SCOTCH_PTHREAD pthread_mutex_lock (&ordeptr->mutelocdat); /* Lock local mutex */ #endif /* SCOTCH_PTHREAD */ cblknewptr->cblknum.cblklocnum = ordeptr->cblklocnbr ++; /* One more locally-rooted block in ordering */ cblknewptr->linkdat.nextptr = &ordeptr->linkdat; /* Link new block at end of local ordering node list */ cblknewptr->linkdat.prevptr = ordeptr->linkdat.prevptr; ordeptr->linkdat.prevptr->nextptr = &cblknewptr->linkdat; ordeptr->linkdat.prevptr = &cblknewptr->linkdat; #ifdef SCOTCH_PTHREAD pthread_mutex_unlock (&ordeptr->mutelocdat); /* Unlock local mutex */ #endif /* SCOTCH_PTHREAD */ return (cblknewptr); } /* This routine gives back a new centralized ** index range in the same ordering structure ** as the given column block. ** It returns: ** - !NULL : new column block. ** - NULL : on error. */ Gnum dorderNewSequIndex ( DorderCblk * const cblkptr, /* One of the column blocks */ const Gnum cblknbr) /* Number of indices to reserve */ { Dorder * restrict ordeptr; Gnum cblklocnum; ordeptr = cblkptr->ordelocptr; #ifdef SCOTCH_PTHREAD pthread_mutex_lock (&ordeptr->mutelocdat); /* Lock local mutex */ #endif /* SCOTCH_PTHREAD */ cblklocnum = ordeptr->cblklocnbr; /* Get current local index number */ ordeptr->cblklocnbr += cblknbr; /* These more root blocks in local ordering */ #ifdef SCOTCH_PTHREAD pthread_mutex_unlock (&ordeptr->mutelocdat); /* Unlock local mutex */ #endif /* SCOTCH_PTHREAD */ return (cblklocnum); } /* This routine removes a no longer used ** column block from the given distributed ** ordering. Leaves or locally-rooted column ** blocks are kept, others are removed. ** It returns: ** - void : in all cases. */ void dorderDispose ( DorderCblk * const cblkptr) /* Column block to consider */ { Dorder * restrict ordeptr; ordeptr = cblkptr->ordelocptr; if (cblkptr->cblknum.proclocnum == ordeptr->proclocnum) /* If node is local root of column block, keep it */ return; if ((cblkptr->typeval & DORDERCBLKLEAF) == 0) { /* If node is not non-rooted leaf of distributed ordering */ #ifdef SCOTCH_PTHREAD pthread_mutex_lock (&ordeptr->mutelocdat); /* Lock local mutex */ #endif /* SCOTCH_PTHREAD */ cblkptr->linkdat.nextptr->prevptr = cblkptr->linkdat.prevptr; /* Unchain node from double-chained list */ cblkptr->linkdat.prevptr->nextptr = cblkptr->linkdat.nextptr; #ifdef SCOTCH_PTHREAD pthread_mutex_unlock (&ordeptr->mutelocdat); /* Unlock local mutex */ #endif /* SCOTCH_PTHREAD */ memFree (cblkptr); } } scotch-6.0.4.dfsg/src/libscotch/vgraph_separate_df.h0000644002563400244210000000660011631447170025635 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vgraph_separate_df.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the diffusion vertex separation **/ /** method. **/ /** **/ /** DATES : # Version 5.1 : from : 29 oct 2007 **/ /** to 24 may 2008 **/ /** **/ /************************************************************/ /* ** The defines. */ /* Small non-zero float value. */ #define VGRAPHSEPARATEDFEPSILON (1.0F / (float) (GNUMMAX)) /* ** The type and structure definitions. */ /*+ Method parameters. +*/ typedef struct VgraphSeparateDfParam_ { INT partval; /*+ Part to aggregate to separator +*/ INT movenbr; /*+ Number of moves to do +*/ INT passnbr; /*+ Number of passes to do +*/ double cdifval; /*+ Coefficient of diffused load +*/ double cremval; /*+ Coefficient of remaining load +*/ } VgraphSeparateDfParam; /* ** The function prototypes. */ #ifndef VGRAPH_SEPARATE_DF #define static #endif int vgraphSeparateDf (Vgraph * restrict const, const VgraphSeparateDfParam * restrict const); #undef static scotch-6.0.4.dfsg/src/libscotch/hgraph_order_kp.h0000644002563400244210000000607412037537776025171 0ustar trophimeutilisateurs du domaine/* Copyright 2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hgraph_order_kp.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the k-way partitioning block **/ /** ordering module. **/ /** **/ /** DATES : # Version 6.0 : from : 17 oct 2012 **/ /** to 17 oct 2012 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct HgraphOrderKpParam_ { INT partsiz; /*+ Minimum part size +*/ Strat * strat; /*+ k-way partitioning strategy used +*/ } HgraphOrderKpParam; /* ** The function prototypes. */ #ifndef HGRAPH_ORDER_KP #define static #endif int hgraphOrderKp (const Hgraph * const, Order * const, const Gnum, OrderCblk * const, const HgraphOrderKpParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/mesh_graph.c0000644002563400244210000002232711631447170024125 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2009 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mesh_graph.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the source mesh **/ /** to graph conversion function. **/ /** **/ /** DATES : # Version 4.0 : from : 11 oct 2003 **/ /** to 05 may 2004 **/ /** # Version 5.1 : from : 19 nov 2009 **/ /** to 19 nov 2009 **/ /** **/ /** NOTES : # From a given mesh is created a graph, **/ /** such that all vertices of the graph **/ /** represent the nodes of the mesh, and **/ /** there exists an edge between two **/ /** vertices if there exists at least one **/ /** element to which the two associated **/ /** nodes belong. **/ /** In order to extract mesh vertex **/ /** partitions from graph vertex **/ /** partitions easily, the vertices of **/ /** the graph are numbered in the same **/ /** order as the nodes of the mesh. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define MESH_GRAPH #include "module.h" #include "common.h" #include "graph.h" #include "mesh.h" #include "mesh_graph.h" /*******************************/ /* */ /* The graph building routine. */ /* */ /*******************************/ /* This routine builds a graph from the ** given mesh. ** It returns: ** - 0 : if the graph has been successfully built. ** - 1 : on error. */ int meshGraph ( const Mesh * restrict const meshptr, /*+ Original mesh +*/ Graph * restrict const grafptr) /*+ Graph to build +*/ { Gnum hashnbr; /* Number of vertices in hash table */ Gnum hashsiz; /* Size of hash table */ Gnum hashmsk; /* Mask for access to hash table */ MeshGraphHash * restrict hashtab; /* Table of edges to other node vertices */ Gnum edgemax; /* Upper bound of number of edges in mesh */ Gnum edgennd; /* Based upper bound on number of edges */ Gnum edgenum; /* Number of current graph edge */ Gnum vertnum; /* Number of current graph vertex */ Gnum degrmax; grafptr->flagval = GRAPHFREETABS | GRAPHVERTGROUP | GRAPHEDGEGROUP; grafptr->baseval = meshptr->baseval; grafptr->vertnbr = meshptr->vnodnbr; grafptr->vertnnd = meshptr->vnodnbr + meshptr->baseval; for (hashsiz = 32, hashnbr = meshptr->degrmax * meshptr->degrmax * 2; /* Compute size of hash table */ hashsiz < hashnbr; hashsiz <<= 1) ; hashmsk = hashsiz - 1; if (((grafptr->verttax = memAlloc ((meshptr->vnodnbr + 1) * sizeof (Gnum))) == NULL) || ((hashtab = memAlloc (hashsiz * sizeof (MeshGraphHash))) == NULL)) { errorPrint ("meshGraph: out of memory (1)"); if (grafptr->verttax != NULL) memFree (grafptr->verttax); return (1); } grafptr->verttax -= grafptr->baseval; grafptr->vendtax = grafptr->verttax + 1; if (meshptr->vnlotax != NULL) /* Keep node part of mesh vertex load array as graph vertex load array */ grafptr->velotax = meshptr->vnlotax + meshptr->vnodbas - grafptr->baseval; /* Since GRAPHVERTGROUP, no problem on graphFree */ grafptr->velosum = meshptr->vnlosum; edgemax = 2 * meshptr->edgenbr; /* Compute lower bound on number of edges in graph */ #ifdef SCOTCH_DEBUG_MESH2 edgemax = meshptr->degrmax + 1; /* Allow testing dynamic reallocation of edge array */ #endif /* SCOTCH_DEBUG_MESH2 */ if ((grafptr->edgetax = memAlloc (edgemax * sizeof (Gnum))) == NULL) { errorPrint ("meshGraph: out of memory (2)"); graphFree (grafptr); return (1); } grafptr->edgetax -= grafptr->baseval; memSet (hashtab, ~0, hashsiz * sizeof (MeshGraphHash)); /* Initialize hash table */ for (vertnum = edgenum = grafptr->baseval, edgennd = edgemax + grafptr->baseval, degrmax = 0; /* Build graph edges */ vertnum < grafptr->vertnnd; vertnum ++) { Gnum vnodnum; Gnum hnodnum; Gnum enodnum; grafptr->verttax[vertnum] = edgenum; vnodnum = vertnum + (meshptr->vnodbas - meshptr->baseval); hnodnum = (vnodnum * MESHGRAPHHASHPRIME) & hashmsk; /* Prevent adding loop edge */ hashtab[hnodnum].vertnum = vnodnum; hashtab[hnodnum].vertend = vnodnum; for (enodnum = meshptr->verttax[vnodnum]; enodnum < meshptr->vendtax[vnodnum]; enodnum ++) { Gnum velmnum; Gnum eelmnum; velmnum = meshptr->edgetax[enodnum]; for (eelmnum = meshptr->verttax[velmnum]; eelmnum < meshptr->vendtax[velmnum]; eelmnum ++) { Gnum vnodend; Gnum hnodend; vnodend = meshptr->edgetax[eelmnum]; for (hnodend = (vnodend * MESHGRAPHHASHPRIME) & hashmsk; ; hnodend = (hnodend + 1) & hashmsk) { if (hashtab[hnodend].vertnum != vnodnum) { /* If edge not yet created */ if (edgenum == edgennd) { /* If edge array already full */ Gnum edgemax; Gnum * restrict edgetmp; edgemax = edgennd - grafptr->baseval; /* Increase size by 25 % */ edgemax = edgemax + (edgemax >> 2); if ((edgetmp = memRealloc (grafptr->edgetax + grafptr->baseval, edgemax * sizeof (Gnum))) == NULL) { errorPrint ("meshGraph: out of memory (3)"); graphFree (grafptr); memFree (hashtab); return (1); } grafptr->edgetax = edgetmp - grafptr->baseval; edgennd = edgemax + grafptr->baseval; } hashtab[hnodend].vertnum = vnodnum; /* Record new edge */ hashtab[hnodend].vertend = vnodend; grafptr->edgetax[edgenum ++] = vnodend - (meshptr->vnodbas - grafptr->baseval); /* Build new edge */ break; } if (hashtab[hnodend].vertend == vnodend) /* If edge already exists */ break; /* Skip to next neighbor */ } } } if ((edgenum - grafptr->verttax[vertnum]) > degrmax) /* Compute maximum degree */ degrmax = (edgenum - grafptr->verttax[vertnum]); } grafptr->verttax[vertnum] = edgenum; /* Set end of vertex array */ grafptr->edgenbr = edgenum - grafptr->baseval; grafptr->degrmax = degrmax; #ifdef SCOTCH_DEBUG_MESH2 if (graphCheck (grafptr) != 0) { errorPrint ("meshGraph: internal error"); return (1); } #endif /* SCOTCH_DEBUG_MESH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/dummysizes.c0000644002563400244210000002700212473140023024204 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007-2010,2012,2014 Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dummysizes.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of the libScotch compilation job. **/ /** This small program processes files that **/ /** are in fact pattern header files for **/ /** the libScotch library, and replaces **/ /** symbolic sizes of the opaque libScotch **/ /** by the proper integer values according **/ /** to the machine on which it is run. **/ /** **/ /** DATES : # Version 3.4 : from : 22 oct 2001 **/ /** to : 22 nov 2001 **/ /** # Version 4.0 : from : 25 nov 2001 **/ /** to : 06 jan 2006 **/ /** # Version 5.0 : from : 26 apr 2006 **/ /** to : 03 apr 2008 **/ /** # Version 5.1 : from : 16 jun 2008 **/ /** to : 15 aug 2010 **/ /** # Version 6.0 : from : 01 dec 2012 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DUMMYSIZES #define CHARMAX 2048 /* Maximum line size */ #define SUBSMAX 48 /* Maximum number of substitutions */ #define C_FILENBR 2 /* Number of files in list */ #define C_FILEARGNBR 2 /* Number of files which can be arguments */ #define C_filenamehedinp C_fileTab[0].nameptr /* Source graph input file name */ #define C_filenamehedout C_fileTab[1].nameptr /* Statistics output file name */ #define C_filepntrhedinp C_fileTab[0].fileptr /* Source graph input file */ #define C_filepntrhedout C_fileTab[1].fileptr /* Statistics output file */ #define EXPAND(s) EXPANDTWO(s) #define EXPANDTWO(s) #s #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "geom.h" #include "mesh.h" #include "arch.h" #include "mapping.h" #include "order.h" #ifdef SCOTCH_PTSCOTCH #include "dgraph.h" #include "dgraph_halo.h" #include "dmapping.h" #include "dorder.h" #include "library_dmapping.h" #endif /* SCOTCH_PTSCOTCH */ #include "library_mapping.h" #include "library_order.h" /* ** The static definitions. */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[C_FILENBR] = { /* The file array */ { "r" }, { "w" } }; /******************************/ /* */ /* This is the main function. */ /* */ /******************************/ void subsFill ( char * substab[2], char * origptr, int subsval) { char * subsptr; subsptr = malloc (32 * sizeof (char)); sprintf (subsptr, "%d", (int) ((subsval + sizeof (double) - 1) / sizeof (double))); substab[0] = origptr; substab[1] = subsptr; } /******************************/ /* */ /* This is the main function. */ /* */ /******************************/ int main ( int argc, char * argv[]) { char chartab[CHARMAX]; char chartmp[CHARMAX]; char * substab[SUBSMAX][2]; /* Substitution array */ int subsnbr; int i; if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ printf ("Usage is:\ndummysizes [ []]\n"); return (((argv[1][0] == '?') && argv[1][1] == '\0') ? 0 : 1); } for (i = 0; i < C_FILENBR; i ++) /* Set default stream pointers */ C_fileTab[i].fileptr = (C_fileTab[i].modeptr[0] == 'r') ? stdin : stdout; for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '+') && /* If found a file name */ ((argv[i][0] != '-') || (argv[i][1] == '\0'))) { if (C_fileNum < C_FILEARGNBR) /* A file name has been given */ C_fileTab[C_fileNum ++].nameptr = argv[i]; else { fprintf (stderr, "dummysizes: ERROR: main: too many file names given"); exit (1); } } else { /* If found an option name */ switch (argv[i][1]) { case 'H' : /* Give the usage message */ case 'h' : printf ("Usage is:\ndummysizes [ []]\n"); exit (0); case 'V' : fprintf (stderr, "dummysizes, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2004,2007-2010 ENSEIRB, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : fprintf (stderr, "dummysizes: ERROR: main: unprocessed option (\"%s\")", argv[i]); exit (1); } } } for (i = 0; i < C_FILENBR; i ++) { /* For all file names */ if ((C_fileTab[i].nameptr[0] != '-') || /* If not standard stream */ (C_fileTab[i].nameptr[1] != '\0')) { if ((C_fileTab[i].fileptr = fopen (C_fileTab[i].nameptr, C_fileTab[i].modeptr)) == NULL) { /* Open the file */ fprintf (stderr, "dummysizes: ERROR: main: cannot open file (%d)", i); exit (1); } } } #ifdef SCOTCH_PTSCOTCH substab[0][0] = "library_pt.h"; substab[0][1] = "ptscotch.h "; substab[1][0] = "library_pt_f.h"; substab[1][1] = "ptscotchf.h "; #else /* SCOTCH_PTSCOTCH */ substab[0][0] = "library.h"; substab[0][1] = "scotch.h "; substab[1][0] = "library_f.h"; substab[1][1] = "scotchf.h "; #endif /* SCOTCH_PTSCOTCH */ substab[2][0] = "DUMMYIDX"; substab[2][1] = EXPAND (IDX); substab[3][0] = "DUMMYINT"; substab[3][1] = EXPAND (INT); substab[4][0] = "DUMMYMAXINT"; substab[4][1] = EXPAND (INTVALMAX); substab[5][0] = "DUMMYNUMSTRING"; substab[5][1] = "\"" GNUMSTRING "\""; substab[6][0] = "DUMMYVERSION"; substab[6][1] = EXPAND (SCOTCH_VERSION); substab[7][0] = "DUMMYRELEASE"; substab[7][1] = EXPAND (SCOTCH_RELEASE); substab[8][0] = "DUMMYPATCHLEVEL"; substab[8][1] = EXPAND (SCOTCH_PATCHLEVEL); subsnbr = 9; subsFill (substab[subsnbr ++], "DUMMYSIZEARCH", sizeof (Arch)); subsFill (substab[subsnbr ++], "DUMMYSIZEGEOM", sizeof (Geom)); subsFill (substab[subsnbr ++], "DUMMYSIZEGRAPH", sizeof (Graph)); subsFill (substab[subsnbr ++], "DUMMYSIZEMESH", sizeof (Mesh)); subsFill (substab[subsnbr ++], "DUMMYSIZEMAP", sizeof (LibMapping)); subsFill (substab[subsnbr ++], "DUMMYSIZEORDER", sizeof (LibOrder)); subsFill (substab[subsnbr ++], "DUMMYSIZESTRAT", sizeof (Strat *)); #ifdef SCOTCH_PTSCOTCH subsFill (substab[subsnbr ++], "DUMMYSIZEDGRAPHHALOREQ", sizeof (DgraphHaloRequest)); /* TRICK: before DUMMYSIZEDGRAPH */ subsFill (substab[subsnbr ++], "DUMMYSIZEDGRAPH", sizeof (Dgraph)); subsFill (substab[subsnbr ++], "DUMMYSIZEDMAP", sizeof (LibDmapping)); subsFill (substab[subsnbr ++], "DUMMYSIZEDORDER", sizeof (Dorder)); #else /* SCOTCH_PTSCOTCH */ subsFill (substab[subsnbr ++], "DUMMYSIZEDGRAPHHALOREQ", 1); /* TRICK: before DUMMYSIZEDGRAPH */ subsFill (substab[subsnbr ++], "DUMMYSIZEDGRAPH", 1); subsFill (substab[subsnbr ++], "DUMMYSIZEDMAP", 1); subsFill (substab[subsnbr ++], "DUMMYSIZEDORDER", 1); #endif /* SCOTCH_PTSCOTCH */ while (fgets (chartab, CHARMAX, C_filepntrhedinp) != NULL) { /* Infinite loop on file lines */ int charnbr; int subsnum; if (((charnbr = strlen (chartab)) >= (CHARMAX - 1)) && /* If line read is at least as long as maximum size */ (chartab[CHARMAX - 1] != '\n')) { /* And last character is not a newline, that is, some is missing */ fprintf (stderr, "dummysizes: ERROR: line too long\n"); exit (1); } for (subsnum = 0; subsnum < subsnbr; subsnum ++) { /* Perform substitutions */ char * charptr; /* Place where token found */ while ((charptr = strstr (chartab, substab[subsnum][0])) != NULL) { /* As long as substitution can be performed */ int charnbr; int charnum; charnum = charptr - chartab; /* Position where token found */ charnbr = strlen (substab[subsnum][0]); /* Length of token */ strcpy (chartmp, charptr + charnbr); /* Save end of line */ sprintf (charptr, "%s%s", substab[subsnum][1], chartmp); /* Replace end of line with substituted token */ } } fputs (chartab, C_filepntrhedout); /* Output possibly updated line */ } #ifdef SCOTCH_DEBUG_MAIN1 for (i = 0; i < C_FILENBR; i ++) { /* For all file names */ if ((C_fileTab[i].name[0] != '-') || /* If not standard stream */ (C_fileTab[i].name[1] != '\0')) { fclose (C_fileTab[i].pntr); /* Close the stream */ } } #endif /* SCOTCH_DEBUG_MAIN1 */ exit (0); } scotch-6.0.4.dfsg/src/libscotch/graph.c0000644002563400244210000001524412371367346023121 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2011,2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : graph.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles the source graph **/ /** functions. **/ /** **/ /** DATES : # Version 0.0 : from : 01 dec 1992 **/ /** to 18 may 1993 **/ /** # Version 1.3 : from : 30 apr 1994 **/ /** to 18 may 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to 31 oct 1994 **/ /** # Version 3.0 : from : 07 jul 1995 **/ /** to 28 sep 1995 **/ /** # Version 3.1 : from : 28 nov 1995 **/ /** to 08 jun 1996 **/ /** # Version 3.2 : from : 07 sep 1996 **/ /** to 15 sep 1998 **/ /** # Version 3.3 : from : 22 sep 1998 **/ /** to 31 dec 1998 **/ /** # Version 4.0 : from : 24 nov 2001 **/ /** to 22 apr 2004 **/ /** # Version 5.1 : from : 08 mar 2011 **/ /** to 08 mar 2011 **/ /** # Version 6.0 : from : 09 sep 2012 **/ /** to 09 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GRAPH #include "module.h" #include "common.h" #include "graph.h" /****************************************/ /* */ /* These routines handle source graphs. */ /* */ /****************************************/ /* This routine initializes a source graph ** structure. ** It returns: ** - 0 : in all cases. */ int graphInit ( Graph * const grafptr) { memSet (grafptr, 0, sizeof (Graph)); /* Initialize graph fields */ grafptr->flagval = GRAPHFREETABS; /* By default, free all arrays */ return (0); } /* This routine frees a source graph structure. ** It returns: ** - VOID : in all cases. */ void graphExit ( Graph * const grafptr) { graphFree (grafptr); /* Free graph data */ #ifdef SCOTCH_DEBUG_GRAPH2 memSet (grafptr, ~0, sizeof (Graph)); /* Purge graph fields */ #endif /* SCOTCH_DEBUG_GRAPH2 */ } /* This routine frees the graph data. ** It returns: ** - VOID : in all cases. */ void graphFree ( Graph * const grafptr) { if (((grafptr->flagval & GRAPHFREEEDGE) != 0) && /* If edgetab must be freed */ (grafptr->edgetax != NULL)) /* And if it exists */ memFree (grafptr->edgetax + grafptr->baseval); /* Free it */ if ((grafptr->flagval & GRAPHFREEVERT) != 0) { /* If verttab/vendtab must be freed */ if ((grafptr->vendtax != NULL) && /* If vendtax is distinct from verttab */ (grafptr->vendtax != grafptr->verttax + 1) && /* (if vertex arrays grouped, vendtab not distinct anyway) */ ((grafptr->flagval & GRAPHVERTGROUP) == 0)) memFree (grafptr->vendtax + grafptr->baseval); /* Then free vendtax */ if (grafptr->verttax != NULL) /* Free verttab anyway, as it is the array group leader */ memFree (grafptr->verttax + grafptr->baseval); } if ((grafptr->flagval & GRAPHFREEVNUM) != 0) { /* If vnumtab must be freed */ if ((grafptr->vnumtax != NULL) && /* And is not in vertex array group */ ((grafptr->flagval & GRAPHVERTGROUP) == 0)) memFree (grafptr->vnumtax + grafptr->baseval); } if ((grafptr->flagval & GRAPHFREEOTHR) != 0) { /* If other arrays must be freed */ if ((grafptr->velotax != NULL) && /* Free graph tables */ ((grafptr->flagval & GRAPHVERTGROUP) == 0)) memFree (grafptr->velotax + grafptr->baseval); if ((grafptr->vlbltax != NULL) && ((grafptr->flagval & GRAPHVERTGROUP) == 0)) memFree (grafptr->vlbltax + grafptr->baseval); if ((grafptr->edlotax != NULL) && ((grafptr->flagval & GRAPHEDGEGROUP) == 0)) memFree (grafptr->edlotax + grafptr->baseval); } #ifdef SCOTCH_DEBUG_GRAPH2 memSet (grafptr, ~0, sizeof (Graph)); /* Purge graph fields */ #endif /* SCOTCH_DEBUG_GRAPH2 */ grafptr->flagval = GRAPHNONE; /* Allow to double-call graphFree or call graphExit */ } scotch-6.0.4.dfsg/src/libscotch/library_version_f.c0000644002563400244210000000622511631447170025525 0ustar trophimeutilisateurs du domaine/* Copyright 2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_version_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API for **/ /** handling API- and version-related **/ /** routines in the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.1 : from : 16 nov 2010 **/ /** to 16 nov 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the version-related routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFVERSION, scotchfversion, ( \ int * const versptr, \ int * const relaptr, \ int * const patcptr), \ (versptr, relaptr, patcptr)) { SCOTCH_version (versptr, relaptr, patcptr); } scotch-6.0.4.dfsg/src/libscotch/library_mesh_io_habo_f.c0000644002563400244210000001207411631447170026453 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_mesh_io_habo_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the Fortran API for the **/ /** mesh i/o routines of the libSCOTCH **/ /** library. **/ /** **/ /** DATES : # Version 4.0 : from : 24 nov 2005 **/ /** to 24 nov 2005 **/ /** # Version 5.1 : from : 27 mar 2010 **/ /** to 27 mar 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the mapping routines. */ /* */ /**************************************/ /* String lengths are passed at the very ** end of the argument list. */ FORTRAN ( \ SCOTCHFMESHGEOMLOADHABO, scotchfmeshgeomloadhabo, ( \ SCOTCH_Mesh * const meshptr, \ SCOTCH_Geom * const geomptr, \ const int * const filegrfptr, \ const int * const filegeoptr, \ const char * const dataptr, /* No use */ \ int * const revaptr, \ const int datanbr), \ (meshptr, geomptr, filegrfptr, filegeoptr, dataptr, revaptr, datanbr)) { FILE * filegrfstream; /* Streams to build from handles */ FILE * filegeostream; int filegrfnum; /* Duplicated handle */ int filegeonum; int o; if ((filegrfnum = dup (*filegrfptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFMESHGEOMLOADHABO: cannot duplicate handle (1)"); *revaptr = 1; /* Indicate error */ return; } if ((filegeonum = dup (*filegeoptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFMESHGEOMLOADHABO: cannot duplicate handle (2)"); close (filegrfnum); *revaptr = 1; /* Indicate error */ return; } if ((filegrfstream = fdopen (filegrfnum, "r")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFMESHGEOMLOADHABO: cannot open input stream (1)"); close (filegrfnum); close (filegeonum); *revaptr = 1; return; } if ((filegeostream = fdopen (filegeonum, "r")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFMESHGEOMLOADHABO: cannot open input stream (2)"); fclose (filegrfstream); close (filegeonum); *revaptr = 1; return; } o = SCOTCH_meshGeomLoadHabo (meshptr, geomptr, filegrfstream, filegeostream, NULL); fclose (filegrfstream); /* This closes file descriptors too */ fclose (filegeostream); *revaptr = o; } scotch-6.0.4.dfsg/src/libscotch/bgraph.c0000644002563400244210000002547512376600457023270 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bgraph.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module contains the bipartition **/ /** graph data structure handling **/ /** routines. **/ /** **/ /** DATES : # Version 0.0 : from : 01 dec 1992 **/ /** to 12 may 1993 **/ /** # Version 1.3 : from : 06 apr 1994 **/ /** to 09 apr 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to 01 nov 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to 30 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 15 aug 1995 **/ /** # Version 3.1 : from : 15 nov 1995 **/ /** to 16 nov 1995 **/ /** # Version 3.2 : from : 24 aug 1996 **/ /** to : 14 oct 1997 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 19 oct 1998 **/ /** # Version 4.0 : from : 18 dec 2001 **/ /** to 31 aug 2004 **/ /** # Version 5.0 : from : 17 dec 2006 **/ /** to 10 sep 2007 **/ /** # Version 5.1 : from : 08 oct 2008 **/ /** to 18 mar 2011 **/ /** # Version 6.0 : from : 03 mar 2011 **/ /** to 25 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define BGRAPH #include "module.h" #include "common.h" #include "graph.h" #include "arch.h" #include "mapping.h" #include "bgraph.h" /*************************/ /* */ /* These routines handle */ /* bipartition graphs. */ /* */ /*************************/ /* This routine builds the active graph ** corresponding to the given bipartitioning ** job parameters. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int bgraphInit ( Bgraph * restrict const actgrafptr, /*+ Active graph +*/ const Graph * restrict const srcgrafptr, /*+ Source graph +*/ const Arch * restrict const archptr, /*+ Target architecture +*/ const ArchDom * restrict const domnsubtab, /*+ Array of the two subdomains +*/ const Gnum * restrict const vflowgttab) /*+ Array of vertex weight biases +*/ { Anum domndist; /* Distance between both subdomains */ Anum domnwght0; /* Processor workforce in each domain */ Anum domnwght1; domndist = archDomDist (archptr, &domnsubtab[0], &domnsubtab[1]); /* Get distance between subdomains */ domnwght0 = archDomWght (archptr, &domnsubtab[0]); /* Get weights of subdomains */ domnwght1 = archDomWght (archptr, &domnsubtab[1]); actgrafptr->s = *srcgrafptr; /* Get source graph data */ actgrafptr->s.flagval = ((srcgrafptr->flagval & GRAPHBITSUSED) & ~GRAPHFREETABS) | BGRAPHFREEFRON | BGRAPHFREEPART; /* Graph is a clone with own grouped bipartitioning arrays */ actgrafptr->s.vlbltax = NULL; /* Remove vertex labels */ actgrafptr->veextax = NULL; /* No external gains (yet) */ if (((actgrafptr->parttax = memAlloc (actgrafptr->s.vertnbr * sizeof (GraphPart))) == NULL) || ((actgrafptr->frontab = memAlloc (actgrafptr->s.vertnbr * sizeof (Gnum))) == NULL)) { errorPrint ("bgraphInit: out of memory"); if (actgrafptr->parttax != NULL) memFree (actgrafptr->parttax); return (1); } actgrafptr->parttax -= actgrafptr->s.baseval; bgraphInit2 (actgrafptr, domndist, domnwght0, domnwght1, vflowgttab[0], vflowgttab[1]); #ifdef SCOTCH_DEBUG_BGRAPH2 if (bgraphCheck (actgrafptr) != 0) { errorPrint ("bgraphInit: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_BGRAPH2 */ return (0); } /* This routine fills the internal fields of ** the given active graph. ** It returns: ** - void : in all cases. */ void bgraphInit2 ( Bgraph * restrict const grafptr, /*+ Active graph +*/ const Anum domndist, /*+ Distance between both subdomains +*/ const Anum domnwght0, /*+ Processor workforce in each domain +*/ const Anum domnwght1, const Gnum vfixload0, /*+ Fixed load in each subdomain +*/ const Gnum vfixload1) { grafptr->fronnbr = 0; /* No frontier vertices */ grafptr->compload0min = 0; /* No external constraints on bipartition (yet) */ grafptr->compload0max = grafptr->s.velosum; grafptr->compload0avg = (Gnum) (((double) (grafptr->s.velosum + vfixload0 + vfixload1) * (double) domnwght0) / (double) (domnwght0 + domnwght1)) - vfixload0; grafptr->compload0dlt = grafptr->s.velosum - grafptr->compload0avg; grafptr->compload0 = grafptr->s.velosum; grafptr->compsize0 = grafptr->s.vertnbr; /* Size does not account for fixed vertices */ grafptr->commload = 0; grafptr->commloadextn0 = 0; grafptr->commgainextn = 0; grafptr->commgainextn0 = 0; grafptr->domndist = domndist; grafptr->domnwght[0] = domnwght0; grafptr->domnwght[1] = domnwght1; grafptr->vfixload[0] = vfixload0; grafptr->vfixload[1] = vfixload1; grafptr->bbalval = (double) grafptr->compload0dlt / (double) grafptr->compload0avg; grafptr->levlnum = 0; memSet (grafptr->parttax + grafptr->s.baseval, 0, grafptr->s.vertnbr * sizeof (GraphPart)); /* Set all vertices to part 0 */ } /* This routine frees the contents ** of the given active graph. ** It returns: ** - void : in all cases. */ void bgraphExit ( Bgraph * restrict const grafptr) { if ((grafptr->veextax != NULL) && /* External gain array is private */ ((grafptr->s.flagval & BGRAPHFREEVEEX) != 0)) memFree (grafptr->veextax + grafptr->s.baseval); if ((grafptr->frontab != NULL) && ((grafptr->s.flagval & BGRAPHFREEFRON) != 0)) memFree (grafptr->frontab); if ((grafptr->parttax != NULL) && ((grafptr->s.flagval & BGRAPHFREEPART) != 0)) memFree (grafptr->parttax + grafptr->s.baseval); graphExit (&grafptr->s); /* Free re-allocated arrays of cloned source graph, if any */ #ifdef SCOTCH_DEBUG_BGRAPH2 memSet (grafptr, ~0, sizeof (Bgraph)); #endif /* SCOTCH_DEBUG_BGRAPH2 */ } /* This routine swaps all of the graph ** vertices from one part to another, and ** recomputes the resulting gains. ** It returns: ** - void : in all cases. */ void bgraphSwal ( Bgraph * restrict const grafptr) { Gnum vertnnd; Gnum vertnum; Gnum comploadsum; GraphPart * restrict const parttax = grafptr->parttax; for (vertnum = grafptr->s.baseval, vertnnd = grafptr->s.vertnnd; vertnum < vertnnd; vertnum ++) parttax[vertnum] ^= 1; comploadsum = grafptr->s.velosum + grafptr->vfixload[0] + grafptr->vfixload[1]; /* Overall load sum, including fixed vertex loads */ grafptr->compload0 = comploadsum - grafptr->compload0; grafptr->compload0dlt = comploadsum - grafptr->compload0dlt - 2 * grafptr->compload0avg; grafptr->compsize0 = grafptr->s.vertnbr - grafptr->compsize0; /* Size does not account for fixed vertices */ grafptr->commload += grafptr->commgainextn; grafptr->commgainextn = - grafptr->commgainextn; } /* This routine moves all of the graph ** vertices to the first part, and ** computes the resulting gains. ** It returns: ** - void : in all cases. */ void bgraphZero ( Bgraph * restrict const grafptr) { Gnum compload0; compload0 = grafptr->s.velosum + grafptr->vfixload[0]; grafptr->fronnbr = 0; /* No frontier vertices */ grafptr->compload0dlt = compload0 - grafptr->compload0avg; grafptr->compload0 = compload0; grafptr->compsize0 = grafptr->s.vertnbr; grafptr->commload = grafptr->commloadextn0; /* Initialize communication load */ grafptr->commgainextn = grafptr->commgainextn0; grafptr->bbalval = (double) grafptr->compload0dlt / (double) grafptr->compload0avg; memSet (grafptr->parttax + grafptr->s.baseval, 0, grafptr->s.vertnbr * sizeof (GraphPart)); /* Set all vertices to part 0 */ } scotch-6.0.4.dfsg/src/libscotch/kgraph_map_fm.h0000644002563400244210000002450212026403110024566 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2010-2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph_map_fm.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the k-way Fiduccia-Mattheyses **/ /** mapping algorithm. **/ /** **/ /** DATES : # Version 3.3 : from : 10 may 1999 **/ /** to 20 jun 1999 **/ /** # Version 3.4 : from : 27 sep 1999 **/ /** to 13 nov 1999 **/ /** # Version 5.0 : from : 11 oct 2006 **/ /** to 12 oct 2006 **/ /** # Version 6.0 : from : 03 mar 2011 **/ /** to 19 sep 2012 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ Prime number for hashing vertex numbers. +*/ #define KGRAPHMAPFMHASHPRIME 17 /*+ Prime number for hashing +*/ /*+ Ratio of unused slots before compacting extended edge array. +*/ #define KGRAPHMAPFMEDXXCOMP 5 /*+ Compact if edxunbr > (edxxnbr / KGRAPHMAPFMEDXXCOMP) */ /*+ Save type identifier +*/ #define KGRAPHMAPPFMSAVEVEXX 0 #define KGRAPHMAPPFMSAVEEDXX 1 #define KGRAPHMAPPFMSAVELINK 2 /* Bit value for KGRAPHMAPPFMSAVELINKADD and KGRAPHMAPPFMSAVELINKDEL */ #define KGRAPHMAPPFMSAVELINKDEL 2 #define KGRAPHMAPPFMSAVELINKADD 3 /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct KgraphMapFmParam_ { INT movenbr; /*+ Maximum number of uneffective moves that can be done +*/ INT passnbr; /*+ Number of passes to be performed (-1 : infinite) +*/ double deltval; /*+ Maximum weight imbalance ratio +*/ } KgraphMapFmParam; /*+ The extended edge structure. In fact, this structure does not represent edges, but possible moves in another domain. For trick reasons, the gain table data structure must be the first field of the structure. +*/ #ifdef SCOTCH_TABLE_GAIN typedef GainTabl * KgraphMapFmTabl; typedef GainLink KgraphMapFmLink; #else /* SCOTCH_TABLE_GAIN */ typedef FiboTree KgraphMapFmTabl; typedef FiboNode KgraphMapFmLink; #endif /* SCOTCH_TABLE_GAIN */ typedef struct KgraphMapFmEdge_ { KgraphMapFmLink gainlink; /*+ Gain link; TRICK: FIRST +*/ Gnum commgain; /*+ Communication gain +*/ Gnum cmiggain; /*+ Migration communication gain +*/ Gnum cmigmask; /*+ Migration communication mask +*/ Gnum edlosum; /*+ Sum of edge loads linking to the domain +*/ Gnum edgenbr; /*+ Number of edges linking to the domain +*/ Anum domnnum; /*+ Destination domain index +*/ Anum distval; /*+ Distance between the two domains +*/ Gnum vexxidx; /*+ Index of owner vertex in vertex array +*/ Gnum edxxidx; /*+ Index of next edge in edge array +*/ Gnum mswpnum; /*+ Number of move sweep when data recorded +*/ } KgraphMapFmEdge; /*+ The hash vertex structure. +*/ typedef struct KgraphMapFmVertex_ { struct KgraphMapFmVertex_ * lockptr; /*+ Pointer to next vertex in lock list or NULL; FIRST +*/ Gnum vertnum; /*+ Number of vertex +*/ Gnum cmigload; /*+ Migration communication load +*/ Gnum edlosum; /*+ Sum of edge loads linking to self domain +*/ Gnum edgenbr; /*+ Number of edges linking to self domain +*/ Anum domnnum; /*+ Domain number +*/ ArchDom * domoptr; /*+ Domain in old mapping (for repartitioning) +*/ Gnum veloval; /*+ Vertex load; negative when locked +*/ Gnum edxxidx; /*+ Index of first element in edge array +*/ Gnum mswpnum; /*+ Number of move sweep when data recorded +*/ } KgraphMapFmVertex; /*+ The move recording structures. +*/ typedef struct KgraphMapFmSave_ { Gnum type; union { struct { Gnum vexxidx; /*+ Index of vertex slot in hash table (vexxhab) +*/ Gnum veloval; /*+ Vertex load +*/ Anum domnnum; /*+ Original vertex domain +*/ Gnum commload; /*+ Communication load for current domain +*/ Gnum cmigload; /*+ Migration communication load +*/ Gnum edlosum; /*+ Sum of edge loads linking to self domain +*/ Gnum edgenbr; /*+ Number of edges linking to self domain +*/ } vexxdat; struct { Gnum edxxidx; /*+ Index of edge in edge array +*/ Anum domnnum; /*+ Destination domain index +*/ Anum distval; /*+ Distance between the two domains +*/ Gnum commgain; /*+ Communication gain +*/ Gnum cmiggain; /*+ Migration communication gain +*/ Gnum edlosum; /*+ Sum of edge loads linking to the domain +*/ Gnum edgenbr; /*+ Number of edges linking to the domain +*/ } edxxdat; struct { Gnum edxxidx; /*+ Index of extended vertex or edge +*/ Gnum vexxidx; /*+ Index of vertex slot in hash table (vexxhab) +*/ } linkdat; } u; } KgraphMapFmSave; /* ** The function prototypes. */ #ifndef KGRAPH_MAP_FM #define static #endif int kgraphMapFm (Kgraph * restrict const, const KgraphMapFmParam * const); #undef static /* ** The macro definitions. */ #ifdef SCOTCH_TABLE_GAIN /*+ Gain table subbits. +*/ #define KGRAPHMAPFMSUBBITS 4 /*+ Service routines. +*/ #define kgraphMapFmTablInit(t) (((*(t)) = gainTablInit (GAINMAX, KGRAPHMAPFMSUBBITS)) == NULL) #define kgraphMapFmTablFree(t) gainTablFree (*(t)) #define kgraphMapFmTablExit(t) do { \ if (*(t) != NULL) \ gainTablExit (*(t)); \ } while (0) #define kgraphMapFmTablAdd(t,e) gainTablAdd ((*(t)), &(e)->gainlink, ((e)->commgain + (((e)->cmiggain) & ((e)->cmigmask))) * (e)->distval) #define kgraphMapFmTablDel(t,e) gainTablDel ((*(t)), &(e)->gainlink) #else /* SCOTCH_TABLE_GAIN */ /*+ Service routines. +*/ #define kgraphMapFmTablInit(t) (fiboTreeInit ((t), kgraphMapFmCmpFunc)) #define kgraphMapFmTablFree(t) fiboTreeFree (t) #define kgraphMapFmTablExit(t) fiboTreeExit (t) #define kgraphMapFmTablAdd(t,e) fiboTreeAdd ((t), &(e)->gainlink) #define kgraphMapFmTablDel(t,e) fiboTreeDel ((t), &(e)->gainlink) #endif /* SCOTCH_TABLE_GAIN */ #define kgraphMapFmLock(l,v) do { \ (v)->lockptr = (KgraphMapFmVertex *) (l); \ (l) = (v); \ } while (0) #define kgraphMapFmLockNext(v) ((KgraphMapFmVertex *) (v)->lockptr) scotch-6.0.4.dfsg/src/libscotch/library_dgraph_order_io.c0000644002563400244210000001006612055777375026676 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_order_io.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the distri- **/ /** buted ordering I/O routines of the **/ /** libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 26 jul 2007 **/ /** to 18 oct 2007 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "dgraph.h" #include "dorder.h" #include "ptscotch.h" /************************************/ /* */ /* These routines are the C API for */ /* the distributed ordering */ /* handling routines. */ /* */ /************************************/ /*+ This routine saves to the given stream *** the mapping data associated with the *** given distributed ordering. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_dgraphOrderSaveMap ( const SCOTCH_Dgraph * const grafptr, /*+ Graph to order +*/ const SCOTCH_Dordering * const ordeptr, /*+ Ordering to save +*/ FILE * const stream) /*+ Output stream +*/ { return (dorderSaveMap ((Dorder *) ordeptr, (Dgraph *) grafptr, stream)); } /*+ This routine saves to the given stream *** the separator tree data associated with *** the given distributed ordering. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_dgraphOrderSaveTree ( const SCOTCH_Dgraph * const grafptr, /*+ Graph to order +*/ const SCOTCH_Dordering * const ordeptr, /*+ Ordering to save +*/ FILE * const stream) /*+ Output stream +*/ { return (dorderSaveTree ((Dorder *) ordeptr, (Dgraph *) grafptr, stream)); } scotch-6.0.4.dfsg/src/libscotch/hmesh_mesh.c0000644002563400244210000001536311631447170024132 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh_mesh.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the mesh un- **/ /** haloing routine. **/ /** **/ /** DATES : # Version 4.0 : from : 28 apr 2004 **/ /** to 11 may 2004 **/ /** **/ /** NOTES : # From a given halo mesh is created a **/ /** non-halo mesh. When nodes are **/ /** numbered after elements, halo nodes **/ /** are simply removed. When nodes are **/ /** numbered before elements, halo nodes **/ /** are turned into empty elements such **/ /** that the numbering of vertices **/ /** remains continuous, without holes. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HMESH_MESH #include "module.h" #include "common.h" #include "graph.h" #include "hgraph.h" #include "mesh.h" #include "hmesh.h" /***************************************/ /* */ /* The non-halo mesh building routine. */ /* */ /***************************************/ /* This routine builds a non-halo mesh from ** the given halo mesh. ** It returns: ** - 0 : if the non-halo mesh has been successfully built. ** - 1 : on error. */ int hmeshMesh ( const Hmesh * restrict const hmshptr, /*+ Original halo mesh +*/ Mesh * restrict const meshptr) /*+ Mesh to build +*/ { meshptr->baseval = hmshptr->m.baseval; meshptr->veisnbr = hmshptr->m.veisnbr + hmshptr->veihnbr; /* Add halo isolated elements to isolated elements */ meshptr->vnodnbr = hmshptr->vnohnbr; meshptr->vnodbas = hmshptr->m.vnodbas; meshptr->vnodnnd = hmshptr->vnohnbr + hmshptr->m.vnodbas; meshptr->verttax = hmshptr->m.verttax; meshptr->velotax = hmshptr->m.velotax; meshptr->vnlotax = hmshptr->m.vnlotax; /* Use non-halo part of node vertex load array, if any */ meshptr->velosum = hmshptr->m.velosum; meshptr->vnlosum = hmshptr->vnhlsum; meshptr->vnumtax = hmshptr->m.vnumtax; /* The same for vnumtab */ meshptr->vlbltax = NULL; meshptr->edgenbr = hmshptr->enohnbr; meshptr->edgetax = hmshptr->m.edgetax; meshptr->degrmax = hmshptr->m.degrmax; if (hmshptr->vnohnbr == hmshptr->m.vnodnbr) { /* If halo mesh does not have any halo */ meshptr->flagval = MESHNONE; /* Just create a clone of the original mesh */ meshptr->velmnbr = hmshptr->m.velmnbr; meshptr->velmbas = hmshptr->m.velmbas; meshptr->velmnnd = hmshptr->m.velmnnd; meshptr->vendtax = hmshptr->m.vendtax; return (0); } meshptr->flagval = MESHFREEVEND; if (hmshptr->m.velmbas <= hmshptr->m.vnodbas) { /* If elements numbered before nodes */ if ((meshptr->vendtax = memAlloc ((hmshptr->m.velmnbr + hmshptr->vnohnbr) * sizeof (Gnum))) == NULL) { /* Do not keep halo nodes at end of array */ errorPrint ("hmeshHgraph: out of memory (1)"); return (1); } memCpy (meshptr->vendtax, hmshptr->vehdtax + hmshptr->m.velmbas, hmshptr->m.velmnbr * sizeof (Gnum)); memCpy (meshptr->vendtax + hmshptr->m.velmnbr, hmshptr->m.vendtax + hmshptr->m.vnodbas, hmshptr->vnohnbr * sizeof (Gnum)); meshptr->velmnbr = hmshptr->m.velmnbr; meshptr->velmbas = hmshptr->m.velmbas; meshptr->velmnnd = hmshptr->m.velmnnd; } else { /* If nodes numbered before elements */ if ((meshptr->vendtax = memAlloc ((hmshptr->m.velmnbr + hmshptr->m.vnodnbr) * sizeof (Gnum))) == NULL) { /* Turn halo nodes into empty elements */ errorPrint ("hmeshHgraph: out of memory (2)"); return (1); } memCpy (meshptr->vendtax, hmshptr->m.vendtax + hmshptr->m.baseval, hmshptr->vnohnbr * sizeof (Gnum)); /* Copy non-halo node part */ memCpy (meshptr->vendtax + hmshptr->vnohnbr, hmshptr->m.verttax + hmshptr->vnohnnd, hmshptr->m.vnodnbr - hmshptr->vnohnbr * sizeof (Gnum)); /* Create empty fake element part */ memCpy (meshptr->vendtax + hmshptr->m.vnodnbr, hmshptr->vehdtax + hmshptr->m.velmbas, hmshptr->m.velmnbr * sizeof (Gnum)); meshptr->velmnbr = hmshptr->m.velmnbr + hmshptr->m.vnodnbr - hmshptr->vnohnbr; /* Turn halo node vertices into element vertices */ meshptr->velmbas = hmshptr->vnohnnd; meshptr->velmnnd = hmshptr->m.velmnnd; } meshptr->vendtax -= meshptr->baseval; #ifdef SCOTCH_DEBUG_HMESH2 if (meshCheck (meshptr) != 0) { errorPrint ("hmeshMesh: internal error"); return (1); } #endif /* SCOTCH_DEBUG_HMESH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/hdgraph_order_st.c0000644002563400244210000002547611631447170025336 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hdgraph_order_st.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the generic call to the **/ /** distributed graph ordering module, **/ /** using a given strategy. **/ /** **/ /** DATES : # Version 5.0 : from : 15 apr 2006 **/ /** to 21 aug 2006 **/ /** # Version 5.1 : from : 11 nov 2008 **/ /** to 11 nov 2008 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HDGRAPH_ORDER_ST #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "order.h" #include "hgraph.h" #include "hgraph_order_st.h" #include "dgraph.h" #include "dorder.h" #include "hdgraph.h" #include "hdgraph_order_nd.h" #include "hdgraph_order_si.h" #include "hdgraph_order_sq.h" #include "hdgraph_order_st.h" #include "vdgraph.h" #include "vdgraph_separate_st.h" /* ** The static and global variables. */ static Hdgraph hdgraphorderstgraphdummy; /* Dummy graph for offset computations */ static union { /* Default parameters for nested dissection method */ HdgraphOrderNdParam param; StratNodeMethodData padding; } hdgraphorderstdefaultnd = { { &stratdummy, &stratdummy, &stratdummy } }; static union { /* Default parameters for sequential method */ HdgraphOrderSqParam param; StratNodeMethodData padding; } hdgraphorderstdefaultsq = { { &stratdummy } }; static StratMethodTab hdgraphorderstmethtab[] = { /* Graph ordering methods array */ { HDGRAPHORDERSTMETHND, "n", hdgraphOrderNd, &hdgraphorderstdefaultnd }, { HDGRAPHORDERSTMETHSI, "s", hdgraphOrderSi, NULL }, { HDGRAPHORDERSTMETHSQ, "q", hdgraphOrderSq, &hdgraphorderstdefaultsq }, { -1, NULL, NULL, NULL } }; static StratParamTab hdgraphorderstparatab[] = { /* The method parameter list */ { HDGRAPHORDERSTMETHND, STRATPARAMSTRAT, "sep", (byte *) &hdgraphorderstdefaultnd.param, (byte *) &hdgraphorderstdefaultnd.param.sepstrat, (void *) &vdgraphseparateststratab }, { HDGRAPHORDERSTMETHND, STRATPARAMSTRAT, "ole", (byte *) &hdgraphorderstdefaultnd.param, (byte *) &hdgraphorderstdefaultnd.param.ordstratlea, (void *) &hdgraphorderststratab }, { HDGRAPHORDERSTMETHND, STRATPARAMSTRAT, "ose", (byte *) &hdgraphorderstdefaultnd.param, (byte *) &hdgraphorderstdefaultnd.param.ordstratsep, (void *) &hdgraphorderststratab }, { HDGRAPHORDERSTMETHND, STRATPARAMSTRAT, "osq", (byte *) &hdgraphorderstdefaultnd.param, (byte *) &hdgraphorderstdefaultnd.param.ordstratseq, (void *) &hgraphorderststratab }, { HDGRAPHORDERSTMETHSQ, STRATPARAMSTRAT, "strat", (byte *) &hdgraphorderstdefaultsq.param, (byte *) &hdgraphorderstdefaultsq.param.ordstratseq, (void *) &hgraphorderststratab }, { HDGRAPHORDERSTMETHNBR, STRATPARAMINT, NULL, NULL, NULL, NULL } }; static StratParamTab hdgraphorderstcondtab[] = { /* Graph condition parameter table */ { STRATNODECOND, STRATPARAMINT, "edge", (byte *) &hdgraphorderstgraphdummy, (byte *) &hdgraphorderstgraphdummy.s.edgeglbnbr, NULL }, { STRATNODECOND, STRATPARAMINT, "levl", (byte *) &hdgraphorderstgraphdummy, (byte *) &hdgraphorderstgraphdummy.levlnum, NULL }, { STRATNODECOND, STRATPARAMINT, "load", (byte *) &hdgraphorderstgraphdummy, (byte *) &hdgraphorderstgraphdummy.s.veloglbsum, NULL }, { STRATNODECOND, STRATPARAMDOUBLE, "mdeg", (byte *) &hdgraphorderstgraphdummy, (byte *) &hdgraphorderstgraphdummy.s.degrglbmax, NULL }, { STRATNODECOND, STRATPARAMINT, "proc", (byte *) &hdgraphorderstgraphdummy, (byte *) &hdgraphorderstgraphdummy.s.procglbnbr, NULL }, { STRATNODECOND, STRATPARAMINT, "rank", (byte *) &hdgraphorderstgraphdummy, (byte *) &hdgraphorderstgraphdummy.s.proclocnum, NULL }, { STRATNODECOND, STRATPARAMINT, "vert", (byte *) &hdgraphorderstgraphdummy, (byte *) &hdgraphorderstgraphdummy.s.vertglbnbr, NULL }, { STRATNODENBR, STRATPARAMINT, NULL, NULL, NULL, NULL } }; StratTab hdgraphorderststratab = { /* Strategy tables for graph ordering methods */ hdgraphorderstmethtab, hdgraphorderstparatab, hdgraphorderstcondtab }; /************************************/ /* */ /* This routine is the entry point */ /* for the graph ordering routines. */ /* */ /************************************/ /* This routine computes an ordering ** with respect to a given strategy. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int hdgraphOrderSt ( const Hdgraph * restrict const grafptr, /*+ Subgraph to order +*/ DorderCblk * restrict const cblkptr, /*+ Current column block +*/ const Strat * restrict const strat) /*+ Graph ordering strategy +*/ { StratTest val; int o; if (grafptr->s.vertglbnbr == 0) /* Return immediately if nothing to do */ return (0); o = 0; switch (strat->type) { case STRATNODECONCAT : errorPrint ("hdgraphOrderSt: concatenation operator not available for graph ordering strategies"); return (1); case STRATNODECOND : o = stratTestEval (strat->data.cond.test, &val, (void *) grafptr); /* Evaluate expression */ if (o == 0) { /* If evaluation was correct */ #ifdef SCOTCH_DEBUG_HDGRAPH2 if ((val.typetest != STRATTESTVAL) && (val.typenode != STRATPARAMLOG)) { errorPrint ("hdgraphOrderSt: invalid test result"); o = 1; break; } #endif /* SCOTCH_DEBUG_HDGRAPH2 */ if (val.data.val.vallog == 1) /* If expression is true */ o = hdgraphOrderSt (grafptr, cblkptr, strat->data.cond.strat[0]); /* Apply first strategy */ else { /* Else if expression is false */ if (strat->data.cond.strat[1] != NULL) /* And if there is an else statement */ o = hdgraphOrderSt (grafptr, cblkptr, strat->data.cond.strat[1]); /* Apply second strategy */ } } break; case STRATNODEEMPTY : hdgraphOrderSi (grafptr, cblkptr); /* Always maintain a consistent ordering */ break; case STRATNODESELECT : errorPrint ("hdgraphOrderSt: selection operator not available for graph ordering strategies"); return (1); #ifdef SCOTCH_DEBUG_HDGRAPH2 case STRATNODEMETHOD : #else /* SCOTCH_DEBUG_HDGRAPH2 */ default : #endif /* SCOTCH_DEBUG_HDGRAPH2 */ return (strat->tabl->methtab[strat->data.method.meth].func (grafptr, cblkptr, (void *) &strat->data.method.data)); #ifdef SCOTCH_DEBUG_HDGRAPH2 default : errorPrint ("hdgraphOrderSt: invalid parameter"); return (1); #endif /* SCOTCH_DEBUG_HDGRAPH2 */ } return (o); } scotch-6.0.4.dfsg/src/libscotch/dgraph_ghst.c0000644002563400244210000003740211736622273024307 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2009,2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_ghst.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Francois CHATENET (P0.0) **/ /** Sebastien FOUCAULT (P0.0) **/ /** Nicolas GICQUEL (P0.1) **/ /** Jerome LACOSTE (P0.1) **/ /** **/ /** FUNCTION : Part of a parallel static mapper. **/ /** This module contains the halo building **/ /** routine. **/ /** **/ /** # Version P0.0 : from : 01 apr 1997 **/ /** to 20 jun 1997 **/ /** # Version P0.1 : from : 14 apr 1998 **/ /** to 20 jun 1998 **/ /** # Version 5.0 : from : 28 feb 2006 **/ /** to 10 sep 2007 **/ /** # Version 5.1 : from : 02 jul 2008 **/ /** to 20 feb 2011 **/ /** # Version 6.0 : from : 21 nov 2011 **/ /** to 21 nov 2011 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DGRAPH_GHST #include "module.h" #include "common.h" #include "dgraph.h" #include "dgraph_allreduce.h" #include "dgraph_ghst.h" #include "dgraph_halo.h" /* This routine builds the ghost structures ** required by the halo routines. If flagval ** is set to 0, the ghost edge array is built ** in addition to the local edge array, while ** if flagval is set to 1, the ghost edge array ** replaces the local edge array. This latter ** option is useful to save memory when processing ** intermediate graphs that are not visible to ** the user. ** It returns: ** - 0 : on success. ** - !0 : on error. */ DGRAPHALLREDUCEMAXSUMOP (2, 1) int dgraphGhst2 ( Dgraph * restrict const grafptr, /* Graph structure */ const int flagval) /* Replacement flag */ { int procngbnbr; /* Number of neighboring processes */ int * restrict procsndtab; Gnum procsndnbr; int * restrict procsidtab; /* Send index array */ int procsidnbr; /* Number of entries in send index array */ Gnum vertsidnum; /* Last vertex index in send index array */ Gnum vertlocmin; /* Smallest index of local vertices */ Gnum vertlocmax; /* Largest index of local vertices, + 1 */ Gnum vertlocbas; /* Base index for ghost edge array */ Gnum vertlocnum; /* Current vertex number (based) */ Gnum * restrict vertsidtab; /* Flag array for building procs(i|n)dtab */ Gnum vertgstnum; /* Number of current ghost vertex */ DgraphGhstSort * restrict sortloctab; /* Array for sorting ghost vertices */ Gnum sortlocnbr; /* Number of ghost edges in sort array */ Gnum sortlocnum; Gnum * edgegsttax; /* Pointer to ghost edge array, maybe the same */ Gnum reduloctab[3]; /* Gnum to perform a maxsum operator */ Gnum reduglbtab[3]; int cheklocval; const Gnum * restrict const procvrttab = grafptr->procvrttab; const Gnum * restrict const vertloctax = grafptr->vertloctax; const Gnum * restrict const vendloctax = grafptr->vendloctax; const Gnum * restrict const edgeloctax = grafptr->edgeloctax; /* Pointer to original edgeloctax array */ if ((grafptr->flagval & DGRAPHHASEDGEGST) != 0) /* If ghost edge array already computed, do nothing */ return (0); cheklocval = 0; if (grafptr->edgegsttax == NULL) { /* If ghost edge array not allocated yet */ if ((flagval == 0) || ((grafptr->flagval & DGRAPHFREETABS) == 0)) { /* If no replacement or cannot modify array */ if ((grafptr->edgegsttax = (Gnum *) memAlloc (grafptr->edgelocsiz * sizeof (Gnum))) == NULL) { errorPrint ("dgraphGhst: out of memory (1)"); cheklocval = 1; } else { grafptr->edgegsttax -= grafptr->baseval; grafptr->flagval |= DGRAPHFREEEDGEGST; /* Free array on exit */ } } else { /* Replace edgeloctab by edgegsttab */ grafptr->edgegsttax = grafptr->edgeloctax; grafptr->edgeloctax = NULL; if ((grafptr->flagval & DGRAPHFREETABS) != 0) grafptr->flagval |= DGRAPHFREEEDGEGST; /* It is edgegsttax which will free edloloctax if edge arrays are grouped */ } } if ((cheklocval == 0) && (memAllocGroup ((void **) (void *) &procsidtab, (size_t) ((grafptr->edgelocnbr + grafptr->vertlocnbr) * sizeof (int)), &vertsidtab, (size_t) (grafptr->procglbnbr * sizeof (Gnum)), &sortloctab, (size_t) ((grafptr->edgelocnbr + 1) * sizeof (DgraphGhstSort)), NULL) == NULL)) { errorPrint ("dgraphGhst: out of memory (2)"); cheklocval = 1; } reduloctab[0] = 1; /* Assume memory error and prepare data for aborting */ reduloctab[1] = reduloctab[2] = 0; if (cheklocval != 0) { /* TRICK: Processes not on error will perform collective communication at end of routine */ if (dgraphAllreduceMaxSum (reduloctab, reduglbtab, 2, 1, grafptr->proccomm) != 0) { errorPrint ("dgraphGhst: communication error (1)"); return (1); } } vertlocmin = procvrttab[grafptr->proclocnum]; vertlocmax = procvrttab[grafptr->proclocnum + 1]; vertlocbas = vertlocmin - grafptr->baseval; memSet (grafptr->procrcvtab, 0, grafptr->procglbnbr * sizeof (int)); memSet (grafptr->procsndtab, 0, grafptr->procglbnbr * sizeof (int)); memSet (vertsidtab, ~0, grafptr->procglbnbr * sizeof (Gnum)); edgegsttax = grafptr->edgegsttax; procsndtab = grafptr->procsndtab; for (vertlocnum = vertsidnum = grafptr->baseval, sortlocnbr = 0, procsidnbr = 0; vertlocnum < grafptr->vertlocnnd; vertlocnum ++) { Gnum edgelocnum; for (edgelocnum = vertloctax[vertlocnum]; edgelocnum < vendloctax[vertlocnum]; edgelocnum ++) { Gnum vertlocend; vertlocend = edgeloctax[edgelocnum]; #ifdef SCOTCH_DEBUG_DGRAPH2 if ((vertlocend < grafptr->baseval) || (vertlocend >= (procvrttab[grafptr->procglbnbr]))) { errorPrint ("dgraphGhst: invalid edge array"); if (dgraphAllreduceMaxSum (reduloctab, reduglbtab, 2, 1, grafptr->proccomm) != 0) errorPrint ("dgraphGhst: communication error (2)"); memFree (procsidtab); /* Free group leader */ return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ if ((vertlocend >= vertlocmin) && (vertlocend < vertlocmax)) /* If edge is local */ edgegsttax[edgelocnum] = vertlocend - vertlocbas; /* Adjust its index */ else { /* End vertex is not local */ int procngbnum; int procngbmax; sortloctab[sortlocnbr].vertglbnum = vertlocend; /* Add it to sort array */ sortloctab[sortlocnbr].edgegstnum = edgelocnum; sortlocnbr ++; for (procngbnum = 0, procngbmax = grafptr->procglbnbr; procngbmax - procngbnum > 1; ) { int procngbmed; procngbmed = (procngbmax + procngbnum) / 2; if (procvrttab[procngbmed] <= vertlocend) procngbnum = procngbmed; else procngbmax = procngbmed; } if (vertsidtab[procngbnum] != vertlocnum) { /* If vertex not already sent to process */ vertsidtab[procngbnum] = vertlocnum; /* Neighbor process will receive vertex */ procsndtab[procngbnum] ++; /* One more vertex to send to this neighbor */ while ((vertlocnum - vertsidnum) >= DGRAPHGHSTSIDMAX) { /* If Gnum range too long for int */ procsidtab[procsidnbr ++] = -DGRAPHGHSTSIDMAX; /* Decrease by maximum int distance */ vertsidnum += DGRAPHGHSTSIDMAX; } if (vertsidnum != vertlocnum) { /* If communication concerns new local vertex */ procsidtab[procsidnbr ++] = - (vertlocnum - vertsidnum); /* Encode jump in procsidtab */ vertsidnum = vertlocnum; /* Current local vertex is last send vertex */ } procsidtab[procsidnbr ++] = procngbnum; /* Send this vertex data to this processor */ } } } } vertgstnum = grafptr->vertlocnnd; /* No ghost vertices yet */ procngbnbr = 0; /* No neighbor processes yet */ procsndnbr = 0; /* No vertex to send yet */ if (sortlocnbr > 0) { /* If there are ghost vertices */ Gnum vertgstbas; /* Number of current ghost vertex */ int procngbnum; intSort2asc1 (sortloctab, sortlocnbr); /* Sort them by ascending end vertex */ sortlocnum = 0; /* Start adjacency search from beginning */ procngbnum = -1; /* Start neighbor search from begnning */ do { /* For each distinct neighbor process */ vertgstbas = vertgstnum; /* Record first ghost number used for it */ edgegsttax[sortloctab[sortlocnum].edgegstnum] = vertgstnum; /* First ghost is always allocated */ while (procvrttab[++ procngbnum + 1] <= sortloctab[sortlocnum].vertglbnum) { /* Find owner process */ #ifdef SCOTCH_DEBUG_DGRAPH2 if ((procngbnum > grafptr->procglbnbr) || /* If we have skipped a neighbor to which we have to send something */ (procsndtab[procngbnum] != 0)) { errorPrint ("dgraphGhst: internal error (1)"); if (dgraphAllreduceMaxSum (reduloctab, reduglbtab, 2, 1, grafptr->proccomm) != 0) errorPrint ("dgraphGhst: communication error (3)"); memFree (procsidtab); /* Free group leader */ return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ } #ifdef SCOTCH_DEBUG_DGRAPH2 if (procsndtab[procngbnum] == 0) { /* If we had in fact no edges to send to this neighbor */ errorPrint ("dgraphGhst: internal error (2)"); if (dgraphAllreduceMaxSum (reduloctab, reduglbtab, 2, 1, grafptr->proccomm) != 0) errorPrint ("dgraphGhst: communication error (4)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ procsndnbr += procsndtab[procngbnum]; /* Sum-up vertices to send */ grafptr->procngbtab[procngbnbr ++] = procngbnum; /* Add it to neighbor process array */ while (++ sortlocnum < sortlocnbr) { /* For all following ghost edges */ if (sortloctab[sortlocnum].vertglbnum != /* If new ghost vertex */ sortloctab[sortlocnum - 1].vertglbnum) { vertgstnum ++; /* Allocate new ghost vertex number */ if (procvrttab[procngbnum + 1] <= sortloctab[sortlocnum].vertglbnum) { /* If new neighbor */ grafptr->procrcvtab[procngbnum] = vertgstnum - vertgstbas; /* Sum-up data for old neighbor */ break; /* Process new neighbor */ } } edgegsttax[sortloctab[sortlocnum].edgegstnum] = vertgstnum; /* Allocate ghost */ } } while (sortlocnum < sortlocnbr); vertgstnum ++; /* Size is one above last number */ grafptr->procrcvtab[procngbnum] = vertgstnum - vertgstbas; /* Sum-up data for last neighbor */ } grafptr->vertgstnbr = vertgstnum - grafptr->baseval; grafptr->vertgstnnd = grafptr->vertgstnbr + grafptr->baseval; grafptr->procngbnbr = procngbnbr; grafptr->procsndnbr = procsndnbr; grafptr->procsidtab = memRealloc (procsidtab, procsidnbr * sizeof (int)); /* Reallocate send index array */ grafptr->procsidnbr = procsidnbr; reduloctab[0] = 0; /* No memory error */ reduloctab[1] = /* Set maximum number of neighbors */ reduloctab[2] = grafptr->procngbnbr; if (dgraphAllreduceMaxSum (reduloctab, reduglbtab, 2, 1, grafptr->proccomm) != 0) { errorPrint ("dgraphGhst: communication error (5)"); return (1); } if (reduglbtab[0] != 0) /* If error, propagated by some previous reduction operator */ return (1); grafptr->procngbmax = reduglbtab[1]; grafptr->flagval |= DGRAPHFREEPSID | DGRAPHHASEDGEGST; /* Graph now has a valid ghost edge array */ #ifndef SCOTCH_COMM_COLL #ifndef SCOTCH_COMM_PTOP if (((float) reduglbtab[2]) <= ((float) grafptr->procglbnbr * (float) (grafptr->procglbnbr - 1) * (float) SCOTCH_COMM_PTOP_RAT)) #endif /* SCOTCH_COMM_PTOP */ grafptr->flagval |= DGRAPHCOMMPTOP; /* If too few communications, use point-to-point instead */ #endif /* SCOTCH_COMM_COLL */ #ifdef SCOTCH_DEBUG_DGRAPH2 if (dgraphHaloCheck (grafptr) != 0) { errorPrint ("dgraphGhst: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_DGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/library_graph_io_scot.c0000644002563400244210000001023511631447170026347 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_io_scot.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the Scotch **/ /** geometry and graph handling routines of **/ /** the libSCOTCH library. **/ /** **/ /** DATES : # Version 3.4 : from : 10 oct 1999 **/ /** to 01 nov 2001 **/ /** # Version 4.0 : from : 18 dec 2001 **/ /** to 19 jan 2004 **/ /** # Version 5.1 : from : 27 apr 2010 **/ /** to 27 apr 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "geom.h" #include "graph.h" #include "scotch.h" /*************************************/ /* */ /* These routines are the C API for */ /* the Scotch graph and geometry */ /* handling routines. */ /* */ /*************************************/ /*+ This routine loads the given opaque graph *** structure with the data of the given stream. *** - 0 : if loading succeeded. *** - !0 : on error. +*/ int SCOTCH_graphGeomLoadScot ( SCOTCH_Graph * restrict const grafptr, SCOTCH_Geom * restrict const geomptr, FILE * const filegrfptr, FILE * const filegeoptr, const char * const dataptr) { return (graphGeomLoadScot ((Graph *) grafptr, (Geom *) geomptr, filegrfptr, filegeoptr, dataptr)); } /*+ This routine saves the contents of the given *** opaque graph structure to the given stream. *** It returns: *** - 0 : if the saving succeeded. *** - !0 : on error. +*/ int SCOTCH_graphGeomSaveScot ( const SCOTCH_Graph * restrict const grafptr, const SCOTCH_Geom * restrict const geomptr, FILE * const filegrfptr, FILE * const filegeoptr, const char * const dataptr) { return (graphGeomSaveScot ((Graph *) grafptr, (Geom *) geomptr, filegrfptr, filegeoptr, dataptr)); } scotch-6.0.4.dfsg/src/libscotch/dgraph_fold_comm.h0000644002563400244210000000760411631447171025303 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2010,2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_fold_comm.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the distributed source graph **/ /** building routines. **/ /** **/ /** # Version 5.0 : from : 23 may 2006 **/ /** to 19 aug 2006 **/ /** # Version 5.1 : from : 30 jul 2010 **/ /** to 03 jan 2011 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ Starting maximum number of communications per process +*/ #define DGRAPHFOLDCOMMNBR 4 /* Starting maximum number of communications per process */ /* ** The type and structure definitions. */ /*+ Process communication type. Receivers that have more local vertices than needed can also be senders, hence the " = 1" to allow for or-ing both values. +*/ typedef enum DgraphFoldCommType_ { DGRAPHFOLDCOMMRECV = 1, /*+ Process is a receiver +*/ DGRAPHFOLDCOMMSEND /*+ Process is a sender +*/ } DgraphFoldCommType; /* Sort structure for processors. */ typedef struct DgraphFoldCommData_ { Gnum vertnbr; /* Number of vertices; TRICK: FIRST */ Gnum procnum; /* Processor index (Gnum for sorting) */ } DgraphFoldCommData; /* ** The function prototypes. */ int dgraphFoldComm (const Dgraph * restrict const, const int, int * restrict const, int * restrict const, DgraphFoldCommData * restrict * restrict const, Gnum * restrict * restrict const, Gnum * restrict const, int * restrict const, Gnum * restrict * restrict const, Gnum * restrict * restrict const); scotch-6.0.4.dfsg/src/libscotch/arch_dist.h0000644002563400244210000001166712500615300023746 0ustar trophimeutilisateurs du domaine/* Copyright 2011,2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : arch_dist.h **/ /** **/ /** AUTHOR : Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the distance multiplicator pseudo- **/ /** architecture functions. This pseudo- **/ /** architecture is used by graph reparti- **/ /** tioning routines to handle floating- **/ /** point migration costs. **/ /** **/ /** DATES : # Version 6.0 : from : 14 fev 2011 **/ /** to : 01 jul 2014 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ #ifndef ARCH_DIST_H_STRUCT #define ARCH_DIST_H_STRUCT /*+ The distance graph definitions. +*/ typedef struct ArchDist_ { struct Arch_ * archptr; /*+ Encapsulated architecture +*/ Anum crloval; /*+ Coefficient load for regular edges +*/ } ArchDist; #define ArchDistDom ArchDom /*+ Domain is the regular domain +*/ #endif /* ARCH_DIST_H_STRUCT */ /* ** The function prototypes. */ #ifndef ARCH_NOPROTO #ifndef ARCH_DIST_H_PROTO #define ARCH_DIST_H_PROTO #ifndef ARCH_DIST #define static #endif int archDistArchLoad (ArchDist * restrict const, FILE * restrict const); int archDistArchSave (const ArchDist * const, FILE * restrict const); #define archDistArchFree NULL int archDistArchBuild (struct Arch_ * const, struct Arch_ * const, const Anum); ArchDomNum archDistDomNum (const ArchDist * const, const ArchDom * const); int archDistDomTerm (const ArchDist * const, ArchDom * restrict const, const ArchDomNum); Anum archDistDomSize (const ArchDist * const, const ArchDom * const); Anum archDistDomWght (const ArchDist * const, const ArchDom * const); Anum archDistDomDist (const ArchDist * const, const ArchDom * const, const ArchDom * const); int archDistDomFrst (const ArchDist * const, ArchDom * const); int archDistDomLoad (const ArchDist * const, ArchDom * const, FILE * const); int archDistDomSave (const ArchDist * const, const ArchDom * const, FILE * const); int archDistDomBipart (const ArchDist * const, const ArchDom * const, ArchDom * restrict const, ArchDom * restrict const); int archDistDomIncl (const ArchDist * const, const ArchDom * const, const ArchDom * const); #ifdef SCOTCH_PTSCOTCH int archDistDomMpiType (const ArchDist * const, MPI_Datatype * const); #endif /* SCOTCH_PTSCOTCH */ #undef static #endif /* ARCH_DIST_H_PROTO */ #endif /* ARCH_NOPROTO */ scotch-6.0.4.dfsg/src/libscotch/wgraph_part_gp.h0000644002563400244210000000702011631447171025013 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : wgraph_part_gp.h **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Charles-Edmond BICHOT (v5.1b) **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the graph partitioning rountine **/ /** based on a vertex-oriented version of **/ /** the Gibbs-Poole-Stockmeyer algorithm. **/ /** **/ /** DATES : # Version 5.1 : from : 01 dec 2007 **/ /** to : 01 jul 2008 **/ /** # Version 6.0 : from : 05 nov 2009 **/ /** to : 04 nov 2010 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ System-defined constants. +*/ #define WGRAPHSEPAGPSUBBITS 4 #define WGRAPHGPCHOOSELASTPART /* ** The type and structure definitions. */ /*+ Method parameters. +*/ typedef struct WgraphPartGpParam_ { INT passnbr; /*+ Number of passes to do +*/ } WgraphPartGpParam; /*+ The complementary vertex structure. +*/ typedef struct WgraphPartGpVertex_ { Gnum partlvl; struct WgraphPartGpVertex_ * prev; struct WgraphPartGpVertex_ * next; Gnum isinstack; } WgraphPartGpVertex; /* ** The function prototypes. */ #ifndef WGRAPH_PART_GP #define static #endif int wgraphPartGp (Wgraph * restrict const, const WgraphPartGpParam * restrict const); #undef static scotch-6.0.4.dfsg/src/libscotch/library_graph_map_io_f.c0000644002563400244210000001426412053744603026467 0ustar trophimeutilisateurs du domaine/* Copyright 2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_map_io_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the Fortran API for the **/ /** graph i/o routines of the libSCOTCH **/ /** library. **/ /** **/ /** DATES : # Version 6.0 : from : 03 jul 2012 **/ /** to 23 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the mapping routines. */ /* */ /**************************************/ FORTRAN ( \ SCOTCHFGRAPHTABLOAD, scotchfgraphtabload, ( \ const SCOTCH_Graph * const grafptr, \ SCOTCH_Num * const parttab, \ const int * const fileptr, \ int * const revaptr), \ (grafptr, parttab, fileptr, revaptr)) { FILE * stream; /* Stream to build from handle */ int filenum; /* Duplicated handle */ int filegeonum; int o; if ((filenum = dup (*fileptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFGRAPHTABLOAD: cannot duplicate handle"); *revaptr = 1; /* Indicate error */ return; } if ((stream = fdopen (filenum, "r")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFGRAPHTABLOAD: cannot open input stream"); close (filenum); *revaptr = 1; return; } o = SCOTCH_graphTabLoad (grafptr, parttab, stream); fclose (stream); /* This closes file descriptor too */ *revaptr = o; } /* ** */ FORTRAN ( \ SCOTCHFGRAPHMAPLOAD, scotchfgraphmapload, ( \ const SCOTCH_Graph * const grafptr, \ SCOTCH_Mapping * const mappptr, \ const int * const fileptr, \ int * const revaptr), \ (grafptr, mappptr, fileptr, revaptr)) { FILE * stream; /* Stream to build from handle */ int filenum; /* Duplicated handle */ int o; if ((filenum = dup (*fileptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFGRAPHMAPLOAD: cannot duplicate handle"); *revaptr = 1; /* Indicate error */ return; } if ((stream = fdopen (filenum, "r")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFGRAPHMAPLOAD: cannot open input stream"); close (filenum); *revaptr = 1; return; } o = SCOTCH_graphMapLoad (grafptr, mappptr, stream); fclose (stream); /* This closes file descriptor too */ *revaptr = o; } /* ** */ FORTRAN ( \ SCOTCHFGRAPHMAPSAVE, scotchfgraphmapsave, ( \ const SCOTCH_Graph * const grafptr, \ SCOTCH_Mapping * const mappptr, \ int * const fileptr, \ int * const revaptr), \ (grafptr, mappptr, fileptr, revaptr)) { FILE * stream; /* Stream to build from handle */ int filenum; /* Duplicated handle */ int o; if ((filenum = dup (*fileptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFGRAPHMAPSAVE: cannot duplicate handle"); *revaptr = 1; /* Indicate error */ return; } if ((stream = fdopen (filenum, "w")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFGRAPHMAPSAVE: cannot open output stream"); close (filenum); *revaptr = 1; return; } o = SCOTCH_graphMapSave (grafptr, mappptr, stream); fclose (stream); /* This closes filenum too */ *revaptr = o; } scotch-6.0.4.dfsg/src/libscotch/hmesh_order_hd.c0000644002563400244210000001545011631447170024761 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh_order_hd.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module orders a submesh using **/ /** the block-oriented Halo Approximate **/ /** (Multiple) Minimum Degree algorithm, **/ /** with super-variable accounting **/ /** R2HAMDf4 v2.0). **/ /** **/ /** DATES : # Version 4.0 : from : 10 dec 2003 **/ /** to : 24 jan 2004 **/ /** # Version 5.0 : from : 12 sep 2007 **/ /** to : 12 sep 2007 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HMESH_ORDER_HD #include "module.h" #include "common.h" #include "graph.h" #include "order.h" #include "mesh.h" #include "hmesh.h" #include "hall_order_hd.h" #include "hall_order_hx.h" #include "hmesh_order_hd.h" #include "hmesh_order_hx.h" #include "hmesh_order_si.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the ordering. ** It returns: ** - 0 : if the ordering could be computed. ** - !0 : on error. */ int hmeshOrderHd ( const Hmesh * restrict const meshptr, Order * restrict const ordeptr, const Gnum ordenum, OrderCblk * restrict const cblkptr, /*+ Single column-block +*/ const HmeshOrderHdParam * restrict const paraptr) { Gnum * restrict petab; Gnum pfree; Gnum iwlen; Gnum * restrict iwtab; Gnum * restrict lentab; Gnum * restrict nvartab; Gnum * restrict elentab; Gnum * restrict lasttab; Gnum * restrict leaftab; Gnum * restrict secntab; /* Array of index to first secondary variable */ Gnum * restrict nexttab; /* Array of index of next principal variable */ Gnum * restrict frsttab; Gnum ncmpa; Gnum n; /* Number of nodes to order */ int o; n = meshptr->m.velmnbr + meshptr->m.vnodnbr; if (n < paraptr->colmin) /* If graph is too small, order simply */ return (hmeshOrderSi (meshptr, ordeptr, ordenum, cblkptr)); iwlen = (Gnum) ((double) meshptr->m.edgenbr * HMESHORDERHDCOMPRAT) + 32; if (iwlen < n) /* Prepare to re-use array */ iwlen = n; if (memAllocGroup ((void **) (void *) &petab, (size_t) (n * sizeof (Gnum)), &iwtab, (size_t) (iwlen * sizeof (Gnum)), &lentab, (size_t) (n * sizeof (Gnum)), &nvartab, (size_t) (n * sizeof (Gnum)), &elentab, (size_t) (n * sizeof (Gnum)), &lasttab, (size_t) (n * sizeof (Gnum)), &leaftab, (size_t) (n * sizeof (Gnum)), &frsttab, (size_t) (n * sizeof (Gnum)), &secntab, (size_t) (n * sizeof (Gnum)), &nexttab, (size_t) (n * sizeof (Gnum)), NULL) == NULL) { errorPrint ("hmeshOrderHd: out of memory"); return (1); } hmeshOrderHxFill (meshptr, petab, lentab, iwtab, elentab, &pfree); hallOrderHdHalmd (n, meshptr->m.velmnbr, iwlen, petab, pfree, lentab, iwtab, nvartab, elentab, lasttab, &ncmpa, leaftab, secntab, nexttab, frsttab); if (ncmpa < 0) { errorPrint ("hmeshOrderHd: internal error"); memFree (petab); /* Free group leader */ return (1); } o = hallOrderHxBuild (meshptr->m.baseval, n, meshptr->vnohnbr, (meshptr->m.vnumtax == NULL) ? NULL : meshptr->m.vnumtax + (meshptr->m.vnodbas - meshptr->m.baseval), /* Point to node part of vnumtab array */ ordeptr, cblkptr, nvartab - meshptr->m.baseval, lentab - meshptr->m.baseval, petab - meshptr->m.baseval, frsttab - meshptr->m.baseval, nexttab - meshptr->m.baseval, secntab - meshptr->m.baseval, iwtab - meshptr->m.baseval, elentab - meshptr->m.baseval, ordeptr->peritab + ordenum, /* Use given inverse permutation as inverse permutation space, never based */ leaftab, paraptr->colmin, paraptr->colmax, (float) paraptr->fillrat); memFree (petab); /* Free group leader */ return (o); } scotch-6.0.4.dfsg/src/libscotch/dgraph_match_check.c0000644002563400244210000002462011631447170025564 0ustar trophimeutilisateurs du domaine/* Copyright 2008,2009 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_match_check.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the distributed graph matching **/ /** routines. **/ /** **/ /** DATES : # Version 5.1 : from : 25 dec 2008 **/ /** to : 08 apr 2009 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DGRAPH_MATCH #include "module.h" #include "common.h" #include "dgraph.h" #include "dgraph_coarsen.h" #include "dgraph_match.h" /*************************************/ /* */ /* These routines handle distributed */ /* matchings. */ /* */ /*************************************/ /* This routine checks the consistency of a ** given complete matching. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int dgraphMatchCheck ( DgraphMatchData * restrict const mateptr) { Gnum baseval; Gnum * restrict flaggsttax; int procngbnum; Gnum multlocnbr; Gnum multlocnum; Gnum vertglbnnd; Gnum vertlocnbr; Gnum vertlocnnd; Gnum vertlocnum; Gnum vertlocadj; int cheklocval; int chekglbval; Dgraph * restrict const grafptr = mateptr->c.finegrafptr; const int * restrict const procngbtab = grafptr->procngbtab; const Gnum * restrict const mategsttax = mateptr->mategsttax; DgraphCoarsenVert * restrict const vsnddattab = mateptr->c.vsnddattab; const DgraphCoarsenMulti * restrict const multloctab = mateptr->c.multloctab; const int * restrict const procgsttax = mateptr->c.procgsttax; const Gnum * restrict const edgeloctax = grafptr->edgeloctax; const Gnum * restrict const edgegsttax = grafptr->edgegsttax; const Gnum * restrict const vertloctax = grafptr->vertloctax; const Gnum * restrict const vendloctax = grafptr->vendloctax; int * restrict const nsndidxtab = mateptr->c.nsndidxtab; baseval = grafptr->baseval; cheklocval = 0; multlocnbr = mateptr->c.multlocnbr; if ((multlocnbr < 0) || (multlocnbr > grafptr->vertlocnbr)) { errorPrint ("dgraphMatchCheck: invalid number of multinodes"); cheklocval = 1; } vertlocnbr = grafptr->vertlocnbr; for (vertlocnum = baseval; vertlocnum < vertlocnbr; vertlocnum ++) { if (mategsttax[vertlocnum] < 0) { errorPrint ("dgraphMatchCheck: unmatched local vertex"); cheklocval = 1; break; } } if ((flaggsttax = memAlloc (grafptr->vertgstnbr * sizeof (Gnum))) == NULL) { errorPrint ("dgraphMatchCheck: out of memory"); cheklocval = 1; } if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_SUM, mateptr->c.finegrafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphMatchCheck: communication error (1)"); chekglbval = 1; } if (chekglbval != 0) { if (flaggsttax != NULL) memFree (flaggsttax); return (1); } for (procngbnum = 0; procngbnum < grafptr->procngbnbr; procngbnum ++) /* Reset indices for sending messages */ nsndidxtab[procngbnum] = mateptr->c.vsnddsptab[procngbtab[procngbnum]]; memSet (flaggsttax, ~0, grafptr->vertgstnbr * sizeof (Gnum)); flaggsttax -= baseval; vertglbnnd = grafptr->vertglbnbr + baseval; vertlocnnd = grafptr->vertlocnnd; vertlocadj = grafptr->procvrttab[grafptr->proclocnum] - baseval; for (multlocnum = 0; multlocnum < multlocnbr; multlocnum ++) { Gnum vertglbnum; Gnum vertlocnum; Gnum vertglbend; vertglbnum = multloctab[multlocnum].vertglbnum[0]; vertlocnum = vertglbnum - vertlocadj; /* First vertex is always local */ if ((vertlocnum < baseval) || (vertlocnum >= vertlocnnd)) { errorPrint ("dgraphMatchCheck: invalid multinode vertex (1)"); goto abort; } if (flaggsttax[vertlocnum] != -1) { errorPrint ("dgraphMatchCheck: duplicate multinode vertex (1)"); goto abort; } flaggsttax[vertlocnum] = multlocnum + vertlocadj; vertglbend = multloctab[multlocnum].vertglbnum[1]; if (vertglbend < 0) { /* If end vertex is remote */ Gnum edgelocnum; Gnum vertgstend; int vsndidxnum; int procngbnum; edgelocnum = -2 - vertglbend; if ((edgelocnum < grafptr->baseval) || (edgelocnum >= (grafptr->edgelocsiz + grafptr->baseval))) { errorPrint ("dgraphMatchCheck: invalid multinode vertex (2)"); goto abort; } vertglbend = edgeloctax[edgelocnum]; if (mategsttax[vertlocnum] != vertglbend) { errorPrint ("dgraphMatchCheck: invalid mate array (1)"); goto abort; } vertgstend = edgegsttax[edgelocnum]; if (flaggsttax[vertgstend] != -1) { errorPrint ("dgraphMatchCheck: duplicate multinode vertex (2)"); goto abort; } flaggsttax[vertgstend] = multlocnum + vertlocadj; if (mategsttax[vertgstend] != vertglbnum) { errorPrint ("dgraphMatchCheck: invalid mate array (2)"); goto abort; } procngbnum = procgsttax[vertgstend]; /* Find neighbor owner process */ if ((procngbnum < 0) || (procngbnum >= grafptr->procngbnbr)) { /* If neighbor had not been computed or is wrong */ errorPrint ("dgraphMatchCheck: internal error (1)"); goto abort; } if ((grafptr->procvrttab[procngbtab[procngbnum]] > vertglbend) || (grafptr->procvrttab[procngbtab[procngbnum] + 1] <= vertglbend)) { errorPrint ("dgraphMatchCheck: internal error (2)"); goto abort; } vsndidxnum = nsndidxtab[procngbnum] ++; /* Get position of message in send array */ if (vsndidxnum >= mateptr->c.vsnddsptab[procngbtab[procngbnum] + 1]) { errorPrint ("dgraphMatchCheck: internal error (3)"); goto abort; } vsnddattab[vsndidxnum].datatab[0] = vertglbnum; vsnddattab[vsndidxnum].datatab[1] = vertglbend; } else { /* End vertex is local */ Gnum vertlocend; Gnum edgelocnum; Gnum edgelocnnd; if (mategsttax[vertlocnum] != vertglbend) { errorPrint ("dgraphMatchCheck: invalid mate array (3)"); goto abort; } if (vertglbend == vertglbnum) /* If single multinode */ continue; vertlocend = vertglbend - vertlocadj; if ((vertlocend < baseval) || (vertlocend >= vertlocnnd)) { errorPrint ("dgraphMatchCheck: invalid multinode vertex (3)"); goto abort; } edgelocnum = vertloctax[vertlocnum]; edgelocnnd = vendloctax[vertlocnum]; if (edgelocnum != edgelocnnd) { /* If first multinode vertex is not an isolated vertex */ for ( ; ; edgelocnum ++) { /* Loop on edges of first multinode vertex */ if (edgelocnum >= edgelocnnd) { /* If not a valid neighbor */ errorPrint ("dgraphMatchCheck: invalid multinode vertex (4)"); goto abort; } if (edgeloctax[edgelocnum] == vertglbend) /* If edge to end vertex found */ break; } } if (flaggsttax[vertlocend] != -1) { errorPrint ("dgraphMatchCheck: duplicate multinode vertex (3)"); goto abort; } flaggsttax[vertlocend] = multlocnum + vertlocadj; if (mategsttax[vertlocend] != vertglbnum) { errorPrint ("dgraphMatchCheck: invalid mate array (4)"); goto abort; } } } cheklocval = -1; abort: cheklocval ++; if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_SUM, mateptr->c.finegrafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphMatchCheck: communication error (2)"); chekglbval = 1; } if (chekglbval != 0) { memFree (flaggsttax + baseval); return (1); } /* TODO: Send messages and check consistency of matching on the receiving side */ memFree (flaggsttax + baseval); return (0); } scotch-6.0.4.dfsg/src/libscotch/hmesh_order_si.c0000644002563400244210000001032411631447171024775 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh_order_si.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module orders halo mesh vertices **/ /** using the natural order. **/ /** **/ /** DATES : # Version 4.0 : from : 01 jan 2002 **/ /** to 27 jan 2004 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HMESH_ORDER_SI #include "module.h" #include "common.h" #include "graph.h" #include "order.h" #include "mesh.h" #include "hmesh.h" #include "hmesh_order_si.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the ordering. ** It returns: ** - 0 : if the ordering could be computed. ** - !0 : on error. */ int hmeshOrderSi ( const Hmesh * restrict const meshptr, Order * restrict const ordeptr, const Gnum ordenum, OrderCblk * restrict const cblkptr) /*+ Single column-block +*/ { Gnum vnodnum; Gnum ordeval; if (meshptr->m.vnumtax == NULL) { /* If mesh is original mesh (no halo) */ #ifdef SCOTCH_DEBUG_ORDER2 if (meshptr->m.vnodnbr != ordeptr->vnodnbr) { errorPrint ("hmeshOrderSi: invalid permutation bounds"); return (1); } #endif /* SCOTCH_DEBUG_ORDER2 */ for (vnodnum = ordeptr->baseval, ordeval = ordenum; vnodnum < ordeptr->baseval + ordeptr->vnodnbr; vnodnum ++, ordeval ++) { ordeptr->peritab[ordeval] = vnodnum; } } else { /* Mesh is not original mesh */ for (vnodnum = meshptr->m.vnodbas, ordeval = ordenum; vnodnum < meshptr->vnohnnd; vnodnum ++, ordeval ++) { ordeptr->peritab[ordeval] = meshptr->m.vnumtax[vnodnum]; #ifdef SCOTCH_DEBUG_ORDER2 if ((ordeptr->peritab[ordeval] < ordeptr->baseval) || (ordeptr->peritab[ordeval] >= (ordeptr->baseval + ordeptr->vnodnbr))) { errorPrint ("hmeshOrderSi: invalid permutation index"); return (1); } #endif /* SCOTCH_DEBUG_ORDER2 */ } } return (0); } scotch-6.0.4.dfsg/src/libscotch/library_mesh_order_f.c0000644002563400244210000002745011631447170026172 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_mesh_order_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the Fortran API for the **/ /** mesh ordering routines of the libSCOTCH **/ /** library. **/ /** **/ /** DATES : # Version 4.0 : from : 14 jan 2004 **/ /** to 20 dec 2005 **/ /** # Version 5.0 : from : 04 aug 2007 **/ /** to 04 aug 2007 **/ /** # Version 5.1 : from : 27 mar 2010 **/ /** to 25 jul 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the ordering routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFMESHORDERINIT, scotchfmeshorderinit, ( \ const SCOTCH_Mesh * const meshptr, \ SCOTCH_Ordering * const ordeptr, \ SCOTCH_Num * const permtab, \ SCOTCH_Num * const peritab, \ SCOTCH_Num * const cblkptr, \ SCOTCH_Num * const rangtab, \ SCOTCH_Num * const treetab, \ int * const revaptr), \ (meshptr, ordeptr, permtab, peritab, \ cblkptr, rangtab, treetab, revaptr)) { *revaptr = SCOTCH_meshOrderInit (meshptr, ordeptr, permtab, peritab, cblkptr, rangtab, treetab); } /* ** */ FORTRAN ( \ SCOTCHFMESHORDEREXIT, scotchfmeshorderexit, ( \ const SCOTCH_Mesh * const meshptr, \ SCOTCH_Ordering * const ordeptr), \ (meshptr, ordeptr)) { SCOTCH_meshOrderExit (meshptr, ordeptr); } /* ** */ FORTRAN ( \ SCOTCHFMESHORDERSAVE, scotchfmeshordersave, ( \ const SCOTCH_Mesh * const meshptr, \ const SCOTCH_Ordering * const ordeptr, \ int * const fileptr, \ int * const revaptr), \ (meshptr, ordeptr, fileptr, revaptr)) { FILE * stream; /* Stream to build from handle */ int filenum; /* Duplicated handle */ int o; if ((filenum = dup (*fileptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFMESHORDERSAVE: cannot duplicate handle"); *revaptr = 1; /* Indicate error */ return; } if ((stream = fdopen (filenum, "w")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFMESHORDERSAVE: cannot open output stream"); close (filenum); *revaptr = 1; return; } o = SCOTCH_meshOrderSave (meshptr, ordeptr, stream); fclose (stream); /* This closes filenum too */ *revaptr = o; } /* ** */ FORTRAN ( \ SCOTCHFMESHORDERSAVEMAP, scotchfmeshordersavemap, ( \ const SCOTCH_Mesh * const meshptr, \ const SCOTCH_Ordering * const ordeptr, \ int * const fileptr, \ int * const revaptr), \ (meshptr, ordeptr, fileptr, revaptr)) { FILE * stream; /* Stream to build from handle */ int filenum; /* Duplicated handle */ int o; if ((filenum = dup (*fileptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFMESHORDERSAVEMAP: cannot duplicate handle"); *revaptr = 1; /* Indicate error */ return; } if ((stream = fdopen (filenum, "w")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFMESHORDERSAVEMAP: cannot open output stream"); close (filenum); *revaptr = 1; return; } o = SCOTCH_meshOrderSaveMap (meshptr, ordeptr, stream); fclose (stream); /* This closes filenum too */ *revaptr = o; } /* ** */ FORTRAN ( \ SCOTCHFMESHORDERSAVETREE, scotchfmeshordersavetree, ( \ const SCOTCH_Mesh * const meshptr, \ const SCOTCH_Ordering * const ordeptr, \ int * const fileptr, \ int * const revaptr), \ (meshptr, ordeptr, fileptr, revaptr)) { FILE * stream; /* Stream to build from handle */ int filenum; /* Duplicated handle */ int o; if ((filenum = dup (*fileptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFMESHORDERSAVETREE: cannot duplicate handle"); *revaptr = 1; /* Indicate error */ return; } if ((stream = fdopen (filenum, "w")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFMESHORDERSAVETREE: cannot open output stream"); close (filenum); *revaptr = 1; return; } o = SCOTCH_meshOrderSaveTree (meshptr, ordeptr, stream); fclose (stream); /* This closes filenum too */ *revaptr = o; } /* ** */ FORTRAN ( \ SCOTCHFMESHORDERCOMPUTE, scotchfmeshordercompute, ( \ SCOTCH_Mesh * const meshptr, \ SCOTCH_Ordering * const ordeptr, \ SCOTCH_Strat * const stratptr, \ int * const revaptr), \ (meshptr, ordeptr, stratptr, revaptr)) { *revaptr = SCOTCH_meshOrderCompute (meshptr, ordeptr, stratptr); } /* ** */ FORTRAN ( \ SCOTCHFMESHORDERCOMPUTELIST, scotchfmeshordercomputelist, ( \ SCOTCH_Mesh * const meshptr, \ SCOTCH_Ordering * const ordeptr, \ const SCOTCH_Num * listptr, \ const SCOTCH_Num * const listtab, \ SCOTCH_Strat * const stratptr, \ int * const revaptr), \ (meshptr, ordeptr, listptr, listtab, stratptr, revaptr)) { *revaptr = SCOTCH_meshOrderComputeList (meshptr, ordeptr, *listptr, listtab, stratptr); } /* ** */ FORTRAN ( \ SCOTCHFMESHORDER, scotchfmeshorder, ( \ SCOTCH_Mesh * const meshptr, \ SCOTCH_Strat * const stratptr, \ SCOTCH_Num * const permtab, \ SCOTCH_Num * const peritab, \ SCOTCH_Num * const cblkptr, \ SCOTCH_Num * const rangtab, \ SCOTCH_Num * const treetab, \ int * const revaptr), \ (meshptr, stratptr, permtab, peritab, \ cblkptr, rangtab, treetab, revaptr)) { *revaptr = SCOTCH_meshOrder (meshptr, stratptr, permtab, peritab, cblkptr, rangtab, treetab); } /* ** */ FORTRAN ( \ SCOTCHFMESHORDERLIST, scotchfmeshorderlist, ( \ SCOTCH_Mesh * const meshptr, \ const SCOTCH_Num * const listptr, \ const SCOTCH_Num * const listtab, \ SCOTCH_Strat * const stratptr, \ SCOTCH_Num * const permtab, \ SCOTCH_Num * const peritab, \ SCOTCH_Num * const cblkptr, \ SCOTCH_Num * const rangtab, \ SCOTCH_Num * const treetab, \ int * const revaptr), \ (meshptr, listptr, listtab, stratptr, \ permtab, peritab, cblkptr, rangtab, treetab, revaptr)) { *revaptr = SCOTCH_meshOrderList (meshptr, *listptr, listtab, stratptr, permtab, peritab, cblkptr, rangtab, treetab); } /* ** */ FORTRAN ( \ SCOTCHFMESHORDERCHECK, scotchfmeshordercheck, ( \ const SCOTCH_Mesh * const meshptr, \ SCOTCH_Ordering * const ordeptr, \ int * const revaptr), \ (meshptr, ordeptr, revaptr)) { *revaptr = SCOTCH_meshOrderCheck (meshptr, ordeptr); } /* ** */ FORTRAN ( \ SCOTCHFSTRATMESHORDER, scotchfstratmeshorder, ( \ SCOTCH_Strat * const stratptr, \ const char * const string, \ int * const revaptr, \ const int strnbr), \ (stratptr, string, revaptr, strnbr)) { char * restrict strtab; /* Pointer to null-terminated string */ if ((strtab = (char *) memAlloc (strnbr + 1)) == NULL) { /* Allocate temporary space */ errorPrint ("SCOTCHFSTRATMESHORDER: out of memory (1)"); *revaptr = 1; } memCpy (strtab, string, strnbr); /* Copy string contents */ strtab[strnbr] = '\0'; /* Terminate string */ *revaptr = SCOTCH_stratMeshOrder (stratptr, strtab); /* Call original routine */ memFree (strtab); /* Prevent compiler warnings */ } /* ** */ FORTRAN ( \ SCOTCHFSTRATMESHORDERBUILD, scotchfstratmeshorderbuild, ( \ SCOTCH_Strat * const stratptr, \ const SCOTCH_Num * const flagval, \ const double * const balrat, \ int * const revaptr), \ (stratptr, flagval, balrat, revaptr)) { *revaptr = SCOTCH_stratMeshOrderBuild (stratptr, *flagval, *balrat); } scotch-6.0.4.dfsg/src/libscotch/bdgraph.h0000644002563400244210000001745112400670745023427 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2010,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bdgraph.h **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for distributed edge bipartition- **/ /** ing routines. **/ /** **/ /** DATES : # Version 5.1 : from : 10 sep 2007 **/ /** to : 14 apr 2011 **/ /** # Version 6.0 : from : 11 sep 2011 **/ /** to : 31 aug 2014 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ Graph option flags. +*/ #define BDGRAPHFREEFRON (DGRAPHBITSNOTUSED) /* Free part array */ #define BDGRAPHFREEPART (DGRAPHBITSNOTUSED << 1) /* Free frontier array */ #define BDGRAPHFREEVEEX (DGRAPHBITSNOTUSED << 2) /* Free external gain array */ /*+ Active graph structure. +*/ typedef struct Bdgraph_ { Dgraph s; /*+ Distributed source graph +*/ Gnum * veexloctax; /*+ Local vertex external gain array if moved to 1 +*/ Gnum veexglbsum; /*+ Global sum of veexloctax array cells +*/ GraphPart * partgsttax; /*+ Based local part array: 0,1: part +*/ Gnum * fronloctab; /*+ Array of local frontier vertex numbers +*/ Gnum fronlocnbr; /*+ Number of local frontier vertices +*/ Gnum fronglbnbr; /*+ Number of global frontier vertices +*/ Gnum complocload0; /*+ Local load of part 0 +*/ Gnum compglbload0; /*+ Global load of part 0 +*/ Gnum compglbload0min; /*+ Minimum allowed load in part 0 (strategy variable) +*/ Gnum compglbload0max; /*+ Maximum allowed load in part 0 (strategy variable) +*/ Gnum compglbload0avg; /*+ Global average load of part 0 +*/ Gnum compglbload0dlt; /*+ Load difference from the average +*/ Gnum complocsize0; /*+ Number of local vertices in part 0 +*/ Gnum compglbsize0; /*+ Number of global vertices in part 0 +*/ Gnum commglbload; /*+ Global communication load +*/ Gnum commglbgainextn; /*+ Global external gain if all swapped +*/ Gnum commglbloadextn0; /*+ Global communication load if all moved to part 0 +*/ Gnum commglbgainextn0; /*+ Global external gain if all swapped from part 0 +*/ double bbalglbval; /*+ Bipartitioning imbalance ratio (strategy variable) +*/ Anum domndist; /*+ Distance between subdomains +*/ Anum domnwght[2]; /*+ Weights for each subdomain +*/ INT levlnum; /*+ Graph coarsening level +*/ } Bdgraph; /*+ The distributed save graph structure. +*/ typedef struct BdgraphStore_ { Gnum fronlocnbr; /*+ Number of local frontier vertices +*/ Gnum fronglbnbr; /*+ Number of frontier vertices +*/ Gnum complocload0; /*+ Local load in part 0 +*/ Gnum compglbload0; /*+ Load in part 0 +*/ Gnum compglbload0dlt; /*+ Difference from the average +*/ Gnum complocsize0; /*+ Number of local vertices in part 0 +*/ Gnum compglbsize0; /*+ Number of global vertices in part 0 +*/ Gnum commglbload; Gnum commglbgainextn; byte * datatab; /*+ Variable-sized data array +*/ } BdgraphStore; /* ** The function prototypes. */ #ifndef BDGRAPH #define static #endif #ifdef DMAPPING_H int bdgraphInit (Bdgraph * const, const Dgraph * const, const Dgraph * const, const Arch * const, const ArchDom[]); #endif /* DMAPPING_H */ void bdgraphInit2 (Bdgraph * const, const Anum, const Anum, const Anum); #ifdef DMAPPING_H int bdgraphInit3 (Bdgraph * const, const Dgraph * const, const Dmapping * const, const ArchDom[]); #endif /* DMAPPING_H */ void bdgraphExit (Bdgraph * restrict const); void bdgraphFree (Bdgraph * restrict const); void bdgraphZero (Bdgraph * restrict const); int bdgraphCheck (const Bdgraph * restrict const); #ifdef BGRAPH_H int bdgraphGatherAll (const Bdgraph * restrict const, Bgraph * restrict); #endif /* BGRAPH_H */ int bdgraphStoreInit (const Bdgraph * const, BdgraphStore * const); void bdgraphStoreExit (BdgraphStore * const); void bdgraphStoreSave (const Bdgraph * const , BdgraphStore * const); void bdgraphStoreUpdt (Bdgraph * const, const BdgraphStore * const); #undef static scotch-6.0.4.dfsg/src/libscotch/bdgraph_bipart_st.c0000644002563400244210000004743312412035044025462 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bdgraph_bipart_st.c **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the strategy and **/ /** method tables for distributed graph **/ /** bipartitioning methods. **/ /** **/ /** DATES : # Version 5.1 : from : 10 sep 2007 **/ /** to : 15 apr 2011 **/ /** # Version 6.0 : from : 11 sep 2011 **/ /** to : 28 sep 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define BDGRAPH_BIPART_ST #include "module.h" #include "common.h" #include "gain.h" #include "parser.h" #include "graph.h" #include "arch.h" #include "bgraph.h" #include "bgraph_bipart_st.h" #include "dgraph.h" #include "dgraph_coarsen.h" #include "bdgraph.h" #include "bdgraph_bipart_bd.h" #include "bdgraph_bipart_df.h" #include "bdgraph_bipart_ex.h" #include "bdgraph_bipart_ml.h" #include "bdgraph_bipart_sq.h" #include "bdgraph_bipart_st.h" #include "bdgraph_bipart_zr.h" /* ** The static and global variables. */ static Bdgraph bdgraphdummy; /* Dummy distributed bipartitioned graph for offset computations */ static union { BdgraphBipartBdParam param; StratNodeMethodData padding; } bdgraphbipartstdefaultbd = { { 3, &stratdummy } }; static union { BdgraphBipartDfParam param; StratNodeMethodData padding; } bdgraphbipartstdefaultdf = { { 500, 1.0, 0.0, BDGRAPHBIPARTDFTYPEBAL } }; static union { BdgraphBipartExParam param; StratNodeMethodData padding; } bdgraphbipartstdefaultex = { { 5, 0.005 } }; static union { BdgraphBipartMlParam param; StratNodeMethodData padding; } bdgraphbipartstdefaultml = { { 5, 1000, 2, 10000, 0.8L, &stratdummy, &stratdummy, &stratdummy} }; static union { BdgraphBipartSqParam param; StratNodeMethodData padding; } bdgraphbipartstdefaultsq = { { &stratdummy } }; static StratMethodTab bdgraphbipartstmethtab[] = { /* Bipartitioning methods array */ { BDGRAPHBIPARTSTMETHBD, "b", bdgraphBipartBd, &bdgraphbipartstdefaultbd }, { BDGRAPHBIPARTSTMETHDF, "d", bdgraphBipartDf, &bdgraphbipartstdefaultdf }, { BDGRAPHBIPARTSTMETHEX, "x", bdgraphBipartEx, &bdgraphbipartstdefaultex }, { BDGRAPHBIPARTSTMETHML, "m", bdgraphBipartMl, &bdgraphbipartstdefaultml }, { BDGRAPHBIPARTSTMETHSQ, "q", bdgraphBipartSq, &bdgraphbipartstdefaultsq }, { BDGRAPHBIPARTSTMETHZR, "z", bdgraphBipartZr, NULL }, { -1, NULL, NULL, NULL } }; static StratParamTab bdgraphbipartstparatab[] = { /* Method parameter list */ { BDGRAPHBIPARTSTMETHBD, STRATPARAMINT, "width", (byte *) &bdgraphbipartstdefaultbd.param, (byte *) &bdgraphbipartstdefaultbd.param.distmax, NULL }, { BDGRAPHBIPARTSTMETHBD, STRATPARAMSTRAT, "bnd", (byte *) &bdgraphbipartstdefaultbd.param, (byte *) &bdgraphbipartstdefaultbd.param.stratbnd, (void *) &bdgraphbipartststratab }, { BDGRAPHBIPARTSTMETHBD, STRATPARAMSTRAT, "org", (byte *) &bdgraphbipartstdefaultbd.param, (byte *) &bdgraphbipartstdefaultbd.param.stratorg, (void *) &bdgraphbipartststratab }, { BDGRAPHBIPARTSTMETHDF, STRATPARAMINT, "pass", (byte *) &bdgraphbipartstdefaultdf.param, (byte *) &bdgraphbipartstdefaultdf.param.passnbr, NULL }, { BDGRAPHBIPARTSTMETHDF, STRATPARAMDOUBLE, "dif", (byte *) &bdgraphbipartstdefaultdf.param, (byte *) &bdgraphbipartstdefaultdf.param.cdifval, NULL }, { BDGRAPHBIPARTSTMETHDF, STRATPARAMDOUBLE, "rem", (byte *) &bdgraphbipartstdefaultdf.param, (byte *) &bdgraphbipartstdefaultdf.param.cremval, NULL }, { BDGRAPHBIPARTSTMETHDF, STRATPARAMCASE, "type", (byte *) &bdgraphbipartstdefaultdf.param, (byte *) &bdgraphbipartstdefaultdf.param.typeval, (void *) "bk" }, { BDGRAPHBIPARTSTMETHEX, STRATPARAMINT, "sbbt", (byte *) &bdgraphbipartstdefaultex.param, (byte *) &bdgraphbipartstdefaultex.param.sbbtnbr, NULL }, { BDGRAPHBIPARTSTMETHEX, STRATPARAMDOUBLE, "bal", (byte *) &bdgraphbipartstdefaultex.param, (byte *) &bdgraphbipartstdefaultex.param.deltval, NULL }, { BDGRAPHBIPARTSTMETHML, STRATPARAMSTRAT, "asc", (byte *) &bdgraphbipartstdefaultml.param, (byte *) &bdgraphbipartstdefaultml.param.stratasc, (void *) &bdgraphbipartststratab }, { BDGRAPHBIPARTSTMETHML, STRATPARAMSTRAT, "low", (byte *) &bdgraphbipartstdefaultml.param, (byte *) &bdgraphbipartstdefaultml.param.stratlow, (void *) &bdgraphbipartststratab }, { BDGRAPHBIPARTSTMETHML, STRATPARAMSTRAT, "seq", (byte *) &bdgraphbipartstdefaultml.param, (byte *) &bdgraphbipartstdefaultml.param.stratseq, (void *) &bdgraphbipartststratab }, { BDGRAPHBIPARTSTMETHML, STRATPARAMINT, "pass", (byte *) &bdgraphbipartstdefaultml.param, (byte *) &bdgraphbipartstdefaultml.param.passnbr, NULL }, { BDGRAPHBIPARTSTMETHML, STRATPARAMINT, "vert", (byte *) &bdgraphbipartstdefaultml.param, (byte *) &bdgraphbipartstdefaultml.param.coarnbr, NULL }, { BDGRAPHBIPARTSTMETHML, STRATPARAMINT, "dvert", (byte *) &bdgraphbipartstdefaultml.param, (byte *) &bdgraphbipartstdefaultml.param.foldmax, NULL }, { BDGRAPHBIPARTSTMETHML, STRATPARAMCASE, "fold", (byte *) &bdgraphbipartstdefaultml.param, (byte *) &bdgraphbipartstdefaultml.param.foldval, (void *) "nfd" }, { BDGRAPHBIPARTSTMETHML, STRATPARAMDOUBLE, "rat", (byte *) &bdgraphbipartstdefaultml.param, (byte *) &bdgraphbipartstdefaultml.param.coarrat, NULL }, { BDGRAPHBIPARTSTMETHSQ, STRATPARAMSTRAT, "strat", (byte *) &bdgraphbipartstdefaultsq.param, (byte *) &bdgraphbipartstdefaultsq.param.strat, (void *) &bgraphbipartststratab }, { BDGRAPHBIPARTSTMETHNBR, STRATPARAMINT, NULL, NULL, NULL, NULL } }; static StratParamTab bdgraphbipartstcondtab[] = { /* Active graph condition parameter table */ { STRATNODECOND, STRATPARAMDOUBLE, "bal", (byte *) &bdgraphdummy, (byte *) &bdgraphdummy.bbalglbval, NULL }, { STRATNODECOND, STRATPARAMINT, "edge", (byte *) &bdgraphdummy, (byte *) &bdgraphdummy.s.edgeglbnbr, NULL }, { STRATNODECOND, STRATPARAMINT, "levl", (byte *) &bdgraphdummy, (byte *) &bdgraphdummy.levlnum, NULL }, { STRATNODECOND, STRATPARAMINT, "lmin0", (byte *) &bdgraphdummy, (byte *) &bdgraphdummy.compglbload0min, NULL }, { STRATNODECOND, STRATPARAMINT, "lmax0", (byte *) &bdgraphdummy, (byte *) &bdgraphdummy.compglbload0max, NULL }, { STRATNODECOND, STRATPARAMINT, "load", (byte *) &bdgraphdummy, (byte *) &bdgraphdummy.s.veloglbsum, NULL }, { STRATNODECOND, STRATPARAMINT, "load0", (byte *) &bdgraphdummy, (byte *) &bdgraphdummy.compglbload0, NULL }, { STRATNODECOND, STRATPARAMINT, "proc", (byte *) &bdgraphdummy, (byte *) &bdgraphdummy.s.procglbnbr, NULL }, { STRATNODECOND, STRATPARAMINT, "rank", (byte *) &bdgraphdummy, (byte *) &bdgraphdummy.s.proclocnum, NULL }, { STRATNODECOND, STRATPARAMINT, "vert", (byte *) &bdgraphdummy, (byte *) &bdgraphdummy.s.vertglbnbr, NULL }, { STRATNODENBR, STRATPARAMINT, NULL, NULL, NULL, NULL } }; StratTab bdgraphbipartststratab = { /* Strategy tables for graph bipartitioning methods */ bdgraphbipartstmethtab, bdgraphbipartstparatab, bdgraphbipartstcondtab }; /***********************************************/ /* */ /* This is the generic bipartitioning routine. */ /* */ /***********************************************/ /* This routine performs the bipartitioning of ** the given active graph according to the ** given strategy. ** It returns: ** - 0 : if bipartitioning could be computed. ** - 1 : on error. */ int bdgraphBipartSt ( Bdgraph * restrict const grafptr, /*+ Active graph to bipartition +*/ const Strat * restrict const strat) /*+ Bipartitioning strategy +*/ { StratTest val; /* Result of condition evaluation */ BdgraphStore savetab[2]; /* Results of the two strategies */ int o; int o2; #ifdef SCOTCH_DEBUG_BDGRAPH2 MPI_Comm proccommold; /*Save area for old communicator */ #endif /* SCOTCH_DEBUG_BDGRAPH2 */ #ifdef SCOTCH_DEBUG_BDGRAPH2 if (sizeof (Gnum) != sizeof (INT)) { errorPrint ("bdgraphBipartSt: invalid type specification for parser variables"); return (1); } if (/*(sizeof (BdgraphBipartFmParam) > sizeof (StratNodeMethodData)) || (sizeof (BdgraphBipartGgParam) > sizeof (StratNodeMethodData)) ||*/ (sizeof (BdgraphBipartMlParam) > sizeof (StratNodeMethodData))) { errorPrint ("bdgraphBipartSt: invalid type specification"); return (1); } /* TODO REMOVE */ #endif /* SCOTCH_DEBUG_BDGRAPH2 */ #ifdef SCOTCH_DEBUG_BDGRAPH1 if ((strat->tabl != &bdgraphbipartststratab) && (strat != &stratdummy)) { errorPrint ("bdgraphBipartSt: invalid parameter (1)"); return (1); } #endif /* SCOTCH_DEBUG_BDGRAPH1 */ o = 0; switch (strat->type) { case STRATNODECONCAT : o = bdgraphBipartSt (grafptr, strat->data.concat.strat[0]); /* Apply the first strategy */ if (o == 0) /* If it worked all right */ o |= bdgraphBipartSt (grafptr, strat->data.concat.strat[1]); /* Then apply second strategy */ break; case STRATNODECOND : o = stratTestEval (strat->data.cond.test, &val, (void *) grafptr); /* Evaluate expression */ if (o == 0) { /* If evaluation was correct */ #ifdef SCOTCH_DEBUG_BDGRAPH2 if ((val.typetest != STRATTESTVAL) || (val.typenode != STRATPARAMLOG)) { errorPrint ("bdgraphBipartSt: invalid test result"); o = 1; break; } #endif /* SCOTCH_DEBUG_BDGRAPH2 */ if (val.data.val.vallog == 1) /* If expression is true */ o = bdgraphBipartSt (grafptr, strat->data.cond.strat[0]); /* Apply first strategy */ else { /* Else if expression is false */ if (strat->data.cond.strat[1] != NULL) /* And if there is an else statement */ o = bdgraphBipartSt (grafptr, strat->data.cond.strat[1]); /* Apply second strategy */ } } break; case STRATNODEEMPTY : break; case STRATNODESELECT : if (((bdgraphStoreInit (grafptr, &savetab[0])) != 0) || /* Allocate save areas */ ((bdgraphStoreInit (grafptr, &savetab[1])) != 0)) { errorPrint ("bdgraphBipartSt: out of memory"); bdgraphStoreExit (&savetab[0]); return (1); } bdgraphStoreSave (grafptr, &savetab[1]); /* Save initial bipartition */ o = bdgraphBipartSt (grafptr, strat->data.select.strat[0]); /* Apply first strategy */ bdgraphStoreSave (grafptr, &savetab[0]); /* Save its result */ bdgraphStoreUpdt (grafptr, &savetab[1]); /* Restore initial bipartition */ o2 = bdgraphBipartSt (grafptr, strat->data.select.strat[1]); /* Apply second strategy */ if ((o == 0) || (o2 == 0)) { /* If at least one method did bipartition */ Gnum compglbload0; int b0; int b1; compglbload0 = grafptr->compglbload0avg + savetab[0].compglbload0dlt; b0 = ((compglbload0 < grafptr->compglbload0min) || (compglbload0 > grafptr->compglbload0max)) ? 1 : o; compglbload0 = grafptr->compglbload0avg + savetab[1].compglbload0dlt; b1 = ((compglbload0 < grafptr->compglbload0min) || (compglbload0 > grafptr->compglbload0max)) ? 1 : o2; do { /* Do we want to restore partition 0 ? */ if (b0 > b1) break; if (b0 == b1) { /* If both are valid or invalid */ if (b0 == 0) { /* If both are valid */ if ( (savetab[0].commglbload > grafptr->commglbload) || /* Compare on cut */ ((savetab[0].commglbload == grafptr->commglbload) && (abs (savetab[0].compglbload0dlt) > abs (grafptr->compglbload0dlt)))) break; } else { /* If both are invalid */ if ( (abs (savetab[0].compglbload0dlt) > abs (grafptr->compglbload0dlt)) || /* Compare on imbalance */ ((abs (savetab[0].compglbload0dlt) == abs (grafptr->compglbload0dlt)) && (savetab[0].commglbload > grafptr->commglbload))) break; } } bdgraphStoreUpdt (grafptr, &savetab[0]); /* Restore its result */ } while (0); } if (o2 < o) /* o = min(o,o2): if one biparts, then bipart */ o = o2; /* Else if one stops, then stop, else error */ bdgraphStoreExit (&savetab[0]); /* Free both save areas */ bdgraphStoreExit (&savetab[1]); break; #ifdef SCOTCH_DEBUG_BDGRAPH1 case STRATNODEMETHOD : #else /* SCOTCH_DEBUG_BDGRAPH1 */ default : #endif /* SCOTCH_DEBUG_BDGRAPH1 */ #ifdef SCOTCH_DEBUG_BDGRAPH2 proccommold = grafptr->s.proccomm; /* Create new communicator to isolate method communications */ MPI_Comm_dup (proccommold, &grafptr->s.proccomm); #endif /* SCOTCH_DEBUG_BDGRAPH2 */ o = (strat->tabl->methtab[strat->data.method.meth].func (grafptr, (void *) &strat->data.method.data)); #ifdef SCOTCH_DEBUG_BDGRAPH2 MPI_Comm_free (&grafptr->s.proccomm); /* Restore old communicator */ grafptr->s.proccomm = proccommold; #endif /* SCOTCH_DEBUG_BDGRAPH2 */ #ifdef SCOTCH_DEBUG_BDGRAPH1 break; default : errorPrint ("bdgraphBipartSt: invalid parameter (2)"); return (1); #endif /* SCOTCH_DEBUG_BDGRAPH1 */ } return (o); } scotch-6.0.4.dfsg/src/libscotch/kgraph_map_ex.h0000644002563400244210000001264311631447171024623 0ustar trophimeutilisateurs du domaine/* Copyright 2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph_map_ex.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the load balancing graph mapping **/ /** routines. **/ /** **/ /** DATES : # Version 6.0 : from : 08 jun 2011 **/ /** to 08 jun 2011 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct KgraphMapExParam_ { double kbalval; /*+ Imbalance ratio +*/ } KgraphMapExParam; /*+ This structure holds extended domain information. sonstab[0] == -1 if node is terminal. Else, sonstab[1] == -1 means only one branch is considered at this level. +*/ typedef struct KgraphMapExDom_ { Anum treenum; /*+ Tree node index for this domain +*/ Anum domnwght; /*+ Domain weight +*/ Gnum compload; /*+ Current load in domain +*/ Gnum comploadmax; /*+ Maximum load allowed in domain +*/ } KgraphMapExDom; /*+ This structure records the best candidate domain found to date. +*/ typedef struct KgraphMapExFind_ { Gnum comploaddlt; /*+ Best imbalance +*/ Anum domnnum; /*+ Domain number +*/ } KgraphMapExFind; /*+ This structure allows one to sort vertices by vertex weight. +*/ typedef struct KgraphMapExSort_ { Gnum veloval; /*+ Vertex load +*/ Gnum vertnum; /*+ Vertex number +*/ } KgraphMapExSort; /*+ This structure allows one to sort existing terminal domains by terminal number. +*/ typedef struct KgraphMapExTerm_ { Anum termnum; /*+ Domain terminal number +*/ Anum domnnum; /*+ Domain index in domntab +*/ } KgraphMapExTerm; /*+ This structure holds a recursive bi-mapping tree node. +*/ typedef struct KgraphMapExTree_ { Anum fathnum; /*+ Index of father node; -1 if root +*/ Anum sonstab[2]; /*+ Index of sons; [0] == -1 for terminal +*/ ArchDom domndat; /*+ Subdomain data +*/ } KgraphMapExTree; /* ** The function prototypes. */ #ifndef KGRAPH_MAP_EX #define static #endif int kgraphMapEx (Kgraph * restrict const, const KgraphMapExParam * const); static Anum kgraphMapExTree (const Arch * restrict const, const KgraphMapExTerm * restrict const, const Anum, KgraphMapExDom * restrict const, KgraphMapExTree * restrict const, Anum * restrict const, const ArchDom * restrict const); static Anum kgraphMapExFind (const Arch * restrict const, const KgraphMapExTree * restrict const, const KgraphMapExDom * restrict const, const Anum, const Gnum); static int kgraphMapExFind2 (const Arch * restrict const, const KgraphMapExTree * restrict const, const KgraphMapExDom * restrict const, KgraphMapExFind * restrict const, const Anum, const Anum, const Gnum); #undef static scotch-6.0.4.dfsg/src/libscotch/wgraph.c0000644002563400244210000001332211631447170023273 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : wgraph.c **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Francois PELLEGRINI **/ /** Charles-Edmond BICHOT (5.1b) **/ /** **/ /** FUNCTION : This module contains the data structure **/ /** handling routines for the vertex overl- **/ /** apped graph partitioning **/ /** **/ /** DATES : # Version 5.1 : from : 01 dec 2007 **/ /** to : 01 jul 2008 **/ /** # Version 6.0 : from : 28 may 2010 **/ /** to : 29 may 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define WGRAPH #include "module.h" #include "common.h" #include "graph.h" #include "wgraph.h" /***********************************/ /* */ /* Active graph handling routines. */ /* */ /***********************************/ /* This routine initialize the active graph ** corresponding to the source graph ** It returns: ** - VOID : in all cases. */ void wgraphInit ( Wgraph * restrict const actgrafptr, /* Active graph */ const Graph * restrict const srcgrafptr, /* Source graph */ const Anum partnbr) { actgrafptr->s = *srcgrafptr; /* Clone source graph */ actgrafptr->s.flagval &= ~GRAPHFREETABS; /* Do not free its contents */ actgrafptr->compload = NULL; /* No group leader yet */ actgrafptr->partnbr = partnbr; actgrafptr->parttax = NULL; /* No part array yet */ } /* This routine frees the contents ** of the given active graph ** It returns: ** - VOID : in all cases. */ void wgraphExit ( Wgraph * const grafptr) /* Active graph */ { if (grafptr->compload != NULL) memFree (grafptr->compload); /* Free group leader */ graphExit (&grafptr->s); /* Free source graph */ #ifdef SCOTCH_DEBUG_WGRAPH2 memSet (grafptr, ~0, sizeof (Wgraph)); #endif /* SCOTCH_DEBUG_WGRAPH2 */ } /* This routine builds the active graph ** It returns: ** - 0 : on success. ** - !0 : on error. */ int wgraphAlloc ( Wgraph * const grafptr) /* Active graph */ { Gnum partsiz; Gnum * restrict parttab; partsiz = (grafptr->parttax == NULL) ? grafptr->s.vertnbr : 0; /* Allocate part array only if not already */ if (memAllocGroup ((void **) (void *) &grafptr->compload, (size_t) (grafptr->partnbr * sizeof (Gnum)), &grafptr->compsize, (size_t) (grafptr->partnbr * sizeof (Gnum)), &parttab, (size_t) (partsiz * sizeof (Anum)), &grafptr->frontab, (size_t) (grafptr->s.vertnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("wgraphAlloc: out of memory (1)"); return (1); } if (grafptr->parttax == NULL) /* Part array does not need flag as will be group freed */ grafptr->parttax = parttab - grafptr->s.baseval; return (0); } /* This routine moves all of the graph ** vertices to the first part. ** It returns: ** - VOID : in all cases. */ void wgraphZero ( Wgraph * const grafptr) { memSet (grafptr->compload, 0, grafptr->partnbr * sizeof (Gnum)); memSet (grafptr->compsize, 0, grafptr->partnbr * sizeof (Gnum)); grafptr->compload[0] = grafptr->s.velosum; grafptr->compsize[0] = grafptr->s.vertnbr; grafptr->fronload = 0; grafptr->fronnbr = 0; memSet (grafptr->parttax + grafptr->s.baseval, 0, grafptr->s.vertnbr * sizeof (Anum)); /* Set all vertices to part 0 */ } scotch-6.0.4.dfsg/src/libscotch/library_dgraph_order_io_block_f.c0000644002563400244210000001104612055777536030353 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_order_io_block_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the Fortran API for the **/ /** distributed graph ordering routines of **/ /** the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 28 may 2008 **/ /** to 28 may 2008 **/ /** # Version 5.1 : from : 27 mar 2010 **/ /** to 27 mar 2010 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "ptscotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the ordering routines. */ /* */ /**************************************/ FORTRAN ( \ SCOTCHFDGRAPHORDERSAVEBLOCK, scotchfdgraphordersaveblock, ( \ const SCOTCH_Dgraph * const grafptr, \ const SCOTCH_Dordering * const ordeptr, \ int * const fileptr, \ int * const revaptr), \ (grafptr, ordeptr, fileptr, revaptr)) { FILE * stream; /* Stream to build from handle */ int filenum; /* Duplicated handle */ int o; if (*fileptr == -1) /* If process is not the root */ stream = NULL; else { /* Open stream for root process */ if ((filenum = dup (*fileptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFDGRAPHORDERSAVEBLOCK: cannot duplicate handle"); *revaptr = 1; /* Indicate error */ return; } if ((stream = fdopen (filenum, "w")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFDGRAPHORDERSAVEBLOCK: cannot open output stream"); close (filenum); *revaptr = 1; return; } } o = SCOTCH_dgraphOrderSaveBlock (grafptr, ordeptr, stream); if (stream != NULL) fclose (stream); /* This closes filenum too */ *revaptr = o; } scotch-6.0.4.dfsg/src/libscotch/wgraph_part_fm.h0000644002563400244210000001446512056100734025013 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : wgraph_part_fm.h **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Charles-Edmond BICHOT (v5.1b) **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the improved Fiduccia-Mattheyses **/ /** refinement routine for the vertex over- **/ /** lapped graph partitioning. **/ /** **/ /** DATES : # Version 5.1 : from : 01 dec 2007 **/ /** to : 01 jul 2008 **/ /** # Version 6.0 : from : 05 nov 2009 **/ /** to : 30 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ Gain table subbits. +*/ #define WGRAPHSEPAFMGAINBITS 4 /*+ Prime number for hashing vertex numbers. +*/ #define WGRAPHSEPAFMHASHPRIME 17 /*+ Prime number for hashing +*/ /*+ +*/ #define WGRAPHSEPAFMMAXPARTLOAD ((Gnum) (((Gunum) ~0) >> 1)) /*+ Gain table vertex status. +*/ #define WGRAPHSEPAFMSTATEFREE ((GainLink *) 0) /*+ Vertex is free or separator-chained +*/ #define WGRAPHSEPAFMSTATESUCH ((GainLink *) 1) /*+ Separator vertex is used and chained +*/ #define WGRAPHSEPAFMSTATEUSED ((GainLink *) 2) /*+ Vertex already swapped once +*/ #define WGRAPHSEPAFMSTATELINK ((GainLink *) 3) /*+ Currently in gain table if higher +*/ /*+ Save type identifier +*/ #define WGRAPHSEPAFMSAVEMOVE 0 #define WGRAPHSEPAFMSAVELINKDEL 1 #define WGRAPHSEPAFMSAVELINKADD 2 #define WGRAPHSEPAFMSAVELOAD 3 /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct WgraphPartFmParam_ { INT movenbr; /*+ Maximum number of uneffective moves that can be done +*/ INT passnbr; /*+ Number of passes to be performed (-1 : infinite) +*/ double deltrat; /*+ Maximum weight imbalance ratio +*/ } WgraphPartFmParam; typedef struct WgraphPartFmPartList_ { struct WgraphPartFmPartList_ * prev; Gnum gain; struct WgraphPartFmPartList_ * loadprev; Gnum loadgain; Gnum sizegain; Gnum isinloadlist; } WgraphPartFmPartList; typedef struct WgraphPartFmVertex_ { Gnum partval; /*+ Vertex part TRICK: same type as vertload +*/ Gnum partval2; /*+ Vertex part into which the current vertex moves +*/ Gnum vertnum; /*+ Number of vertex in hash table +*/ struct WgraphPartFmVertex_ * prev; struct WgraphPartFmLink_ * linklist; Gnum linked; struct WgraphPartFmVertex_ * lockprev; } WgraphPartFmVertex; /*+ The move recording structure. +*/ typedef struct WgraphPartFmLink_ { GainLink gainlink; /*+ Gain link: FIRST +*/ Gnum partval; Gnum hashnum; Gnum gain; struct WgraphPartFmLink_ * next; Gnum minloadpartval; Gnum minloadpartload; } WgraphPartFmLink; typedef struct WgraphPartFmSave_ { Gnum type; union { struct { Gnum hashnum; /*+ Number of hash slot for saved vertex +*/ Gnum partval; /*+ Saved vertex part value +*/ } movedata; struct { Gnum linknum; Gnum gain; } linkdata; struct { Gnum loaddiff; Gnum sizediff; Gnum partval; } loaddata; } u; } WgraphPartFmSave; /* ** The function prototypes. */ #ifndef WGRAPH_PART_FM #define static #endif int wgraphPartFm (Wgraph * const, const WgraphPartFmParam * const); static int wgraphPartFmResize (); static int wgraphPartFmCheck (const Wgraph * restrict const, const WgraphPartFmVertex * restrict const, Gnum, const Gnum, const Gnum); #undef static scotch-6.0.4.dfsg/src/libscotch/dorder_io_block.c0000644002563400244210000001143011631447170025121 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dorder_io_block.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles distributed **/ /** orderings. **/ /** **/ /** DATES : # Version 5.0 : from : 26 may 2008 **/ /** to 26 may 2008 **/ /** # Version 5.1 : from : 11 aug 2010 **/ /** to 11 aug 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DORDER #include "module.h" #include "common.h" #include "dgraph.h" #include "order.h" #include "dorder.h" /************************************/ /* */ /* These routines handle orderings. */ /* */ /************************************/ /* This routine saves a distributed ordering on ** a combined block ordering format. ** The distributed graph structure is provided ** to access the distribution of vertex labels, ** whenever present. ** It returns: ** - 0 : on success. ** - !0 : on error. */ static int dorderSaveBlock2 ( const Order * const cordptr, const Gnum * const vlbltab, FILE * const stream) { Gnum vertnum; Gnum * restrict rangtab; Gnum cblknum; int o; if ((rangtab = memAlloc ((cordptr->vnodnbr + 1) * sizeof (Gnum))) == NULL) { errorPrint ("dorderSaveBlock2: out of memory"); return (1); } orderRang (cordptr, rangtab); if (fprintf (stream, "0\n" GNUMSTRING "\t" GNUMSTRING "\n", (Gnum) cordptr->cblknbr, (Gnum) cordptr->vnodnbr) < 0) { errorPrint ("dorderSaveBlock2: bad output (1)"); return (1); } for (cblknum = 0, o = 1; (o == 1) && (cblknum < cordptr->cblknbr); cblknum ++) { /* Save column-block range array */ o = intSave (stream, rangtab[cblknum]); putc (((cblknum & 7) == 7) ? '\n' : '\t', stream); } o = intSave (stream, rangtab[cblknum]); putc ('\n', stream); orderPeri (cordptr->peritab, cordptr->baseval, cordptr->vnodnbr, rangtab, cordptr->baseval); /* TRICK: re-use rangtab as permtab */ for (vertnum = 0; (o == 1) && (vertnum < (cordptr->vnodnbr - 1)); vertnum ++) { /* Save direct permutation */ o = intSave (stream, rangtab[vertnum]); putc (((vertnum & 7) == 7) ? '\n' : '\t', stream); } o = intSave (stream, rangtab[vertnum]); putc ('\n', stream); if (o != 1) errorPrint ("dorderSaveBlock2: bad output (2)"); return (1 - o); } int dorderSaveBlock ( const Dorder * restrict const ordeptr, const Dgraph * restrict const grafptr, FILE * restrict const stream) { return (dorderSaveTree2 (ordeptr, grafptr, stream, dorderSaveBlock2)); } scotch-6.0.4.dfsg/src/libscotch/library_graph_base.c0000644002563400244210000000625611631447170025632 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_base.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the source **/ /** graph handling routines of the **/ /** libSCOTCH library. **/ /** **/ /** DATES : # Version 4.0 : from : 22 apr 2004 **/ /** to 22 apr 2004 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "graph.h" #include "scotch.h" /************************************/ /* */ /* These routines are the C API for */ /* the graph handling routines. */ /* */ /************************************/ /* This routine sets the base of the given ** graph to the given base value, and returns ** the old base value. ** It returns: ** - old base value : in all cases. */ SCOTCH_Num SCOTCH_graphBase ( SCOTCH_Graph * const grafptr, const SCOTCH_Num baseval) { return ((SCOTCH_Num) graphBase ((Graph * const) grafptr, (Gnum) baseval)); } scotch-6.0.4.dfsg/src/libscotch/dorder_perm.c0000644002563400244210000002457211631447170024316 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dorder_gather.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles distributed **/ /** orderings. **/ /** **/ /** DATES : # Version 5.0 : from : 13 oct 2007 **/ /** to 21 oct 2007 **/ /** # Version 5.1 : from : 26 sep 2008 **/ /** to 26 sep 2008 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DORDER #include "module.h" #include "common.h" #include "dgraph.h" #include "dorder.h" #include "dorder_perm.h" /************************************/ /* */ /* These routines handle orderings. */ /* */ /************************************/ /* This function builds a distributed direct ** permutation from the information stored ** in the distributed ordering structure. ** It returns: ** - 0 : if the distributed permutation could be computed. ** - !0 : on error. */ int dorderPerm ( const Dorder * restrict const ordeptr, const Dgraph * restrict const grafptr, Gnum * restrict const permloctab) { Gnum * restrict permloctax; int * restrict sendcnttab; int * restrict senddsptab; int * restrict recvcnttab; int * restrict recvdsptab; DorderPermSort * restrict sortsndtab; DorderPermSort * restrict sortrcvtab; const DorderLink * restrict linklocptr; Gnum vnodlocnbr; Gnum vnodlocnum; int vnodrcvnbr; int vnodsndnbr; int procnum; Gnum reduloctab[2]; Gnum reduglbtab[2]; for (linklocptr = ordeptr->linkdat.nextptr, vnodlocnbr = 0; /* For all nodes in local ordering structure */ linklocptr != &ordeptr->linkdat; linklocptr = linklocptr->nextptr) { const DorderCblk * restrict cblklocptr; cblklocptr = (DorderCblk *) linklocptr; /* TRICK: FIRST */ if ((cblklocptr->typeval & DORDERCBLKLEAF) != 0) /* If node is leaf */ vnodlocnbr += cblklocptr->data.leaf.vnodlocnbr; /* And more node vertices */ #ifdef SCOTCH_DEBUG_DORDER2 else if (cblklocptr->typeval != DORDERCBLKNEDI) { errorPrint ("dorderPerm: invalid parameters (1)"); return (1); } #endif /* SCOTCH_DEBUG_DORDER2 */ } reduloctab[0] = vnodlocnbr; reduloctab[1] = 0; if (memAllocGroup ((void **) (void *) &senddsptab, (size_t) (grafptr->procglbnbr * sizeof (int)), &sendcnttab, (size_t) (grafptr->procglbnbr * sizeof (int)), &recvdsptab, (size_t) (grafptr->procglbnbr * sizeof (int)), &recvcnttab, (size_t) (grafptr->procglbnbr * sizeof (int)), &sortsndtab, (size_t) ((vnodlocnbr + 1) * sizeof (DorderPermSort)), /* "+1" for end marker */ &sortrcvtab, (size_t) (grafptr->vertlocnbr * sizeof (DorderPermSort)), NULL) == NULL) { errorPrint ("dorderPerm: out of memory"); reduloctab[1] = 1; } if (MPI_Allreduce (reduloctab, reduglbtab, 2, GNUM_MPI, MPI_SUM, ordeptr->proccomm) != MPI_SUCCESS) { errorPrint ("dorderPerm: communication error (1)"); reduglbtab[1] = 1; } if (reduglbtab[1] != 0) { if (senddsptab != NULL) memFree (senddsptab); /* Free group leader */ return (1); } if (reduglbtab[0] == 0) { /* If ordering structure is empty */ Gnum ordelocval; /* Based permutation start index */ memFree (senddsptab); /* Free group leader */ for (vnodlocnum = 0, ordelocval = grafptr->procvrttab[grafptr->proclocnum]; /* Build identity permutation */ vnodlocnum < grafptr->vertlocnbr; vnodlocnum ++) permloctab[vnodlocnum] = ordelocval ++; return (0); } if (reduglbtab[0] != grafptr->vertglbnbr) { errorPrint ("dorderPerm: invalid parameters (2)"); memFree (senddsptab); /* Free group leader */ return (1); } for (linklocptr = ordeptr->linkdat.nextptr, vnodlocnum = 0; /* For all nodes in local ordering structure */ linklocptr != &ordeptr->linkdat; linklocptr = linklocptr->nextptr) { const DorderCblk * restrict cblklocptr; cblklocptr = (DorderCblk *) linklocptr; /* TRICK: FIRST */ if ((cblklocptr->typeval & DORDERCBLKLEAF) != 0) { /* If node is leaf */ Gnum leaflocnbr; Gnum leaflocnum; Gnum ordelocval; /* Based permutation start index */ for (leaflocnum = 0, leaflocnbr = cblklocptr->data.leaf.vnodlocnbr, ordelocval = cblklocptr->data.leaf.ordelocval + ordeptr->baseval; leaflocnum < leaflocnbr; leaflocnum ++, vnodlocnum ++) { sortsndtab[vnodlocnum].vertnum = cblklocptr->data.leaf.periloctab[leaflocnum]; sortsndtab[vnodlocnum].permnum = ordelocval + leaflocnum; #ifdef SCOTCH_DEBUG_DORDER2 if ((sortsndtab[vnodlocnum].vertnum < ordeptr->baseval) || (sortsndtab[vnodlocnum].vertnum > (ordeptr->baseval + ordeptr->vnodglbnbr)) || (sortsndtab[vnodlocnum].permnum < ordeptr->baseval) || (sortsndtab[vnodlocnum].permnum > (ordeptr->baseval + ordeptr->vnodglbnbr))) { errorPrint ("dorderPerm: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_DORDER2 */ } } } sortsndtab[vnodlocnbr].vertnum = /* Set end marker */ sortsndtab[vnodlocnbr].permnum = GNUMMAX; intSort2asc1 (sortsndtab, vnodlocnbr); /* Sort permutation array by original vertex numbers, without marker */ for (vnodlocnum = 0, procnum = 0; procnum < grafptr->procglbnbr; ) { Gnum vnodsndnbr; Gnum procdspval; vnodsndnbr = 0; procdspval = grafptr->procdsptab[procnum + 1]; while (sortsndtab[vnodlocnum].vertnum < procdspval) { vnodsndnbr ++; vnodlocnum ++; #ifdef SCOTCH_DEBUG_DORDER2 if (vnodlocnum > vnodlocnbr) { /* If beyond regular indices plus end marker */ errorPrint ("dorderPerm: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_DORDER2 */ } sendcnttab[procnum ++] = (int) (vnodsndnbr * 2); /* Communication array for MPI, so (int), and "*2" because a Sort is 2 Gnums */ } #ifdef SCOTCH_DEBUG_DORDER2 if (vnodlocnum != vnodlocnbr) { errorPrint ("dorderPerm: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_DORDER2 */ if (MPI_Alltoall (sendcnttab, 1, MPI_INT, recvcnttab, 1, MPI_INT, ordeptr->proccomm) != MPI_SUCCESS) { errorPrint ("dorderPerm: communication error (2)"); return (1); } for (procnum = 0, vnodrcvnbr = vnodsndnbr = 0; procnum < grafptr->procglbnbr; procnum ++) { /* Accumulate send and receive indices */ recvdsptab[procnum] = vnodrcvnbr; vnodrcvnbr += recvcnttab[procnum]; /* Accumulate "*2" values as counts */ senddsptab[procnum] = vnodsndnbr; vnodsndnbr += sendcnttab[procnum]; } if (MPI_Alltoallv (sortsndtab, sendcnttab, senddsptab, GNUM_MPI, sortrcvtab, recvcnttab, recvdsptab, GNUM_MPI, ordeptr->proccomm) != MPI_SUCCESS) { errorPrint ("dorderPerm: communication error (3)"); return (1); } #ifdef SCOTCH_DEBUG_DORDER2 memSet (permloctab, ~0, grafptr->vertlocnbr * sizeof (Gnum)); #endif /* SCOTCH_DEBUG_DORDER2 */ permloctax = permloctab - grafptr->procdsptab[grafptr->proclocnum]; /* Base local array through global indices */ for (vnodlocnum = 0; vnodlocnum < grafptr->vertlocnbr; vnodlocnum ++) { #ifdef SCOTCH_DEBUG_DORDER2 if (permloctax[sortrcvtab[vnodlocnum].vertnum] != ~0) { errorPrint ("dorderPerm: internal error (4)"); return (1); } #endif /* SCOTCH_DEBUG_DORDER2 */ permloctax[sortrcvtab[vnodlocnum].vertnum] = sortrcvtab[vnodlocnum].permnum; } #ifdef SCOTCH_DEBUG_DORDER2 for (vnodlocnum = 0; vnodlocnum < grafptr->vertlocnbr; vnodlocnum ++) { if (permloctab[vnodlocnum] == ~0) { errorPrint ("dorderPerm: internal error (5)"); return (1); } } #endif /* SCOTCH_DEBUG_DORDER2 */ memFree (senddsptab); /* Free group leader */ return (0); } scotch-6.0.4.dfsg/src/libscotch/arch_cmpltw.h0000644002563400244210000001337512410344531024314 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2010,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : arch_cmpltw.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the weighted complete graph target **/ /** architecture functions. **/ /** **/ /** DATES : # Version 5.1 : from : 11 dec 2007 **/ /** to 04 nov 2010 **/ /** # Version 6.0 : from : 14 fev 2011 **/ /** to 23 sep 2014 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ #ifndef ARCH_CMPLTW_H_STRUCT #define ARCH_CMPLTW_H_STRUCT /*+ The weighted target vertex. Since Anum's are INT's, they can be sorted, by means of the intSort2asc1 routine. +*/ typedef struct ArchCmpltwLoad_ { Anum veloval; /*+ Vertex load +*/ Anum vertnum; /*+ Vertex index +*/ } ArchCmpltwLoad; /*+ The weighted complete graph definitions. +*/ typedef struct ArchCmpltw_ { Anum vertnbr; /*+ Number of vertices +*/ ArchCmpltwLoad * velotab; /*+ Vertex index array +*/ Anum velosum; /*+ Sum of all weights +*/ } ArchCmpltw; /*+ The weighted domain structure. +*/ typedef struct ArchCmpltwDom_ { Anum vertmin; /*+ Minimum vertex number +*/ Anum vertnbr; /*+ Number of vertices +*/ Anum veloval; /*+ Weight of subdomain +*/ } ArchCmpltwDom; #endif /* ARCH_CMPLTW_H_STRUCT */ /* ** The function prototypes. */ #ifndef ARCH_NOPROTO #ifndef ARCH_CMPLTW_H_PROTO #define ARCH_CMPLTW_H_PROTO #ifndef ARCH_CMPLTW #define static #endif int archCmpltwArchBuild (ArchCmpltw * restrict const archptr, const Anum, const Anum * restrict const); int archCmpltwArchLoad (ArchCmpltw * restrict const, FILE * restrict const); int archCmpltwArchSave (const ArchCmpltw * const, FILE * restrict const); int archCmpltwArchFree (ArchCmpltw * restrict const); ArchDomNum archCmpltwDomNum (const ArchCmpltw * const, const ArchCmpltwDom * const); int archCmpltwDomTerm (const ArchCmpltw * const, ArchCmpltwDom * restrict const, const ArchDomNum); Anum archCmpltwDomSize (const ArchCmpltw * const, const ArchCmpltwDom * const); Anum archCmpltwDomWght (const ArchCmpltw * const, const ArchCmpltwDom * const); Anum archCmpltwDomDist (const ArchCmpltw * const, const ArchCmpltwDom * const, const ArchCmpltwDom * const); int archCmpltwDomFrst (const ArchCmpltw * const, ArchCmpltwDom * const); int archCmpltwDomLoad (const ArchCmpltw * const, ArchCmpltwDom * const, FILE * const); int archCmpltwDomSave (const ArchCmpltw * const, const ArchCmpltwDom * const, FILE * const); int archCmpltwDomBipart (const ArchCmpltw * const, const ArchCmpltwDom * const, ArchCmpltwDom * restrict const, ArchCmpltwDom * restrict const); int archCmpltwDomIncl (const ArchCmpltw * const, const ArchCmpltwDom * const, const ArchCmpltwDom * const); #ifdef SCOTCH_PTSCOTCH int archCmpltwDomMpiType (const ArchCmpltw * const, MPI_Datatype * const); #endif /* SCOTCH_PTSCOTCH */ #undef static #endif /* ARCH_CMPLTW_H_PROTO */ #endif /* ARCH_NOPROTO */ scotch-6.0.4.dfsg/src/libscotch/kgraph_map_fm.c0000644002563400244210000024616212400054205024574 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph_map_fm.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module refines a k-way mapping of **/ /** the given mapping graph by applying a **/ /** Fiduccia-Mattheyses-like gradient **/ /** method. **/ /** **/ /** DATES : # Version 6.0 : from : 03 mar 2011 **/ /** to 23 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define KGRAPH_MAP_FM #define SCOTCH_TABLE_GAIN #include "module.h" #include "common.h" #include "gain.h" #include "fibo.h" #include "graph.h" #include "arch.h" #include "mapping.h" #include "parser.h" #include "kgraph.h" #include "kgraph_map_fm.h" #include "kgraph_map_st.h" /* ** The static variables. */ static const Gnum kgraphloadone = 1; static const Gnum kgraphnotfixed = -1; /*********************************/ /* */ /* Gain table handling routines. */ /* */ /*********************************/ /* This routine returns the vertex of best gain ** whose swap will keep the balance correct. ** It returns: ** - !NULL : pointer to the vertex. ** - NULL : if no more vertices available. */ #ifdef SCOTCH_TABLE_GAIN static KgraphMapFmEdge * kgraphMapFmTablGet ( KgraphMapFmTabl * restrict const tablptr, /*+ Gain table +*/ KgraphMapFmVertex * restrict const vexxtab, /*+ Extended vertex hash table array +*/ const Gnum * restrict const comploaddlt, /*+ Current imbalance array +*/ const Gnum * restrict const comploadmax, /*+ Maximum imbalance array +*/ Gnum * restrict comploaddiff, Gnum * restrict flagval) { GainTabl * gaintab; KgraphMapFmEdge * edxxptr; KgraphMapFmEdge * edxxbest; Gnum gainbest; const GainEntr * restrict tablbest; Gnum deltbest; gaintab = *tablptr; tablbest = gaintab->tend; /* Assume no candidate vertex found yet */ gainbest = GAINMAX; edxxbest = NULL; deltbest = GNUMMAX; for (edxxptr = (KgraphMapFmEdge *) gainTablFrst (gaintab); /* Select candidate edges */ (edxxptr != NULL) && (edxxptr->gainlink.tabl < tablbest); edxxptr = (KgraphMapFmEdge *) gainTablNext (gaintab, &edxxptr->gainlink)) { Gnum vexxidx; Gnum veloval; Anum domnnumold; Anum domnnumnew; Gnum deltvalold; Gnum deltvalnew; Gnum deltnew; Gnum commgain; vexxidx = edxxptr->vexxidx; veloval = vexxtab[vexxidx].veloval; #ifdef SCOTCH_DEBUG_KGRAPH2 if (vexxtab[vexxidx].lockptr != NULL) { /* If vertex is locked */ errorPrint ("kgraphMapFmTablGet: internal error (1)"); return (NULL); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ domnnumold = vexxtab[vexxidx].domnnum; domnnumnew = edxxptr->domnnum; deltvalold = abs (comploaddlt[domnnumold] - veloval); deltvalnew = abs (comploaddlt[domnnumnew] + veloval); if (((deltvalold > comploadmax[domnnumold]) && (deltvalold >= abs (comploaddlt[domnnumold]))) || /* If vertex does not enforce or improve balance, skip it */ ((deltvalnew > comploadmax[domnnumnew]) && (deltvalnew >= abs (comploaddlt[domnnumnew])))) { if (edxxptr->cmigmask == ~0) { edxxptr->cmigmask = 0; kgraphMapFmTablDel (&gaintab, edxxptr); kgraphMapFmTablAdd (&gaintab, edxxptr); } continue; } deltnew = deltvalold - abs (comploaddlt[domnnumold]) + /* Compute difference in imbalance load sum */ deltvalnew - abs (comploaddlt[domnnumnew]); commgain = edxxptr->commgain + edxxptr->cmiggain; if ((commgain < gainbest) || /* And if it gives better gain */ ((commgain == gainbest) && /* Or if it gives better load */ (deltnew < deltbest))) { tablbest = edxxptr->gainlink.tabl; /* Select it */ gainbest = commgain; edxxbest = edxxptr; deltbest = deltnew; if ((abs (comploaddlt[domnnumold]) > comploadmax[domnnumold]) || (abs (comploaddlt[domnnumnew]) > comploadmax[domnnumnew])) *flagval = 1; else *flagval = 0; } } if (edxxbest != NULL) *comploaddiff += deltbest; return (edxxbest); } #else /* SCOTCH_TABLE_GAIN */ /* kgraphMapFmCmpFunc(a,b) must return a negative ** number if a is "better" than b. The smaller, the ** better. */ static int kgraphMapFmCmpFunc ( const FiboNode * const data0ptr, /* TRICK: KgraphMapFmLink is FIRST in KgraphMapFmEdge */ const FiboNode * const data1ptr) { const KgraphMapFmEdge * const node0ptr = (KgraphMapFmEdge *) data0ptr; const KgraphMapFmEdge * const node1ptr = (KgraphMapFmEdge *) data1ptr; Gnum node0val; Gnum node1val; node0val = node0ptr->commgain + node0ptr->cmiggain; node1val = node1ptr->commgain + node1ptr->cmiggain; if (node0val < node1val) return (-1); if (node0val > node1val) return (1); return (0); } static KgraphMapFmEdge * kgraphMapFmTablGet ( KgraphMapFmTabl * restrict const tablptr, /*+ Gain table +*/ KgraphMapFmVertex * restrict const vexxtab, /*+ Extended vertex hash table array +*/ const Gnum * restrict const comploaddlt, /*+ Current imbalance array +*/ const Gnum * restrict const comploadmax, /*+ Maximum imbalance array +*/ Gnum * restrict comploaddiff, Gnum * restrict flagval) { FiboNode * remoptr; /* List of removed links */ KgraphMapFmEdge * edxxptr; Gnum deltnew; FiboNode * linkptr; /* Pointer to current gain link */ edxxptr = NULL; remoptr = NULL; while ((linkptr = fiboTreeMin (tablptr)) != NULL) { /* Select candidate vertices */ Gnum vexxidx; Gnum veloval; Anum domnnumold; Anum domnnumnew; Gnum deltvalold; Gnum deltvalnew; edxxptr = (KgraphMapFmEdge *) linkptr; vexxidx = edxxptr->vexxidx; veloval = vexxtab[vexxidx].veloval; #ifdef SCOTCH_DEBUG_KGRAPH2 if (vexxtab[vexxidx].lockptr != NULL) { /* If vertex is locked */ errorPrint ("kgraphMapFmTablGet: internal error (2)"); return (NULL); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ fiboTreeDel (tablptr, linkptr); /* Remove vertex link from table */ linkptr->linkdat.prevptr = remoptr; /* Node has been removed but is not kept */ remoptr = linkptr; /* It will be chained back afterwards */ domnnumold = vexxtab[vexxidx].domnnum; domnnumnew = edxxptr->domnnum; deltvalold = abs (comploaddlt[domnnumold] - veloval); deltvalnew = abs (comploaddlt[domnnumnew] + veloval); if (((deltvalold <= comploadmax[domnnumold]) || (deltvalold < abs (comploaddlt[domnnumold]))) && /* If vertex does enforce or improve balance, keep it */ ((deltvalnew <= comploadmax[domnnumnew]) || (deltvalnew < abs (comploaddlt[domnnumnew])))) { deltnew = deltvalold - abs (comploaddlt[domnnumold]) + /* Compute difference in imbalance load sum */ deltvalnew - abs (comploaddlt[domnnumnew]); if ((abs (comploaddlt[domnnumold]) > comploadmax[domnnumold]) || (abs (comploaddlt[domnnumnew]) > comploadmax[domnnumnew])) *flagval = 1; break; } else { if (edxxptr->cmigmask == ~0) { edxxptr->cmigmask = 0; kgraphMapFmTablDel (&gaintab, edxxptr); kgraphMapFmTablAdd (&gaintab, edxxptr); } } } while (remoptr != NULL) { /* Put back all temporarily removed nodes */ FiboNode * tempptr; tempptr = remoptr; /* Get pointer to node */ remoptr = remoptr->linkdat.prevptr; /* Find next node */ fiboTreeAdd (tablptr, tempptr); /* Re-link node */ } if (linkptr == NULL) return (NULL); *comploaddiff += deltnew; return (edxxptr); } #endif /* SCOTCH_TABLE_GAIN */ /* This routine checks the consistency of ** the hash structures. ** It returns: ** - 0 : in case of success. ** - !0 : in case of error. */ #ifdef SCOTCH_DEBUG_KGRAPH3 static int kgraphMapFmCheck ( KgraphMapFmTabl * restrict const tablptr, /*+ Gain table +*/ const Kgraph * restrict const grafptr, const KgraphMapFmVertex * restrict const vexxtab, const KgraphMapFmEdge * const edxxtab, /*+ Extended edge array +*/ const Gnum hashmsk, const Gnum commload, Gnum * const chektab) { Gnum vexxidx; Gnum edxxidx; Gnum commloadtmp; Anum domnnum; Anum * restrict const parttax = grafptr->m.parttax; const Gnum * restrict const verttax = grafptr->s.verttax; const Gnum * restrict const vendtax = grafptr->s.vendtax; const Gnum * restrict const edlotax = grafptr->s.edlotax; const Gnum * restrict const edgetax = grafptr->s.edgetax; const Gnum * restrict const vmlotax = grafptr->r.vmlotax; Gnum * const edlosumtab = chektab; Gnum * const edgenbrtab = chektab + grafptr->m.domnnbr; Gnum * const commgaintab = chektab + (grafptr->m.domnnbr * 2); commloadtmp = 0; for (vexxidx = 0; vexxidx <= hashmsk; vexxidx ++) { /* For all vertex slots */ Gnum vertnum; Gnum edgenum; Anum domnorg; Anum domnlst; /* Domain of last vertex for which a distance was computed */ Anum distlst; /* Last distance computed */ Gnum commloadloctmp; Gnum edlosum; Gnum edgenbr; commloadloctmp = 0; vertnum = vexxtab[vexxidx].vertnum; if ((vertnum == ~0)) /* If unallocated */ continue; /* Skip to next slot */ domnorg = vexxtab[vexxidx].domnnum; if ((domnorg < 0) || (domnorg >= grafptr->m.domnnbr)) { errorPrint ("kgraphMapFmCheck: invalid vertex part value"); return (1); } if (domnorg != parttax[vertnum]) { errorPrint ("kgraphMapFmCheck: invalid extended vertex part value"); return (1); } edxxidx = vexxtab[vexxidx].edxxidx; if ((edxxidx >= 0) && (edxxtab[edxxidx].vexxidx != vexxidx)) { errorPrint ("kgraphMapFmCheck: invalid extended vertex pointer in extended edge"); return (1); } edlosum = edgenbr = 0; domnlst = -1; /* Invalid domnain to recompute distance */ memSet (edlosumtab, 0, grafptr->m.domnnbr * 3 * sizeof(Gnum)); /* Reset edlosumtab, edgenbrtab and commgaintab */ for (edgenum = verttax[vertnum]; /* For all neighbors */ edgenum < vendtax[vertnum]; edgenum ++) { Gnum vertend; Anum domnend; Gnum edloval; vertend = edgetax[edgenum]; domnend = parttax[vertend]; edloval = (edlotax != NULL) ? edlotax[edgenum] : 1; if (domnorg != domnend) { Anum distval; distval = (domnend != domnlst) ? archDomDist (grafptr->m.archptr, &grafptr->m.domntab[domnorg], &grafptr->m.domntab[domnend]) : distlst; distlst = distval; domnlst = domnend; edlosumtab[domnend] += edloval; edgenbrtab[domnend] ++; commloadloctmp += (Gnum) distval * edloval * grafptr->r.crloval; for (edxxidx = vexxtab[vexxidx].edxxidx; (edxxidx != -1) && (edxxtab[edxxidx].domnnum != domnend) ; edxxidx = edxxtab[edxxidx].edxxidx) ; /* Search if edge slot exists */ if (edxxidx == -1) { Gnum vertndd; Gnum vexxndd; vertndd = edgetax[edgenum]; for (vexxndd = 0; (vexxtab[vexxndd].vertnum != vertndd) && (vexxndd <= hashmsk); vexxndd ++) ; /* For all vertex slots */ errorPrint ("kgraphMapFmCheck: no link for migration of vertex %d to domain %d", vexxtab[vexxidx].vertnum, domnend); return (1); } } else { edlosum += edloval; edgenbr ++; } } if (edlosum != vexxtab[vexxidx].edlosum) { errorPrint ("kgraphMapFmCheck: invalid edge load sum for vertex %d", vexxtab[vexxidx].vertnum); return (1); } if (edgenbr != vexxtab[vexxidx].edgenbr) { errorPrint ("kgraphMapFmCheck: invalid edge number for vertex %d", vexxtab[vexxidx].vertnum); return (1); } commloadtmp += commloadloctmp; for (edxxidx = vexxtab[vexxidx].edxxidx; edxxidx != -1; edxxidx = edxxtab[edxxidx].edxxidx) { Gnum domncur; Gnum domnflg; domnflg = 0; domncur = edxxtab[edxxidx].domnnum; commgaintab[domncur] = -commloadloctmp; for (edgenum = verttax[vertnum]; edgenum < vendtax[vertnum]; edgenum ++) { Gnum vertend; Anum domnend; Gnum edloval; vertend = edgetax[edgenum]; domnend = parttax[vertend]; edloval = (edlotax != NULL) ? edlotax[edgenum] : 1; if (domnend == domncur) { domnflg = 1; continue; } edloval *= grafptr->r.crloval; commgaintab[domncur] += edloval /* Add edge contribution to target domain */ * archDomDist (&grafptr->a, &grafptr->m.domntab[domncur], &grafptr->m.domntab[domnend]); } if (domnflg == 0) { errorPrint ("kgraphMapFmCheck: extra link for migration of vertex %d to domain %d", vexxtab[vexxidx].vertnum, domncur); return (1); } } if ((vexxtab[vexxidx].domoptr != NULL) && (vexxtab[vexxidx].cmigload != (archDomIncl (grafptr->m.archptr, &grafptr->m.domntab[domnorg], vexxtab[vexxidx].domoptr) == 1) ? 0 : grafptr->r.cmloval * ((vmlotax != NULL) ? vmlotax[vertnum] : 1) * archDomDist (grafptr->m.archptr, &grafptr->m.domntab[domnorg], vexxtab[vexxidx].domoptr))) { errorPrint ("kgraphMapFmCheck: invalid migration communication load for extended vertex"); return (1); } for (edxxidx = vexxtab[vexxidx].edxxidx; edxxidx != -1; edxxidx = edxxtab[edxxidx].edxxidx) { /* For vertex links */ if (edlosumtab[edxxtab[edxxidx].domnnum] != edxxtab[edxxidx].edlosum) { errorPrint ("kgraphMapFmCheck: invalid extended edge edlosum value"); return (1); } if (edgenbrtab[edxxtab[edxxidx].domnnum] != edxxtab[edxxidx].edgenbr) { errorPrint ("kgraphMapFmCheck: invalid extended edge edgenbr value"); return (1); } if (commgaintab[edxxtab[edxxidx].domnnum] != edxxtab[edxxidx].commgain) { errorPrint ("kgraphMapFmCheck: invalid extended edge commgain value"); return (1); } if ((vexxtab[vexxidx].domoptr != NULL) && (edxxtab[edxxidx].cmiggain + vexxtab[vexxidx].cmigload != (archDomIncl (&grafptr->a, &grafptr->m.domntab[edxxtab[edxxidx].domnnum], vexxtab[vexxidx].domoptr) == 1) ? 0 : grafptr->r.cmloval * ((vmlotax != NULL) ? vmlotax[vertnum] : 1) * archDomDist (&grafptr->a, &grafptr->m.domntab[edxxtab[edxxidx].domnnum], vexxtab[vexxidx].domoptr))) { errorPrint ("kgraphMapFmCheck: invalid migration communication gain for extended edge"); return (1); } } } if (grafptr->pfixtax != NULL) { /* We have fixed vertices */ Anum domnlst; /* Domnain of last vertex for which a distance was computed */ Anum distlst; /* Last distance computed */ Gnum vertnum; for (vertnum = grafptr->s.baseval; vertnum < grafptr->s.vertnnd; vertnum ++) { if (grafptr->pfixtax[vertnum] != -1) { /* If vertex is fixed */ Gnum domnorg; Gnum edgenum; domnorg = parttax[vertnum]; domnlst = -1; /* Invalid part to recompute distance */ for (edgenum = verttax[vertnum]; edgenum < vendtax[vertnum]; edgenum ++) { Gnum vertend; Anum domnend; Gnum edloval; vertend = edgetax[edgenum]; domnend = parttax[vertend]; edloval = (edlotax != NULL) ? edlotax[edgenum] : 1; edloval *= grafptr->r.crloval; if (domnorg != domnend) { Anum distval; distval = (domnend != domnlst) ? archDomDist (grafptr->m.archptr, &grafptr->m.domntab[domnorg], &grafptr->m.domntab[domnend]) : distlst; distlst = distval; domnlst = domnend; commloadtmp += (Gnum) distval * edloval; } } } } } if (commload != commloadtmp / 2) { errorPrint ("kgraphMapFmCheck: invalid communication load"); return (1); } return (0); } #endif /* SCOTCH_DEBUG_KGRAPH3 */ /*****************************/ /* */ /* These routines handle the */ /* insertion of vertices */ /* into the gain arrays. */ /* */ /*****************************/ static int kgraphMapFmEdgeResize ( KgraphMapFmVertex * restrict const vexxtab, /*+ Extended vertex hash table array +*/ Gnum vexxidx, KgraphMapFmEdge * restrict * const edxxtabptr, Gnum * restrict const edxxsizptr, Gnum const edxxnbr, KgraphMapFmTabl * restrict const tablptr) { KgraphMapFmEdge * restrict edxxtmp; KgraphMapFmEdge * restrict edxxtab; Gnum edxxsiz; edxxtab = *edxxtabptr; edxxsiz = *edxxsizptr; edxxsiz *= 2; /* Compute new array size */ *edxxsizptr = edxxsiz; /* Propagate back new size */ if ((edxxtmp = memRealloc (edxxtab, edxxsiz * sizeof (KgraphMapFmEdge))) == NULL) { errorPrint ("kgraphMapFmEdgeResize: out of memory"); return (1); } if (edxxtmp != edxxtab) { /* If array has been reallocated, re-link all edges */ Gnum edxxidx; edxxtab = *edxxtabptr = edxxtmp; /* Point to new array location */ kgraphMapFmTablFree (tablptr); /* Free all edges in gain structure */ for (edxxidx = 0; edxxidx < edxxnbr; edxxidx ++) { if ((vexxtab[edxxtab[edxxidx].vexxidx].lockptr == NULL) && /* Vertex is not locked */ (edxxtab[edxxidx].vexxidx != vexxidx) && /* Edge of current vertex will be added later */ (edxxtab[edxxidx].edxxidx != -2)) /* Skip deprecated extended edges */ kgraphMapFmTablAdd (tablptr, &edxxtab[edxxidx]); } } return (0); } static int kgraphMapFmPartAdd2 ( const Kgraph * restrict const grafptr, KgraphMapFmVertex * restrict const vexxtab, /*+ Extended vertex hash table array +*/ Gnum vexxidx, KgraphMapFmEdge * restrict * const edxxtabptr, Gnum * restrict const edxxsizptr, Gnum * restrict const edxxnbrptr, Anum domnnum, /*+ Vertex domain +*/ Anum domnend, /*+ Domain of the extended edge to add +*/ Gnum edloval, /*+ Load of the edge to domnend +*/ KgraphMapFmTabl * restrict const tablptr) { KgraphMapFmEdge * restrict edxxtab; Gnum edxxidx; Gnum edgenum; Gnum edlosum; Gnum edgenbr; Gnum edxxtmp; Gnum commgain; if (*edxxnbrptr >= *edxxsizptr) /* If new slot would not fit */ kgraphMapFmEdgeResize (vexxtab, -1, edxxtabptr, edxxsizptr, *edxxnbrptr, tablptr); /* No vexxidx because vertex extended edges will be readd later */ edxxtab = *edxxtabptr; edxxidx = (*edxxnbrptr) ++; /* Allocate new slot */ edxxtab[edxxidx].domnnum = domnend; /* Set extended edge data */ edxxtab[edxxidx].distval = archDomDist (&grafptr->a, &grafptr->m.domntab[domnnum], &grafptr->m.domntab[domnend]); edxxtab[edxxidx].edlosum = edloval; edxxtab[edxxidx].edgenbr = 1; edxxtab[edxxidx].vexxidx = vexxidx; edxxtab[edxxidx].mswpnum = 0; commgain = 0; /* Compute commgain */ for (edxxtmp = vexxtab[vexxidx].edxxidx; edxxtmp != -1; edxxtmp = edxxtab[edxxtmp].edxxidx) { commgain += edxxtab[edxxtmp].edlosum * (archDomDist (&grafptr->a, &grafptr->m.domntab[edxxtab[edxxtmp].domnnum], &grafptr->m.domntab[domnend]) - edxxtab[edxxtmp].distval); } commgain += (vexxtab[vexxidx].edlosum - edloval) * edxxtab[edxxidx].distval; edxxtab[edxxidx].commgain = commgain * grafptr->r.crloval; edxxtab[edxxidx].edxxidx = vexxtab[vexxidx].edxxidx; /* Link edge to vertex */ vexxtab[vexxidx].edxxidx = edxxidx; edxxtab[edxxidx].cmiggain = 0; /* Compute migration commgain */ edxxtab[edxxidx].cmigmask = 0; if (vexxtab[vexxidx].domoptr != NULL) { Gnum migcoef; /* Equal to -migedloval if vertex was mapped in old mapping */ migcoef = grafptr->r.cmloval * ((grafptr->r.vmlotax != NULL) ? grafptr->r.vmlotax[vexxtab[vexxidx].vertnum] : 1); edxxtab[edxxidx].cmiggain = (archDomIncl (&grafptr->a, &grafptr->m.domntab[edxxtab[edxxidx].domnnum], vexxtab[vexxidx].domoptr) == 1) ? 0 : migcoef * archDomDist (&grafptr->a, &grafptr->m.domntab[edxxtab[edxxidx].domnnum], vexxtab[vexxidx].domoptr); edxxtab[edxxidx].cmiggain -= vexxtab[vexxidx].cmigload; edxxtab[edxxidx].cmigmask = ~0; } if (vexxtab[vexxidx].lockptr == NULL) /* If value has to be linked */ kgraphMapFmTablAdd (tablptr, &edxxtab[edxxidx]); return (0); } /* This routine adds a vertex to hash table. */ static int kgraphMapFmPartAdd ( const Kgraph * restrict const grafptr, const Gnum vertnum, const Gnum vexxidx, /* Hash value for insertion in vexxtab */ KgraphMapFmVertex * restrict const vexxtab, KgraphMapFmEdge ** edxxtabptr, Gnum * restrict const edxxsizptr, Gnum * restrict const edxxnbrptr, KgraphMapFmTabl * restrict const tablptr) { Gnum oldvertnum; /* Number of current vertex */ KgraphMapFmEdge * restrict edxxtab; Gnum edxxidx; Gnum edgenum; Gnum edlosum; Gnum edgenbr; Anum domnnum; Gnum commload; /* Communication load for local domain */ const Anum * restrict const parttax = grafptr->m.parttax; const Gnum * restrict const verttax = grafptr->s.verttax; const Gnum * restrict const vendtax = grafptr->s.vendtax; const Gnum * restrict const edgetax = grafptr->s.edgetax; const Gnum * restrict const edlotax = grafptr->s.edlotax; #ifdef SCOTCH_DEBUG_KGRAPH2 if (vexxtab[vexxidx].vertnum != ~0) { errorPrint ("kgraphMapFmPartAdd: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ domnnum = parttax[vertnum]; vexxtab[vexxidx].vertnum = vertnum; vexxtab[vexxidx].domnnum = domnnum; vexxtab[vexxidx].veloval = (grafptr->s.velotax != NULL) ? grafptr->s.velotax[vertnum] : 1; /* Vertex will be linked since value is positive */ vexxtab[vexxidx].mswpnum = 0; /* Implicitly set slot as used */ vexxtab[vexxidx].edxxidx = -1; /* No target domains yet */ vexxtab[vexxidx].lockptr = NULL; /* No locked yet */ oldvertnum = ((grafptr->s.vnumtax != NULL) && /* If there is ancestor graph vertex numbers */ (grafptr->s.flagval & KGRAPHHASANCHORS) == 0) /* That are not the ones of the band graph */ ? grafptr->s.vnumtax[vertnum] : vertnum; /* Get vertex number in original graph */ if ((grafptr->r.m.parttax != NULL) && /* If we are doing a repartitioning */ (grafptr->r.m.parttax[oldvertnum] != -1)) /* And if vertex was mapped to an old domain */ vexxtab[vexxidx].domoptr = mapDomain (&grafptr->r.m, oldvertnum); /* Domain in which the vertex was previously mapped */ else vexxtab[vexxidx].domoptr = NULL; edxxtab = *edxxtabptr; /* Compute and link edges */ edgenbr = 0; for (edxxidx = vexxtab[vexxidx].edxxidx; edxxidx != -1; edxxidx = edxxtab[edxxidx].edxxidx) { Gnum domnend; domnend = edxxtab[edxxidx].domnnum; edxxtab[edxxidx].edlosum = 0; edxxtab[edxxidx].edgenbr = 0; edxxtab[edxxidx].distval = archDomDist (&grafptr->a, &grafptr->m.domntab[domnnum], &grafptr->m.domntab[domnend]); } commload = 0; /* Load associated with vertex edges */ edlosum = 0; for (edgenum = verttax[vertnum]; edgenum < vendtax[vertnum]; edgenum ++) { Gnum edxxidx; Gnum vertend; Anum domnend; Gnum edloval; vertend = edgetax[edgenum]; domnend = parttax[vertend]; edloval = (edlotax != NULL) ? edlotax[edgenum] : 1; /* Do not account for crloval yet */ if (domnend == domnnum) { /* If end vertex belongs to same domain */ edlosum += edloval; /* Record local edge load sum */ edgenbr ++; /* Record local edge */ continue; /* Skip further processing */ } for (edxxidx = vexxtab[vexxidx].edxxidx; edxxidx != -1; edxxidx = edxxtab[edxxidx].edxxidx) { /* Search for edge */ if (edxxtab[edxxidx].domnnum == domnend) /* If edge slot found */ break; } if (edxxidx == -1) { /* If edge slot not found */ if (*edxxnbrptr >= *edxxsizptr) /* If new slot would not fit */ kgraphMapFmEdgeResize (vexxtab, vexxidx, edxxtabptr, edxxsizptr, *edxxnbrptr, tablptr); edxxidx = (*edxxnbrptr) ++; /* Allocate new slot */ edxxtab = *edxxtabptr; /* Update edxxtab */ edxxtab[edxxidx].commgain = 0; edxxtab[edxxidx].cmiggain = 0; edxxtab[edxxidx].cmigmask = (grafptr->r.m.parttax != NULL) ? ~0 : 0; edxxtab[edxxidx].domnnum = domnend; edxxtab[edxxidx].distval = archDomDist (&grafptr->a, &grafptr->m.domntab[domnnum], &grafptr->m.domntab[domnend]); edxxtab[edxxidx].edlosum = 0; edxxtab[edxxidx].edgenbr = 0; edxxtab[edxxidx].vexxidx = vexxidx; edxxtab[edxxidx].edxxidx = vexxtab[vexxidx].edxxidx; /* Link edge to vertex */ vexxtab[vexxidx].edxxidx = edxxidx; edxxtab[edxxidx].mswpnum = 0; } commload += edloval * edxxtab[edxxidx].distval; edxxtab[edxxidx].edlosum += edloval; edxxtab[edxxidx].edgenbr ++; } commload *= grafptr->r.crloval; /* Multiply all local loads by crloval */ vexxtab[vexxidx].edlosum = edlosum; vexxtab[vexxidx].edgenbr = edgenbr; for (edxxidx = vexxtab[vexxidx].edxxidx; edxxidx != -1; edxxidx = edxxtab[edxxidx].edxxidx) { Gnum domncur; Gnum edxxtmp; Gnum commgain; domncur = edxxtab[edxxidx].domnnum; commgain = 0; for (edxxtmp = vexxtab[vexxidx].edxxidx; edxxtmp != -1; edxxtmp = edxxtab[edxxtmp].edxxidx) { Anum domnend; if (edxxtmp == edxxidx) continue; domnend = edxxtab[edxxtmp].domnnum; commgain += edxxtab[edxxtmp].edlosum * /* Add edge contribution to target domain */ archDomDist (&grafptr->a, &grafptr->m.domntab[domncur], &grafptr->m.domntab[domnend]); } commgain += vexxtab[vexxidx].edlosum * edxxtab[edxxidx].distval; edxxtab[edxxidx].commgain = commgain * grafptr->r.crloval - commload; } vexxtab[vexxidx].cmigload = 0; if (vexxtab[vexxidx].domoptr != NULL) { Gnum migcoef; /* Equal to -migedloval if vertex was mapped in old mapping */ migcoef = grafptr->r.cmloval * ((grafptr->r.vmlotax != NULL) ? grafptr->r.vmlotax[vertnum] : 1); vexxtab[vexxidx].cmigload = (archDomIncl (&grafptr->a, &grafptr->m.domntab[domnnum], vexxtab[vexxidx].domoptr) == 1) ? 0 : migcoef * archDomDist (&grafptr->a, &grafptr->m.domntab[domnnum], vexxtab[vexxidx].domoptr); for (edxxidx = vexxtab[vexxidx].edxxidx; edxxidx != -1; edxxidx = edxxtab[edxxidx].edxxidx) { edxxtab[edxxidx].cmiggain = (archDomIncl (&grafptr->a, &grafptr->m.domntab[edxxtab[edxxidx].domnnum], vexxtab[vexxidx].domoptr) == 1) ? 0 : migcoef * archDomDist (&grafptr->a, &grafptr->m.domntab[edxxtab[edxxidx].domnnum], vexxtab[vexxidx].domoptr); edxxtab[edxxidx].cmiggain -= vexxtab[vexxidx].cmigload; edxxtab[edxxidx].cmigmask = ~0; } } if (vexxtab[vexxidx].lockptr == NULL) { /* If value has to be (re)linked */ for (edxxidx = vexxtab[vexxidx].edxxidx; edxxidx != -1; edxxidx = edxxtab[edxxidx].edxxidx) /* Insert edges to neighbors in gain arrays */ kgraphMapFmTablAdd (tablptr, &edxxtab[edxxidx]); } return (0); } /* This routine doubles the size all of the arrays ** involved in handling the hash table and hash ** vertex arrays. ** It returns: ** - 0 : if resizing succeeded. ** - !0 : if out of memory. */ static int kgraphMapFmResize ( KgraphMapFmVertex * restrict * vexxtabptr, /*+ Extended vertex array +*/ Gnum * restrict const hashmaxptr, /*+ Size of vertex array +*/ Gnum * const hashmskptr, /*+ Pointer to hash table mask +*/ KgraphMapFmSave * restrict savetab, /*+ Move array +*/ const Gnum savenbr, /*+ Number of moves recorded +*/ KgraphMapFmTabl * const tablptr, /*+ Gain table +*/ KgraphMapFmEdge * edxxtab, /*+ Extended edge array +*/ KgraphMapFmVertex ** const lockptr) /*+ Pointer to locked list +*/ { KgraphMapFmVertex * restrict vexxtab; /* Extended vertex array */ KgraphMapFmSave * restrict saveold; /* Pointer to translated old save array */ Gnum savenum; Gnum hashold; /* Size of old hash table (half of new) */ Gnum hashsiz; Gnum hashmax; Gnum hashmsk; Gnum vexxidx; hashmax = *hashmaxptr << 1; /* Compute new sizes */ hashold = *hashmaxptr << 2; hashsiz = *hashmaxptr << 3; hashmsk = hashsiz - 1; #ifdef SCOTCH_DEBUG_KGRAPH2 if (sizeof (KgraphMapFmVertex) < sizeof (KgraphMapFmSave)) { /* Should always be true */ errorPrint ("kgraphMapFmResize: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ if ((vexxtab = memRealloc (*vexxtabptr, (size_t) hashsiz * sizeof (KgraphMapFmVertex))) == NULL) { errorPrint ("kgraphMapFmResize: out of memory"); return (1); } for (savenum = savenbr - 1; savenum >= 0; savenum --) { /* Move save array, in reverse order */ if (savetab[savenum].type == KGRAPHMAPPFMSAVEVEXX) savetab[savenum].u.vexxdat.vexxidx = vexxtab[savetab[savenum].u.vexxdat.vexxidx].vertnum; /* Temporarily translate from hash index to number */ else if ((savetab[savenum].type & KGRAPHMAPPFMSAVELINK) != 0) savetab[savenum].u.linkdat.vexxidx = vexxtab[savetab[savenum].u.linkdat.vexxidx].vertnum; /* Temporarily translate from hash index to number */ } *vexxtabptr = vexxtab; *hashmaxptr = hashmax; *hashmskptr = hashmsk; memSet (vexxtab + hashold, ~0, hashold * sizeof (KgraphMapFmVertex)); /* Set new slots to ~0 */ kgraphMapFmTablFree (tablptr); /* Reset gain table */ *lockptr = (KgraphMapFmVertex *) -1; /* Rebuild lock list */ if (vexxtab[0].vertnum != ~0) { /* If vertex overflowing may have occured in old hash table */ Gnum hashtmp; Gnum hashnew; for (hashtmp = hashold - 1, hashnew = 0; /* Temporarily move vertices away from end of old table to prevent overflowing */ vexxtab[hashtmp].vertnum != ~0; hashtmp --) { while (vexxtab[++ hashnew].vertnum != ~0) ; /* Find an empty slot to receive moved vertex */ #ifdef SCOTCH_DEBUG_KGRAPH2 if (hashnew >= hashtmp) { errorPrint ("kgraphMapFmResize: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ vexxtab[hashnew] = vexxtab[hashtmp]; /* Move vertex from end of table */ vexxtab[hashtmp].vertnum = ~0; /* Set old slot as free */ } } for (vexxidx = 0; vexxidx < hashold; vexxidx ++) { /* Re-compute position of vertices in new table */ Gnum vertnum; vertnum = vexxtab[vexxidx].vertnum; if (vertnum != ~0) { /* If hash slot used */ Gnum hashnew; Gnum edxxtmp; for (hashnew = (vertnum * KGRAPHMAPFMHASHPRIME) & hashmsk; ; hashnew = (hashnew + 1) & hashmsk) { if (hashnew == vexxidx) /* If hash slot is the same */ break; /* There is nothing to do */ if (vexxtab[hashnew].vertnum == ~0) { /* If new slot is empty */ vexxtab[hashnew] = vexxtab[vexxidx]; /* Copy data to new slot */ vexxtab[vexxidx].mswpnum = ~0; /* TRICK: not tested at creation */ vexxtab[vexxidx].vertnum = ~0; /* Make old slot empty */ break; } } if ((hashnew > vexxidx) && (hashnew < hashold)) /* If vertex was an overflowed vertex which will be replaced at end of old table */ continue; /* It will be re-processed again and re-linked once for good at the end of the loop */ for (edxxtmp = vexxtab[hashnew].edxxidx; edxxtmp != -1; edxxtmp = edxxtab[edxxtmp].edxxidx) /* Insert edges to neighbors in gain arrays */ edxxtab[edxxtmp].vexxidx = hashnew; edxxtmp = vexxtab[hashnew].edxxidx; /* vertices lock is done through their first links */ if (vexxtab[hashnew].lockptr == NULL) { /* If vertex was linked, re-link its edges */ for ( ; edxxtmp != -1; edxxtmp = edxxtab[edxxtmp].edxxidx) /* Insert edges to neighbors in gain arrays */ kgraphMapFmTablAdd (tablptr, &edxxtab[edxxtmp]); } else /* Re-lock vertices */ kgraphMapFmLock (*lockptr, &vexxtab[hashnew]); } } for (savenum = 0; savenum < savenbr; savenum ++) { if (savetab[savenum].type == KGRAPHMAPPFMSAVEVEXX) { Gnum vertnum; Gnum vexxidx; vertnum = savetab[savenum].u.vexxdat.vexxidx; /* Get vertex number */ for (vexxidx = (vertnum * KGRAPHMAPFMHASHPRIME) & hashmsk; vexxtab[vexxidx].vertnum != vertnum; vexxidx = (vexxidx + 1) & hashmsk) { #ifdef SCOTCH_DEBUG_KGRAPH2 if (vexxtab[vexxidx].vertnum == ~0) { errorPrint ("kgraphMapFmResize: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ } savetab[savenum].u.vexxdat.vexxidx = vexxidx; /* Set new hash table index */ } else if ((savetab[savenum].type & KGRAPHMAPPFMSAVELINK) != 0) { Gnum vertnum; Gnum vexxidx; vertnum = savetab[savenum].u.linkdat.vexxidx; /* Get vertex number */ for (vexxidx = (vertnum * KGRAPHMAPFMHASHPRIME) & hashmsk; vexxtab[vexxidx].vertnum != vertnum; vexxidx = (vexxidx + 1) & hashmsk) { #ifdef SCOTCH_DEBUG_KGRAPH2 if (vexxtab[vexxidx].vertnum == ~0) { errorPrint ("kgraphMapFmResize: internal error (4)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ } savetab[savenum].u.linkdat.vexxidx = vexxidx; /* Set new hash table index */ } } return (0); } /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the k-way partitioning. ** It returns: ** - 0 : if k-partition could be computed. ** - 1 : on error. */ int kgraphMapFm ( Kgraph * restrict const grafptr, /*+ Active graph +*/ const KgraphMapFmParam * const paraptr) /*+ Method parameters +*/ { KgraphMapFmSave * savetab; /* Pointer to move array */ KgraphMapFmVertex * restrict vexxtab; /* Extended vertex hash table array */ KgraphMapFmEdge * edxxtab; /* Edge extended array */ Gnum edxxnbr; /* Current number of links in link array */ Gnum edxxsiz; Gnum edxxnum; Gnum edxxcdx; /* Index for extended edge copy */ Gnum edcunbr; /* Current number of unused extended edge slots */ Gnum edxunbr; /* Number of unused extended edge slots */ Gnum * comploadmax; /* Array of maximum imbalances */ Gnum * comploaddlt; Gnum commload; Gnum cmigload; KgraphMapFmTabl * restrict tablptr; /* Pointer to gain table for easy access */ KgraphMapFmTabl tabldat; /* Gain table */ KgraphMapFmVertex * lockptr; Gnum fronnum; Gnum fronnbr; Gnum commloadbst; Gnum cmigloadbst; Gnum moveflag; /* Flag set if useful moves made */ Gnum edcpflag; /* Extended edge array compacting flag */ Gnum comploaddiff; Gnum flagval; Anum domnnum; Gnum vexxidx; Gnum passnbr; /* Maximum number of passes to go */ Gnum movenbr; /* Number of uneffective moves done */ Gnum savenbr; /* Number of recorded backtrack moves */ Gnum savesiz; /* Size of save array */ Gnum mswpnum; /* Current number of recording sweep */ Gnum vertnum; Gnum hashsiz; /* Size of hash table */ Gnum hashmsk; /* Mask for access to hash table */ Gnum hashnum; /* Hash value */ Gnum hashmax; /* Maximum number of entries in vertex hash table */ Gnum hashnbr; /* Current number of entries in vertex hash table */ #ifdef SCOTCH_DEBUG_KGRAPH3 Gnum * chektab; /* Extra memory needed for the check routine */ #endif /* SCOTCH_DEBUG_KGRAPH3 */ Anum * restrict const parttax = grafptr->m.parttax; const Gnum * restrict const verttax = grafptr->s.verttax; const Gnum * restrict const vendtax = grafptr->s.vendtax; const Gnum * restrict const edgetax = grafptr->s.edgetax; const Gnum * restrict const edlotax = grafptr->s.edlotax; const Gnum * restrict const pfixtax = grafptr->pfixtax; #ifdef SCOTCH_DEBUG_KGRAPH3 /* Allocation of extra memory needed for the check routine */ if ((chektab = memAlloc (grafptr->m.domnnbr * 3 * sizeof(Gnum))) == NULL) { errorPrint ("kgraphMapFm: out of memory (1)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH3 */ tablptr = &tabldat; grafptr->kbalval = paraptr->deltval; /* Store last k-way imbalance ratio */ kgraphCost (grafptr); grafptr->commload *= grafptr->r.crloval; /* crloval must be 1 if we are not doing a repartitioning of a no-band graph */ if (memAllocGroup ((void **) (void *) /* Allocation and initialization of imbalance arrays */ &comploadmax, (size_t) (grafptr->m.domnnbr * sizeof (Gnum)), &comploaddlt, (size_t) (grafptr->m.domnnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("kgraphMapFm: out of memory (2)"); return (1); } for (domnnum = 0; domnnum < grafptr->m.domnnbr; domnnum ++) { comploadmax[domnnum] = (Gnum) ((double) grafptr->comploadavg[domnnum] * paraptr->deltval); comploaddlt[domnnum] = grafptr->comploaddlt[domnnum]; } if (grafptr->fronnbr == 0) { /* If no current frontier */ Anum domnnum; for (domnnum = 0; domnnum < grafptr->m.domnnbr; domnnum ++) { if (abs (grafptr->comploaddlt[domnnum]) > comploadmax[domnnum]) break; } if (domnnum == grafptr->m.domnnbr) { /* If balance is correct */ memFree (comploadmax); /* Nothing to do */ return (0); } else { /* Imbalance must be fought */ const Strat * strat; strat = stratInit (&kgraphmapststratab, "r{sep=h{pass=10}}"); /* Use a standard algorithm */ kgraphMapSt (grafptr, strat); /* Perform mapping */ if (grafptr->fronnbr == 0) { /* If new partition has no frontier */ memFree (comploadmax); return (0); /* This algorithm is still useless */ } if (memReallocGroup ((void *) comploadmax, /* domnnbr has changed after mapping */ &comploadmax, (size_t) (grafptr->m.domnnbr * sizeof (Gnum)), &comploaddlt, (size_t) (grafptr->m.domnnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("kgraphMapFm: out of memory (3)"); return (1); } for (domnnum = 0; domnnum < grafptr->m.domnnbr; domnnum ++) { /* Else update compload{max,dlt} according to new partition */ comploadmax[domnnum] = (Gnum) ((double) grafptr->comploadavg[domnnum] * paraptr->deltval); comploaddlt[domnnum] = grafptr->comploaddlt[domnnum]; } } } #ifdef SCOTCH_DEBUG_KGRAPH2 /* Allocation of extended vertex hash table and extended edge array */ hashnbr = 2 * grafptr->fronnbr + 1; /* Ensure resizing will be performed, for maximum code coverage */ savesiz = 2 * grafptr->fronnbr + 1; /* Ensure resizing will be performed, for maximum code coverage */ edxxsiz = 2 * grafptr->fronnbr + 1; /* Ensure resizing will be performed, for maximum code coverage */ #else /* SCOTCH_DEBUG_KGRAPH2 */ hashnbr = 4 * (grafptr->fronnbr + paraptr->movenbr + grafptr->s.degrmax); savesiz = 4 * (grafptr->fronnbr + paraptr->movenbr + grafptr->s.degrmax) * 2; edxxsiz = 4 * (grafptr->fronnbr + paraptr->movenbr + grafptr->s.degrmax) * 4; #endif /* SCOTCH_DEBUG_KGRAPH2 */ if (hashnbr > grafptr->s.vertnbr) hashnbr = grafptr->s.vertnbr; if (edxxsiz > grafptr->s.edgenbr) edxxsiz = grafptr->s.edgenbr; for (hashsiz = 256; hashsiz < hashnbr; hashsiz <<= 1) ; /* Get upper power of two */ hashmsk = hashsiz - 1; hashmax = hashsiz >> 2; if (kgraphMapFmTablInit (tablptr) != 0) { errorPrint ("kgraphMapFm: internal error (1)"); /* Unable to do proper initialization */ kgraphMapFmTablExit (tablptr); return (1); } else { if (((vexxtab = memAlloc ((size_t) hashsiz * sizeof (KgraphMapFmVertex))) == NULL) || ((savetab = memAlloc ((size_t) savesiz * sizeof (KgraphMapFmSave))) == NULL) || ((edxxtab = memAlloc ((size_t) edxxsiz * sizeof (KgraphMapFmEdge))) == NULL)) { errorPrint ("kgraphMapFm: out of memory (4)"); kgraphMapFmTablExit (tablptr); return (1); } } memSet (vexxtab, ~0, hashsiz * sizeof (KgraphMapFmVertex)); /* Set all vertex numbers to ~0 */ memSet (edxxtab, ~0, edxxsiz * sizeof (KgraphMapFmEdge)); /* Set all edge numbers to ~0 */ hashnbr = grafptr->fronnbr; while (hashnbr >= hashmax) { if (kgraphMapFmResize (&vexxtab, &hashmax, &hashmsk, savetab, 0, tablptr, edxxtab, &lockptr) != 0) { errorPrint ("kgraphMapFm: out of memory (5)"); memFree (vexxtab); /* Free group leader */ kgraphMapFmTablExit (tablptr); return (1); } } edxxnbr = 0; for (fronnum = 0; fronnum < hashnbr; fronnum ++) { /* Set initial gains */ Gnum vertnum; vertnum = grafptr->frontab[fronnum]; if ((pfixtax == NULL) || (pfixtax[vertnum] == -1)) { /* Add only not fixed vertices */ for (hashnum = (vertnum * KGRAPHMAPFMHASHPRIME) & hashmsk; vexxtab[hashnum].vertnum != ~0; hashnum = (hashnum + 1) & hashmsk) ; kgraphMapFmPartAdd (grafptr, vertnum, hashnum, vexxtab, &edxxtab, &edxxsiz, &edxxnbr, tablptr); #ifdef SCOTCH_DEBUG_KGRAPH2 if (vexxtab[hashnum].edxxidx == -1) { /* If vertex does not have any neighbor */ errorPrint ("kgraphMapFm: vertex does not belong to frontier"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ } } #ifdef SCOTCH_DEBUG_KGRAPH2 if (hashnbr >= hashmax) { /* Hash table too small (must not occur) */ errorPrint ("kgraphMapFm: hash table to small"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ commloadbst = grafptr->commload; /* Start from initial situation */ cmigloadbst = 0; /* Do not take initial migration cost situation into account */ #ifdef SCOTCH_DEBUG_KGRAPH3 if (kgraphMapFmCheck (tablptr, grafptr, vexxtab, edxxtab, hashmsk, commloadbst, chektab) != 0) { errorPrint ("kgraphMapFm: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH3 */ passnbr = paraptr->passnbr; /* Set remaining number of passes */ savenbr = 0; /* For empty backtrack of first pass */ mswpnum = 0; /* Will be incremented afterwards */ lockptr = (KgraphMapFmVertex *) -1; /* Locked list is empty */ edxunbr = 0; do { /* As long as there are improvements */ KgraphMapFmEdge * edxxptr; Gnum oldsavenbr; oldsavenbr = savenbr; while (savenbr -- > 0) { /* Delete exceeding moves */ /* Restore last correct state of the graph * All unlocked vertices have all there valid extended edges in the table * Any of the deprecated edges are in the table * Any of locked vertices have extended edges in the table */ Gnum vexxidx; Gnum oldveloval; Anum domnnum; Anum domnorg; Gnum edxxidx; Gnum * edxiptr; switch (savetab[savenbr].type) { case KGRAPHMAPPFMSAVEVEXX: vexxidx = savetab[savenbr].u.vexxdat.vexxidx; domnnum = savetab[savenbr].u.vexxdat.domnnum; domnorg = vexxtab[vexxidx].domnnum; oldveloval = vexxtab[vexxidx].veloval; vexxtab[vexxidx].domnnum = domnnum; /* Restore vertex data */ vexxtab[vexxidx].veloval = savetab[savenbr].u.vexxdat.veloval; vexxtab[vexxidx].cmigload = savetab[savenbr].u.vexxdat.cmigload; vexxtab[vexxidx].edlosum = savetab[savenbr].u.vexxdat.edlosum; vexxtab[vexxidx].edgenbr = savetab[savenbr].u.vexxdat.edgenbr; parttax[vexxtab[vexxidx].vertnum] = domnnum; comploaddlt[domnorg] -= oldveloval; /* Update domain load delta */ comploaddlt[domnnum] += oldveloval; break; case KGRAPHMAPPFMSAVEEDXX: edxxidx = savetab[savenbr].u.edxxdat.edxxidx; /* Restore extended edge data */ edxxtab[edxxidx].domnnum = savetab[savenbr].u.edxxdat.domnnum; edxxtab[edxxidx].commgain = savetab[savenbr].u.edxxdat.commgain; edxxtab[edxxidx].cmiggain = savetab[savenbr].u.edxxdat.cmiggain; edxxtab[edxxidx].cmigmask = (grafptr->r.m.parttax != NULL) ? ~0 : 0; edxxtab[edxxidx].edlosum = savetab[savenbr].u.edxxdat.edlosum; edxxtab[edxxidx].edgenbr = savetab[savenbr].u.edxxdat.edgenbr; edxxtab[edxxidx].distval = savetab[savenbr].u.edxxdat.distval; break; case KGRAPHMAPPFMSAVELINKDEL: edxxidx = savetab[savenbr].u.linkdat.edxxidx; vexxidx = savetab[savenbr].u.linkdat.vexxidx; if (edxxtab[edxxidx].vexxidx != vexxidx) /* Restore correct vexxidx after resize */ edxxtab[edxxidx].vexxidx = vexxidx; edxxtab[edxxidx].edxxidx = vexxtab[vexxidx].edxxidx; /* Add it back to vertex list and set it as used */ vexxtab[vexxidx].edxxidx = edxxidx; edxunbr --; /* One more used edge slot */ #ifdef SCOTCH_DEBUG_KGRAPH2 if (edxunbr < 0) { errorPrint ("kgraphMapFm: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ if (vexxtab[vexxidx].lockptr == NULL) kgraphMapFmTablAdd (tablptr, &edxxtab[edxxidx]); /* Link it back */ break; case KGRAPHMAPPFMSAVELINKADD: edxxidx = savetab[savenbr].u.linkdat.edxxidx; vexxidx = savetab[savenbr].u.linkdat.vexxidx; if (edxxtab[edxxidx].vexxidx != vexxidx) /* Restore correct vexxidx after resize */ edxxtab[edxxidx].vexxidx = vexxidx; if (vexxtab[vexxidx].lockptr == NULL) kgraphMapFmTablDel (tablptr, &edxxtab[edxxidx]); /* Unlink it */ for (edxiptr = &vexxtab[vexxidx].edxxidx; (*edxiptr != edxxidx) && (*edxiptr != -1); edxiptr = &edxxtab[*edxiptr].edxxidx) ; #ifdef SCOTCH_DEBUG_KGRAPH2 if (*edxiptr == -1) { /* Since it has been added to the list, extended edge must be in it */ errorPrint ("kgraphMapFm: internal error (4)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ *edxiptr = edxxtab[edxxidx].edxxidx; /* Remove it from the vertex list */ edxxtab[edxxidx].edxxidx = -2; /* Set slot as unused */ edxunbr ++; /* One more unused edge slot */ break; } } edcpflag = 0; /* Assume that extended edge array not need to be compacted */ if (edxunbr > (edxxnbr / KGRAPHMAPFMEDXXCOMP)) { /* If more than 20% of edxxtab is unused, compact edxxtab */ edcpflag = 1; for (vexxidx = 0; vexxidx <= hashmsk; vexxidx ++) /* Extended edge list must be recomputed */ vexxtab[vexxidx].edxxidx = -1; edxxcdx = 0; edcunbr = 0; kgraphMapFmTablFree (tablptr); /* Free all edges in gain structure */ for (edxxnum = 0; edxxnum < edxxnbr; edxxnum ++) { /* Remove unused slots of edxxtab */ if (edxxtab[edxxnum].edxxidx == -2) { if (edcunbr > 0) { memmove (&edxxtab[edxxcdx], &edxxtab[edxxcdx + edcunbr], (edxxnum - edxxcdx - edcunbr) * sizeof (KgraphMapFmEdge)); /* Since there is overlapping, use memmove */ edxxcdx = edxxnum - edcunbr; } else edxxcdx = edxxnum; edcunbr ++; } else { vexxidx = edxxtab[edxxnum].vexxidx; edxxtab[edxxnum].edxxidx = vexxtab[vexxidx].edxxidx; /* Link edge to vertex */ vexxtab[vexxidx].edxxidx = edxxnum - edcunbr; /* Set to new index */ } } if ((edcunbr > 0) && (edxxtab[edxxnbr - 1].edxxidx != -2)) memmove (&edxxtab[edxxcdx], &edxxtab[edxxcdx + edcunbr], (edxxnum - edxxcdx - edcunbr) * sizeof (KgraphMapFmEdge)); edxxnbr -= edcunbr; edxunbr = 0; } else { while (oldsavenbr -- > 0) { /* Must be sure that all parttax is correct before recompute vertices gains */ if (savetab[oldsavenbr].type == KGRAPHMAPPFMSAVEVEXX) { Gnum vexxidx; Gnum edxxtmp; vexxidx = savetab[oldsavenbr].u.vexxdat.vexxidx; if (vexxtab[vexxidx].lockptr == NULL) { for (edxxtmp = vexxtab[vexxidx].edxxidx; edxxtmp != -1; edxxtmp = edxxtab[edxxtmp].edxxidx) { /* Relink all vertex links */ kgraphMapFmTablDel (tablptr, &edxxtab[edxxtmp]); kgraphMapFmTablAdd (tablptr, &edxxtab[edxxtmp]); } } } } } while (lockptr != (KgraphMapFmVertex *) -1) { /* Unlock locked vertices */ KgraphMapFmVertex * vexxptr; Gnum edxxtmp; vexxptr = lockptr; /* Get vertex associated with lock list */ lockptr = kgraphMapFmLockNext (lockptr); /* Point to next vertex to unlock */ #ifdef SCOTCH_DEBUG_KGRAPH2 if (vexxptr->lockptr == NULL) { errorPrint ("kgraphMapFm: internal error (5)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ vexxptr->lockptr = NULL; /* Set vertex as unlocked */ if (edcpflag == 0) /* It has not been done during edxxtab compacting */ for (edxxtmp = vexxptr->edxxidx; edxxtmp != -1; edxxtmp = edxxtab[edxxtmp].edxxidx) /* Relink all vertex links */ kgraphMapFmTablAdd (tablptr, &edxxtab[edxxtmp]); } if (edcpflag == 1) for (edxxnum = 0; edxxnum < edxxnbr; edxxnum ++) kgraphMapFmTablAdd (tablptr, &edxxtab[edxxnum]); /* Add all used links, all vertices will be unlocked */ commload = commloadbst; cmigload = cmigloadbst; mswpnum ++; /* Forget all recorded moves */ #ifdef SCOTCH_DEBUG_KGRAPH3 if (kgraphMapFmCheck (tablptr, grafptr, vexxtab, edxxtab, hashmsk, commload, chektab) != 0) { errorPrint ("kgraphMapFm: internal error (6)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH3 */ moveflag = 0; /* No useful moves made */ movenbr = 0; /* No ineffective moves recorded yet */ savenbr = 0; /* Back up to beginning of table */ comploaddiff = 0; flagval = 0; while ((movenbr < paraptr->movenbr) && ((edxxptr = (KgraphMapFmEdge *) kgraphMapFmTablGet (tablptr, vexxtab, comploaddlt, comploadmax, &comploaddiff, &flagval)) != NULL)) { /* Move one vertex */ Gnum vexxidx; Gnum edxxtmp; Gnum veloval; Gnum edgenum; Anum domnnum; Gnum edlosum; Gnum edgenbr; Anum domnend; Gnum edxxidx; Gnum * edxpptr; Gnum * vpexptr; Gnum vexdflg; vexxidx = edxxptr->vexxidx; /* Get relevant information */ vertnum = vexxtab[vexxidx].vertnum; veloval = vexxtab[vexxidx].veloval; domnnum = vexxtab[vexxidx].domnnum; edlosum = vexxtab[vexxidx].edlosum; edgenbr = vexxtab[vexxidx].edgenbr; domnend = edxxptr->domnnum; /* Save moved vertex information */ if (vexxtab[vexxidx].mswpnum != mswpnum) { /* If extended vertex data not yet recorded */ vexxtab[vexxidx].mswpnum = mswpnum; savetab[savenbr].type = KGRAPHMAPPFMSAVEVEXX; /* Save extended vertex data */ savetab[savenbr].u.vexxdat.vexxidx = vexxidx; savetab[savenbr].u.vexxdat.veloval = veloval; savetab[savenbr].u.vexxdat.domnnum = domnnum; savetab[savenbr].u.vexxdat.cmigload = vexxtab[vexxidx].cmigload; savetab[savenbr].u.vexxdat.edlosum = edlosum; savetab[savenbr].u.vexxdat.edgenbr = edgenbr; savenbr ++; /* One more data recorded */ } for (edxxidx = vexxtab[vexxidx].edxxidx; edxxidx != -1; edxxidx = edxxtab[edxxidx].edxxidx) { /* Save vertex links */ if (edxxtab[edxxidx].mswpnum != mswpnum) { /* If extended edge data not yet recorded */ edxxtab[edxxidx].mswpnum = mswpnum; savetab[savenbr].type = KGRAPHMAPPFMSAVEEDXX; /* Save extended edge data */ savetab[savenbr].u.edxxdat.edxxidx = edxxidx; savetab[savenbr].u.edxxdat.domnnum = edxxtab[edxxidx].domnnum; savetab[savenbr].u.edxxdat.commgain = edxxtab[edxxidx].commgain; savetab[savenbr].u.edxxdat.cmiggain = edxxtab[edxxidx].cmiggain; savetab[savenbr].u.edxxdat.edlosum = edxxtab[edxxidx].edlosum; savetab[savenbr].u.edxxdat.edgenbr = edxxtab[edxxidx].edgenbr; savetab[savenbr].u.edxxdat.distval = edxxtab[edxxidx].distval; savenbr ++; /* One more data recorded */ } } movenbr ++; /* One more move done */ commload += edxxptr->commgain; cmigload += edxxptr->cmiggain; #ifdef SCOTCH_DEBUG_KGRAPH2 if (vexxtab[vexxidx].lockptr != NULL) { /* Vertex is locked */ errorPrint ("kgraphMapFm: internal error (7)"); return (1); } if (vexxtab[vexxidx].edxxidx == -1) { /* Vertex not in the frontier */ errorPrint ("kgraphMapFm: internal error (8)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ kgraphMapFmLock (lockptr, &vexxtab[vexxidx]); /* Set part as having changed (lock vertex) */ for (edxxtmp = vexxtab[vexxidx].edxxidx; edxxtmp != -1; edxxtmp = edxxtab[edxxtmp].edxxidx) /* Unlink all vertex links from gain arrays */ kgraphMapFmTablDel (tablptr, &edxxtab[edxxtmp]); edxxtmp = vexxtab[vexxidx].edxxidx; /* Lock vertex through its first link */ /* Switch information with corresponding extended edge * No add or del of extended edges needed. */ parttax[vertnum] = domnend; /* Change vertex part */ comploaddlt[domnnum] -= veloval; /* Account for move */ comploaddlt[domnend] += veloval; vexxtab[vexxidx].domnnum = domnend; /* Swap edges */ edxxptr->domnnum = domnnum; vexxtab[vexxidx].edlosum = edxxptr->edlosum; edxxptr->edlosum = edlosum; vexxtab[vexxidx].edgenbr = edxxptr->edgenbr; edxxptr->edgenbr = edgenbr; vexxtab[vexxidx].cmigload += edxxptr->cmiggain; edxpptr = &vexxtab[vexxidx].edxxidx; for (edxxidx = vexxtab[vexxidx].edxxidx; edxxidx != -1; edxpptr = &edxxtab[edxxidx].edxxidx, edxxidx = edxxtab[edxxidx].edxxidx) { /* Update vertex links */ Gnum domncur; domncur = edxxtab[edxxidx].domnnum; if (domncur == domnnum) { vpexptr = edxpptr; continue; } edxxtab[edxxidx].commgain -= edxxptr->commgain; edxxtab[edxxidx].cmiggain -= edxxptr->cmiggain; edxxtab[edxxidx].distval = archDomDist (&grafptr->a, &grafptr->m.domntab[domnend], &grafptr->m.domntab[domncur]); } edxxptr->commgain = - edxxptr->commgain; edxxptr->cmiggain = - edxxptr->cmiggain; vexdflg = 0; if (edgenbr == 0) { Gnum edxxidx; edxxidx = *vpexptr; savetab[savenbr].type = KGRAPHMAPPFMSAVELINKDEL; /* Save it */ savetab[savenbr].u.linkdat.edxxidx = edxxidx; savetab[savenbr].u.linkdat.vexxidx = vexxidx; savenbr ++; /* One more data recorded */ *vpexptr = edxxtab[edxxidx].edxxidx; /* Remove it from extended vertex list */ edxxtab[edxxidx].edxxidx = -2; /* Set extended edge slot as unused */ edxunbr ++; /* One more unused edge slot */ } for (edgenum = verttax[vertnum]; edgenum < vendtax[vertnum]; edgenum ++) { /* (Re-)link neighbors */ /* - Add the vertex in vexxtab if not yet inserted * - Del the edge to the vertnum old domain if it was the only vertex * linked to this domain. * - Add and edge to the vertnum new domain if it was the first vertex * linked to this domain. * - Update commgain of other edges. * - Relink extended edges */ Gnum edxxend; Gnum vexxend; Gnum edxoidx; /* Index of extended edge to old domain */ Gnum * edxcptr; /* Pointer to index of current extended edge */ Gnum * edxoptr; /* Pointer to index of extended edge to old domain */ Gnum edxnidx; /* index of extended edge to new domain */ Gnum vertend; /* Number of current end neighbor vertex */ Gnum edxfidx; /* Index of first extended edge to update */ Gnum edgeend; Gnum edodnbr; Gnum edndnbr; Anum divoval; /* Distance between current neighbor domain and old domain */ Anum divnval; /* Distance between current neighbor domain and new domain */ Gnum edloval; vertend = edgetax[edgenum]; edloval = (edlotax != NULL) ? edlotax[edgenum] : 1; if (parttax[edgetax[edgenum]] == domnnum) vexdflg = 1; if ((pfixtax != NULL) && (pfixtax[vertend] != -1)) /* Do not link fixed vertices */ continue; if (savenbr >= (savesiz - (grafptr->m.domnnbr + 4) * 4)) { KgraphMapFmSave * saveptr; /* Pointer to move array */ while (savenbr >= (savesiz - (grafptr->m.domnnbr + 4) * 4)) savesiz += savesiz / 2; if ((saveptr = memRealloc (savetab, savesiz * sizeof (KgraphMapFmSave))) == NULL) { errorPrint ("kgraphMapFm: out of memory (6)"); memFree (savetab); /* Free group leader */ return (1); } savetab = saveptr; } if (hashnbr >= hashmax) { /* If extended vertex table is already full */ if (kgraphMapFmResize (&vexxtab, &hashmax, &hashmsk, savetab, savenbr, tablptr, edxxtab, &lockptr) != 0) { errorPrint ("kgraphMapFm: out of memory (7)"); memFree (vexxtab); /* Free group leader */ kgraphMapFmTablExit (tablptr); return (1); } } for (vexxend = (vertend * KGRAPHMAPFMHASHPRIME) & hashmsk; /* Search for vertex or first free slot */ (vexxtab[vexxend].vertnum != vertend) && (vexxtab[vexxend].vertnum != ~0); vexxend = (vexxend + 1) & hashmsk) ; if (vexxtab[vexxend].vertnum == ~0) { /* If neighbor vertex not yet inserted, create it */ kgraphMapFmPartAdd (grafptr, vertend, vexxend, vexxtab, &edxxtab, &edxxsiz, &edxxnbr, tablptr); hashnbr ++; /* One more vertex in hash table */ #ifdef SCOTCH_DEBUG_KGRAPH2 if (vexxtab[vexxend].edxxidx == -1) { errorPrint ("kgraphMapFm: internal error (9)"); return (1); } if (edxxtab[vexxtab[vexxend].edxxidx].domnnum != domnend) { errorPrint ("kgraphMapFm: internal error (10)"); return (1); } if (edxxtab[vexxtab[vexxend].edxxidx].edxxidx != -1) { errorPrint ("kgraphMapFm: internal error (11)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ vexxtab[vexxend].mswpnum = mswpnum; savetab[savenbr].type = KGRAPHMAPPFMSAVEVEXX; /* Save extended vertex data */ savetab[savenbr].u.vexxdat.vexxidx = vexxend; savetab[savenbr].u.vexxdat.veloval = vexxtab[vexxend].veloval; savetab[savenbr].u.vexxdat.domnnum = vexxtab[vexxend].domnnum; savetab[savenbr].u.vexxdat.cmigload = vexxtab[vexxend].cmigload; savetab[savenbr].u.vexxdat.edlosum = vexxtab[vexxend].edlosum + edloval; /* Save state before vertex move */ savetab[savenbr].u.vexxdat.edgenbr = vexxtab[vexxend].edgenbr + 1; savenbr ++; /* One more data saved */ savetab[savenbr].type = KGRAPHMAPPFMSAVELINKADD; /* Save extended edge creation */ savetab[savenbr].u.linkdat.edxxidx = vexxtab[vexxend].edxxidx; savetab[savenbr].u.linkdat.vexxidx = vexxend; savenbr ++; /* One more data recorded */ #ifdef SCOTCH_DEBUG_KGRAPH2 if (savenbr > savesiz) { errorPrint ("kgraphMapFm: save array error (1)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ continue; } if (vexxtab[vexxend].mswpnum != mswpnum) { /* If vertex data not yet recorded */ vexxtab[vexxend].mswpnum = mswpnum; savetab[savenbr].type = KGRAPHMAPPFMSAVEVEXX; /* Save extended vertex data */ savetab[savenbr].u.vexxdat.vexxidx = vexxend; savetab[savenbr].u.vexxdat.veloval = vexxtab[vexxend].veloval; savetab[savenbr].u.vexxdat.domnnum = vexxtab[vexxend].domnnum; savetab[savenbr].u.vexxdat.cmigload = vexxtab[vexxend].cmigload; savetab[savenbr].u.vexxdat.edlosum = vexxtab[vexxend].edlosum; savetab[savenbr].u.vexxdat.edgenbr = vexxtab[vexxend].edgenbr; savenbr ++; /* One more data saved */ #ifdef SCOTCH_DEBUG_KGRAPH2 if (savenbr > savesiz) { errorPrint ("kgraphMapFm: save array error (2)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ } edxoidx = edxnidx = -1; /* Assume there are no extended edges to domnnum or domnend */ for (edxcptr = &vexxtab[vexxend].edxxidx, edxxidx = vexxtab[vexxend].edxxidx; edxxidx != -1; edxcptr = &edxxtab[edxxidx].edxxidx, edxxidx = edxxtab[edxxidx].edxxidx) { /* Loop on domains */ Gnum domncur; /* Save vertex links */ domncur = edxxtab[edxxidx].domnnum; if (edxxtab[edxxidx].mswpnum != mswpnum) { /* If extended edge data not yet recorded */ edxxtab[edxxidx].mswpnum = mswpnum; savetab[savenbr].type = KGRAPHMAPPFMSAVEEDXX; /* Save extended edge data */ savetab[savenbr].u.edxxdat.edxxidx = edxxidx; savetab[savenbr].u.edxxdat.domnnum = domncur; savetab[savenbr].u.edxxdat.commgain = edxxtab[edxxidx].commgain; savetab[savenbr].u.edxxdat.cmiggain = edxxtab[edxxidx].cmiggain; savetab[savenbr].u.edxxdat.edlosum = edxxtab[edxxidx].edlosum; savetab[savenbr].u.edxxdat.edgenbr = edxxtab[edxxidx].edgenbr; savetab[savenbr].u.edxxdat.distval = edxxtab[edxxidx].distval; savenbr ++; /* One more data recorded */ #ifdef SCOTCH_DEBUG_KGRAPH2 if (savenbr > savesiz) { errorPrint ("kgraphMapFm: save array error (3)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ } if (domncur == domnnum) { edxoidx = edxxidx; edxoptr = edxcptr; edxxtab[edxxidx].edlosum -= edloval; edxxtab[edxxidx].edgenbr --; divoval = edxxtab[edxxidx].distval; } else if (domncur == domnend) { edxnidx = edxxidx; edxxtab[edxxidx].edlosum += edloval; edxxtab[edxxidx].edgenbr ++; divnval = edxxtab[edxxidx].distval; } } #ifdef SCOTCH_DEBUG_KGRAPH2 if ((edxoidx == -1) && (vexxtab[vexxend].domnnum != domnnum)) { errorPrint ("kgraphMapFm: internal error (12)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ if (vexxtab[vexxend].domnnum == domnend) { vexxtab[vexxend].edlosum += edloval; vexxtab[vexxend].edgenbr ++; divnval = 0; } if (vexxtab[vexxend].domnnum == domnnum) { /* Remove edge from neighbor domain */ vexxtab[vexxend].edlosum -= edloval; vexxtab[vexxend].edgenbr --; divoval = 0; } else { if (edxxtab[edxoidx].edgenbr == 0) { /* If it was the last edge in the end domain, save it */ savetab[savenbr].type = KGRAPHMAPPFMSAVELINKDEL; savetab[savenbr].u.linkdat.edxxidx = edxoidx; savetab[savenbr].u.linkdat.vexxidx = vexxend; savenbr ++; /* One more data recorded */ #ifdef SCOTCH_DEBUG_KGRAPH2 if (savenbr > savesiz) { errorPrint ("kgraphMapFm: save array error (4)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ *edxoptr = edxxtab[edxoidx].edxxidx; /* Remove it from extended vertex list */ if (vexxtab[vexxend].lockptr == NULL) /* If edge is of use (vertex not locked) */ kgraphMapFmTablDel (tablptr, &edxxtab[edxoidx]); /* Remove it */ edxxtab[edxoidx].edxxidx = -2; /* Set extended edge slot as unused */ edxunbr ++; /* One more unused edge slot */ } } if ((edxnidx == -1) && (vexxtab[vexxend].domnnum != domnend)) { /* If was first vertex linked to this domain, add edge to new domain */ Gnum edxxidx; kgraphMapFmPartAdd2 (grafptr, vexxtab, vexxend, &edxxtab, &edxxsiz, &edxxnbr, vexxtab[vexxend].domnnum, domnend, edloval, tablptr); /* Add new extended edge */ #ifdef SCOTCH_DEBUG_KGRAPH2 for (edxxidx = vexxtab[vexxend].edxxidx; (edxxidx != -1) && (edxxtab[edxxidx].domnnum != domnend); edxxidx = edxxtab[edxxidx].edxxidx) ; if (edxxidx == -1) { errorPrint ("kgraphMapFm: internal error (13)"); return (1); } if (edxxidx != edxxnbr - 1) { errorPrint ("kgraphMapFm: internal error (14)"); return (1); } if (edxxtab[edxxidx].domnnum != domnend) { errorPrint ("kgraphMapFm: internal error (15)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ savetab[savenbr].type = KGRAPHMAPPFMSAVELINKADD; /* Save extended edge creation */ savetab[savenbr].u.linkdat.edxxidx = edxxnbr - 1; savetab[savenbr].u.linkdat.vexxidx = vexxend; savenbr ++; /* One more data recorded */ #ifdef SCOTCH_DEBUG_KGRAPH2 if (savenbr > savesiz) { errorPrint ("kgraphMapFm: save array error (5)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ divnval = edxxtab[edxxnbr - 1].distval; edxfidx = edxxtab[edxxnbr - 1].edxxidx; /* Skip update of the newly added extended edge */ } else edxfidx = vexxtab[vexxend].edxxidx; edloval *= grafptr->r.crloval; for (edxxend = edxfidx; edxxend != -1; edxxend = edxxtab[edxxend].edxxidx) /* Update vertex links */ edxxtab[edxxend].commgain -= edloval * (divnval - archDomDist (&grafptr->a, &grafptr->m.domntab[edxxtab[edxxend].domnnum], &grafptr->m.domntab[domnend]) - divoval + archDomDist (&grafptr->a, &grafptr->m.domntab[edxxtab[edxxend].domnnum], &grafptr->m.domntab[domnnum])); if (vexxtab[vexxend].lockptr == NULL) { /* If vertex is not locked */ for (edxxend = edxfidx; edxxend != -1; edxxend = edxxtab[edxxend].edxxidx) { /* Relink its extended edges */ kgraphMapFmTablDel (tablptr, &edxxtab[edxxend]); /* Remove it and re-link it */ kgraphMapFmTablAdd (tablptr, &edxxtab[edxxend]); } } } if (flagval == 1) { /* If move improves balance and we do not respect it */ commloadbst = commload; /* This move was effective */ cmigloadbst = cmigload; moveflag = 1; movenbr = savenbr = 0; flagval = 0; comploaddiff = 0; mswpnum ++; } else if ((commload + cmigload) < (commloadbst + cmigloadbst)) { /* If move improves the cost */ commloadbst = commload; /* This move was effective */ cmigloadbst = cmigload; moveflag = 1; movenbr = savenbr = 0; flagval = 0; comploaddiff = 0; mswpnum ++; } else if (((commload + cmigload) == (commloadbst + cmigloadbst)) && (comploaddiff < 0)) { /* If move improves balance and cut does not decrease */ commloadbst = commload; /* This move was effective */ cmigloadbst = cmigload; moveflag = 1; movenbr = savenbr = 0; flagval = 0; comploaddiff = 0; mswpnum ++; } else if (((commload + cmigload) == (commloadbst + cmigloadbst)) && (comploaddiff == 0)) { commloadbst = commload; /* Forget backtracking */ cmigloadbst = cmigload; movenbr = savenbr = 0; flagval = 0; mswpnum ++; } #ifdef SCOTCH_DEBUG_KGRAPH3 if (kgraphMapFmCheck (tablptr, grafptr, vexxtab, edxxtab, hashmsk, commload, chektab) != 0) { errorPrint ("kgraphMapFm: internal error (16)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH3 */ } #ifdef SCOTCH_DEBUG_KGRAPH3 if (kgraphMapFmCheck (tablptr, grafptr, vexxtab, edxxtab, hashmsk, commload, chektab) != 0) { errorPrint ("kgraphMapFm: internal error (17)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH3 */ } while ((moveflag != 0) && /* As long as vertices are moved */ (-- passnbr != 0)); /* And we are allowed to loop (TRICK for negative values) */ #ifdef SCOTCH_DEBUG_KGRAPH3 if (kgraphMapFmCheck (tablptr, grafptr, vexxtab, edxxtab, hashmsk, commload, chektab) != 0) { errorPrint ("kgraphMapFm: internal error (18)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH3 */ while (savenbr -- > 0) { /* Delete exceeding moves */ Gnum vexxidx; Anum domnnum; Gnum veloval; if (savetab[savenbr].type == KGRAPHMAPPFMSAVEVEXX) { vexxidx = savetab[savenbr].u.vexxdat.vexxidx; domnnum = savetab[savenbr].u.vexxdat.domnnum; veloval = savetab[savenbr].u.vexxdat.veloval; comploaddlt[vexxtab[vexxidx].domnnum] -= veloval; comploaddlt[domnnum] += veloval; vexxtab[vexxidx].domnnum = domnnum; /* Restore vertex data */ parttax[vexxtab[vexxidx].vertnum] = domnnum; } } commload = 0; for (vexxidx = fronnbr = 0; /* Build new frontier, compute commload, update parttax */ vexxidx <= hashmsk; vexxidx ++) { /* hashsiz no longer valid after resizing, so use hashmsk */ Gnum vertnum; Gnum edgenum; Anum domnnum; Anum domnlst; /* Domain of last vertex for which a distance was computed */ Anum distlst; /* Last distance computed */ Gnum commcut; vertnum = vexxtab[vexxidx].vertnum; /* Get vertex data from slot */ if (vertnum != ~0) { commcut = 0; domnnum = parttax[vertnum]; domnlst = -1; /* Invalid domnain to recompute distance */ #ifdef SCOTCH_DEBUG_KGRAPH2 if (vexxtab[vexxidx].domnnum != parttax[vertnum]) { errorPrint ("kgraphMapFm: internal error (19)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ for (edgenum = verttax[vertnum]; edgenum < vendtax[vertnum]; edgenum ++) { Gnum vertend; Gnum domnend; vertend = edgetax[edgenum]; domnend = parttax[vertend]; if (domnend != domnnum) { Anum distval; Gnum edloval; distval = (domnend != domnlst) ? archDomDist (grafptr->m.archptr, &grafptr->m.domntab[domnnum], &grafptr->m.domntab[domnend]) : distlst; distlst = distval; domnlst = domnend; edloval = (edlotax != NULL) ? edlotax[edgenum] : 1; commload += (Gnum) distval * edloval; commcut = 1; } } if (commcut != 0) grafptr->frontab[fronnbr ++] = vertnum; } } if (grafptr->pfixtax != NULL) { /* We have fixed vertices */ Gnum vertnum; for (vertnum = grafptr->s.baseval; vertnum < grafptr->s.vertnnd; vertnum ++) { if ((grafptr->pfixtax != NULL) && (grafptr->pfixtax[vertnum] != -1)) { /* If vertex is fixed */ Gnum edgenum; Anum domnnum; Gnum commcut; Anum domnlst; /* Domain of last vertex for which a distance was computed */ Anum distlst; /* Last distance computed */ commcut = 0; domnnum = parttax[vertnum]; domnlst = -1; /* Invalid domnain to recompute distance */ for (edgenum = verttax[vertnum]; /* For all neighbors */ edgenum < vendtax[vertnum]; edgenum ++) { Gnum vertend; Gnum domnend; vertend = edgetax[edgenum]; domnend = parttax[vertend]; if (domnend != domnnum) { Anum distval; Gnum edloval; distval = (domnend != domnlst) ? archDomDist (grafptr->m.archptr, &grafptr->m.domntab[domnnum], &grafptr->m.domntab[domnend]) : distlst; distlst = distval; domnlst = domnend; edloval = (edlotax != NULL) ? edlotax[edgenum] : 1; commload += (Gnum) distval * edloval; commcut = 1; } } if (commcut != 0) grafptr->frontab[fronnbr ++] = vertnum; } } } grafptr->fronnbr = fronnbr; grafptr->commload = commload / 2; for (domnnum = 0; domnnum < grafptr->m.domnnbr; domnnum ++) /* Update graph information */ grafptr->comploaddlt[domnnum] = comploaddlt[domnnum]; #ifdef SCOTCH_DEBUG_KGRAPH3 memFree (chektab); /* Free group leader */ #endif /* SCOTCH_DEBUG_KGRAPH3 */ memFree (comploadmax); /* Free group leader */ memFree (vexxtab); memFree (savetab); memFree (edxxtab); kgraphMapFmTablExit (tablptr); #ifdef SCOTCH_DEBUG_KGRAPH2 if (kgraphCheck (grafptr) != 0) { errorPrint ("kgraphMapFm: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/graph_coarsen_edge.c0000644002563400244210000002034512474554236025615 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2009,2012 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : graph_coarsen_edge.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This commodity file contains the edge **/ /** arrays building subroutine which is **/ /** duplicated, with minor modifications, **/ /** into graph_coarsen.c. **/ /** **/ /** DATES : # Version 4.0 : from : 17 dec 2001 **/ /** to 25 feb 2004 **/ /** # Version 5.0 : from : 13 dec 2006 **/ /** to 14 dec 2006 **/ /** # Version 5.1 : from : 30 oct 2009 **/ /** to 30 oct 2009 **/ /** # Version 6.0 : from : 28 oct 2012 **/ /** to 28 feb 2015 **/ /** **/ /************************************************************/ static void GRAPHCOARSENEDGENAME ( GraphCoarsenThread * thrdptr) { Gnum coarvertnum; Gnum coarvertnnd; Gnum coaredgenum; Gnum coardegrmax; Gnum coaredloadj; /* Edge load sum adjust with respect to fine graph edge load sum */ GraphCoarsenData * restrict coarptr = (GraphCoarsenData *) (thrdptr->thrddat.grouptr); const Graph * restrict const finegrafptr = coarptr->finegrafptr; const Gnum * restrict const fineverttax = finegrafptr->verttax; const Gnum * restrict const finevendtax = finegrafptr->vendtax; const Gnum * restrict const finevelotax = finegrafptr->velotax; const Gnum * restrict const fineedgetax = finegrafptr->edgetax; Gnum * restrict const finecoartax = coarptr->finematetax; const Graph * restrict const coargrafptr = coarptr->coargrafptr; #ifndef GRAPHCOARSENEDGECOUNT Gnum * restrict const coarverttax = coargrafptr->verttax; Gnum * restrict const coarvelotax = coargrafptr->velotax; Gnum * restrict const coaredgetax = coargrafptr->edgetax; Gnum * restrict const coaredlotax = coargrafptr->edlotax; #endif /* GRAPHCOARSENEDGECOUNT */ GraphCoarsenHash * restrict const coarhashtab = thrdptr->coarhashtab; /* Hash table is thread-dependent for memory locality */ const Gnum coarhashmsk = coarptr->coarhashmsk; const GraphCoarsenMulti * restrict const coarmulttax = coarptr->coarmulttab - finegrafptr->baseval; GRAPHCOARSENEDGEINIT; coaredloadj = 0; for (coarvertnum = thrdptr->coarvertbas, coardegrmax = 0, /* For all local coarse vertices */ coarvertnnd = thrdptr->coarvertnnd, coaredgenum = thrdptr->coaredgebas; coarvertnum < coarvertnnd; coarvertnum ++) { Gnum finevertnum; int i; #ifndef GRAPHCOARSENEDGECOUNT /* If we do not only want to count */ Gnum coarveloval; /* Load of coarse vertex */ Gnum coaredgetmp; /* Current index in edge array */ coarverttax[coarvertnum] = /* Set vertex edge index */ coaredgetmp = coaredgenum; coarveloval = 0; #endif /* GRAPHCOARSENEDGECOUNT */ i = 0; do { /* For all fine edges of multinode vertices */ Gnum fineedgenum; finevertnum = coarmulttax[coarvertnum].vertnum[i]; #ifndef GRAPHCOARSENEDGECOUNT /* If we do not only want to count */ coarveloval += (finevelotax != NULL) ? finevelotax[finevertnum] : 1; #endif /* GRAPHCOARSENEDGECOUNT */ for (fineedgenum = fineverttax[finevertnum]; fineedgenum < finevendtax[finevertnum]; fineedgenum ++) { Gnum coarvertend; /* Number of coarse vertex which is end of fine edge */ Gnum h; coarvertend = finecoartax[fineedgetax[fineedgenum]]; if (coarvertend != coarvertnum) { /* If not end of collapsed edge */ for (h = (coarvertend * GRAPHCOARSENHASHPRIME) & coarhashmsk; ; h = (h + 1) & coarhashmsk) { if (coarhashtab[h].vertorgnum != coarvertnum) { /* If old slot */ coarhashtab[h].vertorgnum = coarvertnum; /* Mark it in reference array */ coarhashtab[h].vertendnum = coarvertend; coarhashtab[h].edgenum = coaredgenum; #ifndef GRAPHCOARSENEDGECOUNT /* If we do not only want to count */ coaredgetax[coaredgenum] = coarvertend; /* One more edge created */ GRAPHCOARSENEDGEEDLOINIT; /* Initialize edge load entry */ #endif /* GRAPHCOARSENEDGECOUNT */ coaredgenum ++; break; /* Give up hashing */ } if (coarhashtab[h].vertendnum == coarvertend) { /* If coarse edge already exists */ #ifndef GRAPHCOARSENEDGECOUNT GRAPHCOARSENEDGEEDLOADD; /* Accumulate edge load */ #endif /* GRAPHCOARSENEDGECOUNT */ break; /* Give up hashing */ } } } #ifndef GRAPHCOARSENEDGECOUNT else { GRAPHCOARSENEDGEEDLOSUB; } #endif /* GRAPHCOARSENEDGECOUNT */ } } while (i ++, finevertnum != coarmulttax[coarvertnum].vertnum[1]); /* Skip to next matched vertex if both vertices not equal */ #ifndef GRAPHCOARSENEDGECOUNT /* If we do not only want to count */ coarvelotax[coarvertnum] = coarveloval; /* Create coarse vertex load array */ coaredgetmp = coaredgenum - coaredgetmp; /* Compute degree of current vertex */ if (coardegrmax < coaredgetmp) coardegrmax = coaredgetmp; #endif /* GRAPHCOARSENEDGECOUNT */ } /* End of (local) edge array not marked since will be done by next or main thread */ thrdptr->coaredgebas = coaredgenum; /* Record counted number of edges */ #ifndef GRAPHCOARSENEDGECOUNT thrdptr->coaredloadj = coaredloadj; thrdptr->coardegrmax = coardegrmax; #endif /* GRAPHCOARSENEDGECOUNT */ } scotch-6.0.4.dfsg/src/libscotch/vgraph_separate_bd.c0000644002563400244210000005312211631447170025625 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vgraph_separate_bd.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Cedric CHEVALIER **/ /** **/ /** FUNCTION : This module builds a band graph around **/ /** the frontier in order to decrease **/ /** problem size for the strategy to be **/ /** applied. **/ /** **/ /** DATES : # Version 5.0 : from : 18 oct 2004 **/ /** to : 12 sep 2007 **/ /** # Version 5.1 : from : 30 oct 2007 **/ /** to : 09 nov 2008 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VGRAPH_SEPARATE_BD #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "vgraph.h" #include "vgraph_separate_bd.h" #include "vgraph_separate_st.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ int vgraphSeparateBd ( Vgraph * restrict const orggrafptr, /*+ Active graph +*/ const VgraphSeparateBdParam * const paraptr) /*+ Method parameters +*/ { VgraphSeparateBdQueue queudat; /* Neighbor queue */ Gnum * restrict orgdisttax; /* Based access to distance array for original graph */ Gnum orgdistmax; /* Maximum distance allowed */ #define orgindxtax orgdisttax /* Recycle distance array as number indexing array */ Vgraph bndgrafdat; /* Band graph structure */ Gnum bndvertnbr; /* Number of regular vertices in band graph (without anchors) */ Gnum bndvertnnd; Gnum * restrict bndvnumtax; /* Band vertex number array, recycling queudat.qtab */ Gnum bndcompsize1; /* Number of regular vertices in part 1 of band graph */ Gnum bndcompload1; /* Load of regular vertices in part 1 */ Gnum bndvlvlnum; /* Index of first band graph vertex to belong to the last layer */ Gnum bndvertnum; Gnum bndvelosum; /* Load of regular vertices in band graph */ Gnum * restrict bndedgetax; Gnum bndedgenbr; /* Upper bound on the number of edges, including anchor edges */ Gnum bndeancnbr; /* Number of anchor edges */ Gnum bndedgenum; Gnum bndedgetmp; Gnum bnddegrmax; Gnum fronnum; const Gnum * restrict const orgverttax = orggrafptr->s.verttax; /* Fast accesses */ const Gnum * restrict const orgvendtax = orggrafptr->s.vendtax; const Gnum * restrict const orgvelotax = orggrafptr->s.velotax; const Gnum * restrict const orgedgetax = orggrafptr->s.edgetax; if (orggrafptr->fronnbr == 0) /* If no separator vertices, apply strategy to full graph */ return (vgraphSeparateSt (orggrafptr, paraptr->stratorg)); orgdistmax = (Gnum) paraptr->distmax; if (orgdistmax < 1) /* To simplify algorithm, always at least one layer of vertices around separator */ orgdistmax = 1; if (memAllocGroup ((void **) (void *) &queudat.qtab, (size_t) (orggrafptr->s.vertnbr * sizeof (Gnum)), /* TRICK: no need of "+ 2" for anchor vertices (see below) */ &orgdisttax, (size_t) (orggrafptr->s.vertnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("vgraphSeparateBd: out of memory (1)"); return (1); } memSet (orgdisttax, ~0, orggrafptr->s.vertnbr * sizeof (Gnum)); /* Initialize distance array */ orgdisttax -= orggrafptr->s.baseval; vgraphSeparateBdQueueFlush (&queudat); /* Flush vertex queue */ bndedgenbr = 0; /* Guess upper bound on the number of edges */ bndvelosum = 0; for (fronnum = 0; fronnum < orggrafptr->fronnbr; fronnum ++) { /* Enqueue separator vertices */ Gnum orgvertnum; orgvertnum = orggrafptr->frontab[fronnum]; #ifdef SCOTCH_DEBUG_VGRAPH2 if ((orgvertnum < orggrafptr->s.baseval) || (orgvertnum >= orggrafptr->s.vertnnd)) { errorPrint ("vgraphSeparateBd: internal error (1)"); memFree (queudat.qtab); /* Free group leader */ return (1); } if (orgdisttax[orgvertnum] != ~0) { errorPrint ("vgraphSeparateBd: internal error (2)"); memFree (queudat.qtab); /* Free group leader */ return (1); } if (orggrafptr->parttax[orgvertnum] != 2) { errorPrint ("vgraphSeparateBd: internal error (3)"); memFree (queudat.qtab); /* Free group leader */ return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ orgdisttax[orgvertnum] = 0; vgraphSeparateBdQueuePut (&queudat, orgvertnum); if (orgvelotax != NULL) bndvelosum += orgvelotax[orgvertnum]; } bndcompsize1 = 0; bndcompload1 = 0; do { /* Loop on vertices in queue */ Gnum orgvertnum; Gnum orgedgenum; Gnum orgdistval; orgvertnum = vgraphSeparateBdQueueGet (&queudat); #ifdef SCOTCH_DEBUG_VGRAPH2 if ((orgvertnum < orggrafptr->s.baseval) || (orgvertnum >= orggrafptr->s.vertnnd)) { errorPrint ("vgraphSeparateBd: internal error (4)"); memFree (queudat.qtab); /* Free group leader */ return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ bndedgenbr += orgvendtax[orgvertnum] - orgverttax[orgvertnum]; /* Exact or upper bound on number of edges, including anchor edge(s) */ orgdistval = orgdisttax[orgvertnum]; /* Get vertex distance */ if (orgdistval >= orgdistmax) { /* If we belong to the farthest layer */ bndedgenbr ++; /* One more anchor edge, for the opposite */ continue; } orgdistval ++; /* Distance of neighbors */ for (orgedgenum = orgverttax[orgvertnum]; orgedgenum < orgvendtax[orgvertnum]; orgedgenum ++) { Gnum orgvertend; Gnum orgpartval1; orgvertend = orgedgetax[orgedgenum]; if (orgdisttax[orgvertend] == ~0) { /* If vertex not visited yet */ #ifdef SCOTCH_DEBUG_VGRAPH2 if (orggrafptr->parttax[orgvertend] > 1) { errorPrint ("vgraphSeparateBd: internal error (5)"); memFree (queudat.qtab); /* Free group leader */ return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ orgpartval1 = orggrafptr->parttax[orgvertend] & 1; orgdisttax[orgvertend] = orgdistval; /* Enqueue vertex */ vgraphSeparateBdQueuePut (&queudat, orgvertend); bndcompsize1 += orgpartval1; /* Count vertices in part 1 */ if (orgvelotax != NULL) { bndvelosum += orgvelotax[orgvertend]; bndcompload1 += orgvelotax[orgvertend] * orgpartval1; } } } } while (! vgraphSeparateBdQueueEmpty (&queudat)); /* As long as queue is not empty */ bndvertnbr = queudat.head - queudat.qtab; /* Number of regular band graph vertices (withour anchors) is number of enqueued vertices */ if (orgvelotax == NULL) { bndvelosum = bndvertnbr; bndcompload1 = bndcompsize1; } if ((bndcompsize1 >= orggrafptr->compsize[1]) || /* If either part has all of its vertices in band, use plain graph instead */ ((bndvertnbr - bndcompsize1 - orggrafptr->fronnbr) >= orggrafptr->compsize[0])) { memFree (queudat.qtab); /* Free group leader */ return (vgraphSeparateSt (orggrafptr, paraptr->stratorg)); } /* TRICK: since always at least one missing vertex per part, there is room for anchor vertices */ bndvertnnd = bndvertnbr + orggrafptr->s.baseval; bndvnumtax = queudat.qtab - orggrafptr->s.baseval; /* TRICK: re-use queue array as vertex number array as vertices taken in queue order */ for (bndvertnum = orggrafptr->s.baseval; bndvertnum < bndvertnnd; bndvertnum ++) { /* For vertices not belonging to last layer */ Gnum orgvertnum; orgvertnum = bndvnumtax[bndvertnum]; /* Get distance index of vertex */ if (orgindxtax[orgvertnum] >= paraptr->distmax) /* If vertex belongs to last layer */ break; orgindxtax[orgvertnum] = bndvertnum; } bndvlvlnum = bndvertnum; /* Get index of first vertex of last layer */ for ( ; bndvertnum < bndvertnnd; bndvertnum ++) /* For vertices belonging to last layer */ orgindxtax[bndvnumtax[bndvertnum]] = bndvertnum; memSet (&bndgrafdat, 0, sizeof (Vgraph)); bndgrafdat.s.flagval = GRAPHFREETABS | GRAPHVERTGROUP | GRAPHEDGEGROUP; bndgrafdat.s.baseval = orggrafptr->s.baseval; bndgrafdat.s.vertnbr = bndvertnbr + 2; /* "+ 2" for anchor vertices */ bndgrafdat.s.vertnnd = bndvertnnd + 2; if (memAllocGroup ((void **) (void *) /* Do not allocate vnumtab but keep queudat.qtab instead */ &bndgrafdat.s.verttax, (size_t) ((bndvertnbr + 3) * sizeof (Gnum)), &bndgrafdat.s.velotax, (size_t) ((bndvertnbr + 2) * sizeof (Gnum)), NULL) == NULL) { errorPrint ("vgraphSeparateBd: out of memory (2)"); memFree (queudat.qtab); return (1); } bndgrafdat.s.verttax -= orggrafptr->s.baseval; /* Adjust base of arrays */ bndgrafdat.s.vendtax = bndgrafdat.s.verttax + 1; /* Band graph is compact */ bndgrafdat.s.velotax -= orggrafptr->s.baseval; bndgrafdat.s.vnumtax = bndvnumtax; bndgrafdat.s.velosum = orggrafptr->s.velosum; bndgrafdat.s.velotax[bndvertnnd] = orggrafptr->compload[0] - (bndvelosum - orggrafptr->compload[2] - bndcompload1); /* Set loads of anchor vertices */ bndgrafdat.s.velotax[bndvertnnd + 1] = orggrafptr->compload[1] - bndcompload1; if (((bndgrafdat.s.edgetax = (Gnum *) memAlloc (bndedgenbr * sizeof (Gnum))) == NULL) || (bndgrafdat.s.edgetax -= orggrafptr->s.baseval, ((bndgrafdat.parttax = (GraphPart *) memAlloc ((bndvertnbr + 2) * sizeof (GraphPart))) == NULL))) { errorPrint ("vgraphSeparateBd: out of memory (3)"); graphExit (&bndgrafdat.s); memFree (queudat.qtab); return (1); } bndgrafdat.parttax -= orggrafptr->s.baseval; /* From now on we should free a Vgraph and not a Graph */ bndedgetax = bndgrafdat.s.edgetax; for (bndvertnum = bndedgenum = orggrafptr->s.baseval, bnddegrmax = 0; /* Fill index array for vertices not belonging to last level */ bndvertnum < bndvlvlnum; bndvertnum ++) { Gnum orgvertnum; Gnum orgedgenum; orgvertnum = bndvnumtax[bndvertnum]; bndgrafdat.s.verttax[bndvertnum] = bndedgenum; bndgrafdat.s.velotax[bndvertnum] = (orgvelotax != NULL) ? orgvelotax[orgvertnum] : 1; for (orgedgenum = orgverttax[orgvertnum]; /* All edges of first levels are kept */ orgedgenum < orgvendtax[orgvertnum]; orgedgenum ++, bndedgenum ++) { #ifdef SCOTCH_DEBUG_VGRAPH2 if ((bndedgenum >= (bndedgenbr + orggrafptr->s.baseval)) || (orgindxtax[orgedgetax[orgedgenum]] < 0)) { errorPrint ("vgraphSeparateBd: internal error (6)"); vgraphExit (&bndgrafdat); memFree (queudat.qtab); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ bndedgetax[bndedgenum] = orgindxtax[orgedgetax[orgedgenum]]; } bndgrafdat.parttax[bndvertnum] = orggrafptr->parttax[orgvertnum]; /* Copy part array */ if (bnddegrmax < (bndedgenum - bndgrafdat.s.verttax[bndvertnum])) bnddegrmax = (bndedgenum - bndgrafdat.s.verttax[bndvertnum]); } bndeancnbr = 0; for ( ; bndvertnum < bndvertnnd; bndvertnum ++) { /* Fill index array for vertices belonging to last level */ Gnum orgvertnum; Gnum orgedgenum; GraphPart orgpartval; Gnum bnddegrval; orgvertnum = bndvnumtax[bndvertnum]; bndgrafdat.s.verttax[bndvertnum] = bndedgenum; bndgrafdat.s.velotax[bndvertnum] = (orgvelotax != NULL) ? orgvelotax[orgvertnum] : 1; for (orgedgenum = orgverttax[orgvertnum]; /* Keep only band edges */ orgedgenum < orgvendtax[orgvertnum]; orgedgenum ++) { Gnum bndvertend; #ifdef SCOTCH_DEBUG_VGRAPH2 if (bndedgenum >= (bndedgenbr + orggrafptr->s.baseval)) { errorPrint ("vgraphSeparateBd: internal error (7)"); vgraphExit (&bndgrafdat); memFree (queudat.qtab); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ bndvertend = orgindxtax[orgedgetax[orgedgenum]]; if (bndvertend != ~0) bndedgetax[bndedgenum ++] = bndvertend; } orgpartval = orggrafptr->parttax[orgvertnum]; bndgrafdat.parttax[bndvertnum] = orgpartval; /* Record part for vertices of last level */ bnddegrval = bndedgenum - bndgrafdat.s.verttax[bndvertnum]; if (bnddegrval < (orgvendtax[orgvertnum] - orgverttax[orgvertnum])) { /* If vertex is connected to rest of part */ bndedgetax[bndedgenum ++] = bndvertnnd + (Gnum) orgpartval; /* Add anchor edge to proper anchor vertex */ bndeancnbr ++; bnddegrval ++; /* One more (anchor) edge added to this vertex */ } if (bnddegrmax < bnddegrval) bnddegrmax = bnddegrval; } bndgrafdat.parttax[bndvertnnd] = 0; /* Set parts of anchor vertices */ bndgrafdat.parttax[bndvertnnd + 1] = 1; bndgrafdat.s.verttax[bndvertnnd] = bndedgenum; /* Mark end of regular edge array and start of first anchor edge array */ bndedgetmp = bndedgenum + bndeancnbr; #ifdef SCOTCH_DEBUG_VGRAPH2 if ((bndedgetmp - 1) >= (bndedgenbr + orggrafptr->s.baseval)) { errorPrint ("vgraphSeparateBd: internal error (8)"); vgraphExit (&bndgrafdat); memFree (queudat.qtab); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ bndgrafdat.s.edgenbr = bndgrafdat.s.edlosum = bndedgetmp - orggrafptr->s.baseval; /* Since edge load array not kept */ bndgrafdat.s.verttax[bndvertnnd + 2] = bndedgetmp; /* Mark end of edge array with anchor vertices */ for (bndvertnum = bndvlvlnum; bndvertnum < bndvertnnd; bndvertnum ++) { /* Fill anchor edge arrays */ Gnum orgvertnum; orgvertnum = bndvnumtax[bndvertnum]; if (bndgrafdat.s.verttax[bndvertnum + 1] > bndgrafdat.s.verttax[bndvertnum]) { /* If vertex is not isolated */ Gnum bndvertend; bndvertend = bndedgetax[bndgrafdat.s.verttax[bndvertnum + 1] - 1]; /* Get last neighbor of its edge sub-array */ if (bndvertend >= bndvertnnd) { /* If it is an anchor */ if (bndvertend == bndvertnnd) /* Add edge from proper anchor */ bndedgetax[bndedgenum ++] = bndvertnum; else bndedgetax[-- bndedgetmp] = bndvertnum; } } } bndgrafdat.s.verttax[bndvertnnd + 1] = bndedgenum; /* Mark end of edge array of first anchor and start of second */ #ifdef SCOTCH_DEBUG_VGRAPH2 if (bndedgenum != bndedgetmp) { errorPrint ("vgraphSeparateBd: internal error (9)"); vgraphExit (&bndgrafdat); memFree (queudat.qtab); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ if (bnddegrmax < (bndgrafdat.s.verttax[bndvertnnd + 1] - bndgrafdat.s.verttax[bndvertnnd])) bnddegrmax = (bndgrafdat.s.verttax[bndvertnnd + 1] - bndgrafdat.s.verttax[bndvertnnd]); if (bnddegrmax < (bndgrafdat.s.verttax[bndvertnnd + 2] - bndgrafdat.s.verttax[bndvertnnd + 1])) bnddegrmax = (bndgrafdat.s.verttax[bndvertnnd + 2] - bndgrafdat.s.verttax[bndvertnnd + 1]); bndgrafdat.s.degrmax = bnddegrmax; bndgrafdat.s.edgetax = (Gnum *) memRealloc ((void *) (bndgrafdat.s.edgetax + orggrafptr->s.baseval), bndgrafdat.s.edgenbr * sizeof (Gnum)) - orggrafptr->s.baseval; bndgrafdat.frontab = queudat.qtab + bndgrafdat.s.vertnbr; /* Recycle end of queue array and part of index array as band frontier array */ for (fronnum = 0, bndvertnum = orggrafptr->s.baseval; /* Fill band frontier array with first vertex indices as they make the separator */ fronnum < orggrafptr->fronnbr; fronnum ++, bndvertnum ++) bndgrafdat.frontab[fronnum] = bndvertnum; bndgrafdat.compload[0] = orggrafptr->compload[0]; bndgrafdat.compload[1] = orggrafptr->compload[1]; bndgrafdat.compload[2] = orggrafptr->compload[2]; bndgrafdat.comploaddlt = orggrafptr->comploaddlt; bndgrafdat.compsize[0] = bndvertnbr - bndcompsize1 - orggrafptr->fronnbr + 1; /* "+ 1" for anchor vertices */ bndgrafdat.compsize[1] = bndcompsize1 + 1; bndgrafdat.fronnbr = orggrafptr->fronnbr; bndgrafdat.levlnum = orggrafptr->levlnum; #ifdef SCOTCH_DEBUG_VGRAPH2 if ((graphCheck (&bndgrafdat.s) != 0) || /* Check band graph consistency */ (vgraphCheck (&bndgrafdat) != 0)) { errorPrint ("vgraphSeparateBd: inconsistent band graph data"); bndgrafdat.frontab = NULL; /* Do not free frontab as it is not allocated */ vgraphExit (&bndgrafdat); memFree (queudat.qtab); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ if (vgraphSeparateSt (&bndgrafdat, paraptr->stratbnd) != 0) { /* Apply strategy to band graph */ errorPrint ("vgraphSeparateBd: cannot separate band graph"); bndgrafdat.frontab = NULL; /* Do not free frontab as it is not allocated */ vgraphExit (&bndgrafdat); memFree (queudat.qtab); return (1); } if ((bndgrafdat.parttax[bndvertnnd] != 0) || /* If band graph was too small and anchors changed parts, apply strategy on full graph */ (bndgrafdat.parttax[bndvertnnd + 1] != 1)) { bndgrafdat.frontab = NULL; /* Do not free frontab as it is not allocated */ vgraphExit (&bndgrafdat); memFree (queudat.qtab); return (vgraphSeparateSt (orggrafptr, paraptr->stratorg)); } orggrafptr->compload[0] = bndgrafdat.compload[0]; orggrafptr->compload[1] = bndgrafdat.compload[1]; orggrafptr->compload[2] = bndgrafdat.compload[2]; orggrafptr->comploaddlt = bndgrafdat.comploaddlt; orggrafptr->compsize[0] = orggrafptr->compsize[0] - (bndvertnbr - bndcompsize1 - orggrafptr->fronnbr) + bndgrafdat.compsize[0] - 1; /* "- 1" for anchors */ orggrafptr->compsize[1] = orggrafptr->compsize[1] - bndcompsize1 + bndgrafdat.compsize[1] - 1; orggrafptr->fronnbr = bndgrafdat.fronnbr; for (bndvertnum = bndgrafdat.s.baseval; bndvertnum < bndvertnnd; bndvertnum ++) /* Update part array of full graph */ orggrafptr->parttax[bndvnumtax[bndvertnum]] = bndgrafdat.parttax[bndvertnum]; for (fronnum = 0; fronnum < bndgrafdat.fronnbr; fronnum ++) /* Update frontier array of full graph */ orggrafptr->frontab[fronnum] = bndgrafdat.s.vnumtax[bndgrafdat.frontab[fronnum]]; bndgrafdat.frontab = NULL; /* Do not free frontab as it is not allocated */ vgraphExit (&bndgrafdat); /* Free band graph structures */ memFree (queudat.qtab); #ifdef SCOTCH_DEBUG_VGRAPH2 if (vgraphCheck (orggrafptr) != 0) { errorPrint ("vgraphSeparateBd: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_VGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/dorder_perm.h0000644002563400244210000000547111631447170024320 0ustar trophimeutilisateurs du domaine/* Copyright 2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /**********************************************************/ /* */ /* NAME : dorder_perm.h */ /* */ /* AUTHOR : Francois PELLEGRINI */ /* */ /* FUNCTION : These lines are the data declarations */ /* for the distributed source graph */ /* folding routines. */ /* */ /* # Version 5.0 : from : 14 oct 2007 */ /* to 14 oct 2007 */ /* */ /**********************************************************/ /* ** The type and structure definitions. */ /*+ The sort structure, used to sort permuted vertices. Field vertnum is first because of intSort2asc1. +*/ typedef struct DorderPermSort_ { Gnum vertnum; /*+ Vertex number: FIRST +*/ Gnum permnum; /*+ Direct permutation index +*/ } DorderPermSort; scotch-6.0.4.dfsg/src/libscotch/dgraph_io_load.h0000644002563400244210000000562411631447170024751 0ustar trophimeutilisateurs du domaine/* Copyright 2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_io_load.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the distributed graph loading **/ /** routines. **/ /** **/ /** DATES : # Version 5.0 : from : 12 may 2007 **/ /** to 13 may 2007 **/ /** **/ /************************************************************/ /* ** The function prototypes. */ #ifndef DGRAPH_IO_LOAD #define static #endif static int dgraphLoadCent (Dgraph * restrict const, FILE * const, Gnum, const GraphFlag, const int); static int dgraphLoadDist (Dgraph * restrict const, FILE * const, Gnum, const GraphFlag); static int dgraphLoadMulti (Dgraph * restrict const, FILE * const, Gnum, const GraphFlag); #undef static scotch-6.0.4.dfsg/src/libscotch/kgraph_map_bd.h0000644002563400244210000000670311762164002024566 0ustar trophimeutilisateurs du domaine/* Copyright 2010,2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph_map_bd.h **/ /** **/ /** AUTHOR : Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the band graph partitioning **/ /** routine for distributed graphs. **/ /** **/ /** DATES : # Version 6.0 : from : 05 jan 2010 **/ /** to : 20 feb 2012 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ Flag array accessors. +*/ #define kgraphMapBdFlagSize(n) (((n) + (sizeof (int) << 3) - 1) / (sizeof (int) << 3)) #define kgraphMapBdFlagVal(a,n) (((a)[(n) / (sizeof (int) << 3)] >> ((n) & ((sizeof (int) << 3) - 1))) & 1) #define kgraphMapBdFlagSet(a,n) (a)[(n) / (sizeof (int) << 3)] |= (1 << ((n) & ((sizeof (int) << 3) - 1))) /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct KgraphMapBdParam_ { INT distmax; /*+ Width of band surrounding the frontier +*/ Strat * stratbnd; /*+ Strategy for band graph +*/ Strat * stratorg; /*+ Strategy for original graph +*/ } KgraphMapBdParam; /* ** The function prototypes. */ #ifndef KGRAPH_MAP_BD #define static #endif int kgraphMapBd (Kgraph * const, const KgraphMapBdParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/kgraph.c0000644002563400244210000003671512473174741023300 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : Part of a bipartitioning mapper. **/ /** This module handles the k-way active **/ /** graph and save data structure handling **/ /** routines. **/ /** **/ /** DATES : # Version 3.2 : from : 03 oct 1997 **/ /** to 26 may 1998 **/ /** # Version 3.4 : from : 30 oct 2001 **/ /** to 30 oct 2001 **/ /** # Version 4.0 : from : 24 jun 2004 **/ /** to 16 feb 2005 **/ /** # Version 5.1 : from : 28 sep 2008 **/ /** to 31 aug 2011 **/ /** # Version 6.0 : from : 03 mar 2011 **/ /** to 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define KGRAPH #include "module.h" #include "common.h" #include "graph.h" #include "arch.h" #include "mapping.h" #include "kgraph.h" /***********************************/ /* */ /* Active graph handling routines. */ /* */ /***********************************/ /* This routine builds the active graph ** corresponding to the given k-way ** partition parameters. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int kgraphInit ( Kgraph * restrict const actgrafptr, /*+ Active graph +*/ const Graph * restrict const srcgrafptr, /*+ Source graph +*/ const Arch * restrict const archptr, /*+ Target architecture +*/ const ArchDom * restrict const domnptr, /*+ Target architecture initial domain +*/ const Gnum vfixnbr, /*+ Number of fixed vertices in array +*/ const Anum * restrict const pfixtax, /*+ Fixed vertex part array +*/ const Anum * restrict const parotax, /*+ Pointer to old part array +*/ const Gnum crloval, /*+ Coefficient load for regular edges +*/ const Gnum cmloval, /*+ Coefficient load for migration edges +*/ const Gnum * restrict const vmlotax) /*+ Vertex migration cost array +*/ { ArchDom domndat; /* First, largest domain */ const ArchDom * restrict domntmp; #ifdef SCOTCH_DEBUG_KGRAPH2 if ((crloval < 1) || (cmloval < 0)) { errorPrint ("kgraphInit: invalid parameters"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ archDomFrst (archptr, &domndat); /* Get first, largest domain */ if (srcgrafptr != &actgrafptr->s) { /* If graph not already in place */ actgrafptr->s = *srcgrafptr; /* Clone source graph */ actgrafptr->s.flagval &= (GRAPHBITSUSED & ~GRAPHFREETABS); /* Remove extended graph class flags and do not allow freeing */ } if (archptr != &actgrafptr->a) /* If architecture not already in place */ actgrafptr->a = *archptr; /* Clone it */ mapInit (&actgrafptr->m, &actgrafptr->s, &actgrafptr->a, ((domnptr == NULL) ? &domndat : domnptr)); /* Use largest domain if none provided */ mapInit (&actgrafptr->r.m, &actgrafptr->s, &actgrafptr->a, ((domnptr == NULL) ? &domndat : domnptr)); if (parotax != NULL) { /* If old part array provided */ if ((mapAlloc (&actgrafptr->r.m) != 0) || (mapBuild (&actgrafptr->r.m, parotax) != 0)) { errorPrint ("kgraphInit: cannot initialize remapping"); return (1); } } actgrafptr->r.crloval = crloval; actgrafptr->r.cmloval = cmloval; actgrafptr->r.vmlotax = vmlotax; /* Set vertex migration load array or NULL */ actgrafptr->vfixnbr = vfixnbr; actgrafptr->pfixtax = pfixtax; if (mapAlloc (&actgrafptr->m) != 0) { errorPrint ("kgraphInit: cannot initialize mapping"); return (1); } if (((actgrafptr->frontab = memAlloc (actgrafptr->s.vertnbr * sizeof (Gnum))) == NULL) || /* Allocation and initialization of imbalance arrays */ (memAllocGroup ((void **) (void *) &actgrafptr->comploadavg, (size_t) (actgrafptr->m.domnmax * sizeof (Gnum)), /* TRICK: can send both compload arrays in one piece */ &actgrafptr->comploaddlt, (size_t) (actgrafptr->m.domnmax * sizeof (Gnum)), NULL) == NULL)) { errorPrint ("kgraphInit: out of memory"); if (actgrafptr->frontab != NULL) memFree (actgrafptr->frontab); return (1); } actgrafptr->s.flagval |= KGRAPHFREECOMP | KGRAPHFREEFRON; /* comploadavg and comploaddlt are always grouped */ actgrafptr->comploadavg[0] = actgrafptr->s.velosum; actgrafptr->comploaddlt[0] = 0; actgrafptr->fronnbr = 0; /* No frontier yet */ actgrafptr->comploadrat = (double) srcgrafptr->velosum / (double) archDomWght (archptr, &domndat); /* Always balance with respect to whole original graph */ actgrafptr->commload = 0; actgrafptr->levlnum = 0; actgrafptr->kbalval = 1; /* No information on imbalance yet */ return (0); } /* This routine frees the contents ** of the given active graph and ** updates the mapping data accordingly. ** It returns: ** - VOID : in all cases. */ void kgraphExit ( Kgraph * restrict const grafptr) { mapExit (&grafptr->m); mapExit (&grafptr->r.m); if (((grafptr->s.flagval & KGRAPHFREEVMLO) != 0) && /* If vmlotax must be freed */ (grafptr->r.vmlotax != NULL)) /* And if it exists */ memFree (grafptr->r.vmlotax + grafptr->s.baseval); /* Free it */ if (((grafptr->s.flagval & KGRAPHFREEPFIX) != 0) && /* If pfixtax must be freed */ (grafptr->pfixtax != NULL)) /* And if it exists */ memFree (grafptr->pfixtax + grafptr->s.baseval); /* Free it */ if (((grafptr->s.flagval & KGRAPHFREEFRON) != 0) && /* If frontab must be freed */ (grafptr->frontab != NULL)) /* And if it exists */ memFree (grafptr->frontab); /* Free it */ if (((grafptr->s.flagval & KGRAPHFREECOMP) != 0) && /* If comptabs must be freed */ (grafptr->comploadavg != NULL)) /* And if it exists */ memFree (grafptr->comploadavg); /* Free it */ graphExit (&grafptr->s); #ifdef SCOTCH_DEBUG_KGRAPH2 memSet (grafptr, ~0, sizeof (Kgraph)); /* Purge kgraph fields */ #endif /* SCOTCH_DEBUG_KGRAPH2 */ } /* This routine moves all of the graph ** vertices to the first subdomain, and ** computes the resulting gains. ** It returns: ** - VOID : in all cases. */ void kgraphFrst ( Kgraph * restrict const grafptr) { archDomFrst (grafptr->m.archptr, &grafptr->m.domntab[0]); grafptr->m.domnnbr = 1; memSet (grafptr->m.parttax + grafptr->s.baseval, 0, grafptr->s.vertnbr * sizeof (Anum)); /* Set all vertices to subdomain 0 */ memSet (grafptr->comploadavg + 1, 0, (2 * grafptr->m.domnmax - 1) * sizeof (Gnum)); grafptr->comploadavg[0] = grafptr->s.velosum; grafptr->commload = 0; grafptr->m.domntab[0] = grafptr->m.domnorg; /* Point to first domain */ grafptr->fronnbr = 0; /* No frontier vertices */ } /* This routine computes the cost of the ** current partition. ** It returns: ** - VOID : in all cases. */ void kgraphCost ( Kgraph * restrict const grafptr) { Gnum vertnum; Gnum * restrict compload; Gnum commload; double fdomwgt; Gnum fvelsum; Gnum velosum; Anum domnnum; ArchDom domndat; double domnrat; const Arch * restrict const archptr = &grafptr->a; const ArchDom * restrict const domntab = grafptr->m.domntab; Anum * restrict const parttax = grafptr->m.parttax; const Gnum * restrict const verttax = grafptr->s.verttax; const Gnum * restrict const velotax = grafptr->s.velotax; const Gnum * restrict const vendtax = grafptr->s.vendtax; const Gnum * restrict const edlotax = grafptr->s.edlotax; const Gnum * restrict const edgetax = grafptr->s.edgetax; const Anum domnnbr = grafptr->m.domnnbr; commload = 0; compload = grafptr->comploaddlt; /* Use delta array as temporary storage */ memSet (compload, 0, domnnbr * sizeof (Gnum)); for (vertnum = grafptr->s.baseval; vertnum < grafptr->s.vertnnd; vertnum ++) { Gnum edgenum; Gnum edgennd; Anum partval; /* Part of current vertex */ Anum partlst; /* Part of last vertex for which a distance was computed */ Anum distlst; /* Last distance computed */ Gnum veloval; partval = parttax[vertnum]; partlst = -1; /* Invalid part to recompute distance */ distlst = -1; /* To prevent compiler from yielding */ #ifdef SCOTCH_DEBUG_KGRAPH2 if ((partval < 0) || (partval >= domnnbr)) { errorPrint ("kgraphCost: invalid part number (1)"); return; } #endif /* SCOTCH_DEBUG_KGRAPH2 */ veloval = (velotax != NULL) ? velotax[vertnum] : 1; compload[partval] += veloval; for (edgenum = verttax[vertnum], edgennd = vendtax[vertnum]; edgenum < edgennd; edgenum ++) { Gnum vertend; Anum partend; vertend = edgetax[edgenum]; if (vertend > vertnum) /* Compute loads only once */ continue; partend = parttax[vertend]; #ifdef SCOTCH_DEBUG_KGRAPH2 if ((partend < 0) || (partend >= domnnbr)) { errorPrint ("kgraphCost: invalid part number (2)"); return; } #endif /* SCOTCH_DEBUG_KGRAPH2 */ if (partval != partend) { Anum distval; distval = (partend != partlst) ? archDomDist (archptr, &domntab[partval], &domntab[partend]) : distlst; distlst = distval; partlst = partend; commload += (Gnum) distval * ((edlotax != NULL) ? edlotax[edgenum] : 1); } } } grafptr->commload = commload; fdomwgt = 0; fvelsum = 0; if ((grafptr->s.flagval & KGRAPHHASANCHORS) != 0) { const Gnum vertancnnd = grafptr->s.vertnnd - domnnbr; Gnum veloval; for (domnnum = 0; domnnum < domnnbr; domnnum ++) if ((grafptr->s.verttax[vertancnnd + domnnum + 1] - grafptr->s.verttax[vertancnnd + domnnum]) != 0) continue; if (domnnum != domnnbr) { for (domnnum = 0; domnnum < domnnbr; domnnum ++) { if ((grafptr->s.verttax[vertancnnd + domnnum + 1] - grafptr->s.verttax[vertancnnd + domnnum]) == 0) { veloval = grafptr->s.velotax[vertancnnd + domnnum]; fdomwgt += (double) archDomWght (archptr, &grafptr->m.domntab[domnnum]); fvelsum += veloval; compload[domnnum] -= grafptr->comploadavg[domnnum] = veloval; #ifdef SCOTCH_DEBUG_KGRAPH2 if (compload[domnnum] != 0) { errorPrint ("kgraphCost: invalid load difference"); return; } #endif /* SCOTCH_DEBUG_KGRAPH2 */ } } } } archDomFrst (archptr, &domndat); domnrat = (double) archDomWght (archptr, &domndat); domnrat -= fdomwgt; velosum = grafptr->s.velosum - fvelsum; for (domnnum = 0; domnnum < domnnbr; domnnum ++) { compload[domnnum] -= grafptr->comploadavg[domnnum] = (Gnum) ((double) velosum * ((double) archDomWght (archptr, &grafptr->m.domntab[domnnum]) / domnrat)); } } /* This routine computes the frontier ** array of the current partition. ** It returns: ** - VOID : in all cases. */ void kgraphFron ( Kgraph * restrict const grafptr) { Gnum vertnum; Gnum vertnnd; Gnum fronnbr; const Gnum * restrict const verttax = grafptr->s.verttax; const Gnum * restrict const vendtax = grafptr->s.vendtax; const Gnum * restrict const edgetax = grafptr->s.edgetax; const Anum * restrict const parttax = grafptr->m.parttax; Gnum * restrict const frontab = grafptr->frontab; for (vertnum = grafptr->s.baseval, vertnnd = grafptr->s.vertnnd, fronnbr = 0; vertnum < vertnnd; vertnum ++) { Anum partval; /* Part of current vertex */ Gnum edgenum; /* Number of current edge */ partval = parttax[vertnum]; for (edgenum = verttax[vertnum]; edgenum < vendtax[vertnum]; edgenum ++) { if (parttax[edgetax[edgenum]] != partval) { /* If neighbor does not belong to the same part */ frontab[fronnbr ++] = vertnum; break; } } } grafptr->fronnbr = fronnbr; } scotch-6.0.4.dfsg/src/libscotch/library_graph_map_view.h0000644002563400244210000000714311631447170026530 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_map_view.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the declarations for **/ /** the mapping viewing routines. **/ /** **/ /** DATES : # Version 5.0 : from : 04 feb 2007 **/ /** to 04 feb 2007 **/ /** **/ /************************************************************/ #define LIBRARY_GRAPH_MAP_VIEW_H /* ** The type definitions. */ /*+ Complementary vertex structure. +*/ typedef struct GraphMapViewVertex_ { Gnum passnum; /*+ Number of pass when vertex selected +*/ Gnum vertdist; /*+ Current distance from diameter vertex +*/ } GraphMapViewVertex; /*+ Neighbor queue. +*/ typedef struct GraphMapViewQueue_ { Gnum * head; /*+ Head of distance queue +*/ Gnum * tail; /*+ Tail of distance queue +*/ Gnum * qtab; /*+ Array of queue elements +*/ } GraphMapViewQueue; /* ** The function prototypes. */ #ifndef LIBRARY_GRAPH_MAP_VIEW #define static #endif static Gnum graphMapView3 (const Graph * const, const Anum * const, const Anum); #undef static /* ** The macro definitions. */ #define graphMapViewQueueFlush(queue) ((queue)->head = (queue)->tail = (queue)->qtab) #define graphMapViewQueueEmpty(queue) ((queue)->head <= (queue)->tail) #define graphMapViewQueuePut(queue,vnum) (* ((queue)->head ++) = (vnum)) #define graphMapViewQueueGet(queue) (* ((queue)->tail ++)) scotch-6.0.4.dfsg/src/libscotch/gain.c0000644002563400244210000003214111660505556022726 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gain.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles logarithmic gain **/ /** table structures. **/ /** **/ /** DATES : # Version 0.0 : from : 26 oct 1996 **/ /** to 30 nov 1996 **/ /** # Version 0.1 : from : 10 may 1999 **/ /** to 10 may 1999 **/ /** # Version 4.0 : from : 10 jan 2004 **/ /** to 18 mar 2005 **/ /** # Version 5.0 : from : 24 mar 2008 **/ /** to 24 mar 2008 **/ /** **/ /** NOTES : # Most of the contents of this module **/ /** comes from "map_b_fm" of the SCOTCH **/ /** project (v3.2). **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GAIN #include "module.h" #include "common.h" #include "gain.h" /* ** The static variables. */ static GainLink gainLinkDummy; /*+ Dummy link space for fast linked list operations +*/ /*************************************************/ /* */ /* These routines deal with generic gain tables. */ /* */ /*************************************************/ /* This routine allocates and initializes ** a gain table structure with the proper ** number of subbits. ** It returns: ** - !NULL : pointer to the gain table; ** - NULL : on error. */ GainTabl * gainTablInit ( const INT gainmax, const INT subbits) { GainEntr * entrptr; GainTabl * tablptr; INT totsize; if (gainmax >= GAIN_LINMAX) { /* If logarithmic indexing */ totsize = ((sizeof (INT) << 3) - subbits) << (subbits + 1); /* Allocate gain table */ if ((tablptr = (GainTabl *) memAlloc (sizeof (GainTabl) + (totsize - 1) * sizeof (GainEntr))) == NULL) return (NULL); tablptr->tablAdd = gainTablAddLog; tablptr->subbits = subbits; /* Fill gain table fields */ tablptr->submask = (1 << (subbits + 1)) - 1; /* Mask with all subbits, plus one, set to 1 */ } else { /* Linear indexing */ totsize = 2 * GAIN_LINMAX; /* Allocate gain table */ if ((tablptr = (GainTabl *) memAlloc (sizeof (GainTabl) + (totsize - 1) * sizeof (GainEntr))) == NULL) return (NULL); tablptr->tablAdd = gainTablAddLin; tablptr->subbits = 0; /* Fill gain table fields */ tablptr->submask = 0; } tablptr->totsize = totsize; tablptr->tabl = tablptr->tabk + (totsize / 2); tablptr->tend = tablptr->tabk + (totsize - 1); /* End of gain entry array */ tablptr->tmin = tablptr->tend; /* Entries of extremal gain */ tablptr->tmax = tablptr->tabk; for (entrptr = tablptr->tabk; /* Initialize gain table entries */ entrptr <= tablptr->tend; entrptr ++) entrptr->next = &gainLinkDummy; /* Point to dummy link area */ return (tablptr); } /* This routine deletes a gain list ** It returns: ** - VOID : in all cases. */ void gainTablExit ( GainTabl * const tablptr) { memFree (tablptr); /* Free table structure itself */ } /* This routine flushes the contents of ** the given gain table. ** It returns: ** - VOID : in all cases. */ void gainTablFree ( GainTabl * const tablptr) { GainEntr * entrptr; for (entrptr = tablptr->tmin; /* Flush only used area */ entrptr <= tablptr->tmax; entrptr ++) entrptr->next = &gainLinkDummy; /* Point to dummy link area */ tablptr->tmin = tablptr->tend; /* Entries of extremal gain */ tablptr->tmax = tablptr->tabk; } /* This routine adds a vertex to the table ** and table gain indicated in the vertex ** fields. ** It returns: ** - VOID : in all cases. */ void gainTablAddLin ( GainTabl * const tablptr, /*+ Pointer to gain table +*/ GainLink * const linkptr, /*+ Pointer to entry to add +*/ const INT gain) /*+ Gain value +*/ { GainEntr * entrptr; /* Pointer to gain entry */ GainLink * headptr; /* Pointer to head of list */ #ifdef SCOTCH_DEBUG_GAIN2 if (tablptr->tablAdd != gainTablAddLin) { errorPrint ("gainTablAddLin: table type mismatch"); return; } #endif /* SCOTCH_DEBUG_GAIN2 */ entrptr = tablptr->tabl + gain; if (entrptr < tablptr->tabk) entrptr = tablptr->tabk; else if (entrptr > tablptr->tend) entrptr = tablptr->tend; if (entrptr < tablptr->tmin) tablptr->tmin = entrptr; if (entrptr > tablptr->tmax) tablptr->tmax = entrptr; headptr = (GainLink *) entrptr; /* TRICK: assume gain entry is a link */ linkptr->tabl = entrptr; /* Set table position */ headptr->next->prev = linkptr; /* Link vertex in gain list: TRICK */ linkptr->prev = headptr; linkptr->next = headptr->next; headptr->next = linkptr; } /* This routine adds a vertex to the table ** and table gain indicated in the vertex ** fields. ** It returns: ** - VOID : in all cases. */ void gainTablAddLog ( GainTabl * const tablptr, /*+ Pointer to gain table +*/ GainLink * const linkptr, /*+ Pointer to entry to add +*/ const INT gain) /*+ Gain value +*/ { GainEntr * entrptr; /* Pointer to gain entry */ INT i, j; #ifdef SCOTCH_DEBUG_GAIN2 if (tablptr->tablAdd != gainTablAddLog) { errorPrint ("gainTablAddLog: table type mismatch"); return; } #endif /* SCOTCH_DEBUG_GAIN2 */ if (gain >= 0) { /* Compute table entry for gain */ for (i = 0, j = gain; j > tablptr->submask; i ++, j >>= 1) ; i = (i << tablptr->subbits) + j; } else { for (i = 0, j = - (gain + 1); j > tablptr->submask; i ++, j >>= 1) ; i = - ((i << tablptr->subbits) + j + 1); } entrptr = tablptr->tabl + i; if (entrptr < tablptr->tmin) tablptr->tmin = entrptr; if (entrptr > tablptr->tmax) tablptr->tmax = entrptr; #ifdef SCOTCH_DEBUG_GAIN3 if ((entrptr->next != &gainLinkDummy) && (entrptr->next->prev != (GainLink *) entrptr)) { errorPrint ("gainTablAddLog: bad first element"); return; } if (gainTablCheck (entrptr) != 0) { errorPrint ("gainTablAddLog: bad chaining"); } #endif /* SCOTCH_DEBUG_GAIN3 */ entrptr->next->prev = linkptr; /* Link vertex in gain list: TRICK */ linkptr->prev = (GainLink *) entrptr; linkptr->next = entrptr->next; linkptr->tabl = entrptr; /* Set table position */ entrptr->next = linkptr; } /* This routine removes a link ** from the table. ** It returns: ** - VOID : in all cases. */ #ifdef SCOTCH_DEBUG_GAIN1 /* Compiled only in debug mode */ void gainTablDel ( GainTabl * const tablptr, GainLink * const linkptr) /*+ Pointer to link to delete +*/ { #ifdef SCOTCH_DEBUG_GAIN3 if (linkptr->tabl != NULL) { if ((linkptr->tabl->next != &gainLinkDummy) && (linkptr->tabl->next->prev != (GainLink *) linkptr->tabl)) { errorPrint ("gainTablDel: bad first element"); return; } if (gainTablCheck (linkptr->tabl) != 0) { errorPrint ("gainTablDel: bad chaining"); return; } } #endif /* SCOTCH_DEBUG_GAIN3 */ linkptr->next->prev = linkptr->prev; /* TRICK: may write in dummy link area */ linkptr->prev->next = linkptr->next; } #endif /* SCOTCH_DEBUG_GAIN1 */ /* This routine returns the link of best ** gain in the table structure. ** It returns: ** - !NULL : pointer to the vertex. ** - NULL : if no such vertex available. */ GainLink * gainTablFrst ( GainTabl * const tablptr) { GainEntr * entrptr; for (entrptr = tablptr->tmin; entrptr <= tablptr->tend; entrptr ++) { if (entrptr->next != &gainLinkDummy) { tablptr->tmin = entrptr; #ifdef SCOTCH_DEBUG_GAIN3 if (gainTablCheck (entrptr) != 0) { errorPrint ("gainTablFrst: bad chaining"); return (NULL); } #endif /* SCOTCH_DEBUG_GAIN3 */ return (entrptr->next); } } tablptr->tmin = tablptr->tend; tablptr->tmax = tablptr->tabk; return (NULL); } /* This routine returns the next best vertex ** following the given vertex. ** It returns: ** - !NULL : pointer to the vertex. ** - NULL : if no such vertex available. */ GainLink * gainTablNext ( GainTabl * const tablptr, const GainLink * const linkptr) { GainEntr * entrptr; if (linkptr->next != &gainLinkDummy) { #ifdef SCOTCH_DEBUG_GAIN3 if (gainTablCheck (linkptr->tabl) != 0) { errorPrint ("gainTablNext: bad chaining (1)"); return (NULL); } #endif /* SCOTCH_DEBUG_GAIN3 */ return (linkptr->next); } for (entrptr = linkptr->tabl + 1; entrptr < tablptr->tend; entrptr ++) { if (entrptr->next != &gainLinkDummy) { #ifdef SCOTCH_DEBUG_GAIN3 if (gainTablCheck (entrptr) != 0) { errorPrint ("gainTablNext: bad chaining (2)"); return (NULL); } #endif /* SCOTCH_DEBUG_GAIN3 */ return (entrptr->next); } } return (NULL); } /* This routine checks the consistency of the ** given linked list. ** It returns: ** - !NULL : pointer to the vertex. ** - NULL : if no such vertex available. */ #ifdef SCOTCH_DEBUG_GAIN3 static int gainTablCheck2 ( GainEntr * const entrptr, GainLink * const linkptr) { GainLink * nextptr; int o; if (linkptr->next == &gainLinkDummy) /* If end of list successfully reached */ return (0); if (linkptr->next == NULL) /* If loop discovered */ return (1); if (linkptr->tabl != entrptr) return (1); nextptr = linkptr->next; /* Save pointer to next cell */ linkptr->next = NULL; /* Flag cell as already visited */ o = gainTablCheck2 (entrptr, nextptr); /* Process next cell */ linkptr->next = nextptr; /* Restore cell state */ return (o); } int gainTablCheck ( GainEntr * const entrptr) { if (entrptr->next == &gainLinkDummy) /* If end of list successfully reached */ return (0); if ((entrptr->next == NULL) || /* If problem with link */ (gainTablCheck2 (entrptr, entrptr->next) != 0)) { errorPrint ("gainTablCheck: bad linked list"); return (1); } return (0); } #endif /* SCOTCH_DEBUG_GAIN3 */ scotch-6.0.4.dfsg/src/libscotch/mesh_check.c0000644002563400244210000002167311631447171024105 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mesh_check.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles the source mesh **/ /** functions. **/ /** **/ /** DATES : # Version 4.0 : from : 29 dec 2001 **/ /** to 11 may 2004 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define MESH #include "module.h" #include "common.h" #include "graph.h" #include "mesh.h" /****************************************/ /* */ /* These routines handle source meshes. */ /* */ /****************************************/ /* This routine checks the consistency ** of the given mesh. ** It returns: ** - 0 : if mesh data are consistent. ** - !0 : on error. */ int meshCheck ( const Mesh * const meshptr) { Gnum vertnnd; /* Maximum vertex index */ Gnum vertnum; /* Number of current vertex */ Gnum veisnbr; /* Number of isolated element vertices */ Gnum velosum; /* Vertex element load sum */ Gnum vnlosum; /* Vertex node load sum */ Gnum degrmax; /* Maximum degree */ if ((meshptr->velmbas > meshptr->velmnnd) || (meshptr->vnodbas > meshptr->vnodnnd) || ((meshptr->velmnnd != meshptr->vnodbas) && (meshptr->vnodnnd != meshptr->velmbas))) { errorPrint ("meshCheck: invalid node and element numbers"); return (1); } vertnnd = meshptr->velmnbr + meshptr->vnodnbr + meshptr->baseval; degrmax = 0; veisnbr = 0; for (vertnum = meshptr->velmbas; vertnum < meshptr->velmnnd; vertnum ++) { /* For all element vertices */ Gnum degrval; Gnum edgenum; if ((meshptr->verttax[vertnum] < meshptr->baseval) || (meshptr->vendtax[vertnum] < meshptr->verttax[vertnum])) { errorPrint ("meshCheck: invalid vertex arrays (1)"); return (1); } degrval = meshptr->vendtax[vertnum] - meshptr->verttax[vertnum]; if (degrval > degrmax) degrmax = degrval; else if (degrval == 0) veisnbr ++; for (edgenum = meshptr->verttax[vertnum]; edgenum < meshptr->vendtax[vertnum]; edgenum ++) { Gnum vertend; /* Number of end vertex */ Gnum edgeend; /* Number of end vertex edge */ vertend = meshptr->edgetax[edgenum]; if ((vertend < meshptr->baseval) || (vertend >= vertnnd)) { /* If invalid edge end */ errorPrint ("meshCheck: invalid edge array (1)"); return (1); } if ((vertend >= meshptr->velmbas) && (vertend < meshptr->velmnnd)) { errorPrint ("meshCheck: element vertices must not be connected together"); return (1); } for (edgeend = meshptr->verttax[vertend]; /* Search for matching arc */ (edgeend < meshptr->vendtax[vertend]) && (meshptr->edgetax[edgeend] != vertnum); edgeend ++) ; if (edgeend >= meshptr->vendtax[vertend]) { errorPrint ("meshCheck: arc data do not match (1)"); return (1); } for (edgeend ++; /* Search for duplicate arcs */ (edgeend < meshptr->vendtax[vertend]) && (meshptr->edgetax[edgeend] != vertnum); edgeend ++) ; if (edgeend < meshptr->vendtax[vertend]) { errorPrint ("meshCheck: duplicate arc (1)"); return (1); } } } if (veisnbr != meshptr->veisnbr) { errorPrint ("meshCheck: invalid number of isolated element vertices (1)"); return (1); } for (vertnum = meshptr->vnodbas; vertnum < meshptr->vnodnnd; vertnum ++) { /* For all node vertices */ Gnum edgenum; if ((meshptr->verttax[vertnum] < meshptr->baseval) || (meshptr->vendtax[vertnum] < meshptr->verttax[vertnum])) { errorPrint ("meshCheck: invalid vertex arrays (2)"); return (1); } if ((meshptr->vendtax[vertnum] - meshptr->verttax[vertnum]) > degrmax) degrmax = meshptr->vendtax[vertnum] - meshptr->verttax[vertnum]; for (edgenum = meshptr->verttax[vertnum]; edgenum < meshptr->vendtax[vertnum]; edgenum ++) { Gnum vertend; /* Number of end vertex */ Gnum edgeend; /* Number of end vertex edge */ vertend = meshptr->edgetax[edgenum]; if ((vertend < meshptr->baseval) || (vertend >= vertnnd)) { /* If invalid edge end */ errorPrint ("meshCheck: invalid edge array (2)"); return (1); } if ((vertend >= meshptr->vnodbas) && (vertend < meshptr->vnodnnd)) { errorPrint ("meshCheck: node vertices must not be connected together"); return (1); } for (edgeend = meshptr->verttax[vertend]; /* Search for matching arc */ (edgeend < meshptr->vendtax[vertend]) && (meshptr->edgetax[edgeend] != vertnum); edgeend ++) ; if (edgeend >= meshptr->vendtax[vertend]) { errorPrint ("meshCheck: arc data do not match (2)"); return (1); } for (edgeend ++; /* Search for duplicate arcs */ (edgeend < meshptr->vendtax[vertend]) && (meshptr->edgetax[edgeend] != vertnum); edgeend ++) ; if (edgeend < meshptr->vendtax[vertend]) { errorPrint ("meshCheck: duplicate arc (2)"); return (1); } } } if (meshptr->velotax == NULL) /* Recompute node vertex load sum */ velosum = meshptr->velmnnd - meshptr->velmbas; else { for (vertnum = meshptr->velmbas, velosum = 0; vertnum < meshptr->velmnnd; vertnum ++) { if (meshptr->velotax[vertnum] < 1) { errorPrint ("meshCheck: invalid element vertex load"); return (1); } velosum += meshptr->velotax[vertnum]; } } if (velosum != meshptr->velosum) { errorPrint ("meshCheck: invalid element vertex load sum"); return (1); } if (meshptr->vnlotax == NULL) /* Recompute node vertex load sum */ vnlosum = meshptr->vnodnnd - meshptr->vnodbas; else { for (vertnum = meshptr->vnodbas, vnlosum = 0; vertnum < meshptr->vnodnnd; vertnum ++) { if (meshptr->vnlotax[vertnum] < 1) { errorPrint ("meshCheck: invalid node vertex load"); return (1); } vnlosum += meshptr->vnlotax[vertnum]; } } if (vnlosum != meshptr->vnlosum) { errorPrint ("meshCheck: invalid node vertex load sum"); return (1); } if (meshptr->degrmax < degrmax) { errorPrint ("meshCheck: invalid maximum degree"); return (1); } return (0); } scotch-6.0.4.dfsg/src/libscotch/dgraph_fold.h0000644002563400244210000000662211631447170024266 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2009 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_fold.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the distributed source graph **/ /** folding routines. **/ /** **/ /** # Version 5.0 : from : 06 sep 2006 **/ /** to 06 sep 2006 **/ /** # Version 5.1 : from : 31 dec 2008 **/ /** to 01 jan 2009 **/ /** **/ /************************************************************/ /* ** The defines. */ /* Slot indices used for point-to-point folding communications. First indices are used for communications without further processing. At the moment, there are two anonymous slots: the first one for vnumloctab, and the second one for vertinfotab. */ typedef enum DgraphFoldTag_ { DGRAPHFOLDTAGENBR = 2, /*+ Edge size message +*/ DGRAPHFOLDTAGVERT, /*+ vertloctab message +*/ DGRAPHFOLDTAGVELO, /*+ veloloctab message +*/ DGRAPHFOLDTAGEDGE, /*+ edgeloctab message +*/ DGRAPHFOLDTAGEDLO, /*+ edgeloctab message +*/ DGRAPHFOLDTAGNBR /*+ Number of tags +*/ } DgraphFoldTag; scotch-6.0.4.dfsg/src/libscotch/library_dgraph_check_f.c0000644002563400244210000000643112055775762026455 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_check_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API for **/ /** the distributed source graph handling **/ /** routines of the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 26 aug 2006 **/ /** to 26 aug 2006 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "ptscotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the distributed graph handling */ /* routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFDGRAPHCHECK, scotchfdgraphcheck, ( \ const SCOTCH_Dgraph * const grafptr, \ int * const revaptr), \ (grafptr, revaptr)) { *revaptr = SCOTCH_dgraphCheck (grafptr); } scotch-6.0.4.dfsg/src/libscotch/library_error.c0000644002563400244210000001423411631447170024663 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_error.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module provides error handling **/ /** routines to process errors generated by **/ /** the routines of the libSCOTCH library. **/ /** **/ /** DATES : # Version 3.3 : from : 02 oct 1998 **/ /** to 02 oct 1998 **/ /** # Version 3.4 : from : 01 nov 2001 **/ /** to 01 nov 2001 **/ /** # Version 5.0 : from : 06 mar 2008 **/ /** to 24 may 2008 **/ /** # Version 5.1 : from : 27 sep 2008 **/ /** to 17 jul 2011 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY_ERROR #include "module.h" #include "common.h" #include "scotch.h" /********************************/ /* */ /* The error handling routines. */ /* */ /********************************/ static char _SCOTCHerrorProgName[32] = ""; /* This routine sets the program name for ** error reporting. ** It returns: ** - VOID : in all cases. */ void SCOTCH_errorProg ( const char * const progstr) /*+ Program name +*/ { int charnbr; const char * nsrcptr; char * ndstptr; nsrcptr = progstr; ndstptr = _SCOTCHerrorProgName; charnbr = strlen (progstr); if (charnbr > 31) { _SCOTCHerrorProgName[0] = _SCOTCHerrorProgName[1] = _SCOTCHerrorProgName[2] = '.'; ndstptr += 3; nsrcptr += charnbr - 28; charnbr = 28; } strncpy (ndstptr, nsrcptr, charnbr); _SCOTCHerrorProgName[31] = '\0'; } /* This routine prints an error message with ** a variable number of arguments, as printf () ** does, and exits. ** It returns: ** - void : in all cases. */ void SCOTCH_errorPrint ( const char * const errstr, /*+ printf-like variable argument list */ ...) { va_list errlist; /* The argument list of the call */ #ifdef SCOTCH_PTSCOTCH int proclocnum; #endif /* SCOTCH_PTSCOTCH */ fprintf (stderr, "%s", _SCOTCHerrorProgName); #ifdef SCOTCH_PTSCOTCH if ((MPI_Initialized (&proclocnum) == MPI_SUCCESS) && (proclocnum != 0) && (MPI_Comm_rank (MPI_COMM_WORLD, &proclocnum) == MPI_SUCCESS)) fprintf (stderr, "(%d): ", proclocnum); else fprintf (stderr, ": "); #else /* SCOTCH_PTSCOTCH */ if (_SCOTCHerrorProgName[0] != '\0') fprintf (stderr, ": "); #endif /* SCOTCH_PTSCOTCH */ fprintf (stderr, "ERROR: "); va_start (errlist, errstr); vfprintf (stderr, errstr, errlist); /* Print arguments */ va_end (errlist); fprintf (stderr, "\n"); fflush (stderr); /* In case it has been set to buffered mode */ } /* This routine prints a warning message with ** a variable number of arguments, as printf () ** does. ** It returns: ** - VOID : in all cases. */ void SCOTCH_errorPrintW ( const char * const errstr, /*+ printf-like variable argument list */ ...) { va_list errlist; /* The argument list of the call */ #ifdef SCOTCH_PTSCOTCH int proclocnum; #endif /* SCOTCH_PTSCOTCH */ fprintf (stderr, "%s", _SCOTCHerrorProgName); #ifdef SCOTCH_PTSCOTCH if ((MPI_Initialized (&proclocnum) == MPI_SUCCESS) && (proclocnum != 0) && (MPI_Comm_rank (MPI_COMM_WORLD, &proclocnum) == MPI_SUCCESS)) fprintf (stderr, "(%d): ", proclocnum); else fprintf (stderr, ": "); #else /* SCOTCH_PTSCOTCH */ if (_SCOTCHerrorProgName[0] != '\0') fprintf (stderr, ": "); #endif /* SCOTCH_PTSCOTCH */ fprintf (stderr, "WARNING: "); va_start (errlist, errstr); vfprintf (stderr, errstr, errlist); /* Print arguments */ va_end (errlist); fprintf (stderr, "\n"); fflush (stderr); /* In case it has been set to buffered mode */ } scotch-6.0.4.dfsg/src/libscotch/graph_match.h0000644002563400244210000001074712474554132024300 0ustar trophimeutilisateurs du domaine/* Copyright 2012,2015 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : graph_match.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the centralized source graph **/ /** matching routines. **/ /** **/ /** DATES : # Version 6.0 : from : 02 oct 2012 **/ /** to 25 feb 2015 **/ /** **/ /************************************************************/ /* ** The defines. */ #if (defined SCOTCH_PTHREAD) && (defined GRAPHCOARSENTHREAD) #define GRAPHMATCHTHREAD #endif /* (defined SCOTCH_PTHREAD) && (defined GRAPHCOARSENTHREAD) */ /** Prime number for cache-friendly perturbations. **/ #define GRAPHMATCHSCANPERTPRIME 179 /* Prime number */ /** Function block building macro. **/ #define GRAPHMATCHFUNCBLOCK(t) graphMatch##t##NfNvNe, \ graphMatch##t##NfNvEl, \ graphMatch##t##NfVlNe, \ graphMatch##t##NfVlEl, \ graphMatch##t##FxNvNe, \ graphMatch##t##FxNvEl, \ graphMatch##t##FxVlNe, \ graphMatch##t##FxVlEl #define GRAPHMATCHFUNCDECL(t) static void graphMatch##t##NfNvNe (GraphCoarsenThread *); \ static void graphMatch##t##NfNvEl (GraphCoarsenThread *); \ static void graphMatch##t##NfVlNe (GraphCoarsenThread *); \ static void graphMatch##t##NfVlEl (GraphCoarsenThread *); \ static void graphMatch##t##FxNvNe (GraphCoarsenThread *); \ static void graphMatch##t##FxNvEl (GraphCoarsenThread *); \ static void graphMatch##t##FxVlNe (GraphCoarsenThread *); \ static void graphMatch##t##FxVlEl (GraphCoarsenThread *); /* ** The function prototypes. */ void graphMatchNone (GraphCoarsenData *); int graphMatchInit (GraphCoarsenData *); void graphMatch (GraphCoarsenThread * restrict const); #ifndef GRAPH_MATCH #define static #endif GRAPHMATCHFUNCDECL (Seq); GRAPHMATCHFUNCDECL (ThrBeg); GRAPHMATCHFUNCDECL (ThrMid); GRAPHMATCHFUNCDECL (ThrEnd); #undef static scotch-6.0.4.dfsg/src/libscotch/common_sort.c0000644002563400244210000002130411732102634024334 0ustar trophimeutilisateurs du domaine/* This file is part of the Scotch distribution. It does ** not have the standard Scotch header with the INRIA & co. ** copyright notice because it is a very slight adaptation ** of the qsort routine of glibc 2.4, taylored to match ** Scotch needs. As Scotch is distributed according to the ** CeCILL-C license, which is LGPL-compatible, no further ** notices are required. Hence, this "common_sort.c" file ** is distributed according the terms of the LGPL, see ** copyright notice just below. */ /* Copyright (C) 1991,1992,1996,1997,1999,2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Douglas C. Schmidt (schmidt@ics.uci.edu). The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ /* If you consider tuning this algorithm, you should consult first: Engineering a sort function; Jon Bentley and M. Douglas McIlroy; Software - Practice and Experience; Vol. 23 (11), 1249-1265, 1993. */ #ifndef MAX_THRESH #define MAX_THRESH 6 #define max_thresh (MAX_THRESH * INTSORTSIZE) /* Variable turned into constant */ /* Stack node declarations used to store unfulfilled partition obligations. */ typedef struct { char *lo; char *hi; } stack_node; /* The next 4 #defines implement a very fast in-line stack abstraction. */ /* The stack needs log (total_elements) entries (we could even subtract log(MAX_THRESH)). Since total_elements has type size_t, we get as upper bound for log (total_elements): bits per byte (CHAR_BIT) * sizeof(size_t). */ #define STACK_SIZE (CHAR_BIT * sizeof (INT)) #define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top)) #define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi))) #define STACK_NOT_EMPTY (stack < top) #endif /* MAX_THRESH */ /* Order size using quicksort. This implementation incorporates four optimizations discussed in Sedgewick: 1. Non-recursive, using an explicit stack of pointer that store the next array partition to sort. To save time, this maximum amount of space required to store an array of SIZE_MAX is allocated on the stack. Assuming a 32-bit (64 bit) integer for size_t, this needs only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes). Pretty cheap, actually. 2. Chose the pivot element using a median-of-three decision tree. This reduces the probability of selecting a bad pivot value and eliminates certain extraneous comparisons. 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving insertion sort to order the MAX_THRESH items within each partition. This is a big win, since insertion sort is faster for small, mostly sorted array segments. 4. The larger of the two sub-partitions is always pushed onto the stack first, with the algorithm then concentrating on the smaller partition. This *guarantees* no more than log (total_elems) stack size is needed (actually O(1) in this case)! */ /* To be defined : ** INTSORTQUAL : whether the function is "static" or not ** INTSORTNAME : Name of function ** INTSORTSIZE : Size of elements to sort ** INTSORTSWAP : Swapping macro ** INTSORTCMP : Comparison function */ #ifdef INTSORTQUAL INTSORTQUAL #endif /* INTSORTQUAL */ void INTSORTNAME ( void * const pbase, /*+ Array to sort +*/ const INT total_elems) /*+ Number of entries to sort +*/ { register char *base_ptr = (char *) pbase; if (total_elems == 0) /* Avoid lossage with unsigned arithmetic below. */ return; if (total_elems > MAX_THRESH) { char *lo = base_ptr; char *hi = &lo[INTSORTSIZE * (total_elems - 1)]; stack_node stack[STACK_SIZE]; stack_node *top = stack; PUSH (NULL, NULL); while (STACK_NOT_EMPTY) { char *left_ptr; char *right_ptr; /* Select median value from among LO, MID, and HI. Rearrange LO and HI so the three values are sorted. This lowers the probability of picking a pathological pivot value and skips a comparison for both the LEFT_PTR and RIGHT_PTR in the while loops. */ char *mid = lo + INTSORTSIZE * ((hi - lo) / INTSORTSIZE >> 1); if (INTSORTCMP ((void *) mid, (void *) lo)) INTSORTSWAP (mid, lo); if (INTSORTCMP ((void *) hi, (void *) mid)) INTSORTSWAP (mid, hi); else goto jump_over; if (INTSORTCMP ((void *) mid, (void *) lo)) INTSORTSWAP (mid, lo); jump_over:; left_ptr = lo + INTSORTSIZE; right_ptr = hi - INTSORTSIZE; /* Here's the famous ``collapse the walls'' section of quicksort. Gotta like those tight inner loops! They are the main reason that this algorithm runs much faster than others. */ do { while (INTSORTCMP ((void *) left_ptr, (void *) mid)) left_ptr += INTSORTSIZE; while (INTSORTCMP ((void *) mid, (void *) right_ptr)) right_ptr -= INTSORTSIZE; if (left_ptr < right_ptr) { INTSORTSWAP (left_ptr, right_ptr); if (mid == left_ptr) mid = right_ptr; else if (mid == right_ptr) mid = left_ptr; left_ptr += INTSORTSIZE; right_ptr -= INTSORTSIZE; } else if (left_ptr == right_ptr) { left_ptr += INTSORTSIZE; right_ptr -= INTSORTSIZE; break; } } while (left_ptr <= right_ptr); /* Set up pointers for next iteration. First determine whether left and right partitions are below the threshold size. If so, ignore one or both. Otherwise, push the larger partition's bounds on the stack and continue sorting the smaller one. */ if ((size_t) (right_ptr - lo) <= max_thresh) { if ((size_t) (hi - left_ptr) <= max_thresh) /* Ignore both small partitions. */ POP (lo, hi); else /* Ignore small left partition. */ lo = left_ptr; } else if ((size_t) (hi - left_ptr) <= max_thresh) /* Ignore small right partition. */ hi = right_ptr; else if ((right_ptr - lo) > (hi - left_ptr)) { /* Push larger left partition indices. */ PUSH (lo, right_ptr); lo = left_ptr; } else { /* Push larger right partition indices. */ PUSH (left_ptr, hi); hi = right_ptr; } } } /* Once the BASE_PTR array is partially sorted by quicksort the rest is completely sorted using insertion sort, since this is efficient for partitions below MAX_THRESH size. BASE_PTR points to the beginning of the array to sort, and END_PTR points at the very last element in the array (*not* one beyond it!). */ #define min(x, y) ((x) < (y) ? (x) : (y)) { char *const end_ptr = &base_ptr[INTSORTSIZE * (total_elems - 1)]; char *tmp_ptr = base_ptr; char *thresh = min(end_ptr, base_ptr + max_thresh); register char *run_ptr; /* Find smallest element in first threshold and place it at the array's beginning. This is the smallest array element, and the operation speeds up insertion sort's inner loop. */ for (run_ptr = tmp_ptr + INTSORTSIZE; run_ptr <= thresh; run_ptr += INTSORTSIZE) if (INTSORTCMP ((void *) run_ptr, (void *) tmp_ptr)) tmp_ptr = run_ptr; if (tmp_ptr != base_ptr) INTSORTSWAP (tmp_ptr, base_ptr); /* Insertion sort, running from left-hand-side up to right-hand-side. */ run_ptr = base_ptr + INTSORTSIZE; while ((run_ptr += INTSORTSIZE) <= end_ptr) { tmp_ptr = run_ptr - INTSORTSIZE; while (INTSORTCMP ((void *) run_ptr, (void *) tmp_ptr)) tmp_ptr -= INTSORTSIZE; tmp_ptr += INTSORTSIZE; if (tmp_ptr != run_ptr) { char *trav; trav = run_ptr + INTSORTSIZE; while (--trav >= run_ptr) { char c = *trav; char *hi, *lo; for (hi = lo = trav; (lo -= INTSORTSIZE) >= tmp_ptr; hi = lo) *hi = *lo; *hi = c; } } } } } scotch-6.0.4.dfsg/src/libscotch/bgraph_bipart_df_loop.c0000644002563400244210000004017412371155706026321 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2011-2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bgraph_bipart_df_loop.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module computes a bipartition of **/ /** a bipartition graph by using a **/ /** diffusion scheme. **/ /** **/ /** NOTES : # This algorithm has been designed to **/ /** work on band graphs only, for which **/ /** the two anchor vertices are the two **/ /** last vertices, the before-last as **/ /** anchor of part 0, and the last as **/ /** anchor of part 1. **/ /** **/ /** DATES : # Version 5.0 : from : 09 jan 2007 **/ /** to 10 sep 2007 **/ /** # Version 5.1 : from : 29 oct 2007 **/ /** to 27 mar 2011 **/ /** # Version 6.0 : from : 07 nov 2011 **/ /** to : 08 aug 2014 **/ /** **/ /************************************************************/ /****************************/ /* */ /* The diffusion subroutine */ /* pattern. */ /* */ /****************************/ /* This routine computes the diffusion of two ** liquids on the given part of the bipartition ** graph. ** It returns: ** - void : in all cases */ static int BGRAPHBIPARTDFLOOPNAME ( BgraphBipartDfThread * restrict thrdptr) /* Thread-dependent data */ { float * restrict ielstax; /* Inverse of edge load sum array */ float * restrict difotax; /* Old diffusion value array */ float * restrict difntax; /* New diffusion value array */ Gnum vertnum; Gnum fronnum; Gnum compload0; Gnum compload1; Gnum compsize1; Gnum commloadintn; Gnum commloadextn; Gnum commgainextn; Gnum veexnbr; Gnum veexval; Gnum veexval1; /* Negative external gain to part 1 */ Gnum veexsum; Gnum veexsum1; /* Sum of negative external gains */ Gnum veloval; float velfval; INT passnum; Anum distval; BgraphBipartDfData * restrict const loopptr = (BgraphBipartDfData *) thrdptr->thrddat.grouptr; Bgraph * restrict const grafptr = loopptr->grafptr; const Gnum vertbas = thrdptr->vertbas; const Gnum vertnnd = thrdptr->vertnnd; const Gnum vancnnd = MIN (vertnnd, grafptr->s.vertnnd - 2); /* End of regular vertices */ const Gnum * restrict const verttax = grafptr->s.verttax; const Gnum * restrict const vendtax = grafptr->s.vendtax; const Gnum * restrict const velotax = grafptr->s.velotax; const Gnum * restrict const edgetax = grafptr->s.edgetax; const Gnum * restrict const edlotax = grafptr->s.edlotax; const Gnum * restrict const veextax = grafptr->veextax; GraphPart * restrict const parttax = grafptr->parttax; #ifdef BGRAPHBIPARTDFLOOPTHREAD const int thrdlst = loopptr->thrddat.thrdnbr - 1; #endif /* BGRAPHBIPARTDFLOOPTHREAD */ difotax = loopptr->difotax; difntax = loopptr->difntax; if ((ielstax = memAlloc ((vertnnd - vertbas) * sizeof (float))) == NULL) { /* Allocate here for memory affinity as it is a private array */ errorPrint (STRINGIFY (BGRAPHBIPARTDFLOOPNAME) ": out of memory"); #ifdef BGRAPHBIPARTDFLOOPTHREAD loopptr->abrtval = 1; #else /* BGRAPHBIPARTDFLOOPTHREAD */ return (1); #endif /* BGRAPHBIPARTDFLOOPTHREAD */ } else { ielstax -= vertbas; /* Base access to local part of edge load sum array */ distval = grafptr->domndist; veexval = /* Assume no external gains */ veexval1 = 0; veexsum = veexsum1 = 0; for (vertnum = vertbas; vertnum < vertnnd; vertnum ++) { /* Process all vertices, including anchors */ Gnum edlosum; if (edlotax == NULL) /* If graph doesn't have edge weights */ edlosum = vendtax[vertnum] - verttax[vertnum]; else { Gnum edgenum; Gnum edgennd; for (edgenum = verttax[vertnum], edgennd = vendtax[vertnum], edlosum = 0; edgenum < edgennd; edgenum ++) edlosum += edlotax[edgenum]; } edlosum *= distval; if (veextax != NULL) { veexval = veextax[vertnum]; veexval1 = veexval & BGRAPHBIPARTDFGNUMSGNMSK (veexval); /* Get negative external gain only, by superscalar update */ #ifdef SCOTCH_DEBUG_BGRAPH2 if (((veexval >= 0) && (veexval1 != 0)) || ((veexval < 0) && (veexval1 != veexval))) { errorPrint (STRINGIFY (BGRAPHBIPARTDFLOOPNAME) ": internal error"); #ifdef BGRAPHBIPARTDFLOOPTHREAD loopptr->abrtval = 1; #else /* BGRAPHBIPARTDFLOOPTHREAD */ return (1); #endif /* BGRAPHBIPARTDFLOOPTHREAD */ } #endif /* SCOTCH_DEBUG_BGRAPH2 */ veexsum += veexval; /* Sum all external gains, positive and negative */ veexsum1 += veexval1; /* Sum all negative gains */ } difotax[vertnum] = 0.0; ielstax[vertnum] = 1.0F / (float) (edlosum + veexval - 2 * veexval1); /* Add absolute value of veexval */ } if (veextax != NULL) { #ifdef BGRAPHBIPARTDFLOOPTHREAD thrdptr->veexsum = veexsum; thrdptr->veexsum1 = veexsum1; threadReduce (thrdptr, thrdptr, (ThreadReduceFunc) bgraphBipartDfReduceVeex, thrdlst); veexsum = thrdptr->veexsum; /* Will be useful for thread (thrdlst) only */ veexsum1 = thrdptr->veexsum1; if (thrdptr->thrddat.thrdnum == thrdlst) /* Last thread will handle anchors as root of reduction */ #endif /* BGRAPHBIPARTDFLOOPTHREAD */ { ielstax[vertnnd - 2] = 1.0F / (1.0F / ielstax[vertnnd - 2] + (float) (veexsum - veexsum1)); ielstax[vertnnd - 1] = 1.0F / (1.0F / ielstax[vertnnd - 1] - (float) veexsum1); } } #ifdef BGRAPHBIPARTDFLOOPTHREAD if (thrdptr->thrddat.thrdnum == thrdlst) /* Last thread will handle anchors as root of reduction */ #endif /* BGRAPHBIPARTDFLOOPTHREAD */ { difotax[vertnnd - 2] = loopptr->vanctab[0] * ielstax[vertnnd - 2]; /* Load anchor vertices for first pass */ difotax[vertnnd - 1] = loopptr->vanctab[1] * ielstax[vertnnd - 1]; } } #ifdef BGRAPHBIPARTDFLOOPTHREAD threadBarrier (thrdptr); /* Wait until all array values have been computed */ if (loopptr->abrtval == 1) { /* If process alone or some decided to quit */ if (ielstax != NULL) /* Free local array if necessary */ memFree (ielstax + vertbas); return (1); } #endif /* BGRAPHBIPARTDFLOOPTHREAD */ velfval = 1.0F; /* Assume no vertex loads */ for (passnum = loopptr->passnbr; passnum > 0; passnum --) { /* For all passes */ Gnum vertnum; Gnum vancnnt; float vancval; /* Value to load vertex with if anchor */ float * difttax; /* Temporary swap value */ float vancold0 = difotax[grafptr->s.vertnnd - 2]; /* Get for all threads */ float vancold1 = difotax[grafptr->s.vertnnd - 1]; float vancval0; /* External gain contributions from regular vertices to anchors */ float vancval1; vancval0 = vancval1 = 0.0F; vancval = 0.0F; /* At first vertices are not anchors */ vertnum = vertbas; /* Start processing regular vertices, then see */ vancnnt = vancnnd; /* Loop until end of (regular) vertex block */ while (1) { for ( ; vertnum < vancnnt; vertnum ++) { Gnum edgenum; Gnum edgennd; float diffval; edgenum = verttax[vertnum]; edgennd = vendtax[vertnum]; diffval = 0.0F; if (edlotax != NULL) for ( ; edgenum < edgennd; edgenum ++) diffval += difotax[edgetax[edgenum]] * (float) edlotax[edgenum]; else for ( ; edgenum < edgennd; edgenum ++) diffval += difotax[edgetax[edgenum]]; diffval *= (float) distval; if (veextax != NULL) { Gnum veexval; veexval = veextax[vertnum]; if (veexval != 0) { float veextmp; float vanctmp; veextmp = (float) veexval; vanctmp = veextmp * difotax[vertnum]; if (veexval > 0) { /* If external gain links to part 0 */ diffval += veextmp * vancold0; /* Spread contribution from anchor 0 */ vancval0 += vanctmp; } else { /* If external gain links to part 1 */ diffval -= veextmp * vancold1; /* Take opposite of negative value */ vancval1 -= vanctmp; } } } diffval += vancval; /* Add anchor contribution if anchor vertex */ if (velotax != NULL) velfval = (float) velotax[vertnum]; if (diffval >= 0.0F) { diffval -= velfval; if (diffval <= 0.0F) diffval = +BGRAPHBIPARTDFEPSILON; } else { diffval += velfval; if (diffval >= 0.0F) diffval = -BGRAPHBIPARTDFEPSILON; } if (isnan (diffval)) { /* If overflow occured (because of avalanche process) */ #ifdef SCOTCH_DEBUG_BGRAPH2 errorPrintW (STRINGIFY (BGRAPHBIPARTDFLOOPNAME) ": overflow"); #endif /* SCOTCH_DEBUG_BGRAPH2 */ #ifdef BGRAPHBIPARTDFLOOPTHREAD loopptr->abrtval = 1; /* Threads need to halt */ vertnum = vancnnt; /* Skip regular computations but synchronize */ #else /* BGRAPHBIPARTDFLOOPTHREAD */ goto abort; /* Exit this loop without swapping arrays */ #endif /* BGRAPHBIPARTDFLOOPTHREAD */ } difntax[vertnum] = diffval * ielstax[vertnum]; } if (vertnum == vancnnd) { /* If first time we reach the end of regular vertices */ thrdptr->vanctab[0] = vancval0; thrdptr->vanctab[1] = vancval1; #ifdef BGRAPHBIPARTDFLOOPTHREAD if (veextax != NULL) threadReduce (thrdptr, thrdptr, (ThreadReduceFunc) bgraphBipartDfReduceVanc, thrdlst); #endif /* BGRAPHBIPARTDFLOOPTHREAD */ } if (vertnum >= vertnnd) /* If all vertices processed in range array, exit intermediate infinite loop */ break; vancnnt ++; /* Prepare to go only for one more run, to be done twice */ vancval = loopptr->vanctab[vertnum - vancnnd] + thrdptr->vanctab[vertnum - vancnnd]; /* Load variable with anchor value */ } difttax = (float *) difntax; /* Swap old and new diffusion arrays */ difntax = (float *) difotax; /* Casts to prevent IBM compiler from yelling */ difotax = (float *) difttax; #ifdef BGRAPHBIPARTDFLOOPTHREAD threadBarrier (thrdptr); if (loopptr->abrtval == 1) { /* If all threads need to abort */ difotax = (float *) difntax; /* Roll-back to keep last valid array */ break; } #endif /* BGRAPHBIPARTDFLOOPTHREAD */ } abort : ; for (vertnum = vertbas; vertnum < vertnnd; vertnum ++) /* Update part according to diffusion state */ parttax[vertnum] = (difotax[vertnum] <= 0.0F) ? 0 : 1; #ifdef BGRAPHBIPARTDFLOOPTHREAD threadBarrier (thrdptr); #endif /* BGRAPHBIPARTDFLOOPTHREAD */ veloval = 1; veexval = 0; for (vertnum = vertbas, fronnum = vertbas - grafptr->s.baseval, commloadextn = commgainextn = commloadintn = compload1 = compsize1 = 0; vertnum < vertnnd; vertnum ++) { Gnum edgenum; Gnum partval; Gnum commload; /* Vertex internal communication load */ partval = (Gnum) parttax[vertnum]; if (velotax != NULL) veloval = velotax[vertnum]; if (veextax != NULL) veexval = veextax[vertnum]; compsize1 += partval; compload1 += partval * veloval; commloadextn += partval * veexval; commgainextn += (1 - 2 * partval) * veexval; commload = 0; if (edlotax != NULL) { for (edgenum = verttax[vertnum]; edgenum < vendtax[vertnum]; edgenum ++) { Gnum partend; partend = (Gnum) parttax[edgetax[edgenum]]; commload += (partval ^ partend) * edlotax[edgenum]; } } else { for (edgenum = verttax[vertnum]; edgenum < vendtax[vertnum]; edgenum ++) commload += partval ^ (Gnum) parttax[edgetax[edgenum]]; } commloadintn += commload; /* Internal loads will be added twice */ if (commload != 0) /* If end vertex is in the other part */ grafptr->frontab[fronnum ++] = vertnum; /* Then it belongs to the frontier */ } thrdptr->fronnnd = fronnum; /* Save state */ thrdptr->compload1 = compload1; thrdptr->compsize1 = compsize1; thrdptr->commloadextn = commloadextn; thrdptr->commloadintn = commloadintn; thrdptr->commgainextn = commgainextn; memFree (ielstax + vertbas); /* Free local part of (local part of) edge load sum array */ return (0); } scotch-6.0.4.dfsg/src/libscotch/mesh_induce_sepa.c0000644002563400244210000004673011631447170025307 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mesh_induce_sepa.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the source **/ /** mesh separator subgraph-making **/ /** functions. **/ /** **/ /** DATES : # Version 4.0 : from : 26 jan 2003 **/ /** to 11 may 2004 **/ /** # Version 5.0 : from : 12 sep 2007 **/ /** to 03 apr 2008 **/ /** **/ /** NOTES : # This routine differs from the **/ /** standard mesh induction routine by **/ /** the fact that neighboring elements do **/ /** not bear the same part number as the **/ /** vertices to keep and are found on the **/ /** fly. **/ /** **/ /** # This routine is used in hmeshInduce- **/ /** Nd to build the induced separator **/ /** mesh. **/ /** Since separator vertices are likely **/ /** to be surrounded by elements that **/ /** belong to different parts but connect **/ /** the same vertices in the separator, **/ /** a simple detection mechanism is used **/ /** to try to reduce the number of such **/ /** redundant elements. **/ /** Also, since this mesh is to be **/ /** ordered with the highest available **/ /** numbers, halo is not really needed **/ /** so this "mesh*" routine is used. If **/ /** halo was needed, a "hmesh*" routine **/ /** should be used instead. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define MESH #define MESH_INDUCE_SEPA #include "module.h" #include "common.h" #include "graph.h" #include "mesh.h" #include "mesh_induce_sepa.h" /***************************************/ /* */ /* This routine handles source meshes. */ /* */ /***************************************/ /* This routine builds the separator mesh ** induced by the original mesh, the list of ** selected separator node vertices, and the ** vertex part array. Elements which are ** adjacent to the selected nodes are themselves ** selected. ** The induced vnumtab array is the baseval-based ** list of remaining node vertices if the original ** mesh does not have a vnumtab, or the proper ** subset of the original vnumtab else. ** This routine builds a mesh with nodes first ** and elements last. If a halo version of this ** algorithm had to be created, it should be ** re-worked such that elements are put first ** and nodes last, to enforce the structure of ** halo meshes. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int meshInduceSepa ( const Mesh * restrict const orgmeshptr, /* Pointer to original mesh */ const GraphPart * restrict const orgparttax, /* Array of vertex partition flags */ const Gnum orgsepanbr, /* Number of node vertices in separator */ const Gnum * restrict const orgsepatab, /* Array of node indices */ Mesh * restrict const indmeshptr) /* Pointer to induced submesh */ { Gnum orgvertnbr; /* Number of vertices in original mesh */ Gnum orgbitssiz; /* Size of int array holding as many bits as element vertices */ unsigned int * restrict orgbitstab; /* Array of bit flags for mesh elements */ Gnum indvnumnum; /* Current vertex number index in separator node list */ Gnum * restrict indvneltax; /* Array of original numbers for induced elements */ Gnum indvelmnbr; /* (Approximate) number of element vertices in induced mesh */ Gnum indvertnbr; /* (Approximate) number of vertices in induced mesh */ Gnum indvnodnum; /* Number of current node vertex in induced mesh */ Gnum indvnlosum; /* Sum of node vertex load array */ Gnum indvelmnum; /* Number of current element vertex in induced mesh */ Gnum * restrict indedgetax; /* Based array to edge array of induced mesh */ Gnum indedgenum; /* Number of current edge to be created in induced mesh */ Gnum indedgenbr; /* (Approximate) number of edges in induced mesh graph */ Gnum * restrict orgindxtax; /* Original to induced vertex number translation */ MeshInduceSepaHash * restrict hashtab; /* Node hash array */ Gnum hashmsk; /* Mask for hash array */ void * restrict p; orgbitssiz = (orgmeshptr->velmnbr + (INTSIZEBITS - 1)) / INTSIZEBITS; /* Compute size of element bit array */ if ((orgbitstab = (unsigned int *) memAlloc (orgbitssiz * sizeof (unsigned int))) == NULL) { errorPrint ("meshInduceSepa: out of memory (1)"); return (1); } memSet (orgbitstab, ~0, orgbitssiz * sizeof (unsigned int)); for (indvnumnum = 0, indvelmnbr = 0, indedgenbr = 0; /* For all separator nodes in list */ indvnumnum < orgsepanbr; indvnumnum ++) { Gnum orgvnodnum; /* Number of current node in original mesh */ Gnum orgenodnum; orgvnodnum = orgsepatab[indvnumnum]; /* Get number of separator node */ for (orgenodnum = orgmeshptr->verttax[orgvnodnum], indedgenbr += (orgmeshptr->vendtax[orgvnodnum] - orgenodnum); orgenodnum < orgmeshptr->vendtax[orgvnodnum]; orgenodnum ++) { Gnum orgvelmidx; /* Index of incident element in bit array */ Gnum orgvelmbit; /* Bit to update in element bit array */ orgvelmidx = orgmeshptr->edgetax[orgenodnum] - orgmeshptr->velmbas; orgvelmbit = orgvelmidx & (INTSIZEBITS - 1); orgvelmidx /= INTSIZEBITS; indvelmnbr += (orgbitstab[orgvelmidx] >> orgvelmbit) & 1; /* Count element vertex if not yet accounted for */ orgbitstab[orgvelmidx] &= ~(1 << orgvelmbit); } } indedgenbr *= 2; /* Number of arcs is twice number of edges */ memFree (orgbitstab); memSet (indmeshptr, 0, sizeof (Mesh)); /* Initialize mesh fields */ indmeshptr->baseval = orgmeshptr->baseval; indmeshptr->flagval = MESHFREETABS | MESHVERTGROUP; indmeshptr->vnodnbr = orgsepanbr; /* Nodes first */ indmeshptr->vnodbas = indmeshptr->baseval; indmeshptr->vnodnnd = indmeshptr->velmbas = orgsepanbr + indmeshptr->baseval; /* Elements last */ indmeshptr->veisnbr = 0; /* No isolated elements */ for (hashmsk = 15; hashmsk < orgmeshptr->degrmax; hashmsk = hashmsk * 2 + 1) ; hashmsk = hashmsk * 4 + 3; /* Compute size of node hash table */ indvertnbr = indvelmnbr + orgsepanbr; /* Upper bound on number of all vertices */ if (orgmeshptr->velotax != NULL) { p = memAllocGroup ((void **) (void *) &indmeshptr->verttax, (size_t) (indvertnbr * sizeof (Gnum)), /* verttab is not compact */ &indmeshptr->vendtax, (size_t) (indvertnbr * sizeof (Gnum)), &indmeshptr->vnumtax, (size_t) (orgsepanbr * sizeof (Gnum)), /* vnumtab is of size indnodenbr */ &indmeshptr->velotax, (size_t) (orgsepanbr * sizeof (Gnum)), NULL); /* Element vertices assumed not weighted */ indmeshptr->velotax -= indmeshptr->vnodbas; } else p = memAllocGroup ((void **) (void *) &indmeshptr->verttax, (size_t) (indvertnbr * sizeof (Gnum)), &indmeshptr->vendtax, (size_t) (indvertnbr * sizeof (Gnum)), &indmeshptr->vnumtax, (size_t) (orgsepanbr * sizeof (Gnum)), NULL); /* vnumtab is of size indnodenbr */ orgvertnbr = orgmeshptr->velmnbr + orgmeshptr->vnodnbr; if (p != 0) { indmeshptr->verttax -= indmeshptr->baseval; indmeshptr->vendtax -= indmeshptr->baseval; indmeshptr->vnumtax -= indmeshptr->vnodbas; /* vnumtab is of size indmeshptr->vnodnbr */ p = memAllocGroup ((void **) (void *) &indedgetax, (size_t) (indedgenbr * sizeof (Gnum)), &indvneltax, (size_t) (indvelmnbr * sizeof (Gnum)), &orgindxtax, (size_t) (orgvertnbr * sizeof (Gnum)), &hashtab, (size_t) ((hashmsk + 1) * sizeof (MeshInduceSepaHash)), NULL); } if (p == 0) { errorPrint ("meshInduceSepa: out of memory (2)"); /* Allocate induced mesh graph structure */ return (1); } memSet (orgindxtax, ~0, orgvertnbr * sizeof (Gnum)); memSet (hashtab, ~0, (hashmsk + 1) * sizeof (MeshInduceSepaHash)); indedgetax -= indmeshptr->baseval; indvneltax -= indmeshptr->velmbas; orgindxtax -= orgmeshptr->baseval; for (indvnumnum = 0, indvnodnum = indedgenum = indmeshptr->baseval, indvelmnum = orgsepanbr + indvnodnum, indedgenbr = 0, indvnlosum = 0; indvnumnum < orgsepanbr; indvnumnum ++) { /* For all node vertices in separator */ Gnum orgvnodnum; /* Number of current node in original mesh */ Gnum orgenodnum; Gnum indenodnum; /* Current index in node edge sub-array */ orgvnodnum = orgsepatab[indvnumnum]; /* Get number of separator node */ if (orgindxtax[orgvnodnum] == ~0) /* If separator node not yet numbered */ orgindxtax[orgvnodnum] = indvnodnum ++; /* One more node vertex created */ indmeshptr->verttax[orgindxtax[orgvnodnum]] = indedgenum; /* Set beginning of edge sub-array */ indmeshptr->vnumtax[orgindxtax[orgvnodnum]] = orgvnodnum - (orgmeshptr->vnodbas - orgmeshptr->baseval); if (indmeshptr->velotax != NULL) { Gnum indvnloval; indvnloval = orgmeshptr->velotax[orgvnodnum]; indvnlosum += indvnloval; indmeshptr->velotax[orgindxtax[orgvnodnum]] = indvnloval; } indenodnum = indedgenum; /* Record position of node edge sub-array */ indedgenum += orgmeshptr->vendtax[orgvnodnum] - /* Reserve space for node edges */ orgmeshptr->verttax[orgvnodnum]; for (orgenodnum = orgmeshptr->verttax[orgvnodnum]; /* For all element vertices neighboring the separator node */ orgenodnum < orgmeshptr->vendtax[orgvnodnum]; orgenodnum ++) { Gnum orgvelmnum; /* Number of element node in original mesh */ orgvelmnum = orgmeshptr->edgetax[orgenodnum]; /* Get number of element */ if (orgindxtax[orgvelmnum] == -2) /* If discarded element */ continue; /* Skip to next element */ if (orgindxtax[orgvelmnum] == ~0) { /* If element not yet created */ Gnum indedgetmp; /* Save value for edge index */ Gnum orgeelmnum; Gnum indenodtmp; indmeshptr->verttax[indvelmnum] = indedgenum; /* Set beginning of element edge sub-array */ indedgetmp = indedgenum; for (orgeelmnum = orgmeshptr->verttax[orgvelmnum]; /* For all nodes neighboring the element vertex */ orgeelmnum < orgmeshptr->vendtax[orgvelmnum]; orgeelmnum ++) { Gnum orgvnodend; /* Number of current end node vertex in original mesh */ orgvnodend = orgmeshptr->edgetax[orgeelmnum]; /* Get number of end node */ if (orgparttax[orgvnodend] == 2) { /* If end node is in separator */ Gnum hashnum; if (orgindxtax[orgvnodend] == ~0) /* If end node not yet numbered */ orgindxtax[orgvnodend] = indvnodnum ++; /* Assign number to end node */ indedgetax[indedgenum ++] = orgindxtax[orgvnodend]; /* Add node to element edge sub-array */ for (hashnum = (orgindxtax[orgvnodend] * MESHINDUCESEPAHASHPRIME) & hashmsk; hashtab[hashnum].orgvelmnum == orgvelmnum; hashnum = (hashnum + 1) & hashmsk) ; hashtab[hashnum].orgvelmnum = orgvelmnum; /* Add vertex to hash table */ hashtab[hashnum].indvnodnum = orgindxtax[orgvnodend]; } } indmeshptr->vendtax[indvelmnum] = indedgenum; /* Set end of element edge sub-array */ for (indenodtmp = indenodnum - 1; indenodtmp >= indmeshptr->verttax[orgindxtax[orgvnodnum]]; indenodtmp --) { Gnum indvelmtmp; /* Number of current already declared element for current node */ Gnum indeelmtmp; /* Number of current edge of already declared element for current node */ Gnum mtchnbr; /* Number of matches between new element and current element */ indvelmtmp = indedgetax[indenodtmp]; for (indeelmtmp = indmeshptr->verttax[indvelmtmp], mtchnbr = 0; indeelmtmp < indmeshptr->vendtax[indvelmtmp]; indeelmtmp ++) { Gnum indvnodend; Gnum hashnum; indvnodend = indedgetax[indeelmtmp]; /* Get number of current end node of already declared element */ for (hashnum = (indvnodend * MESHINDUCESEPAHASHPRIME) & hashmsk; ; hashnum = (hashnum + 1) & hashmsk) { if (hashtab[hashnum].orgvelmnum != orgvelmnum) /* If end node not present */ break; if (hashtab[hashnum].indvnodnum == indvnodend) { /* If end node found */ mtchnbr ++; /* One more matching node */ break; } } } if (mtchnbr == (indedgenum - indmeshptr->verttax[indvelmnum])) { /* If we are useless */ orgindxtax[orgvelmnum] = -2; /* Never consider this element again */ indedgenum = indedgetmp; /* Recycle edge sub-array of new element */ break; /* No need to go any further */ } if (mtchnbr == (indmeshptr->vendtax[indvelmtmp] - indmeshptr->verttax[indvelmtmp])) { /* If other element is useless */ indedgenbr -= mtchnbr; /* Remove its edges */ indmeshptr->verttax[indvelmtmp] = indmeshptr->verttax[indvelmnum]; /* Recycle it into our element */ indmeshptr->vendtax[indvelmtmp] = indmeshptr->vendtax[indvelmnum]; orgindxtax[indvneltax[indvelmtmp]] = -2; indvneltax[indvelmtmp] = orgvelmnum; } } if (indenodtmp < indmeshptr->verttax[orgindxtax[orgvnodnum]]) { /* If new element distinct from all other neighboring elements */ indedgetax[indenodnum ++] = indvelmnum; /* Record element in edge sub-array of current node */ indedgenbr += indedgenum - indmeshptr->verttax[indvelmnum]; indvneltax[indvelmnum] = orgvelmnum; /* Record original number of element in case we have to remove it afterwards */ orgindxtax[orgvelmnum] = indvelmnum ++; } } else /* Element already exists */ indedgetax[indenodnum ++] = orgindxtax[orgvelmnum]; /* Record element in edge sub-array of current node */ } indmeshptr->vendtax[orgindxtax[orgvnodnum]] = indenodnum; /* Set end of edge sub-array for current node */ indedgenbr += (indenodnum - indmeshptr->verttax[orgindxtax[orgvnodnum]]); /* Account for thes edges */ } #ifdef SCOTCH_DEBUG_MESH2 if (indvnodnum != (orgsepanbr + indmeshptr->baseval)) { errorPrint ("meshInduceSepa: internal error"); return (1); } #endif /* SCOTCH_DEBUG_MESH2 */ indmeshptr->velmnbr = indvelmnum - indmeshptr->velmbas; indmeshptr->velmnnd = indvelmnum; indmeshptr->edgenbr = indedgenbr; if ((indmeshptr->edgetax = (Gnum *) memRealloc (indedgetax + indmeshptr->baseval, (indedgenum - indmeshptr->baseval) * sizeof (Gnum))) == NULL) { errorPrint ("meshInduceSepa: out of memory (3)"); memFree (indedgetax + indmeshptr->baseval); /* Free group leader */ meshFree (indmeshptr); return (1); } indmeshptr->edgetax -= indmeshptr->baseval; indmeshptr->velosum = indmeshptr->velmnbr; /* TODO: account for element weights */ indmeshptr->vnlosum = (indmeshptr->velotax == NULL) ? orgsepanbr : indvnlosum; indmeshptr->degrmax = orgmeshptr->degrmax; /* Rough estimate */ if (orgmeshptr->vnumtax != NULL) { /* If mesh is a submesh */ for (indvnodnum = indmeshptr->vnodbas; indvnodnum < indmeshptr->vnodnnd; indvnodnum ++) indmeshptr->vnumtax[indvnodnum] = orgmeshptr->vnumtax[indmeshptr->vnumtax[indvnodnum] + (orgmeshptr->vnodbas - orgmeshptr->baseval)]; } return (0); } scotch-6.0.4.dfsg/src/libscotch/hgraph_order_kp.c0000644002563400244210000001601312376064570025147 0ustar trophimeutilisateurs du domaine/* Copyright 2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hgraph_order_kp.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module computes a block ordering **/ /** from a k-way edge partition. **/ /** **/ /** DATES : # Version 5.0 : from : 17 oct 2012 **/ /** to : 17 oct 2012 **/ /** # Version 6.0 : from : 23 aug 2014 **/ /** to : 23 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HGRAPH_ORDER_KP #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "arch.h" #include "mapping.h" #include "order.h" #include "hgraph.h" #include "hgraph_order_kp.h" #include "hgraph_order_si.h" #include "kgraph.h" #include "kgraph_map_st.h" #include "scotch.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the ordering. ** It returns: ** - 0 : if the ordering could be computed. ** - !0 : on error. */ int hgraphOrderKp ( const Hgraph * restrict const grafptr, Order * restrict const ordeptr, const Gnum ordenum, /*+ Zero-based ordering number +*/ OrderCblk * restrict const cblkptr, /*+ Single column-block +*/ const HgraphOrderKpParam * restrict const paraptr) { Kgraph actgrafdat; Gnum * restrict ordetab; Gnum ordeadj; Anum * restrict parttax; Gnum partnbr; Gnum partnum; Gnum * restrict peritab; Gnum vertnnd; Gnum vertnum; Gnum cblknbr; if ((paraptr->partsiz < 1) || /* If nothing to do, order consecutively */ ((partnbr = grafptr->vnohnbr / paraptr->partsiz) <= 1)) return (hgraphOrderSi (grafptr, ordeptr, ordenum, cblkptr)); if ((cblkptr->cblktab = (OrderCblk *) memAlloc (partnbr * sizeof (OrderCblk))) == NULL) { /* Allocate first as it will remain */ errorPrint ("hgraphOrderKp: out of memory (1)"); return (1); } hgraphUnhalo (grafptr, &actgrafdat.s); /* Extract non-halo part of given graph */ actgrafdat.s.vnumtax = NULL; /* Do not keep numbers from nested dissection */ SCOTCH_archCmplt ((SCOTCH_Arch *) &actgrafdat.a, (SCOTCH_Num) partnbr); /* Build complete graph architecture */ if ((kgraphInit (&actgrafdat, &actgrafdat.s, &actgrafdat.a, NULL, 0, NULL, NULL, 1, 1, NULL) != 0) || (kgraphMapSt (&actgrafdat, paraptr->strat) != 0)) { errorPrint ("hgraphOrderKp: cannot compute partition"); memFree (cblkptr->cblktab); cblkptr->cblktab = NULL; return (1); } if (memAllocGroup ((void **) (void *) &ordetab, (size_t) (partnbr * sizeof (Gnum)), &parttax, (size_t) (grafptr->vnohnbr * sizeof (Anum)), NULL) == NULL) { errorPrint ("hgraphOrderKp: out of memory (2)"); memFree (cblkptr->cblktab); cblkptr->cblktab = NULL; return (1); } parttax -= actgrafdat.s.baseval; mapTerm (&actgrafdat.m, parttax); /* Get result of partitioning as terminal part array */ memSet (ordetab, 0, partnbr * sizeof (Gnum)); /* Reset part count array */ for (vertnum = actgrafdat.s.baseval, vertnnd = actgrafdat.s.vertnnd; vertnum < vertnnd; vertnum ++) { ordetab[parttax[vertnum]] ++; /* Count number of vertices in each part */ } for (partnum = 0, cblknbr = 0, ordeadj = ordenum; /* For all potential column blocks */ partnum < partnbr; partnum ++) { Gnum ordetmp; ordetmp = ordetab[partnum]; ordetab[partnum] = ordeadj; ordeadj += ordetmp; if (ordetmp != 0) { /* If part is not empty, one more column block */ cblkptr->cblktab[cblknbr].typeval = ORDERCBLKOTHR; cblkptr->cblktab[cblknbr].vnodnbr = ordetmp; cblkptr->cblktab[cblknbr].cblknbr = 0; cblkptr->cblktab[cblknbr].cblktab = NULL; cblknbr ++; } } ordeptr->treenbr += cblknbr; /* These more number of tree nodes */ ordeptr->cblknbr += cblknbr - 1; /* These more number of column blocks */ cblkptr->cblknbr = cblknbr; peritab = ordeptr->peritab; if (grafptr->s.vnumtax == NULL) { /* If graph is original graph */ for (vertnum = actgrafdat.s.baseval; vertnum < vertnnd; vertnum ++) peritab[ordetab[parttax[vertnum]] ++] = vertnum; } else { /* Graph is not original graph */ const Gnum * restrict vnumtax; vnumtax = grafptr->s.vnumtax; for (vertnum = actgrafdat.s.baseval; vertnum < vertnnd; vertnum ++) peritab[ordetab[parttax[vertnum]] ++] = vnumtax[vertnum]; } memFree (ordetab); /* Free group leader */ kgraphExit (&actgrafdat); return (0); } scotch-6.0.4.dfsg/src/libscotch/bgraph_bipart_gp.h0000644002563400244210000001055111631447171025304 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bgraph_bipart_gp.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the Gibbs, Poole, and Stockmeyer **/ /** bipartitioning algorithm. **/ /** **/ /** DATES : # Version 2.0 : from : 06 jun 1994 **/ /** to 28 oct 1994 **/ /** # Version 3.2 : from : 21 sep 1996 **/ /** to 13 sep 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 4.0 : from : 01 nov 2003 **/ /** to 20 aug 2004 **/ /** # Version 5.1 : from : 04 nov 2010 **/ /** to 04 nov 2010 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ Method parameters. +*/ typedef struct BgraphBipartGpParam_ { INT passnbr; /*+ Number of passes to do +*/ } BgraphBipartGpParam; /*+ Complementary vertex structure. +*/ typedef struct BgraphBipartGpVertex_ { Gnum passnum; /*+ Number of pass when vertex selected +*/ Gnum distval; /*+ Current distance from diameter vertex +*/ } BgraphBipartGpVertex; /*+ Neighbor queue. +*/ typedef struct BgraphBipartGpQueue_ { Gnum headnum; /*+ Head of distance queue +*/ Gnum tailnum; /*+ Tail of distance queue +*/ Gnum * queutab; /*+ Array of queue elements +*/ } BgraphBipartGpQueue; /* ** The function prototypes. */ #ifndef BGRAPH_BIPART_GP #define static #endif int bgraphBipartGp (Bgraph * restrict const, const BgraphBipartGpParam * const); #undef static /* ** The macro definitions. */ #define bgraphBipartGpQueueFlush(queue) ((queue)->headnum = (queue)->tailnum = 0) #define bgraphBipartGpQueueEmpty(queue) ((queue)->headnum <= (queue)->tailnum) #define bgraphBipartGpQueuePut(queue,vnum) ((queue)->queutab[(queue)->headnum ++] = (vnum)) #define bgraphBipartGpQueueGet(queue) ((queue)->queutab[(queue)->tailnum ++]) scotch-6.0.4.dfsg/src/libscotch/graph_io_habo.c0000644002563400244210000004430511631447171024572 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : graph_io_habo.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the I/O routines **/ /** for handling the Harwell-Boeing matrix **/ /** format. **/ /** **/ /** DATES : # Version 3.2 : from : 06 nov 1997 **/ /** to 26 may 1998 **/ /** # Version 3.3 : from : 13 dec 1998 **/ /** to 24 dec 1998 **/ /** # Version 4.0 : from : 18 dec 2001 **/ /** to 21 mar 2005 **/ /** # Version 5.0 : from : 06 jun 2007 **/ /** to 31 aug 2007 **/ /** # Version 5.1 : from : 09 nov 2008 **/ /** to 27 apr 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GRAPH_IO_HABO #include "module.h" #include "common.h" #include "geom.h" #include "graph.h" #include "graph_io_habo.h" /* This routine loads the geometrical graph ** in the Harwell-Boeing matrix format, and ** allocates the proper structures. ** - 0 : on success. ** - !0 : on error. */ int graphGeomLoadHabo ( Graph * restrict const grafptr, /* Graph to load */ Geom * restrict const geomptr, /* Geometry to load */ FILE * const filesrcptr, /* Topological data */ FILE * const filegeoptr, /* No use */ const char * const dataptr) /* Tag value */ { Gnum habmattag; /* Matrix tag number in file */ Gnum habmatnum; /* Current matrix number */ char habmatbuf[4][84]; /* Matrix header line buffers */ char habmattype[3]; /* Matrix type */ Gnum habcrdnbr; /* Total number of data lines */ Gnum habrhsnbr; /* Number of right hand side lines */ Gnum habrownbr; /* Number of rows */ GraphGeomHaboLine habcolfmt; /* Format of column line */ int habvalnum; /* Number of value in line */ Gnum habcolnbr; /* Number of columns */ Gnum habcolnum; /* Number of current column index */ Gnum * restrict habcoltab; /* Index array */ GraphGeomHaboLine habnzrfmt; /* Format of non-zero type */ Gnum habnzrnbr; /* Number of non-zero indices */ Gnum habnzrnum; /* Number of current row data */ Gnum * restrict habnzrtab; /* Row data array */ GraphGeomHaboHash * restrict hashtab; /* Neighbor hash table */ Gnum hashmsk; /* Mask for access to hash table */ Gnum vertnum; /* Number of current vertex */ Gnum edgenum; /* Number of current edge (arc) */ Gnum edgeold; /* Number of non-purged edge */ Gnum edgetmp; /* Temporary edge number */ Gnum degrmax; /* Maximum degree */ int c; if ((dataptr != NULL) && /* If tag value provided */ (dataptr[0] != '\0') && ((habmattag = (Gnum) atol (dataptr)) == 0) && /* Get tag value */ (dataptr[0] != '0')) { errorPrint ("graphGeomLoadHabo: invalid parameter"); return (1); } habmattype[0] = habmattype[1] = habmattype[2] = '\0'; for (habmatnum = 0; habmatnum <= habmattag; habmatnum ++) { /* Read headers and skip if necessary */ memSet (habmatbuf[0], ' ', &habmatbuf[3][83] - &habmatbuf[0][0]); /* Initialize header buffers */ if ((fgets (habmatbuf[0], 83, filesrcptr) == NULL) || /* Read graph header */ (fgets (habmatbuf[1], 83, filesrcptr) == NULL) || (fgets (habmatbuf[2], 83, filesrcptr) == NULL) || (fgets (habmatbuf[3], 83, filesrcptr) == NULL)) { errorPrint ("graphGeomLoadHabo: bad input (1)"); return (1); } habmatbuf[1][70] = '\0'; /* Extract header values */ habrhsnbr = (Gnum) atol (&habmatbuf[1][56]); habmatbuf[1][14] = '\0'; habcrdnbr = (Gnum) atol (&habmatbuf[1][00]); habmattype[0] = toupper (habmatbuf[2][0]); habmattype[1] = toupper (habmatbuf[2][1]); habmattype[2] = toupper (habmatbuf[2][2]); habmatbuf[2][56] = '\0'; habnzrnbr = (Gnum) atol (&habmatbuf[2][43]); habmatbuf[2][42] = '\0'; habcolnbr = (Gnum) atol (&habmatbuf[2][29]); habmatbuf[2][28] = '\0'; habrownbr = (Gnum) atol (&habmatbuf[2][14]); habmatbuf[3][32] = '\0'; if (graphGeomLoadHaboFormat (&habnzrfmt, &habmatbuf[3][16]) != 0) { errorPrint ("graphGeomLoadHabo: bad input (2)"); return (1); } habmatbuf[3][16] = '\0'; if (graphGeomLoadHaboFormat (&habcolfmt, &habmatbuf[3][0]) != 0) { errorPrint ("graphGeomLoadHabo: bad input (3)"); return (1); } if (habrhsnbr != 0) { while ((c = getc (filesrcptr)) != '\n'){ /* Skip RHS format line */ if (c == EOF) { errorPrint ("graphGeomLoadHabo: bad input (4)"); return (1); } } } if (habmatnum < habmattag) { /* If we have to skip file */ while (habcrdnbr -- > 0) { /* Skip all of file lines */ while ((c = getc (filesrcptr)) != '\n') { /* Skip line */ if (c == EOF) { errorPrint ("graphGeomLoadHabo: bad input (5)"); return (1); } } } } } if (habmattype[2] != 'A') { errorPrint ("graphGeomLoadHabo: only assembled matrices supported; for unassembled matrices, use the mesh version of the tools"); return (1); } if (habmattype[1] == 'R') { errorPrint ("graphGeomLoadHabo: rectangular matrices not supported"); return (1); } if (((grafptr->verttax = (Gnum *) memAlloc ((habcolnbr + 1) * sizeof (Gnum))) == NULL) || ((grafptr->edgetax = (Gnum *) memAllocGroup ((void **) (void *) &grafptr->edgetax, (size_t) (habnzrnbr * 2 * sizeof (Gnum)), &habcoltab, (size_t) ((habcolnbr + 1) * sizeof (Gnum)), &habnzrtab, (size_t) (habnzrnbr * sizeof (Gnum)), NULL)) == NULL)) { errorPrint ("graphGeomLoadHabo: out of memory (1)"); if (grafptr->verttax != NULL) { memFree (grafptr->verttax); grafptr->verttax = NULL; } return (1); } grafptr->flagval = GRAPHFREETABS; /* Totally new graph structure */ grafptr->baseval = 1; /* Harwell-Boeing graphs have base 1 */ grafptr->vertnbr = (Gnum) habcolnbr; grafptr->vertnnd = grafptr->vertnbr + 1; grafptr->velosum = grafptr->vertnbr; grafptr->vendtax = grafptr->verttax; /* Use compact representation for array based at 1 */ grafptr->verttax --; /* Base verttab array at 1, with vendtab = verttab + 1 */ grafptr->edgetax --; ungetc ('\n', filesrcptr); /* Create fake previous line */ for (habcolnum = 0, habvalnum = habcolfmt.datanbr; /* Eat up fake previous line */ habcolnum <= habcolnbr; habcolnum ++) { /* Read column indices */ Gnum habcolval; /* Current column value */ int habcolidx; /* Current index in column value */ c = getc (filesrcptr); if (habvalnum ++ >= habcolfmt.datanbr) { /* If all useful data read from line */ habvalnum = 1; /* Start at beginning of new line */ while ((c != '\n') && (c != '\r')) /* Eat up all remaining spaces */ c = getc (filesrcptr); while (((c = getc (filesrcptr)) == '\n') || (c == '\r')) ; /* Read till end of line */ for (habcolidx = 0; habcolidx < habcolfmt.strtnbr; habcolidx ++) /* Get start of line */ c = getc (filesrcptr); } habcolval = (c == ' ') ? 0 : (c - '0'); for (habcolidx = 1; habcolidx < habcolfmt.datalen; habcolidx ++) { if ((c = getc (filesrcptr)) != ' ') habcolval = habcolval * 10 + c - '0'; } if (c == EOF) { errorPrint ("graphGeomLoadHabo: bad input (6)"); graphFree (grafptr); return (1); } habcoltab[habcolnum] = habcolval; } if (habcoltab[habcolnbr] != (Gnum) habnzrnbr + 1) { errorPrint ("graphGeomLoadHabo: bad input (7)"); graphFree (grafptr); return (1); } memSet (grafptr->vendtax, 0, habcolnbr * sizeof (Gnum)); /* Here, vendtax = verttab */ for (vertnum = 1, habnzrnum = 0, habvalnum = habnzrfmt.datanbr; /* Start by eating end of previous line */ vertnum < grafptr->vertnnd; vertnum ++) { /* Read matrix pattern */ for ( ; habnzrnum < (habcoltab[vertnum] - 1); habnzrnum ++) { /* All right since vertnum is based at 1 */ Gnum habnzrval; /* Current non-zero value */ int habnzridx; /* Current index in non-zero value */ c = getc (filesrcptr); if (habvalnum ++ >= habnzrfmt.datanbr) { /* If all useful data read from line */ habvalnum = 1; /* Start at beginning of new line */ while ((c != '\n') && (c != '\r')) /* Eat up all remaining spaces */ c = getc (filesrcptr); while (((c = getc (filesrcptr)) == '\n') || (c == '\r')) ; /* Read till end of line */ for (habnzridx = 0; habnzridx < habnzrfmt.strtnbr; habnzridx ++) /* Get start of line */ c = getc (filesrcptr); } habnzrval = (c == ' ') ? 0 : (c - '0'); for (habnzridx = 1; habnzridx < habnzrfmt.datalen; habnzridx ++) { if ((c = getc (filesrcptr)) != ' ') habnzrval = habnzrval * 10 + c - '0'; } if (c == EOF) { errorPrint ("graphGeomLoadHabo: bad input (8)"); graphFree (grafptr); return (1); } habnzrtab[habnzrnum] = habnzrval; if (habnzrval != vertnum) { /* If not loop edge */ grafptr->verttax[vertnum] ++; /* Account for arc */ grafptr->verttax[habnzrval] ++; /* Add arc to symmetrize */ } } } degrmax = 1; for (vertnum = edgenum = 1; vertnum < grafptr->vertnnd; vertnum ++) { /* Build (superset of) vertex array */ Gnum edgetmp; edgetmp = grafptr->verttax[vertnum]; grafptr->verttax[vertnum] = edgenum; edgenum += edgetmp; if (edgetmp > degrmax) /* Update bound on maximum degree */ degrmax = edgetmp; } grafptr->verttax[vertnum] = edgenum; /* Set end of vertex array */ for (vertnum = 1, habnzrnum = 0; vertnum < grafptr->vertnnd; vertnum ++) { /* Build (superset of) edge array */ for ( ; habnzrnum < (habcoltab[vertnum] - 1); habnzrnum ++) { Gnum vertend; /* Number of end vertex */ vertend = habnzrtab[habnzrnum]; if (vertend != vertnum) { /* If not loop edge */ grafptr->edgetax[grafptr->verttax[vertnum] ++] = vertend; /* Build arc */ grafptr->edgetax[grafptr->verttax[vertend] ++] = vertnum; /* Symmetrize */ } } } for (hashmsk = 31; hashmsk < degrmax; hashmsk = hashmsk * 2 + 1) ; /* Set neighbor hash table size */ hashmsk = hashmsk * 4 + 3; if ((hashtab = (GraphGeomHaboHash *) memAlloc ((hashmsk + 1) * sizeof (GraphGeomHaboHash))) == NULL) { errorPrint ("graphGeomLoadHabo: out of memory (2)"); graphFree (grafptr); return (1); } memSet (hashtab, ~0, (hashmsk + 1) * sizeof (GraphGeomHaboHash)); /* Pre-set hash table */ degrmax = 1; for (vertnum = edgetmp = edgenum = 1; vertnum < grafptr->vertnnd; vertnum ++) { /* Remove duplicates from edge array */ for (edgeold = edgetmp, edgetmp = grafptr->verttax[vertnum], grafptr->verttax[vertnum] = edgenum; edgeold < edgetmp; edgeold ++) { Gnum vertend; /* Number of end vertex */ Gnum hashnum; /* Current hash index */ vertend = grafptr->edgetax[edgeold]; for (hashnum = (vertend * GRAPHGEOMHABOHASHPRIME) & hashmsk; ; hashnum = (hashnum + 1) & hashmsk) { if (hashtab[hashnum].vertnum != vertnum) { /* If edge not found */ hashtab[hashnum].vertnum = vertnum; hashtab[hashnum].vertend = vertend; grafptr->edgetax[edgenum ++] = vertend; break; } if (hashtab[hashnum].vertend == vertend) /* Do not add duplicate edges */ break; } } if ((edgenum - grafptr->verttax[vertnum]) > degrmax) /* Set real maximum degree */ degrmax = edgenum - grafptr->verttax[vertnum]; } grafptr->verttax[vertnum] = edgenum; /* Set end of vertex array */ grafptr->edgenbr = edgenum - 1; grafptr->edlosum = grafptr->edgenbr; grafptr->degrmax = degrmax; memFree (hashtab); grafptr->edgetax = ((Gnum *) memRealloc (grafptr->edgetax + 1, grafptr->edgenbr * sizeof (Gnum))) - 1; #ifdef SCOTCH_DEBUG_GRAPH2 if (graphCheck (grafptr) != 0) { /* Check graph consistency */ errorPrint ("graphGeomLoadHabo: internal error"); graphFree (grafptr); return (1); } #endif /* SCOTCH_DEBUG_GRAPH2 */ return (0); } /* This routine reads a Fortran format structure ** and returns the size of the integers to read. */ static int graphGeomLoadHaboFormat ( GraphGeomHaboLine * restrict const lineptr, /* Line format to fill */ const char * const dataptr) /* Format string */ { const char * restrict charptr; int number; /* Number to read */ lineptr->strtnbr = lineptr->datanbr = lineptr->datalen = 0; for (charptr = dataptr; ; charptr ++) { /* Skip to first '(' */ if (*charptr == '(') break; if (*charptr == '\0') /* Error if end of string */ return (1); } number = 0; /* Read number */ for (charptr ++ ; ; charptr ++) { if (*charptr == '\0') /* Error if end of string */ return (1); if (! isdigit ((int) (unsigned char) *charptr)) break; number = number * 10 + *charptr - '0'; } if ((*charptr == 'x') || (*charptr == 'X')) { /* If dummy characters at beginning of line */ lineptr->strtnbr = number; for (charptr ++; ; charptr ++) { /* Skip to first ',' */ if (*charptr == '\0') /* Error if end of string */ return (1); if (*charptr == ',') break; } number = 0; /* Read number */ for (charptr ++; *charptr != '\0'; charptr ++) { if (*charptr == '\0') /* Error if end of string */ return (1); if (! isdigit (*charptr < '0')) break; number = number * 10 + *charptr - '0'; } } if ((*charptr != 'I') && (*charptr != 'i')) /* If not integer specification */ return (1); lineptr->datanbr = number; number = 0; /* Read size of integer */ for (charptr ++; ; charptr ++) { if (*charptr == '\0') /* Error if end of string */ return (1); if (! isdigit ((int) (unsigned char) *charptr)) break; number = number * 10 + *charptr - '0'; } if (number == 0) return (1); lineptr->datalen = number; return (0); } scotch-6.0.4.dfsg/src/libscotch/kgraph_map_rb_map.h0000644002563400244210000002017512377661064025455 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph_map_rb_map.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the Dual Recursive Bipartitioning **/ /** mapping algorithm. **/ /** **/ /** DATES : # Version 0.0 : from : 23 mar 1993 **/ /** to 12 may 1993 **/ /** # Version 1.3 : from : 06 apr 1994 **/ /** to 09 apr 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to 04 nov 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to 30 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 28 sep 1995 **/ /** # Version 3.1 : from : 15 nov 1995 **/ /** to 15 nov 1995 **/ /** # Version 3.2 : from : 01 oct 1996 **/ /** to 10 jun 1998 **/ /** # Version 3.3 : from : 19 oct 1998 **/ /** to 17 may 1999 **/ /** # Version 3.4 : from : 12 sep 2001 **/ /** to 06 nov 2001 **/ /** # Version 4.0 : from : 29 nov 2003 **/ /** to 05 may 2006 **/ /** # Version 5.1 : from : 30 sep 2008 **/ /** to 04 nov 2010 **/ /** # Version 6.0 : from : 03 mar 2011 **/ /** to 28 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ Dual recursive bipartitioning option flags. +*/ #define KGRAPHMAPRBMAPARCHVAR 0x0001 /* Variable-sized architecture */ #define KGRAPHMAPRBMAPARCHCMPLT 0x0002 /* Complete-graph architecture */ #define KGRAPHMAPRBMAPPARTHALF 0x0004 /* Only update half of part array as mappings are tied */ /* ** The type and structure definitions. */ /*+ Job pool structures. +*/ typedef struct KgraphMapRbMapPoolLink_ { struct KgraphMapRbMapPoolLink_ * prev; /*+ Pointer to previous link +*/ struct KgraphMapRbMapPoolLink_ * next; /*+ Pointer to next link +*/ } KgraphMapRbMapPoolLink; /*+ This structure defines a job to be performed with respect to a partial mapping of a source graph. +*/ typedef struct KgraphMapRbMapJob_ { KgraphMapRbMapPoolLink poollink; /*+ Link to job pool; TRICK: FIRST +*/ KgraphMapRbMapPoolLink * poolptr; /*+ Pointer to last/current job pool +*/ int poolflag; /*+ Flag set if job in pool +*/ Gnum prioval; /*+ Job priority value by policy +*/ Gnum priolvl; /*+ Priority level computed for this job +*/ ArchDom domnorg; /*+ Domain to which the vertices belong +*/ Graph grafdat; /*+ Job graph data (may be clone of another) +*/ Anum vflonbr; /*+ Number of fixed vertex load slots +*/ KgraphMapRbVflo * vflotab; /*+ Partial array of fixed vertex load slots +*/ } KgraphMapRbMapJob; /*+ This structure defines the working data, for easier parameter passing. +*/ typedef struct KgraphMapRbMapPoolData_ { int flagval; /*+ Pool flag value +*/ KgraphMapRbPolicy polival; /*+ Job selection policy +*/ const Graph * grafptr; /*+ Pointer to top graph +*/ const Anum * pfixtax; /*+ Pointer to fixed part array +*/ KgraphMapRbMapPoolLink linktab[2]; /*+ Lists of jobs in pools +*/ KgraphMapRbMapPoolLink * pooltab[2]; /*+ Pointer to pools (same if tied) +*/ ArchDom * domntab[2]; /*+ Pointer to domain arrays (same if tied) +*/ KgraphMapRbMapJob * jobtab; /*+ Job table +*/ Mapping * mappptr; /*+ Pointer to original mapping: current state +*/ } KgraphMapRbMapPoolData; /* ** The function prototypes. */ #ifndef KGRAPH_MAP_RB_MAP #define static #endif static int kgraphMapRbMapPoolInit (KgraphMapRbMapPoolData * restrict const, const KgraphMapRbData * restrict const); static void kgraphMapRbMapPoolExit (KgraphMapRbMapPoolData * restrict const poolptr); static void kgraphMapRbMapPoolAdd (KgraphMapRbMapPoolLink * restrict const, KgraphMapRbMapJob * const); static KgraphMapRbMapJob * kgraphMapRbMapPoolGet (KgraphMapRbMapPoolData * restrict const); static void kgraphMapRbMapPoolFrst (KgraphMapRbMapPoolData * const, KgraphMapRbMapJob * const); static void kgraphMapRbMapPoolUpdt1 (KgraphMapRbMapPoolData * const, const KgraphMapRbMapJob * const, const GraphPart * const, KgraphMapRbMapJob * const, const GraphPart); static void kgraphMapRbMapPoolUpdt2 (KgraphMapRbMapPoolData * const, const KgraphMapRbMapJob * const, const GraphPart * const, KgraphMapRbMapJob * const, KgraphMapRbMapJob * const); int kgraphMapRbMap (const KgraphMapRbData * restrict const, const Graph * restrict const, const Anum, KgraphMapRbVflo * restrict const); static int kgraphMapRbMapPoolResize (KgraphMapRbMapPoolData * restrict const); #undef static /* ** The macro definitions. */ #define kgraphMapRbMapPoolEmpty(poolptr) ((poolptr)->pooltab[0]->next == &kgraphmaprbmappooldummy) scotch-6.0.4.dfsg/src/libscotch/vmesh_separate_gg.c0000644002563400244210000005551711631447170025502 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vmesh_separate_gg.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module separates a node separation **/ /** mesh using an element-oriented version **/ /** of the Greedy Graph Growing algorithm. **/ /** **/ /** DATES : # Version 4.0 : from : 16 sep 2002 **/ /** to 18 aug 2004 **/ /** # Version 5.0 : from : 12 sep 2007 **/ /** to 24 mar 2008 **/ /** # Version 5.1 : from : 09 nov 2008 **/ /** to 09 nov 2008 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VMESH_SEPARATE_GG #include "module.h" #include "common.h" #include "gain.h" #include "graph.h" #include "mesh.h" #include "vmesh.h" #include "vmesh_separate_gg.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the bipartitioning. ** It returns: ** - 0 : if the bipartitioning could be computed. ** - !0 : on error. */ int vmeshSeparateGg ( Vmesh * restrict const meshptr, /*+ Node separation mesh +*/ const VmeshSeparateGgParam * restrict const paraptr) /*+ Method parameters +*/ { GainTabl * restrict tablptr; /* Pointer to gain table */ byte * restrict vexxtab; /* Start of auxiliary arrays */ Gnum vexxsiz; /* Size of auxiliary arrays to be reset every pass */ VmeshSeparateGgElem * restrict velxtax; /* Based auxiliary element array */ VmeshSeparateGgNode * restrict vnoxtax; /* Based auxiliary node array */ Gnum * restrict velitax; /* Array of sums of weights of isolated neighboring nodes of elements */ Gnum * restrict velstax; /* Array of sums of weights of neighboring nodes of elements */ Gnum velssiz; /* Size of element neighboring node load sum array */ VmeshSeparateGgElem * sepaptr; /* Head of chained list of elements to re-link */ Gnum * restrict permtab; /* Element permutation table for finding new roots */ Gnum * permptr; /* Pointer to current permutation index */ INT passnum; /* Number of current pass */ Gnum ecmpsize0; /* Number of elements in part 0 */ Gnum ncmploaddlt; /* Current imbalance of bipartition */ Gnum ncmpload2; /* Current number of nodes in separator */ Gnum vnodnum; Gnum fronnum; Gnum ncmpsize1; Gnum ncmpsize2; if (meshptr->m.velmnbr == 0) { /* If only a single node or disconnected nodes */ vmeshZero (meshptr); /* Don't bother with parts */ return (0); } velssiz = (meshptr->m.vnlotax == NULL) ? 0 : meshptr->m.velmnbr; /* Compute size of vetex load sum array */ if (((tablptr = gainTablInit (GAINMAX, VMESHSEPAGGSUBBITS)) == NULL) || /* Use logarithmic array only */ ((vexxtab = (byte *) memAllocGroup ((void **) (void *) &velxtax, (size_t) (meshptr->m.velmnbr * sizeof (VmeshSeparateGgElem)), &vnoxtax, (size_t) (meshptr->m.vnodnbr * sizeof (VmeshSeparateGgNode)), &velitax, (size_t) (meshptr->m.velmnbr * sizeof (Gnum)), &velstax, (size_t) (velssiz * sizeof (Gnum)), NULL)) == NULL)) { /* Indicates end of group allocated array */ if (tablptr != NULL) gainTablExit (tablptr); errorPrint ("vmeshSeparateGg: out of memory (1)"); return (1); } vexxsiz = (byte *) velitax - vexxtab; /* Size of arrays that must be reset at each pass */ velxtax -= meshptr->m.velmbas; /* Base access to auxiliary arrays */ vnoxtax -= meshptr->m.vnodbas; velitax -= meshptr->m.velmbas; if (velssiz == 0) { /* If no vertex load array */ Gnum velmnum; for (velmnum = meshptr->m.velmbas; velmnum < meshptr->m.velmnnd; velmnum ++) { Gnum eelmnum; Gnum velisum; for (eelmnum = meshptr->m.verttax[velmnum], velisum = 0; eelmnum < meshptr->m.vendtax[velmnum]; eelmnum ++) { Gnum vnodnum; vnodnum = meshptr->m.edgetax[eelmnum]; if ((meshptr->m.vendtax[vnodnum] - meshptr->m.verttax[vnodnum]) == 1) velisum --; } velitax[velmnum] = velisum; } } else { Gnum velmnum; velstax -= meshptr->m.velmbas; for (velmnum = meshptr->m.velmbas; velmnum < meshptr->m.velmnnd; velmnum ++) { Gnum eelmnum; Gnum velisum; Gnum velssum; for (eelmnum = meshptr->m.verttax[velmnum], velisum = velssum = 0; eelmnum < meshptr->m.vendtax[velmnum]; eelmnum ++) { Gnum vnodnum; Gnum vnloval; vnodnum = meshptr->m.edgetax[eelmnum]; vnloval = meshptr->m.vnlotax[vnodnum]; velssum += vnloval; if ((meshptr->m.vendtax[vnodnum] - meshptr->m.verttax[vnodnum]) == 1) velisum -= vnloval; } velitax[velmnum] = velisum; velstax[velmnum] = velssum; } } permtab = NULL; /* Do not allocate permutation array yet */ for (passnum = 0; passnum < paraptr->passnbr; passnum ++) { /* For all passes */ VmeshSeparateGgElem * velxptr; /* Pointer to selected element */ memSet (vexxtab, 0, vexxsiz); /* All vertices to part 0 */ gainTablFree (tablptr); /* Reset gain table */ permptr = NULL; /* No permutation built yet */ ecmpsize0 = meshptr->m.velmnbr; /* All elements to part 0 */ ncmpload2 = 0; /* Reset separation parameters */ ncmploaddlt = meshptr->m.vnlosum; velxptr = (VmeshSeparateGgElem *) vexxtab + intRandVal (meshptr->m.velmnbr); /* Randomly select first root element vertex */ do { /* Loop on root element vertices */ Gnum velmnum; /* Number of current element to process */ velxptr->gainlink.next = /* TRICK: allow deletion of root vertex */ velxptr->gainlink.prev = (GainLink *) velxptr; velmnum = velxptr - velxtax; /* Get root element number */ { Gnum ncmpgain1; /* Gain (2->1) */ Gnum ncmpgain2; /* Gain (0->2) */ ncmpgain2 = (meshptr->m.vnlotax == NULL) /* Set gains */ ? meshptr->m.vendtax[velmnum] - meshptr->m.verttax[velmnum] : velstax[velmnum]; ncmpgain1 = velitax[velmnum]; velxptr->ncmpgain2 = ncmpgain1 + ncmpgain2; velxptr->ncmpgaindlt = ncmpgain1 - ncmpgain2; } do { /* While element vertices can be retrieved */ Gnum eelmnum; /* Number of current element edge */ velmnum = velxptr - velxtax; /* Get based number of selected element */ if (ncmploaddlt < abs (ncmploaddlt + velxtax[velmnum].ncmpgaindlt)) { /* If swapping would cause imbalance */ permptr = permtab + meshptr->m.velmnbr; /* Terminate swapping process */ velxptr = NULL; break; } ecmpsize0 --; /* One less element in part 0 */ gainTablDel (tablptr, (GainLink *) velxptr); /* Remove element from table */ velxptr->gainlink.next = VMESHSEPAGGSTATEPART1; /* Move element to part 1 */ ncmpload2 += velxptr->ncmpgain2; /* Update partition parameters */ ncmploaddlt += velxptr->ncmpgaindlt; sepaptr = NULL; /* No frontier elements to relink yet */ for (eelmnum = meshptr->m.verttax[velmnum]; /* For all neighbor node vertices */ eelmnum < meshptr->m.vendtax[velmnum]; eelmnum ++) { Gnum vnodnum; /* Number of current node neighbor */ vnodnum = meshptr->m.edgetax[eelmnum]; /* Get number of neighbor node */ #ifdef SCOTCH_DEBUG_VMESH2 if (vnoxtax[vnodnum].partval == 1) { errorPrint ("vmeshSeparateGg: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH2 */ if (vnoxtax[vnodnum].partval == 0) { /* If yet untouched neighbor node */ Gnum enodnum; /* Current egde of current neighbor node */ Gnum vnloval; vnloval = (meshptr->m.vnlotax == NULL) ? 1 : meshptr->m.vnlotax[vnodnum]; vnoxtax[vnodnum].partval = 2; /* Node now belongs to separator */ vnoxtax[vnodnum].commsize0 = meshptr->m.vendtax[vnodnum] - meshptr->m.verttax[vnodnum] - 1; vnoxtax[vnodnum].velmisum0 = - velmnum; for (enodnum = meshptr->m.verttax[vnodnum]; /* For all its elements */ enodnum < meshptr->m.vendtax[vnodnum]; enodnum ++) { Gnum velmend; velmend = meshptr->m.edgetax[enodnum]; /* Get neighbor element */ vnoxtax[vnodnum].velmisum0 += velmend; /* Sum-up element indices for neighbor node */ #ifdef SCOTCH_DEBUG_VMESH2 if ((velxtax[velmend].gainlink.next == VMESHSEPAGGSTATEPART1) && (velmend != velmnum)) { errorPrint ("vmeshSeparateGg: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH2 */ if (velxtax[velmend].gainlink.next == VMESHSEPAGGSTATEPART0) { /* If untouched element */ Gnum ncmpgain1; /* Gain (2->1) */ Gnum ncmpgain2; /* Gain (0->2) */ #ifdef SCOTCH_DEBUG_VMESH2 Gnum eelmend; #endif /* SCOTCH_DEBUG_VMESH2 */ velxtax[velmend].gainlink.next = VMESHSEPAGGSTATEPART2; /* Move element to frontier */ velxtax[velmend].gainlink.prev = (GainLink *) sepaptr; /* Chain vertex */ sepaptr = &velxtax[velmend]; ncmpgain2 = (meshptr->m.vnlotax == NULL) /* Set gains */ ? meshptr->m.vendtax[velmend] - meshptr->m.verttax[velmend] - 1 : velstax[velmend] - vnloval; ncmpgain1 = velitax[velmend]; #ifdef SCOTCH_DEBUG_VMESH2 for (eelmend = meshptr->m.verttax[velmend]; /* For all its neighboring nodes */ eelmend < meshptr->m.vendtax[velmend]; eelmend ++) { Gnum vnodend; vnodend = meshptr->m.edgetax[eelmend]; if ((vnoxtax[vnodend].partval == 1) || ((vnoxtax[vnodend].partval == 2) && (vnodend != vnodnum))) { errorPrint ("vmeshSeparateGg: internal error (3)"); return (1); } if (meshptr->m.vendtax[vnodend] - meshptr->m.verttax[vnodend] == 1) { if (vnoxtax[vnodend].partval != 0) { errorPrint ("vmeshSeparateGg: internal error (4)"); return (1); } } } #endif /* SCOTCH_DEBUG_VMESH2 */ velxtax[velmend].ncmpgain2 = ncmpgain1 + ncmpgain2; velxtax[velmend].ncmpgaindlt = ncmpgain1 - ncmpgain2; } else { /* Neighbor element belongs to frontier */ velxtax[velmend].ncmpgain2 -= vnloval; /* One less node to add to separator for element */ velxtax[velmend].ncmpgaindlt += vnloval; /* One less node to remove from part 0 */ if (velxtax[velmend].gainlink.next >= VMESHSEPAGGSTATELINK) { gainTablDel (tablptr, (GainLink *) &velxtax[velmend]); /* Unlink vertex */ velxtax[velmend].gainlink.next = VMESHSEPAGGSTATEPART2; /* Chain vertex */ velxtax[velmend].gainlink.prev = (GainLink *) sepaptr; sepaptr = &velxtax[velmend]; } } } } else { /* Neighbor node already in separator */ vnoxtax[vnodnum].commsize0 --; /* One less neighbor element in part 0 */ vnoxtax[vnodnum].velmisum0 -= velmnum; /* Subtract index of removed element */ } if (vnoxtax[vnodnum].commsize0 == 0) /* If node no longer has neighbors in part 0 */ vnoxtax[vnodnum].partval = 1; /* Node moves from separator to part 1 */ else if (vnoxtax[vnodnum].commsize0 == 1) { /* If only one neighbor element in part 0 */ Gnum velmend; /* Index of remaining element in part 0 */ Gnum vnloval; velmend = vnoxtax[vnodnum].velmisum0; /* Get neighbor element from remaining index */ #ifdef SCOTCH_DEBUG_VMESH2 if (velxtax[velmend].gainlink.next < VMESHSEPAGGSTATEPART2) { /* Element should have been declared in part 0 at this stage */ errorPrint ("vmeshSeparateGg: internal error (5)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH2 */ vnloval = (meshptr->m.vnlotax == NULL) ? 1 : meshptr->m.vnlotax[vnodnum]; velxtax[velmend].ncmpgain2 -= vnloval; velxtax[velmend].ncmpgaindlt -= vnloval; if (velxtax[velmend].gainlink.next >= VMESHSEPAGGSTATELINK) { gainTablDel (tablptr, (GainLink *) &velxtax[velmend]); /* Unlink vertex */ velxtax[velmend].gainlink.next = VMESHSEPAGGSTATEPART2; /* Chain vertex */ velxtax[velmend].gainlink.prev = (GainLink *) sepaptr; sepaptr = &velxtax[velmend]; } } } while (sepaptr != NULL) { /* For all vertices in chain list */ velxptr = sepaptr; /* Unlink vertex from list */ sepaptr = (VmeshSeparateGgElem *) velxptr->gainlink.prev; gainTablAdd (tablptr, (GainLink *) velxptr, velxptr->ncmpgain2); /* Relink it */ } #ifdef SCOTCH_DEBUG_VMESH3 if (vmeshSeparateGgCheck (meshptr, ncmpload2, ncmploaddlt, velxtax, vnoxtax) != 0) { errorPrint ("vmeshSeparateGg: internal error (6)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH3 */ } while ((velxptr = (VmeshSeparateGgElem *) gainTablFrst (tablptr)) != NULL); if (permptr == NULL) { /* If element permutation not yet built */ if (permtab == NULL) { /* If permutation array not yet allocated */ if ((permtab = (Gnum *) memAlloc (meshptr->m.velmnbr * sizeof (Gnum))) == NULL) { errorPrint ("vmeshSeparateGg: out of memory (2)"); memFree (vexxtab); gainTablExit (tablptr); return (1); } intAscn (permtab, meshptr->m.velmnbr, meshptr->m.baseval); /* Initialize permutation array */ } intPerm (permtab, meshptr->m.velmnbr); /* Build random permutation */ permptr = permtab; /* Start at beginning of permutation */ } for ( ; permptr < permtab + meshptr->m.velmnbr; permptr ++) { /* Find next root vertex */ #ifdef SCOTCH_DEBUG_VMESH2 if (velxtax[*permptr].gainlink.next >= VMESHSEPAGGSTATEPART2) { errorPrint ("vmeshSeparateGg: internal error (7)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH2 */ if (velxtax[*permptr].gainlink.next == VMESHSEPAGGSTATEPART0) { velxptr = velxtax + (*permptr ++); break; } } } while (velxptr != NULL); if ((passnum == 0) || /* If it is the first try */ ( (meshptr->ncmpload[2] > ncmpload2) || /* Or if better solution reached */ ((meshptr->ncmpload[2] == ncmpload2) && (abs (meshptr->ncmploaddlt) > abs (ncmploaddlt))))) { Gnum vertnum; meshptr->ecmpsize[0] = ecmpsize0; /* Set graph parameters */ meshptr->ncmpload[2] = ncmpload2; meshptr->ncmploaddlt = ncmploaddlt; for (vertnum = meshptr->m.velmbas; vertnum < meshptr->m.velmnnd; vertnum ++) /* Copy element bipartition state */ meshptr->parttax[vertnum] = (velxtax[vertnum].gainlink.next == VMESHSEPAGGSTATEPART1) ? 1 : 0; for (vertnum = meshptr->m.vnodbas; vertnum < meshptr->m.vnodnnd; vertnum ++) /* Copy node bipartition state */ meshptr->parttax[vertnum] = vnoxtax[vertnum].partval; } } meshptr->ecmpsize[1] = meshptr->m.velmnbr - meshptr->ecmpsize[0]; meshptr->ncmpload[1] = ((meshptr->m.vnlosum - meshptr->ncmpload[2]) - meshptr->ncmploaddlt) >> 1; meshptr->ncmpload[0] = (meshptr->m.vnlosum - meshptr->ncmpload[2]) - meshptr->ncmpload[1]; for (vnodnum = meshptr->m.vnodbas, fronnum = 0, ncmpsize1 = ncmpsize2 = 0; vnodnum < meshptr->m.vnodnnd; vnodnum ++) { Gnum partval; partval = meshptr->parttax[vnodnum]; ncmpsize1 += (partval & 1); /* Superscalar update */ ncmpsize2 += (partval >> 1); if (partval == 2) meshptr->frontab[fronnum ++] = vnodnum; /* Vertex belongs to frontier */ } meshptr->ncmpsize[0] = meshptr->m.vnodnbr - (ncmpsize1 + ncmpsize2); meshptr->ncmpsize[1] = ncmpsize1; meshptr->fronnbr = ncmpsize2; #ifdef SCOTCH_DEBUG_VMESH2 if (vmeshCheck (meshptr) != 0) { errorPrint ("vmeshSeparateGg: inconsistent graph data"); return (1); } #endif /* SCOTCH_DEBUG_VMESH2 */ if (permtab != NULL) memFree (permtab); memFree (vexxtab); /* Free group leader */ gainTablExit (tablptr); /* printf ("GG Sepa\tsize=%ld\tload=%ld\tbal=%ld\n", (long) meshptr->fronnbr, (long) meshptr->ncmpload[2], (long) meshptr->ncmploaddlt); */ return (0); } /* This routine checks the consistency ** of the current bipartition. ** It returns: ** - 0 : if the bipartition is consistent. ** - !0 : on error. */ #ifdef SCOTCH_DEBUG_VMESH3 static int vmeshSeparateGgCheck ( Vmesh * restrict const meshptr, const Gnum ncmpload2, const Gnum ncmploaddlt, const VmeshSeparateGgElem * restrict const velxtax, const VmeshSeparateGgNode * restrict const vnoxtax) { Gnum vnodnum; Gnum vnloval; Gnum ncmpsize0c; Gnum ncmpsize1c; Gnum ncmpsize2c; Gnum ncmpload0c; Gnum ncmpload1c; Gnum ncmpload2c; ncmpsize1c = ncmpsize2c = ncmpload1c = ncmpload2c = 0; vnloval = 1; for (vnodnum = meshptr->m.vnodbas; vnodnum < meshptr->m.vnodnnd; vnodnum ++) { int partval; Gnum partval1; Gnum partval2; partval = vnoxtax[vnodnum].partval; partval1 = partval & 1; partval2 = partval >> 1; if (meshptr->m.vnlotax != NULL) vnloval = meshptr->m.vnlotax[vnodnum]; if (partval > 2) { errorPrint ("vmeshSeparateGgCheck: invalid node part value"); return (1); } ncmpsize1c += partval1; ncmpsize2c += partval2; ncmpload1c += partval1 * vnloval; ncmpload2c += partval2 * vnloval; } ncmpsize0c = meshptr->m.vnodnbr - ncmpsize1c - ncmpsize2c; ncmpload0c = meshptr->m.vnlosum - ncmpload1c - ncmpload2c; if (ncmpload2c != ncmpload2) { errorPrint ("vmeshSeparateGgCheck: invalid separator size"); return (1); } if (ncmploaddlt != (ncmpload0c - ncmpload1c)) { errorPrint ("vmeshSeparateGgCheck: invalid separator balance"); return (1); } return (0); } #endif /* SCOTCH_DEBUG_VMESH3 */ scotch-6.0.4.dfsg/src/libscotch/common.c0000644002563400244210000001217612217145045023276 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : common.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** David GOUDIN **/ /** Pascal HENON **/ /** Pierre RAMET **/ /** Yves SECRETAN (v5.1) **/ /** **/ /** FUNCTION : Part of a parallel direct block solver. **/ /** These lines are common routines used **/ /** by all modules. **/ /** **/ /** DATES : # Version 0.0 : from : 08 may 1998 **/ /** to 14 sep 1998 **/ /** # Version 2.0 : from : 27 sep 2004 **/ /** to 27 sep 2004 **/ /** # Version 5.1 : from : 27 jun 2010 **/ /** to 23 nov 2010 **/ /** # Version 6.0 : from : 21 sep 2013 **/ /** to 21 sep 2013 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define COMMON #ifndef COMMON_NOMODULE #include "module.h" #endif /* COMMON_NOMODULE */ #include "common.h" /*******************/ /* */ /* Timing routine. */ /* */ /*******************/ double clockGet (void) { #ifdef MPI_INT return (MPI_Wtime ()); #else /* MPI_INT */ #if defined COMMON_WINDOWS double res = 0.0; LARGE_INTEGER fq; if (QueryPerformanceFrequency (&fq) == 0) { FILETIME ft; ULARGE_INTEGER t; GetSystemTimeAsFileTime (&ft); t.LowPart = ft.dwLowDateTime; t.HighPart = ft.dwHighDateTime; res = (double) t.QuadPart / 10000000.0; } else { LARGE_INTEGER pc; QueryPerformanceCounter (&pc); res = (double) pc.QuadPart / (double) fq.QuadPart; } return (res); #elif defined COMMON_TIMING_OLD /* Old Unix timing routine */ struct rusage data; getrusage (RUSAGE_SELF, &data); return (((double) data.ru_utime.tv_sec + (double) data.ru_stime.tv_sec) + ((double) data.ru_utime.tv_usec + (double) data.ru_stime.tv_usec) * 1.0e-6L); #else /* COMMON_TIMING_OLD */ #if defined (_POSIX_TIMERS) && (_POSIX_TIMERS >= 200112L) struct timespec tp; clock_gettime (CLOCK_REALTIME, &tp); /* Elapsed time */ return ((double) tp.tv_sec + (double) tp.tv_nsec * 1.0e-9L); #else /* defined (_POSIX_TIMERS) && (_POSIX_TIMERS >= 200112L) */ struct timeval tv; gettimeofday (&tv, NULL); return ((double) tv.tv_sec + (double) tv.tv_usec * 1.0e-6L); #endif /* defined (_POSIX_TIMERS) && (_POSIX_TIMERS >= 200112L) */ #endif /* COMMON_TIMING_OLD */ #endif /* MPI_INT */ } /***************************/ /* */ /* Usage printing routine. */ /* */ /***************************/ void usagePrint ( FILE * const stream, const char ** const data) { const char ** cptr; fprintf (stream, "Usage is:\n"); for (cptr = data; *cptr != NULL; cptr ++) fprintf (stream, " %s\n", *cptr); } scotch-6.0.4.dfsg/src/libscotch/arch_build.h0000644002563400244210000001014211631447170024101 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : arch_build.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the architecture building routine. **/ /** **/ /** DATES : # Version 3.2 : from : 29 may 1997 **/ /** to 01 sep 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 4.0 : from : 29 nov 2003 **/ /** to 29 nov 2003 **/ /** **/ /** NOTES : # This file contains pieces of code **/ /** extracted from release 3.1 of **/ /** "amk_src.c". **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ Job to process. +*/ typedef struct ArchBuildJob_ { struct ArchBuildJob_ * joblink; /*+ Link to job pool +*/ ArchDomNum domnum; /*+ Mapping domain to which vertices belong +*/ Graph grafdat; /*+ Job graph data +*/ } ArchBuildJob; /*+ Vertex distance information. +*/ typedef struct ArchBuildDistElem_ { int queued; /*+ Flag set if vertex queued +*/ Anum distval; /*+ Distance to initial vertex +*/ } ArchBuildDistElem; /*+ Queue element. +*/ typedef struct ArchBuildQueuElem_ { Gnum vertnum; /*+ Vertex number in source graph +*/ Anum distval; /*+ Distance reached +*/ } ArchBuildQueuElem; /* ** The function prototypes. */ #ifndef ARCH_BUILD #define static #endif static void archBuildJobExit (ArchBuildJob *); int archBuild (Arch * const, const Graph * const, const VertList * const, const Strat * const); #undef static scotch-6.0.4.dfsg/src/libscotch/dgraph_scatter.c0000644002563400244210000004332011631447170024776 0ustar trophimeutilisateurs du domaine/* Copyright 2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_scatter.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** Francois CHATENET (P0.0) **/ /** Sebastien FOUCAULT (P0.0) **/ /** **/ /** FUNCTION : This module contains the routine that **/ /** builds a distributed graph by evenly **/ /** distributing the pieces of a central- **/ /** ized graph across processors. **/ /** **/ /** # Version P0.0 : from : 01 apr 1997 **/ /** to 20 jun 1997 **/ /** # Version P0.1 : from : 14 apr 1998 **/ /** to 20 jun 1998 **/ /** # Version P0.2 : from : 19 may 1999 **/ /** to 19 may 1999 **/ /** # Version 5.0 : from : 27 apr 2006 **/ /** to : 10 sep 2007 **/ /** **/ /** NOTES : # The definitions of MPI_Scatter and **/ /** MPI_Scatterv indicate that elements **/ /** in the send array should not be read **/ /** more than once. Great care should be **/ /** taken to enforce this rule, especial- **/ /** ly when the number of vertices in the **/ /** centralized graph is smaller than the **/ /** number of processors. **/ /** **/ /** # When the source graph is not compact, **/ /** compacted arrays are created prior to **/ /** sending parts of them. In a really **/ /** efficient implementation, these **/ /** should be created by pieces and sent **/ /** in a one-to-one way so as to save as **/ /** much memory as possible. This is yet **/ /** to be done. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DGRAPH_SCATTER #include "module.h" #include "common.h" #include "graph.h" #include "dgraph.h" /* Service function which creates compact ** arrays from non-compact ones. */ static void dgraphScatter2 ( const Graph * restrict const cgrfptr, Gnum * restrict verttax, Gnum * restrict edgetax, Gnum * restrict edlotax) { Gnum vertnum; /* Current vertex number in compacted arrays */ Gnum edgenum; /* Current edge number in compacted arrays */ for (vertnum = edgenum = cgrfptr->baseval; vertnum < cgrfptr->vertnnd; vertnum ++) { Gnum edgetmp; Gnum edgetnd; verttax[vertnum] = edgenum; edgetmp = cgrfptr->verttax[vertnum]; edgetnd = cgrfptr->vendtax[vertnum]; for ( ; edgetmp < edgetnd; edgetmp ++, edgenum ++) edgetax[edgenum] = cgrfptr->edgetax[edgetmp]; if (edlotax != NULL) { for (edgetmp = cgrfptr->verttax[vertnum], edgenum = verttax[vertnum]; edgetmp < edgetnd; edgetmp ++, edgenum ++) edlotax[edgenum] = cgrfptr->edlotax[edgetmp]; } } verttax[vertnum] = edgenum; } /* This function evenly distributes the pieces ** of a centralized graph across processors. ** It returns: ** - 0 : if scattering has succeeded. ** - !0 : on error. */ int dgraphScatter ( Dgraph * restrict const grafptr, /* Distributed graph */ const Graph * restrict const cgrfptr) /* Centralized graph to scatter */ { Gnum baseval; /* Base value */ Gnum * restrict verttax; /* Array of vertices when edge array is not compact */ Gnum * restrict edgetax; /* Compact array of edges when edge aray is not compact */ Gnum * restrict edlotax; /* Compact array of edges weights */ Gnum vertlocnum; /* Current local vertex number */ Gnum vertlocnbr; /* Number of local vertices */ Gnum vertlocnnd; Gnum * restrict vertloctax; /* Array of local vertices */ Gnum * restrict veloloctax; /* Array of local vertex weights */ Gnum velolocnbr; Gnum vlbllocnbr; Gnum * restrict vlblloctax; /* Array of local vertex labels */ Gnum edgelocnbr; /* Number of local edges */ Gnum edlolocnbr; Gnum * restrict edgeloctax; /* Array of local edges */ Gnum * restrict edloloctax; /* Array of local edge weights */ int * restrict attrdsptab; /* Displacement array for scatter operations */ int * restrict attrcnttab; /* Count array for scatter operations */ Gnum * restrict attrdattab; /* Temporary array to avoid multiple scatter reads */ Gnum reduloctab[9]; /* Arrays for reductions */ Gnum reduglbtab[9]; Gnum vertlocadj; /* Local vertex array adjust */ int protnum; /* Root process */ if (cgrfptr != NULL) { /* If centralized graph provided */ if (cgrfptr->vendtax != (cgrfptr->verttax + 1)) { /* If edge array is not compact */ Gnum edlonbr; edlonbr = (cgrfptr->edlotax != NULL) ? cgrfptr->edgenbr : 0; if (memAllocGroup ((void **) (void *) &verttax, (size_t) ((cgrfptr->vertnbr + 1) * sizeof (Gnum)), &edgetax, (size_t) (cgrfptr->edgenbr * sizeof (Gnum)), &edlotax, (size_t) (edlonbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("dgraphScatter: out of memory (1)"); return (1); } verttax -= cgrfptr->baseval; edgetax -= cgrfptr->baseval; edlotax = (cgrfptr->edlotax != NULL) ? (edlotax - cgrfptr->baseval) : NULL; dgraphScatter2 (cgrfptr, verttax, edgetax, edlotax); } else { verttax = cgrfptr->verttax; edgetax = cgrfptr->edgetax; edlotax = cgrfptr->edlotax; } reduloctab[0] = 1; /* This process is the root */ reduloctab[1] = (Gnum) grafptr->proclocnum; /* Get its number */ reduloctab[2] = cgrfptr->baseval; reduloctab[3] = cgrfptr->vertnbr; reduloctab[4] = cgrfptr->edgenbr; reduloctab[5] = cgrfptr->velosum; reduloctab[6] = (cgrfptr->velotax != NULL) ? 1 : 0; reduloctab[7] = (cgrfptr->vlbltax != NULL) ? 1 : 0; reduloctab[8] = (cgrfptr->edlotax != NULL) ? 1 : 0; } else { reduloctab[0] = /* This process is not the root */ reduloctab[1] = reduloctab[2] = reduloctab[3] = reduloctab[4] = reduloctab[5] = reduloctab[6] = reduloctab[7] = reduloctab[8] = 0; } if (MPI_Allreduce (reduloctab, reduglbtab, 9, GNUM_MPI, MPI_SUM, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphScatter: communication error (1)"); return (1); } if (reduglbtab[0] != 1) { errorPrint ("dgraphScatter: should have only one root"); return (1); } baseval = reduglbtab[2]; vertlocnbr = DATASIZE (reduglbtab[3], grafptr->procglbnbr, grafptr->proclocnum); velolocnbr = (reduglbtab[6] != 0) ? vertlocnbr : 0; vlbllocnbr = (reduglbtab[7] != 0) ? vertlocnbr : 0; if (memAllocGroup ((void **) (void *) &vertloctax, (size_t) ((vertlocnbr + 1) * sizeof (Gnum)), &veloloctax, (size_t) (velolocnbr * sizeof (Gnum)), &vlblloctax, (size_t) (vlbllocnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("dgraphScatter: out of memory (2)"); if ((cgrfptr != NULL) && (cgrfptr->verttax != verttax)) memFree (verttax + baseval); /* Free group leader */ return (1); } vertloctax -= baseval; veloloctax = (reduglbtab[6] != 0) ? (veloloctax - baseval) : NULL; vlblloctax = (reduglbtab[7] != 0) ? (vlblloctax - baseval) : NULL; protnum = (int) reduglbtab[1]; if (cgrfptr != NULL) { /* If root process */ Gnum procnum; if (memAllocGroup ((void **) (void *) &attrdattab, (size_t) (grafptr->procglbnbr * sizeof (Gnum)), &attrdsptab, (size_t) (grafptr->procglbnbr * sizeof (int)), &attrcnttab, (size_t) (grafptr->procglbnbr * sizeof (int)), NULL) == NULL) { errorPrint ("dgraphScatter: out of memory (3)"); memFree (vertloctax + baseval); if (cgrfptr->verttax != verttax) memFree (verttax + baseval); /* Free group leader */ return (1); } attrdsptab[0] = 0; /* Build arrays for MPI_Scatterv */ attrcnttab[0] = DATASIZE (reduglbtab[3], grafptr->procglbnbr, 0); attrdattab[0] = verttax[attrdsptab[0] + attrcnttab[0] + baseval]; for (procnum = 1; procnum < grafptr->procglbnbr; procnum ++) { attrdsptab[procnum] = attrdsptab[procnum - 1] + attrcnttab[procnum - 1]; attrcnttab[procnum] = DATASIZE (reduglbtab[3], grafptr->procglbnbr, procnum); attrdattab[procnum] = verttax[attrdsptab[procnum] + attrcnttab[procnum] + baseval]; } if (MPI_Scatterv (verttax + baseval, attrcnttab, attrdsptab, GNUM_MPI, /* Perform two scatters since cannot avoid multiple reads with only one scatter */ vertloctax + baseval, vertlocnbr, GNUM_MPI, protnum, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphScatter: communication error (2)"); return (1); } if (MPI_Scatter (attrdattab, 1, GNUM_MPI, vertloctax + baseval + vertlocnbr, 1, GNUM_MPI, protnum, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphScatter: communication error (3)"); return (1); } if (reduglbtab[6] != 0) { /* Scatter vertex loads */ if (MPI_Scatterv (cgrfptr->velotax + baseval, attrcnttab, attrdsptab, GNUM_MPI, veloloctax + baseval, vertlocnbr, GNUM_MPI, protnum, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphScatter: communication error (4)"); return (1); } } if (reduglbtab[7] != 0) { /* Scatter labels */ if (MPI_Scatterv (cgrfptr->vlbltax + baseval, attrcnttab, attrdsptab, GNUM_MPI, vlblloctax + baseval, vertlocnbr, GNUM_MPI, protnum, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphScatter: communication error (5)"); return (1); } } } else { /* Process is not root */ if (MPI_Scatterv (NULL, NULL, NULL, GNUM_MPI, vertloctax + baseval, vertlocnbr, GNUM_MPI, protnum, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphScatter: communication error (6)"); return (1); } if (MPI_Scatter (NULL, 1, GNUM_MPI, vertloctax + baseval + vertlocnbr, 1, GNUM_MPI, protnum, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphScatter: communication error (7)"); return (1); } if (reduglbtab[6] != 0) { /* Scatter vertex loads */ if (MPI_Scatterv (NULL, NULL, NULL, GNUM_MPI, veloloctax + baseval, vertlocnbr, GNUM_MPI, protnum, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphScatter: communication error (8)"); return (1); } } if (reduglbtab[7] != 0) { /* Scatter labels */ if (MPI_Scatterv (NULL, NULL, NULL, GNUM_MPI, vlblloctax + baseval, vertlocnbr, GNUM_MPI, protnum, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphScatter: communication error (9)"); return (1); } } } vertlocadj = vertloctax[baseval] - baseval; /* Compute local indices */ for (vertlocnum = baseval, vertlocnnd = vertlocnbr + baseval; vertlocnum <= vertlocnnd; vertlocnum ++) vertloctax[vertlocnum] -= vertlocadj; edgelocnbr = vertloctax[vertlocnnd] - vertloctax[baseval]; edlolocnbr = (reduglbtab[8] != 0) ? edgelocnbr : 0; if (memAllocGroup ((void **) (void *) &edgeloctax, (size_t) (edgelocnbr * sizeof (Gnum)), &edloloctax, (size_t) (edlolocnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("dgraphScatter: out of memory (4)"); if (cgrfptr != NULL) { memFree (attrdattab); /* Free group leader */ if (cgrfptr->verttax != verttax) memFree (verttax + baseval); /* Free group leader */ } memFree (vertloctax + baseval); return (1); } edgeloctax -= baseval; edloloctax = (reduglbtab[8] != 0) ? edloloctax - baseval : NULL; if (cgrfptr != NULL) { /* If root process */ Gnum procnum; for (procnum = 0; procnum < grafptr->procglbnbr; procnum ++) { /* Build arrays for MPI_Scatterv */ attrcnttab[procnum] = verttax[attrdsptab[procnum] + attrcnttab[procnum]+baseval] - verttax[attrdsptab[procnum] + baseval]; attrdsptab[procnum] = verttax[attrdsptab[procnum] + baseval] - baseval; } if (MPI_Scatterv (edgetax + baseval, attrcnttab, attrdsptab, GNUM_MPI, edgeloctax + baseval, edgelocnbr, GNUM_MPI, protnum, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphScatter: communication error (10)"); return (1); } if (reduglbtab[8] != 0) { if (MPI_Scatterv (edlotax + baseval, attrcnttab, attrdsptab, GNUM_MPI, edloloctax + baseval, edgelocnbr, GNUM_MPI, protnum, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphScatter: communication error (11)"); return (1); } } memFree (attrdattab); /* Free group leader */ if (cgrfptr->verttax != verttax) memFree (verttax + baseval); } else { /* Process is not root */ if (MPI_Scatterv (NULL, NULL, NULL, GNUM_MPI, edgeloctax + baseval , edgelocnbr, GNUM_MPI, protnum, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphScatter: communication error (12)"); return (1); } if (reduglbtab[8] != 0) { if (MPI_Scatterv (NULL, NULL, NULL, GNUM_MPI, edloloctax + baseval , edgelocnbr, GNUM_MPI, protnum, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dgraphScatter: communication error (13)"); return (1); } } } if (dgraphBuild (grafptr, baseval, vertlocnbr, vertlocnbr, vertloctax, vertloctax + 1, veloloctax, NULL, NULL, edgelocnbr, edgelocnbr, edgeloctax, NULL, edloloctax) != 0) { memFree (edgeloctax + baseval); memFree (vertloctax + baseval); return (1); } grafptr->flagval |= DGRAPHFREETABS | DGRAPHVERTGROUP | DGRAPHEDGEGROUP; /* Give ownership of arrays to graph */ grafptr->vlblloctax = vlblloctax; /* Add labels afterwards, since relabeling already done */ return (0); } scotch-6.0.4.dfsg/src/libscotch/bdgraph_gather_all.c0000644002563400244210000002651512400674360025602 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2010,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bdgraph_gather_all.c **/ /** **/ /** AUTHORS : Jun-Ho HER (v6.0) **/ /** Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the routine which **/ /** builds a centralized Bgraph on all **/ /** processors by gathering the pieces of **/ /** a distributed Bdgraph. **/ /** **/ /** DATES : # Version 5.1 : from : 21 dec 2007 **/ /** to 14 apr 2011 **/ /** # Version 6.0 : from : 29 aug 2014 **/ /** to 31 aug 2014 **/ /** **/ /** NOTES : # The definitions of MPI_Gather and **/ /** MPI_Gatherv indicate that elements in **/ /** the receive array should not be **/ /** written more than once. Great care **/ /** should be taken to enforce this rule, **/ /** especially when the number of **/ /** vertices in the centralized graph is **/ /** smaller than the number of **/ /** processors. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #include "module.h" #include "common.h" #include "comm.h" #include "arch.h" #include "graph.h" #include "bgraph.h" #include "dgraph.h" #include "bdgraph.h" /* This function gathers on all processors ** the pieces of a distributed Bdgraph to ** build a centralized Bgraph. ** It returns: ** - 0 : if graph data are consistent. ** - !0 : on error. */ int bdgraphGatherAll ( const Bdgraph * restrict const dgrfptr, /* Distributed graph */ Bgraph * restrict cgrfptr) /* Centralized graph */ { int * restrict froncnttab; /* Count array for gather operations */ int * restrict fronvrttab; /* Displacement array for gather operations */ int fronlocnbr; /* Also int to enforce MPI standard */ int cheklocval; #ifdef SCOTCH_DEBUG_BDGRAPH1 int chekglbval; #endif /* SCOTCH_DEBUG_BDGRAPH1 */ int procnum; cheklocval = 0; #ifdef SCOTCH_DEBUG_BDGRAPH1 if (cgrfptr == NULL) /* Centralized graphs should be provided by all */ cheklocval = 1; if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphGatherAll: communication error (1)"); return (1); } if (chekglbval != 0) { errorPrint ("bdgraphGatherAll: centralized graphs should be provided on every process"); return (1); } #endif /* SCOTCH_DEBUG_BDGRAPH1 */ if (dgraphGatherAll (&dgrfptr->s, &cgrfptr->s) != 0) { errorPrint ("bdgraphGatherAll: cannot build centralized graph"); return (1); } cgrfptr->s.flagval |= BGRAPHFREEFRON | BGRAPHFREEPART | BGRAPHFREEVEEX; cgrfptr->veextax = NULL; /* In case of error */ cgrfptr->parttax = NULL; cgrfptr->frontab = NULL; if ((cgrfptr->frontab = (Gnum *) memAlloc (cgrfptr->s.vertnbr * sizeof (Gnum))) == NULL) { errorPrint ("bdgraphGatherAll: out of memory (1)"); #ifndef SCOTCH_DEBUG_BDGRAPH1 bgraphExit (cgrfptr); return (1); #else /* SCOTCH_DEBUG_BDGRAPH1 */ cheklocval = 1; #endif /* SCOTCH_DEBUG_BDGRAPH1 */ } else if ((cgrfptr->parttax = (GraphPart *) memAlloc (cgrfptr->s.vertnbr * sizeof (GraphPart))) == NULL) { errorPrint ("bdgraphGatherAll: out of memory (2)"); #ifndef SCOTCH_DEBUG_BDGRAPH1 bgraphExit (cgrfptr); return (1); #else /* SCOTCH_DEBUG_BDGRAPH1 */ cheklocval = 1; #endif /* SCOTCH_DEBUG_BDGRAPH1 */ } else { cgrfptr->parttax -= cgrfptr->s.baseval; if (dgrfptr->veexloctax != NULL) { if ((cgrfptr->veextax = (Gnum *) memAlloc (cgrfptr->s.vertnbr * sizeof (Gnum))) == NULL) { errorPrint ("bdgraphGatherAll: out of memory (3)"); #ifndef SCOTCH_DEBUG_BDGRAPH1 bgraphExit (cgrfptr); return (1); #else /* SCOTCH_DEBUG_BDGRAPH1 */ cheklocval = 1; #endif /* SCOTCH_DEBUG_BDGRAPH1 */ } else cgrfptr->veextax -= cgrfptr->s.baseval; } } #ifdef SCOTCH_DEBUG_BDGRAPH1 if (cheklocval == 0) { #endif /* SCOTCH_DEBUG_BDGRAPH1 */ if (memAllocGroup ((void **) (void *) /* Allocate tempory arrays to gather frontiers */ &froncnttab, (size_t) (dgrfptr->s.procglbnbr * sizeof (int)), &fronvrttab, (size_t) (dgrfptr->s.procglbnbr * sizeof (int)), NULL) == NULL) { errorPrint ("bdgraphGatherAll: out of memory (4)"); #ifndef SCOTCH_DEBUG_BDGRAPH1 bgraphExit (cgrfptr); return (1); } #else /* SCOTCH_DEBUG_BDGRAPH1 */ cheklocval = 1; } } if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphGatherAll: communication error (2)"); return (1); } if (chekglbval != 0) { if (froncnttab != NULL) memFree (froncnttab); /* Free group leader */ bgraphExit (cgrfptr); return (1); } #endif /* SCOTCH_DEBUG_BDGRAPH1 */ cgrfptr->compload0min = dgrfptr->compglbload0min; /* Set constant fields of the centralized graph as those of the distibuted graph */ cgrfptr->compload0max = dgrfptr->compglbload0max; cgrfptr->compload0avg = dgrfptr->compglbload0avg; cgrfptr->commloadextn0 = dgrfptr->commglbloadextn0; cgrfptr->commgainextn0 = dgrfptr->commglbgainextn0; cgrfptr->domndist = dgrfptr->domndist; cgrfptr->domnwght[0] = dgrfptr->domnwght[0]; cgrfptr->domnwght[1] = dgrfptr->domnwght[1]; cgrfptr->vfixload[0] = /* Fixed vertices will soon be available in PT-Scotch */ cgrfptr->vfixload[1] = 0; cgrfptr->levlnum = dgrfptr->levlnum; if (dgrfptr->partgsttax == NULL) { /* If distributed graph does not have a part array yet */ bgraphZero (cgrfptr); memFree (froncnttab); /* Free group leader */ return (0); } if (commAllgatherv (dgrfptr->partgsttax + dgrfptr->s.baseval, dgrfptr->s.vertlocnbr, GRAPHPART_MPI, /* Get parttax of distributed graph */ cgrfptr->parttax, dgrfptr->s.proccnttab, dgrfptr->s.procdsptab, GRAPHPART_MPI, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphGatherAll: communication error (4)"); return (1); } if (dgrfptr->veexloctax != NULL) { if (commAllgatherv (dgrfptr->veexloctax + dgrfptr->s.baseval, dgrfptr->s.vertlocnbr, GNUM_MPI, /* Get veextax of distributed graph */ cgrfptr->veextax, dgrfptr->s.proccnttab, dgrfptr->s.procdsptab, GNUM_MPI, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphGatherAll: communication error (5)"); return (1); } } fronlocnbr = (int) dgrfptr->fronlocnbr; if (MPI_Allgather (&fronlocnbr, 1, MPI_INT, /* Compute how frontiers are distributed */ froncnttab, 1, MPI_INT, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphGatherAll: communication error (6)"); return (1); } fronvrttab[0] = 0; /* Offset 0 for first process */ for (procnum = 1; procnum < dgrfptr->s.procglbnbr; procnum ++) /* Adjust index sub-arrays for all processors except the first one */ fronvrttab[procnum] = fronvrttab[procnum - 1] + froncnttab[procnum - 1]; if (MPI_Allgatherv (dgrfptr->fronloctab, (int) dgrfptr->fronlocnbr, GNUM_MPI, /* Gather frontiers */ cgrfptr->frontab, froncnttab, fronvrttab, GNUM_MPI, dgrfptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphGatherAll: communication error (7)"); return (1); } for (procnum = 1; procnum < dgrfptr->s.procglbnbr; procnum ++) { /* Adjust index sub-arrays for all processors except the first one */ Gnum vertnum; Gnum vertnnd; for (vertnum = (Gnum) fronvrttab[procnum], vertnnd = (Gnum) fronvrttab[procnum] + (Gnum) froncnttab[procnum]; vertnum < vertnnd; vertnum ++) cgrfptr->frontab[vertnum] += (Gnum) dgrfptr->s.procdsptab[procnum] - dgrfptr->s.baseval; } memFree (froncnttab); /* Free group leader */ for (procnum = 0; procnum < dgrfptr->s.proclocnum; procnum ++) /* Desynchronize random generators across processes */ cheklocval = intRandVal (2); intPerm (cgrfptr->frontab, dgrfptr->fronglbnbr); /* Compute permutation of frontier array to have different solutions on every process */ cgrfptr->compload0 = dgrfptr->compglbload0; /* Update other fields */ cgrfptr->compload0dlt = dgrfptr->compglbload0dlt; cgrfptr->compsize0 = dgrfptr->compglbsize0; cgrfptr->commload = dgrfptr->commglbload; cgrfptr->commgainextn = dgrfptr->commglbgainextn; cgrfptr->commgainextn0 = dgrfptr->commglbgainextn0; cgrfptr->fronnbr = dgrfptr->fronglbnbr; #ifdef SCOTCH_DEBUG_BDGRAPH2 if (bgraphCheck (cgrfptr) != 0) { errorPrint ("bdgraphGatherAll: internal error"); bgraphExit (cgrfptr); return (1); } #endif /* SCOTCH_DEBUG_BDGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/kdgraph.c0000644002563400244210000001034512022573652023425 0ustar trophimeutilisateurs du domaine/* Copyright 2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kdgraph.c **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a parallel bipartitioning **/ /** mapper. **/ /** This module handles the k-way active **/ /** distributed graph and save data struct- **/ /** ure handling routines. **/ /** **/ /** DATES : # Version 5.1 : from : 31 mar 2008 **/ /** to 01 jul 2008 **/ /** # Version 6.0 : from : 08 sep 2012 **/ /** to 08 sep 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define KDGRAPH #include "module.h" #include "common.h" #include "arch.h" #include "dgraph.h" #include "dmapping.h" #include "kdgraph.h" /************************************/ /* */ /* Active dgraph handling routines. */ /* */ /************************************/ /* This routine builds the active dgraph ** corresponding to the given k-way ** partition parameters. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int kdgraphInit ( Kdgraph * restrict const actgrafptr, /* Active graph */ const Dgraph * restrict const srcgrafptr, /* Source graph */ Dmapping * restrict const dmapptr) /* Mapping */ { actgrafptr->s = *srcgrafptr; /* Clone source graph */ actgrafptr->s.flagval &= ~DGRAPHFREEALL; actgrafptr->s.vlblloctax = NULL; /* Do not propagate vertex labels within computations (e.g. dgraphInduce) */ actgrafptr->levlnum = 0; actgrafptr->m.mappptr = dmapptr; archDomFrst (&dmapptr->archdat, &actgrafptr->m.domnorg); return (0); } /* This routine frees the contents ** of the given active graph ** It returns: ** - VOID : in all cases. */ void kdgraphExit ( Kdgraph * restrict const actgrafptr) /* Active graph */ { dgraphExit (&actgrafptr->s); #ifdef SCOTCH_DEBUG_KDGRAPH1 memSet (actgrafptr, 0, sizeof (Kdgraph)); #endif /* SCOTCH_DEBUG_KDGRAPH1 */ } scotch-6.0.4.dfsg/src/libscotch/library_graph_io_scot_f.c0000644002563400244210000001633711631447170026665 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_io_scot_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the Fortran API for the **/ /** graph i/o routines of the libSCOTCH **/ /** library. **/ /** **/ /** DATES : # Version 4.0 : from : 23 nov 2005 **/ /** to 23 nov 2005 **/ /** # Version 5.1 : from : 27 mar 2010 **/ /** to 27 mar 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the mapping routines. */ /* */ /**************************************/ /* String lengths are passed at the very ** end of the argument list. */ FORTRAN ( \ SCOTCHFGRAPHGEOMLOADSCOT, scotchfgraphgeomloadscot, ( \ SCOTCH_Graph * const grafptr, \ SCOTCH_Geom * const geomptr, \ const int * const filegrfptr, \ const int * const filegeoptr, \ const char * const dataptr, /* No use */ \ int * const revaptr, \ const int datanbr), \ (grafptr, geomptr, filegrfptr, filegeoptr, dataptr, revaptr, datanbr)) { FILE * filegrfstream; /* Streams to build from handles */ FILE * filegeostream; int filegrfnum; /* Duplicated handle */ int filegeonum; int o; if ((filegrfnum = dup (*filegrfptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFGRAPHGEOMLOADSCOT: cannot duplicate handle (1)"); *revaptr = 1; /* Indicate error */ return; } if ((filegeonum = dup (*filegeoptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFGRAPHGEOMLOADSCOT: cannot duplicate handle (2)"); close (filegrfnum); *revaptr = 1; /* Indicate error */ return; } if ((filegrfstream = fdopen (filegrfnum, "r")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFGRAPHGEOMLOADSCOT: cannot open input stream (1)"); close (filegrfnum); close (filegeonum); *revaptr = 1; return; } if ((filegeostream = fdopen (filegeonum, "r")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFGRAPHGEOMLOADSCOT: cannot open input stream (2)"); fclose (filegrfstream); close (filegeonum); *revaptr = 1; return; } o = SCOTCH_graphGeomLoadScot (grafptr, geomptr, filegrfstream, filegeostream, NULL); fclose (filegrfstream); /* This closes file descriptors too */ fclose (filegeostream); *revaptr = o; } /* String lengths are passed at the very ** end of the argument list. */ FORTRAN ( \ SCOTCHFGRAPHGEOMSAVESCOT, scotchfgraphgeomsavescot, ( \ const SCOTCH_Graph * const grafptr, \ const SCOTCH_Geom * const geomptr, \ const int * const filegrfptr, \ const int * const filegeoptr, \ const char * const dataptr, /* No use */ \ int * const revaptr, \ const int datanbr), \ (grafptr, geomptr, filegrfptr, filegeoptr, dataptr, revaptr, datanbr)) { FILE * filegrfstream; /* Streams to build from handles */ FILE * filegeostream; int filegrfnum; /* Duplicated handle */ int filegeonum; int o; if ((filegrfnum = dup (*filegrfptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFGRAPHGEOMSAVESCOT: cannot duplicate handle (1)"); *revaptr = 1; /* Indicate error */ return; } if ((filegeonum = dup (*filegeoptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFGRAPHGEOMSAVESCOT: cannot duplicate handle (2)"); close (filegrfnum); *revaptr = 1; /* Indicate error */ return; } if ((filegrfstream = fdopen (filegrfnum, "w")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFGRAPHGEOMSAVESCOT: cannot open output stream (1)"); close (filegrfnum); close (filegeonum); *revaptr = 1; return; } if ((filegeostream = fdopen (filegeonum, "w")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFGRAPHGEOMSAVESCOT: cannot open output stream (2)"); fclose (filegrfstream); close (filegeonum); *revaptr = 1; return; } o = SCOTCH_graphGeomSaveScot (grafptr, geomptr, filegrfstream, filegeostream, NULL); fclose (filegrfstream); /* This closes file descriptors too */ fclose (filegeostream); *revaptr = o; } scotch-6.0.4.dfsg/src/libscotch/hgraph.c0000644002563400244210000001176612370023010023246 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hgraph.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles the source graph **/ /** functions. **/ /** **/ /** DATES : # Version 4.0 : from : 17 jan 2002 **/ /** to 01 dec 2003 **/ /** # Version 5.0 : from : 19 dec 2006 **/ /** to 30 may 2008 **/ /** # Version 6.0 : from : 17 oct 2012 **/ /** to 04 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HGRAPH #include "module.h" #include "common.h" #include "graph.h" #include "hgraph.h" /****************************************/ /* */ /* These routines handle source graphs. */ /* */ /****************************************/ /* This routine initializes a source graph ** structure. ** It returns: ** - 0 : in all cases. */ int hgraphInit ( Hgraph * restrict const grafptr) { memSet (grafptr, 0, sizeof (Hgraph)); /* Initialize graph fields */ grafptr->s.flagval = GRAPHFREETABS; /* By default, free all arrays */ return (0); } /* This routine frees a source graph structure. ** It returns: ** - VOID : in all cases. */ void hgraphExit ( Hgraph * restrict const grafptr) { hgraphFree (grafptr); } /* This routine frees a source graph structure. ** It returns: ** - VOID : in all cases. */ void hgraphFree ( Hgraph * restrict const grafptr) { if ((grafptr->vnhdtax != NULL) && /* Free end vertex array for non-halo vertices */ ((grafptr->s.flagval & HGRAPHFREEVNHD) != 0)) memFree (grafptr->vnhdtax + grafptr->s.baseval); graphFree (&grafptr->s); /* Free graph data */ #ifdef SCOTCH_DEBUG_HGRAPH2 memSet (grafptr, ~0, sizeof (Hgraph)); /* Purge graph fields */ #endif /* SCOTCH_DEBUG_HGRAPH2 */ } /* This routine creates a non-halo graph from a ** halo graph. ** It returns: ** - VOID : in all cases. */ void hgraphUnhalo ( const Hgraph * restrict const grafptr, Graph * restrict const ugrfptr) { ugrfptr->flagval = grafptr->s.flagval & (GRAPHBITSUSED & ~GRAPHFREETABS); /* Remove extended graph class flags and do not allow freeing */ ugrfptr->baseval = grafptr->s.baseval; ugrfptr->vertnbr = grafptr->vnohnbr; ugrfptr->vertnnd = grafptr->vnohnnd; ugrfptr->verttax = grafptr->s.verttax; ugrfptr->vendtax = grafptr->vnhdtax; ugrfptr->velotax = grafptr->s.velotax; ugrfptr->velosum = grafptr->vnlosum; ugrfptr->vnumtax = grafptr->s.vnumtax; ugrfptr->vlbltax = NULL; ugrfptr->edgenbr = grafptr->enohnbr; ugrfptr->edgetax = grafptr->s.edgetax; ugrfptr->edlotax = grafptr->s.edlotax; ugrfptr->edlosum = grafptr->enohsum; ugrfptr->degrmax = grafptr->s.degrmax; /* Upper bound */ } scotch-6.0.4.dfsg/src/libscotch/graph_list.c0000644002563400244210000002003111631447171024133 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : graph_list.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles the source graph **/ /** vertex lists functions. **/ /** **/ /** DATES : # Version 0.0 : from : 01 dec 1992 **/ /** to 18 may 1993 **/ /** # Version 1.3 : from : 30 apr 1994 **/ /** to 18 may 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to 31 oct 1994 **/ /** # Version 3.0 : from : 07 jul 1995 **/ /** to 28 sep 1995 **/ /** # Version 3.1 : from : 28 nov 1995 **/ /** to 08 jun 1996 **/ /** # Version 3.2 : from : 07 sep 1996 **/ /** to 15 sep 1998 **/ /** # Version 4.0 : from : 10 dec 2001 **/ /** to 10 dec 2001 **/ /** # Version 5.1 : from : 11 aug 2010 **/ /** to 11 aug 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GRAPH_LIST #include "module.h" #include "common.h" #include "graph.h" /********************************/ /* */ /* These routines handle vertex */ /* number lists. */ /* */ /********************************/ /* This routine creates a vertex number list. ** It returns: ** - 0 : in all cases. */ int listInit ( VertList * listptr) { listptr->vnumnbr = 0; /* Initialize list fields */ listptr->vnumtab = NULL; return (0); } /* This routine deletes the given vertex number list. ** It returns: ** - VOID : in all cases. */ void listExit ( VertList * listptr) { if (listptr->vnumtab != NULL) memFree (listptr->vnumtab); /* Free vertex list array */ #ifdef SCOTCH_DEBUG_GRAPH2 memSet (listptr, 0, sizeof (VertList)); /* Purge list fields */ #endif /* SCOTCH_DEBUG_GRAPH2 */ } /* This routine allocates a vertex ** number list array. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int listAlloc ( VertList * listptr, Gnum vnumnbr) { if (vnumnbr == listptr->vnumnbr) /* If array is already dimensioned */ return (0); /* Keep it as it is */ listFree (listptr); /* Free vertex array */ if (vnumnbr > 0) { /* Reallocate vertex space */ if ((listptr->vnumtab = (Gnum *) memAlloc (vnumnbr * sizeof (Gnum))) == NULL) { errorPrint ("listAlloc: out of memory"); return (1); } listptr->vnumnbr = vnumnbr; } return (0); } /* This routine frees a vertex ** number list array. ** It returns: ** - 0 : in all cases. */ int listFree ( VertList * listptr) { if (listptr->vnumtab != NULL) /* Free vertex list array */ memFree (listptr->vnumtab); listptr->vnumnbr = 0; /* Reset list values */ listptr->vnumtab = NULL; return (0); } /* These routines load a vertex number list ** from the given stream. Because of the search ** for duplicates, the list read is always ** sorted by ascending order. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int listLoad ( VertList * listptr, FILE * stream) { Gnum vnumnbr; Gnum vnumnum; if (intLoad (stream, &vnumnbr) != 1) { /* Read number of vertices */ errorPrint ("listLoad: bad input (1)"); return (1); } if (listAlloc (listptr, vnumnbr) != 0) { /* Allocate vertex space */ errorPrint ("listLoad: out of memory"); return (1); } for (vnumnum = 0; vnumnum < vnumnbr; vnumnum ++) { /* Read vertex list contents */ if (intLoad (stream, &listptr->vnumtab[vnumnum]) != 1) { errorPrint ("listLoad: bad input (2)"); return (1); } } listSort (listptr); /* Sort vertex list by ascending order */ for (vnumnum = 1; vnumnum < vnumnbr; vnumnum ++) { /* Search list for duplicates */ if (listptr->vnumtab[vnumnum] == listptr->vnumtab[vnumnum - 1]) { errorPrint ("listLoad: duplicate vertex numbers"); return (1); } } return (0); } /* This routine sorts a vertex list ** by ascending order. ** It returns: ** - VOID : in all cases. */ void listSort ( VertList * listptr) { intSort1asc1 (listptr->vnumtab, listptr->vnumnbr); } /* This routine saves a vertex number list ** to the given stream. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int listSave ( VertList * listptr, FILE * stream) { Gnum vnumnum; int o; o = (intSave (stream, listptr->vnumnbr) == 0); /* Write number of vertices */ for (vnumnum = 0; (o == 0) && (vnumnum < listptr->vnumnbr); vnumnum ++) { o = (fprintf (stream, "%c" GNUMSTRING, ((vnumnum % 8) == 0) ? '\n' : '\t', (Gnum) listptr->vnumtab[vnumnum]) == EOF); } o |= (fprintf (stream, "\n") == EOF); if (o != 0) errorPrint ("listSave: bad output"); return (o); } /* This routine copies the contents ** of a vertex list into another. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int listCopy ( VertList * dstlistptr, /* Destination list */ VertList * srclistptr) /* Source list */ { if (listAlloc (dstlistptr, dstlistptr->vnumnbr) != 0) { /* Allocate vertex space */ errorPrint ("listCopy: out of memory"); return (1); } memCpy (dstlistptr->vnumtab, /* Copy list data */ srclistptr->vnumtab, srclistptr->vnumnbr * sizeof (Gnum)); return (0); } scotch-6.0.4.dfsg/src/libscotch/dgraph_build.h0000644002563400244210000000671311631447170024442 0ustar trophimeutilisateurs du domaine/* Copyright 2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /**********************************************************/ /* */ /* NAME : dgraph_build.h */ /* */ /* AUTHOR : Francois PELLEGRINI */ /* Francois CHATENET (P0.0) */ /* Sebastien FOUCAULT (P0.0) */ /* Nicolas GICQUEL (P0.1) */ /* Jerome LACOSTE (P0.1) */ /* */ /* FUNCTION : Part of a parallel static mapper. */ /* These lines are the data declarations */ /* for the distributed source graph */ /* building routines. */ /* */ /* # Version P0.1 : from : 01 apr 1997 */ /* to 13 sep 2006 */ /* # Version 5.0 : from : 22 dec 2006 */ /* to 22 dec 2006 */ /* */ /**********************************************************/ /* ** The type and structure definitions. */ /* Sort structure for local vertices. First element used for intSort2asc1. */ typedef struct DgraphLablSortVert_ { Gnum vlblglbnum; /* Global vertex label: FIRST */ Gnum vertlocnum; /* Index in local vertex array */ } DgraphLablSortVert; /* Sort structure for local edges. */ typedef struct DgraphLablSortEdge_ { Gnum vlblglbnum; /* Global vertex label */ Gnum edgelocnum; /* Index of local edge */ } DgraphLablSortEdge; scotch-6.0.4.dfsg/src/libscotch/mapping.h0000644002563400244210000002047612405403704023446 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mapping.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : These lines are the declarations for **/ /** the mapping handling routines. **/ /** **/ /** DATES : # Version 0.0 : from : 15 dec 1992 **/ /** to 01 apr 1993 **/ /** # Version 1.0 : from : 04 oct 1993 **/ /** to 06 oct 1993 **/ /** # Version 1.1 : from : 15 oct 1993 **/ /** to 15 oct 1993 **/ /** # Version 1.3 : from : 09 apr 1994 **/ /** to 11 may 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to 02 nov 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to 18 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 04 jul 1995 **/ /** # Version 3.1 : from : 30 oct 1995 **/ /** to 06 jun 1996 **/ /** # Version 3.2 : from : 23 aug 1996 **/ /** to 26 may 1998 **/ /** # Version 3.3 : from : 19 oct 1998 **/ /** to 30 mar 1999 **/ /** # Version 4.0 : from : 11 dec 2001 **/ /** to 13 nov 2005 **/ /** # Version 5.1 : from : 25 jun 2008 **/ /** to 04 nov 2010 **/ /** # Version 6.0 : from : 03 mar 2011 **/ /** to 14 sep 2014 **/ /** **/ /** NOTES : # While Anum and Gnum are different **/ /** types, because architectures are **/ /** most often much smaller than **/ /** than graphs and require smaller **/ /** integer ranges, for interface **/ /** consistency reasons as well as for **/ /** variable-sized architecture handling, **/ /** they will always amount to the same **/ /** type. **/ /** **/ /************************************************************/ #define MAPPING_H /* ** The defines. */ /*+ Prime number for hashing terminal domain numbers. +*/ #define MAPPINGHASHPRIME 17 /*+ Prime number for hashing +*/ /*+ Graph option flags. +*/ #define MAPPINGNONE 0x0000 /* No options set */ #define MAPPINGFREEPART 0x0001 /* Free partition array */ #define MAPPINGFREEDOMN 0x0002 /* Free domain array */ /* ** The type definitions. */ /*+ This structure defines an (eventually partial) mapping of a source graph to a target architecture. +*/ typedef struct Mapping_ { int flagval; /*+ Mapping properties +*/ const Graph * grafptr; /*+ Graph data +*/ const Arch * archptr; /*+ Architecture data +*/ Anum * parttax; /*+ Mapping array [vertnbr] +*/ ArchDom * domntab; /*+ Array of domains [domnmax] +*/ Anum domnnbr; /*+ Current number of domains +*/ Anum domnmax; /*+ Maximum number of domains +*/ ArchDom domnorg; /*+ Initial (sub)domain +*/ } Mapping; /*+ The target architecture sort structure, used to sort vertices by increasing label value. +*/ typedef struct MappingHash_ { Anum termnum; /*+ Terminal vertex number +*/ Anum domnnum; /*+ Domain number +*/ } MappingHash; /*+ The target architecture sort structure, used to sort vertices by increasing label value. +*/ typedef struct MappingSort_ { Anum labl; /*+ Target architecture vertex label +*/ Anum peri; /*+ Inverse permutation +*/ } MappingSort; /* ** The function prototypes. */ void mapExit (Mapping * const); #ifndef MAPPING #define static #endif void mapInit (Mapping * restrict const, const Graph * restrict const, const Arch * restrict const, const ArchDom * restrict const); void mapInit2 (Mapping * restrict const, const Graph * restrict const, const Arch * restrict const, const ArchDom * restrict const, const Anum, const Anum); void mapExit (Mapping * const); int mapAlloc (Mapping * const); void mapFree (Mapping * const); int mapResize (Mapping * restrict const, const Anum); int mapResize2 (Mapping * restrict const, const Anum); int mapCopy (Mapping * const, const Mapping * const); void mapFrst (Mapping * const); int mapBuild (Mapping * restrict const, const Anum * restrict const); int mapMerge (Mapping * restrict const, const Anum * restrict const); void mapTerm (const Mapping * restrict const, Anum * restrict const); int mapLoad (Mapping * restrict const, const Gnum * restrict const, FILE * restrict const); int mapSave (const Mapping * restrict const, FILE * restrict const); int mapView (const Mapping * restrict const, const Graph * restrict const, FILE * const); #undef static /* ** The macro definitions. */ #define mapDomain(map,idx) (&((map)->domntab[(map)->parttax[(idx)]])) scotch-6.0.4.dfsg/src/libscotch/kgraph_band.c0000644002563400244210000007726412474554132024265 0ustar trophimeutilisateurs du domaine/* Copyright 2009-2011,2013-2015 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph_band.c **/ /** **/ /** AUTHOR : Sebastien FOURESTIER (v6.0) **/ /** Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module computes a k-way band **/ /** graph from the given frontier **/ /** array. **/ /** **/ /** DATES : # Version 6.0 : from : 05 jan 2009 **/ /** to : 01 mar 2015 **/ /** **/ /** NOTES : # This code derives from the code of **/ /** kdgraph_band.c in version 5.2 for **/ /** direct k-way partitioning. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define KGRAPH_BAND #include "module.h" #include "common.h" #include "arch.h" #include "graph.h" #include "mapping.h" #include "kgraph.h" #include "kgraph_band.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine computes a index array of given ** width around the current separator. ** It returns: ** - 0 : if the index array could be computed. ** - !0 : on error. */ int kgraphBand ( Kgraph * restrict const grafptr, /*+ Pointer to original graph +*/ const Gnum distmax, /*+ Maximum distance from separator vertices +*/ Kgraph * restrict const bandgrafptr, /*+ Pointer to band graph structure to fill +*/ Gnum * const bandvertlvlptr, /*+ Pointer to based start index of last level +*/ Gnum * restrict * restrict const bandvnumptr) /*+ Pointer to bandvnumtax +*/ { Gnum bandvertnbr; /* Number of band vertices (including anchor vertices) */ Gnum bandvertnnd; /* Based end of band vertex array (without anchor vertices) */ Gnum bandvertnum; Gnum * restrict bandverttax; Gnum * restrict bandvelotax; Gnum * restrict bandvmlotax; Gnum * restrict bandvnumtax; /* Original numbers of vertices in band graph */ #define bandedgetab bandcompload /* TRICK: use delta array to compute edge offsets */ Gnum * restrict bandedgetax; Gnum * restrict bandedlotax; Gnum * restrict bandeeextab; Gnum bandedgenbr; Gnum bandedgenum; Gnum banddegrmax; Gnum * restrict bandfrontab; Anum * restrict bandparttax; Anum * restrict bandparotax; Gnum bandvfixnbr; Gnum bandvertlvlnum; /* Index of first band vertex belonging to last level */ Gnum bandvertancadj; /* Flag set when anchor(s) represent inexistent vertices */ Gnum * restrict vnumotbdtax; /* Original to band graph vertex numbers (~0 if not in band graph, -2 for fixed vertices) */ Gnum * restrict bandanlotab; /* Temporary array to store loads to anchors */ Gnum bandedlonbr; /* Size of local band edge load array */ Gnum bandedlosum; Gnum * restrict bandcompload; Gnum bandcommload; Gnum * restrict compload; /* Load of parts in original graph */ Gnum fronnum; Anum domnnbr; Anum domnnum; Gnum veloval; Gnum vertnum; Gnum vfixnum; Gnum vfixflag; KgraphBandHash * restrict termhashtab; Anum termhashmsk; const Gnum * restrict const verttax = grafptr->s.verttax; const Gnum * restrict const vendtax = grafptr->s.vendtax; const Gnum * restrict const velotax = grafptr->s.velotax; const Gnum * restrict const edgetax = grafptr->s.edgetax; const Gnum * restrict const edlotax = grafptr->s.edlotax; const Gnum * restrict const frontab = grafptr->frontab; const Gnum * restrict const pfixtax = grafptr->pfixtax; const Anum * restrict const parttax = grafptr->m.parttax; const Anum * restrict const parotax = grafptr->r.m.parttax; const Gnum * restrict const vmlotax = grafptr->r.vmlotax; if (graphBand (&grafptr->s, grafptr->fronnbr, grafptr->frontab, distmax, &vnumotbdtax, &bandvertlvlnum, &bandvertnbr, &bandedgenbr, pfixtax, &bandvfixnbr) != 0) { /* Get vertices to keep in band graph */ errorPrint ("kgraphBand: cannot number graph vertices"); return (1); } if (bandvertlvlptr != NULL) *bandvertlvlptr = bandvertlvlnum; domnnbr = grafptr->m.domnnbr; termhashtab = NULL; bandanlotab = NULL; bandeeextab = NULL; if (pfixtax != NULL) { /* Fixed vertices may be neighbors of band graph vertices and may not belong to the band graph */ Anum termhashsiz; const Arch * restrict const tgtarchptr = grafptr->m.archptr; for (termhashsiz = 0, termhashmsk = domnnbr; termhashmsk != 0; termhashsiz ++, termhashmsk >>= 1) ; /* Get upper power of two */ termhashsiz = 1 << (termhashsiz + 2); /* Fill hash table at 25% maximum */ termhashmsk = termhashsiz - 1; if (memAllocGroup ((void **) (void *) /* Allocation and initialization of fixed vertices temporary arrays */ &termhashtab, (size_t) (termhashsiz * sizeof (KgraphBandHash)), &bandanlotab, (size_t) (domnnbr * sizeof (Gnum)), &bandeeextab, (size_t) (domnnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("kgraphBand: out of memory (1)"); return (1); } memSet (termhashtab, ~0, termhashsiz * sizeof (KgraphBandHash)); memSet (bandanlotab, 0, domnnbr * sizeof (Gnum)); /* Assume there are no extra loads to anchors */ memSet (bandeeextab, 0, domnnbr * sizeof (Gnum)); for (domnnum = 0; domnnum < domnnbr; domnnum ++) { ArchDom * domnptr; domnptr = &grafptr->m.domntab[domnnum]; if (archDomSize (tgtarchptr, domnptr) == 1) { /* If domain is terminal */ Gnum termhashnum; Anum termnum; termnum = archDomNum (tgtarchptr, domnptr); /* Get terminal domain number */ for (termhashnum = (termnum * KGRAPHBANDHASHPRIME) & termhashmsk; ; termhashnum = (termhashnum + 1) & termhashmsk) { if (termhashtab[termhashnum].termnum == ~0) { /* If hash slot empty */ termhashtab[termhashnum].termnum = termnum; /* Create slot */ termhashtab[termhashnum].domnnum = domnnum; break; } #ifdef SCOTCH_DEBUG_KGRAPH2 if (termhashtab[termhashnum].termnum == termnum) { /* If hash slot found */ errorPrint ("kgraphBand: duplicate terminal domain in domain array"); memFree (termhashtab); kgraphExit (bandgrafptr); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ } } } } bandedgenbr += 2 * (bandvertnbr + grafptr->s.baseval - bandvertlvlnum) + /* Add edges to and from anchors */ grafptr->s.degrmax * grafptr->vfixnbr; /* A band graph vertex that is the neighbour of a fixed vertex will get an extra edge, even if the fixed vertex is not in the band graph */ bandvertnbr += domnnbr; /* Add anchor vertices */ bandedlonbr = ((edlotax != NULL) || (pfixtax != NULL)) ? bandedgenbr : 0; graphInit (&bandgrafptr->s); bandgrafptr->s.flagval = GRAPHFREETABS | GRAPHVERTGROUP | GRAPHEDGEGROUP | /* Arrays created by the routine itself */ KGRAPHFREEFRON | KGRAPHFREECOMP | KGRAPHHASANCHORS; bandgrafptr->s.baseval = grafptr->s.baseval; bandgrafptr->s.vertnbr = bandvertnbr; bandgrafptr->s.vertnnd = bandvertnbr + bandgrafptr->s.baseval; /* With anchor vertices */ bandgrafptr->a = grafptr->a; mapInit2 (&bandgrafptr->m, &bandgrafptr->s, &bandgrafptr->a, &grafptr->m.domnorg, grafptr->m.domnmax, grafptr->m.domnnbr); mapInit2 (&bandgrafptr->r.m, &bandgrafptr->s, &bandgrafptr->a, &grafptr->m.domnorg, grafptr->r.m.domnmax, grafptr->r.m.domnnbr); bandgrafptr->r.m.domntab = grafptr->r.m.domntab; /* Band old mapping domain array is a clone of old mapping (no freeing) */ bandgrafptr->r.m.domnnbr = grafptr->r.m.domnnbr; bandgrafptr->r.crloval = grafptr->r.crloval; bandgrafptr->r.cmloval = grafptr->r.cmloval; bandgrafptr->r.vmlotax = NULL; bandgrafptr->vfixnbr = 0; /* Band graphs do not have fixed vertices */ bandgrafptr->pfixtax = NULL; bandgrafptr->frontab = NULL; /* Frontier array not yet allocated */ bandgrafptr->comploadavg = NULL; /* Computation load arrays not yet allocated */ bandgrafptr->comploaddlt = NULL; bandgrafptr->commload = grafptr->commload; /* Communication load is preserved */ bandgrafptr->kbalval = grafptr->kbalval; bandgrafptr->levlnum = grafptr->levlnum; if (memAllocGroup ((void **) (void *) /* Allocate graph data */ &bandgrafptr->s.verttax, (size_t) ((bandvertnbr + 1) * sizeof (Gnum)), /* Compact vertex array */ &bandgrafptr->s.velotax, (size_t) (bandvertnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("kgraphBand: out of memory (2)"); return (1); } if ((bandvnumtax = memAlloc ((bandvertnbr) * sizeof (Gnum))) == NULL) { /* Allocate alone since it is an output */ errorPrint ("kgraphBand: out of memory (3)"); return (1); } if (vmlotax != NULL) { if ((bandvmlotax = memAlloc (bandvertnbr * sizeof (Gnum))) == NULL) { errorPrint ("kgraphBand: out of memory (4)"); return (1); } memSet (bandvnumtax + bandvertnbr - domnnbr, ~0, domnnbr * sizeof (Gnum)); /* Prevent Valgrind from yelling when centralizing band graphs */ bandvmlotax -= bandgrafptr->s.baseval; bandgrafptr->r.vmlotax = bandvmlotax; bandgrafptr->s.flagval |= KGRAPHFREEVMLO; } if (parotax != NULL) { if ((bandparotax = memAlloc (bandvertnbr * sizeof (Gnum))) == NULL) { errorPrint ("kgraphBand: out of memory (5)"); return (1); } memSet (bandparotax + bandvertnbr - bandgrafptr->r.m.domnnbr, ~0, bandgrafptr->r.m.domnnbr * sizeof (Gnum)); /* Prevent Valgrind from yelling when centralizing band graphs */ bandparotax -= bandgrafptr->s.baseval; bandgrafptr->r.m.parttax = bandparotax; bandgrafptr->r.m.flagval |= MAPPINGFREEPART; } bandgrafptr->s.verttax -= bandgrafptr->s.baseval; bandvnumtax -= bandgrafptr->s.baseval; bandgrafptr->s.velotax -= bandgrafptr->s.baseval; if ((bandgrafptr->s.edgetax = memAlloc ((bandedgenbr + bandedlonbr) * sizeof (Gnum))) == NULL) { errorPrint ("kgraphBand: out of memory (6)"); return (1); } bandedlotax = NULL; bandedgetax = bandgrafptr->s.edgetax -= bandgrafptr->s.baseval; if ((edlotax != NULL) || (pfixtax != NULL)) { bandgrafptr->s.edlotax = bandedlotax = bandedgetax + bandedgenbr; } if (((bandgrafptr->frontab = memAlloc (bandvertnbr * sizeof (Gnum))) == NULL) || /* Allocation and initialization of imbalance arrays */ (memAllocGroup ((void **) (void *) &bandgrafptr->comploadavg, (size_t) ((domnnbr + 2) * sizeof (Gnum)), /* TRICK: always keep two slots for collective communication */ &bandgrafptr->comploaddlt, (size_t) ((domnnbr + 2) * sizeof (Gnum)), NULL) == NULL)) { errorPrint ("kgraphBand: out of memory (7)"); if (bandgrafptr->frontab != NULL) memFree (bandgrafptr->frontab); return (1); } bandfrontab = bandgrafptr->frontab; if ((bandparttax = memAlloc (bandvertnbr * sizeof (Anum))) == NULL) { errorPrint ("kgraphBand: out of memory (8)"); return (1); } bandgrafptr->m.parttax = bandparttax -= bandgrafptr->s.baseval; if ((bandgrafptr->m.domntab = memAlloc (domnnbr * sizeof (ArchDom))) == NULL) { errorPrint ("kgraphBand: out of memory (9)"); return (1); } bandgrafptr->m.flagval |= MAPPINGFREEDOMN; #ifdef SCOTCH_DEBUG_KGRAPH2 memSet (bandvnumtax + bandgrafptr->s.baseval, ~0, (bandvertnbr * sizeof (Gnum))); #endif /* SCOTCH_DEBUG_KGRAPH2 */ vfixnum = 0; for (fronnum = 0, bandvertnum = bandgrafptr->s.baseval; fronnum < grafptr->fronnbr; fronnum ++) { /* Turn all graph frontier vertices into band frontier vertices */ Gnum vertnum; vertnum = frontab[fronnum]; if ((pfixtax != NULL) && (pfixtax[vertnum] != -1)) /* It is a fixed vertex */ vfixnum ++; else { bandfrontab[bandvertnum - bandgrafptr->s.baseval] = bandvertnum; /* All frontier vertices are first vertices of band graph */ bandvnumtax[bandvertnum] = vertnum; bandvertnum ++; } } bandgrafptr->fronnbr = grafptr->fronnbr - vfixnum; /* Remove fixed vertices from frontier */ for (bandvertnnd = bandvertnbr + bandgrafptr->s.baseval - domnnbr; /* Pick selected band vertices from rest of frontier array without anchors */ bandvertnum < bandvertnnd + bandvfixnbr - vfixnum; fronnum ++) { Gnum vertnum; vertnum = frontab[fronnum]; if ((pfixtax != NULL) && (pfixtax[vertnum] != -1)) /* It is a fixed vertex */ vfixnum ++; else { bandvnumtax[bandvertnum] = vertnum; bandvertnum ++; } } #ifdef SCOTCH_DEBUG_KGRAPH2 if (vfixnum != bandvfixnbr) { errorPrint ("kgraphBand: internal error (1)"); /* All fixed vertices indices must be at the beginning of frontab */ return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ memSet (bandvnumtax + bandvertnnd, ~0, domnnbr * sizeof (Gnum)); /* Prevent Valgrind from yelling when centralizing band graphs */ bandverttax = bandgrafptr->s.verttax; bandvelotax = bandgrafptr->s.velotax; banddegrmax = 0; bandcommload = 0; bandcompload = bandgrafptr->comploaddlt; /* TRICK: use delta array to compute load sums */ memSet (bandcompload, 0, domnnbr * sizeof (Gnum)); bandedlosum = 0; vfixflag = 0; for (bandvertnum = bandedgenum = bandgrafptr->s.baseval; /* Build vertex array of band graph */ bandvertnum < bandvertlvlnum; bandvertnum ++) { /* For all vertices that do not belong to the last level */ Gnum vertnum; Gnum edgenum; Anum partval; Gnum degrval; vertnum = bandvnumtax[bandvertnum]; if (vfixflag == 1) { /* Last vertex had neighbours fixed vertices */ memSet (bandanlotab, 0, domnnbr * sizeof (Gnum)); /* Reset loads to anchors */ vfixflag = 0; /* Guess that these are no extra loads to anchors */ } if (vmlotax != NULL) bandvmlotax[bandvertnum] = vmlotax[vertnum]; if (parotax != NULL) bandparotax[bandvertnum] = parotax[vertnum]; partval = parttax[vertnum]; #ifdef SCOTCH_DEBUG_KGRAPH2 if ((partval < 0) || (partval >= domnnbr)) { errorPrint ("kgraphBand: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ bandparttax[bandvertnum] = partval; bandverttax[bandvertnum] = bandedgenum; veloval = (velotax != NULL) ? velotax[vertnum] : 1; bandcompload[partval] += veloval; /* Sum vertex load for each part */ bandvelotax[bandvertnum] = veloval; degrval = vendtax[vertnum] - verttax[vertnum]; if (banddegrmax < degrval) banddegrmax = degrval; for (edgenum = verttax[vertnum]; /* For all original edges */ edgenum < vendtax[vertnum]; edgenum ++) { Gnum vertend; vertend = edgetax[edgenum]; #ifdef SCOTCH_DEBUG_KGRAPH2 if (vnumotbdtax[vertend] == -1) { /* All ends should belong to the band graph too */ errorPrint ("kgraphBand: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ if (bandedlotax != NULL) { /* If graph has edge weights (always true when fixed vertices present) */ Gnum edloval; Gnum termnum; edloval = (edlotax == NULL) ? 1 : edlotax[edgenum]; if ((pfixtax != NULL) && ((termnum = pfixtax[vertend]) >= 0)) { /* If end vertex is fixed */ Gnum termhashnum; for (termhashnum = (termnum * KGRAPHBANDHASHPRIME) & termhashmsk; ; termhashnum = (termhashnum + 1) & termhashmsk) { if (termhashtab[termhashnum].termnum == termnum) { /* If hash slot found */ bandanlotab[termhashtab[termhashnum].domnnum] += edloval; vfixflag = 1; /* Vertex have some end vertices fixed */ break; } #ifdef SCOTCH_DEBUG_KGRAPH2 if (termhashtab[termhashnum].termnum == ~0) { /* If hash slot not found */ errorPrint ("kgraphBand: missing terminal domain in domain array (1)"); memFree (termhashtab); kgraphExit (bandgrafptr); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ } } else { /* End vertex is not fixed */ bandedlosum += edloval; bandedlotax[bandedgenum] = edloval; bandedgetax[bandedgenum ++] = vnumotbdtax[vertend]; } } else bandedgetax[bandedgenum ++] = vnumotbdtax[vertend]; } if (vfixflag == 1) { /* If vertex has at least one neighbours that is fixed */ Gnum edloval; edloval = 0; for (domnnum = 0; domnnum < domnnbr; domnnum ++) { /* Traverse bandanlotab to handle loads to anchors */ if (bandanlotab[domnnum] != 0) /* Fixed neighbours are linked to this domain */ edloval += bandanlotab[domnnum]; /* Add load induced by edges to fixed vertices */ if (edloval != 0) { /* We have to add an edge to the anchor */ Gnum degrval; bandedlotax[bandedgenum] = edloval; bandedlosum += edloval; bandedgetax[bandedgenum ++] = bandvertnnd + domnnum; /* Add edge to anchor of proper part */ bandeeextab[domnnum] ++; /* One more extra edge to the anchor */ degrval = bandedgenum - bandverttax[bandvertnum]; if (banddegrmax < degrval) banddegrmax = degrval; edloval = 0; } } } } for ( ; bandvertnum < bandvertnnd; bandvertnum ++) { /* For all vertices that belong to the last level except anchors */ Gnum vertnum; Gnum edgenum; Anum partval; vertnum = bandvnumtax[bandvertnum]; if (vfixflag == 1) { /* Last vertex had neighbours fixed vertices */ memSet (bandanlotab, 0, domnnbr * sizeof (Gnum)); /* Reset loads to anchors */ vfixflag = 0; /* Guess that these are no extra loads to anchors */ } if (vmlotax != NULL) bandvmlotax[bandvertnum] = vmlotax[vertnum]; if (parotax != NULL) bandparotax[bandvertnum] = parotax[vertnum]; partval = parttax[vertnum]; #ifdef SCOTCH_DEBUG_KGRAPH2 if ((partval < 0) || (partval >= domnnbr)) { errorPrint ("kgraphBand: internal error (4)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ bandparttax[bandvertnum] = partval; bandverttax[bandvertnum] = bandedgenum; veloval = (velotax != NULL) ? velotax[vertnum] : 1; bandcompload[partval] += veloval; /* Sum vertex load for each part */ bandvelotax[bandvertnum] = veloval; for (edgenum = verttax[vertnum]; /* For all original edges */ edgenum < vendtax[vertnum]; edgenum ++) { Gnum vertend; Gnum bandvertend; vertend = edgetax[edgenum]; bandvertend = vnumotbdtax[vertend]; if (bandedlotax != NULL) { /* If graph has edge weights, copy load */ Gnum edloval; Gnum termnum; edloval = (edlotax == NULL) ? 1 : edlotax[edgenum]; if ((pfixtax != NULL) && ((termnum = pfixtax[vertend]) >= 0)) { /* If end vertex is fixed */ Gnum termhashnum; for (termhashnum = (termnum * KGRAPHBANDHASHPRIME) & termhashmsk; ; termhashnum = (termhashnum + 1) & termhashmsk) { if (termhashtab[termhashnum].termnum == termnum) { /* If hash slot found */ bandanlotab[termhashtab[termhashnum].domnnum] += edloval; vfixflag = 1; /* Vertex have some end vertices fixed */ break; } #ifdef SCOTCH_DEBUG_KGRAPH2 if (termhashtab[termhashnum].termnum == ~0) { /* If hash slot not found */ errorPrint ("kgraphBand: missing terminal domain in domain array (2)"); memFree (termhashtab); kgraphExit (bandgrafptr); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ } } else if (bandvertend >= 0) { /* If end vertex is not fixed and in the band graph */ bandedlosum += edloval; bandedlotax[bandedgenum] = edloval; } } if (bandvertend >= 0) /* If end vertex is not fixed and in the band graph */ bandedgetax[bandedgenum ++] = vnumotbdtax[vertend]; } if (vfixflag == 1) { /* If vertex has at least one fixed neighbor */ Gnum edloval; for (domnnum = 0; domnnum < domnnbr; domnnum ++) { /* Traverse bandanlotab to handle loads to anchors */ edloval = 0; if (domnnum == partval) /* The current vertex is mapped to current domain */ edloval += 1; /* Add basic edge load to anchor */ if (bandanlotab[domnnum] != 0) /* Fixed neighbours are linked to this domain */ edloval += bandanlotab[domnnum]; /* Add load induced by edges to fixed vertices */ if (edloval != 0) { /* We have to add an edge to the anchor */ Gnum degrval; bandedlotax[bandedgenum] = edloval; bandedlosum += edloval; bandedgetax[bandedgenum ++] = bandvertnnd + domnnum; /* Add edge to anchor of proper part */ if (domnnum != partval) bandeeextab[domnnum] ++; /* One more extra edge to the anchor */ degrval = bandedgenum - bandverttax[bandvertnum]; if (banddegrmax < degrval) banddegrmax = degrval; edloval = 0; } } } else { Gnum degrval; if (bandedlotax != NULL) { /* If graph has edge weights */ bandedlotax[bandedgenum] = 1; /* Edge to anchor has load 1 */ bandedlosum ++; } bandedgetax[bandedgenum ++] = bandvertnnd + partval; /* Add edge to anchor of proper part */ degrval = bandedgenum - bandverttax[bandvertnum]; if (banddegrmax < degrval) banddegrmax = degrval; } } memFree (vnumotbdtax + bandgrafptr->s.baseval); /* Free useless space */ compload = bandgrafptr->comploadavg; /* Use average array to store actual part loads */ memSet (compload, 0, domnnbr * sizeof (Gnum)); for (vertnum = grafptr->s.baseval; vertnum < grafptr->s.vertnnd; vertnum ++) compload[parttax[vertnum]] += (velotax != NULL) ? velotax[vertnum] : 1; for (domnnum = 0, bandvertancadj = 0; domnnum < domnnbr; domnnum ++) { /* For all anchors */ Gnum bandveloval; bandveloval = compload[domnnum] - bandcompload[domnnum]; /* Get load of anchor */ bandparttax[bandvertnnd + domnnum] = domnnum; /* Set parts of anchor vertices */ bandvelotax[bandvertnnd + domnnum] = bandveloval; if (bandveloval == 0) bandvertancadj = 1; } if (bandvertancadj == 1) /* Anchors have to be adjusted */ for (domnnum = 0; domnnum < domnnbr; domnnum ++) /* Increase weight of all anchors to keep balance */ bandvelotax[bandvertnnd + domnnum] ++; bandverttax[bandvertnum] = bandedgenum; /* Fill last element without anchors */ if (pfixtax != NULL) memCpy (bandedgetab, bandeeextab, domnnbr * sizeof (Gnum)); else memSet (bandedgetab, 0, domnnbr * sizeof (Gnum)); for (bandvertnum = bandvertlvlnum; bandvertnum < bandvertnnd; bandvertnum ++) bandedgetab[bandparttax[bandvertnum]] ++; /* Fill array of anchors' degrees */ for (domnnum = 0; domnnum < domnnbr; domnnum ++) { /* Set bandverttax for anchors vertices and pre-set bandedgetab */ Gnum degrval; /* to be able to quickly fill bandedgetax in next loop */ Gnum dispval; degrval = bandedgetab[domnnum]; dispval = bandverttax[bandvertnnd + domnnum]; if (banddegrmax < degrval) /* Update maximum degree value */ banddegrmax = degrval; bandverttax[bandvertnnd + domnnum + 1] = dispval + degrval; bandedgetab[domnnum] = dispval; /* Start index for edges to vertices of last layer */ } if (pfixtax != NULL) { /* We have fixed vertices */ memFree (termhashtab); /* Free group leader */ for (bandvertnum = bandgrafptr->s.baseval, bandedgenum = 0; bandvertnum < bandvertnnd; bandvertnum ++) { /* Link anchors to vertices */ for ( ; bandedgenum < bandverttax[bandvertnum + 1]; bandedgenum ++) { Gnum bandvertend; bandvertend = bandedgetax[bandedgenum]; if (bandvertend >= bandvertnnd) { /* If it is an edge to an anchor */ Gnum partval; /* Add the symmetric edge from the anchor */ Gnum edloval; partval = bandvertend - bandvertnnd; edloval = bandedlotax[bandedgenum]; bandedlotax[bandedgetab[partval]] = edloval; bandedlosum += edloval; bandedgetax[bandedgetab[partval] ++] = bandvertnum; } } } } else { if (bandedlotax != NULL) { /* If graph has edge weights */ Gnum edgenum; Gnum edgennd; for (bandvertnum = bandgrafptr->s.baseval; /* For all vertices not belonging to last level */ bandvertnum < bandvertlvlnum; bandvertnum ++) { Gnum vertnum; Gnum bandedgenum; vertnum = bandvnumtax[bandvertnum]; bandedgenum = bandverttax[bandvertnum]; memCpy (&bandedlotax[bandedgenum], &edlotax[verttax[vertnum]], /* Copy edge load array */ (bandverttax[bandvertnum + 1] - bandedgenum) * sizeof (Gnum)); } /* Vertices of last level have been processed before */ for (edgenum = bandverttax[bandvertnnd], /* Loads of anchor edges are all 1's too */ edgennd = bandverttax[bandvertnnd + domnnbr]; edgenum < edgennd; edgenum ++) bandedlotax[edgenum] = 1; } for (bandvertnum = bandvertlvlnum; bandvertnum < bandvertnnd; /* We do not have fixed vertices */ bandvertnum ++) { /* Link anchors to vertices of last level */ Anum partval; Gnum vertnum; vertnum = bandvnumtax[bandvertnum]; partval = bandparttax[bandvertnum]; bandedgetax[bandedgetab[partval] ++] = bandvertnum; if (bandedlotax != NULL) bandedlotax[bandedgetab[partval] - 1] = 1; bandedlosum ++; } #ifdef SCOTCH_DEBUG_KGRAPH2 for (domnnum = 0; domnnum < domnnbr; domnnum ++) { if (bandedgetab[domnnum] != bandverttax[bandvertnnd + 1 + domnnum]) { errorPrint ("kgraphBand: internal error (6)"); return (1); } } #endif /* SCOTCH_DEBUG_KGRAPH2 */ } bandedgenbr = bandgrafptr->s.verttax[bandvertnnd + domnnbr] - bandgrafptr->s.baseval; /* Set real number of edges */ bandgrafptr->s.vendtax = bandgrafptr->s.verttax + 1; /* Band graph is compact */ bandgrafptr->s.velosum = grafptr->s.velosum + domnnbr * bandvertancadj; bandgrafptr->s.edgenbr = bandedgenbr; if (bandedlotax == NULL) bandedlosum = bandedgenbr; bandgrafptr->s.edlosum = bandedlosum; bandgrafptr->s.degrmax = banddegrmax; /* Local maximum degree will be turned into global maximum degree */ #ifdef SCOTCH_DEBUG_KGRAPH2 if (graphCheck (&bandgrafptr->s) != 0) { errorPrint ("kgraphBand: internal error (7)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ memCpy (bandgrafptr->m.domntab, grafptr->m.domntab, domnnbr * sizeof (ArchDom)); if (pfixtax != NULL) kgraphFron (bandgrafptr); kgraphCost (bandgrafptr); #ifdef SCOTCH_DEBUG_KGRAPH2 if (kgraphCheck (bandgrafptr) != 0) { errorPrint ("kgraphBand: internal error (8)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ *bandvnumptr = bandvnumtax; return (0); } scotch-6.0.4.dfsg/src/libscotch/kgraph_map_df.c0000644002563400244210000002126612052363754024576 0ustar trophimeutilisateurs du domaine/* Copyright 2010-2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph_map_df.c **/ /** **/ /** AUTHOR : Sebastien FOURESTIER (v6.0) **/ /** Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module computes a k-way partition **/ /** of the given mapping graph by applying **/ /** a diffusion method to what is assumed **/ /** to be a band graph. **/ /** **/ /** DATES : # Version 6.0 : from : 05 jan 2010 **/ /** to : 04 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define KGRAPH_MAP_DF #ifdef SCOTCH_PTHREAD #define KGRAPHMAPDFTHREAD #endif /* SCOTCH_PTHREAD */ #include "module.h" #include "common.h" #include "arch.h" #include "graph.h" #include "mapping.h" #include "kgraph.h" #include "kgraph_map_df.h" /************************/ /* */ /* The sorting routine. */ /* */ /************************/ /* This routine sorts an array of KgraphMapDfVertex ** values in descending order by their amount of liquid. ** By nature of the sorting algorithm, data are left in ** place in case of equality. Therefore, the original ** part of the vertex, which is put first in the sort ** array during the diffusion process, is always preserved ** when all liquid amounts are equal. ** It returns: ** - VOID : in all cases. */ #define INTSORTQUAL static #define INTSORTNAME kgraphMapDfSort #define INTSORTSIZE (sizeof (KgraphMapDfSort)) #define INTSORTSWAP(p,q) do { \ KgraphMapDfSort t; \ t = *((KgraphMapDfSort *) (p)); \ *((KgraphMapDfSort *) (p)) = *((KgraphMapDfSort *) (q)); \ *((KgraphMapDfSort *) (q)) = t; \ } while (0) #define INTSORTCMP(p,q) (((KgraphMapDfSort *) (p))->diffval > ((KgraphMapDfSort *) (q))->diffval) #include "common_sort.c" #undef INTSORTQUAL #undef INTSORTNAME #undef INTSORTSIZE #undef INTSORTSWAP #undef INTSORTCMP /********************************/ /* */ /* The sequential loop routine. */ /* */ /********************************/ #define KGRAPHMAPDFLOOPNAME kgraphMapDfSeq #include "kgraph_map_df_loop.c" #undef KGRAPHMAPDFLOOPNAME /******************************/ /* */ /* The threaded loop routine. */ /* */ /******************************/ #ifdef KGRAPHMAPDFTHREAD #define KGRAPHMAPDFLOOPTHREAD #define KGRAPHMAPDFLOOPNAME kgraphMapDfThr #include "kgraph_map_df_loop.c" #undef KGRAPHMAPDFLOOPNAME #undef KGRAPHMAPDFLOOPTHREAD #endif /* KGRAPHMAPDFTHREAD */ /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine computes a k-way partition ** by diffusion across what is assumed ** to be a k-way band graph. ** It returns: ** - 0 : if the k-partition could be computed. ** - !0 : on error. */ int kgraphMapDf ( Kgraph * restrict const grafptr, /*+ Active graph +*/ const KgraphMapDfParam * const paraptr) /*+ Method parameters +*/ { KgraphMapDfData loopdat; /* Diffusion loop data */ Gnum vertnbr; Gnum vancnbr; Gnum domnnbr; #ifdef KGRAPHMAPDFTHREAD /* Threads can be accepted even when SCOTCH_DETERMINISTIC set */ int thrdnbr; #endif /* KGRAPHMAPDFTHREAD */ domnnbr = grafptr->m.domnnbr; vertnbr = grafptr->s.vertnbr; vancnbr = vertnbr - domnnbr; if (memAllocGroup ((void **) (void *) &loopdat.vanctab, (size_t) (domnnbr * sizeof (float)), &loopdat.valotab, (size_t) (domnnbr * sizeof (Gnum)), &loopdat.velstax, (size_t) (vertnbr * sizeof (Gnum)), &loopdat.difntax, (size_t) (vertnbr * sizeof (KgraphMapDfVertex)), &loopdat.difotax, (size_t) (vertnbr * sizeof (KgraphMapDfVertex)), NULL) == NULL) { errorPrint ("kgraphMapDf: out of memory (1)"); return (1); } loopdat.grafptr = grafptr; loopdat.velstax -= grafptr->s.baseval; loopdat.difntax -= grafptr->s.baseval; loopdat.difotax -= grafptr->s.baseval; loopdat.passnbr = paraptr->passnbr; #ifdef KGRAPHMAPDFTHREAD /* Threads can be accepted even when SCOTCH_DETERMINISTIC set */ thrdnbr = SCOTCH_PTHREAD_NUMBER; loopdat.abrtval = 0; /* No one wants to abort yet */ if (thrdnbr > 1) { KgraphMapDfThread * restrict thrdtab; int thrdnum; Gnum vertbas; Anum domnbas; if ((thrdtab = memAlloc (thrdnbr * sizeof (KgraphMapDfThread))) == NULL) { errorPrint ("kgraphMapDf: out of memory (2)"); memFree (loopdat.vanctab); return (1); } for (thrdnum = 0, vertbas = grafptr->s.baseval, domnbas = 0; thrdnum < thrdnbr; thrdnum ++) { thrdtab[thrdnum].vertbas = vertbas; thrdtab[thrdnum].vertnnd = vertbas += DATASIZE (vancnbr, thrdnbr, thrdnum); thrdtab[thrdnum].domnbas = domnbas; thrdtab[thrdnum].domnnnd = domnbas += DATASIZE (domnnbr, thrdnbr, thrdnum); } threadLaunch (&loopdat, thrdtab, sizeof (KgraphMapDfThread), (ThreadLaunchStartFunc) kgraphMapDfThr, (ThreadLaunchJoinFunc) NULL, thrdnbr, THREADCANBARRIER); memFree (thrdtab); /* Free group leader */ } else #endif /* KGRAPHMAPDFTHREAD */ { KgraphMapDfThread thrddat; thrddat.thrddat.grouptr = &loopdat; thrddat.vertbas = grafptr->s.baseval; thrddat.vertnnd = vertnbr + grafptr->s.baseval - domnnbr; thrddat.domnbas = 0; thrddat.domnnnd = domnnbr; #ifdef KGRAPHMAPDFTHREAD thrddat.thrddat.thrdnum = 0; /* Thread is thread 0 of 1 */ #endif /* KGRAPHMAPDFTHREAD */ kgraphMapDfSeq (&thrddat); } memFree (loopdat.vanctab); /* Free group leader */ kgraphFron (grafptr); kgraphCost (grafptr); #ifdef SCOTCH_DEBUG_KGRAPH2 if (kgraphCheck (grafptr) != 0) { errorPrint ("kgraphMapDf: internal error"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/vmesh_separate_fm.c0000644002563400244210000016225412400054266025477 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vmesh_separate_fm.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module separates an active **/ /** mesh using an element-oriented version **/ /** of our improved Fiduccia-Mattheyses **/ /** heuristics. **/ /** **/ /** DATES : # Version 4.0 : from : 26 feb 2003 **/ /** to 06 may 2004 **/ /** # Version 5.0 : from : 12 sep 2007 **/ /** to 22 may 2008 **/ /** # Version 5.1 : from : 12 nov 2008 **/ /** to 12 nov 2008 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VMESH_SEPARATE_FM /* #define SCOTCH_DEBUG_VMESH3 */ /* For intensive debugging */ #include "module.h" #include "common.h" #include "gain.h" #include "graph.h" #include "mesh.h" #include "vmesh.h" #include "vmesh_separate_gg.h" #include "vmesh_separate_fm.h" /* This routine resizes the hash arrays ** as well as the associated structures. ** In the group of allocated arrays, ** the element array must be put before ** the node array, because the element ** structure is larger than the node ** structure, such that the old and new ** node arrays can never overlap after ** the doubling in size of the element ** array. The same for the move array. ** It returns: ** - 0 : if resize succeeded. ** - !0 : in case of error. */ static int vmeshSeparateFmResize ( GainTabl * restrict const tablptr, /*+ Pointer to gain table +*/ VmeshSeparateFmElement * restrict * const helmptr, /*+ Pointer to pointer to element hash table +*/ VmeshSeparateFmNode * restrict * const hnodptr, /*+ Pointer to pointer to node hash table +*/ VmeshSeparateFmSave * restrict * const saveptr, /*+ Pointer to pointer to move array +*/ const Gnum savenbr, /*+ Current number of items in save array +*/ VmeshSeparateFmElement ** lockptr, /*+ Pointer to list of locked elements +*/ VmeshSeparateFmElement ** sepaptr, /*+ Pointer to list of separator elements, if any +*/ const Gnum hashold) /*+ Maximum number of vertices in hash structures +*/ { Gnum hashsiz; /* Size of hash table */ Gnum hashmsk; /* Mask for access to hash table */ Gnum hashmax; /* Maximum number of objects in tables */ VmeshSeparateFmSave * restrict movetab; /* Pointer to move array */ VmeshSeparateFmElement * restrict helmtab; /* Element hash table */ VmeshSeparateFmNode * hnodtab; /* Node hash table */ size_t addradj; /* Address adjustment */ Gnum helmold; VmeshSeparateFmNode * hnodtld; Gnum hnodold; VmeshSeparateFmSave * restrict savetab; Gnum savenum; hashmax = 2 * hashold; /* Set new number */ hashsiz = 4 * hashmax; /* Set new size */ hashmsk = hashsiz - 1; savetab = *saveptr; /* Point to old move array */ for (savenum = 0; savenum < savenbr; savenum ++) { /* Turn hash indices into vertex indices */ Gnum hertnum; hertnum = savetab[savenum].hertnum; savetab[savenum].hertnum = (hertnum >= 0) ? (*helmptr)[hertnum].velmnum : (-1 - (*hnodptr)[-1 - hertnum].vnodnum); } if (memReallocGroup ((void *) *helmptr, /* Get old group leader */ &helmtab, (size_t) (hashsiz * sizeof (VmeshSeparateFmElement)), &hnodtab, (size_t) (hashsiz * sizeof (VmeshSeparateFmNode)), &movetab, (size_t) (hashmax * sizeof (VmeshSeparateFmSave)), NULL) == NULL) { errorPrint ("vmeshSeparateFmResize: cannot resize arrays"); return (1); /* If cannot reallocate */ } #ifdef SCOTCH_DEBUG_VMESH2 if (((byte *) hnodtab - (byte *) helmtab) < ((byte *) (*saveptr) - (byte *) (*helmptr))) { /* If cannot simply copy node hash array */ errorPrint ("vmeshSeparateFmResize: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH2 */ memMov (movetab, ((byte *) helmtab) + ((byte *) *saveptr - (byte *) *helmptr), savenbr * sizeof (VmeshSeparateFmSave)); /* Old array may have moved but arrays cannot overlap */ memSet (hnodtab, ~0, hashsiz * sizeof (VmeshSeparateFmNode)); /* Cannot overlap */ hnodtld = (VmeshSeparateFmNode *) ((byte *) helmtab) + ((byte *) *hnodptr - (byte *) *helmptr); /* Point to old node array */ for (hnodold = 0; hnodold < (hashold * 4); hnodold ++) { /* For all old allocated nodes */ Gnum hnodnew; if (hnodtld[hnodold].vnodnum == ~0) /* If unallocated slot */ continue; /* Skip to next slot */ for (hnodnew = (hnodtld[hnodold].vnodnum * VMESHSEPAFMHASHPRIME) & hashmsk; hnodtab[hnodnew].vnodnum != ~0; hnodnew = (hnodnew + 1) & hashmsk) ; hnodtab[hnodnew] = hnodtld[hnodold]; /* Move node data to new position */ } /* TODO */ fprintf (stderr, "hertnum no longer valid !\n"); exit (1); addradj = (byte *) helmtab - (byte *) (*helmptr); /* Compute address difference */ gainTablFree (tablptr); /* Reset gain table */ memSet (helmtab + hashold, ~0, hashold * 2 * sizeof (VmeshSeparateFmElement)); for (helmold = 0; helmold < (hashold * 4); helmold ++) { /* For all old allocated elements */ Gnum helmnew; if (helmtab[helmold].velmnum == ~0) /* If unallocated slot */ continue; /* Skip to next slot */ for (helmnew = (helmtab[helmold].velmnum * VMESHSEPAFMHASHPRIME) & hashmsk; ; helmnew = (helmnew + 1) & hashmsk) { if (helmtab[helmnew].velmnum == ~0) { helmtab[helmnew].velmnum = helmtab[helmold].velmnum; helmtab[helmnew].vertpart = helmtab[helmold].vertpart; helmtab[helmnew].ncmpcut2 = helmtab[helmold].ncmpcut2; helmtab[helmnew].ncmpgain2 = helmtab[helmold].ncmpgain2; helmtab[helmnew].ncmpgaindlt = helmtab[helmold].ncmpgaindlt; helmtab[helmnew].mswpnum = helmtab[helmold].mswpnum; helmtab[helmold].velmnum = ~0; /* Free old slot */ helmtab[helmold].mswpnum = ~0; /* Reset sweep number */ break; } if (helmtab[helmnew].velmnum != helmtab[helmold].velmnum) /* If element not found */ continue; /* Go on searching */ } if (helmtab[helmold].gainlink.next >= VMESHSEPAFMSTATELINK) /* If element was linked */ gainTablAdd (tablptr, (GainLink *) &helmtab[helmnew], helmtab[helmnew].ncmpgain2); /* Re-link it */ else { /* Element may be chained in some list */ helmtab[helmnew].gainlink.next = helmtab[helmold].gainlink.next; /* Save it */ helmtab[helmnew].gainlink.prev = (GainLink *) ((byte *) helmtab[helmold].gainlink.prev + addradj); } } if (*lockptr != NULL) *lockptr = (VmeshSeparateFmElement *) ((byte *) (*lockptr) + addradj); if (sepaptr != NULL) { if (*sepaptr != NULL) *sepaptr = (VmeshSeparateFmElement *) ((byte *) (*sepaptr) + addradj); } for (savenum = 0; savenum < savenbr; savenum ++) { /* Turn vertex indices back into hash indices */ Gnum vertnum; vertnum = movetab[savenum].hertnum; /* Read vertex index */ if (vertnum >= 0) { /* If element vertex */ Gnum helmnum; for (helmnum = (vertnum * VMESHSEPAFMHASHPRIME) & hashmsk; ; helmnum = (helmnum + 1) & hashmsk) { #ifdef SCOTCH_DEBUG_VMESH2 if (helmtab[helmnum].velmnum == ~0) { /* We should always find the elements */ errorPrint ("vmeshSeparateFmResize: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH2 */ if (helmtab[helmnum].velmnum == vertnum) /* If element found */ break; } movetab[savenum].hertnum = helmnum; /* Save element hash index */ } else { /* If node vertex */ Gnum hnodnum; vertnum = -1 - vertnum; for (hnodnum = (vertnum * VMESHSEPAFMHASHPRIME) & hashmsk; ; hnodnum = (hnodnum + 1) & hashmsk) { #ifdef SCOTCH_DEBUG_VMESH2 if (hnodtab[hnodnum].vnodnum == ~0) { /* We should always find the nodes */ errorPrint ("vmeshSeparateFmResize: internal error (3)"); return (1); } if (hnodtab[hnodnum].vnodnum == vertnum) /* If element found */ break; #endif /* SCOTCH_DEBUG_VMESH2 */ } movetab[savenum].hertnum = -1 - hnodnum; /* Save node hash index */ } } fprintf (stderr, "########### vmeshSeparateFmResize (%ld) !!!\n", (long) hashold); return (0); } /* This routine returns the vertex of best gain ** whose swap will keep the balance correct. ** It returns: ** - !NULL : pointer to the vertex. ** - NULL : if no more vertices available. */ static VmeshSeparateFmElement * vmeshSeparateFmTablGet ( GainTabl * const tablptr, /*+ Gain table +*/ const Gnum deltcur, /*+ Current imbalance +*/ const Gnum deltmax) /*+ Maximum imbalance +*/ { const VmeshSeparateFmElement * velmptr; VmeshSeparateFmElement * vertbest; Gnum gainbest; const GainEntr * tablbest; Gnum deltbest; Gnum deltnew; tablbest = tablptr->tend; /* Assume no candidate vertex found yet */ gainbest = GAINMAX; vertbest = NULL; deltbest = deltmax; for (velmptr = (VmeshSeparateFmElement *) gainTablFrst (tablptr); /* Select candidate vertices */ (velmptr != NULL) && (velmptr->gainlink.tabl < tablbest); velmptr = (VmeshSeparateFmElement *) gainTablNext (tablptr, &velmptr->gainlink)) { deltnew = abs (deltcur + velmptr->ncmpgaindlt); if (deltnew <= deltmax) { /* If vertex enforces balance */ if ((velmptr->ncmpgain2 < gainbest) || /* And if it gives better gain */ ((velmptr->ncmpgain2 == gainbest) && /* Or if it gives better load */ (deltnew < deltbest))) { tablbest = velmptr->gainlink.tabl; /* Select it */ gainbest = velmptr->ncmpgain2; vertbest = (VmeshSeparateFmElement *) velmptr; deltbest = deltnew; } } } return (vertbest); } /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine computes the ** separation of the given mesh. ** It returns: ** - 0 : if bipartitioning could be computed. ** - !0 : on error. */ int vmeshSeparateFm ( Vmesh * restrict const meshptr, /*+ Node separation mesh +*/ const VmeshSeparateFmParam * restrict const paraptr) /*+ Method parameters +*/ { GainTabl * restrict tablptr; /* Pointer to gain table */ long passnbr; /* Maximum number of passes to go */ VmeshSeparateFmSave * restrict movetab; /* Pointer to move array */ Gnum movenbr; /* Number of uneffective moves done */ Gnum savenbr; /* Number of recorded backtrack moves */ Gnum mswpnum; /* Current number of recording sweep */ int moveflag; /* Flag set if useful moves made */ Gnum fronnum; /* Current index in frontier array */ Gnum vertnbr; Gnum hashsiz; /* Size of hash table */ Gnum hashmsk; /* Mask for access to hash table */ Gnum hashmax; /* Maximum number of objects in tables */ Gnum hashnbr; /* Estimated number of onjects in hash */ Gnum helmnbr; /* Number of elements in hash table */ Gnum helmnum; Gnum hnodnum; Gnum hnodnbr; /* Number of nodes in hash table */ VmeshSeparateFmElement * restrict helmtab; /* Element hash table */ VmeshSeparateFmNode * restrict hnodtab; /* Node hash table */ VmeshSeparateFmElement * lockptr; /* Linked list of locked elements */ VmeshSeparateFmElement * velmptr; /* Pointer to current element */ Gnum ncmploaddltmat; /* Theoretical latgest imbalance allowed */ Gnum ncmploaddltmax; /* Largest imbalance allowed */ Gnum ncmploaddlt; /* Current imbalance */ Gnum ncmpload2; /* Current size of separator */ Gnum ncmpload2bst; Gnum ncmploaddltbst; Gnum ecmpload1; Gnum ncmpload1; Gnum ncmpsize1; Gnum ncmpsize2; if (paraptr->deltrat > 0.0L) { Gnum ncmploaddlttmp; ncmploaddltmat = (Gnum) (paraptr->deltrat * meshptr->m.vnlosum) + 1; ncmploaddlttmp = (Gnum) (((float) meshptr->m.edgenbr * (float) meshptr->m.vnlosum) / ((float) meshptr->m.velmnbr * (float) meshptr->m.vnodnbr)); if (ncmploaddltmat < ncmploaddlttmp) ncmploaddltmat = ncmploaddlttmp; } else ncmploaddltmat = 0; ncmploaddltmat = (paraptr->deltrat > 0.0L) ? ((Gnum) (paraptr->deltrat * meshptr->m.vnlosum) + 1) : 0; /* printf ("FM Mbal=%ld\n", (long) ncmploaddltmat); */ if ((meshptr->fronnbr == 0) && /* If imbalance in graph with no frontier */ (abs (meshptr->ncmploaddlt) > ncmploaddltmat)) { VmeshSeparateGgParam paramdat; paramdat.passnbr = 3; vmeshSeparateGg (meshptr, ¶mdat); /* Compute a balanced initial partition */ } vertnbr = meshptr->m.velmnbr + meshptr->m.vnodnbr; hashnbr = 2 * ((meshptr->fronnbr + paraptr->movenbr) * (1 + (Gnum) ((float) meshptr->m.edgenbr / (float) vertnbr))); if (hashnbr > vertnbr) /* Set bound on hash table */ hashnbr = vertnbr; for (hashmax = 256; hashmax < hashnbr; hashmax <<= 1) ; /* Get upper power of two */ /* TODO */ hashmax *= 4; hashsiz = 4 * hashmax; hashmsk = hashsiz - 1; if (((tablptr = gainTablInit (meshptr->m.vnlosum, VMESHSEPAFMGAINBITS)) == NULL) || (memAllocGroup ((void **) (void *) &helmtab, (size_t) (hashsiz * sizeof (VmeshSeparateFmElement)), &hnodtab, (size_t) (hashsiz * sizeof (VmeshSeparateFmNode)), &movetab, (size_t) (hashmax * sizeof (VmeshSeparateFmSave)), NULL) == NULL)) { if (tablptr != NULL) { errorPrint ("vmeshSeparateFm: out of memory (1)"); gainTablExit (tablptr); } return (1); } passnbr = paraptr->passnbr; /* Set remaining number of passes */ ncmpload2 = meshptr->ncmpload[2]; /* Set current partition loads */ ncmploaddlt = meshptr->ncmploaddlt; memSet (helmtab, ~0, (byte *) &hnodtab[hashsiz] - (byte *) helmtab); /* Set all vertex numbers to ~0 */ helmnbr = hnodnbr = 0; savenbr = 0; /* No recorded moves yet */ lockptr = NULL; /* Set locked list as empty */ for (fronnum = 0; fronnum < meshptr->fronnbr; fronnum ++) { /* Set initial gains */ Gnum vnloval; Gnum vnodnum; Gnum enodnum; Gnum hnodnum; Gnum ecmpsize1; vnodnum = meshptr->frontab[fronnum]; #ifdef SCOTCH_DEBUG_VMESH2 if (meshptr->parttax[vnodnum] != 2) { errorPrint ("vmeshSeparateFm: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH2 */ vnloval = (meshptr->m.vnlotax == NULL) ? 1 : meshptr->m.vnlotax[vnodnum]; for (hnodnum = (vnodnum * VMESHSEPAFMHASHPRIME) & hashmsk; ; hnodnum = (hnodnum + 1) & hashmsk) { if (hnodtab[hnodnum].vnodnum == ~0) /* If node slot found */ break; /* No need to go on */ #ifdef SCOTCH_DEBUG_VMESH2 if (hnodtab[hnodnum].vnodnum == vnodnum) { /* If node already present in frontier array */ errorPrint ("vmeshSeparateFm: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH2 */ } hnodnbr ++; /* One more node in hash table */ hnodtab[hnodnum].vnodnum = vnodnum; /* Insert node in hash table */ hnodtab[hnodnum].vnloval = vnloval; if ((meshptr->m.vendtax[vnodnum] - meshptr->m.verttax[vnodnum]) == 0) { /* If single node */ int vnodpart; vnodpart = (ncmploaddlt > 0) ? 1 : 0; ncmpload2 -= vnloval; /* Node cannot belong to the separator */ ncmploaddlt += (1 - 2 * vnodpart) * vnloval; hnodtab[hnodnum].vertpart = vnodpart; hnodtab[hnodnum].ecmpsize0 = 0; continue; /* No need to process elements of node vertex */ } for (enodnum = meshptr->m.verttax[vnodnum], ecmpsize1 = 0; /* For all (at least one) element neighbors of node */ enodnum < meshptr->m.vendtax[vnodnum]; enodnum ++) { Gnum velmnum; Gnum helmnum; velmnum = meshptr->m.edgetax[enodnum]; for (helmnum = (velmnum * VMESHSEPAFMHASHPRIME) & hashmsk; ; helmnum = (helmnum + 1) & hashmsk) { if (helmtab[helmnum].velmnum == ~0) { /* If element not yet inserted */ if (helmnbr >= hashmax) { /* If element hash table is full */ if (vmeshSeparateFmResize (tablptr, &helmtab, &hnodtab, &movetab, savenbr, &lockptr, NULL, hashmax) != 0) { errorPrint ("vmeshSeparateFm: cannot resize arrays (1)"); memFree (helmtab); /* Free group leader */ gainTablExit (tablptr); return (1); } hashmax <<= 1; hashsiz <<= 1; hashmsk = (hashmsk << 1) | 1; #ifdef SCOTCH_DEBUG_VMESH3 if (vmeshSeparateFmCheck (meshptr, helmtab, hnodtab, hashmsk, ncmpload2, ncmploaddlt) != 0) { errorPrint ("vmeshSeparateFm: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH3 */ for (helmnum = (velmnum * VMESHSEPAFMHASHPRIME) & hashmsk; /* Re-compute position in table */ helmtab[helmnum].velmnum != ~0; helmnum = (helmnum + 1) & hashmsk) ; } helmtab[helmnum].gainlink.prev = (GainLink *) lockptr; /* Link it */ lockptr = &helmtab[helmnum]; helmtab[helmnum].velmnum = velmnum; /* Insert it */ helmtab[helmnum].vertpart = meshptr->parttax[velmnum] & 1; /* Separator elements to part 0 */ helmnbr ++; break; } if (helmtab[helmnum].velmnum == velmnum) /* If element already or newly inserted */ break; /* It will already be processed later */ } ecmpsize1 += helmtab[helmnum].vertpart; /* Account for its (possibly modified) part */ } hnodtab[hnodnum].vertpart = 2; /* Assume node is in separator */ hnodtab[hnodnum].ecmpsize0 = meshptr->m.vendtax[vnodnum] - meshptr->m.verttax[vnodnum] - ecmpsize1; if (hnodtab[hnodnum].ecmpsize0 == 0) { /* If all neighboring elements are in part 1 */ ncmpload2 -= vnloval; /* Node moves from separator to part 1 too */ ncmploaddlt -= vnloval; hnodtab[hnodnum].vertpart = 1; } else if (ecmpsize1 == 0) { /* If all neighboring elements are in part 0 */ ncmpload2 -= vnloval; /* Node moves from separator to part 0 too */ ncmploaddlt += vnloval; hnodtab[hnodnum].vertpart = 0; } } for (velmptr = lockptr; velmptr != NULL; /* Process all frontier elements */ velmptr = (VmeshSeparateFmElement *) velmptr->gainlink.prev) { Gnum velmnum; Gnum eelmnum; Gnum ncmpcut2; Gnum ncmpgain2; Gnum ncmpgaindlt; velmnum = velmptr->velmnum; ncmpcut2 = ncmpgain2 = ncmpgaindlt = 0; for (eelmnum = meshptr->m.verttax[velmnum]; /* For all neighbors of element */ eelmnum < meshptr->m.vendtax[velmnum]; eelmnum ++) { Gnum vnodnum; Gnum hnodnum; Gnum vnoddeg; vnodnum = meshptr->m.edgetax[eelmnum]; vnoddeg = meshptr->m.vendtax[vnodnum] - meshptr->m.verttax[vnodnum]; for (hnodnum = (vnodnum * VMESHSEPAFMHASHPRIME) & hashmsk; ; hnodnum = (hnodnum + 1) & hashmsk) { if (hnodtab[hnodnum].vnodnum == vnodnum) { /* If node exists (can be in same part or separator) */ int vnodpart; Gnum vnloval; vnodpart = hnodtab[hnodnum].vertpart; vnloval = hnodtab[hnodnum].vnloval; if (vnodpart == 2) { /* If vertex is in separator */ ncmpcut2 ++; /* One more node in separator */ if ((hnodtab[hnodnum].ecmpsize0 - 1) == ((vnoddeg - 2) * velmptr->vertpart)) { /* If element is only neighbor in its part */ ncmpgain2 -= vnloval; ncmpgaindlt += vnloval * (2 * velmptr->vertpart - 1); } } else { /* Vertex not in separator */ #ifdef SCOTCH_DEBUG_VMESH2 if (vnodpart != velmptr->vertpart) { /* Node should be in same part as element */ errorPrint ("vmeshSeparateFm: internal error (4)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH2 */ if (vnoddeg <= 1) /* If element is node's sole neighbor */ ncmpgaindlt += (vnloval * (2 * vnodpart - 1)) * 2; else { ncmpgain2 += vnloval; ncmpgaindlt += (vnloval * (2 * vnodpart - 1)); } } break; } if (hnodtab[hnodnum].vnodnum == ~0) { /* If node does not exist */ int vnodpart; Gnum vnloval; vnodpart = velmptr->vertpart; /* Get its part */ vnloval = (meshptr->m.vnlotax == NULL) ? 1 : meshptr->m.vnlotax[vnodnum]; #ifdef SCOTCH_DEBUG_VMESH2 if (vnodpart != meshptr->parttax[vnodnum]) { /* Node should be in same part as element */ errorPrint ("vmeshSeparateFm: internal error (5)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH2 */ if (vnoddeg > 1) { /* If node will move to separator */ ncmpgain2 += vnloval; /* Increase size of separator */ ncmpgaindlt += (2 * vnodpart - 1) * vnloval; /* Account for imbalance */ } else /* Node will move with element */ ncmpgaindlt += (2 * vnodpart - 1) * 2 * vnloval; /* Double imbalance */ break; } } } velmptr->ncmpcut2 = ncmpcut2; velmptr->ncmpgain2 = ncmpgain2; velmptr->ncmpgaindlt = ncmpgaindlt; } ncmploaddltmax = MAX (ncmploaddltmat, abs (ncmploaddlt)); /* Set current maximum imbalance after cleaning */ #ifdef SCOTCH_DEBUG_VMESH3 if (vmeshSeparateFmCheck (meshptr, helmtab, hnodtab, hashmsk, ncmpload2, ncmploaddlt) != 0) { errorPrint ("vmeshSeparateFm: internal error (6)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH3 */ mswpnum = 0; /* First sweep */ ncmpload2bst = ncmpload2; /* Record best state */ ncmploaddltbst = ncmploaddlt; do { /* As long as there are improvements */ VmeshSeparateFmElement * velmptr; Gnum velmgain2; Gnum velmgaindlt; while (lockptr != NULL) { /* For all elements in locked list */ VmeshSeparateFmElement * velmptr; velmptr = lockptr; /* Unlink element from list */ lockptr = (VmeshSeparateFmElement *) velmptr->gainlink.prev; velmptr->gainlink.next = VMESHSEPAFMSTATEFREE;/* Set it free anyway */ if (velmptr->ncmpcut2 > 0) /* If element has nodes in separator */ gainTablAdd (tablptr, (GainLink *) velmptr, velmptr->ncmpgain2); /* Put it in table */ } /* fprintf (stderr, "LOOP %ld\t(%ld,\t%ld)\n", (long) passnbr, (long) ncmpload2bst, (long) ncmploaddltbst); */ moveflag = 0; /* No moves to date */ movenbr = 0; /* No uneffective moves yet */ while ((movenbr < paraptr->movenbr) && /* As long as we can find effective elements */ ((velmptr = vmeshSeparateFmTablGet (tablptr, ncmploaddlt, ncmploaddltmax)) != NULL)) { VmeshSeparateFmElement * sepaptr; /* Linked list of separator frontier elements */ Gnum velmnum; /* Number of current element */ Gnum velmpart; /* Old part of current element */ Gnum eelmnum; gainTablDel (tablptr, &velmptr->gainlink); /* Remove it from table */ velmptr->gainlink.next = VMESHSEPAFMSTATEUSED; /* Mark it as used */ velmptr->gainlink.prev = (GainLink *) lockptr; /* Lock it */ lockptr = velmptr; if (velmptr->mswpnum != mswpnum) { /* If element data not yet recorded */ movetab[savenbr].hertnum = velmptr - helmtab; /* Record them */ movetab[savenbr].data.elem.vertpart = velmptr->vertpart; movetab[savenbr].data.elem.ncmpcut2 = velmptr->ncmpcut2; movetab[savenbr].data.elem.ncmpgain2 = velmptr->ncmpgain2; movetab[savenbr].data.elem.ncmpgaindlt = velmptr->ncmpgaindlt; velmptr->mswpnum = mswpnum; savenbr ++; /* One more move recorded */ } movenbr ++; /* One more assumed uneffective move performed */ velmgain2 = velmptr->ncmpgain2; /* Save old gains for this vertex */ velmgaindlt = velmptr->ncmpgaindlt; ncmpload2 += velmgain2; /* Account for gains */ ncmploaddlt += velmgaindlt; velmnum = velmptr->velmnum; /* Move element to other part */ velmpart = velmptr->vertpart; velmptr->vertpart = velmpart ^ 1; sepaptr = NULL; /* No frontier elements to relink yet */ for (eelmnum = meshptr->m.verttax[velmnum]; /* (Re-)link neighbors */ eelmnum < meshptr->m.vendtax[velmnum]; eelmnum ++) { Gnum vnoddeg; Gnum vnodnum; Gnum hnodnum; Gnum enodnum; Gnum vnloval; /* Load of current node */ int vnodpartold; /* Old part of current node */ int vnodpartnew; /* New part of current node */ Gnum ecmpsize0old; Gnum ecmpsize0new; vnodnum = meshptr->m.edgetax[eelmnum]; vnoddeg = meshptr->m.vendtax[vnodnum] - meshptr->m.verttax[vnodnum]; for (hnodnum = (vnodnum * VMESHSEPAFMHASHPRIME) & hashmsk; ; hnodnum = (hnodnum + 1) & hashmsk) { if (hnodtab[hnodnum].vnodnum == vnodnum) /* If node found */ break; if (hnodtab[hnodnum].vnodnum == ~0) { /* If node not yet inserted */ #ifdef SCOTCH_DEBUG_VMESH2 if (meshptr->parttax[vnodnum] != velmpart) { errorPrint ("vmeshSeparateFm: internal error (7)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH2 */ if (hnodnbr >= hashmax) { /* If node hash table is full */ if (vmeshSeparateFmResize (tablptr, &helmtab, &hnodtab, &movetab, savenbr, &lockptr, &sepaptr, hashmax) != 0) { errorPrint ("vmeshSeparateFm: cannot resize arrays (2)"); memFree (helmtab); /* Free group leader */ gainTablExit (tablptr); return (1); } hashmax <<= 1; hashsiz <<= 1; hashmsk = (hashmsk << 1) | 1; #ifdef SCOTCH_DEBUG_VMESH3 if (vmeshSeparateFmCheck (meshptr, helmtab, hnodtab, hashmsk, ncmpload2, ncmploaddlt) != 0) { errorPrint ("vmeshSeparateFm: internal error (8)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH3 */ for (helmnum = (velmnum * VMESHSEPAFMHASHPRIME) & hashmsk; /* Re-compute positions in tables */ helmtab[helmnum].velmnum != velmnum; helmnum = (helmnum + 1) & hashmsk) ; velmptr = helmtab + helmnum; for (hnodnum = (vnodnum * VMESHSEPAFMHASHPRIME) & hashmsk; hnodtab[hnodnum].vnodnum != ~0; hnodnum = (hnodnum + 1) & hashmsk) ; } hnodtab[hnodnum].vnodnum = vnodnum; /* Insert node in hash table */ hnodtab[hnodnum].vnloval = (meshptr->m.vnlotax == NULL) ? 1 : meshptr->m.vnlotax[vnodnum]; hnodtab[hnodnum].ecmpsize0 = vnoddeg * (1 - velmpart); hnodtab[hnodnum].vertpart = velmpart; /* Node belongs to old part */ hnodnbr ++; /* One more node created */ break; } } if (hnodtab[hnodnum].mswpnum != mswpnum) { /* If node data not yet recorded */ movetab[savenbr].hertnum = -1 - hnodnum; movetab[savenbr].data.node.vertpart = hnodtab[hnodnum].vertpart; movetab[savenbr].data.node.ecmpsize0 = hnodtab[hnodnum].ecmpsize0; hnodtab[hnodnum].mswpnum = mswpnum; savenbr ++; /* One more move recorded */ } vnloval = hnodtab[hnodnum].vnloval; if (vnoddeg <= 1) { /* If node only has one neighbor */ #ifdef SCOTCH_DEBUG_VMESH2 if (hnodtab[hnodnum].vertpart != velmpart) { errorPrint ("vmeshSeparateFm: internal error (9)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH2 */ hnodtab[hnodnum].vertpart = 1 - velmpart; /* Directly move node to other part */ hnodtab[hnodnum].ecmpsize0 = velmpart; continue; /* Skip to next node */ } ecmpsize0old = hnodtab[hnodnum].ecmpsize0; ecmpsize0new = hnodtab[hnodnum].ecmpsize0 += (2 * velmpart - 1); /* One less neighbor element for this node */ #ifdef SCOTCH_DEBUG_VMESH2 if ((hnodtab[hnodnum].ecmpsize0 < 0) || (hnodtab[hnodnum].ecmpsize0 > vnoddeg)) { errorPrint ("vmeshSeparateFm: internal error (10)"); return (1); } if (hnodtab[hnodnum].vertpart == (1 - velmpart)) { errorPrint ("vmeshSeparateFm: internal error (11)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH2 */ vnodpartold = hnodtab[hnodnum].vertpart; /* Get old node part value */ vnodpartnew = 2; /* Assume new node part */ if (vnodpartold != vnodpartnew) /* If belonged to old part */ hnodtab[hnodnum].vertpart = vnodpartnew; /* Move to separator */ else if ((ecmpsize0old - 1) == (vnoddeg - 2) * velmpart) { vnodpartnew = /* Belonged to separator and last element in this part */ hnodtab[hnodnum].vertpart = 1 - velmpart; } for (enodnum = meshptr->m.verttax[vnodnum]; /* For all element neighbors of node */ enodnum < meshptr->m.vendtax[vnodnum]; enodnum ++) { Gnum velmend; Gnum helmend; int vendpart; Gnum ncmpcut2; Gnum ncmpgain2; Gnum ncmpgaindlt; velmend = meshptr->m.edgetax[enodnum]; for (helmend = (velmend * VMESHSEPAFMHASHPRIME) & hashmsk; ; helmend = (helmend + 1) & hashmsk) { if (helmtab[helmend].velmnum == velmend) /* If element found */ break; if (helmtab[helmend].velmnum == ~0) { /* If element not yet inserted */ Gnum ncmpgain2; Gnum ncmpgaindlt; #ifdef SCOTCH_DEBUG_VMESH2 if (vnodpartold == 2) { /* Elements neighboring the frontier should exist */ errorPrint ("vmeshSeparateFm: internal error (12)"); return (1); } if (vnodpartold != meshptr->parttax[velmend]) { /* Unexisting elements should be in same part as their neighboring nodes */ errorPrint ("vmeshSeparateFm: internal error (13)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH2 */ if (helmnbr >= hashmax) { /* If element hash table is full */ if (vmeshSeparateFmResize (tablptr, &helmtab, &hnodtab, &movetab, savenbr, &lockptr, &sepaptr, hashmax) != 0) { errorPrint ("vmeshSeparateFm: cannot resize arrays (3)"); memFree (helmtab); /* Free group leader */ gainTablExit (tablptr); return (1); } hashmax <<= 1; hashsiz <<= 1; hashmsk = (hashmsk << 1) | 1; #ifdef SCOTCH_DEBUG_VMESH3 if (vmeshSeparateFmCheck (meshptr, helmtab, hnodtab, hashmsk, ncmpload2, ncmploaddlt) != 0) { errorPrint ("vmeshSeparateFm: internal error (14)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH3 */ for (helmnum = (velmnum * VMESHSEPAFMHASHPRIME) & hashmsk; /* Re-compute positions in tables */ helmtab[helmnum].velmnum != velmnum; helmnum = (helmnum + 1) & hashmsk) ; velmptr = helmtab + helmnum; for (hnodnum = (vnodnum * VMESHSEPAFMHASHPRIME) & hashmsk; hnodtab[hnodnum].vnodnum != vnodnum; hnodnum = (hnodnum + 1) & hashmsk) ; for (helmend = (velmend * VMESHSEPAFMHASHPRIME) & hashmsk; helmtab[helmend].velmnum != ~0; helmend = (helmend + 1) & hashmsk) ; } helmtab[helmend].gainlink.next = VMESHSEPAFMSTATEFREE; helmtab[helmend].velmnum = velmend; helmtab[helmend].vertpart = vnodpartold; helmtab[helmend].ncmpcut2 = 0; if (meshptr->m.vnlotax == NULL) { Gnum eelmend; ncmpgain2 = meshptr->m.vendtax[velmend] - meshptr->m.verttax[velmend]; ncmpgaindlt = (2 * vnodpartold - 1) * ncmpgain2; for (eelmend = meshptr->m.verttax[velmend]; /* For all neighboring nodes */ eelmend < meshptr->m.vendtax[velmend]; eelmend ++) { Gnum vnodend; vnodend = meshptr->m.edgetax[eelmend]; if ((meshptr->m.vendtax[vnodend] - meshptr->m.verttax[vnodend]) <= 1) { /* If node linked to element only */ ncmpgain2 --; /* Node will directly move to other part */ ncmpgaindlt += (2 * velmpart - 1); } } } else { Gnum eelmend; Gnum veloend; for (eelmend = meshptr->m.verttax[velmend], ncmpgain2 = ncmpgaindlt = veloend = 0; /* For all neighboring nodes */ eelmend < meshptr->m.vendtax[velmend]; eelmend ++) { Gnum vnodend; Gnum vnloend; vnodend = meshptr->m.edgetax[eelmend]; vnloend = meshptr->m.vnlotax[vnodend]; veloend += vnloend; if ((meshptr->m.vendtax[vnodend] - meshptr->m.verttax[vnodend]) <= 1) { /* If node linked to element only */ ncmpgain2 -= vnloend; ncmpgaindlt += vnloend * (2 * velmpart - 1); } } ncmpgain2 += veloend; ncmpgaindlt += (2 * vnodpartold - 1) * veloend; } helmtab[helmend].ncmpgain2 = ncmpgain2; helmtab[helmend].ncmpgaindlt = ncmpgaindlt; helmnbr ++; break; } } if (helmtab[helmend].mswpnum != mswpnum) { /* If element data not yet recorded */ movetab[savenbr].hertnum = helmend; movetab[savenbr].data.elem.vertpart = helmtab[helmend].vertpart; movetab[savenbr].data.elem.ncmpcut2 = helmtab[helmend].ncmpcut2; movetab[savenbr].data.elem.ncmpgain2 = helmtab[helmend].ncmpgain2; movetab[savenbr].data.elem.ncmpgaindlt = helmtab[helmend].ncmpgaindlt; helmtab[helmend].mswpnum = mswpnum; savenbr ++; /* One more move recorded */ } if (helmtab[helmend].gainlink.next != VMESHSEPAFMSTATEUSED) { /* If element available */ if (helmtab[helmend].gainlink.next >= VMESHSEPAFMSTATELINK) /* If element linked */ gainTablDel (tablptr, &helmtab[helmend].gainlink); /* Unlink element */ helmtab[helmend].gainlink.next = VMESHSEPAFMSTATEUSED; /* Chain neighbor elements */ helmtab[helmend].gainlink.prev = (GainLink *) sepaptr; sepaptr = &helmtab[helmend]; } vendpart = helmtab[helmend].vertpart; ncmpcut2 = helmtab[helmend].ncmpcut2; /* Get element values */ ncmpgain2 = helmtab[helmend].ncmpgain2; ncmpgaindlt = helmtab[helmend].ncmpgaindlt; if (vnodpartold != 2) { /* If node was in same part as the element */ ncmpgain2 -= vnloval; ncmpgaindlt -= (2 * vendpart - 1) * vnloval; } else { /* If node was in separator */ ncmpcut2 --; if ((ecmpsize0old - 1) == ((vnoddeg - 2) * vendpart)) { /* If element was the only one in its part */ ncmpgain2 += vnloval; ncmpgaindlt -= (2 * vendpart - 1) * vnloval; } } if (vnodpartnew != 2) { /* If node is now in same part as the element */ ncmpgain2 += vnloval; ncmpgaindlt += (2 * vendpart - 1) * vnloval; } else { /* If node is now in separator */ ncmpcut2 ++; if ((ecmpsize0new - 1) == ((vnoddeg - 2) * vendpart)) { /* If element is the only one in its part */ ncmpgain2 -= vnloval; ncmpgaindlt += (2 * vendpart - 1) * vnloval; } } helmtab[helmend].ncmpcut2 = ncmpcut2; /* Adjust element values */ helmtab[helmend].ncmpgain2 = ncmpgain2; helmtab[helmend].ncmpgaindlt = ncmpgaindlt; } } velmptr->ncmpgain2 = - velmgain2; /* Set new gains of element */ velmptr->ncmpgaindlt = - velmgaindlt; while (sepaptr != NULL) { /* As long as there are element to re-link */ VmeshSeparateFmElement * velmptr; velmptr = sepaptr; /* Get element to re-link */ sepaptr = (VmeshSeparateFmElement *) velmptr->gainlink.prev; velmptr->gainlink.next = VMESHSEPAFMSTATEFREE; if (velmptr->ncmpcut2 != 0) /* If element belongs to frontier */ gainTablAdd (tablptr, (GainLink *) velmptr, velmptr->ncmpgain2); /* Re-link it */ } #ifdef SCOTCH_DEBUG_VMESH3 if (vmeshSeparateFmCheck (meshptr, helmtab, hnodtab, hashmsk, ncmpload2, ncmploaddlt) != 0) { errorPrint ("vmeshSeparateFm: internal error (15)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH3 */ if (ncmpload2 < ncmpload2bst) { /* If move improves separator size */ ncmpload2bst = ncmpload2; /* This move was effective */ ncmploaddltbst = ncmploaddlt; movenbr = savenbr = 0; moveflag = 1; mswpnum ++; } else if (ncmpload2 == ncmpload2bst) { if (abs (ncmploaddlt) < abs (ncmploaddltbst)) { ncmploaddltbst = ncmploaddlt; /* This move was effective */ movenbr = savenbr = 0; moveflag = 1; mswpnum ++; } else if (abs (ncmploaddlt) == abs (ncmploaddltbst)) { ncmploaddltbst = ncmploaddlt; /* Might be the opposite, so record */ savenbr = 0; /* Forget backtracking */ mswpnum ++; } } if (ncmploaddltmax > ncmploaddltmat) { /* If must restrict distance bounds */ Gnum ncmploaddlttmp; ncmploaddlttmp = ncmploaddltmax; /* Save old working ncmpdltmax value */ ncmploaddltmax = MAX (ncmploaddltmat, /* Restrict at most to maximum */ abs (ncmploaddlt)); if (ncmploaddltmax < ncmploaddlttmp) { /* If we have done something useful */ ncmpload2bst = ncmpload2; /* Then record best move done */ ncmploaddltbst = ncmploaddlt; movenbr = savenbr = 0; mswpnum ++; } } } while (savenbr > 0) { /* Delete exceeding moves */ Gnum hertnum; hertnum = movetab[-- savenbr].hertnum; /* Get vertex hash number */ if (hertnum >= 0) { /* If vertex is element */ helmtab[hertnum].vertpart = movetab[savenbr].data.elem.vertpart; helmtab[hertnum].ncmpcut2 = movetab[savenbr].data.elem.ncmpcut2; helmtab[hertnum].ncmpgain2 = movetab[savenbr].data.elem.ncmpgain2; helmtab[hertnum].ncmpgaindlt = movetab[savenbr].data.elem.ncmpgaindlt; if (helmtab[hertnum].gainlink.next != VMESHSEPAFMSTATEUSED) { /* If element not already removed */ if (helmtab[hertnum].gainlink.next >= VMESHSEPAFMSTATELINK) /* If vertex is still linked */ gainTablDel (tablptr, &helmtab[hertnum].gainlink); /* Remove it from table */ helmtab[hertnum].gainlink.next = VMESHSEPAFMSTATEUSED; helmtab[hertnum].gainlink.prev = (GainLink *) lockptr; /* Lock it */ lockptr = &helmtab[hertnum]; } } else { /* Vertex is node */ hertnum = -1 - hertnum; /* Get hash index */ hnodtab[hertnum].vertpart = movetab[savenbr].data.node.vertpart; hnodtab[hertnum].ecmpsize0 = movetab[savenbr].data.node.ecmpsize0; } } ncmpload2 = ncmpload2bst; /* Restore best separator parameters */ ncmploaddlt = ncmploaddltbst; mswpnum ++; /* Forget all recorded moves */ #ifdef SCOTCH_DEBUG_VMESH3 if (vmeshSeparateFmCheck (meshptr, helmtab, hnodtab, hashmsk, ncmpload2, ncmploaddlt) != 0) { errorPrint ("vmeshSeparateFm: internal error (16)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH3 */ } while ((moveflag != 0) && /* As long as vertices are moved */ (-- passnbr != 0)); /* And we are allowed to loop (TRICK for negative values) */ ecmpload1 = 0; /* Assume no change in elements */ for (helmnum = 0; helmnum < hashsiz; helmnum ++) { Gnum velmnum; velmnum = helmtab[helmnum].velmnum; if ((velmnum != ~0) && (helmtab[helmnum].vertpart != meshptr->parttax[velmnum])) { #ifdef SCOTCH_DEBUG_VMESH2 if ((helmtab[helmnum].vertpart < 0) || /* Separator elements should have been removed */ (helmtab[helmnum].vertpart > 1)) { errorPrint ("vmeshSeparateFm: internal error (17)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH2 */ ecmpload1 += helmtab[helmnum].vertpart - (meshptr->parttax[velmnum] & 1); meshptr->parttax[velmnum] = helmtab[helmnum].vertpart; } } meshptr->ecmpsize[1] += ecmpload1; /* No longer elements in separator */ meshptr->ecmpsize[0] = meshptr->m.velmnbr - meshptr->ecmpsize[1]; #ifdef SCOTCH_DEBUG_VMESH2 if ((meshptr->ecmpsize[0] + meshptr->ecmpsize[1]) != meshptr->m.velmnbr) { /* Separator elements should have been removed */ errorPrint ("vmeshSeparateFm: internal error (18)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH2 */ ncmpsize1 = ncmpsize2 = 0; ncmpload1 = ncmpload2 = 0; for (hnodnum = 0, fronnum = 0; hnodnum < hashsiz; hnodnum ++) { Gnum vnodnum; vnodnum = hnodtab[hnodnum].vnodnum; if (vnodnum != ~0) { #ifdef SCOTCH_DEBUG_VMESH2 if ((hnodtab[hnodnum].vertpart < 0) || (hnodtab[hnodnum].vertpart > 2)) { errorPrint ("vmeshSeparateFm: internal error (19)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH2 */ if (hnodtab[hnodnum].vertpart == 2) /* If node belongs to separator */ meshptr->frontab[fronnum ++] = vnodnum; /* Add it to separator array */ if (hnodtab[hnodnum].vertpart != meshptr->parttax[vnodnum]) { Gnum diffpart1; Gnum diffpart2; diffpart1 = (hnodtab[hnodnum].vertpart & 1) - (meshptr->parttax[vnodnum] & 1); diffpart2 = (hnodtab[hnodnum].vertpart >> 1) - (meshptr->parttax[vnodnum] >> 1); ncmpsize1 += diffpart1; ncmpsize2 += diffpart2; ncmpload1 += hnodtab[hnodnum].vnloval * diffpart1; ncmpload2 += hnodtab[hnodnum].vnloval * diffpart2; meshptr->parttax[vnodnum] = hnodtab[hnodnum].vertpart; } } } #ifdef SCOTCH_DEBUG_VMESH2 if ((meshptr->fronnbr + ncmpsize2) != fronnum) { errorPrint ("vmeshSeparateFm: internal error (20)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH2 */ meshptr->ncmpload[1] += ncmpload1; meshptr->ncmpload[2] += ncmpload2; meshptr->ncmpload[0] = meshptr->m.vnlosum - meshptr->ncmpload[1] - meshptr->ncmpload[2]; meshptr->ncmploaddlt = meshptr->ncmpload[0] - meshptr->ncmpload[1]; meshptr->fronnbr = fronnum; meshptr->ncmpsize[1] += ncmpsize1; meshptr->ncmpsize[0] = meshptr->m.vnodnbr - fronnum - meshptr->ncmpsize[1]; memFree (helmtab); /* Free group leader */ gainTablExit (tablptr); #ifdef SCOTCH_DEBUG_VMESH2 if (vmeshCheck (meshptr) != 0) { errorPrint ("vmeshSeparateFm: internal error (21)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH2 */ /* printf ("FM Sepa\tsize=%ld\tload=%ld\tbal=%ld\n", (long) meshptr->fronnbr, (long) meshptr->ncmpload[2], (long) meshptr->ncmploaddlt); */ return (0); } /* This routine checks the consistency of ** the hash structures. ** It returns: ** - 0 : in case of success. ** - !0 : in case of error. */ #ifdef SCOTCH_DEBUG_VMESH3 static int vmeshSeparateFmCheck ( const Vmesh * const meshptr, const VmeshSeparateFmElement * restrict helmtab, const VmeshSeparateFmNode * restrict hnodtab, const Gnum hashmsk, const Gnum ncmpload2, const Gnum ncmploaddlt) { Gnum vertnbr; Gnum helmnum; Gnum hnodnum; Gnum ncmploadtmp[3]; GraphPart * restrict parttax; vertnbr = meshptr->m.velmnbr + meshptr->m.vnodnbr; if ((parttax = (GraphPart *) memAlloc (vertnbr * sizeof (GraphPart))) == NULL) { errorPrint ("vmeshSeparateFmCheck: out of memory"); return (1); } memCpy (parttax, meshptr->parttax + meshptr->m.baseval, vertnbr * sizeof (GraphPart)); parttax -= meshptr->m.baseval; ncmploadtmp[0] = meshptr->ncmpload[0]; ncmploadtmp[1] = meshptr->ncmpload[1]; ncmploadtmp[2] = meshptr->ncmpload[2]; for (hnodnum = 0; hnodnum <= hashmsk; hnodnum ++) { /* For all node slots */ Gnum vnodnum; Gnum enodnum; Gnum ecmpsize0; int vnodpart; vnodnum = hnodtab[hnodnum].vnodnum; if (vnodnum == ~0) /* If unallocated slot */ continue; /* Skip to next slot */ if (hnodtab[hnodnum].vnloval != ((meshptr->m.vnlotax == NULL) ? 1 : meshptr->m.vnlotax[vnodnum])) { errorPrint ("vmeshSeparateFmCheck: invalid node load"); return (1); } if ((hnodtab[hnodnum].ecmpsize0 < 0) || (hnodtab[hnodnum].ecmpsize0 > (meshptr->m.vendtax[vnodnum] - meshptr->m.verttax[vnodnum]))) { errorPrint ("vmeshSeparateFmCheck: invalid node neighbors in part 0"); return (1); } vnodpart = hnodtab[hnodnum].vertpart; if (vnodpart != meshptr->parttax[vnodnum]) { ncmploadtmp[meshptr->parttax[vnodnum]] -= hnodtab[hnodnum].vnloval; ncmploadtmp[vnodpart] += hnodtab[hnodnum].vnloval; parttax[vnodnum] = vnodpart; } ecmpsize0 = 0; for (enodnum = meshptr->m.verttax[vnodnum]; /* For all element neighbors */ enodnum < meshptr->m.vendtax[vnodnum]; enodnum ++) { Gnum velmnum; Gnum helmnum; int velmpart; velmnum = meshptr->m.edgetax[enodnum]; for (helmnum = (velmnum * VMESHSEPAFMHASHPRIME) & hashmsk; ; helmnum = (helmnum + 1) & hashmsk) { if (helmtab[helmnum].velmnum == velmnum) { /* If element found */ velmpart = helmtab[helmnum].vertpart; parttax[velmnum] = velmpart; break; } if (helmtab[helmnum].velmnum == ~0) { /* If element not present */ velmpart = meshptr->parttax[velmnum]; break; } } if (velmpart == 0) ecmpsize0 ++; } if (ecmpsize0 != hnodtab[hnodnum].ecmpsize0) { errorPrint ("vmeshSeparateFmCheck: invalid node neighbor count"); return (1); } } if (ncmpload2 != ncmploadtmp[2]) { errorPrint ("vmeshSeparateFmCheck: invalid frontier load"); return (1); } if (ncmploaddlt != (ncmploadtmp[0] - ncmploadtmp[1])) { errorPrint ("vmeshSeparateFmCheck: invalid separator balance"); return (1); } for (helmnum = 0; helmnum <= hashmsk; helmnum ++) { /* For all element slots */ Gnum velmnum; Gnum eelmnum; Gnum ncmpcut2; Gnum ncmpgain2; Gnum ncmpgaindlt; Gnum ncmpsize[3]; int velmpart; velmnum = helmtab[helmnum].velmnum; if (velmnum == ~0) /* If unallocated slot */ continue; /* Skip to next slot */ ncmpcut2 = ncmpgain2 = ncmpgaindlt = 0; ncmpsize[0] = ncmpsize[1] = ncmpsize[2] = 0; velmpart = helmtab[helmnum].vertpart; for (eelmnum = meshptr->m.verttax[velmnum]; /* For all node neighbors */ eelmnum < meshptr->m.vendtax[velmnum]; eelmnum ++) { Gnum vnodnum; Gnum hnodnum; int vnodpart; Gnum vnloval; vnodnum = meshptr->m.edgetax[eelmnum]; vnloval = (meshptr->m.vnlotax == NULL) ? 1 : meshptr->m.vnlotax[vnodnum]; for (hnodnum = (vnodnum * VMESHSEPAFMHASHPRIME) & hashmsk; ; hnodnum = (hnodnum + 1) & hashmsk) { if (hnodtab[hnodnum].vnodnum == vnodnum) { /* If element found */ vnodpart = hnodtab[hnodnum].vertpart; if (vnodpart != 2) { if (vnodpart != velmpart) { errorPrint ("vmeshSeparateFmCheck: invalid separator node (1)"); return (1); } if ((meshptr->m.vendtax[vnodnum] - meshptr->m.verttax[vnodnum] - 1) == 0) ncmpgaindlt += (2 * vnodpart - 1) * 2 * vnloval; else { ncmpgain2 += vnloval; ncmpgaindlt += (2 * vnodpart - 1) * vnloval; } } else if (((hnodtab[hnodnum].ecmpsize0 == 1) && (velmpart == 0)) || ((hnodtab[hnodnum].ecmpsize0 == (meshptr->m.vendtax[vnodnum] - meshptr->m.verttax[vnodnum] - 1)) && (velmpart == 1))) { ncmpgain2 -= vnloval; ncmpgaindlt += (2 * velmpart - 1) * vnloval; } break; } if (hnodtab[hnodnum].vnodnum == ~0) { /* If element not present */ vnodpart = meshptr->parttax[vnodnum]; if (vnodpart != velmpart) { errorPrint ("vmeshSeparateFmCheck: invalid separator node (2)"); return (1); } if ((meshptr->m.vendtax[vnodnum] - meshptr->m.verttax[vnodnum]) == 1) { if (vnodpart == 2) { errorPrint ("vmeshSeparateFmCheck: invalid separator node (3)"); return (1); } ncmpgaindlt += (2 * vnodpart - 1) * 2 * vnloval; } else { ncmpgain2 += vnloval; ncmpgaindlt += (2 * vnodpart - 1) * vnloval; } break; } } ncmpsize[vnodpart] ++; } if ((ncmpsize[0] != 0) && (ncmpsize[1] != 0)) { errorPrint ("vmeshSeparateFmCheck: invalid element nodes"); return (1); } if (ncmpsize[2] != helmtab[helmnum].ncmpcut2) { errorPrint ("vmeshSeparateFmCheck: invalid element separator count"); return (1); } if ((ncmpgain2 != helmtab[helmnum].ncmpgain2) || (ncmpgaindlt != helmtab[helmnum].ncmpgaindlt)) { errorPrint ("vmeshSeparateFmCheck: invalid element gains"); return (1); } } memFree (parttax + meshptr->m.baseval); return (0); } #endif /* SCOTCH_DEBUG_VMESH3 */ scotch-6.0.4.dfsg/src/libscotch/vgraph_separate_fm.h0000644002563400244210000001513211631447170025646 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vgraph_separate_fm.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the improved Fiduccia-Mattheyses **/ /** graph separation routine. **/ /** **/ /** DATES : # Version 3.2 : from : 02 nov 1997 **/ /** to 20 nov 1997 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 28 dec 1998 **/ /** # Version 4.0 : from : 13 dec 2001 **/ /** to 18 aug 2004 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ Gain table subbits. +*/ #define VGRAPHSEPAFMGAINBITS 4 /*+ Prime number for hashing vertex numbers. +*/ #define VGRAPHSEPAFMHASHPRIME 17 /*+ Prime number for hashing +*/ /*+ Gain table vertex status. +*/ #define VGRAPHSEPAFMSTATEFREE ((GainLink *) 0) /*+ Vertex is free or separator-chained +*/ #define VGRAPHSEPAFMSTATESUCH ((GainLink *) 1) /*+ Separator vertex is used and chained +*/ #define VGRAPHSEPAFMSTATEUSED ((GainLink *) 2) /*+ Vertex already swapped once +*/ #define VGRAPHSEPAFMSTATELINK ((GainLink *) 3) /*+ Currently in gain table if higher +*/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct VgraphSeparateFmParam_ { INT movenbr; /*+ Maximum number of uneffective moves that can be done +*/ INT passnbr; /*+ Number of passes to be performed (-1 : infinite) +*/ double deltrat; /*+ Maximum weight imbalance ratio +*/ } VgraphSeparateFmParam; /*+ The hash vertex structure. For trick reasons, one of the gain table data structures is followed by a negative integer, and the other by a positive one. Thus, one can deduce the value of the pointer to the structure from a pointer to any of the gain table data structures. Moreover, some fields have special meaning: - gainlink0.next: state of vertex (see VGRAPHSEPAFMSTATEXXXX). - gainlink0.prev: simple chaining for separator vertices, if vertex is in chained state (((vertpart == 2) && (gainlink0.next == VGRAPHSEPAFMSTATEFREE)) || (gainlink0.next == VGRAPHSEPAFMSTATESUCH)). - gainlink1: double chained list of locked vertices, if ((gainlink0.next == VGRAPHSEPAFMSTATESUCH) || (gainlink0.next == VGRAPHSEPAFMSTATEUSED)). +*/ typedef struct VgraphSeparateFmVertex_ { GainLink gainlink0; /*+ Gain link if moved to part 0; FIRST +*/ Gnum veloval; /*+ TRICK: opposite of vertex load +*/ GainLink gainlink1; /*+ Gain link if moved to part 1; TRICK: before vertpart +*/ Gnum partval; /*+ Vertex part TRICK: same type as vertload +*/ Gnum compgain[2]; /*+ Separator gain if moved to given part; TRICK: not first +*/ Gnum mswpnum; /*+ Number of move sweep when data recorded +*/ Gnum vertnum; /*+ Number of vertex in hash table +*/ } VgraphSeparateFmVertex; /*+ The move recording structure. +*/ typedef struct VgraphSeparateFmSave_ { Gnum hashnum; /*+ Number of hash slot for saved vertex +*/ int partval; /*+ Saved vertex part value +*/ Gnum compgain[2]; /*+ Saved vertex gain +*/ } VgraphSeparateFmSave; /* ** The function prototypes. */ #ifndef VGRAPH_SEPARATE_FM #define static #endif int vgraphSeparateFm (Vgraph * const, const VgraphSeparateFmParam * const); static int vgraphSeparateFmResize (VgraphSeparateFmVertex * restrict * hashtabptr, Gnum * const, Gnum * const, VgraphSeparateFmSave * restrict *, const Gnum, GainTabl * const, GainLink * const); #ifdef SCOTCH_DEBUG_VGRAPH3 static int vgraphSeparateFmCheck (const Vgraph * const, const VgraphSeparateFmVertex * restrict const, const Gnum, const Gnum, const Gnum); #endif /* SCOTCH_DEBUG_VGRAPH3 */ static GainLink * vgraphSeparateFmTablGet (GainTabl * const, const Gnum, const Gnum, const int); #undef static scotch-6.0.4.dfsg/src/libscotch/library_mesh_io_habo.c0000644002563400244210000000664111631447170026151 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_mesh_io_habo.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the Harwell- **/ /** Boeing geometry and mesh handling **/ /** routines of the libSCOTCH library. **/ /** **/ /** DATES : # Version 4.0 : from : 19 jan 2004 **/ /** to 19 jan 2004 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "geom.h" #include "graph.h" #include "mesh.h" #include "scotch.h" /*************************************/ /* */ /* These routines are the C API for */ /* the Harwell-Boeing mesh and */ /* geometry handling routines. */ /* */ /*************************************/ /*+ This routine loads the given opaque geom *** structure with the data of the given stream. *** - 0 : if loading succeeded. *** - !0 : on error. +*/ int SCOTCH_meshGeomLoadHabo ( SCOTCH_Mesh * restrict const meshptr, SCOTCH_Geom * restrict const geomptr, FILE * const filesrcptr, FILE * const filegeoptr, const char * const dataptr) /* No use */ { return (meshGeomLoadHabo ((Mesh *) meshptr, (Geom *) geomptr, filesrcptr, filegeoptr, dataptr)); } scotch-6.0.4.dfsg/src/libscotch/library_dgraph_scatter_f.c0000644002563400244210000000653712056000126027024 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_scatter_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API for **/ /** the distributed source graph handling **/ /** routines of the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 16 feb 2007 **/ /** to 12 jul 2007 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "ptscotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the distributed graph handling */ /* routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFDGRAPHSCATTER, scotchfdgraphscatter, ( \ SCOTCH_Dgraph * const dgrfptr, \ SCOTCH_Graph * const cgrfptr, \ int * const revaptr), \ (dgrfptr, cgrfptr, revaptr)) { *revaptr = SCOTCH_dgraphScatter (dgrfptr, cgrfptr); } scotch-6.0.4.dfsg/src/libscotch/library_graph_part_ovl.c0000644002563400244210000001437712407311512026541 0ustar trophimeutilisateurs du domaine/* Copyright 2010,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_part_ovl.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the graph **/ /** partitioning routines with overlap of **/ /** the libSCOTCH library. **/ /** **/ /** DATES : # Version 6.0 : from : 28 may 2010 **/ /** to 20 sep 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "wgraph.h" #include "wgraph_part_st.h" #include "scotch.h" /************************************/ /* */ /* These routines are the C API for */ /* graph partitioning with overlap. */ /* */ /************************************/ /*+ This routine computes a partition with *** overlap of the given graph structure *** with respect to the given strategy. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_graphPartOvl ( SCOTCH_Graph * const grafptr, /*+ Graph to map +*/ const SCOTCH_Num partnbr, /*+ Number of parts +*/ SCOTCH_Strat * const straptr, /*+ Partitioning strategy +*/ SCOTCH_Num * const parttab) /*+ Partition array +*/ { Wgraph grafdat; const Strat * partstraptr; int o; if (*((Strat **) straptr) == NULL) /* Set default partitioning strategy if necessary */ SCOTCH_stratGraphPartOvlBuild (straptr, SCOTCH_STRATQUALITY, (Gnum) partnbr, (double) 0.05); partstraptr = *((Strat **) straptr); if (partstraptr->tabl != &wgraphpartststratab) { errorPrint ("SCOTCH_graphPartOvl: not a graph partitioning with overlap strategy"); return (1); } intRandInit (); /* Check that random number generator is initialized */ wgraphInit (&grafdat, (Graph *) grafptr, partnbr); /* Initialize graph from given graph */ grafdat.parttax = ((Gnum *) parttab) - grafdat.s.baseval; /* Directly use given part array */ grafdat.levlnum = 0; if (wgraphAlloc (&grafdat) != 0) { /* Always allocate graph data when calling */ errorPrint ("SCOTCH_graphPartOvl: out of memory"); return (1); } o = wgraphPartSt (&grafdat, partstraptr); wgraphExit (&grafdat); return (o); } /*+ This routine parses the given *** partitioning strategy. *** It returns: *** - 0 : if string successfully scanned. *** - !0 : on error. +*/ int SCOTCH_stratGraphPartOvl ( SCOTCH_Strat * const straptr, const char * const string) { if (*((Strat **) straptr) != NULL) stratExit (*((Strat **) straptr)); if ((*((Strat **) straptr) = stratInit (&wgraphpartststratab, string)) == NULL) { errorPrint ("SCOTCH_stratGraphPartOvl: error in sequential overlap partitioning strategy"); return (1); } return (0); } /*+ This routine provides predefined *** overlap partitioning strategies. *** It returns: *** - 0 : if string successfully initialized. *** - !0 : on error. +*/ int SCOTCH_stratGraphPartOvlBuild ( SCOTCH_Strat * const straptr, /*+ Strategy to create +*/ const SCOTCH_Num flagval, /*+ Desired characteristics +*/ const SCOTCH_Num partnbr, /*+ Number of expected parts/size +*/ const double balrat) /*+ Desired imbalance ratio +*/ { char bufftab[8192]; /* Should be enough */ char kbaltab[64]; sprintf (bufftab, "m{vert=%ld,low=r{sep=m{rat=0.7,vert=100,low=h{pass=10},asc=b{width=3,bnd=f{bal=},org=(|h{pass=10})f{bal=}}}|m{rat=0.7,vert=100,low=h{pass=10},asc=b{width=3,bnd=f{bal=},org=(|h{pass=10})f{bal=}}}},asc=f{bal=}}", (long) (20 * partnbr)); sprintf (kbaltab, "%lf", balrat); stringSubst (bufftab, "", kbaltab); if (SCOTCH_stratGraphPartOvl (straptr, bufftab) != 0) { errorPrint ("SCOTCH_stratGraphPartOvlBuild: error in sequential overlap partitioning strategy"); return (1); } return (0); } scotch-6.0.4.dfsg/src/libscotch/hmesh_order_hf.h0000644002563400244210000000666011631447170024773 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2009 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh_order_hf.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the block-oriented Halo **/ /** Approximate (Multiple) Minimum Fill **/ /** mesh ordering routine. **/ /** **/ /** DATES : # Version 4.0 : from : 09 dec 2003 **/ /** to 10 dec 2003 **/ /** # Version 5.1 : from : 01 oct 2009 **/ /** to : 01 oct 2009 **/ /** **/ /************************************************************/ /* ** The defines. */ #define HMESHORDERHFCOMPRAT 1.2L /*+ Compression ratio +*/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct HmeshOrderHfParam_ { INT colmin; /*+ Minimum number of columns +*/ INT colmax; /*+ Maximum number of columns +*/ double fillrat; /*+ Fill-in ratio +*/ } HmeshOrderHfParam; /* ** The function prototypes. */ #ifndef HMESH_ORDER_HF #define static #endif int hmeshOrderHf (const Hmesh * restrict const, Order * restrict const, const Gnum, OrderCblk * restrict const, const HmeshOrderHfParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/library_common_f.c0000644002563400244210000000646211766370532025341 0ustar trophimeutilisateurs du domaine/* Copyright 2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_common_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API for **/ /** the some miscellaneous routines **/ /** provided by the common files of the **/ /** libSCOTCH library. **/ /** **/ /** DATES : # Version 6.0 : from : 14 jun 2012 **/ /** to 14 jun 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for some miscellaneous routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFMEMCUR, scotchfmemcur, ( \ SCOTCH_Idx * const memoptr), \ (memoptr)) { *memoptr = SCOTCH_memCur (); } /* ** */ FORTRAN ( \ SCOTCHFMEMMAX, scotchfmemmax, ( \ SCOTCH_Idx * const memoptr), \ (memoptr)) { *memoptr = SCOTCH_memMax (); } scotch-6.0.4.dfsg/src/libscotch/library_graph_check_f.c0000644002563400244210000000633111631447170026274 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_check_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API for **/ /** the source graph handling routines of **/ /** the libSCOTCH library. **/ /** **/ /** DATES : # Version 3.4 : from : 02 dec 1999 **/ /** to 15 nov 2001 **/ /** # Version 4.0 : from : 11 dec 2001 **/ /** to 22 apr 2004 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the graph handling routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFGRAPHCHECK, scotchfgraphcheck, ( \ const SCOTCH_Graph * const grafptr, \ int * const revaptr), \ (grafptr, revaptr)) { *revaptr = SCOTCH_graphCheck (grafptr); } scotch-6.0.4.dfsg/src/libscotch/kgraph_map_st.c0000644002563400244210000004614412412035373024626 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2009-2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph_map_st.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module contains the strategy and **/ /** method tables for the multi-way static **/ /** mapping routines. **/ /** **/ /** DATES : # Version 3.2 : from : 15 oct 1996 **/ /** to 26 may 1998 **/ /** # Version 3.3 : from : 19 oct 1998 **/ /** to 17 may 1999 **/ /** # Version 3.4 : from : 12 sep 2001 **/ /** to 12 sep 2001 **/ /** # Version 4.0 : from : 12 jan 2004 **/ /** to 05 jan 2005 **/ /** # Version 5.1 : from : 04 oct 2009 **/ /** to 29 mar 2011 **/ /** # Version 6.0 : from : 03 mar 2011 **/ /** to 28 sep 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define KGRAPH_MAP_ST #include "module.h" #include "common.h" #include "parser.h" #include "gain.h" #include "fibo.h" #include "graph.h" #include "arch.h" #include "graph_coarsen.h" #include "mapping.h" #include "bgraph.h" #include "bgraph_bipart_st.h" #include "kgraph.h" #include "kgraph_map_bd.h" #include "kgraph_map_cp.h" #include "kgraph_map_df.h" #include "kgraph_map_ex.h" #include "kgraph_map_fm.h" #include "kgraph_map_ml.h" #include "kgraph_map_rb.h" #include "kgraph_map_st.h" /* ** The static and global variables. */ static Kgraph kgraphdummy; /*+ Dummy active graph for offset computations +*/ static union { KgraphMapBdParam param; StratNodeMethodData padding; } kgraphmapstdefaultbd = { { 3, &stratdummy, &stratdummy } }; static union { StratNodeMethodData padding; } kgraphmapstdefaultcp; static union { KgraphMapDfParam param; StratNodeMethodData padding; } kgraphmapstdefaultdf = { { 40, 1.0F, 0.0F } }; static union { KgraphMapExParam param; StratNodeMethodData padding; } kgraphmapstdefaultex = { { 0.05 } }; static union { KgraphMapFmParam param; StratNodeMethodData padding; } kgraphmapstdefaultfm = { { 200, ~0, 0.05 } }; static union { KgraphMapMlParam param; StratNodeMethodData padding; } kgraphmapstdefaultml = { { 100, 0.8, &stratdummy, &stratdummy, 0 } }; static union { KgraphMapRbParam param; StratNodeMethodData padding; } kgraphmapstdefaultrb = { { 1, 1, KGRAPHMAPRBPOLINGSIZE, &stratdummy, 0.05 } }; static StratMethodTab kgraphmapstmethtab[] = { /* Mapping methods array */ { KGRAPHMAPSTMETHBD, "b", kgraphMapBd, &kgraphmapstdefaultbd }, { KGRAPHMAPSTMETHCP, "c", kgraphMapCp, &kgraphmapstdefaultcp }, { KGRAPHMAPSTMETHDF, "d", kgraphMapDf, &kgraphmapstdefaultdf }, { KGRAPHMAPSTMETHEX, "x", kgraphMapEx, &kgraphmapstdefaultex }, { KGRAPHMAPSTMETHFM, "f", kgraphMapFm, &kgraphmapstdefaultfm }, { KGRAPHMAPSTMETHML, "m", kgraphMapMl, &kgraphmapstdefaultml }, { KGRAPHMAPSTMETHRB, "r", kgraphMapRb, &kgraphmapstdefaultrb }, { -1, NULL, NULL, NULL } }; static StratParamTab kgraphmapstparatab[] = { /* Method parameter list */ { KGRAPHMAPSTMETHBD, STRATPARAMINT, "width", (byte *) &kgraphmapstdefaultbd.param, (byte *) &kgraphmapstdefaultbd.param.distmax, NULL }, { KGRAPHMAPSTMETHBD, STRATPARAMSTRAT, "bnd", (byte *) &kgraphmapstdefaultbd.param, (byte *) &kgraphmapstdefaultbd.param.stratbnd, (void *) &kgraphmapststratab }, { KGRAPHMAPSTMETHBD, STRATPARAMSTRAT, "org", (byte *) &kgraphmapstdefaultbd.param, (byte *) &kgraphmapstdefaultbd.param.stratorg, (void *) &kgraphmapststratab }, { KGRAPHMAPSTMETHDF, STRATPARAMINT, "pass", (byte *) &kgraphmapstdefaultdf.param, (byte *) &kgraphmapstdefaultdf.param.passnbr, NULL }, { KGRAPHMAPSTMETHDF, STRATPARAMDOUBLE, "dif", (byte *) &kgraphmapstdefaultdf.param, (byte *) &kgraphmapstdefaultdf.param.cdifval, NULL }, { KGRAPHMAPSTMETHDF, STRATPARAMDOUBLE, "rem", (byte *) &kgraphmapstdefaultdf.param, (byte *) &kgraphmapstdefaultdf.param.cremval, NULL }, { KGRAPHMAPSTMETHEX, STRATPARAMDOUBLE, "bal", (byte *) &kgraphmapstdefaultex.param, (byte *) &kgraphmapstdefaultex.param.kbalval, (void *) &kgraphmapststratab }, { KGRAPHMAPSTMETHFM, STRATPARAMINT, "move", (byte *) &kgraphmapstdefaultfm.param, (byte *) &kgraphmapstdefaultfm.param.movenbr, NULL }, { KGRAPHMAPSTMETHFM, STRATPARAMINT, "pass", (byte *) &kgraphmapstdefaultfm.param, (byte *) &kgraphmapstdefaultfm.param.passnbr, NULL }, { KGRAPHMAPSTMETHFM, STRATPARAMDOUBLE, "bal", (byte *) &kgraphmapstdefaultfm.param, (byte *) &kgraphmapstdefaultfm.param.deltval, NULL }, { KGRAPHMAPSTMETHML, STRATPARAMSTRAT, "asc", (byte *) &kgraphmapstdefaultml.param, (byte *) &kgraphmapstdefaultml.param.stratasc, (void *) &kgraphmapststratab }, { KGRAPHMAPSTMETHML, STRATPARAMSTRAT, "low", (byte *) &kgraphmapstdefaultml.param, (byte *) &kgraphmapstdefaultml.param.stratlow, (void *) &kgraphmapststratab }, { KGRAPHMAPSTMETHML, STRATPARAMINT, "vert", (byte *) &kgraphmapstdefaultml.param, (byte *) &kgraphmapstdefaultml.param.coarnbr, NULL }, { KGRAPHMAPSTMETHML, STRATPARAMDOUBLE, "rat", (byte *) &kgraphmapstdefaultml.param, (byte *) &kgraphmapstdefaultml.param.coarval, NULL }, { KGRAPHMAPSTMETHML, STRATPARAMCASE, "type", (byte *) &kgraphmapstdefaultml.param, (byte *) &kgraphmapstdefaultml.param.typeval, (void *) "hscd" }, { KGRAPHMAPSTMETHRB, STRATPARAMCASE, "job", (byte *) &kgraphmapstdefaultrb.param, (byte *) &kgraphmapstdefaultrb.param.flagjobtie, (void *) "ut" }, { KGRAPHMAPSTMETHRB, STRATPARAMDOUBLE, "bal", (byte *) &kgraphmapstdefaultrb.param, (byte *) &kgraphmapstdefaultrb.param.kbalval, NULL }, { KGRAPHMAPSTMETHRB, STRATPARAMCASE, "map", (byte *) &kgraphmapstdefaultrb.param, (byte *) &kgraphmapstdefaultrb.param.flagmaptie, (void *) "ut" }, { KGRAPHMAPSTMETHRB, STRATPARAMCASE, "poli", (byte *) &kgraphmapstdefaultrb.param, (byte *) &kgraphmapstdefaultrb.param.polival, (void *) "rls LS" }, { KGRAPHMAPSTMETHRB, STRATPARAMSTRAT, "sep", (byte *) &kgraphmapstdefaultrb.param, (byte *) &kgraphmapstdefaultrb.param.strat, (void *) &bgraphbipartststratab }, { KGRAPHMAPSTMETHNBR, STRATPARAMINT, NULL, NULL, NULL, NULL } }; static StratParamTab kgraphmapstcondtab[] = { /* Graph condition parameter table */ { STRATNODECOND, STRATPARAMINT, "load", (byte *) &kgraphdummy, (byte *) &kgraphdummy.s.velosum, NULL }, { STRATNODECOND, STRATPARAMINT, "levl", (byte *) &kgraphdummy, (byte *) &kgraphdummy.levlnum, NULL }, { STRATNODECOND, STRATPARAMINT, "edge", (byte *) &kgraphdummy, (byte *) &kgraphdummy.s.edgenbr, NULL }, { STRATNODECOND, STRATPARAMINT, "vert", (byte *) &kgraphdummy, (byte *) &kgraphdummy.s.vertnbr, NULL }, { STRATNODENBR, STRATPARAMINT, NULL, NULL, NULL, NULL } }; StratTab kgraphmapststratab = { /* Strategy tables for graph mapping methods */ kgraphmapstmethtab, kgraphmapstparatab, kgraphmapstcondtab }; /****************************************/ /* */ /* This is the generic mapping routine. */ /* */ /****************************************/ /* This routine computes the given ** mapping according to the given ** strategy. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int kgraphMapSt ( Kgraph * restrict const grafptr, /*+ Mapping graph +*/ const Strat * restrict const strat) /*+ Mapping strategy +*/ { StratTest val; /* Result of condition evaluation */ KgraphStore savetab[2]; /* Results of the two strategies */ Gnum comploaddltasu[2]; /* Absolute sum of computation load delta */ ArchDom domnfrst; /* Largest domain in the architecture */ Anum partnbr; /* Number of processors in the target topology */ Anum partnum; int o; int o2; #ifdef SCOTCH_DEBUG_KGRAPH2 if (sizeof (Gnum) != sizeof (INT)) { errorPrint ("kgraphMapSt: invalid type specification for parser variables"); return (1); } if ((sizeof (KgraphMapRbParam) > sizeof (StratNodeMethodData))) { errorPrint ("kgraphMapSt: invalid type specification"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH2 */ #ifdef SCOTCH_DEBUG_KGRAPH1 if ((strat->tabl != &kgraphmapststratab) && (strat != &stratdummy)) { errorPrint ("kgraphMapSt: invalid parameter (1)"); return (1); } #endif /* SCOTCH_DEBUG_KGRAPH1 */ o = 0; switch (strat->type) { case STRATNODECONCAT : o = kgraphMapSt (grafptr, strat->data.concat.strat[0]); /* Apply first strategy */ if (o == 0) /* If it worked all right */ o |= kgraphMapSt (grafptr, strat->data.concat.strat[1]); /* Then apply second strategy */ break; case STRATNODECOND : o = stratTestEval (strat->data.cond.test, &val, (void *) grafptr); /* Evaluate expression */ if (o == 0) { /* If evaluation was correct */ #ifdef SCOTCH_DEBUG_KGRAPH2 if ((val.typetest != STRATTESTVAL) || (val.typenode != STRATPARAMLOG)) { errorPrint ("kgraphMapSt: invalid test result"); o = 1; break; } #endif /* SCOTCH_DEBUG_KGRAPH2 */ if (val.data.val.vallog == 1) /* If expression is true */ o = kgraphMapSt (grafptr, strat->data.cond.strat[0]); /* Apply first strategy */ else { /* Else if expression is false */ if (strat->data.cond.strat[1] != NULL) /* And if there is an else statement */ o = kgraphMapSt (grafptr, strat->data.cond.strat[1]); /* Apply second strategy */ } } break; case STRATNODEEMPTY : break; case STRATNODESELECT : archDomFrst (&grafptr->a, &domnfrst); /* Get architecture domain */ partnbr = archDomSize (&grafptr->a, &domnfrst); /* Get architecture size */ if (((kgraphStoreInit (grafptr, &savetab[0])) != 0) || /* Allocate save areas */ ((kgraphStoreInit (grafptr, &savetab[1])) != 0)) { errorPrint ("kgraphMapSt: out of memory"); kgraphStoreExit (&savetab[0]); return (1); } kgraphStoreSave (grafptr, &savetab[1]); /* Save initial partition */ o = kgraphMapSt (grafptr, strat->data.select.strat[0]); /* Apply first strategy */ kgraphStoreSave (grafptr, &savetab[0]); /* Save its result */ kgraphStoreUpdt (grafptr, &savetab[1]); /* Restore initial partition */ o2 = kgraphMapSt (grafptr, strat->data.select.strat[1]); /* Apply second strategy */ if ((o == 0) || (o2 == 0)) { /* If at least one method has computed a partition */ Gnum comploadadlt; int b0; int b1; comploaddltasu[0] = comploaddltasu[1] = 0; b0 = o; /* Assume that balance is invalid if partitioning has failed */ b1 = o2; for (partnum = 0; partnum < partnbr; partnum ++) { comploadadlt = abs (savetab[0].comploaddlt[partnum]); if (comploadadlt > ((Gnum) ((double) savetab[0].comploadavg[partnum] * savetab[0].kbalval))) b0 |= 1; comploaddltasu[0] += comploadadlt; comploadadlt = abs (grafptr->comploaddlt[partnum]); if (comploadadlt > ((Gnum) ((double) grafptr->comploadavg[partnum] * grafptr->kbalval))) b1 |= 1; comploaddltasu[1] += comploadadlt; } do { /* Do we want to restore partition 0? */ if (b0 > b1) break; if (b0 == b1) { /* If both are valid or invalid */ if (b0 == 0) { /* If both are valid */ if ( (savetab[0].commload > grafptr->commload) || /* Compare on cut */ ((savetab[0].commload == grafptr->commload) && (comploaddltasu[0] > comploaddltasu[1]))) break; } else { /* If both are invalid */ if ( (comploaddltasu[0] > comploaddltasu[1]) || /* Compare on imbalance */ ((comploaddltasu[0] == comploaddltasu[1]) && (savetab[0].commload > grafptr->commload))) break; } } kgraphStoreUpdt (grafptr, &savetab[0]); /* Restore its result */ } while (0); } if (o2 < o) /* o = min(o,o2): if one parts, then part */ o = o2; /* Else if one stops, then stop, else error */ kgraphStoreExit (&savetab[0]); /* Free both save areas */ kgraphStoreExit (&savetab[1]); break; #ifdef SCOTCH_DEBUG_KGRAPH1 case STRATNODEMETHOD : #else /* SCOTCH_DEBUG_KGRAPH1 */ default : #endif /* SCOTCH_DEBUG_KGRAPH1 */ return (strat->tabl->methtab[strat->data.method.meth].func (grafptr, (void *) &strat->data.method.data)); #ifdef SCOTCH_DEBUG_KGRAPH1 default : errorPrint ("kgraphMapSt: invalid parameter (2)"); return (1); #endif /* SCOTCH_DEBUG_KGRAPH1 */ } return (o); } scotch-6.0.4.dfsg/src/libscotch/hdgraph_order_nd.h0000644002563400244210000001222111631447170025276 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hdgraph_order_nd.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the halo distributed graph nested **/ /** dissection ordering algorithm. **/ /** **/ /** DATES : # Version 5.0 : from : 16 apr 2006 **/ /** to 16 jun 2007 **/ /** # Version 5.1 : from : 11 nov 2008 **/ /** to 04 nov 2010 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct HdgraphOrderNdParam_ { Strat * sepstrat; /*+ Separation strategy +*/ Strat * ordstratlea; /*+ Leaf ordering strategy +*/ Strat * ordstratsep; /*+ Separator ordering strategy +*/ Strat * ordstratseq; /*+ Sequential ordering strategy +*/ } HdgraphOrderNdParam; /*+ Method types. +*/ typedef enum HdgraphOrderNdType_ { HDGRAPHORDERNDTYPECENT = 0, /*+ Centralized folded graph +*/ HDGRAPHORDERNDTYPEDIST /*+ Distributed folded graph +*/ } HdgraphOrderNdType; /*+ This structure holds folded graph data, whether centralized or distributed. +*/ typedef struct HdgraphOrderNdGraph_ { HdgraphOrderNdType typeval; /*+ Halo graph type +*/ union { Hgraph cgrfdat; /*+ Centralized halo graph +*/ Hdgraph dgrfdat; /*+ Distributed halo graph +*/ } data; } HdgraphOrderNdGraph; /*+ This structure holds the data passed to the subgraph building threads. +*/ typedef struct HdgraphOrderNdData_ { Hdgraph * orggrafptr; /*+ Pointer to original graph +*/ Gnum indlistnbr; /*+ Local number of vertices in subgraph +*/ const Gnum * indlisttab; /*+ Local list of vertices in subgraph +*/ HdgraphOrderNdGraph * fldgrafptr; /*+ Pointer to folded graph union area +*/ int fldpartval; /*+ Part of processor array to which to fold to +*/ int fldprocnbr; /*+ Number of processes in folded communicator +*/ int fldprocnum; /*+ Rank of process in folded communicator, or -1 +*/ MPI_Comm fldproccomm; /*+ Communicator for the folded graph, if any +*/ } HdgraphOrderNdData; /* ** The function prototypes. */ #ifndef HDGRAPH_ORDER_ND #define static #endif static void * hdgraphOrderNdFold2 (void * const); static int hdgraphOrderNdFold (Hdgraph * restrict const, const Gnum, const Gnum * restrict const, const Gnum, const Gnum * restrict const, HdgraphOrderNdGraph * restrict const); int hdgraphOrderNd (Hdgraph * const, DorderCblk * const, const HdgraphOrderNdParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/dgraph_redist.h0000644002563400244210000000574012023651167024633 0ustar trophimeutilisateurs du domaine/* Copyright 2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_redist.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the data declara- **/ /** tions for the graph redistribution **/ /** routine. **/ /** **/ /** DATES : # Version 6.0 : from : 10 may 2010 **/ /** to : 11 sep 2012 **/ /** **/ /************************************************************/ /* ** The function prototypes. */ #ifndef DGRAPH_REDIST #define static #endif int dgraphRedist (Dgraph * restrict const, const Gnum * restrict const, const Gnum * restrict const, const Gnum, const Gnum, Dgraph * restrict const); static int dgraphRedist2 (Dgraph * restrict const, const Gnum * restrict const, const Gnum * restrict const, const Gnum * const, const Gnum * const, const Gnum, const Gnum, Dgraph * restrict const); #undef static scotch-6.0.4.dfsg/src/libscotch/common_stub.c0000644002563400244210000000621111631447170024327 0ustar trophimeutilisateurs du domaine/* Copyright 2008,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : common_stub.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are common stub routines **/ /** for several systems, used by all **/ /** modules. **/ /** **/ /** DATES : # Version 5.0 : from : 11 may 2008 **/ /** to 11 may 2008 **/ /** # Version 5.1 : from : 27 jun 2010 **/ /** to 01 jul 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define COMMON #ifndef COMMON_NOMODULE #include "module.h" #endif /* COMMON_NOMODULE */ #include "common.h" /* ** The static and global variables. */ int commonStubDummy; /* Dummy variable so that the object file will never be empty */ /******************/ /* */ /* Stub routines. */ /* */ /******************/ #ifdef COMMON_STUB_FORK int fork () { errorPrint ("fork() not implemented on this system"); return (-1); } #endif /* COMMON_STUB_FORK */ scotch-6.0.4.dfsg/src/libscotch/library_dgraph_f.c0000644002563400244210000001512112055775352025307 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API for **/ /** the distributed source graph handling **/ /** routines of the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 04 sep 2006 **/ /** to 05 aug 2007 **/ /** # Version 5.1 : from : 27 jul 2008 **/ /** to 15 apr 2010 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "ptscotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the graph handling routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFDGRAPHINIT, scotchfdgraphinit, ( \ SCOTCH_Dgraph * const grafptr, \ const MPI_Fint * const commptr, \ int * const revaptr), \ (grafptr, commptr, revaptr)) { MPI_Comm commdat; commdat = MPI_Comm_f2c (*commptr); *revaptr = SCOTCH_dgraphInit (grafptr, commdat); } /* ** */ FORTRAN ( \ SCOTCHFDGRAPHEXIT, scotchfdgraphexit, ( \ SCOTCH_Dgraph * const grafptr), \ (grafptr)) { SCOTCH_dgraphExit (grafptr); } /* ** */ FORTRAN ( \ SCOTCHFDGRAPHSIZE, scotchfdgraphsize, ( \ const SCOTCH_Dgraph * const grafptr, \ SCOTCH_Num * const vertglbptr, \ SCOTCH_Num * const vertlocptr, \ SCOTCH_Num * const edgeglbptr, \ SCOTCH_Num * const edgelocptr), \ (grafptr, vertglbptr, vertlocptr, edgeglbptr, edgelocptr)) { SCOTCH_dgraphSize (grafptr, vertglbptr, vertlocptr, edgeglbptr, edgelocptr); } /* ** */ FORTRAN ( \ SCOTCHFDGRAPHDATA, scotchfdgraphdata, ( \ const SCOTCH_Dgraph * const grafptr, \ const SCOTCH_Num * const indxptr, \ SCOTCH_Num * const baseptr, \ SCOTCH_Num * const vertglbptr, \ SCOTCH_Num * const vertlocptr, \ SCOTCH_Num * const vertlocptz, \ SCOTCH_Num * const vertgstptr, \ SCOTCH_Idx * const vertlocidx, \ SCOTCH_Idx * const vendlocidx, \ SCOTCH_Idx * const velolocidx, \ SCOTCH_Idx * const vlbllocidx, \ SCOTCH_Num * const edgeglbptr, \ SCOTCH_Num * const edgelocptr, \ SCOTCH_Num * const edgelocptz, \ SCOTCH_Idx * const edgelocidx, \ SCOTCH_Idx * const edgegstidx, \ SCOTCH_Idx * const edlolocidx, \ MPI_Fint * const commptr), \ (grafptr, indxptr, baseptr, \ vertglbptr, vertlocptr, vertlocptz, \ vertgstptr, vertlocidx, vendlocidx, \ velolocidx, vlbllocidx, edgeglbptr, \ edgelocptr, edgelocptz, edgelocidx, \ edgegstidx, edlolocidx, commptr)) { SCOTCH_Num * vertloctab; /* Pointer to graph arrays */ SCOTCH_Num * vendloctab; SCOTCH_Num * veloloctab; SCOTCH_Num * vlblloctab; SCOTCH_Num * edgeloctab; SCOTCH_Num * edgegsttab; SCOTCH_Num * edloloctab; MPI_Comm commdat; SCOTCH_dgraphData (grafptr, baseptr, vertglbptr, vertlocptr, vertlocptz, vertgstptr, &vertloctab, &vendloctab, &veloloctab, &vlblloctab, edgeglbptr, edgelocptr, edgelocptz, &edgeloctab, &edgegsttab, &edloloctab, &commdat); *vertlocidx = (vertloctab - indxptr) + 1; /* Add 1 since Fortran indices start at 1 */ *vendlocidx = (vendloctab - indxptr) + 1; *velolocidx = (veloloctab != NULL) ? (veloloctab - indxptr) + 1 : *vertlocidx; *vlbllocidx = (vlblloctab != NULL) ? (vlblloctab - indxptr) + 1 : *vertlocidx; *edgelocidx = (edgeloctab - indxptr) + 1; *edgegstidx = (edgegsttab != NULL) ? (edgegsttab - indxptr) + 1 : *vertlocidx; *edlolocidx = (edloloctab != NULL) ? (edloloctab - indxptr) + 1 : *vertlocidx; *commptr = MPI_Comm_c2f (commdat); } scotch-6.0.4.dfsg/src/libscotch/library_version.c0000644002563400244210000000642411631447170025221 0ustar trophimeutilisateurs du domaine/* Copyright 2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_version.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains miscellaneous **/ /** routines for handling API- and **/ /** version-related routines in the **/ /** libSCOTCH library. **/ /** **/ /** DATES : # Version 5.1 : from : 16 nov 2010 **/ /** to 16 nov 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /************************************/ /* */ /* These routines are the C API for */ /* miscellaneous routines. */ /* */ /************************************/ /*+ This routine returns the version, *** release and patchlevel numbers of *** the library being used (useful for *** dynamic libraries). *** It returns: *** - void : in all cases. +*/ void SCOTCH_version ( int * const versptr, int * const relaptr, int * const patcptr) { *versptr = SCOTCH_VERSION; *relaptr = SCOTCH_RELEASE; *patcptr = SCOTCH_PATCHLEVEL; } scotch-6.0.4.dfsg/src/libscotch/bdgraph_bipart_df.c0000644002563400244210000004530512400671357025433 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bdgraph_bipart_df.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module computes a bipartition of **/ /** the given distributed separator graph **/ /** by applying a diffusion method to what **/ /** is assumed to be a distributed band **/ /** graph. **/ /** **/ /** DATES : # Version 5.1 : from : 16 nov 2007 **/ /** to : 19 jul 2011 **/ /** # Version 6.0 : from : 11 sep 2011 **/ /** to : 31 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define BDGRAPH_BIPART_DF #include "module.h" #include "common.h" #include "arch.h" #include "dgraph.h" #include "bdgraph.h" #include "bdgraph_bipart_df.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine computes a distributed bipartition ** by diffusion across what is assumed to be a ** distributed band graph. ** It returns: ** - 0 : if the bipartition could be computed. ** - !0 : on error. */ int bdgraphBipartDf ( Bdgraph * const grafptr, /*+ Distributed graph +*/ const BdgraphBipartDfParam * const paraptr) /*+ Method parameters +*/ { float * restrict ielsloctax; /* Inverse of degree array */ float * restrict veexloctax; /* Veexval over domndist */ float * restrict difogsttax; /* Old diffusion value array */ float * restrict difngsttax; /* New diffusion value array */ const Gnum * restrict edgegsttax; Gnum fronlocnum; Gnum veexlocnbr; float vanclocval[2]; float valolocval[2]; /* Fraction of load to remove from anchor vertices at each step */ Gnum vanclocnnd; Gnum vertlocnum; Gnum complocload1; Gnum complocsize1; Gnum commlocloadintn; Gnum commlocloadextn; Gnum commlocgainextn; Gnum reduloctab[6]; Gnum reduglbtab[6]; Gnum passnum; float cdifval; float cremval; int ovflval; /* Overflow flag value */ const Gnum * restrict const veloloctax = grafptr->s.veloloctax; const Gnum * restrict const edloloctax = grafptr->s.edloloctax; if (dgraphGhst (&grafptr->s) != 0) { /* Compute ghost edge array if not already present */ errorPrint ("bdgraphBipartDf: cannot compute ghost edge array"); return (1); } reduloctab[0] = grafptr->s.vendloctax[grafptr->s.vertlocnnd - 2] - grafptr->s.vertloctax[grafptr->s.vertlocnnd - 2] - (grafptr->s.procglbnbr - 1); /* Local degree of both anchor vertices, minus edges to other anchors */ reduloctab[1] = grafptr->s.vendloctax[grafptr->s.vertlocnnd - 1] - grafptr->s.vertloctax[grafptr->s.vertlocnnd - 1] - (grafptr->s.procglbnbr - 1); /* Anchor edges have load 1 even for weighted graphs */ if (grafptr->s.veloloctax == NULL) reduloctab[2] = /* Weights of anchors */ reduloctab[3] = 1; else { reduloctab[2] = grafptr->s.veloloctax[grafptr->s.vertlocnnd - 2]; reduloctab[3] = grafptr->s.veloloctax[grafptr->s.vertlocnnd - 1]; } veexlocnbr = (grafptr->veexloctax != NULL) ? grafptr->s.vertlocnbr : 0; if (memAllocGroup ((void **) (void *) &ielsloctax, (size_t) (grafptr->s.vertlocnbr * sizeof (float)), &veexloctax, (size_t) (veexlocnbr * sizeof (float)), &difogsttax, (size_t) (grafptr->s.vertgstnbr * sizeof (float)), &difngsttax, (size_t) (grafptr->s.vertgstnbr * sizeof (float)), NULL) == NULL) { errorPrint ("bdgraphBipartDf: out of memory"); reduloctab[0] = -1; } ielsloctax -= grafptr->s.baseval; difogsttax -= grafptr->s.baseval; difngsttax -= grafptr->s.baseval; veexloctax = (grafptr->veexloctax != NULL) ? (veexloctax - grafptr->s.baseval) : NULL; if (MPI_Allreduce (reduloctab, reduglbtab, 4, GNUM_MPI, MPI_SUM, grafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphBipartDf: communication error (1)"); return (1); } if (reduglbtab[0] < 0) { if (ielsloctax != NULL) memFree (ielsloctax + grafptr->s.baseval); /* Free group leader */ return (1); } if ((reduglbtab[0] == 0) || /* If graph is too small to have any usable anchors, leave partition as is */ (reduglbtab[1] == 0)) { memFree (ielsloctax + grafptr->s.baseval); if (dgraphHaloSync (&grafptr->s, (byte *) (void *) (grafptr->partgsttax + grafptr->s.baseval), GRAPHPART_MPI) != 0) { errorPrint ("bdgraphBipartDf: cannot propagate part data (1)"); return (1); } return (0); } vanclocval[0] = (float) ((paraptr->typeval == BDGRAPHBIPARTDFTYPEBAL) /* If balanced parts wanted */ ? grafptr->compglbload0avg /* Target is average */ : ( (grafptr->compglbload0 < grafptr->compglbload0min) ? grafptr->compglbload0min : /* Else keep load if not off balance */ ((grafptr->compglbload0 > grafptr->compglbload0max) ? grafptr->compglbload0max : grafptr->compglbload0))); vanclocval[1] = (float) grafptr->s.veloglbsum - vanclocval[0]; vanclocval[0] = - vanclocval[0]; /* Part 0 holds negative values */ valolocval[0] = (float) reduglbtab[2]; /* Compute values to remove from anchor vertices */ valolocval[1] = (float) reduglbtab[3] - BDGRAPHBIPARTDFEPSILON; /* Slightly tilt value to add to part 1 */ vanclocnnd = grafptr->s.vertlocnnd - 2; /* Do not account for anchor vertices in diffusion computations */ if (grafptr->s.edloloctax != NULL) { for (vertlocnum = grafptr->s.baseval; vertlocnum < vanclocnnd; vertlocnum ++) { Gnum edgelocnum; Gnum edgelocnnd; Gnum edlolocsum; #ifdef SCOTCH_DEBUG_BDGRAPH2 if ((grafptr->s.vendloctax[vertlocnum] - grafptr->s.vertloctax[vertlocnum]) == 0) { errorPrint ("bdgraphBipartDf: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_BDGRAPH2 */ difogsttax[vertlocnum] = 0.0F; for (edgelocnum = grafptr->s.vertloctax[vertlocnum], edgelocnnd = grafptr->s.vendloctax[vertlocnum], edlolocsum = 0; edgelocnum < edgelocnnd; edgelocnum ++) edlolocsum += grafptr->s.edloloctax[edgelocnum]; ielsloctax[vertlocnum] = 1.0F / (float) edlolocsum; } } else { /* Graph has no edge loads */ for (vertlocnum = grafptr->s.baseval; vertlocnum < vanclocnnd; vertlocnum ++) { #ifdef SCOTCH_DEBUG_BDGRAPH2 if ((grafptr->s.vendloctax[vertlocnum] - grafptr->s.vertloctax[vertlocnum]) == 0) { errorPrint ("bdgraphBipartDf: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_BDGRAPH2 */ ielsloctax[vertlocnum] = 1.0F / (float) (grafptr->s.vendloctax[vertlocnum] - grafptr->s.vertloctax[vertlocnum]); difogsttax[vertlocnum] = 0.0F; } } ielsloctax[vanclocnnd] = 1.0F / (float) reduglbtab[0]; ielsloctax[vanclocnnd + 1] = 1.0F / (float) reduglbtab[1]; difogsttax[vanclocnnd] = vanclocval[0] * ielsloctax[vanclocnnd]; /* Load anchor vertices for first pass */ difogsttax[vanclocnnd + 1] = vanclocval[1] * ielsloctax[vanclocnnd + 1]; difngsttax[vanclocnnd] = /* In case of isolated anchors, do not risk overflow because of NaN */ difngsttax[vanclocnnd + 1] = 0.0F; if (dgraphHaloSync (&grafptr->s, (byte *) (void *) (difogsttax + grafptr->s.baseval), MPI_FLOAT) != 0) { /* Perform initial diffusion (and build communication structures) */ errorPrint ("bdgraphBipartDf: cannot propagate diffusion data (1)"); memFree (ielsloctax + grafptr->s.baseval); /* Free group leader */ return (1); } ovflval = 0; cdifval = paraptr->cdifval; cremval = paraptr->cremval; edgegsttax = grafptr->s.edgegsttax; for (passnum = 0; ; ) { /* For all passes */ if (ovflval == 0) { /* If no overflow occured */ float * diftgsttax; /* Temporary swap value */ Gnum vertlocnum; float veloval; veloval = 1.0F; /* Assume no vertex loads */ for (vertlocnum = grafptr->s.baseval; vertlocnum < vanclocnnd; vertlocnum ++) { Gnum edgelocnum; Gnum edgelocnnd; float diffval; diffval = 0.0F; edgelocnum = grafptr->s.vertloctax[vertlocnum]; edgelocnnd = grafptr->s.vendloctax[vertlocnum]; if (grafptr->s.edloloctax != NULL) for ( ; edgelocnum < edgelocnnd; edgelocnum ++) diffval += difogsttax[edgegsttax[edgelocnum]] * (float) grafptr->s.edloloctax[edgelocnum]; else for ( ; edgelocnum < edgelocnnd; edgelocnum ++) diffval += difogsttax[edgegsttax[edgelocnum]]; diffval *= cdifval; diffval += (difogsttax[vertlocnum] * cremval) / ielsloctax[vertlocnum]; if (grafptr->s.veloloctax != NULL) veloval = (float) grafptr->s.veloloctax[vertlocnum]; if (diffval >= 0.0F) { diffval = (diffval - veloval) * ielsloctax[vertlocnum]; if (diffval <= 0.0F) diffval = +BDGRAPHBIPARTDFEPSILON; } else { diffval = (diffval + veloval) * ielsloctax[vertlocnum]; if (diffval >= 0.0F) diffval = -BDGRAPHBIPARTDFEPSILON; } if (isnan (diffval)) { /* If overflow occured */ ovflval = 1; /* We are in state of overflow */ goto abort; /* Exit this loop without swapping arrays */ } difngsttax[vertlocnum] = diffval; } for ( ; vertlocnum < grafptr->s.vertlocnnd; vertlocnum ++) { /* For the two local anchor vertices */ Gnum edgelocnum; Gnum edgelocnnd; float diffval; diffval = 0.0F; edgelocnum = grafptr->s.vertloctax[vertlocnum] + grafptr->s.procglbnbr - 1; /* Skip links to other anchors */ edgelocnnd = grafptr->s.vendloctax[vertlocnum]; if (edgelocnum == edgelocnnd) /* If isolated anchor */ continue; /* Barrel is empty */ for ( ; edgelocnum < edgelocnnd; edgelocnum ++) /* Anchor edges have load 1 even for weighted graphs */ diffval += difogsttax[edgegsttax[edgelocnum]]; diffval *= cdifval; diffval += vanclocval[vertlocnum - vanclocnnd] + (difogsttax[vertlocnum] * cremval) / ielsloctax[vertlocnum]; if (diffval >= 0.0F) { diffval = (diffval - valolocval[vertlocnum - vanclocnnd]) * ielsloctax[vertlocnum]; if (diffval <= 0.0F) diffval = +BDGRAPHBIPARTDFEPSILON; } else { diffval = (diffval + valolocval[vertlocnum - vanclocnnd]) * ielsloctax[vertlocnum]; if (diffval >= 0.0F) diffval = -BDGRAPHBIPARTDFEPSILON; } if (isnan (diffval)) { /* If overflow occured */ ovflval = 1; /* We are in state of overflow */ goto abort; /* Exit this loop without swapping arrays */ } difngsttax[vertlocnum] = diffval; } diftgsttax = (float *) difngsttax; /* Swap old and new diffusion arrays */ difngsttax = (float *) difogsttax; /* Casts to prevent IBM compiler from yelling */ difogsttax = (float *) diftgsttax; } abort : /* If overflow occured, resume here */ if (++ passnum >= paraptr->passnbr) /* If maximum number of passes reached */ break; /* Exit main loop */ if (dgraphHaloSync (&grafptr->s, (byte *) (void *) (difogsttax + grafptr->s.baseval), MPI_FLOAT) != 0) { errorPrint ("bdgraphBipartDf: cannot propagate diffusion data (2)"); memFree (ielsloctax + grafptr->s.baseval); /* Free group leader */ return (1); } } for (vertlocnum = grafptr->s.baseval; vertlocnum < vanclocnnd; vertlocnum ++) /* Set new part distribution */ grafptr->partgsttax[vertlocnum] = (difogsttax[vertlocnum] <= 0.0F) ? 0 : 1; grafptr->partgsttax[vanclocnnd] = 0; /* Set up parts in case anchors are isolated */ grafptr->partgsttax[vanclocnnd + 1] = 1; memFree (ielsloctax + grafptr->s.baseval); /* Free group leader */ if (dgraphHaloSync (&grafptr->s, (byte *) (void *) (grafptr->partgsttax + grafptr->s.baseval), GRAPHPART_MPI) != 0) { errorPrint ("bdgraphBipartDf: cannot propagate part data (2)"); return (1); } commlocloadintn = commlocloadextn = commlocgainextn = 0; for (vertlocnum = grafptr->s.baseval, fronlocnum = complocsize1 = complocload1 = 0; vertlocnum < grafptr->s.vertlocnnd; vertlocnum ++) { Gnum edgelocnum; Gnum edgelocnnd; Gnum veloval; Gnum partval; Gnum flagval; #ifdef SCOTCH_DEBUG_BDGRAPH2 if (grafptr->partgsttax[vertlocnum] > 1) { errorPrint ("bdgraphBipartDf: internal error (3)"); break; /* Do not break upcoming collective communications */ } #endif /* SCOTCH_DEBUG_BDGRAPH2 */ partval = (Gnum) grafptr->partgsttax[vertlocnum]; veloval = (veloloctax != NULL) ? veloloctax[vertlocnum] : 1; if (grafptr->veexloctax != NULL) { commlocloadextn += grafptr->veexloctax[vertlocnum] * partval; commlocgainextn += grafptr->veexloctax[vertlocnum] * (1 - partval * 2); } complocsize1 += partval; complocload1 += partval * veloval; flagval = 0; for (edgelocnum = grafptr->s.vertloctax[vertlocnum], edgelocnnd = grafptr->s.vendloctax[vertlocnum]; edgelocnum < edgelocnnd; edgelocnum ++) { Gnum edloval; Gnum partend; partend = (Gnum) grafptr->partgsttax[edgegsttax[edgelocnum]]; #ifdef SCOTCH_DEBUG_BDGRAPH2 if (partend > 1) { errorPrint ("bdgraphBipartDf: internal error (4)"); vertlocnum = grafptr->s.vertlocnnd; break; /* Do not break upcoming collective communications */ } #endif /* SCOTCH_DEBUG_BDGRAPH2 */ edloval = (edloloctax != NULL) ? edloloctax[edgelocnum] : 1; flagval |= partval ^ partend; commlocloadintn += (partval ^ partend) * edloval; /* Internal load is accounted for twice */ } if (flagval != 0) /* If vertex has neighbors in other part */ grafptr->fronloctab[fronlocnum ++] = vertlocnum; /* Record it as member of separator */ } grafptr->complocload0 = grafptr->s.velolocsum - complocload1; grafptr->complocsize0 = grafptr->s.vertlocnbr - complocsize1; grafptr->fronlocnbr = fronlocnum; reduloctab[0] = fronlocnum; reduloctab[1] = grafptr->complocload0; reduloctab[2] = grafptr->complocsize0; reduloctab[3] = commlocloadintn; /* Twice the internal load; sum globally before dividing by two */ reduloctab[4] = commlocloadextn; reduloctab[5] = commlocgainextn; if (MPI_Allreduce (&reduloctab[0], &reduglbtab[0], 6, GNUM_MPI, MPI_SUM, grafptr->s.proccomm) != MPI_SUCCESS) { errorPrint ("bdgraphBipartDf: communication error (2)"); return (1); } grafptr->fronglbnbr = reduglbtab[0]; grafptr->compglbload0 = reduglbtab[1]; grafptr->compglbload0dlt = grafptr->compglbload0 - grafptr->compglbload0avg; grafptr->compglbsize0 = reduglbtab[2]; grafptr->commglbload = (reduglbtab[3] / 2) * grafptr->domndist + reduglbtab[4]; grafptr->commglbgainextn = reduglbtab[5]; grafptr->bbalglbval = (double) ((grafptr->compglbload0dlt < 0) ? (- grafptr->compglbload0dlt) : grafptr->compglbload0dlt) / (double) grafptr->compglbload0avg; #ifdef SCOTCH_DEBUG_BDGRAPH2 if (bdgraphCheck (grafptr) != 0) { errorPrint ("bdgraphBipartDf: internal error (5)"); return (1); } #endif /* SCOTCH_DEBUG_BDGRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/comm.c0000644002563400244210000001665511631447171022753 0ustar trophimeutilisateurs du domaine/* Copyright 2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : comm.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the large size **/ /** communication handling routines. **/ /** **/ /** DATES : # Version 5.1 : from : 30 jul 2010 **/ /** to : 30 jul 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define COMM #include "module.h" #include "common.h" #include "comm.h" /************************************/ /* */ /* These routines handle large size */ /* communications */ /* */ /************************************/ /* ** */ int commAllgatherv ( void * const senddattab, const Gnum sendcntnbr, MPI_Datatype sendtypval, void * const recvdattab, const Gnum * const recvcnttab, const Gnum * const recvdsptab, MPI_Datatype recvtypval, MPI_Comm comm) { int * restrict ircvcnttab; int * restrict ircvdsptab; int procglbnbr; int procnum; int o; MPI_Comm_size (comm, &procglbnbr); if (memAllocGroup ((void **) (void *) &ircvcnttab, (size_t) (procglbnbr * sizeof (int)), &ircvdsptab, (size_t) (procglbnbr * sizeof (int)), NULL) == NULL) { errorPrint ("commAllgatherv: out of memory"); return (MPI_ERR_OTHER); } for (procnum = 0; procnum < procglbnbr; procnum ++) { ircvcnttab[procnum] = (int) recvcnttab[procnum]; ircvdsptab[procnum] = (int) recvdsptab[procnum]; if (((Gnum) ircvcnttab[procnum] != recvcnttab[procnum]) || ((Gnum) ircvdsptab[procnum] != recvdsptab[procnum])) { errorPrint ("commAllgatherv: communication indices out of range"); memFree (ircvcnttab); return (MPI_ERR_ARG); } } o = MPI_Allgatherv (senddattab, sendcntnbr, sendtypval, recvdattab, ircvcnttab, ircvdsptab, recvtypval, comm); memFree (ircvcnttab); return (o); } /* ** */ int commGatherv ( void * const senddattab, const Gnum sendcntnbr, MPI_Datatype sendtypval, void * const recvdattab, const Gnum * const recvcnttab, const Gnum * const recvdsptab, MPI_Datatype recvtypval, const int rootnum, MPI_Comm comm) { int * restrict ircvcnttab; int * restrict ircvdsptab; int proclocnum; int o; MPI_Comm_rank (comm, &proclocnum); ircvcnttab = NULL; if (rootnum == proclocnum) { int procglbnbr; int procnum; MPI_Comm_size (comm, &procglbnbr); if (memAllocGroup ((void **) (void *) &ircvcnttab, (size_t) (procglbnbr * sizeof (int)), &ircvdsptab, (size_t) (procglbnbr * sizeof (int)), NULL) == NULL) { errorPrint ("commGatherv: out of memory"); return (MPI_ERR_OTHER); } for (procnum = 0; procnum < procglbnbr; procnum ++) { ircvcnttab[procnum] = (int) recvcnttab[procnum]; ircvdsptab[procnum] = (int) recvdsptab[procnum]; if (((Gnum) ircvcnttab[procnum] != recvcnttab[procnum]) || ((Gnum) ircvdsptab[procnum] != recvdsptab[procnum])) { errorPrint ("commGatherv: communication indices out of range"); memFree (ircvcnttab); return (MPI_ERR_ARG); } } } o = MPI_Gatherv (senddattab, sendcntnbr, sendtypval, recvdattab, ircvcnttab, ircvdsptab, recvtypval, rootnum, comm); if (ircvcnttab != NULL) memFree (ircvcnttab); return (o); } /* ** */ int commScatterv ( void * const senddattab, const Gnum * const sendcnttab, const Gnum * const senddsptab, MPI_Datatype sendtypval, void * const recvdattab, const Gnum recvcntnbr, MPI_Datatype recvtypval, const int rootnum, MPI_Comm comm) { int * restrict isndcnttab; int * restrict isnddsptab; int proclocnum; int o; MPI_Comm_rank (comm, &proclocnum); isndcnttab = NULL; if (rootnum == proclocnum) { int procglbnbr; int procnum; MPI_Comm_size (comm, &procglbnbr); if (memAllocGroup ((void **) (void *) &isndcnttab, (size_t) (procglbnbr * sizeof (int)), &isnddsptab, (size_t) (procglbnbr * sizeof (int)), NULL) == NULL) { errorPrint ("commScatterv: out of memory"); return (MPI_ERR_OTHER); } for (procnum = 0; procnum < procglbnbr; procnum ++) { isndcnttab[procnum] = (int) sendcnttab[procnum]; isnddsptab[procnum] = (int) senddsptab[procnum]; if (((Gnum) isndcnttab[procnum] != sendcnttab[procnum]) || ((Gnum) isnddsptab[procnum] != senddsptab[procnum])) { errorPrint ("commScatterv: communication indices out of range"); memFree (isndcnttab); return (MPI_ERR_ARG); } } } o = MPI_Scatterv (senddattab, isndcnttab, isnddsptab, sendtypval, recvdattab, (int) recvcntnbr, recvtypval, rootnum, comm); if (isndcnttab != NULL) memFree (isndcnttab); return (o); } scotch-6.0.4.dfsg/src/libscotch/vmesh.c0000644002563400244210000000765211631447171023137 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vmesh.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the separator **/ /** handling routines. **/ /** **/ /** DATES : # Version 4.0 : from : 06 feb 2003 **/ /** to 05 mar 2003 **/ /** # Version 5.1 : from : 09 nov 2008 **/ /** to 09 nov 2008 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VMESH #include "module.h" #include "common.h" #include "graph.h" #include "mesh.h" #include "vmesh.h" /*************************/ /* */ /* These routines handle */ /* separator meshes. */ /* */ /*************************/ /* This routine frees the contents ** of the given active mesh. ** It returns: ** - VOID : in all cases. */ void vmeshExit ( Vmesh * const meshptr) { if (meshptr->parttax != NULL) /* Free leader of group (parttab + frontab) */ memFree (meshptr->parttax + meshptr->m.baseval); meshFree (&meshptr->m); /* Free source mesh */ #ifdef SCOTCH_DEBUG_VMESH2 memSet (meshptr, ~0, sizeof (Vmesh)); #endif /* SCOTCH_DEBUG_VMESH2 */ } /* This routine moves all of the mesh ** elements to the first part. ** It returns: ** - VOID : in all cases. */ void vmeshZero ( Vmesh * const meshptr) { memSet (meshptr->parttax + meshptr->m.baseval, 0, (meshptr->m.velmnbr + meshptr->m.vnodnbr) * sizeof (GraphPart)); meshptr->ecmpsize[0] = meshptr->m.velmnbr; meshptr->ecmpsize[1] = 0; meshptr->ncmpload[0] = meshptr->m.vnlosum; meshptr->ncmpload[1] = meshptr->ncmpload[2] = 0; meshptr->ncmploaddlt = meshptr->m.vnlosum; meshptr->ncmpsize[0] = meshptr->m.vnodnbr; meshptr->ncmpsize[1] = meshptr->fronnbr = 0; } scotch-6.0.4.dfsg/src/libscotch/vgraph_separate_th.h0000644002563400244210000000540211631447171025657 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vgraph_separate_th.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the the separator thinner **/ /** vertex separation method. **/ /** **/ /** DATES : # Version 3.3 : from : 17 oct 1998 **/ /** to 17 oct 1998 **/ /** # Version 4.0 : from : 12 dec 2001 **/ /** to 01 jan 2002 **/ /** **/ /************************************************************/ /* ** The function prototypes. */ #ifndef VGRAPH_SEPARATE_TH #define static #endif int vgraphSeparateTh (Vgraph * const); #undef static scotch-6.0.4.dfsg/src/libscotch/parser_ll.h0000644002563400244210000000634111631447170023776 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : parser_ll.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a static mapper. **/ /** These lines are the declarations for **/ /** the strategy strings lexical parser. **/ /** **/ /** DATES : # Version 3.1 : from : 07 nov 1995 **/ /** to 13 jun 1996 **/ /** # Version 3.2 : from : 03 oct 1996 **/ /** to 19 oct 1996 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 4.0 : from : 20 dec 2001 **/ /** to 20 dec 2001 **/ /** **/ /************************************************************/ /* ** The function prototypes. */ #ifndef PARSER_LL #define static #endif void stratParserInit (const char * const); static int stratParserInput (void); int stratParserLex (void); const char * stratParserRemain (void); void stratParserSelect (unsigned int); #undef static scotch-6.0.4.dfsg/src/libscotch/library_strat.c0000644002563400244210000000621011631447170024662 0ustar trophimeutilisateurs du domaine/* Copyright 2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_strat.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains miscellaneous **/ /** routines for handling strategy **/ /** strings. **/ /** **/ /** DATES : # Version 5.1 : from : 17 nov 2010 **/ /** to 17 nov 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /*****************************************/ /* */ /* These routines are the C API for */ /* ordering structure handling routines. */ /* */ /*****************************************/ /*+ This routine reserves a memory area *** of a size sufficient to store a *** distributed ordering structure. *** It returns: *** - !NULL : if the initialization succeeded. *** - NULL : on error. +*/ SCOTCH_Strat * SCOTCH_stratAlloc () { return ((SCOTCH_Strat *) memAlloc (sizeof (SCOTCH_Strat))); } scotch-6.0.4.dfsg/src/libscotch/dgraph_match_scan.c0000644002563400244210000003351512225624704025436 0ustar trophimeutilisateurs du domaine/* Copyright 2008,2012,2013 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_match_scan.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines define a generic scanning **/ /** framework for distributed graph **/ /** matching routines. **/ /** **/ /** DATES : # Version 6.0 : from : 04 dec 2008 **/ /** to : 10 oct 2013 **/ /** **/ /************************************************************/ void DGRAPHMATCHSCANNAME ( DgraphMatchData * restrict const mateptr) { int flagval; Gnum vertlocnnd; Gnum vertlocadj; Gnum edgekptnbr; Gnum queulocnbr; Gnum matelocnbr; /* TRICK: Initial number of local mated vertices, from which are subtracted single multinodes */ Gnum multlocnbr; Gnum probmax; const Dgraph * restrict const grafptr = mateptr->c.finegrafptr; const Gnum * restrict const vertloctax = grafptr->vertloctax; const Gnum * restrict const vendloctax = grafptr->vendloctax; const Gnum * restrict const edgegsttax = grafptr->edgegsttax; Gnum * restrict const queuloctab = mateptr->queuloctab; Gnum * restrict const mategsttax = mateptr->mategsttax; DgraphCoarsenMulti * restrict const multloctab = mateptr->c.multloctab; DGRAPHMATCHSCANINIT flagval = mateptr->c.flagval; /* Get flag value */ vertlocadj = grafptr->procvrttab[grafptr->proclocnum] - grafptr->baseval; vertlocnnd = grafptr->vertlocnnd; matelocnbr = mateptr->matelocnbr; multlocnbr = mateptr->c.multlocnbr; edgekptnbr = mateptr->c.edgekptnbr; if (matelocnbr == 0) { /* If initial pass or nothing useful done */ Gnum vertlocnnt; /* End of useable local vertices */ Gnum vertlocnum; memSet (mategsttax + grafptr->baseval, ~0, grafptr->vertlocnbr * sizeof (Gnum)); /* No local vertices matched to date: wipe all unsatisfied queries */ queulocnbr = 0; /* Build queue from scratch */ for (vertlocnum = grafptr->baseval, vertlocnnt = vertlocnnd; vertlocnum < vertlocnnt; vertlocnum ++) { Gnum edgelocnum; Gnum edgelocnnd; Gnum edgeendnbr; Gnum edgefrenbr; Gnum probval; DGRAPHMATCHSCANCOUNTDECL if (mategsttax[vertlocnum] >= 0) /* If vertex has been matched by one of the previous ones, skip it */ continue; #ifdef SCOTCH_DEBUG_DGRAPH2 if (mategsttax[vertlocnum] < -1) { /* Vertex must not be requesting yet */ errorPrint ("dgraphMatchSc: internal error (1)"); return; } #endif /* SCOTCH_DEBUG_DGRAPH2 */ DGRAPHMATCHSCANCOUNTINIT if (probval > probmax) { /* If vertex not active this turn */ queuloctab[queulocnbr ++] = vertlocnum; /* Enqueue it for next time */ continue; /* Skip to next vertex */ } edgelocnum = vertloctax[vertlocnum]; edgelocnnd = vendloctax[vertlocnum]; if (((flagval & DGRAPHCOARSENNOMERGE) == 0) && /* If merging isolated vertices is allowed */ ((edgelocnnd - edgelocnum) == 0)) { /* And if vertex is isolated */ while (mategsttax[-- vertlocnnt] != ~0) ; /* Search for first matchable local "neighbor" */ mategsttax[vertlocnum] = (vertlocnnt + vertlocadj); /* At worst we will stop at vertlocnum */ mategsttax[vertlocnnt] = (vertlocnum + vertlocadj); multloctab[multlocnbr].vertglbnum[0] = (vertlocnum + vertlocadj); multloctab[multlocnbr].vertglbnum[1] = (vertlocnnt + vertlocadj); multlocnbr ++; /* One more coarse vertex created (two more local mates) */ edgekptnbr += vendloctax[vertlocnnt] - vertloctax[vertlocnnt]; /* Add edges of other vertex only */ continue; } for (edgeendnbr = edgefrenbr = 0; edgelocnum < edgelocnnd; edgelocnum ++) { /* For all edges, count yet unmatched ends */ Gnum vertgstend; vertgstend = edgegsttax[edgelocnum]; if (mategsttax[vertgstend] == -1) { /* Count relevant free end vertices */ DGRAPHMATCHSCANCOUNTSELECT } if (mategsttax[vertgstend] < 0) /* Count not yet assigned end vertices */ edgeendnbr ++; } if (edgeendnbr <= 0) { /* If vertex has no possible neighbor */ mategsttax[vertlocnum] = /* Create single multinode */ multloctab[multlocnbr].vertglbnum[0] = multloctab[multlocnbr].vertglbnum[1] = vertlocnum + vertlocadj; multlocnbr ++; /* One more coarse vertex created */ matelocnbr --; /* TRICK: But with only one vertex */ edgekptnbr += edgelocnnd - vertloctax[vertlocnum]; continue; } if (edgefrenbr > 0) { /* If vertex has some free neighbor */ Gnum vertgstend; edgefrenbr = intRandVal (edgefrenbr); /* Select one of them randomly */ for (edgelocnum = vertloctax[vertlocnum]; ; edgelocnum ++) { /* Loop again on edges */ #ifdef SCOTCH_DEBUG_DGRAPH2 if (edgelocnum >= edgelocnnd) { errorPrint ("dgraphMatchSc: internal error (2)"); return; } #endif /* SCOTCH_DEBUG_DGRAPH2 */ vertgstend = edgegsttax[edgelocnum]; if (mategsttax[vertgstend] == -1) { /* If free end vertex found */ if (DGRAPHMATCHSCANFINDSELECT) /* If it is the one we want */ break; /* Exit loop */ } } if (vertgstend >= vertlocnnd) { /* If end vertex is a ghost vertex */ queuloctab[queulocnbr ++] = vertlocnum; /* Enqueue vertex for communication processing */ mategsttax[vertlocnum] = -2 - edgelocnum; /* Local vertex index codes edge number */ } else { /* Perform local matching */ mategsttax[vertlocnum] = (vertgstend + vertlocadj); mategsttax[vertgstend] = (vertlocnum + vertlocadj); multloctab[multlocnbr].vertglbnum[0] = (vertlocnum + vertlocadj); multloctab[multlocnbr].vertglbnum[1] = (vertgstend + vertlocadj); multlocnbr ++; /* One more coarse vertex created (two more local mates) */ edgekptnbr += (edgelocnnd - vertloctax[vertlocnum]) + (vendloctax[vertgstend] - vertloctax[vertgstend]) - 2; /* "-2" for collapsed arcs */ } } else queuloctab[queulocnbr ++] = vertlocnum; /* Enqueue vertex for next time */ } } else { /* Vertices to consider are already enqueued */ Gnum queulocnum; Gnum queulocnew; for (queulocnum = queulocnew = 0, queulocnbr = mateptr->queulocnbr; queulocnum < queulocnbr; queulocnum ++) { /* For all vertices in queue */ Gnum vertlocnum; Gnum mategstnum; vertlocnum = queuloctab[queulocnum]; /* Get current vertex */ mategstnum = mategsttax[vertlocnum]; if (mategstnum > -1) /* If already mated */ continue; /* Find another one */ queuloctab[queulocnew ++] = vertlocnum; if (mategstnum < -1) mategsttax[vertlocnum] = -1; } queulocnbr = queulocnew; for (queulocnum = 0; queulocnum < queulocnbr; queulocnum ++) { /* For all vertices in queue */ Gnum vertlocnum; Gnum edgelocnum; Gnum edgelocnnd; Gnum edgeendnbr; Gnum edgefrenbr; Gnum probval; DGRAPHMATCHSCANCOUNTDECL vertlocnum = queuloctab[queulocnum]; /* Get current vertex */ if (mategsttax[vertlocnum] >= 0) /* If already mated */ continue; /* Find another one */ #ifdef SCOTCH_DEBUG_DGRAPH2 if (mategsttax[vertlocnum] < -1) { /* Vertex must not be requesting yet */ errorPrint ("dgraphMatchSc: internal error (3)"); return; } #endif /* SCOTCH_DEBUG_DGRAPH2 */ DGRAPHMATCHSCANCOUNTINIT if (probval > probmax) /* If vertex not active this turn */ continue; /* Keep vertex enqueued and skip to next vertex */ edgelocnum = vertloctax[vertlocnum]; edgelocnnd = vendloctax[vertlocnum]; /* No need to test for isolated vertices this turn */ for (edgeendnbr = edgefrenbr = 0; edgelocnum < edgelocnnd; edgelocnum ++) { /* For all edges, count yet unmatched ends */ Gnum vertgstend; vertgstend = edgegsttax[edgelocnum]; if (mategsttax[vertgstend] == -1) { /* Count free end vertices */ DGRAPHMATCHSCANCOUNTSELECT } if (mategsttax[vertgstend] < 0) /* Count not yet assigned end vertices */ edgeendnbr ++; } if (edgeendnbr <= 0) { /* If vertex has no possible neighbor */ mategsttax[vertlocnum] = /* Create single multinode */ multloctab[multlocnbr].vertglbnum[0] = multloctab[multlocnbr].vertglbnum[1] = vertlocnum + vertlocadj; multlocnbr ++; /* One more coarse vertex created */ matelocnbr --; /* TRICK: But with only one vertex */ edgekptnbr += edgelocnnd - vertloctax[vertlocnum]; continue; } if (edgefrenbr > 0) { /* If vertex has some free neighbor */ Gnum vertgstend; edgefrenbr = intRandVal (edgefrenbr); /* Select one of them randomly */ for (edgelocnum = vertloctax[vertlocnum]; ; edgelocnum ++) { /* Loop again on edges */ #ifdef SCOTCH_DEBUG_DGRAPH2 if (edgelocnum >= edgelocnnd) { errorPrint ("dgraphMatchSc: internal error (4)"); return; } #endif /* SCOTCH_DEBUG_DGRAPH2 */ vertgstend = edgegsttax[edgelocnum]; if (mategsttax[vertgstend] == -1) { /* If free end vertex found */ if (DGRAPHMATCHSCANFINDSELECT) /* If it is the one we want */ break; /* Exit loop */ } } if (vertgstend >= vertlocnnd) /* If end vertex is a ghost vertex */ mategsttax[vertlocnum] = -2 - edgelocnum; /* Local vertex index codes edge number */ else { /* Perform local matching */ mategsttax[vertlocnum] = (vertgstend + vertlocadj); mategsttax[vertgstend] = (vertlocnum + vertlocadj); multloctab[multlocnbr].vertglbnum[0] = (vertlocnum + vertlocadj); multloctab[multlocnbr].vertglbnum[1] = (vertgstend + vertlocadj); multlocnbr ++; /* One more coarse vertex created (two more local mates) */ edgekptnbr += (edgelocnnd - vertloctax[vertlocnum]) + (vendloctax[vertgstend] - vertloctax[vertgstend]) - 1; } } /* Else vertex stays enqueued */ } } mateptr->matelocnbr = matelocnbr + 2 * (multlocnbr - mateptr->c.multlocnbr); /* TRICK: Two times new multinodes, minus single multinode adjustment */ mateptr->queulocnbr = queulocnbr; mateptr->c.multlocnbr = multlocnbr; mateptr->c.edgekptnbr = edgekptnbr; } scotch-6.0.4.dfsg/src/libscotch/wgraph_part_gg.h0000644002563400244210000000722211631447170025005 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : wgraph_part_gg.h **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Charles-Edmond BICHOT (v5.1b) **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the graph partitioning rountine **/ /** based on a vertex-oriented version of **/ /** the Greedy Graph Growing algorithm. **/ /** **/ /** DATES : # Version 5.1 : from : 01 dec 2007 **/ /** to : 01 jul 2008 **/ /** # Version 6.0 : from : 05 nov 2009 **/ /** to : 04 nov 2010 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ System-defined constants. +*/ #define WGRAPHSEPAGGSUBBITS 4 #define WGRAPHGGCHOOSELASTPART /* ** The type and structure definitions. */ /*+ Method parameters. +*/ typedef struct WgraphPartGgParam_ { INT passnbr; /*+ Number of passes to do +*/ } WgraphPartGgParam; /*+ The complementary vertex structure. For trick reasons, the gain table data structure must be the first field of the structure. +*/ typedef struct WgraphPartGgVertex_ { GainLink gainlink; /*+ Gain link: FIRST +*/ Gnum partlvl; struct WgraphPartGgVertex_ * prev; struct WgraphPartGgVertex_ * next; } WgraphPartGgVertex; /* ** The function prototypes. */ #ifndef WGRAPH_PART_GG #define static #endif int wgraphPartGg (Wgraph * restrict const, const WgraphPartGgParam * restrict const); #undef static scotch-6.0.4.dfsg/src/libscotch/library_dgraph_order_perm.c0000644002563400244210000000707312055777611027227 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_order_perm.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the distri- **/ /** buted ordering permutation building **/ /** routine of the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 18 oct 2007 **/ /** to 18 oct 2007 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "dgraph.h" #include "dorder.h" #include "ptscotch.h" /************************************/ /* */ /* These routines are the C API for */ /* the distributed ordering */ /* handling routines. */ /* */ /************************************/ /*+ This routine fills the given distributed *** permutation array with the permutation *** stored in the given distributed ordering. *** It returns: *** - 0 : on success. *** - !0 : on error. +*/ int SCOTCH_dgraphOrderPerm ( const SCOTCH_Dgraph * const grafptr, /*+ Graph to order +*/ const SCOTCH_Dordering * const ordeptr, /*+ Computed ordering +*/ SCOTCH_Num * const permloctab) /*+ Direct permutation +*/ { return (dorderPerm ((Dorder *) ordeptr, (Dgraph *) grafptr, permloctab)); } scotch-6.0.4.dfsg/src/libscotch/library_dgraph_order_gather_f.c0000644002563400244210000001065612055777333030045 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_order_gather_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the Fortran API for the **/ /** distributed ordering gathering routines **/ /** of the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 21 jul 2007 **/ /** to 22 jul 2007 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "ptscotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the ordering routines. */ /* */ /**************************************/ FORTRAN ( \ SCOTCHFDGRAPHCORDERINIT, scotchfdgraphcorderinit, ( \ const SCOTCH_Dgraph * const grafptr, \ SCOTCH_Ordering * const ordeptr, \ SCOTCH_Num * const permtab, \ SCOTCH_Num * const peritab, \ SCOTCH_Num * const cblkptr, \ SCOTCH_Num * const rangtab, \ SCOTCH_Num * const treetab, \ int * const revaptr), \ (grafptr, ordeptr, permtab, peritab, \ cblkptr, rangtab, treetab, revaptr)) { *revaptr = SCOTCH_dgraphCorderInit (grafptr, ordeptr, permtab, peritab, cblkptr, rangtab, treetab); } /* ** */ FORTRAN ( \ SCOTCHFDGRAPHCORDEREXIT, scotchfdgraphcorderexit, ( \ const SCOTCH_Dgraph * const grafptr, \ SCOTCH_Ordering * const ordeptr), \ (grafptr, ordeptr)) { SCOTCH_dgraphCorderExit (grafptr, ordeptr); } /* ** */ FORTRAN ( \ SCOTCHFDGRAPHORDERGATHER, scotchfdgraphordergather, ( \ const SCOTCH_Dgraph * const grafptr, \ const SCOTCH_Dordering * const dordptr, \ SCOTCH_Ordering * const cordptr, \ int * const revaptr), \ (grafptr, dordptr, cordptr, revaptr)) { *revaptr = SCOTCH_dgraphOrderGather (grafptr, dordptr, cordptr); } scotch-6.0.4.dfsg/src/libscotch/dmapping.c0000644002563400244210000002561212211373732023604 0ustar trophimeutilisateurs du domaine/* Copyright 2008,2013 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dmapping.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Jun-Ho HER (v6.0) **/ /** **/ /** FUNCTION : This module handles (partial) mappings. **/ /** **/ /** DATES : # Version 5.1 : from : 31 mar 2008 **/ /** to 09 nov 2008 **/ /** # Version 6.0 : from : 03 sep 2013 **/ /** to 03 sep 2013 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DMAPPING #include "module.h" #include "common.h" #include "dgraph.h" #include "arch.h" #include "dmapping.h" /***********************************/ /* */ /* These routines handle mappings. */ /* */ /***********************************/ /* This routine builds a mapping. ** It returns: ** - 0 : if mapping successfully initialized. ** - !0 : on error. */ int dmapInit ( Dmapping * restrict const dmapptr, const Arch * restrict const archptr) { dmapptr->fragptr = NULL; dmapptr->fragnbr = dmapptr->vertlocmax = dmapptr->vertlocnbr = 0; dmapptr->archdat = *archptr; #ifdef SCOTCH_PTHREAD pthread_mutex_init (&dmapptr->mutelocdat, NULL); /* Initialize local mutex */ #endif /* SCOTCH_PTHREAD */ return (0); } /* This routine frees the contents of the given ** mapping. The architecture data is never freed ** as it is usually a copy of an existing Arch ** structure. ** It returns: ** - VOID : in all cases. */ void dmapExit ( Dmapping * const dmapptr) { DmappingFrag * fragptr; DmappingFrag * fragtmp; for (fragptr = dmapptr->fragptr; fragptr != NULL; fragptr = fragtmp) { memFree (fragptr->vnumtab); memFree (fragptr->parttab); memFree (fragptr->domntab); fragtmp = fragptr->nextptr; memFree (fragptr); } #ifdef SCOTCH_PTHREAD pthread_mutex_destroy (&dmapptr->mutelocdat); /* Destroy local mutex */ #endif /* SCOTCH_PTHREAD */ #ifdef SCOTCH_DEBUG_DMAP2 memSet (dmapptr, ~0, sizeof (Dmapping)); #endif /* SCOTCH_DEBUG_DMAP2 */ } /* This routine adds a fragment to the given ** distributed mapping. ** It returns: ** - void : in all cases. */ void dmapAdd ( Dmapping * restrict const dmapptr, DmappingFrag * restrict const fragptr) { #ifdef SCOTCH_PTHREAD pthread_mutex_lock (&dmapptr->mutelocdat); /* Lock local mutex */ #endif /* SCOTCH_PTHREAD */ if (dmapptr->vertlocmax < fragptr->vertnbr) dmapptr->vertlocmax = fragptr->vertnbr; dmapptr->vertlocnbr += fragptr->vertnbr; dmapptr->fragnbr ++; fragptr->nextptr = dmapptr->fragptr; /* Link fragment to mapping */ dmapptr->fragptr = fragptr; #ifdef SCOTCH_PTHREAD pthread_mutex_unlock (&dmapptr->mutelocdat); /* Unlock local mutex */ #endif /* SCOTCH_PTHREAD */ } /* This routine propagates back distributed mapping ** information to a part array associated with a ** distributed graph structure. ** It returns: ** - 0 : if partition data successfully obtained. ** - !0 : on error. */ int dmapTerm ( const Dmapping * restrict const dmapptr, const Dgraph * restrict const grafptr, Gnum * restrict const termloctab) { Gnum * restrict termloctax; int * restrict sendcnttab; int * restrict senddsptab; int * restrict recvcnttab; int * restrict recvdsptab; DmappingTermSort * restrict sortsndtab; DmappingTermSort * restrict sortrcvtab; Gnum vertlocnum; int vertrcvnbr; int vertsndnbr; int procnum; DmappingFrag * restrict fragptr; Gnum reduloctab[2]; Gnum reduglbtab[2]; reduloctab[0] = dmapptr->vertlocnbr; reduloctab[1] = 0; if (memAllocGroup ((void **) (void *) &senddsptab, (size_t) (grafptr->procglbnbr * sizeof (int)), &sendcnttab, (size_t) (grafptr->procglbnbr * sizeof (int)), &recvdsptab, (size_t) (grafptr->procglbnbr * sizeof (int)), &recvcnttab, (size_t) (grafptr->procglbnbr * sizeof (int)), &sortsndtab, (size_t) ((dmapptr->vertlocnbr + 1) * sizeof (DmappingTermSort)), /* "+1" for end marker */ &sortrcvtab, (size_t) (grafptr->vertlocnbr * sizeof (DmappingTermSort)), NULL) == NULL) { errorPrint ("dmapTerm: out of memory"); reduloctab[1] = 1; } if (MPI_Allreduce (reduloctab, reduglbtab, 2, GNUM_MPI, MPI_SUM, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dmapTerm: communication error (1)"); reduglbtab[1] = 1; } if (reduglbtab[1] != 0) { if (senddsptab != NULL) memFree (senddsptab); /* Free group leader */ return (1); } if (reduglbtab[0] == 0) { /* If mapping structure is empty, create an empty mapping */ memSet (termloctab, 0, grafptr->vertlocnbr * sizeof (Gnum)); memFree (senddsptab); /* Free group leader */ return (0); } if (reduglbtab[0] != grafptr->vertglbnbr) { errorPrint ("dmapTerm: invalid mapping (1)"); memFree (senddsptab); /* Free group leader */ return (1); } for (fragptr = dmapptr->fragptr, vertlocnum = 0; fragptr != NULL; fragptr = fragptr->nextptr) { Gnum fraglocnum; for (fraglocnum = 0; fraglocnum < fragptr->vertnbr; fraglocnum ++, vertlocnum ++) { #ifdef SCOTCH_DEBUG_DMAP2 if ((vertlocnum >= dmapptr->vertlocnbr) || (fragptr->parttab[fraglocnum] < 0) || (fragptr->parttab[fraglocnum] >= fragptr->domnnbr)) { errorPrint ("dmapTerm: invalid mapping (2)"); return (1); } #endif /* SCOTCH_DEBUG_DMAP2 */ sortsndtab[vertlocnum].vertnum = fragptr->vnumtab[fraglocnum]; sortsndtab[vertlocnum].termnum = (Gnum) archDomNum (&dmapptr->archdat, &fragptr->domntab[fragptr->parttab[fraglocnum]]); } } #ifdef SCOTCH_DEBUG_DMAP2 if (vertlocnum != dmapptr->vertlocnbr) { errorPrint ("dmapTerm: invalid mapping (3)"); return (1); } #endif /* SCOTCH_DEBUG_DMAP2 */ sortsndtab[vertlocnum].vertnum = /* Set end marker */ sortsndtab[vertlocnum].termnum = GNUMMAX; intSort2asc1 (sortsndtab, dmapptr->vertlocnbr); /* Sort mapping array by original vertex numbers, without marker */ for (vertlocnum = 0, procnum = 0; procnum < grafptr->procglbnbr; ) { Gnum vertsndnbr; Gnum procvrtval; vertsndnbr = 0; procvrtval = grafptr->procvrttab[procnum + 1]; while (sortsndtab[vertlocnum].vertnum < procvrtval) { vertsndnbr ++; vertlocnum ++; #ifdef SCOTCH_DEBUG_DMAP2 if (vertlocnum > dmapptr->vertlocnbr) { /* If beyond regular indices plus end marker */ errorPrint ("dmapTerm: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_DMAP2 */ } sendcnttab[procnum ++] = (int) (vertsndnbr * 2); /* Communication array for MPI, so (int), and "*2" because a Sort is 2 Gnums */ } #ifdef SCOTCH_DEBUG_DMAP2 if (vertlocnum != dmapptr->vertlocnbr) { errorPrint ("dmapTerm: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_DMAP2 */ if (MPI_Alltoall (sendcnttab, 1, MPI_INT, recvcnttab, 1, MPI_INT, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dmapTerm: communication error (2)"); return (1); } for (procnum = 0, vertrcvnbr = vertsndnbr = 0; procnum < grafptr->procglbnbr; procnum ++) { /* Accumulate send and receive indices */ recvdsptab[procnum] = vertrcvnbr; vertrcvnbr += recvcnttab[procnum]; /* Accumulate "*2" values as counts */ senddsptab[procnum] = vertsndnbr; vertsndnbr += sendcnttab[procnum]; } if (MPI_Alltoallv (sortsndtab, sendcnttab, senddsptab, GNUM_MPI, sortrcvtab, recvcnttab, recvdsptab, GNUM_MPI, grafptr->proccomm) != MPI_SUCCESS) { errorPrint ("dmapTerm: communication error (3)"); return (1); } memSet (termloctab, ~0, grafptr->vertlocnbr * sizeof (Gnum)); termloctax = termloctab - grafptr->procvrttab[grafptr->proclocnum]; /* Base local array through global indices */ for (vertlocnum = 0; vertlocnum < grafptr->vertlocnbr; vertlocnum ++) { #ifdef SCOTCH_DEBUG_DMAP2 if (termloctax[sortrcvtab[vertlocnum].vertnum] != ~0) { errorPrint ("dmapTerm: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_DMAP2 */ termloctax[sortrcvtab[vertlocnum].vertnum] = sortrcvtab[vertlocnum].termnum; } #ifdef SCOTCH_DEBUG_DMAP2 for (vertlocnum = 0; vertlocnum < grafptr->vertlocnbr; vertlocnum ++) { if (termloctab[vertlocnum] == ~0) { errorPrint ("dmapTerm: internal error (4)"); return (1); } } #endif /* SCOTCH_DEBUG_DMAP2 */ memFree (senddsptab); /* Free group leader */ return (0); } scotch-6.0.4.dfsg/src/libscotch/vmesh_separate_st.h0000644002563400244210000000664611631447170025537 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vmesh_separate_st.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the global mesh separation **/ /** strategy and method tables. **/ /** **/ /** DATES : # Version 4.0 : from : 20 sep 2002 **/ /** to 31 oct 2003 **/ /** **/ /************************************************************/ /* ** The type definitions. */ /*+ Method types. +*/ typedef enum VmeshSeparateStMethodType_ { VMESHSEPASTMETHFM = 0, /*+ Fiduccia-Mattheyses +*/ VMESHSEPASTMETHGG, /*+ Greedy Mesh Growing +*/ #ifdef SCOTCH_DEBUG_VMESH2 VMESHSEPASTMETHGR, /*+ Graph partitioning +*/ #endif /* SCOTCH_DEBUG_VMESH2 */ VMESHSEPASTMETHML, /*+ Multi-level separation +*/ VMESHSEPASTMETHZR, /*+ Zero method +*/ VMESHSEPASTMETHNBR /*+ Number of methods +*/ } VmeshSeparateStMethodType; /* ** The external declarations. */ extern StratTab vmeshseparateststratab; /* ** The function prototypes. */ #ifndef VMESH_SEPARATE_ST #define static #endif int vmeshSeparateSt (Vmesh * restrict const, const Strat * restrict const); #undef static scotch-6.0.4.dfsg/src/libscotch/bdgraph_bipart_bd.h0000644002563400244210000000615211631447170025430 0ustar trophimeutilisateurs du domaine/* Copyright 2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bdgraph_bipart_bd.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the band graph bipartitioning **/ /** routine for distributed graphs. **/ /** **/ /** DATES : # Version 5.1 : from : 11 nov 2007 **/ /** to : 15 jul 2010 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct BdgraphBipartBdParam_ { INT distmax; /*+ Width of band surrounding the frontier +*/ Strat * stratbnd; /*+ Strategy for band graph +*/ Strat * stratorg; /*+ Strategy for original graph +*/ } BdgraphBipartBdParam; /* ** The function prototypes. */ #ifndef BDGRAPH_BIPART_BD #define static #endif int bdgraphBipartBd (Bdgraph * const, const BdgraphBipartBdParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/kdgraph_map_st.h0000644002563400244210000000627511631447170025004 0ustar trophimeutilisateurs du domaine/* Copyright 2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kdgraph_map_st.h **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the strategy and method **/ /** tables and the generic entry point for **/ /** the parallel multi-way static mapping **/ /** routines. **/ /** **/ /** DATES : # Version 5.1 : from : 16 jun 2008 **/ /** to 16 jun 2008 **/ /** **/ /************************************************************/ /* ** The type definitions. */ /*+ Method types. +*/ typedef enum KdgraphMapStMethodType_ { KDGRAPHMAPSTMETHRB = 0, /*+ Dual Recursive Bipartitioning +*/ KDGRAPHMAPSTMETHNBR /*+ Number of methods +*/ } KdgraphMapStMethodType; /* ** The external declarations. */ extern StratTab kdgraphmapststratab; /* ** The function prototypes. */ #ifndef KDGRAPH_MAP_ST #define static #endif int kdgraphMapSt (Kdgraph * restrict const, Kdmapping * restrict const, const Strat * restrict const); #undef static scotch-6.0.4.dfsg/src/libscotch/common_file_uncompress.c0000644002563400244210000003116112262355406026552 0ustar trophimeutilisateurs du domaine/* Copyright 2008,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : common_file_uncompress.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles compressed streams **/ /** for uncompression. **/ /** **/ /** DATES : # Version 5.0 : from : 11 mar 2008 **/ /** to : 15 may 2008 **/ /** # Version 5.1 : from : 27 jun 2010 **/ /** to 27 jun 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define COMMON_FILE #define COMMON_FILE_UNCOMPRESS #ifndef COMMON_NOMODULE #include "module.h" #endif /* COMMON_NOMODULE */ #include "common.h" #include "common_file.h" #include "common_file_compress.h" #ifdef COMMON_FILE_COMPRESS_BZ2 #include "bzlib.h" #endif /* COMMON_FILE_COMPRESS_BZ2 */ #ifdef COMMON_FILE_COMPRESS_GZ #include "zlib.h" #endif /* COMMON_FILE_COMPRESS_GZ */ #ifdef COMMON_FILE_COMPRESS_LZMA #include "lzmadec.h" /* TODO: Temporary interface */ #endif /* COMMON_FILE_COMPRESS_LZMA */ /* ** The static definitions. */ static FileCompressTab filetab[] = { #ifdef COMMON_FILE_COMPRESS_BZ2 { ".bz2", FILECOMPRESSTYPEBZ2, }, #else /* COMMON_FILE_COMPRESS_BZ2 */ { ".bz2", FILECOMPRESSTYPENOTIMPL }, #endif /* COMMON_FILE_COMPRESS_BZ */ #ifdef COMMON_FILE_COMPRESS_GZ { ".gz", FILECOMPRESSTYPEGZ, }, #else /* COMMON_FILE_COMPRESS_GZ */ { ".gz", FILECOMPRESSTYPENOTIMPL }, #endif /* COMMON_FILE_COMPRESS_GZ */ #ifdef COMMON_FILE_COMPRESS_LZMA { ".lzma", FILECOMPRESSTYPELZMA }, #else /* COMMON_FILE_COMPRESS_LZMA */ { ".lzma", FILECOMPRESSTYPENOTIMPL }, #endif /* COMMON_FILE_COMPRESS_LZMA */ { NULL, FILECOMPRESSTYPENOTIMPL } }; /*********************************/ /* */ /* Basic routines for filenames. */ /* */ /*********************************/ /* This routine searches the given file name ** for relevant extensions and returns the ** corresponding code if it is the case. ** It returns: ** - FILECOMPRESSTYPENONE : no recognized file extension. ** - FILECOMPRESSTYPENOTIMPL : compression algorithm not implemented. ** - FILECOMPRESSTYPExxxx : implemented compression algorithm. */ int fileUncompressType ( const char * const nameptr) /*+ Name string +*/ { int namelen; int i; namelen = strlen (nameptr); for (i = 0; filetab[i].name != NULL; i ++) { int extnlen; /* Name of extension string */ extnlen = strlen (filetab[i].name); if ((namelen >= extnlen) && (strncmp (filetab[i].name, nameptr + (namelen - extnlen), extnlen) == 0)) return (filetab[i].type); } return (FILECOMPRESSTYPENONE); } /* This routine creates a thread to uncompress the ** given stream according to the given (un)compression ** algorithm. ** If threads are available, uncompression will be ** performed by an auxiliary thread. Else, a child process ** will be fork()'ed, and after completion this process ** will remain a zombie until the main process terminates. ** It returns: ** - !NULL : stream holding uncompressed data. ** - NULL : on error. */ static void * /* (void *) to comply to the Posix pthread API */ fileUncompress2 ( FileCompressData * const dataptr) { switch (dataptr->typeval) { #ifdef COMMON_FILE_COMPRESS_BZ2 case FILECOMPRESSTYPEBZ2 : fileUncompressBz2 (dataptr); break; #endif /* COMMON_FILE_COMPRESS_BZ2 */ #ifdef COMMON_FILE_COMPRESS_GZ case FILECOMPRESSTYPEGZ : fileUncompressGz (dataptr); break; #endif /* COMMON_FILE_COMPRESS_GZ */ #ifdef COMMON_FILE_COMPRESS_LZMA case FILECOMPRESSTYPELZMA : fileUncompressLzma (dataptr); break; #endif /* COMMON_FILE_COMPRESS_LZMA */ default : errorPrint ("fileUncompress2: method not implemented"); } close (dataptr->innerfd); /* Close writer's end */ memFree (dataptr); /* Free buffers */ return ((void *) 0); /* Don't care anyway */ } FILE * fileUncompress ( FILE * const stream, /*+ Compressed stream +*/ const int typeval) /*+ (Un)compression algorithm +*/ { int filetab[2]; FILE * readptr; FileCompressData * dataptr; #ifdef COMMON_PTHREAD pthread_t thrdval; #endif /* COMMON_PTHREAD */ if (typeval <= FILECOMPRESSTYPENONE) /* If uncompressed stream, return original stream pointer */ return (stream); if (pipe (filetab) != 0) { errorPrint ("fileUncompress: cannot create pipe"); return (NULL); } if ((readptr = fdopen (filetab[0], "r")) == NULL) { errorPrint ("fileUncompress: cannot create stream"); close (filetab[0]); close (filetab[1]); return (NULL); } if ((dataptr = memAlloc (sizeof (FileCompressData) + FILECOMPRESSDATASIZE)) == NULL) { errorPrint ("fileUncompress: out of memory"); fclose (readptr); close (filetab[1]); return (NULL); } dataptr->typeval = typeval; /* Fill structure to be passed to uncompression thread/process */ dataptr->innerfd = filetab[1]; dataptr->outerstream = stream; #ifdef COMMON_PTHREAD if (pthread_create (&thrdval, NULL, (void * (*) (void *)) fileUncompress2, (void *) dataptr) != 0) { /* If could not create thread */ errorPrint ("fileUncompress: cannot create thread"); memFree (dataptr); fclose (readptr); close (filetab[1]); return (NULL); } pthread_detach (thrdval); /* Detach thread so that it will end up gracefully by itself */ #else /* COMMON_PTHREAD */ switch (fork ()) { case -1 : /* Error */ errorPrint ("fileUncompress: cannot create child process"); memFree (dataptr); fclose (readptr); close (filetab[1]); return (NULL); case 0 : /* We are the son process */ fclose (readptr); /* Close reader pipe stream */ fileUncompress2 (dataptr); /* Perform uncompression */ exit (0); /* Exit gracefully */ default : /* We are the father process */ close (filetab[1]); /* Close the writer pipe end */ } #endif /* COMMON_PTHREAD */ return (readptr); } /* This routine uncompresses a stream compressed in the ** bzip2 format. ** It returns: ** - void : in all cases. Uncompression stops immediately ** in case of error. */ #ifdef COMMON_FILE_COMPRESS_BZ2 static void fileUncompressBz2 ( FileCompressData * const dataptr) { BZFILE * bzfile; int bzsize; int bzerror; if (FILECOMPRESSDATASIZE < (BZ_MAX_UNUSED)) { errorPrint ("fileUncompressBz2: cannot start decompression (1)"); return; } if ((bzfile = BZ2_bzReadOpen (&bzerror, dataptr->outerstream, 0, 0, NULL, 0)) == NULL) { errorPrint ("fileUncompressBz2: cannot start decompression (2)"); BZ2_bzReadClose (&bzerror, bzfile); return; } while ((bzsize = BZ2_bzRead (&bzerror, bzfile, &dataptr->datatab, FILECOMPRESSDATASIZE), bzerror) >= BZ_OK) { /* If BZ_OK or BZ_STREAM_END */ if (write (dataptr->innerfd, &dataptr->datatab, bzsize) != bzsize) { errorPrint ("fileUncompressBz2: cannot write"); bzerror = BZ_STREAM_END; /* Avoid other error message */ break; } if (bzerror == BZ_STREAM_END) { /* If end of compressed stream */ void * bzunusptr; int bzunusnbr; BZ2_bzReadGetUnused (&bzerror, bzfile, &bzunusptr, &bzunusnbr); /* Get remaining chars in stream */ if ((bzunusnbr == 0) && (feof (dataptr->outerstream) != 0)) { /* If end of uncompressed stream too */ bzerror = BZ_STREAM_END; break; } memMov (&dataptr->datatab, bzunusptr, bzunusnbr); BZ2_bzReadClose (&bzerror, bzfile); if ((bzfile = BZ2_bzReadOpen (&bzerror, dataptr->outerstream, 0, 0, &dataptr->datatab, bzunusnbr)) == NULL) { errorPrint ("fileUncompressBz2: cannot start decompression (3)"); bzerror = BZ_STREAM_END; break; } } } if (bzerror != BZ_STREAM_END) errorPrint ("fileUncompressBz2: cannot read"); BZ2_bzReadClose (&bzerror, bzfile); fclose (dataptr->outerstream); /* Do as zlib does */ } #endif /* COMMON_FILE_COMPRESS_BZ2 */ /* This routine uncompresses a stream compressed in the ** gzip format. ** It returns: ** - void : in all cases. Uncompression stops immediately ** in case of error. */ #ifdef COMMON_FILE_COMPRESS_GZ static void fileUncompressGz ( FileCompressData * const dataptr) { gzFile gzfile; int gzsize; if ((gzfile = gzdopen (fileno (dataptr->outerstream), "rb")) == NULL) { errorPrint ("fileUncompressGz: cannot start decompression"); return; } while ((gzsize = gzread (gzfile, &dataptr->datatab, FILECOMPRESSDATASIZE)) > 0) { if (write (dataptr->innerfd, &dataptr->datatab, gzsize) != gzsize) { errorPrint ("fileUncompressGz: cannot write"); break; } } if (gzsize < 0) errorPrint ("fileUncompressGz: cannot read"); gzclose (gzfile); } #endif /* COMMON_FILE_COMPRESS_GZ */ /* This routine uncompresses a stream compressed in the ** lzma format. ** It returns: ** - void : in all cases. Uncompression stops immediately ** in case of error. */ #ifdef COMMON_FILE_COMPRESS_LZMA static void fileUncompressLzma ( FileCompressData * const dataptr) { lzmadec_FILE * lzmafile; ssize_t lzmasize; if ((lzmafile = lzmadec_dopen (fileno (dataptr->outerstream))) == NULL) { errorPrint ("fileUncompressLzma: cannot start decompression"); return; } while ((lzmasize = lzmadec_read (lzmafile, (void *) &dataptr->datatab, FILECOMPRESSDATASIZE)) > 0) { if (write (dataptr->innerfd, &dataptr->datatab, lzmasize) != lzmasize) { errorPrint ("fileUncompressLzma: cannot write"); break; } } if (lzmasize < 0) errorPrint ("fileUncompressLzma: cannot read"); lzmadec_close (lzmafile); } #endif /* COMMON_FILE_COMPRESS_LZMA */ scotch-6.0.4.dfsg/src/libscotch/dgraph_allreduce.h0000644002563400244210000001070111631447171025274 0ustar trophimeutilisateurs du domaine/* Copyright 2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /**********************************************************/ /* */ /* NAME : dgraph_allreduce.h */ /* */ /* AUTHOR : Francois PELLEGRINI */ /* */ /* FUNCTION : These lines are the data declarations */ /* for the communication routines */ /* */ /* # Version 5.0 : from : 28 aug 2006 */ /* to 29 aug 2006 */ /* */ /**********************************************************/ /* ** The defines. */ /*+ Combined maximum-sum reduction operator +*/ #define DGRAPHALLREDUCEMAXSUMOP(m,s) \ static \ void \ dgraphAllreduceMaxSumOp##m##_##s ( \ const Gnum * const in, /* First operand */ \ Gnum * const inout, /* Second and output operand */ \ const int * const len, /* Number of instances ; should be 1, not used */ \ const MPI_Datatype * const typedat) /* MPI datatype ; not used */ \ { \ int i; \ \ for (i = 0; i < (m); i ++) /* Perform maximum on first part of data array */ \ if (in[i] > inout[i]) \ inout[i] = in[i]; \ \ for ( ; i < ((m) + (s)); i ++) /* Perform sum on second part of data array */ \ inout[i] += in[i]; \ } #define dgraphAllreduceMaxSum(rlt,rgt,m,s,comm) dgraphAllreduceMaxSum2 ((rlt), (rgt), (m) + (s), (MPI_User_function *) (dgraphAllreduceMaxSumOp##m##_##s), (comm)) /* ** The function prototypes. */ int dgraphAllreduceMaxSum2 (Gnum *, Gnum *, int, MPI_User_function *, MPI_Comm); scotch-6.0.4.dfsg/src/libscotch/library_graph_order_f.c0000644002563400244210000003041011702306121026312 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_order_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the Fortran API for the **/ /** graph ordering routines of the **/ /** libSCOTCH library. **/ /** **/ /** DATES : # Version 3.4 : from : 02 feb 2000 **/ /** to 15 nov 2001 **/ /** # Version 4.0 : from : 02 feb 2002 **/ /** to 13 dec 2005 **/ /** # Version 5.0 : from : 04 aug 2007 **/ /** to 31 may 2008 **/ /** # Version 5.1 : from : 27 mar 2010 **/ /** to 25 jul 2010 **/ /** # Version 6.0 : from : 08 jan 2012 **/ /** to 08 jan 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the ordering routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFGRAPHORDERINIT, scotchfgraphorderinit, ( \ const SCOTCH_Graph * const grafptr, \ SCOTCH_Ordering * const ordeptr, \ SCOTCH_Num * const permtab, \ SCOTCH_Num * const peritab, \ SCOTCH_Num * const cblkptr, \ SCOTCH_Num * const rangtab, \ SCOTCH_Num * const treetab, \ int * const revaptr), \ (grafptr, ordeptr, permtab, peritab, \ cblkptr, rangtab, treetab, revaptr)) { *revaptr = SCOTCH_graphOrderInit (grafptr, ordeptr, permtab, peritab, cblkptr, rangtab, treetab); } /* ** */ FORTRAN ( \ SCOTCHFGRAPHORDEREXIT, scotchfgraphorderexit, ( \ const SCOTCH_Graph * const grafptr, \ SCOTCH_Ordering * const ordeptr), \ (grafptr, ordeptr)) { SCOTCH_graphOrderExit (grafptr, ordeptr); } /* ** */ FORTRAN ( \ SCOTCHFGRAPHORDERSAVE, scotchfgraphordersave, ( \ const SCOTCH_Graph * const grafptr, \ const SCOTCH_Ordering * const ordeptr, \ int * const fileptr, \ int * const revaptr), \ (grafptr, ordeptr, fileptr, revaptr)) { FILE * stream; /* Stream to build from handle */ int filenum; /* Duplicated handle */ int o; if ((filenum = dup (*fileptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFGRAPHORDERSAVE: cannot duplicate handle"); *revaptr = 1; /* Indicate error */ return; } if ((stream = fdopen (filenum, "w")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFGRAPHORDERSAVE: cannot open output stream"); close (filenum); *revaptr = 1; return; } o = SCOTCH_graphOrderSave (grafptr, ordeptr, stream); fclose (stream); /* This closes filenum too */ *revaptr = o; } /* ** */ FORTRAN ( \ SCOTCHFGRAPHORDERSAVEMAP, scotchfgraphordersavemap, ( \ const SCOTCH_Graph * const grafptr, \ const SCOTCH_Ordering * const ordeptr, \ int * const fileptr, \ int * const revaptr), \ (grafptr, ordeptr, fileptr, revaptr)) { FILE * stream; /* Stream to build from handle */ int filenum; /* Duplicated handle */ int o; if ((filenum = dup (*fileptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFGRAPHORDERSAVEMAP: cannot duplicate handle"); *revaptr = 1; /* Indicate error */ return; } if ((stream = fdopen (filenum, "w")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFGRAPHORDERSAVEMAP: cannot open output stream"); close (filenum); *revaptr = 1; return; } o = SCOTCH_graphOrderSaveMap (grafptr, ordeptr, stream); fclose (stream); /* This closes filenum too */ *revaptr = o; } /* ** */ FORTRAN ( \ SCOTCHFGRAPHORDERSAVETREE, scotchfgraphordersavetree, ( \ const SCOTCH_Graph * const grafptr, \ const SCOTCH_Ordering * const ordeptr, \ int * const fileptr, \ int * const revaptr), \ (grafptr, ordeptr, fileptr, revaptr)) { FILE * stream; /* Stream to build from handle */ int filenum; /* Duplicated handle */ int o; if ((filenum = dup (*fileptr)) < 0) { /* If cannot duplicate file descriptor */ errorPrint ("SCOTCHFGRAPHORDERSAVETREE: cannot duplicate handle"); *revaptr = 1; /* Indicate error */ return; } if ((stream = fdopen (filenum, "w")) == NULL) { /* Build stream from handle */ errorPrint ("SCOTCHFGRAPHORDERSAVETREE: cannot open output stream"); close (filenum); *revaptr = 1; return; } o = SCOTCH_graphOrderSaveTree (grafptr, ordeptr, stream); fclose (stream); /* This closes filenum too */ *revaptr = o; } /* ** */ FORTRAN ( \ SCOTCHFGRAPHORDERCOMPUTE, scotchfgraphordercompute, ( \ SCOTCH_Graph * const grafptr, \ SCOTCH_Ordering * const ordeptr, \ SCOTCH_Strat * const stratptr, \ int * const revaptr), \ (grafptr, ordeptr, stratptr, revaptr)) { *revaptr = SCOTCH_graphOrderCompute (grafptr, ordeptr, stratptr); } /* ** */ FORTRAN ( \ SCOTCHFGRAPHORDERCOMPUTELIST, scotchfgraphordercomputelist, ( \ SCOTCH_Graph * const grafptr, \ SCOTCH_Ordering * const ordeptr, \ const SCOTCH_Num * listptr, \ const SCOTCH_Num * const listtab, \ SCOTCH_Strat * const stratptr, \ int * const revaptr), \ (grafptr, ordeptr, listptr, listtab, stratptr, revaptr)) { *revaptr = SCOTCH_graphOrderComputeList (grafptr, ordeptr, *listptr, listtab, stratptr); } /* ** */ FORTRAN ( \ SCOTCHFGRAPHORDER, scotchfgraphorder, ( \ SCOTCH_Graph * const grafptr, \ SCOTCH_Strat * const stratptr, \ SCOTCH_Num * const permtab, \ SCOTCH_Num * const peritab, \ SCOTCH_Num * const cblkptr, \ SCOTCH_Num * const rangtab, \ SCOTCH_Num * const treetab, \ int * const revaptr), \ (grafptr, stratptr, permtab, peritab, \ cblkptr, rangtab, treetab, revaptr)) { *revaptr = SCOTCH_graphOrder (grafptr, stratptr, permtab, peritab, cblkptr, rangtab, treetab); } /* ** */ FORTRAN ( \ SCOTCHFGRAPHORDERLIST, scotchfgraphorderlist, ( \ SCOTCH_Graph * const grafptr, \ const SCOTCH_Num * const listptr, \ const SCOTCH_Num * const listtab, \ SCOTCH_Strat * const stratptr, \ SCOTCH_Num * const permtab, \ SCOTCH_Num * const peritab, \ SCOTCH_Num * const cblkptr, \ SCOTCH_Num * const rangtab, \ SCOTCH_Num * const treetab, \ int * const revaptr), \ (grafptr, listptr, listtab, stratptr, \ permtab, peritab, cblkptr, rangtab, treetab, revaptr)) { *revaptr = SCOTCH_graphOrderList (grafptr, *listptr, listtab, stratptr, permtab, peritab, cblkptr, rangtab, treetab); } /* ** */ FORTRAN ( \ SCOTCHFGRAPHORDERCHECK, scotchfgraphordercheck, ( \ const SCOTCH_Graph * const grafptr, \ const SCOTCH_Ordering * const ordeptr, \ int * const revaptr), \ (grafptr, ordeptr, revaptr)) { *revaptr = SCOTCH_graphOrderCheck (grafptr, ordeptr); } /* ** */ FORTRAN ( \ SCOTCHFSTRATGRAPHORDER, scotchfstratgraphorder, ( \ SCOTCH_Strat * const stratptr, \ const char * const string, \ int * const revaptr, \ const int strnbr), \ (stratptr, string, revaptr, strnbr)) { char * restrict strtab; /* Pointer to null-terminated string */ if ((strtab = (char *) memAlloc (strnbr + 1)) == NULL) { /* Allocate temporary space */ errorPrint ("SCOTCHFSTRATGRAPHORDER: out of memory (1)"); *revaptr = 1; } memCpy (strtab, string, strnbr); /* Copy string contents */ strtab[strnbr] = '\0'; /* Terminate string */ *revaptr = SCOTCH_stratGraphOrder (stratptr, strtab); /* Call original routine */ memFree (strtab); /* Prevent compiler warnings */ } /* ** */ FORTRAN ( \ SCOTCHFSTRATGRAPHORDERBUILD, scotchfstratgraphorderbuild, ( \ SCOTCH_Strat * const stratptr, \ const SCOTCH_Num * const flagval, \ const SCOTCH_Num * const levlnbr, \ const double * const balrat, \ int * const revaptr), \ (stratptr, flagval, levlnbr, balrat, revaptr)) { *revaptr = SCOTCH_stratGraphOrderBuild (stratptr, *levlnbr, *flagval, *balrat); } scotch-6.0.4.dfsg/src/libscotch/common_string.c0000644002563400244210000001076411631447171024671 0ustar trophimeutilisateurs du domaine/* Copyright 2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : common_string.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a parallel direct block solver. **/ /** These lines are common routines used **/ /** by all modules. **/ /** **/ /** DATES : # Version 5.1 : from : 23 jul 2010 **/ /** to 23 jul 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define COMMON #ifndef COMMON_NOMODULE #include "module.h" #endif /* COMMON_NOMODULE */ #include #include "common.h" /********************************/ /* */ /* String substitution routine. */ /* */ /********************************/ static void stringSubst2 ( char * const bsrcptr, char * const bdstptr, const char * const pattstr, const char * const replstr, const int pattsiz, const int replsiz) { char * pattptr; int pattidx; pattptr = strstr (bsrcptr, pattstr); /* Search for the pattern in the remaining source string */ pattidx = (pattptr == NULL) ? (strlen (bsrcptr) + 1): (pattptr - bsrcptr); /* Get length of unchanged part */ if (replsiz < pattsiz) /* If replacement is smaller, pre-move unchanged part */ memMov (bdstptr, bsrcptr, pattidx * sizeof (char)); if (pattptr != NULL) /* If remaining part of string has to be processed */ stringSubst2 (pattptr + pattsiz, bdstptr + pattidx + replsiz, pattstr, replstr, pattsiz, replsiz); if (replsiz > pattsiz) /* If replacement is longer, post-move unchanged part */ memMov (bdstptr, bsrcptr, pattidx * sizeof (char)); if (pattptr != NULL) /* If there is something to replace */ memCpy (bdstptr + pattidx, replstr, replsiz * sizeof (char)); /* Write replacement string */ return; } void stringSubst ( char * const buffptr, /* String to search into */ const char * const pattstr, /* Pattern to search for */ const char * const replstr) /* Replacement string */ { int pattsiz; int replsiz; pattsiz = strlen (pattstr); replsiz = strlen (replstr); stringSubst2 (buffptr, buffptr, pattstr, replstr, pattsiz, replsiz); } scotch-6.0.4.dfsg/src/libscotch/bgraph_bipart_df.h0000644002563400244210000001306212056137755025275 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2011,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bgraph_bipart_df.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the function **/ /** declarations for the diffusion scheme **/ /** bipartitioning method. **/ /** **/ /** DATES : # Version 5.0 : from : 09 jan 2007 **/ /** to 28 may 2007 **/ /** # Version 5.1 : from : 29 oct 2007 **/ /** to 28 mar 2011 **/ /** # Version 6.0 : from : 08 nov 2011 **/ /** to 20 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines. */ /* Small non-zero float value. */ #define BGRAPHBIPARTDFEPSILON (1.0F / (float) (GNUMMAX)) /*+ Sign masking operator. +*/ #define BGRAPHBIPARTDFGNUMSGNMSK(i) (- (Gnum) (((Gunum) (i)) >> (sizeof (Gnum) * 8 - 1))) /* ** The type and structure definitions. */ /*+ Job selection policy types. +*/ typedef enum BgraphBipartDfType_ { BGRAPHBIPARTDFTYPEBAL = 0, /*+ Balance to average +*/ BGRAPHBIPARTDFTYPEKEEP /*+ Preserve current imbalance +*/ } BgraphBipartDfType; /*+ Method parameters. +*/ typedef struct BgraphBipartDfParam_ { INT passnbr; /*+ Number of passes to do +*/ BgraphBipartDfType typeval; /*+ Type of balance to reach +*/ } BgraphBipartDfParam; /*+ The loop routine parameter structure. It contains the thread-independent data. +*/ typedef struct BgraphBipartDfData_ { ThreadGroupHeader thrddat; Bgraph * grafptr; /*+ Graph to work on +*/ float * difntax; /*+ New diffusion value array +*/ float * difotax; /*+ Old diffusion value array +*/ INT passnbr; /*+ Number of passes +*/ Gnum vanctab[2]; /*+ Anchor load arrays +*/ #ifdef BGRAPHBIPARTDFTHREAD int abrtval; /*+ Abort value +*/ #endif /* BGRAPHBIPARTDFTHREAD */ } BgraphBipartDfData; /*+ The thread-specific data block. +*/ typedef struct BgraphBipartDfThread_ { ThreadHeader thrddat; /*+ Thread management data +*/ Gnum vertbas; /*+ Minimum regular vertex index +*/ Gnum vertnnd; /*+ After-last regular vertex index +*/ Gnum fronnnd; /*+ After-last frontier vertex index +*/ Gnum compload1; /*+ State return values to aggregate +*/ Gnum compsize1; Gnum commloadextn; Gnum commloadintn; Gnum commgainextn; float vanctab[2]; /*+ Area for (reducing) contributions to anchors +*/ #ifdef BGRAPHBIPARTDFTHREAD Gnum veexsum; /*+ Area for reducing sums of external gains +*/ Gnum veexsum1; #endif /* BGRAPHBIPARTDFTHREAD */ } BgraphBipartDfThread; /* ** The function prototypes. */ #ifndef BGRAPH_BIPART_DF #define static #endif int bgraphBipartDf (Bgraph * restrict const, const BgraphBipartDfParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/vmesh_store.c0000644002563400244210000001414311631447170024343 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vmesh_store.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the save data **/ /** structure handling routines for node **/ /** separation meshes. **/ /** **/ /** DATES : # Version 4.0 : from : 10 sep 2002 **/ /** to : 10 sep 2002 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VMESH_STORE #include "module.h" #include "common.h" #include "graph.h" #include "mesh.h" #include "vmesh.h" /*********************************/ /* */ /* Store mesh handling routines. */ /* */ /*********************************/ /* This routine builds a save structure ** for the given node separation mesh. ** It returns: ** - 0 : if allocation succeeded. ** - !0 : on error. */ int vmeshStoreInit ( const Vmesh * const meshptr, VmeshStore * const storptr) { Gnum savsize; savsize = (meshptr->m.velmnbr + meshptr->m.vnodnbr) * (sizeof (GraphPart) + sizeof (Gnum)); /* Compute size for frontier and part arrays */ if ((storptr->datatab = (byte *) memAlloc (savsize)) == NULL) { /* Allocate save structure */ errorPrint ("vmeshStoreInit: out of memory"); return (1); } return (0); } /* This routine frees a mesh node ** separation save structure. ** It returns: ** - VOID : in all cases. */ void vmeshStoreExit ( VmeshStore * const storptr) { memFree (storptr->datatab); #ifdef SCOTCH_DEBUG_VMESH2 storptr->datatab = NULL; #endif /* SCOTCH_DEBUG_VMESH2 */ } /* This routine saves partition data from the ** given node separation mesh to the given ** save structure. ** It returns: ** - VOID : in all cases. */ void vmeshStoreSave ( const Vmesh * const meshptr, VmeshStore * const storptr) { byte * parttab; /* Pointer to part data save area */ byte * frontab; /* Pointer to frontier data save area */ storptr->ecmpsize[0] = meshptr->ecmpsize[0]; /* Save partition parameters */ storptr->ecmpsize[1] = meshptr->ecmpsize[1]; storptr->ncmpload[0] = meshptr->ncmpload[0]; storptr->ncmpload[1] = meshptr->ncmpload[1]; storptr->ncmpload[2] = meshptr->ncmpload[2]; storptr->ncmploaddlt = meshptr->ncmploaddlt; storptr->ncmpsize[0] = meshptr->ncmpsize[0]; storptr->ncmpsize[1] = meshptr->ncmpsize[1]; storptr->fronnbr = meshptr->fronnbr; frontab = storptr->datatab; /* Compute data offsets within save structure */ parttab = frontab + meshptr->fronnbr * sizeof (Gnum); memCpy (frontab, meshptr->frontab, meshptr->fronnbr * sizeof (Gnum)); memCpy (parttab, meshptr->parttax + meshptr->m.baseval, (meshptr->m.velmnbr + meshptr->m.vnodnbr) * sizeof (GraphPart)); } /* This routine updates partition data of the ** given active graph, using the given save graph. ** It returns: ** - VOID : in all cases. */ void vmeshStoreUpdt ( Vmesh * const meshptr, const VmeshStore * const storptr) { byte * frontab; /* Pointer to frontier data save area */ byte * parttab; /* Pointer to part data save area */ meshptr->ecmpsize[0] = storptr->ecmpsize[0]; /* Load partition parameters */ meshptr->ecmpsize[1] = storptr->ecmpsize[1]; meshptr->ncmpload[0] = storptr->ncmpload[0]; meshptr->ncmpload[1] = storptr->ncmpload[1]; meshptr->ncmpload[2] = storptr->ncmpload[2]; meshptr->ncmploaddlt = storptr->ncmploaddlt; meshptr->ncmpsize[0] = storptr->ncmpsize[0]; meshptr->ncmpsize[1] = storptr->ncmpsize[1]; meshptr->fronnbr = storptr->fronnbr; frontab = storptr->datatab; /* Compute data offsets within save structure */ parttab = frontab + storptr->fronnbr * sizeof (Gnum); memCpy (meshptr->frontab, frontab, storptr->fronnbr * sizeof (Gnum)); memCpy (meshptr->parttax + meshptr->m.baseval, parttab, (meshptr->m.velmnbr + meshptr->m.vnodnbr) * sizeof (GraphPart)); } scotch-6.0.4.dfsg/src/libscotch/library_dgraph_build_grid3d_f.c0000644002563400244210000000757412055776105027734 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_build_grid3d_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API for **/ /** the source graph handling routines of **/ /** the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 16 feb 2007 **/ /** to 16 feb 2007 **/ /** # Version 5.1 : from : 06 jun 2010 **/ /** to 06 jun 2010 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "ptscotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the distributed graph handling */ /* routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFDGRAPHBUILDGRID3D, scotchfdgraphbuildgrid3d, ( \ SCOTCH_Dgraph * const grafptr, \ const SCOTCH_Num * const baseptr, \ const SCOTCH_Num * const dimxptr, \ const SCOTCH_Num * const dimyptr, \ const SCOTCH_Num * const dimzptr, \ const SCOTCH_Num * const incrptr, \ const int * const flagptr, \ int * const revaptr), \ (grafptr, baseptr, dimxptr, dimyptr, dimzptr, incrptr, flagptr, revaptr)) { *revaptr = SCOTCH_dgraphBuildGrid3D (grafptr, *baseptr, *dimxptr, *dimyptr, *dimzptr, *incrptr, *flagptr); } scotch-6.0.4.dfsg/src/libscotch/library_dgraph_order_io_f.c0000644002563400244210000000760312055777432027200 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_order_io_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the Fortran API for the **/ /** distributed ordering I/O routines of **/ /** the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 26 jul 2007 **/ /** to 18 oct 2007 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "ptscotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the ordering routines. */ /* */ /**************************************/ FORTRAN ( \ SCOTCHFDGRAPHORDERSAVEMAP, scotchfdgraphordersavemap, ( \ const SCOTCH_Dgraph * const grafptr, \ const SCOTCH_Dordering * const ordeptr, \ FILE * const stream, \ int * const revaptr), \ (grafptr, ordeptr, stream, revaptr)) { *revaptr = SCOTCH_dgraphOrderSaveMap (grafptr, ordeptr, stream); } /* ** */ FORTRAN ( \ SCOTCHFDGRAPHORDERSAVETREE, scotchfdgraphordersavetree, ( \ const SCOTCH_Dgraph * const grafptr, \ const SCOTCH_Dordering * const ordeptr, \ FILE * const stream, \ int * const revaptr), \ (grafptr, ordeptr, stream, revaptr)) { *revaptr = SCOTCH_dgraphOrderSaveTree (grafptr, ordeptr, stream); } scotch-6.0.4.dfsg/src/libscotch/hgraph_order_nd.h0000644002563400244210000000677011631447170025146 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hgraph_order_nd.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the halo graph nested dissection **/ /** ordering algorithm. **/ /** **/ /** DATES : # Version 3.2 : from : 17 oct 1996 **/ /** to : 18 aug 1998 **/ /** # Version 3.3 : from : 02 oct 1998 **/ /** to 13 mar 1999 **/ /** # Version 4.0 : from : 03 jan 2002 **/ /** to 24 apr 2004 **/ /** # Version 5.1 : from : 04 nov 2010 **/ /** to 04 nov 2010 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct HgraphOrderNdParam_ { Strat * sepstrat; /*+ Separation strategy +*/ Strat * ordstratlea; /*+ Leaf ordering strategy +*/ Strat * ordstratsep; /*+ Separator ordering strategy +*/ } HgraphOrderNdParam; /* ** The function prototypes. */ #ifndef HGRAPH_ORDER_ND #define static #endif int hgraphOrderNd (const Hgraph * const, Order * const, const Gnum, OrderCblk * const, const HgraphOrderNdParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/dorder_tree_dist.c0000644002563400244210000003316411631447170025332 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dorder_tree_dist.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles distributed **/ /** orderings. **/ /** **/ /** DATES : # Version 5.1 : from : 28 nov 2007 **/ /** to 09 may 2008 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DORDER #include "module.h" #include "common.h" #include "dgraph.h" #include "dorder.h" /************************************/ /* */ /* These routines handle orderings. */ /* */ /************************************/ /* This function returns to all processes the ** number of distributed leaf column blocks ** possessed by the ordering. ** It returns: ** - >=0 : number of distributed column blocks. ** - <0 : on error. */ Gnum dorderCblkDist ( const Dorder * restrict const ordeptr) { const DorderLink * restrict linklocptr; Gnum dblklocnbr; /* Local number of locally-rooted distributed column blocks */ Gnum dblkglbnbr; for (linklocptr = ordeptr->linkdat.nextptr, dblklocnbr = 0; /* For all nodes in local ordering structure */ linklocptr != &ordeptr->linkdat; linklocptr = linklocptr->nextptr) { const DorderCblk * restrict cblklocptr; cblklocptr = (DorderCblk *) linklocptr; /* TRICK: FIRST */ if (cblklocptr->cblknum.proclocnum == ordeptr->proclocnum) dblklocnbr ++; } if (MPI_Allreduce (&dblklocnbr, &dblkglbnbr, 1, GNUM_MPI, MPI_SUM, ordeptr->proccomm) != MPI_SUCCESS) { errorPrint ("dorderCblkDist: communication error"); return ((Gnum) -1); } return (dblkglbnbr); } /* This function returns on all of the procesors the ** distributed part of the distributed structure of ** the given distributed ordering. The two array ** pointers which must be passed should both point to ** arrays of size dorderCblkDist(). ** It returns: ** - 0 : if the distributed tree structure could be computed. ** - !0 : on error. */ int dorderTreeDist ( const Dorder * restrict const ordeptr, const Dgraph * restrict const grafptr, Gnum * restrict const treeglbtab, Gnum * restrict const sizeglbtab) { const DorderLink * restrict linklocptr; Gnum * restrict dataloctab; Gnum * restrict dataglbtab; Gnum dblklocnum; Gnum dblklocnbr; /* Local number of distributed column blocks */ Gnum dblkglbnbr; /* Global number of distributed column blocks */ Gnum dblkglbnum; Gnum dblkglbtmp; int * restrict dblkcnttab; int * restrict dblkdsptab; int * restrict cblkdsptab; Gnum cblkglbtmp; Gnum * restrict srt1glbtab; Gnum * restrict srt2glbtab; int procglbnbr; int procnum; Gnum reduloctab[3]; Gnum reduglbtab[3]; for (linklocptr = ordeptr->linkdat.nextptr, dblklocnbr = 0; /* For all nodes in local ordering structure */ linklocptr != &ordeptr->linkdat; linklocptr = linklocptr->nextptr) { const DorderCblk * restrict cblklocptr; cblklocptr = (DorderCblk *) linklocptr; /* TRICK: FIRST */ if (cblklocptr->cblknum.proclocnum == ordeptr->proclocnum) { #ifdef SCOTCH_DEBUG_DORDER2 Gnum cblklocnum; cblklocnum = cblklocptr->cblknum.cblklocnum; if ((cblklocnum < 0) || (cblklocnum >= ordeptr->cblklocnbr)) { errorPrint ("dorderTreeDist: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_DORDER2 */ dblklocnbr ++; } } if (MPI_Allreduce (&dblklocnbr, &dblkglbnbr, 1, GNUM_MPI, MPI_SUM, ordeptr->proccomm) != MPI_SUCCESS) { /* Get overall number of distributed blocks */ errorPrint ("dorderTreeDist: communication error (1)"); return (1); } MPI_Comm_size (ordeptr->proccomm, &procglbnbr); reduloctab[0] = reduloctab[1] = reduloctab[2] = 0; if (memAllocGroup ((void **) (void *) &dblkcnttab, (size_t) ( procglbnbr * sizeof (int)), &dblkdsptab, (size_t) ( procglbnbr * sizeof (int)), /* TRICK: cblkdsptab used as secondary array after cblkcnttab */ &cblkdsptab, (size_t) ((procglbnbr + 1) * sizeof (int)), /* TRICK: have an array at least of size 2 */ &dataloctab, (size_t) ( dblklocnbr * 4 * sizeof (Gnum)), &dataglbtab, (size_t) ( dblkglbnbr * 4 * sizeof (Gnum)), &srt1glbtab, (size_t) ( dblkglbnbr * 2 * sizeof (Gnum)), /* TRICK: one more slot for root node */ &srt2glbtab, (size_t) ( dblkglbnbr * 2 * sizeof (Gnum)), NULL) == NULL) { /* TRICK: one more slot for root node */ errorPrint ("dorderTreeDist: out of memory"); reduloctab[0] = 1; /* Memory error */ } else { if (treeglbtab != NULL) reduloctab[1] = 1; /* Compute the "or" of any array being non-null */ if (sizeglbtab != NULL) { reduloctab[2] = reduloctab[1]; /* Compute the "and" of any array being non-null */ reduloctab[1] = 1; } } #ifdef SCOTCH_DEBUG_DORDER1 /* Communication cannot be merged with a useful one */ if (MPI_Allreduce (reduloctab, reduglbtab, 3, GNUM_MPI, MPI_SUM, ordeptr->proccomm) != MPI_SUCCESS) { errorPrint ("dorderTreeDist: communication error (1)"); reduglbtab[0] = /* Post-process error below */ reduglbtab[1] = /* Prevent Valgrind from yelling */ reduglbtab[2] = 1; } #else /* SCOTCH_DEBUG_DORDER1 */ reduglbtab[0] = reduloctab[0]; reduglbtab[1] = procglbnbr - 1 + reduloctab[1]; reduglbtab[2] = procglbnbr - 1 + reduloctab[2]; #endif /* SCOTCH_DEBUG_DORDER1 */ if (reduglbtab[1] != reduglbtab[2]) { /* If not both arrays provided on each of the candidate processors */ if (reduloctab[1] != reduloctab[2]) errorPrint ("dorderTreeDist: invalid parameters (1)"); reduglbtab[0] = 1; } if (reduglbtab[2] != procglbnbr) { errorPrint ("dorderTreeDist: invalid parameters (2)"); reduglbtab[0] = 1; } if (reduglbtab[0] != 0) { if (dblkcnttab != NULL) memFree (dblkcnttab); /* Free group leader */ return (1); } cblkdsptab[0] = (int) dblklocnbr; /* MPI only supports int as count type */ cblkdsptab[1] = (int) ordeptr->cblklocnbr; /* TRICK: cblkdsptab is at least of size 2 */ if (MPI_Allgather (cblkdsptab, 2, MPI_INT, dblkcnttab, 2, MPI_INT, ordeptr->proccomm) != MPI_SUCCESS) { errorPrint ("dorderTreeDist: communication error (2)"); return (1); } for (procnum = cblkglbtmp = 0; procnum < procglbnbr; procnum ++) { /* Accumulate un-based global start indices for all column blocks */ cblkdsptab[procnum] = cblkglbtmp; dblkcnttab[procnum] = dblkcnttab[2 * procnum] * 4; /* Four times for dataloctab */ cblkglbtmp += dblkcnttab[2 * procnum + 1]; } for (procnum = dblkglbtmp = 0; procnum < procglbnbr; procnum ++) { /* Accumulate un-based global start indices for distributed column blocks */ dblkdsptab[procnum] = dblkglbtmp; dblkglbtmp += dblkcnttab[procnum]; } for (linklocptr = ordeptr->linkdat.nextptr, dblklocnum = 0; /* For all nodes in local ordering structure */ linklocptr != &ordeptr->linkdat; linklocptr = linklocptr->nextptr) { const DorderCblk * restrict cblklocptr; cblklocptr = (DorderCblk *) linklocptr; /* TRICK: FIRST */ if (cblklocptr->cblknum.proclocnum == ordeptr->proclocnum) { /* If node is local */ dataloctab[4 * dblklocnum] = cblkdsptab[ordeptr->proclocnum] + cblklocptr->cblknum.cblklocnum; dataloctab[4 * dblklocnum + 1] = cblklocptr->ordeglbval; dataloctab[4 * dblklocnum + 2] = cblkdsptab[cblklocptr->fathnum.proclocnum] + cblklocptr->fathnum.cblklocnum; dataloctab[4 * dblklocnum + 3] = cblklocptr->vnodglbnbr; dblklocnum ++; } } if (MPI_Allgatherv (dataloctab, 4 * dblklocnbr, GNUM_MPI, dataglbtab, dblkcnttab, dblkdsptab, GNUM_MPI, ordeptr->proccomm) != MPI_SUCCESS) { errorPrint ("dorderTreeDist: communication error (3)"); return (1); } for (dblkglbnum = 0; dblkglbnum < dblkglbnbr; dblkglbnum ++) { srt1glbtab[2 * dblkglbnum] = dataglbtab[4 * dblkglbnum + 1]; srt1glbtab[2 * dblkglbnum + 1] = dataglbtab[4 * dblkglbnum]; } intSort2asc2 (srt1glbtab, dblkglbnbr); /* Sort nodes by ascending inverse start index to get permutation of column block indices */ for (dblkglbnum = 0; dblkglbnum < dblkglbnbr; dblkglbnum ++) { srt1glbtab[2 * dblkglbnum] = srt1glbtab[2 * dblkglbnum + 1]; srt1glbtab[2 * dblkglbnum + 1] = dblkglbnum; } intSort2asc2 (srt1glbtab, dblkglbnbr); /* Sort nodes by ascending column block index to match with the ones of dataglbtab */ for (dblkglbnum = 0; dblkglbnum < dblkglbnbr; dblkglbnum ++) { srt2glbtab[2 * dblkglbnum] = dataglbtab[4 * dblkglbnum + 2]; srt2glbtab[2 * dblkglbnum + 1] = dblkglbnum; } intSort2asc2 (srt2glbtab, dblkglbnbr); /* Sort father indices by ascending column block indices */ #ifdef SCOTCH_DEBUG_DORDER2 if (srt2glbtab[0] != -1) { /* If tree has no root */ errorPrint ("dorderTreeDist: internal error (2)"); memFree (dblkcnttab); /* Free group leader */ return (1); } if ((dblkglbnbr > 1) && (srt2glbtab[2] == -1)) { /* If tree has multiple roots */ errorPrint ("dorderTreeDist: internal error (3)"); memFree (dblkcnttab); /* Free group leader */ return (1); } #endif /* SCOTCH_DEBUG_DORDER2 */ for (dblkglbnum = 1, dblkglbtmp = 0; dblkglbnum < dblkglbnbr; ) { /* Replace in block data the father column block indices by the new permuted indices */ if (srt2glbtab[2 * dblkglbnum] == srt1glbtab[2 * dblkglbtmp]) dataglbtab[4 * srt2glbtab[2 * (dblkglbnum ++) + 1] + 2] = srt1glbtab[2 * dblkglbtmp + 1]; else { #ifdef SCOTCH_DEBUG_DORDER2 if ((srt2glbtab[2 * dblkglbnum] < srt1glbtab[2 * dblkglbtmp]) || /* If column block index not found in table */ (dblkglbtmp >= (dblkglbnbr - 1))) { errorPrint ("dorderTreeDist: internal error (4)"); memFree (dblkcnttab); /* Free group leader */ return (1); } #endif /* SCOTCH_DEBUG_DORDER2 */ dblkglbtmp ++; } } for (dblkglbnum = 0; dblkglbnum < dblkglbnbr; dblkglbnum ++) { srt2glbtab[2 * dblkglbnum] = dataglbtab[4 * dblkglbnum]; srt2glbtab[2 * dblkglbnum + 1] = dblkglbnum; } intSort2asc2 (srt2glbtab, dblkglbnbr); /* Sort father indices by ascending column block indices */ for (dblkglbnum = 0; dblkglbnum < dblkglbnbr; dblkglbnum ++) { #ifdef SCOTCH_DEBUG_DORDER2 if (srt1glbtab[2 * dblkglbnum] != srt2glbtab[2 * dblkglbnum]) { errorPrint ("dorderTreeDist: internal error (5)"); memFree (dblkcnttab); /* Free group leader */ return (1); } #endif /* SCOTCH_DEBUG_DORDER2 */ treeglbtab[srt1glbtab[2 * dblkglbnum + 1]] = dataglbtab[4 * srt2glbtab[2 * dblkglbnum + 1] + 2]; sizeglbtab[srt1glbtab[2 * dblkglbnum + 1]] = dataglbtab[4 * srt2glbtab[2 * dblkglbnum + 1] + 3]; } memFree (dblkcnttab); /* Free group leader */ return (0); } scotch-6.0.4.dfsg/src/libscotch/wgraph_part_fm.c0000644002563400244210000011537212256321673025016 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2013 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : wgraph_part_fm.c **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Charles-Edmond BICHOT (v5.1b) **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module is the improved Fiduccia- **/ /** Mattheyses refinement routine for the **/ /** vertex overlapped graph partitioning. **/ /** **/ /** DATES : # Version 5.1 : from : 01 dec 2007 **/ /** to : 01 jul 2008 **/ /** # Version 6.0 : from : 05 nov 2009 **/ /** to 24 dec 2013 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define WGRAPH_PART_FM #include "module.h" #include "common.h" #include "gain.h" #include "graph.h" #include "wgraph.h" #include "wgraph_part_gg.h" #include "wgraph_part_fm.h" /* ** The static variables. */ static const Gnum wgraphpartfmloadone = 1; /*********************************/ /* */ /* Gain table handling routines. */ /* */ /*********************************/ /* This routine returns the vertex of best gain ** whose swap will keep the balance correct. ** It returns: ** - !NULL : pointer to the vertex gainlink. ** - NULL : if no more vertices available. */ static WgraphPartFmLink * wgraphPartFmTablGet ( Wgraph * restrict const grafptr, /*+ Active graph +*/ WgraphPartFmVertex * hashtab, GainTabl * const tablptr, /*+ Gain table +*/ Gnum * restrict diffload) { Gnum gainbest; /* Separator gain of best link */ Gnum bestdiffload; const GainEntr * tablbest; /* Gain table entry of best link */ WgraphPartFmLink * linkptr; /* Pointer to current gain link */ WgraphPartFmLink * linkbest; /* Pointer to best link found */ linkbest = NULL; /* Assume no candidate vertex found yet */ tablbest = tablptr->tend; gainbest = GAINMAX; for (linkptr = (WgraphPartFmLink *) gainTablFrst (tablptr); /* Select candidate vertices */ (linkptr != NULL) && (linkptr->gainlink.tabl <= tablbest); linkptr = (WgraphPartFmLink *) gainTablNext (tablptr, (GainLink *) linkptr)) { Gnum vertpart; /* Part of current vertex */ Gnum gaincur; /* Separator gain of current link */ vertpart = linkptr->partval; gaincur = linkptr->gain; /* Get separator gain and vertex balance */ if (linkptr->minloadpartval == -1) { return (linkptr); /* Return best link found */ } if ((gaincur < gainbest) || /* And if it gives better gain than gain max */ ((gaincur == gainbest) && /* Or is in preferred part */ ((grafptr->compload[vertpart] - grafptr->compload[linkptr->minloadpartval]) <= bestdiffload))) { linkbest = linkptr; /* Select it */ gainbest = gaincur; tablbest = linkptr->gainlink.tabl; bestdiffload = grafptr->compload[vertpart] - grafptr->compload[linkptr->minloadpartval]; } } *diffload += bestdiffload; return (linkbest); /* Return best link found */ } /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ int wgraphPartFm ( Wgraph * restrict const grafptr, /*+ Active graph +*/ const WgraphPartFmParam * const paraptr) /*+ Method parameters +*/ { int passnbr; /* Maximum number of passes to go */ int moveflag; /* Flag set if useful moves made */ Gnum fronnum; /* Current index of frontier vertex */ Gnum partval; Gnum partnbr; Gnum vertnum; Gnum hashnum; Gnum velosum; Gnum minload; Gnum maxload; Gnum frlobst; Gnum linknbr; Gnum savenum; Gnum hashmax; /* Maximum number of elements in table */ Gnum hashsiz; /* Size of hash and save tables */ Gnum hashmsk; /* Mask for access to hash table */ Gnum hashnbr; /* Number of elements in hash table */ Gnum velomsk; Gnum * restrict movetab; GainTabl * restrict tablptr; /* Pointer to gain tables */ const Gnum * restrict velobax; /* Data for handling of optional arrays */ WgraphPartFmVertex * hashtab; /* Hash vertex table */ WgraphPartFmVertex * vexxptr; WgraphPartFmVertex * vertlist; WgraphPartFmVertex * locklist; WgraphPartFmSave * restrict savetab; WgraphPartFmLink * restrict linktab; WgraphPartFmPartList * restrict partlist; WgraphPartFmPartList * restrict partlistptr; WgraphPartFmPartList * restrict partlistloadptr; partnbr = grafptr->partnbr; for (partval = 0, velosum = 0; partval < partnbr; partval ++) velosum += grafptr->compload[partval]; if (grafptr->s.velotax == NULL) { /* Set accesses to optional arrays */ velobax = &wgraphpartfmloadone; /* In case vertices not weighted (least often) */ velomsk = 0; } else { velobax = grafptr->s.velotax; velomsk = ~((Gnum) 0); } minload = velosum * (1. - paraptr->deltrat) / (float) (partnbr); maxload = velosum * (1. + paraptr->deltrat) / (float) (partnbr); if (grafptr->fronnbr == 0) { /* If no frontier defined */ for (partval = 0; partval < partnbr; partval ++) { if (grafptr->compload[partval] < minload /* If balance is not achieved */ || grafptr->compload[partval] > maxload) { /* Imbalance must be fought */ WgraphPartGgParam paradat; paradat.passnbr = 5; /* Use a standard algorithm */ wgraphPartGg (grafptr, ¶dat); if (grafptr->fronnbr == 0) /* If new partition has no frontier */ return (0); /* This algorithm is still useless */ } return (0); /* This algorithm is still useless */ } } hashnbr = 16 * (grafptr->fronnbr + paraptr->movenbr + grafptr->s.degrmax) + 1; if (hashnbr > grafptr->s.vertnbr) hashnbr = 4 * grafptr->s.vertnbr; hashnbr *= 2; for (hashsiz = 512; hashsiz < hashnbr; hashsiz <<= 1) ; /* Get upper power of two */ hashmsk = hashsiz - 1; hashmax = hashsiz >> 2; /* Use hash table at 1/4 of its capacity */ hashnbr = 0; if (((tablptr = gainTablInit (GAINMAX, WGRAPHSEPAFMGAINBITS)) == NULL) || /* Use logarithmic array only */ (memAllocGroup ((void **) (void *) &hashtab, (size_t) (hashsiz * sizeof (WgraphPartFmVertex)), &linktab, (size_t) (hashsiz * sizeof (WgraphPartFmLink)), &partlist,(size_t) (partnbr * sizeof (WgraphPartFmPartList)), &savetab, (size_t) (hashsiz * sizeof (WgraphPartFmSave)), &movetab, (size_t) (hashsiz * sizeof (Gnum)), NULL) == NULL)) { errorPrint ("wgraphPartFm: out of memory (1)"); if (tablptr != NULL) gainTablExit (tablptr); return (1); } memSet (hashtab, ~0, hashsiz * sizeof (WgraphPartFmVertex)); memSet (linktab, ~0, hashsiz * sizeof (WgraphPartFmLink)); linknbr = 0; locklist = NULL; passnbr = paraptr->passnbr; frlobst = grafptr->fronload; for (fronnum = 0; fronnum < grafptr->fronnbr; fronnum ++) { /* Set initial gains */ Gnum edgenum; Gnum compgain; Gnum minloadpartval; Gnum minloadpartload; Gnum secondloadpartval; WgraphPartFmLink * restrict linklist; WgraphPartFmLink * restrict linkptr; minloadpartval = secondloadpartval = -1; partlistptr = NULL; vertnum = grafptr->frontab[fronnum]; compgain = - velobax[vertnum & velomsk]; /* Gain initialised as negative value for the frontier */ memSet (partlist, 0, partnbr * sizeof (WgraphPartFmPartList)); for (edgenum = grafptr->s.verttax[vertnum]; edgenum < grafptr->s.vendtax[vertnum]; edgenum ++) { Gnum vertnum2; WgraphPartFmVertex * vexxptr; vertnum2 = grafptr->s.edgetax[edgenum]; for (hashnum = (vertnum2 * WGRAPHSEPAFMHASHPRIME) & hashmsk; (hashtab[hashnum].vertnum != vertnum2) && (hashtab[hashnum].vertnum != ~0); hashnum = (hashnum + 1) & hashmsk); vexxptr = hashtab + hashnum; if (vexxptr->vertnum == ~0) { /* If vertex not found add it in the hash table */ vexxptr->vertnum = vertnum2; vexxptr->partval = grafptr->parttax[vertnum2]; vexxptr->linklist = NULL; hashnbr ++; if (hashnbr >= hashmax) { if (wgraphPartFmResize () != 0) { errorPrint ("wgraphPartFm: out of memory (2)"); return (1); } } } if (vexxptr->partval != -1) { /* If its part is not the separator */ if (partlist[vexxptr->partval].gain == 0) { /* and not yet linked */ partlist[vexxptr->partval].prev = partlistptr; /* link it */ partlistptr = partlist + vexxptr->partval; if (minloadpartval == -1 || minloadpartload > grafptr->compload[vexxptr->partval]) { secondloadpartval = minloadpartval; minloadpartval = vexxptr->partval; minloadpartload = grafptr->compload[minloadpartval]; } else if (secondloadpartval != vexxptr->partval) { secondloadpartval = vexxptr->partval; } } partlist[vexxptr->partval].gain -= velobax[vertnum2 & velomsk]; /* Store the gain of this vertex move for this part */ compgain += velobax[vertnum2 & velomsk]; /* Store the global gain of this vertex move */ } } for (hashnum = (vertnum * WGRAPHSEPAFMHASHPRIME) & hashmsk; hashtab[hashnum].vertnum != vertnum && hashtab[hashnum].vertnum != ~0; hashnum = (hashnum + 1) & hashmsk); if (hashtab[hashnum].vertnum == ~0) { /* If vertex not found */ hashtab[hashnum].vertnum = vertnum; /* Add it in the hash table */ hashtab[hashnum].partval = -1; hashtab[hashnum].linklist = NULL; hashnbr ++; if (hashnbr >= hashmax) { if (wgraphPartFmResize () != 0) { errorPrint ("wgraphPartFm: out of memory (2)"); return (1); } } } hashtab[hashnum].linklist = (partlistptr != NULL) /* If selected vertex is not isolated */ ? linktab + linknbr /* Then first link will next element in linktab */ : NULL; /* Else, no link */ linklist = linkptr = NULL; /* Assume list is empty */ while (partlistptr != NULL) { /* For each linked part */ partval = partlistptr - partlist; partlistptr = partlistptr->prev; linkptr = linktab + linknbr; /* Create link at the end of linktab */ linkptr->partval = partval; linkptr->hashnum = hashnum; linkptr->gain = compgain + partlist[partval].gain; if (partval != minloadpartval) linkptr->minloadpartval = minloadpartval; else linkptr->minloadpartval = secondloadpartval; linkptr->minloadpartload = minloadpartload; if (linklist != NULL) /* Add link to the list */ linklist->next = linkptr; linklist = linkptr; gainTablAdd (tablptr, (GainLink *) (linktab + linknbr), linkptr->gain); /* add the link in the gain table */ linknbr ++; partlist[partval].prev = NULL; partlist[partval].gain = 0; } if (linkptr != NULL) linkptr->next = NULL; /* close the end of the list */ } movetab[0] = -1; do { /* As long as there is improvement */ Gnum partval2; Gnum movenbr; /* Number of uneffective moves done */ Gnum savenbr; /* Position of current move */ Gnum diffload; WgraphPartFmLink * restrict linkptr; movenbr = 0; /* No uneffective moves yet */ savenbr = 0; /* No recorded moves yet */ moveflag = 0; /* No moves to date */ diffload = 0; while ((movenbr < paraptr->movenbr) && /* As long as we can find effective vertices */ ((linkptr = wgraphPartFmTablGet (grafptr, hashtab, tablptr, &diffload)) != NULL)) { Gnum edgenum; WgraphPartFmVertex * vexxptr2; /* Pointer to current vertex */ WgraphPartFmVertex * vertlist2; movenbr ++; minload = velosum * (1. - paraptr->deltrat) / (float) (partnbr); maxload = velosum * (1. + paraptr->deltrat) / (float) (partnbr); partval = linkptr->partval; /* Get data from the selected link */ hashnum = linkptr->hashnum; vexxptr2 = hashtab + hashnum; vertnum = vexxptr2->vertnum; vertlist = NULL; /* and a list of vertex */ partlistptr = NULL; /* initialise an empty list of part */ partlistloadptr = NULL; vexxptr2->linked = 1; /* link the vertex */ vexxptr2->partval2 = partval; /* the vertex will move to the part partval */ vexxptr2->prev = vertlist; vertlist = hashtab + hashnum; for (edgenum = grafptr->s.verttax[vertnum]; /* for neighbours vertices */ edgenum < grafptr->s.vendtax[vertnum]; edgenum ++) { WgraphPartFmVertex * vexxptr3; /* Pointer to current vertex */ Gnum vertnum2; Gnum edgenum2; vertnum2 = grafptr->s.edgetax[edgenum]; for (hashnum = (vertnum2 * WGRAPHSEPAFMHASHPRIME) & hashmsk; /* search the vertex in the hash table */ hashtab[hashnum].vertnum != vertnum2 && hashtab[hashnum].vertnum != ~0; hashnum = (hashnum + 1) & hashmsk); vexxptr3 = hashtab + hashnum; if (vexxptr3->vertnum == ~0) { /* if vertex not found */ vexxptr3->vertnum = vertnum2; /* add it in the hash table */ vexxptr3->partval = grafptr->parttax[vertnum2]; vexxptr3->linklist = NULL; hashnbr ++; if (hashnbr >= hashmax) { if (wgraphPartFmResize () != 0) { errorPrint ("wgraphPartFm: out of memory (2)"); return (1); } } } if (vexxptr3->partval == -1) { /* if vertex is in the separator */ if (vexxptr3->linked == ~0) { /* link the vertex */ vexxptr3->linked = 1; vexxptr3->prev = vertlist; vertlist = hashtab + hashnum; vexxptr3->partval2 = -1; /* the vertex will stay in the separator */ } } else if ((vexxptr3->partval != partval)) { /* or if it's not in the part of the selected vertex */ if (vexxptr3->linked == ~0) { /* link the vertex */ vexxptr3->linked = 1; vexxptr3->prev = vertlist; vertlist = hashtab + hashnum; vexxptr3->partval2 = -1; /* the vertex will move to the separator */ } for (edgenum2 = grafptr->s.verttax[vertnum2]; /* for neighbours vertices */ edgenum2 < grafptr->s.vendtax[vertnum2]; edgenum2 ++) { WgraphPartFmVertex * vexxptr4; /* Pointer to current vertex */ Gnum vertnum3; vertnum3 = grafptr->s.edgetax[edgenum2]; for (hashnum = (vertnum3 * WGRAPHSEPAFMHASHPRIME) & hashmsk; /* search the vertex in the hash table */ hashtab[hashnum].vertnum != vertnum3 && hashtab[hashnum].vertnum != ~0; hashnum = (hashnum + 1) & hashmsk); vexxptr4 = hashtab + hashnum; if (vexxptr4->vertnum == ~0) { /* if vertex not found */ vexxptr4->vertnum = vertnum3; /* add it in the hash table */ vexxptr4->partval = grafptr->parttax[vertnum3]; vexxptr4->linklist = NULL; hashnbr ++; if (hashnbr >= hashmax) { if (wgraphPartFmResize () != 0) { errorPrint ("wgraphPartFm: out of memory (2)"); return (1); } } } if (vexxptr4->partval == -1) { /* if vertex in separator */ if (vexxptr4->linked == ~0) { /* link the vertex */ vexxptr4->linked = 1; vexxptr4->prev = vertlist; vexxptr4->partval2 = -1; vertlist = hashtab + hashnum; } } } } } vertlist2 = vertlist; grafptr->fronload -= velobax[vertnum & velomsk]; /* Decrease the frontier load (due to the selected vertex) */ grafptr->fronnbr --; /* Decrease the frontier size (due to the selected vertex) */ while (vertlist != NULL) { /* For each vertex in the list of linked vertices */ Gnum newpart; /* Move vertex from part parval to part partval2 */ Gnum oldpart; Gnum vertnum2; vertnum2 = vertlist->vertnum; oldpart = vertlist->partval; newpart = vertlist->partval2; if (oldpart != newpart) moveflag = 1; if ((newpart == -1) && (oldpart != -1)) { /* If the vertex will move into separator */ grafptr->fronload += velobax[vertnum2 & velomsk]; /* Increase the frontier load */ grafptr->fronnbr ++; /* Increase the frontier size */ } if (oldpart != -1) { grafptr->compload[oldpart] -= velobax[vertnum2 & velomsk]; /* Decrease the load of the selected part */ grafptr->compsize[oldpart] --; /* Decrease the size of the selected part */ partlist[oldpart].loadgain -= velobax[vertnum2 & velomsk]; partlist[oldpart].sizegain --; if (partlist[oldpart].isinloadlist != 1) { partlist[oldpart].loadprev = partlistloadptr; partlistloadptr = partlist + oldpart; partlist[oldpart].isinloadlist = 1; } } if (newpart != -1) { grafptr->compload[newpart] += velobax[vertnum2 & velomsk]; /* increase the load of the selected part */ grafptr->compsize[newpart] ++; /* increase the size of the selected part */ partlist[newpart].loadgain += velobax[vertnum2 & velomsk]; partlist[newpart].sizegain ++; if (partlist[newpart].isinloadlist != 1) { partlist[newpart].loadprev = partlistloadptr; partlistloadptr = partlist + newpart; partlist[newpart].isinloadlist = 1; } } vertlist->partval2 = oldpart; /* exchange the old and the new parts */ vertlist->partval = newpart; if (savenbr >= hashsiz) { if (wgraphPartFmResize () != 0) { errorPrint ("wgraphPartFm: out of memory (2)"); return (1); } } savetab[savenbr].type = WGRAPHSEPAFMSAVEMOVE; /* save the move */ savetab[savenbr].u.movedata.hashnum = vertlist - hashtab; savetab[savenbr].u.movedata.partval = vertlist->partval2; movetab[movenbr] = savenbr; savenbr ++; vertlist = vertlist->prev; } while (vertlist2 != NULL) { /* for each vertex in the same list of linked vertices */ Gnum vertnum2; vertnum2 = vertlist2->vertnum; if (vertlist2->partval2 == -1) { /* If vertex was in separator */ WgraphPartFmLink * restrict linkptr2; for (linkptr2 = vertlist2->linklist; /* For each link of the vertex */ linkptr2 != NULL; linkptr2 = linkptr2->next) { if (linkptr2->gainlink.next != NULL) { grafptr->compload[linkptr2->partval] -= velobax[vertnum2 & velomsk]; /* decrease the load of this part */ grafptr->compsize[linkptr2->partval]--; /* decrease the size of this part */ partlist[linkptr2->partval].loadgain -= velobax[vertnum2 & velomsk]; partlist[linkptr2->partval].sizegain --; if (partlist[linkptr2->partval].isinloadlist != 1) { partlist[linkptr2->partval].loadprev = partlistloadptr; partlistloadptr = partlist + linkptr2->partval; partlist[linkptr2->partval].isinloadlist = 1; } } if (linkptr2->gainlink.next != NULL) { if (linkptr2->gainlink.next != (GainLink *) 1) /* If link is in gain table */ gainTablDel (tablptr, (GainLink *) linkptr2); /* Remove link from table */ if (savenbr >= hashsiz) { if (wgraphPartFmResize () != 0) { /* TODO: Check if table resizing changes linkptr2 ? */ errorPrint ("wgraphPartFm: out of memory (2)"); return (1); } } savetab[savenbr].type = WGRAPHSEPAFMSAVELINKDEL; /* Save link removal from table */ savetab[savenbr].u.linkdata.linknum = linkptr2 - linktab; savetab[savenbr].u.linkdata.gain = linkptr2->gain; movetab[movenbr] = savenbr; savenbr ++; } linkptr2->gainlink.next = NULL; } } if (vertlist2->partval == -1) { /* if vertex move (or stay) in the separator */ Gnum gain; Gnum minloadpartval; Gnum minloadpartload; Gnum secondloadpartval; WgraphPartFmLink * restrict linklist; WgraphPartFmLink * restrict linkptr2; vertnum2 = vertlist2->vertnum; partlistptr = NULL; gain = -1; minloadpartval = -1; secondloadpartval = -1; for (hashnum = (vertnum2 * WGRAPHSEPAFMHASHPRIME) & hashmsk; /* search the vertex in the hash table */ hashtab[hashnum].vertnum != vertnum2; hashnum = (hashnum + 1) & hashmsk); vexxptr = hashtab + hashnum; for (edgenum = grafptr->s.verttax[vertnum2]; /* recompute the gain */ edgenum < grafptr->s.vendtax[vertnum2]; edgenum ++) { WgraphPartFmVertex * vexxptr4; /* Pointer to current vertex */ Gnum vertnum3; vertnum3 = grafptr->s.edgetax[edgenum]; for (hashnum = (vertnum3 * WGRAPHSEPAFMHASHPRIME) & hashmsk; /* search the vertex in the hash table */ hashtab[hashnum].vertnum != vertnum3 && hashtab[hashnum].vertnum != ~0; hashnum = (hashnum + 1) & hashmsk); vexxptr4 = hashtab + hashnum; if (vexxptr4->vertnum == ~0) { /* if vertex not found */ vexxptr4->vertnum = vertnum3; /* add it in the hash table */ vexxptr4->partval = grafptr->parttax[vertnum3]; vexxptr4->linklist = NULL; hashnbr ++; if (hashnbr >= hashmax) { if (wgraphPartFmResize () != 0) { errorPrint ("wgraphPartFm: out of memory (2)"); return (1); } } } if (vexxptr4->partval != -1) { /* if part is not the separator */ if (partlist[vexxptr4->partval].gain == 0) { /* and not yet linked */ partlist[vexxptr4->partval].prev = partlistptr; /* link it */ partlistptr = partlist + vexxptr4->partval; if (minloadpartval == -1 || minloadpartload > grafptr->compload[vexxptr4->partval]) { secondloadpartval = minloadpartval; minloadpartval = vexxptr4->partval; minloadpartload = grafptr->compload[minloadpartval]; } else if (secondloadpartval != vexxptr4->partval) { secondloadpartval = vexxptr4->partval; } } partlist[vexxptr4->partval].gain --; gain ++; } } for (linkptr2 = vexxptr->linklist, linklist = NULL; /* For each vertex link in list */ linkptr2 != NULL; linkptr2 = linkptr2->next) { linklist = linkptr2; partval2 = linkptr2->partval; if (partlist[partval2].gain != 0) { /* If part is linked */ hashtab[linkptr2->hashnum].vertnum = vertnum2; linkptr2->partval = partval2; linkptr2->gain = gain + partlist[partval2].gain; if (partval2 != minloadpartval) linkptr2->minloadpartval = minloadpartval; else linkptr2->minloadpartval = secondloadpartval; linkptr2->minloadpartload = minloadpartload; if (hashtab[linkptr2->hashnum].lockprev == (WgraphPartFmVertex *) ~0) { /* If vertex is not locked */ if (savenbr >= hashsiz) { if (wgraphPartFmResize () != 0) { errorPrint ("wgraphPartFm: out of memory (2)"); return (1); } } savetab[savenbr].type = WGRAPHSEPAFMSAVELINKADD; savetab[savenbr].u.linkdata.linknum = linkptr2 - linktab; savetab[savenbr].u.linkdata.gain = linkptr2->gain; movetab[movenbr] = savenbr; savenbr ++; gainTablAdd(tablptr, (GainLink *) linkptr2, linkptr2->gain); /* add the link in the gain table of the part */ } else { if (savenbr >= hashsiz) { if (wgraphPartFmResize () != 0) { errorPrint ("wgraphPartFm: out of memory (2)"); return (1); } } savetab[savenbr].type = WGRAPHSEPAFMSAVELINKADD; savetab[savenbr].u.linkdata.linknum = linkptr2 - linktab; savetab[savenbr].u.linkdata.gain = linkptr2->gain; movetab[movenbr] = savenbr; savenbr ++; linkptr2->gainlink.next = (GainLink *) 1; } partlist[partval2].gain = 0; grafptr->compload[linkptr2->partval] += velobax[hashtab[linkptr2->hashnum].vertnum & velomsk]; /* increase the load of this part */ grafptr->compsize[linkptr2->partval] ++; /* increase the size of this part */ partlist[linkptr2->partval].loadgain += velobax[hashtab[linkptr2->hashnum].vertnum & velomsk]; partlist[linkptr2->partval].sizegain ++; if (partlist[linkptr2->partval].isinloadlist != 1) { partlist[linkptr2->partval].isinloadlist = 1; partlist[linkptr2->partval].loadprev = partlistloadptr; partlistloadptr = partlist + linkptr2->partval; } } } while (partlistptr != NULL) { /* for each part in the linked list */ partval2 = partlistptr - partlist; if (partlist[partval2].gain != 0) { WgraphPartFmLink * restrict linkptr3; linkptr3 = linktab + linknbr; if (linklist != NULL) /* If vertex has a list of link */ linklist->next = linkptr3; /* Add link to the list */ else vexxptr->linklist = linkptr3; /* Else create the list */ linknbr ++; linkptr3->hashnum = vexxptr - hashtab; hashtab[linkptr3->hashnum].vertnum = vertnum2; linkptr3->partval = partval2; linkptr3->gain = gain + partlist[partval2].gain; if (partval2 != minloadpartval) linkptr3->minloadpartval = minloadpartval; else linkptr3->minloadpartval = secondloadpartval; linkptr3->minloadpartload = minloadpartload; if (vexxptr->lockprev == (WgraphPartFmVertex *) ~0/* || linkptr3->gain == -1 */) gainTablAdd(tablptr, (GainLink *) linkptr3, linkptr3->gain); /* add the link in the gain table of the part */ else linkptr3->gainlink.next = (GainLink *) 1; if (savenbr >= hashsiz) { if (wgraphPartFmResize () != 0) { errorPrint ("wgraphPartFm: out of memory (2)"); return (1); } } savetab[savenbr].type = WGRAPHSEPAFMSAVELINKADD; savetab[savenbr].u.linkdata.linknum = linkptr3 - linktab; savetab[savenbr].u.linkdata.gain = linkptr3->gain; movetab[movenbr] = savenbr; savenbr ++; linklist = linkptr3; grafptr->compload[partval2] += velobax[vertnum2 & velomsk]; partlist[partval2].loadgain += velobax[vertnum2 & velomsk]; grafptr->compsize[partval2] ++; partlist[partval2].sizegain ++; if (partlist[partval2].isinloadlist != 1) { /* link the part in the load list */ partlist[partval2].isinloadlist = 1; partlist[partval2].loadprev = partlistloadptr; partlistloadptr = partlist + partval2; } partlist[partval2].gain = 0; } partlistptr = partlistptr->prev; partlist[partval2].prev = NULL; } if (linklist != NULL) linklist->next = NULL; } vertlist2->linked = ~0; vertlist2 = vertlist2->prev; } while (partlistloadptr != NULL) { /* For each part in the load list */ if (partlistloadptr->loadgain != 0) { if (savenbr >= hashsiz) { if (wgraphPartFmResize () != 0) { errorPrint ("wgraphPartFm: out of memory (2)"); return (1); } } savetab[savenbr].type = WGRAPHSEPAFMSAVELOAD; /* Save load variation */ savetab[savenbr].u.loaddata.partval = partlistloadptr - partlist; savetab[savenbr].u.loaddata.loaddiff = partlistloadptr->loadgain; savetab[savenbr].u.loaddata.sizediff = partlistloadptr->sizegain; movetab[movenbr] = savenbr; savenbr ++; velosum += partlistloadptr->loadgain; } partlistloadptr->loadgain = partlistloadptr->sizegain = partlistloadptr->isinloadlist = 0; partlistloadptr = partlistloadptr->loadprev; } vexxptr2->lockprev = locklist; /* Lock the selected vertex */ locklist = vexxptr2; if (grafptr->fronload < frlobst) { movenbr = savenbr = diffload = 0; moveflag = 1; frlobst = grafptr->fronload; } else if ((grafptr->fronload == frlobst) && (diffload < -1)) { movenbr = savenbr = diffload = 0; moveflag = 1; } else if (linkptr->minloadpartval == -1) { movenbr = savenbr = diffload = 0; } else if ((grafptr->compload[linkptr->partval] < minload) || (grafptr->compload[linkptr->partval] < grafptr->compload[linkptr->minloadpartval])) { movenbr = savenbr = diffload = 0; } } while (locklist != NULL) { /* For each locked vertex */ WgraphPartFmLink * restrict linkptr2; vexxptr = locklist; locklist = locklist->lockprev; /* Unlock it */ vexxptr->lockprev = (WgraphPartFmVertex *) ~0; for (linkptr2 = vexxptr->linklist; linkptr2 != NULL; linkptr2 = linkptr2->next) { if (linkptr2->gainlink.next == (GainLink *) 1) gainTablAdd(tablptr, (GainLink *) linkptr2, linkptr2->gain); /* Add link to part gain table */ } } locklist = NULL; for ( ; movenbr > 0; movenbr --) { /* For each move to undo */ for (savenum = movetab[movenbr]; savenum > movetab[movenbr - 1]; savenum --) { WgraphPartFmLink * restrict linkptr2; switch (savetab[savenum].type) { case WGRAPHSEPAFMSAVEMOVE : if (savetab[savenum].u.movedata.partval == -1) grafptr->fronload += velobax[hashtab[savetab[savenum].u.movedata.hashnum].vertnum & velomsk]; if (hashtab[savetab[savenum].u.movedata.hashnum].partval == -1) grafptr->fronload -= velobax[hashtab[savetab[savenum].u.movedata.hashnum].vertnum & velomsk]; hashtab[savetab[savenum].u.movedata.hashnum].partval = savetab[savenum].u.movedata.partval; break; case WGRAPHSEPAFMSAVELINKDEL : linkptr2 = linktab + savetab[savenum].u.linkdata.linknum; linkptr2->gain = savetab[savenum].u.linkdata.gain; gainTablAdd (tablptr, (GainLink *) linkptr2, linkptr2->gain); /* Add link into part gain table */ break; case WGRAPHSEPAFMSAVELINKADD : linkptr2 = linktab + savetab[savenum].u.linkdata.linknum; if (linkptr2->gainlink.next != (GainLink *) 1) { gainTablDel (tablptr, (GainLink *) linkptr2); /* Remove link from table */ linkptr2->gainlink.next = NULL; } break; case WGRAPHSEPAFMSAVELOAD: grafptr->compload[savetab[savenum].u.loaddata.partval] -= savetab[savenum].u.loaddata.loaddiff; grafptr->compsize[savetab[savenum].u.loaddata.partval] -= savetab[savenum].u.loaddata.sizediff; break; } } } } while ((moveflag != 0) && /* As long as vertices are moved */ (-- passnbr > 0)); /* and we are allowed to loop */ grafptr->fronload = 0; for (vexxptr = hashtab, fronnum = 0; /* Build new frontier */ vexxptr < hashtab + (hashmax << 2); vexxptr ++) { /* from all vertices in table */ Gnum vertnum; vertnum = vexxptr->vertnum; if (vertnum != ~0) { /* If vertex slot is used */ Gnum partval; /* New part of current vertex */ Gnum partold; /* Old part of current vertex */ partval = vexxptr->partval; partold = grafptr->parttax[vertnum]; /* Get old part value from array */ if (partval != partold) /* If vertex part changed */ grafptr->parttax[vertnum] = partval; /* Set new part value */ if (partval == -1) { grafptr->fronload += velobax[vertnum & velomsk]; grafptr->frontab[fronnum ++] = vexxptr->vertnum; } } } grafptr->fronnbr = fronnum; memFree (hashtab); /* Free group leader */ gainTablExit (tablptr); return (0); } /* This routine doubles the size all of the arrays ** involved in handling the hash table and hash ** vertex arrays. ** It returns: ** - 0 : if resizing succeeded. ** - !0 : if out of memory. */ static int wgraphPartFmResize () { errorPrint ("wgraphPartFmResize: not implemented"); return (0); } scotch-6.0.4.dfsg/src/libscotch/hgraph_order_bl.c0000644002563400244210000001234511631447171025131 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hgraph_order_bl.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module resizes block data using **/ /** the block splitting post-processing **/ /** algorithm. **/ /** **/ /** DATES : # Version 3.4 : from : 24 jun 2002 **/ /** to 24 jun 2002 **/ /** # Version 4.0 : from : 26 jun 2002 **/ /** to 17 mar 2005 **/ /** # Version 5.0 : from : 25 jul 2007 **/ /** to : 25 jul 2007 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HGRAPH_ORDER_BL #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "order.h" #include "hgraph.h" #include "hgraph_order_bl.h" #include "hgraph_order_st.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the ordering. ** It returns: ** - 0 : if the ordering could be computed. ** - !0 : on error. */ int hgraphOrderBl ( const Hgraph * restrict const grafptr, Order * restrict const ordeptr, const Gnum ordenum, /*+ Zero-based ordering number +*/ OrderCblk * restrict const cblkptr, /*+ Single column-block +*/ const HgraphOrderBlParam * restrict const paraptr) { Gnum cblknbr; /* Number of old column blocks before splitting */ Gnum cblknum; /* Number of current column block */ if (paraptr->cblkmin <= 0) { errorPrint ("hgraphOrderBl: invalid minimum block size"); return (1); } if (hgraphOrderSt (grafptr, ordeptr, ordenum, cblkptr, paraptr->strat) != 0) /* Perform ordering strategy */ return (1); if (cblkptr->cblktab == NULL) { /* If single column block */ if (cblkptr->vnodnbr < (2 * paraptr->cblkmin)) /* If block cannot be split */ return (0); cblknbr = cblkptr->vnodnbr / paraptr->cblkmin; /* Get new number of blocks */ if ((cblkptr->cblktab = (OrderCblk *) memAlloc (cblknbr * sizeof (OrderCblk))) == NULL) { errorPrint ("hgraphOrderBl: out of memory"); return (1); } ordeptr->treenbr += cblknbr; /* These more number of tree nodes */ ordeptr->cblknbr += cblknbr - 1; /* These more number of column blocks */ cblkptr->cblknbr = cblknbr; for (cblknum = 0; cblknum < cblknbr; cblknum ++) { cblkptr->cblktab[cblknum].typeval = ORDERCBLKOTHR; cblkptr->cblktab[cblknum].vnodnbr = ((cblkptr->vnodnbr + cblknbr - 1) - cblknum) / cblknbr; cblkptr->cblktab[cblknum].cblknbr = 0; cblkptr->cblktab[cblknum].cblktab = NULL; } } else { /* Block already partitioned */ for (cblknum = 0; cblknum < cblkptr->cblknbr; cblknum ++) { if (hgraphOrderBl (grafptr, ordeptr, ordenum, cblkptr->cblktab + cblknum, paraptr) != 0) return (1); } } return (0); } scotch-6.0.4.dfsg/src/libscotch/library_dgraph_redist_f.c0000644002563400244210000000675012056000035026645 0ustar trophimeutilisateurs du domaine/* Copyright 2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_redist_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API for **/ /** the distributed source graph handling **/ /** routines of the libSCOTCH library. **/ /** **/ /** DATES : # Version 6.0 : from : 28 mar 2012 **/ /** to : 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "ptscotch.h" /********************************************/ /* */ /* These routines are the Fortran API for */ /* the distributed graph handling routines. */ /* */ /********************************************/ /* ** */ FORTRAN ( \ SCOTCHFDGRAPHREDIST, scotchfdgraphredist, ( \ SCOTCH_Dgraph * const srcgrafptr, \ const SCOTCH_Num * const partloctab, \ const SCOTCH_Num * const permgsttab, \ const SCOTCH_Num * const vertlocdlt, \ const SCOTCH_Num * const edgelocdlt, \ SCOTCH_Dgraph * const dstgrafptr, \ int * const revaptr), \ (srcgrafptr, partloctab, permgsttab, vertlocdlt, edgelocdlt, dstgrafptr, revaptr)) { *revaptr = SCOTCH_dgraphRedist (srcgrafptr, partloctab, permgsttab, *vertlocdlt, *edgelocdlt, dstgrafptr); } scotch-6.0.4.dfsg/src/libscotch/vmesh_separate_zr.h0000644002563400244210000000520211631447170025527 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vmesh_separate_zr.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declarations **/ /** for the move-all-to-first-subdomain **/ /** mesh node separation method. **/ /** **/ /** DATES : # Version 4.0 : from : 10 sep 2002 **/ /** to 10 sep 2002 **/ /** **/ /************************************************************/ /* ** The function prototypes. */ #ifndef VMESH_SEPARATE_ZR #define static #endif int vmeshSeparateZr (Vmesh * const); #undef static scotch-6.0.4.dfsg/src/libscotch/hmesh_order_cp.h0000644002563400244210000001007211631447171024771 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh_order_cp.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the mesh compression algorithm. **/ /** **/ /** DATES : # Version 4.0 : from : 08 feb 2004 **/ /** to 08 feb 2004 **/ /** # Version 5.1 : from : 04 nov 2010 **/ /** to 04 nov 2010 **/ /** **/ /************************************************************/ /* ** The defines. */ /** Prime number for hashing vertex numbers. **/ #define HMESHORDERCPHASHPRIME 17 /* Prime number */ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct HmeshOrderCpParam_ { double comprat; /*+ Compression ratio threshold +*/ Strat * stratcpr; /*+ Compressed submesh ordering strategy +*/ Strat * stratunc; /*+ Uncompressed submesh ordering strategy +*/ } HmeshOrderCpParam; /*+ This structure holds fine neighbor hashing data. +*/ typedef struct HmeshOrderCpHash_ { Gnum vnodnum; /*+ Origin node vertex (i.e. pass) number +*/ Gnum velmnum; /*+ Adjacent end element vertex number +*/ } HmeshOrderCpHash; /*+ This structure holds coarse neighbor mate data. +*/ typedef struct HgraphOrderCpMate_ { Gnum coarvertend; /*+ Adjacent coarse end vertex number +*/ Gnum finevertend; /*+ Adjacent end vertex number +*/ } HgraphOrderCpMate; /* ** The function prototypes. */ #ifndef HMESH_ORDER_CP #define static #endif int hmeshOrderCp (const Hmesh * const, Order * const, const Gnum, OrderCblk * const, const HmeshOrderCpParam * const); static Gnum hmeshOrderCpTree (const Gnum * const, const Gnum * const, OrderCblk * const, Gnum); #undef static scotch-6.0.4.dfsg/src/libscotch/kdgraph_map_rb_map.h0000644002563400244210000000543611631447170025614 0ustar trophimeutilisateurs du domaine/* Copyright 2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kdgraph_map_rb_map.h **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the Parallel Dual Recursive **/ /** Bipartitioning mapping algorithm. **/ /** **/ /** DATES : # Version 5.1 : from : 24 jun 2008 **/ /** to 24 jun 2008 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /* ** The function prototypes. */ #ifndef KDGRAPH_MAP_RB #define static #endif int kdgraphMapRbMap (Kdgraph * const, Kdmapping * const, const KdgraphMapRbParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/library_dgraph_order_perm_f.c0000644002563400244210000000670312055777646027543 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_order_perm_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the Fortran API for the **/ /** distributed ordering permutation **/ /** building routine of the libSCOTCH **/ /** library. **/ /** **/ /** DATES : # Version 5.0 : from : 18 oct 2007 **/ /** to 18 oct 2007 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "ptscotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the ordering routines. */ /* */ /**************************************/ FORTRAN ( \ SCOTCHFDGRAPHORDERPERM, scotchfdgraphorderperm, ( \ const SCOTCH_Dgraph * const grafptr, \ const SCOTCH_Dordering * const ordeptr, \ SCOTCH_Num * const permloctab, \ int * const revaptr), \ (grafptr, ordeptr, permloctab, revaptr)) { *revaptr = SCOTCH_dgraphOrderPerm (grafptr, ordeptr, permloctab); } scotch-6.0.4.dfsg/src/libscotch/hgraph_order_hx.h0000644002563400244210000000550211631447171025155 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hgraph_order_hx.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the halo graph block Approxi- **/ /** mate (Multiple) Minimum Degree and Fill **/ /** ordering routines. **/ /** **/ /** DATES : # Version 4.0 : from : 24 jan 2004 **/ /** to 24 jan 2004 **/ /** **/ /************************************************************/ /* ** The function prototypes. */ #ifndef HGRAPH_ORDER_HX #define static #endif void hgraphOrderHxFill (const Hgraph * restrict const, Gnum * restrict const, Gnum * restrict const, Gnum * restrict const, Gnum * restrict const, Gnum * restrict const); #undef static scotch-6.0.4.dfsg/src/libscotch/graph_match.c0000644002563400244210000004427612474554132024277 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2009,2011,2012,2015 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : graph_match.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the source graph **/ /** matching functions, generated from the **/ /** generic pattern. **/ /** **/ /** DATES : # Version 6.0 : from : 05 oct 2012 **/ /** to 26 feb 2015 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GRAPH_MATCH #include "module.h" #include "common.h" #include "arch.h" #include "graph.h" #include "graph_coarsen.h" #include "graph_match.h" /* ** The static variables. */ static void (* graphmatchfuncseqtab[]) (GraphCoarsenThread *) = { /* Array of sequential matching routines */ GRAPHMATCHFUNCBLOCK (Seq) }; #ifdef GRAPHMATCHTHREAD static void (* graphmatchfuncthrbegtab[]) (GraphCoarsenThread *) = { /* Array of threaded matching start routines */ GRAPHMATCHFUNCBLOCK (ThrBeg) }; static void (* graphmatchfuncthrmidtab[]) (GraphCoarsenThread *) = { /* Array of threaded matching intermediate routines */ GRAPHMATCHFUNCBLOCK (ThrMid) }; static void (* graphmatchfuncthrendtab[]) (GraphCoarsenThread *) = { /* Array of threaded matching end routines */ GRAPHMATCHFUNCBLOCK (ThrEnd) }; #endif /* GRAPHMATCHTHREAD */ /***************************/ /* */ /* The sequential matching */ /* subroutines. */ /* */ /***************************/ #define GRAPHMATCHSCANP1INPERT /* Perturbation scan for first pass */ #define GRAPHMATCHSCANP2INPERT /* Perturbation scan for second pass */ #define GRAPHMATCHSCANNAME graphMatchSeqNfNvNe #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #define GRAPHMATCHSCANEDLOTAB #define GRAPHMATCHSCANNAME graphMatchSeqNfNvEl #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #define GRAPHMATCHSCANVELOTAB #define GRAPHMATCHSCANNAME graphMatchSeqNfVlEl #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #undef GRAPHMATCHSCANEDLOTAB #define GRAPHMATCHSCANNAME graphMatchSeqNfVlNe #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #undef GRAPHMATCHSCANVELOTAB #define GRAPHMATCHSCANPFIXTAB #define GRAPHMATCHSCANNAME graphMatchSeqFxNvNe #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #define GRAPHMATCHSCANEDLOTAB #define GRAPHMATCHSCANNAME graphMatchSeqFxNvEl #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #define GRAPHMATCHSCANVELOTAB #define GRAPHMATCHSCANNAME graphMatchSeqFxVlEl #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #undef GRAPHMATCHSCANEDLOTAB #define GRAPHMATCHSCANNAME graphMatchSeqFxVlNe #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #undef GRAPHMATCHSCANVELOTAB #undef GRAPHMATCHSCANPFIXTAB #undef GRAPHMATCHSCANP1INPERT #undef GRAPHMATCHSCANP2INPERT /*************************/ /* */ /* The threaded matching */ /* start subroutines. */ /* */ /*************************/ #ifdef GRAPHMATCHTHREAD /* Start subroutines */ #define GRAPHMATCHSCANP1INPERT /* Perturbation scan for first pass */ #define GRAPHMATCHSCANP2INPERT /* Perturbation scan for second pass */ #define GRAPHMATCHSCANP2OUTQUEUE /* Queue storage for second pass */ #define GRAPHMATCHSCANNAME graphMatchThrBegNfNvNe #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #define GRAPHMATCHSCANEDLOTAB #define GRAPHMATCHSCANNAME graphMatchThrBegNfNvEl #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #define GRAPHMATCHSCANVELOTAB #define GRAPHMATCHSCANNAME graphMatchThrBegNfVlEl #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #undef GRAPHMATCHSCANEDLOTAB #define GRAPHMATCHSCANNAME graphMatchThrBegNfVlNe #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #undef GRAPHMATCHSCANVELOTAB #define GRAPHMATCHSCANPFIXTAB #define GRAPHMATCHSCANNAME graphMatchThrBegFxNvNe #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #define GRAPHMATCHSCANEDLOTAB #define GRAPHMATCHSCANNAME graphMatchThrBegFxNvEl #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #define GRAPHMATCHSCANVELOTAB #define GRAPHMATCHSCANNAME graphMatchThrBegFxVlEl #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #undef GRAPHMATCHSCANEDLOTAB #define GRAPHMATCHSCANNAME graphMatchThrBegFxVlNe #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #undef GRAPHMATCHSCANVELOTAB #undef GRAPHMATCHSCANPFIXTAB #undef GRAPHMATCHSCANP1INPERT #undef GRAPHMATCHSCANP2INPERT #undef GRAPHMATCHSCANP2OUTQUEUE /* Intermediate subroutines */ #define GRAPHMATCHSCANP2INQUEUE /* Read queue for second (only) pass */ #define GRAPHMATCHSCANP2OUTQUEUE /* Queue storage for second pass */ #define GRAPHMATCHSCANNAME graphMatchThrMidNfNvNe #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #define GRAPHMATCHSCANEDLOTAB #define GRAPHMATCHSCANNAME graphMatchThrMidNfNvEl #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #define GRAPHMATCHSCANVELOTAB #define GRAPHMATCHSCANNAME graphMatchThrMidNfVlEl #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #undef GRAPHMATCHSCANEDLOTAB #define GRAPHMATCHSCANNAME graphMatchThrMidNfVlNe #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #undef GRAPHMATCHSCANVELOTAB #define GRAPHMATCHSCANPFIXTAB #define GRAPHMATCHSCANNAME graphMatchThrMidFxNvNe #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #define GRAPHMATCHSCANEDLOTAB #define GRAPHMATCHSCANNAME graphMatchThrMidFxNvEl #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #define GRAPHMATCHSCANVELOTAB #define GRAPHMATCHSCANNAME graphMatchThrMidFxVlEl #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #undef GRAPHMATCHSCANEDLOTAB #define GRAPHMATCHSCANNAME graphMatchThrMidFxVlNe #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #undef GRAPHMATCHSCANVELOTAB #undef GRAPHMATCHSCANPFIXTAB #undef GRAPHMATCHSCANP2INQUEUE #undef GRAPHMATCHSCANP2OUTQUEUE /* End subroutines */ #define GRAPHMATCHSCANP2INQUEUE /* Read queue for second (only) pass */ #define GRAPHMATCHSCANNAME graphMatchThrEndNfNvNe #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #define GRAPHMATCHSCANEDLOTAB #define GRAPHMATCHSCANNAME graphMatchThrEndNfNvEl #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #define GRAPHMATCHSCANVELOTAB #define GRAPHMATCHSCANNAME graphMatchThrEndNfVlEl #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #undef GRAPHMATCHSCANEDLOTAB #define GRAPHMATCHSCANNAME graphMatchThrEndNfVlNe #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #undef GRAPHMATCHSCANVELOTAB #define GRAPHMATCHSCANPFIXTAB #define GRAPHMATCHSCANNAME graphMatchThrEndFxNvNe #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #define GRAPHMATCHSCANEDLOTAB #define GRAPHMATCHSCANNAME graphMatchThrEndFxNvEl #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #define GRAPHMATCHSCANVELOTAB #define GRAPHMATCHSCANNAME graphMatchThrEndFxVlEl #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #undef GRAPHMATCHSCANEDLOTAB #define GRAPHMATCHSCANNAME graphMatchThrEndFxVlNe #include "graph_match_scan.c" #undef GRAPHMATCHSCANNAME #undef GRAPHMATCHSCANVELOTAB #undef GRAPHMATCHSCANPFIXTAB #undef GRAPHMATCHSCANP2INQUEUE #endif /* GRAPHMATCHTHREAD */ /*************************/ /* */ /* The matching routine. */ /* */ /*************************/ /* This routine performs the sequential ** initialization of the global mating ** data structures, so as to indicate ** that no mating will be performed. ** It returns: ** - 0 : in all cases. */ void graphMatchNone ( GraphCoarsenData * restrict coarptr) { #ifdef SCOTCH_PTHREAD coarptr->finelocktax = NULL; coarptr->finequeutab = NULL; coarptr->fendptr = (void (*) (void *)) NULL; coarptr->fmidptr = (void (*) (void *)) NULL; #endif /* SCOTCH_PTHREAD */ coarptr->fbegptr = (void (*) (void *)) NULL; } /* This routine performs the sequential ** initialization of the global mating ** data structures, before the threads ** are launched. ** It returns: ** - 0 : if initialization could be performed. ** - 1 : on error. */ int graphMatchInit ( GraphCoarsenData * restrict coarptr) { int flagval; const Graph * restrict const finegrafptr = coarptr->finegrafptr; #if ((defined GRAPHMATCHTHREAD) && ! (defined SCOTCH_DETERMINISTIC)) const Gnum finevertnbr = finegrafptr->vertnbr; const Gnum baseval = finegrafptr->baseval; const int thrdnbr = coarptr->thrddat.thrdnbr; #endif /* ((defined GRAPHMATCHTHREAD) && ! (defined SCOTCH_DETERMINISTIC)) */ flagval = (finegrafptr->edlotax != NULL) ? 1 : 0; if (finegrafptr->velotax != NULL) flagval |= 2; if ((coarptr->finevfixnbr > 0) || (coarptr->fineparotax != NULL)) flagval |= 4; #if ((defined GRAPHMATCHTHREAD) && ! (defined SCOTCH_DETERMINISTIC)) if (thrdnbr > 1) { if (memAllocGroup ((void **) (void *) &coarptr->finequeutab, (size_t) (finevertnbr * sizeof (Gnum)), &coarptr->finelocktax, (size_t) (finevertnbr * sizeof (int)), NULL) == NULL) { errorPrint ("graphMatchInit: out of memory"); return (1); } coarptr->finelocktax -= baseval; coarptr->fbegptr = (void (*) (void *)) graphmatchfuncthrbegtab[flagval]; coarptr->fmidptr = (void (*) (void *)) graphmatchfuncthrmidtab[flagval]; coarptr->fendptr = (void (*) (void *)) graphmatchfuncthrendtab[flagval]; } else { coarptr->finequeutab = NULL; coarptr->finelocktax = NULL; /* If deterministic behavior wanted, no threaded mating */ coarptr->fbegptr = (void (*) (void *)) graphmatchfuncseqtab[flagval]; #ifdef SCOTCH_DEBUG_GRAPH2 coarptr->fmidptr = (void (*) (void *)) NULL; coarptr->fendptr = (void (*) (void *)) NULL; #endif /* SCOTCH_DEBUG_GRAPH2 */ } #else /* ((defined GRAPHMATCHTHREAD) && ! (defined SCOTCH_DETERMINISTIC)) */ coarptr->fbegptr = (void (*) (void *)) graphmatchfuncseqtab[flagval]; #endif /* ((defined GRAPHMATCHTHREAD) && ! (defined SCOTCH_DETERMINISTIC)) */ return (0); } /* This routine merges the results of two mating ** threads and re-launches a mating operations ** if necessary. */ #ifdef GRAPHMATCHTHREAD static void graphMatchReduce ( GraphCoarsenThread * restrict const tlocptr, /* Pointer to local thread */ void * restrict const vlocptr, /* Pointer to local value */ void * restrict const vremptr) /* Pointer to remote value */ { GraphCoarsenData * restrict const coarptr = (GraphCoarsenData *) (tlocptr->thrddat.grouptr); GraphCoarsenThread * restrict const tremptr = (GraphCoarsenThread *) vremptr; const int thrdnbr = coarptr->thrddat.thrdnbr; const int thrdnum = tlocptr->thrddat.thrdnum; Gnum qremnbr; qremnbr = tremptr->finequeunnd - tremptr->finequeubas; /* Number of enqueued fine vertices in second thread */ memMov (coarptr->finequeutab + tlocptr->finequeunnd, /* Merge queues */ coarptr->finequeutab + tremptr->finequeubas, qremnbr * sizeof (Gnum)); tlocptr->finequeunnd += qremnbr; tlocptr->coarvertnbr += tremptr->coarvertnbr; if ((thrdnum == 0) && (((tremptr - tlocptr) << 1) >= thrdnbr)) /* If last join */ coarptr->fendptr (tlocptr); /* Call end match routine */ else coarptr->fmidptr (tlocptr); /* Call intermediate match routine */ } #endif /* GRAPHMATCHTHREAD */ /* This routine matches the vertices of the given ** graph, according to various constraints. The ** matching can be either single-threaded or ** multi-threaded. ** It returns: ** - 0 : if matching could be performed. ** - 1 : on error. */ void graphMatch ( GraphCoarsenThread * restrict thrdptr) /*+ Pointer to incomplete match data array +*/ { Gnum finevertsiz; #ifdef SCOTCH_DEBUG_GRAPH2 Gnum finevertnum; #endif /* SCOTCH_DEBUG_GRAPH2 */ GraphCoarsenData * restrict const coarptr = (GraphCoarsenData *) (thrdptr->thrddat.grouptr); const Graph * restrict const finegrafptr = coarptr->finegrafptr; const Gnum finevertbas = thrdptr->finevertbas; /* Get fine vertex range */ const Gnum finevertnnd = thrdptr->finevertnnd; Gnum * restrict const finematetax = coarptr->finematetax; const Gnum baseval = finegrafptr->baseval; if (coarptr->fbegptr == NULL) /* If user-provided mating, nothing to do */ return; thrdptr->finequeubas = finevertbas; /* Assume matching range is fine vertex processing range */ thrdptr->finequeunnd = finevertnnd; thrdptr->coarvertnbr = 0; /* No coarse vertices created yet */ finevertsiz = finevertnnd - finevertbas; /* Compute fine vertex range */ memSet (finematetax + finevertbas, ~0, finevertsiz * sizeof (Gnum)); #if ((defined GRAPHMATCHTHREAD) && ! (defined SCOTCH_DETERMINISTIC)) if (coarptr->thrddat.thrdnbr > 1) { memSet (coarptr->finelocktax + finevertbas, 0, finevertsiz * sizeof (int)); /* Initialize local part of lock array for concurrent accesses */ threadBarrier (thrdptr); /* finematetax and finelocktax must have been globally initialized before we can go on */ coarptr->fbegptr (thrdptr); /* Perform bulk on local part */ threadReduce (thrdptr, thrdptr, (ThreadReduceFunc) graphMatchReduce, 0); /* Reduce work on remaining vertices */ if (thrdptr->thrddat.thrdnum == 0) { coarptr->coarvertnbr = thrdptr->coarvertnbr; /* Global number of coarse vertices is reduced number */ memFree (coarptr->finequeutab); /* Free group leader of matching data */ } threadBarrier (thrdptr); /* coarptr->coarvertnbr must be known to all */ } else #else /* (defined GRAPHMATCHTHREAD) && ! (defined SCOTCH_DETERMINISTIC) */ #ifdef GRAPHCOARSENTHREAD /* If matching was called from a threaded environment */ if (coarptr->thrddat.thrdnbr > 1) { threadBarrier (thrdptr); /* finematetax must have been fully initialized before we go on */ thrdptr->finequeubas = finegrafptr->baseval; /* Thread 0 will handle all of fine graph vertices */ thrdptr->finequeunnd = finegrafptr->vertnnd; if (thrdptr->thrddat.thrdnum == 0) { /* Only thread 0 will do the job sequentially */ coarptr->fbegptr (thrdptr); /* Call sequential mating routine */ coarptr->coarvertnbr = thrdptr->coarvertnbr; /* Global number of coarse vertices is that computed by (sequential) thread 0 */ } threadBarrier (thrdptr); /* coarptr->coarvertnbr must be known to all */ } else #endif /* GRAPHCOARSENTHREAD */ #endif /* (defined GRAPHMATCHTHREAD) && ! (defined SCOTCH_DETERMINISTIC) */ { coarptr->fbegptr (thrdptr); /* Call sequential mating routine */ coarptr->coarvertnbr = thrdptr->coarvertnbr; /* Global number of coarse vertices is that computed by (sequential) thread 0 */ } #ifdef SCOTCH_DEBUG_GRAPH2 for (finevertnum = finevertbas; finevertnum < finevertnnd; finevertnum ++) { if (finematetax[finevertnum] == ~0) { /* If matching not aborted, this should not happen */ errorPrint ("graphMatch: internal error"); coarptr->coarvertnbr = coarptr->coarvertmax; } } #endif /* SCOTCH_DEBUG_GRAPH2 */ } scotch-6.0.4.dfsg/src/libscotch/common_integer.c0000644002563400244210000004141212416742700025010 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : common_integer.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module handles the generic integer **/ /** type. **/ /** **/ /** DATES : # Version 0.0 : from : 07 sep 1998 **/ /** to 22 sep 1998 **/ /** # Version 0.1 : from : 07 jan 2002 **/ /** to 17 jan 2003 **/ /** # Version 1.0 : from : 23 aug 2005 **/ /** to : 19 dec 2006 **/ /** # Version 2.0 : from : 26 feb 2008 **/ /** to : 26 feb 2008 **/ /** # Version 5.1 : from : 09 nov 2008 **/ /** to : 16 jul 2010 **/ /** # Version 6.0 : from : 03 mar 2011 **/ /** to 13 oct 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define COMMON_INTEGER #ifndef COMMON_NOMODULE #include "module.h" #endif /* COMMON_NOMODULE */ #include "common.h" /********************************/ /* */ /* Basic routines for fast I/O. */ /* */ /********************************/ /* Fast read for INT values. ** It returns: ** - 1 : on success. ** - 0 : on error. */ int intLoad ( FILE * const stream, /*+ Stream to read from +*/ INT * const valptr) /*+ Area where to put value +*/ { int sign; /* Sign flag */ int car; /* Character read */ INT val; /* Value */ sign = 0; /* Assume positive constant */ for ( ; ; ) { /* Consume whitespaces and sign */ car = getc (stream); if (isspace (car)) continue; if ((car >= '0') && (car <= '9')) break; if (car == '-') { sign = 1; car = getc (stream); break; } if (car == '+') { car = getc (stream); break; } return (0); } if ((car < '0') || (car > '9')) /* If first char is non numeric */ return (0); /* Then it is an error */ val = car - '0'; /* Get first digit */ for ( ; ; ) { car = getc (stream); if ((car < '0') || (car > '9')) { ungetc (car, stream); break; } val = val * 10 + (car - '0'); /* Accumulate digits */ } *valptr = (sign != 0) ? (- val) : val; /* Set result */ return (1); } /* Write routine for INT values. ** It returns: ** - 1 : on success. ** - 0 : on error. */ int intSave ( FILE * const stream, /*+ Stream to write to +*/ const INT val) /*+ Value to write +*/ { return ((fprintf (stream, INTSTRING, (INT) val) == EOF) ? 0 : 1); } /**********************************/ /* */ /* Permutation building routines. */ /* */ /**********************************/ /* This routine fills an array with ** consecutive INT values, in ** ascending order. ** It returns: ** - VOID : in all cases. */ void intAscn ( INT * const permtab, /*+ Permutation array to build +*/ const INT permnbr, /*+ Number of entries in array +*/ const INT baseval) /*+ Base value +*/ { INT * permtax; INT permnum; INT permnnd; for (permnum = baseval, permnnd = baseval + permnbr, permtax = permtab - baseval; permnum < permnnd; permnum ++) permtax[permnum] = permnum; } /* This routine computes a random permutation ** of an array of INT values. ** It returns: ** - VOID : in all cases. */ void intPerm ( INT * const permtab, /*+ Permutation array to build +*/ const INT permnbr) /*+ Number of entries in array +*/ { INT * permptr; INT permrmn; for (permptr = permtab, permrmn = permnbr; /* Perform random permutation */ permrmn > 0; permptr ++, permrmn --) { INT permnum; INT permtmp; permnum = intRandVal (permrmn); /* Select index to swap */ permtmp = permptr[0]; /* Swap it with current index */ permptr[0] = permptr[permnum]; permptr[permnum] = permtmp; } } /*************************************/ /* */ /* Pseudo-random generator routines. */ /* */ /*************************************/ static volatile int intrandflag = 0; /*+ Flag set if generator already initialized +*/ static UINT32 intrandproc = 0; /*+ Process number +*/ static UINT32 intrandseed = 1; /*+ Pseudo-random seed +*/ /* This routine sets the process number that is ** used to generate a different seed across all ** processes. In order for this number to be ** taken into account, it must be followed by ** a subsequent call to intRandInit(), ** intRandReset() or intRandSeed(). ** It returns: ** - VOID : in all cases. */ void intRandProc ( int procnum) { intrandproc = (UINT32) procnum; /* Set process number */ } /* This routine initializes the seed used by Scotch ** with the provided value. Hence, all subsequent ** calls to intRandInit() will start from this seed. ** It returns: ** - VOID : in all cases. */ #ifndef COMMON_RANDOM_SYSTEM static IntRandState intrandstat; /*+ Pseudo-random state value +*/ static void intRandSeed3 ( IntRandState * restrict randptr, UINT32 randval) { UINT32 randtmp; UINT32 i; UINT32 * restrict const randtab = randptr->randtab; /* Fast access */ randtmp = (UINT32) randval; randtab[0] = randtmp; /* Reset array contents */ for (i = 1; i < 623; i ++) { randtmp = 0x6c078965 * randtmp ^ (randtmp >> 30) + i; randtab[i] = randtmp; } randptr->randnum = 0; /* Reset array index */ } #endif /* COMMON_RANDOM_SYSTEM */ static void intRandSeed2 ( UINT32 seedval) { UINT32 randtmp; randtmp = seedval * (intrandproc + 1); /* Account for process index */ #ifdef COMMON_RANDOM_SYSTEM #ifdef COMMON_RANDOM_RAND srand ((unsigned int) randtmp); #else /* COMMON_RANDOM_RAND */ srandom ((unsigned int) randtmp); #endif /* COMMON_RANDOM_RAND */ #else /* COMMON_RANDOM_SYSTEM */ intRandSeed3 (&intrandstat, randtmp); /* Initialize state vector from random seed */ #endif /* COMMON_RANDOM_SYSTEM */ } void intRandSeed ( INT seedval) { intrandflag = 1; /* Generator has been initialized */ intrandseed = (UINT32) seedval; /* Save new seed */ intRandSeed2 (intrandseed); /* Initialize pseudo-random seed */ } /* This routine initializes the pseudo-random ** generator if necessary. In order for multi-sequential ** programs to have exactly the same behavior on any ** process, the random seed does not depend on process ** rank. This routine is not really thread-safe, so it ** should not be called concurrently when it has never ** been initialized before. ** It returns: ** - VOID : in all cases. */ void intRandInit (void) { if (intrandflag == 0) { /* Non thread-safe check */ intrandflag = 1; /* Generator has been initialized */ #if ! ((defined COMMON_DEBUG) || (defined COMMON_RANDOM_FIXED_SEED) || (defined SCOTCH_DETERMINISTIC)) intrandseed = (UINT32) time (NULL); /* Set random seed if needed */ #endif /* ((defined COMMON_DEBUG) || (defined COMMON_RANDOM_FIXED_SEED) || (defined SCOTCH_DETERMINISTIC)) */ intRandSeed2 (intrandseed); /* Initialize state vector from seed */ } } /* This routine reinitializes the pseudo-random ** generator to its initial value. This routine ** is not thread-safe. ** It returns: ** - VOID : in all cases. */ void intRandReset (void) { if (intrandflag == 0) /* Keep seed computed during first initialization */ intRandInit (); intRandSeed2 (intrandseed); } /* This routine computes a new pseudo-random ** 32bit value from the state that is passed ** to it. ** For speed and reproducibility reasons, ** this routine is not thread-safe. Providing ** a thread-safe routine would mean determinism ** could not be achieved in caller routines. ** It is the responsibility of application ** routines to call intRandVal() in a way that ** avoids concurrent execution and potentially ** enforces reproducibility. ** It returns: ** - x : pseudo-random value. */ #ifndef COMMON_RANDOM_SYSTEM static UINT32 intRandVal2 ( IntRandState * restrict randptr) { int randnum; UINT32 randval; UINT32 * restrict const randtab = randptr->randtab; /* Fast access */ #ifdef COMMON_DEBUG if (intrandflag == 0) { errorPrint ("intRandVal2: random generator not initialized"); return (~0); } #endif /* COMMON_DEBUG */ randnum = randptr->randnum; if (randnum == 0) { int i; for (i = 0; i < 624; i ++) { UINT32 randtmp; randtmp = (randtab[i] & 0x80000000) + (randtab[(i + 1) % 624] & 0x7FFFFFFF); randtmp = randtab[(i + 397) % 624] ^ (randtmp >> 1); if ((randtmp & 1) != 0) randtmp ^= 0x9908B0DF; randtab[i] = randtmp; } } randval = randtab[randnum]; randval ^= (randval >> 11); randval ^= (randval >> 7) & 0x9D2C5680; randval ^= (randval >> 15) & 0xEFC60000; randval ^= (randval >> 18); randptr->randnum = (randnum + 1) % 624; return (randval); } #endif /* COMMON_RANDOM_SYSTEM */ /* This routine returns a pseudo-random integer ** value in the range [0..randmax[. This routine ** is not thread-safe as it uses a global state ** variable. ** It returns: ** - x : pseudo-random value. */ #ifndef COMMON_RANDOM_SYSTEM INT intRandVal ( INT randmax) { return (((UINT) intRandVal2 (&intrandstat)) % randmax); } #endif /* COMMON_RANDOM_SYSTEM */ /*********************/ /* */ /* Sorting routines. */ /* */ /*********************/ /* This routine sorts an array of ** INT values in ascending order ** by their first value, used as key. ** It returns: ** - VOID : in all cases. */ #define INTSORTNAME intSort1asc1 #define INTSORTSIZE (sizeof (INT)) #define INTSORTSWAP(p,q) do { INT t; t = *((INT *) (p)); *((INT *) (p)) = *((INT *) (q)); *((INT *) (q)) = t; } while (0) #define INTSORTCMP(p,q) (*((INT *) (p)) < *((INT *) (q))) #include "common_sort.c" #undef INTSORTNAME #undef INTSORTSIZE #undef INTSORTSWAP #undef INTSORTCMP /* This routine sorts an array of pairs of ** INT values in ascending order by their ** first value, used as key. ** It returns: ** - VOID : in all cases. */ #define INTSORTNAME intSort2asc1 #define INTSORTSIZE (2 * sizeof (INT)) #define INTSORTSWAP(p,q) do { INT t, u; t = *((INT *) (p)); u = *((INT *) (p) + 1); *((INT *) (p)) = *((INT *) (q)); *((INT *) (p) + 1) = *((INT *) (q) + 1); *((INT *) (q)) = t; *((INT *) (q) + 1) = u; } while (0) #define INTSORTCMP(p,q) (*((INT *) (p)) < *((INT *) (q))) #include "common_sort.c" #undef INTSORTNAME #undef INTSORTSIZE #undef INTSORTSWAP #undef INTSORTCMP /* This routine sorts an array of pairs of ** INT values in ascending order by both ** of their values, used as primary and ** secondary keys. ** It returns: ** - VOID : in all cases. */ #define INTSORTNAME intSort2asc2 #define INTSORTSIZE (2 * sizeof (INT)) #define INTSORTSWAP(p,q) do { INT t, u; t = *((INT *) (p)); u = *((INT *) (p) + 1); *((INT *) (p)) = *((INT *) (q)); *((INT *) (p) + 1) = *((INT *) (q) + 1); *((INT *) (q)) = t; *((INT *) (q) + 1) = u; } while (0) #define INTSORTCMP(p,q) ((*((INT *) (p)) < *((INT *) (q))) || ((*((INT *) (p)) == *((INT *) (q))) && (*((INT *) (p) + 1) < *((INT *) (q) + 1)))) #include "common_sort.c" #undef INTSORTNAME #undef INTSORTSIZE #undef INTSORTSWAP #undef INTSORTCMP /* This routine sorts an array of 3-uples of ** INT values in ascending order by their ** first value, used as key. ** It returns: ** - VOID : in all cases. */ #define INTSORTNAME intSort3asc1 #define INTSORTSIZE (3 * sizeof (INT)) #define INTSORTSWAP(p,q) do { INT t, u, v; t = *((INT *) (p)); u = *((INT *) (p) + 1); v = *((INT *) (p) + 2); *((INT *) (p)) = *((INT *) (q)); *((INT *) (p) + 1) = *((INT *) (q) + 1); *((INT *) (p) + 2) = *((INT *) (q) + 2); *((INT *) (q)) = t; *((INT *) (q) + 1) = u; *((INT *) (q) + 2) = v; } while (0) #define INTSORTCMP(p,q) (*((INT *) (p)) < *((INT *) (q))) #include "common_sort.c" #undef INTSORTNAME #undef INTSORTSIZE #undef INTSORTSWAP #undef INTSORTCMP /* This routine sorts an array of 3-uples of ** INT values in ascending order by their ** first and second values, used as primary ** and secondary keys. ** It returns: ** - VOID : in all cases. */ #define INTSORTNAME intSort3asc2 #define INTSORTSIZE (3 * sizeof (INT)) #define INTSORTSWAP(p,q) do { INT t, u, v; t = *((INT *) (p)); u = *((INT *) (p) + 1); v = *((INT *) (p) + 2); *((INT *) (p)) = *((INT *) (q)); *((INT *) (p) + 1) = *((INT *) (q) + 1); *((INT *) (p) + 2) = *((INT *) (q) + 2); *((INT *) (q)) = t; *((INT *) (q) + 1) = u; *((INT *) (q) + 2) = v; } while (0) #define INTSORTCMP(p,q) ((*((INT *) (p)) < *((INT *) (q))) || ((*((INT *) (p)) == *((INT *) (q))) && (*((INT *) (p) + 1) < *((INT *) (q) + 1)))) #include "common_sort.c" #undef INTSORTNAME #undef INTSORTSIZE #undef INTSORTSWAP #undef INTSORTCMP /* This routine computes the greatest common ** divisor of two non-negative integers u and v. ** It returns: ** - x : the GCD of u and v. */ INT intGcd ( INT u, INT v) { INT t; if (v < u) { /* u should always be the biggest */ t = u; u = v; v = t; } while (v != 0) { t = v; v = u % v; u = t; } return (u); } scotch-6.0.4.dfsg/src/libscotch/bgraph_bipart_gg.h0000644002563400244210000001636312211313553025271 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : bgraph_bipart_gg.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Luca SCARANO (v3.1) **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module contains the function **/ /** declarations for the greedy graph **/ /** growing bipartitioning method. **/ /** **/ /** DATES : # Version 3.1 : from : 07 jan 1996 **/ /** to 29 apr 1996 **/ /** # Version 3.2 : from : 20 sep 1996 **/ /** to 13 sep 1998 **/ /** # Version 3.3 : from : 01 oct 1998 **/ /** to 01 oct 1998 **/ /** # Version 4.0 : from : 09 jan 2004 **/ /** to 09 jan 2004 **/ /** # Version 6.0 : from : 23 fev 2011 **/ /** to 09 nov 2011 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /** Method parameters. **/ typedef struct BgraphBipartGgParam_ { INT passnbr; /*+ Number of passes to do +*/ } BgraphBipartGgParam; #ifdef BGRAPH_BIPART_GG /* Private part of the module */ /*+ The complementary vertex structure. For trick reasons, the gain table data structure must be the first field of the structure. +*/ #ifdef SCOTCH_TABLE_GAIN typedef GainTabl * BgraphBipartGgTabl; typedef GainLink BgraphBipartGgLink; #else /* SCOTCH_TABLE_GAIN */ typedef FiboTree BgraphBipartGgTabl; typedef FiboNode BgraphBipartGgLink; #endif /* SCOTCH_TABLE_GAIN */ typedef struct BgraphBipartGgVertex_ { BgraphBipartGgLink gainlink; /*+ Gain link: FIRST +*/ Gnum commgain0; /*+ Gain if vertex and neighbors in part 0 +*/ Gnum commgain; /*+ Gain value +*/ } BgraphBipartGgVertex; #endif /* BGRAPH_BIPART_GG */ /* ** The function prototypes. */ #ifndef BGRAPH_BIPART_GG #define static #endif int bgraphBipartGg (Bgraph * restrict const, const BgraphBipartGgParam * const); #undef static /* ** The macro definitions. */ #ifdef SCOTCH_TABLE_GAIN /*+ Gain table subbits. +*/ #define BGRAPHBIPARTGGGAINTABLSUBBITS 1 /** Gain table vertex status. **/ #define BGRAPHBIPARTGGSTATEFREE ((GainLink *) 0) /*+ Vertex in initial state (TRICK: must be 0) +*/ #define BGRAPHBIPARTGGSTATEUSED ((GainLink *) 1) /*+ Swapped vertex +*/ #define BGRAPHBIPARTGGSTATELINK ((GainLink *) 2) /*+ Currently in gain table if higher +*/ /*+ Service routines. +*/ #define bgraphBipartGgTablInit(t) (((*(t)) = gainTablInit (GAIN_LINMAX, BGRAPHBIPARTGGGAINTABLSUBBITS)) == NULL) #define bgraphBipartGgTablFree(t) gainTablFree (*(t)) #define bgraphBipartGgTablExit(t) do { \ if (*(t) != NULL) \ gainTablExit (*(t)); \ } while (0) #define bgraphBipartGgTablAdd(t,v) gainTablAdd ((*(t)), &(v)->gainlink, (v)->commgain) #define bgraphBipartGgTablDel(t,v) gainTablDel ((*(t)), &(v)->gainlink) #define bgraphBipartGgTablFrst(t) gainTablFrst (*(t)) #define bgraphBipartGgIsFree(v) ((v)->gainlink.next == BGRAPHBIPARTGGSTATEFREE) #define bgraphBipartGgIsTabl(v) ((v)->gainlink.next >= BGRAPHBIPARTGGSTATELINK) #define bgraphBipartGgIsUsed(v) ((v)->gainlink.next == BGRAPHBIPARTGGSTATEUSED) #define bgraphBipartGgSetFree(v) ((v)->gainlink.next = BGRAPHBIPARTGGSTATEFREE) #define bgraphBipartGgSetUsed(v) ((v)->gainlink.next = BGRAPHBIPARTGGSTATEUSED) #define bgraphBipartGgNext(v) ((v)->gainlink.next) #else /* SCOTCH_TABLE_GAIN */ /*+ Gain table vertex status. +*/ #define BGRAPHBIPARTGGSTATEFREE ((FiboNode *) 0) /*+ Vertex in initial state (TRICK: must be 0) +*/ #define BGRAPHBIPARTGGSTATEUSED ((FiboNode *) 1) /*+ Swapped vertex +*/ #define BGRAPHBIPARTGGSTATELINK ((FiboNode *) 2) /*+ Currently in gain table if higher +*/ /*+ Service routines. +*/ #define bgraphBipartGgTablInit(t) (fiboTreeInit ((t), bgraphBipartGgCmpFunc)) #define bgraphBipartGgTablFree(t) fiboTreeFree (t) #define bgraphBipartGgTablExit(t) fiboTreeExit (t) #define bgraphBipartGgTablAdd(t,v) fiboTreeAdd ((t), &(v)->gainlink) #define bgraphBipartGgTablDel(t,v) fiboTreeDel ((t), &(v)->gainlink) #define bgraphBipartGgTablFrst(t) fiboTreeMin ((t)) #define bgraphBipartGgIsFree(v) ((v)->gainlink.linkdat.nextptr == BGRAPHBIPARTGGSTATEFREE) #define bgraphBipartGgIsTabl(v) ((v)->gainlink.linkdat.nextptr >= BGRAPHBIPARTGGSTATELINK) #define bgraphBipartGgIsUsed(v) ((v)->gainlink.linkdat.nextptr == BGRAPHBIPARTGGSTATEUSED) #define bgraphBipartGgSetFree(v) ((v)->gainlink.linkdat.nextptr = BGRAPHBIPARTGGSTATEFREE) #define bgraphBipartGgSetUsed(v) ((v)->gainlink.linkdat.nextptr = BGRAPHBIPARTGGSTATEUSED) #define bgraphBipartGgNext(v) ((v)->gainlink.linkdat.nextptr) #endif /* SCOTCH_TABLE_GAIN */ scotch-6.0.4.dfsg/src/libscotch/hmesh.c0000644002563400244210000001067511631447171023120 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module handles the halo source **/ /** mesh functions. **/ /** **/ /** DATES : # Version 4.0 : from : 12 sep 2002 **/ /** to 10 feb 2003 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HMESH #include "module.h" #include "common.h" #include "graph.h" #include "mesh.h" #include "hmesh.h" /****************************************/ /* */ /* These routines handle source meshes. */ /* */ /****************************************/ /* This routine frees a source halo mesh structure. ** It returns: ** - VOID : in all cases. */ void hmeshExit ( Hmesh * const meshptr) { if ((meshptr->vehdtax != NULL) && /* Exit halo mesh data */ (meshptr->vehdtax != (meshptr->m.vendtax + (meshptr->m.baseval - meshptr->m.velmbas))) && ((meshptr->m.flagval & MESHVERTGROUP) == 0)) memFree (meshptr->vehdtax + meshptr->m.velmbas); meshExit (&meshptr->m); /* Exit mesh data */ #ifdef SCOTCH_DEBUG_HMESH2 memSet (meshptr, ~0, sizeof (Hmesh)); /* Purge halo mesh fields */ #endif /* SCOTCH_DEBUG_HMESH2 */ } /* This routine sets the base of the given ** halo mesh to the given base value, and ** returns the old base value. ** It returns: ** - old base value : in all cases. */ Gnum hmeshBase ( Hmesh * const meshptr, const Gnum baseval) { Gnum baseold; /* Old base value */ Gnum baseadj; /* Base adjustment */ Gnum velmnum; if (meshptr->m.baseval == baseval) /* If nothing to do */ return (baseval); baseold = meshptr->m.baseval; /* Record old base value */ baseadj = baseval - baseold; /* Compute adjustment */ meshBase (&meshptr->m, baseval); /* Change base of mesh */ for (velmnum = meshptr->m.velmbas; velmnum < meshptr->m.velmnnd; velmnum ++) meshptr->vehdtax[velmnum] += baseadj; /* Change base of array */ meshptr->vnohnnd += baseadj; meshptr->vehdtax -= baseadj; return (baseold); /* Return old base value */ } scotch-6.0.4.dfsg/src/libscotch/library_graph_part_ovl_f.c0000644002563400244210000001156411631447171027052 0ustar trophimeutilisateurs du domaine/* Copyright 2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_part_ovl_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the Fortran API for the **/ /** graph partitioning routines with **/ /** overlap of the libSCOTCH library. **/ /** **/ /** DATES : # Version 6.0 : from : 29 may 2010 **/ /** to 17 oct 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /**************************************/ /* */ /* These routines are the Fortran API */ /* for the partitioning routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ SCOTCHFGRAPHPARTOVL, scotchfgraphpartovl, ( \ SCOTCH_Graph * const grafptr, \ const SCOTCH_Num * const partptr, \ SCOTCH_Strat * const straptr, \ SCOTCH_Num * const parttab, \ int * const revaptr), \ (grafptr, partptr, straptr, parttab, revaptr)) { *revaptr = SCOTCH_graphPartOvl (grafptr, *partptr, straptr, parttab); } /* String lengths are passed at the very ** end of the argument list. */ FORTRAN ( \ SCOTCHFSTRATGRAPHPARTOVL, scotchfstratgraphpartovl, ( \ SCOTCH_Strat * const straptr, \ const char * const string, \ int * const revaptr, \ const int strnbr), \ (straptr, string, revaptr, strnbr)) { char * restrict strtab; /* Pointer to null-terminated string */ if ((strtab = (char *) memAlloc (strnbr + 1)) == NULL) { /* Allocate temporary space */ errorPrint ("SCOTCHFSTRATGRAPHPARTOVL: out of memory (1)"); *revaptr = 1; } memCpy (strtab, string, strnbr); /* Copy string contents */ strtab[strnbr] = '\0'; /* Terminate string */ *revaptr = SCOTCH_stratGraphPartOvl (straptr, strtab); /* Call original routine */ memFree (strtab); } /* ** */ FORTRAN ( \ SCOTCHFSTRATGRAPHPARTOVLBUILD, scotchfstratgraphpartovlbuild, ( \ SCOTCH_Strat * const straptr, \ const SCOTCH_Num * const flagptr, \ const SCOTCH_Num * const partptr, \ const double * const balrptr, \ int * const revaptr), \ (straptr, flagptr, partptr, balrptr, revaptr)) { *revaptr = SCOTCH_stratGraphPartOvlBuild (straptr, *flagptr, *partptr, *balrptr); /* Call original routine */ } scotch-6.0.4.dfsg/src/libscotch/hgraph_order_bl.h0000644002563400244210000000633411631447170025136 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2009,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hgraph_order_bl.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the block splitting algorithm. **/ /** **/ /** DATES : # Version 3.4 : from : 24 jun 2002 **/ /** to 24 jun 2002 **/ /** # Version 4.0 : from : 26 jun 2002 **/ /** to 29 dec 2004 **/ /** # Version 5.1 : from : 01 oct 2009 **/ /** to : 04 nov 2010 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the method parameters. +*/ typedef struct HgraphOrderBlParam_ { Strat * strat; /*+ Ordering strategy +*/ INT cblkmin; /*+ Block splitting size +*/ } HgraphOrderBlParam; /* ** The function prototypes. */ #ifndef HGRAPH_ORDER_BL #define static #endif int hgraphOrderBl (const Hgraph * const, Order * const, const Gnum, OrderCblk * const, const HgraphOrderBlParam * const); #undef static scotch-6.0.4.dfsg/src/libscotch/dgraph_fold_dup.h0000644002563400244210000000752112412035044025124 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2010,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgraph_fold_dup.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : These lines are the data declaration **/ /** for the distributed graph duplicate **/ /** folding routine. **/ /** **/ /** DATES : # Version 5.0 : from : 13 aug 2006 **/ /** to 13 aug 2006 **/ /** # Version 5.1 : from : 04 nov 2010 **/ /** to 04 nov 2010 **/ /** # Version 6.0 : from : 28 sep 2014 **/ /** to : 28 sep 2014 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ This structure holds the data passed to the subgraph building threads. +*/ typedef struct DgraphFoldDupData_ { const Dgraph * orggrafptr; /*+ Pointer to original graph +*/ Dgraph * fldgrafptr; /*+ Pointer to folded graph +*/ MPI_Comm fldproccomm; /*+ Communicator to be used in folded graph +*/ int partval; /*+ Part of processes to which to fold +*/ void * orgdataptr; /*+ Data associated to vertices, e.g. coarmulttab +*/ void * flddataptr; /*+ Data associated to vertices, e.g. coarmulttab +*/ MPI_Datatype datatype; /*+ MPI type of associated information +*/ } DgraphFoldDupData; /* ** The function prototypes. */ #ifndef DGRAPH_FOLD_DUP #define static #endif #ifdef SCOTCH_PTHREAD static void * dgraphFoldDup2 (void *); #endif /* SCOTCH_PTHREAD */ #undef static scotch-6.0.4.dfsg/src/libscotch/graph_check.c0000644002563400244210000002000311716324003024224 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2011,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : graph_check.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the source graph **/ /** checking function. **/ /** **/ /** DATES : # Version 0.0 : from : 01 dec 1992 **/ /** to 18 may 1993 **/ /** # Version 1.3 : from : 30 apr 1994 **/ /** to 18 may 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to 31 oct 1994 **/ /** # Version 3.0 : from : 07 jul 1995 **/ /** to 28 sep 1995 **/ /** # Version 3.1 : from : 28 nov 1995 **/ /** to 08 jun 1996 **/ /** # Version 3.2 : from : 07 sep 1996 **/ /** to 15 sep 1998 **/ /** # Version 3.3 : from : 22 sep 1998 **/ /** to 31 dec 1998 **/ /** # Version 4.0 : from : 24 nov 2001 **/ /** to 22 apr 2004 **/ /** # Version 5.0 : from : 13 dec 2006 **/ /** to 02 oct 2007 **/ /** # Version 6.0 : from : 27 jun 2011 **/ /** to 14 feb 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GRAPH #include "module.h" #include "common.h" #include "graph.h" /****************************************/ /* */ /* These routines handle source graphs. */ /* */ /****************************************/ /* This routine checks the consistency ** of the given graph. ** It returns: ** - 0 : if graph data are consistent. ** - !0 : on error. */ int graphCheck ( const Graph * const grafptr) { Gnum vertnum; /* Number of current vertex */ Gnum velosum; /* Sum of vertex loads */ Gnum edlosum; /* Sum of edge loads */ Gnum edgenbr; /* Number of edges (arcs) */ Gnum edgenum; /* Number of current edge */ Gnum degrmax; /* Maximum degree */ if (grafptr->vertnbr != (grafptr->vertnnd - grafptr->baseval)) { errorPrint ("graphCheck: invalid vertex numbers"); return (1); } degrmax = edgenbr = 0; velosum = (grafptr->velotax == NULL) ? grafptr->vertnbr : 0; edlosum = (grafptr->edlotax == NULL) ? grafptr->edgenbr : 0; for (vertnum = grafptr->baseval; vertnum < grafptr->vertnnd; vertnum ++) { if ((grafptr->verttax[vertnum] < grafptr->baseval) || (grafptr->vendtax[vertnum] < grafptr->verttax[vertnum])) { errorPrint ("graphCheck: invalid vertex arrays"); return (1); } if ((grafptr->vendtax[vertnum] - grafptr->verttax[vertnum]) > degrmax) degrmax = grafptr->vendtax[vertnum] - grafptr->verttax[vertnum]; edgenbr += grafptr->vendtax[vertnum] - grafptr->verttax[vertnum]; for (edgenum = grafptr->verttax[vertnum]; edgenum < grafptr->vendtax[vertnum]; edgenum ++) { Gnum vertend; /* Number of end vertex */ Gnum edgeend; /* Number of end vertex edge */ vertend = grafptr->edgetax[edgenum]; if (grafptr->edlotax != NULL) { Gnum edlotmp; edlotmp = edlosum + grafptr->edlotax[edgenum]; if (edlotmp < edlosum) { /* If overflow */ errorPrint ("graphCheck: edge load sum overflow"); return (1); } edlosum = edlotmp; } if ((vertend < grafptr->baseval) || (vertend >= grafptr->vertnnd)) { /* If invalid edge end */ errorPrint ("graphCheck: invalid edge array"); return (1); } if (vertend == vertnum) { /* Loops not allowed */ errorPrint ("graphCheck: loops not allowed"); return (1); } for (edgeend = grafptr->verttax[vertend]; /* Search for matching arc */ (edgeend < grafptr->vendtax[vertend]) && (grafptr->edgetax[edgeend] != vertnum); edgeend ++) ; if ((edgeend >= grafptr->vendtax[vertend]) || ((grafptr->edlotax != NULL) && (grafptr->edlotax[edgenum] != grafptr->edlotax[edgeend]))) { errorPrint ("graphCheck: arc data do not match"); return (1); } for (edgeend ++; /* Search for duplicate arcs */ (edgeend < grafptr->vendtax[vertend]) && (grafptr->edgetax[edgeend] != vertnum); edgeend ++) ; if (edgeend < grafptr->vendtax[vertend]) { errorPrint ("graphCheck: duplicate arc"); return (1); } } if (grafptr->velotax != NULL) { Gnum velotmp; if (grafptr->velotax[vertnum] < 0) { /* If non positive loads */ errorPrint ("graphCheck: invalid vertex load array"); return (1); } velotmp = velosum + grafptr->velotax[vertnum]; if (velotmp < velosum) { /* If overflow */ errorPrint ("graphCheck: vertex load sum overflow"); return (1); } velosum = velotmp; } } if (grafptr->edgenbr != edgenbr) { errorPrint ("graphCheck: invalid number of edges"); return (1); } if (grafptr->velosum != velosum) { errorPrint ("graphCheck: invalid vertex load sum"); return (1); } if (grafptr->edlosum != edlosum) { errorPrint ("graphCheck: invalid edge load sum"); return (1); } if (grafptr->degrmax < degrmax) { errorPrint ("graphCheck: invalid maximum degree"); return (1); } return (0); } scotch-6.0.4.dfsg/src/libscotch/vdgraph_separate_st.h0000644002563400244210000000671111631447171026042 0ustar trophimeutilisateurs du domaine/* Copyright 2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vdgraph_separate_st.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the global distributed sepa- **/ /** ration strategy and method tables. **/ /** **/ /** DATES : # Version 5.0 : from : 16 feb 2006 **/ /** to 08 mar 2006 **/ /** # Version 5.1 : from : 05 nov 2007 **/ /** to 05 nov 2007 **/ /** **/ /************************************************************/ /* ** The type definitions. */ /*+ Method types. +*/ typedef enum VdgraphSeparateStMethodType_ { VDGRAPHSEPASTMETHBD = 0, /*+ Band strategy +*/ VDGRAPHSEPASTMETHDF, /*+ Diffusion method +*/ VDGRAPHSEPASTMETHML, /*+ Multilevel strategy +*/ VDGRAPHSEPASTMETHSQ, /*+ Sequential strategy +*/ VDGRAPHSEPASTMETHZR, /*+ Zero method +*/ VDGRAPHSEPASTMETHNBR /*+ Number of methods +*/ } VdgraphSeparateStMethodType; /* ** The external declarations. */ extern StratTab vdgraphseparateststratab; /* ** The function prototypes. */ #ifndef VDGRAPH_SEPARATE_ST #define static #endif int vdgraphSeparateSt (Vdgraph * const, const Strat * const); #undef static scotch-6.0.4.dfsg/src/libscotch/kdgraph.h0000644002563400244210000000752112017442671023434 0ustar trophimeutilisateurs du domaine/* Copyright 2008,2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kdgraph.h **/ /** **/ /** AUTHOR : Jun-Ho HER (v6.0) **/ /** Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a static mapper. **/ /** These lines are the data declarations **/ /** for the parallel k-way graph partiton- **/ /** ing structures and routines. **/ /** **/ /** DATES : # Version 5.1 : from : 31 mar 2008 **/ /** to 04 nov 2010 **/ /** # Version 6.0 : from : 29 aug 2012 **/ /** to 29 aug 2012 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ The dynamic mapping structure. +*/ typedef struct Kdmapping_ { Dmapping * mappptr; /*+ Resulting mapping +*/ ArchDom domnorg; /*+ Initial domain +*/ } Kdmapping; /*+ The graph structure. +*/ typedef struct Kdgraph_ { Dgraph s; /*+ Source graph +*/ Kdmapping m; /*+ Mapping +*/ INT levlnum; } Kdgraph; /* ** The function prototypes. */ #ifndef KDGRAPH #define static #endif int kdgraphInit (Kdgraph * const, const Dgraph * restrict const, Dmapping * restrict const); void kdgraphExit (Kdgraph * const); int kdgraphFold (const Kdgraph *, const int, Kdgraph * const); int kdgraphFold2 (const Kdgraph *, const int, Kdgraph * const, MPI_Comm); #ifdef KGRAPH_H int kdgraphGather (Kdgraph *, Kgraph *); #endif /* KGRAPH_H */ #undef static scotch-6.0.4.dfsg/src/libscotch/kgraph_store.c0000644002563400244210000001505611703530521024472 0ustar trophimeutilisateurs du domaine/* Copyright 2011 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : kgraph_store.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module contains the save data **/ /** structure handling routines for k-par- **/ /** tition graphs. **/ /** **/ /** DATES : # Version 6.0 : from : 16 aug 2011 **/ /** to 16 aug 2011 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define KGRAPH_STORE #include "module.h" #include "common.h" #include "graph.h" #include "arch.h" #include "mapping.h" #include "kgraph.h" /**********************************/ /* */ /* Store graph handling routines. */ /* */ /**********************************/ /* This routine builds a save structure ** for the given active graph. ** It returns: ** - 0 : if allocation succeeded. ** - !0 : on error. */ int kgraphStoreInit ( const Kgraph * const grafptr, KgraphStore * const storptr) { ArchDom domnfrst; /* Largest domain in the architecture */ archDomFrst (&grafptr->a, &domnfrst); /* Get architecture domain */ storptr->partnbr = (Gnum) archDomSize (&grafptr->a, &domnfrst); /* Get architecture size */ if (memAllocGroup ((void **) (void *) /* Allocate save structure */ &storptr->parttab, (size_t) (grafptr->s.vertnbr * sizeof (Anum)), &storptr->domntab, (size_t) (grafptr->m.domnmax * sizeof (ArchDom)), &storptr->frontab, (size_t) (grafptr->s.vertnbr * sizeof (Gnum)), &storptr->comploadavg, (size_t) (storptr->partnbr * sizeof (Gnum)), &storptr->comploaddlt, (size_t) (storptr->partnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("kgraphStoreInit out of memory (1)"); return (1); } return (0); } /* This routine frees a save structure. ** It returns: ** - VOID : in all cases. */ void kgraphStoreExit ( KgraphStore * const storptr) { memFree (storptr->parttab); /* Free group leader */ #ifdef SCOTCH_DEBUG_KGRAPH2 storptr->parttab = NULL; storptr->domntab = NULL; storptr->frontab = NULL; storptr->comploadavg = NULL; storptr->comploaddlt = NULL; #endif /* SCOTCH_DEBUG_KGRAPH2 */ } /* This routine saves partition data from the ** given active graph to the given save structure. ** It returns: ** - VOID : in all cases. */ void kgraphStoreSave ( const Kgraph * const grafptr, KgraphStore * const storptr) { storptr->mflaval = grafptr->commload; storptr->domnnbr = grafptr->m.domnnbr; storptr->fronnbr = grafptr->fronnbr; storptr->kbalval = grafptr->kbalval; storptr->commload = grafptr->commload; memCpy (storptr->parttab, grafptr->m.parttax + grafptr->s.baseval, grafptr->s.vertnbr * sizeof (Anum)); memCpy (storptr->domntab, grafptr->m.domntab, grafptr->m.domnnbr * sizeof (ArchDom)); memCpy (storptr->frontab, grafptr->frontab, storptr->fronnbr * sizeof (Gnum)); memCpy (storptr->comploadavg, grafptr->comploadavg, storptr->partnbr * sizeof (Gnum)); memCpy (storptr->comploaddlt, grafptr->comploaddlt, storptr->partnbr * sizeof (Gnum)); } /* This routine updates partition data of the ** given active graph, using the given save graph. ** It returns: ** - VOID : in all cases. */ void kgraphStoreUpdt ( Kgraph * const grafptr, const KgraphStore * const storptr) { grafptr->commload = storptr->mflaval; grafptr->m.domnnbr = storptr->domnnbr; grafptr->fronnbr = storptr->fronnbr; grafptr->kbalval = storptr->kbalval; grafptr->commload = storptr->commload; memCpy (grafptr->m.parttax + grafptr->s.baseval, storptr->parttab, grafptr->s.vertnbr * sizeof (Anum)); memCpy (grafptr->m.domntab, storptr->domntab, grafptr->m.domnnbr * sizeof (ArchDom)); memCpy (grafptr->frontab, storptr->frontab, storptr->fronnbr * sizeof (Gnum)); memCpy (grafptr->comploadavg, storptr->comploadavg, storptr->partnbr * sizeof (Gnum)); memCpy (grafptr->comploaddlt, storptr->comploaddlt, storptr->partnbr * sizeof (Gnum)); #ifdef SCOTCH_DEBUG_KGRAPH2 if (kgraphCheck (grafptr) != 0) errorPrint ("kgraphStoreUpdt: inconsistent graph data"); #endif /* SCOTCH_DEBUG_KGRAPH2 */ } scotch-6.0.4.dfsg/src/libscotch/common_error.c0000644002563400244210000001073511631447171024512 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : common_error.c **/ /** **/ /** AUTHORS : David GOUDIN **/ /** Pascal HENON **/ /** Francois PELLEGRINI **/ /** Pierre RAMET **/ /** **/ /** FUNCTION : Part of a parallel direct block solver. **/ /** This module handles errors. **/ /** **/ /** DATES : # Version 0.0 : from : 08 may 1998 **/ /** to 02 oct 1998 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define COMMON_ERROR #include "common.h" /********************************/ /* */ /* The error handling routines. */ /* */ /********************************/ static char errorProgName[32] = ""; /* This routine sets the program name for ** error reporting. ** It returns: ** - VOID : in all cases. */ void errorProg ( const char * const progstr) /*+ Program name +*/ { strncpy (errorProgName, progstr, 29); errorProgName[29] = '\0'; strcat (errorProgName, ": "); } /* This routine prints an error message with ** a variable number of arguments, as printf () ** does, and exits. ** It returns: ** - EXIT : in all cases. */ void errorPrint ( const char * const errstr, /*+ printf-like variable argument list */ ...) { va_list errlist; /* Argument list of the call */ fprintf (stderr, "%sERROR: ", errorProgName); va_start (errlist, errstr); vfprintf (stderr, errstr, errlist); /* Print arguments */ va_end (errlist); fprintf (stderr, "\n"); fflush (stderr); /* In case it has been set to buffered mode */ } /* This routine prints a warning message with ** a variable number of arguments, as printf () ** does. ** It returns: ** - VOID : in all cases. */ void errorPrintW ( const char * const errstr, /*+ printf-like variable argument list */ ...) { va_list errlist; /* Argument list of the call */ fprintf (stderr, "%sWARNING: ", errorProgName); va_start (errlist, errstr); vfprintf (stderr, errstr, errlist); /* Print arguments */ va_end (errlist); fprintf (stderr, "\n"); fflush (stderr); /* In case it has been set to buffered mode */ } scotch-6.0.4.dfsg/src/libscotch/vgraph.h0000644002563400244210000001164111631447170023301 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vgraph.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for vertex separation routines. **/ /** **/ /** DATES : # Version 3.2 : from : 24 aug 1996 **/ /** to : 17 oct 1997 **/ /** # Version 3.3 : from : 13 mar 1999 **/ /** to : 13 mar 1999 **/ /** # Version 4.0 : from : 11 dec 2001 **/ /** to : 07 jan 2002 **/ /** # Version 5.1 : from : 04 nov 2010 **/ /** to : 04 nov 2010 **/ /** **/ /************************************************************/ #define VGRAPH_H /* ** The type and structure definitions. */ /*+ Active graph structure. +*/ typedef struct Vgraph_ { Graph s; /*+ Source graph +*/ GraphPart * parttax; /*+ Based part array: 0,1: part; 2: separator +*/ Gnum compload[3]; /*+ Size of both parts and separator +*/ Gnum comploaddlt; /*+ Load difference between both parts +*/ Gnum compsize[2]; /*+ Number of vertices in parts (separator is fronnbr) +*/ Gnum fronnbr; /*+ Number of frontier vertices; TRICK: compsize[2] +*/ Gnum * frontab; /*+ Array of frontier vertex numbers +*/ Gnum levlnum; /*+ Nested dissection or coarsening level +*/ } Vgraph; /*+ The graph separator storing structure. +*/ typedef struct VgraphStore_ { Gnum fronnbr; /*+ Number of frontier nodes +*/ Gnum comploaddlt; /*+ Difference from the average +*/ Gnum compload[2]; /*+ Load in both parts +*/ Gnum compsize0; /*+ Number of vertices in part 0 +*/ byte * datatab; /*+ Variable-sized data array +*/ } VgraphStore; /* ** The function prototypes. */ #ifndef VGRAPH #define static #endif void vgraphExit (Vgraph * const); void vgraphZero (Vgraph * const); int vgraphCheck (const Vgraph * const); int vgraphStoreInit (const Vgraph * const, VgraphStore * const); void vgraphStoreExit (VgraphStore * const); void vgraphStoreSave (const Vgraph * const , VgraphStore * const); void vgraphStoreUpdt (Vgraph * const, const VgraphStore * const); #undef static scotch-6.0.4.dfsg/src/libscotch/library_graph_io_chac.c0000644002563400244210000001003611631447170026274 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_graph_io_chac.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the Chaco **/ /** geometry and graph handling routines of **/ /** the libSCOTCH library. **/ /** **/ /** DATES : # Version 4.0 : from : 28 nov 2003 **/ /** to 19 jan 2004 **/ /** # Version 5.1 : from : 27 apr 2010 **/ /** to 27 apr 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "geom.h" #include "graph.h" #include "scotch.h" /*************************************/ /* */ /* These routines are the C API for */ /* the Chaco graph and geometry */ /* handling routines. */ /* */ /*************************************/ /*+ This routine loads the given opaque geom *** structure with the data of the given stream. *** - 0 : if loading succeeded. *** - !0 : on error. +*/ int SCOTCH_graphGeomLoadChac ( SCOTCH_Graph * restrict const grafptr, SCOTCH_Geom * restrict const geomptr, FILE * const filegrfptr, FILE * const filegeoptr, const char * const dataptr) { return (graphGeomLoadChac ((Graph *) grafptr, (Geom *) geomptr, filegrfptr, filegeoptr, dataptr)); } /*+ This routine saves the contents of the given *** opaque graph structure to the given stream. *** It returns: *** - 0 : if the saving succeeded. *** - !0 : on error. +*/ int SCOTCH_graphGeomSaveChac ( const SCOTCH_Graph * restrict const grafptr, const SCOTCH_Geom * restrict const geomptr, FILE * const filegrfptr, FILE * const filegeoptr, const char * const dataptr) { return (graphGeomSaveChac ((Graph *) grafptr, (Geom *) geomptr, filegrfptr, filegeoptr, dataptr)); } scotch-6.0.4.dfsg/src/libscotch/hdgraph_order_si.c0000644002563400244210000001223011631447170025303 0ustar trophimeutilisateurs du domaine/* Copyright 2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hdgraph_order_si.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module orders halo distributed **/ /** graph vertices using a simple method. **/ /** **/ /** DATES : # Version 5.0 : from : 15 apr 2006 **/ /** to 25 jul 2007 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HDGRAPH_ORDER_SI #include "module.h" #include "common.h" #include "dgraph.h" #include "dorder.h" #include "hdgraph.h" #include "hdgraph_order_si.h" /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ /* This routine performs the ordering. ** It returns: ** - 0 : if the ordering could be computed. ** - !0 : on error. */ int hdgraphOrderSi ( const Hdgraph * restrict const grafptr, DorderCblk * restrict const cblkptr) /*+ Single column-block +*/ { Gnum * restrict periloctab; Gnum * restrict periloctax; Gnum vnohlocnbr; Gnum vertlocnum; #ifdef SCOTCH_DEBUG_HDGRAPH1 int cheklocval; int chekglbval; cheklocval = 0; #endif /* SCOTCH_DEBUG_HDGRAPH1 */ vnohlocnbr = grafptr->s.vertlocnbr; /* Get number of local non-halo vertices */ if ((periloctab = (Gnum *) memAlloc (vnohlocnbr * sizeof (Gnum))) == NULL) { /* Allocate local fragment */ errorPrint ("hdgraphOrderSi: out of memory"); #ifndef SCOTCH_DEBUG_HDGRAPH1 return (1); } #else /* SCOTCH_DEBUG_HDGRAPH1 */ } if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, grafptr->s.proccomm) != MPI_SUCCESS) { /* Communication cannot be merged with a useful one */ errorPrint ("hdgraphOrderSi: communication error (1)"); return (1); } if (chekglbval != 0) { if (periloctab != NULL) memFree (periloctab); return (1); } #endif /* SCOTCH_DEBUG_HDGRAPH1 */ cblkptr->typeval = DORDERCBLKLEAF; /* Fill node as leaf */ cblkptr->data.leaf.ordelocval = cblkptr->ordeglbval + grafptr->s.procdsptab[grafptr->s.proclocnum] - grafptr->s.baseval;; cblkptr->data.leaf.vnodlocnbr = vnohlocnbr; cblkptr->data.leaf.periloctab = periloctab; cblkptr->data.leaf.nodelocnbr = 0; cblkptr->data.leaf.nodeloctab = NULL; #ifdef SCOTCH_DEBUG_HDGRAPH2 cblkptr->data.leaf.cblklocnum = -1; #endif /* SCOTCH_DEBUG_HDGRAPH2 */ periloctax = periloctab - grafptr->s.baseval; if (grafptr->s.vnumloctax == NULL) { /* If graph is original graph */ Gnum vertglbadj; vertglbadj = grafptr->s.procdsptab[grafptr->s.proclocnum] - grafptr->s.baseval; /* Set adjustement for global ordering */ for (vertlocnum = grafptr->s.baseval; vertlocnum < grafptr->s.vertlocnnd; vertlocnum ++) periloctax[vertlocnum] = vertlocnum + vertglbadj; } else { /* Graph is not original graph */ for (vertlocnum = grafptr->s.baseval; vertlocnum < grafptr->s.vertlocnnd; vertlocnum ++) periloctax[vertlocnum] = grafptr->s.vnumloctax[vertlocnum]; } return (0); } scotch-6.0.4.dfsg/src/libscotch/hmesh_hgraph.c0000644002563400244210000003456011631447171024450 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : hmesh_hgraph.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the source halo **/ /** mesh to halo graph conversion function. **/ /** **/ /** DATES : # Version 4.0 : from : 30 nov 2003 **/ /** to 05 may 2004 **/ /** # Version 5.0 : from : 10 sep 2007 **/ /** to : 10 sep 2007 **/ /** **/ /** NOTES : # From a given halo mesh is created a **/ /** halo graph, such that all vertices of **/ /** the graph represent the nodes of the **/ /** mesh, and there exists an edge **/ /** between two vertices if there exists **/ /** at least one element to which the two **/ /** associated nodes belong. **/ /** While all non-halo nodes become non- **/ /** halo vertices, some halo nodes may **/ /** disappear from the graph if their **/ /** elements are only connected to other **/ /** halo nodes. **/ /** Since the contents of vnumtab are **/ /** based with respect to s.baseval and **/ /** not to vnodbas, the vnumtab array can **/ /** simply be shared by the graph. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define HMESH_HGRAPH #include "module.h" #include "common.h" #include "graph.h" #include "hgraph.h" #include "mesh.h" #include "hmesh.h" #include "hmesh_hgraph.h" /************************************/ /* */ /* The halo graph building routine. */ /* */ /************************************/ /* This routine builds a halo graph from ** the given halo mesh. ** It returns: ** - 0 : if the halo graph has been successfully built. ** - 1 : on error. */ int hmeshHgraph ( const Hmesh * restrict const meshptr, /*+ Original mesh +*/ Hgraph * restrict const grafptr) /*+ Graph to build +*/ { Gnum hashnbr; /* Number of vertices in hash table */ Gnum hashsiz; /* Size of hash table */ Gnum hashmsk; /* Mask for access to hash table */ HmeshHgraphHash * restrict hashtab; /* Table of edges to other node vertices */ Gnum edgemax; /* Upper bound of number of edges in mesh */ Gnum edgennd; /* Based upper bound on number of edges */ Gnum enohnbr; /* Number of non-halo edges */ Gnum edgenum; /* Number of current graph edge */ Gnum vertnum; /* Number of current graph vertex */ Gnum degrmax; #ifdef SCOTCH_DEBUG_HMESH2 if (hmeshCheck (meshptr) != 0) { errorPrint ("hmeshHgraph: invalid input halo mesh"); return (1); } #endif /* SCOTCH_DEBUG_HMESH2 */ grafptr->s.flagval = GRAPHFREETABS | GRAPHVERTGROUP | GRAPHEDGEGROUP; grafptr->s.baseval = meshptr->m.baseval; grafptr->s.vertnbr = meshptr->m.vnodnbr; grafptr->s.vertnnd = meshptr->m.vnodnbr + meshptr->m.baseval; grafptr->vnohnbr = meshptr->vnohnbr; grafptr->vnohnnd = meshptr->vnohnbr + grafptr->s.baseval; grafptr->vnlosum = meshptr->vnhlsum; for (hashsiz = 2, hashnbr = meshptr->m.degrmax * meshptr->m.degrmax * 2; /* Compute size of hash table */ hashsiz < hashnbr; hashsiz <<= 1) ; hashmsk = hashsiz - 1; if (memAllocGroup ((void **) (void *) &grafptr->s.verttax, (size_t) ((grafptr->s.vertnbr + 1) * sizeof (Gnum)), &grafptr->vnhdtax, (size_t) ( grafptr->vnohnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("hmeshHgraph: out of memory (1)"); return (1); } if ((hashtab = memAlloc (hashsiz * sizeof (HmeshHgraphHash))) == NULL) { errorPrint ("hmeshHgraph: out of memory (2)"); memFree (grafptr->s.verttax); return (1); } grafptr->s.verttax -= grafptr->s.baseval; grafptr->s.vendtax = grafptr->s.verttax + 1; grafptr->vnhdtax -= grafptr->s.baseval; if (meshptr->m.vnumtax != NULL) /* If (node) vertex index array present, point to its relevant part */ grafptr->s.vnumtax = meshptr->m.vnumtax + (meshptr->m.vnodbas - grafptr->s.baseval); /* Since GRAPHVERTGROUP, no problem on graphFree */ if (meshptr->m.vnlotax != NULL) /* Keep node part of mesh (node) vertex load array as graph vertex load array */ grafptr->s.velotax = meshptr->m.vnlotax + (meshptr->m.vnodbas - grafptr->s.baseval); /* Since GRAPHVERTGROUP, no problem on graphFree */ grafptr->s.velosum = meshptr->m.vnlosum; edgemax = ((meshptr->m.degrmax * meshptr->m.degrmax) / 2 + 1) * meshptr->m.vnodnbr; /* Compute estimated number of edges in graph */ #ifdef SCOTCH_DEBUG_HMESH2 edgemax = meshptr->m.degrmax + 4; /* Test dynamic reallocation of edge array; 4 guarantees that 25% > 0 */ #endif /* SCOTCH_DEBUG_HMESH2 */ if ((grafptr->s.edgetax = memAlloc (edgemax * sizeof (Gnum))) == NULL) { errorPrint ("hmeshHgraph: out of memory (3)"); hgraphFree (grafptr); return (1); } grafptr->s.edgetax -= grafptr->s.baseval; memSet (hashtab, ~0, hashsiz * sizeof (HmeshHgraphHash)); /* Initialize hash table */ for (vertnum = edgenum = grafptr->s.baseval, edgennd = edgemax + grafptr->s.baseval, enohnbr = degrmax = 0; /* Build graph edges for non-halo vertices */ vertnum < grafptr->vnohnnd; vertnum ++) { Gnum vnodnum; Gnum hnodnum; Gnum enodnum; Gnum enhdnum; /* Index of first non-halo neighbor in edge array for current vertex */ grafptr->s.verttax[vertnum] = edgenum; vnodnum = vertnum + (meshptr->m.vnodbas - meshptr->m.baseval); hnodnum = (vnodnum * HMESHHGRAPHHASHPRIME) & hashmsk; /* Prevent adding loop edge */ hashtab[hnodnum].vertnum = vnodnum; hashtab[hnodnum].vertend = vnodnum; for (enodnum = meshptr->m.verttax[vnodnum], enhdnum = edgenum; enodnum < meshptr->m.vendtax[vnodnum]; enodnum ++) { Gnum velmnum; Gnum eelmnum; velmnum = meshptr->m.edgetax[enodnum]; for (eelmnum = meshptr->m.verttax[velmnum]; eelmnum < meshptr->m.vendtax[velmnum]; eelmnum ++) { Gnum vnodend; Gnum hnodend; vnodend = meshptr->m.edgetax[eelmnum]; for (hnodend = (vnodend * HMESHHGRAPHHASHPRIME) & hashmsk; ; hnodend = (hnodend + 1) & hashmsk) { if (hashtab[hnodend].vertnum != vnodnum) { /* If edge not yet created */ Gnum vertend; if (edgenum == edgennd) { /* If edge array already full */ Gnum edgemax; Gnum * restrict edgetmp; edgemax = edgennd - grafptr->s.baseval; /* Increase size by 25 % */ edgemax = edgemax + (edgemax >> 2); if ((edgetmp = memRealloc (grafptr->s.edgetax + grafptr->s.baseval, edgemax * sizeof (Gnum))) == NULL) { errorPrint ("hmeshHgraph: out of memory (4)"); hgraphFree (grafptr); memFree (hashtab); return (1); } grafptr->s.edgetax = edgetmp - grafptr->s.baseval; edgennd = edgemax + grafptr->s.baseval; } hashtab[hnodend].vertnum = vnodnum; /* Record new edge */ hashtab[hnodend].vertend = vnodend; vertend = vnodend - (meshptr->m.vnodbas - grafptr->s.baseval); if (vnodend >= meshptr->vnohnnd) /* If halo edge */ grafptr->s.edgetax[edgenum ++] = vertend; /* Build at end of array */ else { /* If non-halo edge */ if (edgenum != enhdnum) /* If already halo edges */ grafptr->s.edgetax[edgenum] = grafptr->s.edgetax[enhdnum]; /* Make room */ grafptr->s.edgetax[enhdnum ++] = vertend; /* Record new edge */ edgenum ++; /* One more edge created */ } break; } if (hashtab[hnodend].vertend == vnodend) /* If edge already exists */ break; /* Skip to next neighbor */ } } } grafptr->vnhdtax[vertnum] = enhdnum; /* Set end of non-halo edge array */ enohnbr += enhdnum - grafptr->s.verttax[vertnum]; if ((edgenum - grafptr->s.verttax[vertnum]) > degrmax) /* Compute maximum degree */ degrmax = (edgenum - grafptr->s.verttax[vertnum]); } grafptr->enohnbr = enohnbr; /* All other edges will be halo edges */ for ( ; vertnum < grafptr->s.vertnnd; vertnum ++) { /* Build graph edges for halo vertices */ Gnum vnodnum; Gnum enodnum; vnodnum = vertnum + (meshptr->m.vnodbas - meshptr->m.baseval); grafptr->s.verttax[vertnum] = edgenum; for (enodnum = meshptr->m.verttax[vnodnum]; enodnum < meshptr->m.vendtax[vnodnum]; enodnum ++) { Gnum velmnum; Gnum eelmnum; velmnum = meshptr->m.edgetax[enodnum]; for (eelmnum = meshptr->m.verttax[velmnum]; /* Only consider non-halo edges of elements this time */ eelmnum < meshptr->vehdtax[velmnum]; eelmnum ++) { Gnum vnodend; Gnum hnodend; vnodend = meshptr->m.edgetax[eelmnum]; #ifdef SCOTCH_DEBUG_HMESH2 if (vnodend >= meshptr->vnohnnd) { /* Not visiting halo edges should prevent this */ errorPrint ("hmeshHgraph: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_HMESH2 */ for (hnodend = (vnodend * HMESHHGRAPHHASHPRIME) & hashmsk; ; hnodend = (hnodend + 1) & hashmsk) { if (hashtab[hnodend].vertnum != vnodnum) { /* If edge not yet created */ Gnum vertend; if (edgenum == edgennd) { /* If edge array already full */ Gnum edgemax; Gnum * restrict edgetmp; edgemax = edgennd - grafptr->s.baseval; /* Increase size by 25 % */ edgemax = edgemax + (edgemax >> 2); if ((edgetmp = memRealloc (grafptr->s.edgetax + grafptr->s.baseval, edgemax * sizeof (Gnum))) == NULL) { errorPrint ("hmeshHgraph: out of memory (5)"); hgraphFree (grafptr); memFree (hashtab); return (1); } grafptr->s.edgetax = edgetmp - grafptr->s.baseval; edgennd = edgemax + grafptr->s.baseval; } hashtab[hnodend].vertnum = vnodnum; /* Record new edge */ hashtab[hnodend].vertend = vnodend; vertend = vnodend - (meshptr->m.vnodbas - grafptr->s.baseval); grafptr->s.edgetax[edgenum ++] = vertend; /* Build halo edge */ break; } if (hashtab[hnodend].vertend == vnodend) /* If edge already exists */ break; /* Skip to next neighbor */ } } } if ((edgenum - grafptr->s.verttax[vertnum]) > degrmax) /* Compute maximum degree */ degrmax = (edgenum - grafptr->s.verttax[vertnum]); } grafptr->s.verttax[vertnum] = edgenum; /* Set end of vertex array */ grafptr->s.edgenbr = edgenum - grafptr->s.baseval; grafptr->s.degrmax = degrmax; memFree (hashtab); #ifdef SCOTCH_DEBUG_HMESH2 if (hgraphCheck (grafptr) != 0) { errorPrint ("hmeshHgraph: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_HMESH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/library_dmapping.h0000644002563400244210000000537511631447170025344 0ustar trophimeutilisateurs du domaine/* Copyright 2008,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dmapping.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the library ordering **/ /** structure. **/ /** **/ /** DATES : # Version 5.1 : from : 16 jun 2008 **/ /** to 04 nov 2010 **/ /** **/ /************************************************************/ /* ** The type and structure definitions. */ /*+ Distributed mapping. +*/ typedef struct LibDmapping_ { Dmapping m; /*+ Distributed mapping data +*/ Gnum * termloctab; /*+ Local mapping array +*/ } LibDmapping; scotch-6.0.4.dfsg/src/libscotch/library_dgraph_halo.c0000644002563400244210000001341512055776355026015 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2009,2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_dgraph_halo.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the API for the distri- **/ /** buted source graph handling routines of **/ /** the libSCOTCH library. **/ /** **/ /** DATES : # Version 5.0 : from : 17 jul 2007 **/ /** to 02 aug 2007 **/ /** # Version 5.1 : from : 02 jul 2008 **/ /** to 17 nov 2010 **/ /** # Version 6.0 : from : 29 nov 2012 **/ /** to 29 nov 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "graph.h" #include "dgraph.h" #include "dgraph_halo.h" #include "ptscotch.h" /************************************/ /* */ /* These routines are the C API for */ /* the graph handling routines. */ /* */ /************************************/ /*+ This routine requests the computation *** of the ghost edge array. *** It returns: *** - 0 : if the computation succeeded. *** - !0 : on error. +*/ int SCOTCH_dgraphGhst ( SCOTCH_Dgraph * const grafptr) { return (dgraphGhst ((Dgraph *) grafptr)); } /*+ This routine requests the computation of the *** ghost edge array in replacement of the global *** edge array. *** It returns: *** - 0 : if the computation succeeded. *** - !0 : on error. +*/ int SCOTCH_dgraphGhstReplace ( SCOTCH_Dgraph * const grafptr) { Dgraph * restrict srcgrafptr; /* Pointer to scotch graph */ DgraphFlag srcflagval; /* Graph properties */ int o; srcgrafptr = (Dgraph *) grafptr; srcflagval = srcgrafptr->flagval; srcgrafptr->flagval |= DGRAPHFREETABS; /* If edge array was not allocated internally, assume it was */ o = dgraphGhstReplace (srcgrafptr); srcgrafptr->flagval = (srcgrafptr->flagval & ~DGRAPHFREETABS) | srcflagval; /* Restore original allocation flag */ return (o); } /*+ This routine spreads local information *** borne by local vertices across the ghost *** vertices of the neighboring processes. *** It returns: *** - 0 : if the exchange succeeded. *** - !0 : on error. +*/ int SCOTCH_dgraphHalo ( SCOTCH_Dgraph * const grafptr, void * const datatab, const MPI_Datatype typeval) { return (dgraphHaloSync ((Dgraph *) grafptr, (byte *) datatab, typeval)); } /*+ This routine spreads local information *** borne by local vertices across the ghost *** vertices of the neighboring processes, in *** an asynchronous way. *** It returns: *** - 0 : if the exchange succeeded. *** - !0 : on error. +*/ int SCOTCH_dgraphHaloAsync ( SCOTCH_Dgraph * const grafptr, void * const datatab, const MPI_Datatype typeval, SCOTCH_DgraphHaloReq * const requptr) { dgraphHaloAsync ((Dgraph *) grafptr, (byte *) datatab, typeval, (DgraphHaloRequest *) requptr); return (0); } /*+ This routine waits for the termination of *** an asynchronous halo request. *** It returns: *** - 0 : if the exchange succeeded. *** - !0 : on error. +*/ int SCOTCH_dgraphHaloWait ( SCOTCH_DgraphHaloReq * const requptr) { return (dgraphHaloWait ((DgraphHaloRequest *) requptr)); } /*+ This routine reserves a memory area *** of a size sufficient to store a *** halo request structure. *** It returns: *** - !NULL : if the initialization succeeded. *** - NULL : on error. +*/ SCOTCH_DgraphHaloReq * SCOTCH_dgraphHaloReqAlloc () { return ((SCOTCH_DgraphHaloReq *) memAlloc (sizeof (SCOTCH_DgraphHaloReq))); } scotch-6.0.4.dfsg/src/libscotch/library_geom_f.c0000644002563400244210000000772111631447170024771 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2010 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library_geom_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API for **/ /** the graph geometry handling routines **/ /** of the libSCOTCH library. **/ /** **/ /** DATES : # Version 4.0 : from : 15 jun 2005 **/ /** to 22 dec 2005 **/ /** # Version 5.1 : from : 15 apr 2010 **/ /** to 15 apr 2010 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" /******************************************/ /* */ /* These routines are the Fortran API for */ /* the graph geometry handling routines. */ /* */ /******************************************/ /* ** */ FORTRAN ( \ SCOTCHFGEOMINIT, scotchfgeominit, ( \ SCOTCH_Geom * const geomptr, \ int * const revaptr), \ (geomptr, revaptr)) { *revaptr = SCOTCH_geomInit (geomptr); } /* ** */ FORTRAN ( \ SCOTCHFGEOMEXIT, scotchfgeomexit, ( \ SCOTCH_Geom * const geomptr), \ (geomptr)) { SCOTCH_geomExit (geomptr); } /* ** */ FORTRAN ( \ SCOTCHFGEOMDATA, scotchfgeomdata, ( \ const SCOTCH_Geom * const geomptr, \ const double * const indxptr, \ SCOTCH_Num * const dimnptr, \ SCOTCH_Idx * const geomidx), \ (geomptr, indxptr, dimnptr, geomidx)) { double * geomtab; SCOTCH_geomData (geomptr, dimnptr, &geomtab); *geomidx = (geomtab - indxptr) + 1; /* Add 1 since Fortran indices start at 1 */ } scotch-6.0.4.dfsg/src/libscotch/vmesh_separate_ml.c0000644002563400244210000002616211631447170025507 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : vmesh_separate_ml.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module separates an active **/ /** mesh using a multi-level scheme. **/ /** **/ /** DATES : # Version 4.0 : from : 19 feb 2003 **/ /** to 31 aug 2005 **/ /** # Version 5.0 : from : 30 jan 2008 **/ /** to 30 jan 2008 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define VMESH_SEPARATE_ML #include "module.h" #include "common.h" #include "parser.h" #include "graph.h" #include "mesh.h" #include "mesh_coarsen.h" #include "vmesh.h" #include "vmesh_separate_ml.h" #include "vmesh_separate_st.h" /*********************************************/ /* */ /* The coarsening and uncoarsening routines. */ /* */ /*********************************************/ /* This routine builds a coarser mesh from the ** mesh that is given on input. The coarser ** meshes differ at this stage from classical ** active meshes as their internal gains are not ** yet computed. ** It returns: ** - 0 : if the coarse mesh has been built. ** - 1 : if threshold achieved. ** - 2 : on error. */ static int vmeshSeparateMlCoarsen ( const Vmesh * restrict const finemeshptr, /*+ Finer mesh +*/ Vmesh * restrict const coarmeshptr, /*+ Coarser mesh to build +*/ Gnum * restrict * const finecoarptr, /*+ Pointer to multinode table to build +*/ const VmeshSeparateMlParam * const paraptr) /*+ Method parameters +*/ { int o; if (finemeshptr->m.vnodnbr <= (Gnum) paraptr->vnodnbr) return (1); if ((o = meshCoarsen (&finemeshptr->m, &coarmeshptr->m, finecoarptr, (Gnum) paraptr->vnodnbr, paraptr->coarrat, paraptr->coartype)) != 0) return (o); /* Return if coarsening failed */ coarmeshptr->parttax = NULL; /* Do not allocate partition data yet */ coarmeshptr->frontab = finemeshptr->frontab; /* Re-use frontier array for coarser mesh */ coarmeshptr->levlnum = finemeshptr->levlnum + 1; /* Mesh level is coarsening level */ return (0); } /* This routine propagates the separation of the ** coarser mesh back to the finer mesh, according ** to the multinode table of collapsed elements. ** After the separation is propagated, it finishes ** to compute the parameters of the finer mesh that ** were not computed at the coarsening stage. ** It returns: ** - 0 : if coarse mesh data has been propagated to fine mesh. ** - !0 : on error. */ static int vmeshSeparateMlUncoarsen ( Vmesh * restrict const finemeshptr, /*+ Finer mesh +*/ const Vmesh * restrict const coarmeshptr, /*+ Coarser mesh +*/ const Gnum * restrict const finecoartax) /*+ Multinode array +*/ { if (finemeshptr->parttax == NULL) { /* If partition array not yet allocated */ if ((finemeshptr->parttax = (GraphPart *) memAlloc ((finemeshptr->m.velmnbr + finemeshptr->m.vnodnbr) * sizeof (GraphPart))) == NULL) { errorPrint ("vmeshSeparateMlUncoarsen: out of memory"); return (1); /* Allocated data will be freed along with mesh structure */ } finemeshptr->parttax -= finemeshptr->m.baseval; } if (coarmeshptr != NULL) { /* If coarser mesh provided */ Gnum finevelmnum; Gnum fineecmpsize1; /* Number of fine elements */ Gnum fineecmpsize2; Gnum finevnodnum; Gnum finencmpsize1; /* Number of fine nodes */ Gnum finefronnbr; /* Number of frontier vertices in fine mesh */ for (finevelmnum = finemeshptr->m.velmbas, fineecmpsize1 = fineecmpsize2 = 0; finevelmnum < finemeshptr->m.velmnnd; finevelmnum ++) { Gnum partval; #ifdef SCOTCH_DEBUG_VMESH2 if ((finecoartax[finevelmnum] < coarmeshptr->m.baseval) || (finecoartax[finevelmnum] >= (coarmeshptr->m.velmnbr + coarmeshptr->m.vnodnbr + coarmeshptr->m.baseval))) { errorPrint ("vmeshSeparateMlUncoarsen: internal error (1)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH2 */ partval = (Gnum) coarmeshptr->parttax[finecoartax[finevelmnum]]; finemeshptr->parttax[finevelmnum] = partval; fineecmpsize1 += (partval & 1); /* Superscalar update of counters */ fineecmpsize2 += (partval & 2); } finemeshptr->ecmpsize[0] = finemeshptr->m.velmnbr - fineecmpsize1 - (fineecmpsize2 >> 1); finemeshptr->ecmpsize[1] = fineecmpsize1; for (finevnodnum = finemeshptr->m.vnodbas, finencmpsize1 = finefronnbr = 0; finevnodnum < finemeshptr->m.vnodnnd; finevnodnum ++) { Gnum partval; #ifdef SCOTCH_DEBUG_VMESH2 if ((finecoartax[finevnodnum] < coarmeshptr->m.vnodbas) || /* Sons of nodes are always nodes */ (finecoartax[finevnodnum] >= coarmeshptr->m.vnodnnd)) { errorPrint ("vmeshSeparateMlUncoarsen: internal error (2)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH2 */ partval = coarmeshptr->parttax[finecoartax[finevnodnum]]; finemeshptr->parttax[finevnodnum] = partval; if ((partval & 2) != 0) /* If node is in separator */ finemeshptr->frontab[finefronnbr ++] = finevnodnum; /* Add to frontier */ finencmpsize1 += (partval & 1); } finemeshptr->ncmpload[0] = coarmeshptr->ncmpload[0]; finemeshptr->ncmpload[1] = coarmeshptr->ncmpload[1]; finemeshptr->ncmpload[2] = coarmeshptr->ncmpload[2]; finemeshptr->ncmploaddlt = coarmeshptr->ncmploaddlt; finemeshptr->ncmpsize[0] = finemeshptr->m.vnodnbr - finencmpsize1 - finefronnbr; finemeshptr->ncmpsize[1] = finencmpsize1; finemeshptr->fronnbr = finefronnbr; } else /* No coarse mesh provided */ vmeshZero (finemeshptr); /* Assign all vertices to part 0 */ #ifdef SCOTCH_DEBUG_VMESH2 if (vmeshCheck (finemeshptr) != 0) { errorPrint ("vmeshSeparateMlUncoarsen: internal error (3)"); return (1); } #endif /* SCOTCH_DEBUG_VMESH2 */ return (0); } /* This routine recursively performs the ** coarsening recursion. ** It returns: ** - 0 : if recursion proceeded well. ** - !0 : on error. */ static int vmeshSeparateMl2 ( Vmesh * restrict const finemeshptr, /* Vertex-separation mesh */ const VmeshSeparateMlParam * restrict const paraptr) /* Method parameters */ { Vmesh coarmeshdat; Gnum * restrict finecoartax; int o; o = 1; /* Assume an error if "switch...case" returns a strange value in debug mode */ switch (vmeshSeparateMlCoarsen (finemeshptr, &coarmeshdat, &finecoartax, paraptr)) { case 0 : if (((o = vmeshSeparateMl2 (&coarmeshdat, paraptr)) == 0) && ((o = vmeshSeparateMlUncoarsen (finemeshptr, &coarmeshdat, finecoartax)) == 0) && ((o = vmeshSeparateSt (finemeshptr, paraptr->stratasc)) != 0)) /* Apply ascending strategy */ errorPrint ("vmeshSeparateMl2: cannot apply ascending strategy"); coarmeshdat.frontab = NULL; /* Prevent frontab of fine mesh from being freed */ vmeshExit (&coarmeshdat); memFree (finecoartax + finemeshptr->m.baseval); /* Free finecoartab as not part of coarse mesh vertex group (unlike for graphCoarsen) */ break; #ifdef SCOTCH_DEBUG_VMESH2 case 1 : case 2 : /* Cannot coarsen due to lack of memory */ finecoartax = NULL; /* Prevent Valgrind from yelling */ #else /* SCOTCH_DEBUG_VMESH2 */ default : #endif /* SCOTCH_DEBUG_VMESH2 */ if (((o = vmeshSeparateMlUncoarsen (finemeshptr, NULL, finecoartax)) == 0) && /* Finalize mesh */ ((o = vmeshSeparateSt (finemeshptr, paraptr->stratlow)) != 0)) /* Apply low strategy */ errorPrint ("vmeshSeparateMl2: cannot apply low strategy"); break; } return (o); } /*****************************/ /* */ /* This is the main routine. */ /* */ /*****************************/ int vmeshSeparateMl ( Vmesh * restrict const meshptr, /*+ Node-separation mesh +*/ const VmeshSeparateMlParam * const paraptr) /*+ Method parameters +*/ { Gnum levlnum; /* Save value for mesh level */ int o; levlnum = meshptr->levlnum; /* Save mesh level */ meshptr->levlnum = 0; /* Initialize coarsening level */ o = vmeshSeparateMl2 (meshptr, paraptr); /* Perform multi-level separation */ meshptr->levlnum = levlnum; /* Restore mesh level */ return (o); } scotch-6.0.4.dfsg/src/libscotch/library.h0000644002563400244210000005235512474554132023470 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007-2012,2014,2015 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : library.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Jun-Ho HER (v6.0) **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : Declaration file for the LibScotch **/ /** static mapping and sparse matrix block **/ /** ordering library. **/ /** **/ /** DATES : # Version 3.2 : from : 07 sep 1996 **/ /** to 22 aug 1998 **/ /** # Version 3.3 : from : 02 oct 1998 **/ /** to 31 may 1999 **/ /** # Version 3.4 : from : 10 oct 1999 **/ /** to 15 nov 2001 **/ /** # Version 4.0 : from : 11 dec 2001 **/ /** to 20 dec 2005 **/ /** # Version 5.0 : from : 26 apr 2006 **/ /** to : 20 feb 2008 **/ /** # Version 5.1 : from : 30 nov 2007 **/ /** to : 07 aug 2011 **/ /** # Version 6.0 : from : 12 sep 2008 **/ /** to 28 feb 2015 **/ /** **/ /************************************************************/ #ifndef SCOTCH_H #define SCOTCH_H /* ** The type and structure definitions. */ /*+ Version flags. +*/ #define SCOTCH_VERSION DUMMYVERSION #define SCOTCH_RELEASE DUMMYRELEASE #define SCOTCH_PATCHLEVEL DUMMYPATCHLEVEL /*+ Integer type. +*/ typedef DUMMYIDX SCOTCH_Idx; typedef DUMMYINT SCOTCH_Num; #define SCOTCH_NUMMAX DUMMYMAXINT #define SCOTCH_NUMSTRING DUMMYNUMSTRING /*+ Coarsening flags +*/ #define SCOTCH_COARSENNONE 0x0000 #define SCOTCH_COARSENFOLD 0x0100 #define SCOTCH_COARSENFOLDDUP 0x0300 #define SCOTCH_COARSENNOMERGE 0x4000 /*+ Strategy string parametrization values +*/ #define SCOTCH_STRATDEFAULT 0x0000 #define SCOTCH_STRATQUALITY 0x0001 #define SCOTCH_STRATSPEED 0x0002 #define SCOTCH_STRATBALANCE 0x0004 #define SCOTCH_STRATSAFETY 0x0008 #define SCOTCH_STRATSCALABILITY 0x0010 #define SCOTCH_STRATRECURSIVE 0x0100 #define SCOTCH_STRATREMAP 0x0200 #define SCOTCH_STRATLEVELMAX 0x1000 #define SCOTCH_STRATLEVELMIN 0x2000 #define SCOTCH_STRATLEAFSIMPLE 0x4000 #define SCOTCH_STRATSEPASIMPLE 0x8000 /*+ Opaque objects. The dummy sizes of these objects, computed at compile-time by program "dummysizes", are given as double values for proper padding +*/ typedef struct { double dummy[DUMMYSIZEARCH]; } SCOTCH_Arch; typedef struct { double dummy[DUMMYSIZEGEOM]; } SCOTCH_Geom; typedef struct { double dummy[DUMMYSIZEGRAPH]; } SCOTCH_Graph; typedef struct { double dummy[DUMMYSIZEMESH]; } SCOTCH_Mesh; typedef struct { double dummy[DUMMYSIZEMAP]; } SCOTCH_Mapping; typedef struct { double dummy[DUMMYSIZEORDER]; } SCOTCH_Ordering; typedef struct { double dummy[DUMMYSIZESTRAT]; } SCOTCH_Strat; /* ** The function prototypes. */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ SCOTCH_Arch * SCOTCH_archAlloc (void); int SCOTCH_archInit (SCOTCH_Arch * const); void SCOTCH_archExit (SCOTCH_Arch * const); int SCOTCH_archLoad (SCOTCH_Arch * const, FILE * const); int SCOTCH_archSave (const SCOTCH_Arch * const, FILE * const); int SCOTCH_archBuild (SCOTCH_Arch * const, const SCOTCH_Graph * const, const SCOTCH_Num, const SCOTCH_Num * const, const SCOTCH_Strat * const); char * SCOTCH_archName (const SCOTCH_Arch * const); SCOTCH_Num SCOTCH_archSize (const SCOTCH_Arch * const); int SCOTCH_archVar (const SCOTCH_Arch * const); int SCOTCH_archCmplt (SCOTCH_Arch * const, const SCOTCH_Num); int SCOTCH_archCmpltw (SCOTCH_Arch * const, const SCOTCH_Num, const SCOTCH_Num * const); int SCOTCH_archHcub (SCOTCH_Arch * const, const SCOTCH_Num); int SCOTCH_archMesh2 (SCOTCH_Arch * const, const SCOTCH_Num, const SCOTCH_Num); int SCOTCH_archMesh3 (SCOTCH_Arch * const, const SCOTCH_Num, const SCOTCH_Num, const SCOTCH_Num); int SCOTCH_archTleaf (SCOTCH_Arch * const, const SCOTCH_Num, const SCOTCH_Num * const, const SCOTCH_Num * const); int SCOTCH_archTorus2 (SCOTCH_Arch * const, const SCOTCH_Num, const SCOTCH_Num); int SCOTCH_archTorus3 (SCOTCH_Arch * const, const SCOTCH_Num, const SCOTCH_Num, const SCOTCH_Num); int SCOTCH_archVcmplt (SCOTCH_Arch * const); int SCOTCH_archVhcub (SCOTCH_Arch * const); void SCOTCH_errorProg (const char * const); void SCOTCH_errorPrint (const char * const, ...); void SCOTCH_errorPrintW (const char * const, ...); SCOTCH_Geom * SCOTCH_geomAlloc (void); int SCOTCH_geomInit (SCOTCH_Geom * const); void SCOTCH_geomExit (SCOTCH_Geom * const); void SCOTCH_geomData (const SCOTCH_Geom * const, SCOTCH_Num * const, double ** const); SCOTCH_Graph * SCOTCH_graphAlloc (void); int SCOTCH_graphInit (SCOTCH_Graph * const); void SCOTCH_graphExit (SCOTCH_Graph * const); void SCOTCH_graphFree (SCOTCH_Graph * const); int SCOTCH_graphLoad (SCOTCH_Graph * const, FILE * const, const SCOTCH_Num, const SCOTCH_Num); int SCOTCH_graphSave (const SCOTCH_Graph * const, FILE * const); int SCOTCH_graphBuild (SCOTCH_Graph * const, const SCOTCH_Num, const SCOTCH_Num, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num, const SCOTCH_Num * const, const SCOTCH_Num * const); int SCOTCH_graphCoarsen (const SCOTCH_Graph * const, SCOTCH_Graph * const, SCOTCH_Num * const, const SCOTCH_Num, const double); int SCOTCH_graphCoarsenBuild (const SCOTCH_Graph * const, SCOTCH_Graph * const, SCOTCH_Num * const, const SCOTCH_Num, SCOTCH_Num * const); int SCOTCH_graphColor (const SCOTCH_Graph * const, SCOTCH_Num * const, SCOTCH_Num * const, const SCOTCH_Num); SCOTCH_Num SCOTCH_graphBase (SCOTCH_Graph * const, const SCOTCH_Num baseval); int SCOTCH_graphCheck (const SCOTCH_Graph * const); void SCOTCH_graphSize (const SCOTCH_Graph * const, SCOTCH_Num * const, SCOTCH_Num * const); void SCOTCH_graphData (const SCOTCH_Graph * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num ** const, SCOTCH_Num ** const, SCOTCH_Num ** const, SCOTCH_Num ** const, SCOTCH_Num * const, SCOTCH_Num ** const, SCOTCH_Num ** const); void SCOTCH_graphStat (const SCOTCH_Graph * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, double * const, double * const, SCOTCH_Num * const, SCOTCH_Num * const, double * const, double * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, double * const, double * const); int SCOTCH_graphGeomLoadChac (SCOTCH_Graph * const, SCOTCH_Geom * const, FILE * const, FILE * const, const char * const); int SCOTCH_graphGeomLoadHabo (SCOTCH_Graph * const, SCOTCH_Geom * const, FILE * const, FILE * const, const char * const); int SCOTCH_graphGeomLoadMmkt (SCOTCH_Graph * const, SCOTCH_Geom * const, FILE * const, FILE * const, const char * const); int SCOTCH_graphGeomLoadScot (SCOTCH_Graph * const, SCOTCH_Geom * const, FILE * const, FILE * const, const char * const); int SCOTCH_graphGeomSaveChac (const SCOTCH_Graph * const, const SCOTCH_Geom * const, FILE * const, FILE * const, const char * const); int SCOTCH_graphGeomSaveMmkt (const SCOTCH_Graph * const, const SCOTCH_Geom * const, FILE * const, FILE * const, const char * const); int SCOTCH_graphGeomSaveScot (const SCOTCH_Graph * const, const SCOTCH_Geom * const, FILE * const, FILE * const, const char * const); int SCOTCH_graphMapInit (const SCOTCH_Graph * const, SCOTCH_Mapping * const, const SCOTCH_Arch * const, SCOTCH_Num * const); void SCOTCH_graphMapExit (const SCOTCH_Graph * const, SCOTCH_Mapping * const); int SCOTCH_graphMapLoad (const SCOTCH_Graph * const, const SCOTCH_Mapping * const, FILE * const); int SCOTCH_graphTabLoad (const SCOTCH_Graph * const, SCOTCH_Num * const, FILE * const); int SCOTCH_graphMapSave (const SCOTCH_Graph * const, const SCOTCH_Mapping * const, FILE * const); int SCOTCH_graphMapView (const SCOTCH_Graph * const, const SCOTCH_Mapping * const, FILE * const); int SCOTCH_graphRemapView (const SCOTCH_Graph * const, const SCOTCH_Mapping * const, const SCOTCH_Mapping * const, const double, SCOTCH_Num *, FILE * const); int SCOTCH_graphRemapViewRaw (const SCOTCH_Graph * const, const SCOTCH_Mapping * const, const SCOTCH_Mapping * const, const double, SCOTCH_Num *, FILE * const); int SCOTCH_graphMapCompute (SCOTCH_Graph * const, SCOTCH_Mapping * const, SCOTCH_Strat * const); int SCOTCH_graphMapFixedCompute (SCOTCH_Graph * const, SCOTCH_Mapping * const, SCOTCH_Strat * const); int SCOTCH_graphRemapCompute (SCOTCH_Graph * const, SCOTCH_Mapping * const, SCOTCH_Mapping * const, const double, const SCOTCH_Num *, SCOTCH_Strat * const); int SCOTCH_graphRemapFixedCompute (SCOTCH_Graph * const, SCOTCH_Mapping * const, SCOTCH_Mapping * const, const double, const SCOTCH_Num *, SCOTCH_Strat * const); int SCOTCH_graphMap (SCOTCH_Graph * const, const SCOTCH_Arch * const, SCOTCH_Strat * const, SCOTCH_Num * const); int SCOTCH_graphMapFixed (SCOTCH_Graph * const, const SCOTCH_Arch * const, SCOTCH_Strat * const, SCOTCH_Num * const); int SCOTCH_graphRemap (SCOTCH_Graph * const, const SCOTCH_Arch * const, SCOTCH_Num *, const double, const SCOTCH_Num *, SCOTCH_Strat * const, SCOTCH_Num * const); int SCOTCH_graphRemapFixed (SCOTCH_Graph * const, const SCOTCH_Arch * const, SCOTCH_Num *, const double, const SCOTCH_Num *, SCOTCH_Strat * const, SCOTCH_Num * const); int SCOTCH_graphPart (SCOTCH_Graph * const, const SCOTCH_Num, SCOTCH_Strat * const, SCOTCH_Num * const); int SCOTCH_graphPartFixed (SCOTCH_Graph * const, const SCOTCH_Num, SCOTCH_Strat * const, SCOTCH_Num * const); int SCOTCH_graphPartOvl (SCOTCH_Graph * const, const SCOTCH_Num, SCOTCH_Strat * const, SCOTCH_Num * const); int SCOTCH_graphRepart (SCOTCH_Graph * const, const SCOTCH_Num, SCOTCH_Num * const, const double, const SCOTCH_Num *, SCOTCH_Strat * const, SCOTCH_Num * const); int SCOTCH_graphRepartFixed (SCOTCH_Graph * const, const SCOTCH_Num, SCOTCH_Num * const, const double, const SCOTCH_Num *, SCOTCH_Strat * const, SCOTCH_Num * const); int SCOTCH_graphOrderInit (const SCOTCH_Graph * const, SCOTCH_Ordering * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const); void SCOTCH_graphOrderExit (const SCOTCH_Graph * const, SCOTCH_Ordering * const); int SCOTCH_graphOrderLoad (const SCOTCH_Graph * const, SCOTCH_Ordering * const, FILE * const); int SCOTCH_graphOrderSave (const SCOTCH_Graph * const, const SCOTCH_Ordering * const, FILE * const); int SCOTCH_graphOrderSaveMap (const SCOTCH_Graph * const, const SCOTCH_Ordering * const, FILE * const); int SCOTCH_graphOrderSaveTree (const SCOTCH_Graph * const, const SCOTCH_Ordering * const, FILE * const); int SCOTCH_graphOrderCompute (SCOTCH_Graph * const, SCOTCH_Ordering * const, SCOTCH_Strat * const); int SCOTCH_graphOrderComputeList (SCOTCH_Graph * const, SCOTCH_Ordering * const, const SCOTCH_Num, const SCOTCH_Num * const, SCOTCH_Strat * const); int SCOTCH_graphOrderFactor (const SCOTCH_Graph * const, const SCOTCH_Ordering * const, SCOTCH_Graph * const); int SCOTCH_graphOrderView (const SCOTCH_Graph * const, const SCOTCH_Ordering * const, FILE * const); int SCOTCH_graphOrder (SCOTCH_Graph * const, SCOTCH_Strat * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const); int SCOTCH_graphOrderList (SCOTCH_Graph * const, const SCOTCH_Num, const SCOTCH_Num * const, SCOTCH_Strat * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const); int SCOTCH_graphOrderCheck (const SCOTCH_Graph * const, const SCOTCH_Ordering * const); SCOTCH_Mapping * SCOTCH_mapAlloc (void); void SCOTCH_memFree (void * const); SCOTCH_Idx SCOTCH_memCur (void); SCOTCH_Idx SCOTCH_memMax (void); int SCOTCH_meshInit (SCOTCH_Mesh * const); void SCOTCH_meshExit (SCOTCH_Mesh * const); int SCOTCH_meshLoad (SCOTCH_Mesh * const, FILE * const, const SCOTCH_Num); int SCOTCH_meshSave (const SCOTCH_Mesh * const, FILE * const); int SCOTCH_meshBuild (SCOTCH_Mesh * const, const SCOTCH_Num, const SCOTCH_Num, const SCOTCH_Num, const SCOTCH_Num, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num, const SCOTCH_Num * const); int SCOTCH_meshCheck (const SCOTCH_Mesh * const); void SCOTCH_meshSize (const SCOTCH_Mesh * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const); void SCOTCH_meshData (const SCOTCH_Mesh * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num ** const, SCOTCH_Num ** const, SCOTCH_Num ** const, SCOTCH_Num ** const, SCOTCH_Num ** const, SCOTCH_Num * const, SCOTCH_Num ** const, SCOTCH_Num * const); void SCOTCH_meshStat (const SCOTCH_Mesh * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, double * const, double * const, SCOTCH_Num * const, SCOTCH_Num * const, double * const, double * const, SCOTCH_Num * const, SCOTCH_Num * const, double * const, double * const); int SCOTCH_meshGraph (const SCOTCH_Mesh * const, SCOTCH_Graph * const); int SCOTCH_meshGeomLoadHabo (SCOTCH_Mesh * const, SCOTCH_Geom * const, FILE * const, FILE * const, const char * const); int SCOTCH_meshGeomLoadScot (SCOTCH_Mesh * const, SCOTCH_Geom * const, FILE * const, FILE * const, const char * const); int SCOTCH_meshGeomSaveScot (const SCOTCH_Mesh * const, const SCOTCH_Geom * const, FILE * const, FILE * const, const char * const); int SCOTCH_meshOrderInit (const SCOTCH_Mesh * const, SCOTCH_Ordering * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const); void SCOTCH_meshOrderExit (const SCOTCH_Mesh * const, SCOTCH_Ordering * const); int SCOTCH_meshOrderSave (const SCOTCH_Mesh * const, const SCOTCH_Ordering * const, FILE * const); int SCOTCH_meshOrderSaveMap (const SCOTCH_Mesh * const, const SCOTCH_Ordering * const, FILE * const); int SCOTCH_meshOrderSaveTree (const SCOTCH_Mesh * const, const SCOTCH_Ordering * const, FILE * const); int SCOTCH_meshOrderCompute (SCOTCH_Mesh * const, SCOTCH_Ordering * const, SCOTCH_Strat * const); int SCOTCH_meshOrderComputeList (SCOTCH_Mesh * const, SCOTCH_Ordering * const, const SCOTCH_Num, const SCOTCH_Num * const, SCOTCH_Strat * const); int SCOTCH_meshOrder (SCOTCH_Mesh * const, SCOTCH_Strat * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const); int SCOTCH_meshOrderList (SCOTCH_Mesh * const, const SCOTCH_Num, const SCOTCH_Num * const, SCOTCH_Strat * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const); int SCOTCH_meshOrderCheck (const SCOTCH_Mesh * const, const SCOTCH_Ordering * const); int SCOTCH_numSizeof (void); SCOTCH_Ordering * SCOTCH_orderAlloc (void); void SCOTCH_randomReset (void); void SCOTCH_randomSeed (SCOTCH_Num); SCOTCH_Strat * SCOTCH_stratAlloc (void); int SCOTCH_stratInit (SCOTCH_Strat * const); void SCOTCH_stratExit (SCOTCH_Strat * const); void SCOTCH_stratFree (SCOTCH_Strat * const); int SCOTCH_stratSave (const SCOTCH_Strat * const, FILE * const); int SCOTCH_stratGraphBipart (SCOTCH_Strat * const, const char * const); int SCOTCH_stratGraphMap (SCOTCH_Strat * const, const char * const); int SCOTCH_stratGraphMapBuild (SCOTCH_Strat * const, const SCOTCH_Num, const SCOTCH_Num, const double); int SCOTCH_stratGraphClusterBuild (SCOTCH_Strat * const, const SCOTCH_Num, const SCOTCH_Num, const double, const double); int SCOTCH_stratGraphPartOvl (SCOTCH_Strat * const, const char * const); int SCOTCH_stratGraphPartOvlBuild (SCOTCH_Strat * const, const SCOTCH_Num, const SCOTCH_Num, const double); int SCOTCH_stratGraphOrder (SCOTCH_Strat * const, const char * const); int SCOTCH_stratGraphOrderBuild (SCOTCH_Strat * const, const SCOTCH_Num, const SCOTCH_Num, const double); int SCOTCH_stratMeshOrder (SCOTCH_Strat * const, const char * const); int SCOTCH_stratMeshOrderBuild (SCOTCH_Strat * const, const SCOTCH_Num, const double); void SCOTCH_version (int * const, int * const, int * const); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* SCOTCH_H */ scotch-6.0.4.dfsg/src/libscotch/graph_induce.c0000644002563400244210000004476512474554132024455 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007-2009,2011,2013-2015 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : graph_induce.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : This module handles the source graph **/ /** subgraph-making functions. **/ /** **/ /** DATES : # Version 0.0 : from : 01 dec 1992 **/ /** to 18 may 1993 **/ /** # Version 1.3 : from : 30 apr 1994 **/ /** to 18 may 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to 31 oct 1994 **/ /** # Version 3.0 : from : 07 jul 1995 **/ /** to 28 sep 1995 **/ /** # Version 3.1 : from : 28 nov 1995 **/ /** to 08 jun 1996 **/ /** # Version 3.2 : from : 07 sep 1996 **/ /** to 17 sep 1998 **/ /** # Version 4.0 : from : 28 nov 2001 **/ /** to 17 apr 2006 **/ /** # Version 5.0 : from : 14 dec 2006 **/ /** to 11 jun 2008 **/ /** # Version 5.1 : from : 01 jan 2009 **/ /** to 01 jan 2009 **/ /** # Version 6.0 : from : 29 mar 2011 **/ /** to 28 feb 2015 **/ /** **/ /** NOTES : # Several algorithms, such as the **/ /** active graph building routine of **/ /** bgraphInit2, assume that, for every **/ /** vertex, remaining edges will be kept **/ /** in the same order as in the original **/ /** graph. This must be enforced. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GRAPH #define GRAPH_INDUCE #include "module.h" #include "common.h" #include "graph.h" #include "graph_induce.h" /****************************************/ /* */ /* These routines handle source graphs. */ /* */ /****************************************/ /* This routine builds the graph induced ** by the original graph and the list of ** selected vertices. ** The induced vnumtab array is the list ** array if the original graph does not have ** a vnumtab, or the proper subset of the ** original vnumtab else. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int graphInduceList ( const Graph * restrict const orggrafptr, const VertList * restrict const indlistptr, Graph * restrict const indgrafptr) { Gnum * restrict orgindxtax; /* Based access to vertex translation array */ Gnum indvertnbr; /* Number of vertices in induced graph */ Gnum indvertnnd; Gnum indvertnum; /* Number of current vertex in induced graph */ const Gnum * restrict indvnumtax; Gnum * restrict indedgetab; /* Pointer to pre-allocated edge array */ Gnum indedgenbr; /* (Approximate) number of edges in induced graph */ const Gnum * restrict const orgverttax = orggrafptr->verttax; const Gnum * restrict const orgvendtax = orggrafptr->vendtax; indvertnbr = indlistptr->vnumnbr; memSet (indgrafptr, 0, sizeof (Graph)); /* Initialize graph fields */ indgrafptr->flagval = GRAPHFREETABS | GRAPHVERTGROUP | GRAPHEDGEGROUP; indgrafptr->baseval = orggrafptr->baseval; if (orggrafptr->velotax != NULL) { if (memAllocGroup ((void **) (void *) &indgrafptr->verttax, (size_t) ((indvertnbr + 1) * sizeof (Gnum)), &indgrafptr->vnumtax, (size_t) ( indvertnbr * sizeof (Gnum)), &indgrafptr->velotax, (size_t) ( indvertnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("graphInduceList: out of memory (1)"); return (1); /* Nothing to free because group allocation failed */ } indgrafptr->velotax -= indgrafptr->baseval; } else { if (memAllocGroup ((void **) (void *) &indgrafptr->verttax, (size_t) ((indvertnbr + 1) * sizeof (Gnum)), &indgrafptr->vnumtax, (size_t) ( indvertnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("graphInduceList: out of memory (2)"); return (1); } } indgrafptr->verttax -= indgrafptr->baseval; /* Adjust base of arrays */ indgrafptr->vnumtax -= indgrafptr->baseval; indgrafptr->vertnbr = indvertnbr; indgrafptr->vertnnd = indvertnbr + indgrafptr->baseval; indedgenbr = orggrafptr->edgenbr; /* Choose best upper bound on number of edges (avoid multiply overflow) */ if ((orggrafptr->degrmax > 0) && (indvertnbr < (indedgenbr / orggrafptr->degrmax))) indedgenbr = indvertnbr * orggrafptr->degrmax; if (orggrafptr->edlotax != NULL) /* If graph has edge weights */ indedgenbr *= 2; /* Account for edge weights */ if (memAllocGroup ((void *) &indedgetab, (size_t) (indedgenbr * sizeof (Gnum)), /* Pre-allocate space for edgetab (and edlotab) */ &orgindxtax, (size_t) (orggrafptr->vertnbr * sizeof (Gnum)), NULL) == NULL) { /* orgindxtab is at the end of the heap */ errorPrint ("graphInduceList: out of memory (3)"); graphExit (indgrafptr); return (1); } orgindxtax -= orggrafptr->baseval; memCpy (indgrafptr->vnumtax + indgrafptr->baseval, /* Copy vertex number array from list */ indlistptr->vnumtab, indvertnbr * sizeof (Gnum)); memSet (orgindxtax + orggrafptr->baseval, ~0, orggrafptr->vertnbr * sizeof (Gnum)); /* Preset index array */ indvnumtax = indgrafptr->vnumtax; for (indvertnum = indgrafptr->baseval, indvertnnd = indvertnum + indvertnbr, indedgenbr = 0; /* Fill index array */ indvertnum < indvertnnd; indvertnum ++) { Gnum orgvertnum; orgvertnum = indvnumtax[indvertnum]; orgindxtax[orgvertnum] = indvertnum; /* Mark selected vertices */ indedgenbr += orgvendtax[orgvertnum] - orgverttax[orgvertnum]; } return (graphInduce2 (orggrafptr, indgrafptr, indvertnbr, indedgenbr, indedgetab, orgindxtax)); } /* This routine builds the graph induced ** by the original graph and the vector ** of selected vertices. ** The induced vnumtab array is the list of ** selected vertices if the original graph ** does not have a vnumtab, or the proper ** subset of the original vnumtab else. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int graphInducePart ( const Graph * restrict const orggrafptr, /* Pointer to original graph */ const GraphPart * const orgparttax, /* Based array of vertex partition flags */ const Gnum indvertnbr, /* Number of vertices in selected part */ const GraphPart indpartval, /* Partition value of vertices to keep */ Graph * restrict const indgrafptr) /* Pointer to induced subgraph */ { Gnum * restrict orgindxtax; /* Based access to vertex translation array */ Gnum indvertnum; /* Number of current vertex in induced graph */ Gnum * restrict indvnumtax; Gnum * restrict indedgetab; /* Pointer to pre-allocated edge array */ Gnum indedgenbr; /* (Approximate) number of edges in induced graph */ Gnum orgvertnum; const Gnum * restrict const orgverttax = orggrafptr->verttax; const Gnum * restrict const orgvendtax = orggrafptr->vendtax; memSet (indgrafptr, 0, sizeof (Graph)); /* Initialize graph fields */ indgrafptr->flagval = GRAPHFREETABS | GRAPHVERTGROUP | GRAPHEDGEGROUP; indgrafptr->baseval = orggrafptr->baseval; if (orggrafptr->velotax != NULL) { if (memAllocGroup ((void **) (void *) &indgrafptr->verttax, (size_t) ((indvertnbr + 1) * sizeof (Gnum)), &indgrafptr->vnumtax, (size_t) ( indvertnbr * sizeof (Gnum)), &indgrafptr->velotax, (size_t) ( indvertnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("graphInducePart: out of memory (1)"); return (1); /* Nothing to free because group allocation failed */ } indgrafptr->velotax -= indgrafptr->baseval; } else { if (memAllocGroup ((void **) (void *) &indgrafptr->verttax, (size_t) ((indvertnbr + 1) * sizeof (Gnum)), &indgrafptr->vnumtax, (size_t) ( indvertnbr * sizeof (Gnum)), NULL) == NULL) { errorPrint ("graphInducePart: out of memory (2)"); return (1); } } indgrafptr->verttax -= indgrafptr->baseval; /* Adjust base of arrays */ indgrafptr->vnumtax -= indgrafptr->baseval; indgrafptr->vertnbr = indvertnbr; indgrafptr->vertnnd = indvertnbr + indgrafptr->baseval; indedgenbr = orggrafptr->edgenbr; /* Choose best upper bound on number of edges (avoid multiply overflow) */ if ((orggrafptr->degrmax > 0) && (indvertnbr < (indedgenbr / orggrafptr->degrmax))) indedgenbr = indvertnbr * orggrafptr->degrmax; if (orggrafptr->edlotax != NULL) /* If graph has edge weights */ indedgenbr *= 2; /* Account for edge weights */ if (memAllocGroup ((void *) &indedgetab, (size_t) (indedgenbr * sizeof (Gnum)), /* Pre-allocate space for edgetab (and edlotab) */ &orgindxtax, (size_t) (orggrafptr->vertnbr * sizeof (Gnum)), NULL) == NULL) { /* orgindxtab is at the end of the heap */ errorPrint ("graphInducePart: out of memory (3)"); graphExit (indgrafptr); return (1); } orgindxtax -= orggrafptr->baseval; indvnumtax = indgrafptr->vnumtax; for (orgvertnum = indvertnum = orggrafptr->baseval, indedgenbr = 0; /* Fill index array */ orgvertnum < orggrafptr->vertnnd; orgvertnum ++) { if (orgparttax[orgvertnum] == indpartval) { /* If vertex should be kept */ orgindxtax[orgvertnum] = indvertnum; /* Mark selected vertex */ indvnumtax[indvertnum] = orgvertnum; indedgenbr += orgvendtax[orgvertnum] - orgverttax[orgvertnum]; indvertnum ++; /* One more induced vertex created */ } else orgindxtax[orgvertnum] = ~0; } #ifdef SCOTCH_DEBUG_GRAPH2 if ((indvertnum - indgrafptr->baseval) != indvertnbr) { errorPrint ("graphInducePart: inconsistent data"); memFree (indedgetab); graphExit (indgrafptr); return (1); } #endif /* SCOTCH_DEBUG_GRAPH2 */ return (graphInduce2 (orggrafptr, indgrafptr, indvertnbr, indedgenbr, indedgetab, orgindxtax)); } /* This routine finalizes the building ** of the induced subgraph. ** It returns: ** - 0 : on success. ** - !0 : on error. */ static int graphInduce2 ( const Graph * restrict const orggrafptr, /* Pointer to original graph */ Graph * restrict const indgrafptr, /* Pointer to induced graph */ const Gnum indvertnbr, /* Number of vertices in induced graph */ const Gnum indedgenbr, /* (Upper bound of) number of edges in induced graph */ Gnum * const indedgetab, /* Pointer to pre-allocated edge and edge load arrays */ const Gnum * restrict const orgindxtax) /* Array of numbers of selected vertices */ { Gnum indvertnum; /* Current induced vertex number */ Gnum indvelosum; /* Overall induced vertex load */ Gnum indedlosum; /* Overall induced edge load */ Gnum indedgenum; /* Number of current induced edge */ Gnum orgvertnum; /* Number of current vertex in original graph */ Gnum orgedgenum; /* Number of current edge in original graph */ const Gnum * restrict const orgverttax = orggrafptr->verttax; const Gnum * restrict const orgvendtax = orggrafptr->vendtax; const Gnum * restrict const orgvelotax = orggrafptr->velotax; const Gnum * restrict const orgvnumtax = orggrafptr->vnumtax; const Gnum * restrict const orgedgetax = orggrafptr->edgetax; const Gnum * restrict const orgedlotax = orggrafptr->edlotax; Gnum * restrict const indverttax = indgrafptr->verttax; Gnum * restrict const indvelotax = indgrafptr->velotax; Gnum * restrict const indvnumtax = indgrafptr->vnumtax; Gnum * restrict indedgetax; Gnum * restrict indedlotax; if (orgedlotax != NULL) { memOffset ((void *) indedgetab, &indedgetax, (size_t) (indedgenbr * sizeof (Gnum)), &indedlotax, (size_t) (indedgenbr * sizeof (Gnum)), NULL); indedgetax -= indgrafptr->baseval; indedlotax -= indgrafptr->baseval; } else { indedgetax = indedgetab - indgrafptr->baseval; indedlotax = NULL; } indvelosum = (indvelotax == NULL) ? indgrafptr->vertnbr : 0; indedlosum = 0; for (indvertnum = indedgenum = indgrafptr->baseval; indvertnum < indgrafptr->vertnnd; indvertnum ++) { orgvertnum = indvnumtax[indvertnum]; indverttax[indvertnum] = indedgenum; if (indvelotax != NULL) { /* If graph has vertex weights */ indvelosum += /* Accumulate vertex loads */ indvelotax[indvertnum] = orgvelotax[orgvertnum]; } if (indedlotax != NULL) { /* If graph has edge weights */ for (orgedgenum = orgverttax[orgvertnum]; orgedgenum < orgvendtax[orgvertnum]; orgedgenum ++) { if (orgindxtax[orgedgetax[orgedgenum]] != ~0) { /* If edge should be kept */ indedlosum += indedlotax[indedgenum] = orgedlotax[orgedgenum]; indedgetax[indedgenum] = orgindxtax[orgedgetax[orgedgenum]]; indedgenum ++; } } } else { for (orgedgenum = orgverttax[orgvertnum]; orgedgenum < orgvendtax[orgvertnum]; orgedgenum ++) { if (orgindxtax[orgedgetax[orgedgenum]] != ~0) { /* If edge should be kept */ indedgetax[indedgenum] = orgindxtax[orgedgetax[orgedgenum]]; indedgenum ++; } } } } indverttax[indvertnum] = indedgenum; /* Mark end of edge array */ indgrafptr->vendtax = indgrafptr->verttax + 1; /* Use compact representation of vertex arrays */ indgrafptr->vertnbr = indvertnum - indgrafptr->baseval; indgrafptr->vertnnd = indvertnum; indgrafptr->velosum = indvelosum; indgrafptr->edgenbr = indedgenum - indgrafptr->baseval; /* Set actual number of edges */ indgrafptr->edlosum = (indedlotax != NULL) ? indedlosum : indgrafptr->edgenbr; indgrafptr->degrmax = orggrafptr->degrmax; /* Induced maximum degree is likely to be the one of the original graph */ if (orggrafptr->vnumtax != NULL) { /* Adjust vnumtax */ for (indvertnum = indgrafptr->baseval; indvertnum < indgrafptr->vertnnd; indvertnum ++) indvnumtax[indvertnum] = orgvnumtax[indvnumtax[indvertnum]]; } if (indedlotax != NULL) { /* Re-allocate arrays and delete orgindxtab */ size_t indedlooftval; /* Offset of edge load array with respect to edge array */ indedlooftval = indedlotax - indedgetax; indgrafptr->edgetax = (Gnum *) memRealloc (indedgetab, (indedlooftval + indgrafptr->edgenbr) * sizeof (Gnum)) - indgrafptr->baseval; indgrafptr->edlotax = indgrafptr->edgetax + indedlooftval; /* Use old index into old array as new index */ } else indgrafptr->edgetax = (Gnum *) memRealloc (indedgetab, indgrafptr->edgenbr * sizeof (Gnum)) - indgrafptr->baseval; #ifdef SCOTCH_DEBUG_GRAPH2 if (graphCheck (indgrafptr) != 0) { /* Check graph consistency */ errorPrint ("graphInduce2: inconsistent graph data"); graphExit (indgrafptr); return (1); } #endif /* SCOTCH_DEBUG_GRAPH2 */ return (0); } scotch-6.0.4.dfsg/src/libscotch/graph_base.c0000644002563400244210000001324112370027224024071 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : graph_base.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the graph base **/ /** changing routine. **/ /** **/ /** DATES : # Version 0.0 : from : 01 dec 1992 **/ /** to 18 may 1993 **/ /** # Version 1.3 : from : 30 apr 1994 **/ /** to 18 may 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to 31 oct 1994 **/ /** # Version 3.0 : from : 07 jul 1995 **/ /** to 28 sep 1995 **/ /** # Version 3.1 : from : 28 nov 1995 **/ /** to 08 jun 1996 **/ /** # Version 3.2 : from : 07 sep 1996 **/ /** to 15 sep 1998 **/ /** # Version 3.3 : from : 22 sep 1998 **/ /** to 31 dec 1998 **/ /** # Version 4.0 : from : 24 nov 2001 **/ /** to 22 apr 2004 **/ /** # Version 6.0 : from : 05 aug 2014 **/ /** to 05 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GRAPH #include "module.h" #include "common.h" #include "graph.h" /****************************************/ /* */ /* These routines handle source graphs. */ /* */ /****************************************/ /* This routine sets the base of the given ** graph to the given base value, and returns ** the old base value. ** It returns: ** - old base value : in all cases. */ Gnum graphBase ( Graph * const grafptr, const Gnum baseval) { Gnum baseold; /* Old base value */ Gnum baseadj; /* Base adjustment */ Gnum vertnum; Gnum edgenum; if (grafptr->baseval == baseval) /* If nothing to do */ return (baseval); baseold = grafptr->baseval; /* Record old base value */ baseadj = baseval - baseold; /* Compute adjustment */ for (vertnum = grafptr->baseval; vertnum < grafptr->vertnnd; vertnum ++) { for (edgenum = grafptr->verttax[vertnum]; edgenum < grafptr->vendtax[vertnum]; edgenum ++) grafptr->edgetax[edgenum] += baseadj; grafptr->verttax[vertnum] += baseadj; } if (grafptr->vendtax != grafptr->verttax + 1) { /* If distinct vertex end array */ for (vertnum = grafptr->baseval; vertnum < grafptr->vertnnd; vertnum ++) grafptr->vendtax[vertnum] += baseadj; } else /* If same vertex end array (of size +1) */ grafptr->verttax[grafptr->vertnnd] += baseadj; /* Adjust last entry of verttax */ grafptr->verttax -= baseadj; /* Adjust array accesses */ grafptr->vendtax -= baseadj; grafptr->edgetax -= baseadj; if (grafptr->velotax != NULL) grafptr->velotax -= baseadj; if (grafptr->vnumtax != NULL) grafptr->vnumtax -= baseadj; if (grafptr->vlbltax != NULL) grafptr->vlbltax -= baseadj; if (grafptr->edlotax != NULL) grafptr->edlotax -= baseadj; grafptr->baseval = baseval; /* Set new base value */ grafptr->vertnnd += baseadj; return (baseold); /* Return old base value */ } scotch-6.0.4.dfsg/src/Makefile0000644002563400244210000001200112413267730021317 0ustar trophimeutilisateurs du domaine## Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ## ## This file is part of the Scotch software package for static mapping, ## graph partitioning and sparse matrix ordering. ## ## This software is governed by the CeCILL-C license under French law ## and abiding by the rules of distribution of free software. You can ## use, modify and/or redistribute the software under the terms of the ## CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ## URL: "http://www.cecill.info". ## ## As a counterpart to the access to the source code and rights to copy, ## modify and redistribute granted by the license, users are provided ## only with a limited warranty and the software's author, the holder of ## the economic rights, and the successive licensors have only limited ## liability. ## ## In this respect, the user's attention is drawn to the risks associated ## with loading, using, modifying and/or developing or reproducing the ## software by the user in light of its specific status of free software, ## that may mean that it is complicated to manipulate, and that also ## therefore means that it is reserved for developers and experienced ## professionals having in-depth computer knowledge. Users are therefore ## encouraged to load and test the software's suitability as regards ## their requirements in conditions enabling the security of their ## systems and/or data to be ensured and, more generally, to use and ## operate it in the same conditions as regards security. ## ## The fact that you are presently reading this means that you have had ## knowledge of the CeCILL-C license and that you accept its terms. ## VERSION = 6 RELEASE = 0 PATCHLEVEL = 4 .PHONY : clean default install ptscotch realclean required scotch default : scotch required : Makefile.inc ../bin ../include ../lib Makefile.inc : @echo "#####################################################################" @echo "BEFORE COMPILING Scotch OR PT-Scotch, YOU SHOULD HAVE AN APPROPRIATE" @echo "Makefile.inc FILE IN THIS DIRECTORY. PLEASE LOOK INTO DIRECTORY" @echo " ./Make.inc FOR AN EXISTING Makefile.inc FILE THAT FITS YOUR NEED, OR" @echo "USE THEM AS MODELS IN CASE YOU NEED TO BUILD A NEW ONE FOR YOUR" @echo "PARTICULAR PLATFORM." @echo "#####################################################################" @echo "Then, type \"make scotch\" (default) for the sequential library" @echo "and software, or \"make ptscotch\" for the parallel library and" @echo "software." @exit 1 include Makefile.inc prefix ?= /usr/local bindir ?= $(prefix)/bin includedir ?= $(prefix)/include libdir ?= $(prefix)/lib datarootdir ?= $(prefix)/share mandir ?= $(datarootdir)/man ../bin : -$(MKDIR) ../bin ../include : -$(MKDIR) ../include ../lib : -$(MKDIR) ../lib $(bindir) : -$(MKDIR) $(bindir) $(datarootdir) : -$(MKDIR) $(datarootdir) $(includedir) : -$(MKDIR) $(includedir) $(libdir) : -$(MKDIR) $(libdir) $(mandir) : $(datarootdir) -$(MKDIR) $(mandir) $(mandir)/man1 : $(mandir) -$(MKDIR) $(mandir)/man1 scotch : required (cd libscotch ; $(MAKE) VERSION=$(VERSION) RELEASE=$(RELEASE) PATCHLEVEL=$(PATCHLEVEL) scotch && $(MAKE) install) (cd scotch ; $(MAKE) VERSION=$(VERSION) RELEASE=$(RELEASE) PATCHLEVEL=$(PATCHLEVEL) scotch && $(MAKE) install) (cd libscotchmetis ; $(MAKE) scotch && $(MAKE) install) ptscotch : required (cd libscotch ; $(MAKE) VERSION=$(VERSION) RELEASE=$(RELEASE) PATCHLEVEL=$(PATCHLEVEL) ptscotch && $(MAKE) ptinstall) (cd scotch ; $(MAKE) VERSION=$(VERSION) RELEASE=$(RELEASE) PATCHLEVEL=$(PATCHLEVEL) ptscotch && $(MAKE) ptinstall) (cd libscotchmetis ; $(MAKE) ptscotch && $(MAKE) ptinstall) check : scotch (cd check ; $(MAKE) check) ptcheck : ptscotch (cd check ; $(MAKE) ptcheck) esmumps : scotch (cd esmumps ; $(MAKE) scotch && $(MAKE) install) ptesmumps : ptscotch (cd esmumps ; $(MAKE) ptscotch && $(MAKE) ptinstall) install : required $(bindir) $(includedir) $(libdir) $(mandir)/man1 -$(CP) -f ../bin/[agm]*$(EXE) $(bindir) -$(CP) -f ../bin/d[agm]*$(EXE) $(bindir) -$(CP) -f ../include/*scotch*.h $(includedir) -$(CP) -f ../lib/*scotch*$(LIB) $(libdir) -$(CP) -Rf ../man/* $(mandir) clean : required (cd libscotch ; $(MAKE) clean) (cd scotch ; $(MAKE) clean) (cd libscotchmetis ; $(MAKE) clean) (cd check ; $(MAKE) clean) (cd esmumps ; $(MAKE) clean) realclean : required (cd libscotch ; $(MAKE) realclean) (cd scotch ; $(MAKE) realclean) (cd libscotchmetis ; $(MAKE) realclean) (cd check ; $(MAKE) realclean) (cd esmumps ; $(MAKE) realclean) -$(RM) ../bin/* ../include/* ../lib/* scotch-6.0.4.dfsg/src/check/0000755002563400244210000000000012500613457020740 5ustar trophimeutilisateurs du domainescotch-6.0.4.dfsg/src/check/test_scotch_graph_part_ovl.c0000644002563400244210000002021112412034737026511 0ustar trophimeutilisateurs du domaine/* Copyright 2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : test_scotch_graph_part_ovl.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module tests the sequential **/ /** graph partitioning with overlap **/ /** routine. **/ /** **/ /** DATES : # Version 6.0 : from : 20 sep 2014 **/ /** to 20 sep 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #include #if (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) #include #endif /* (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) */ #include #include #include "scotch.h" /*********************/ /* */ /* The main routine. */ /* */ /*********************/ int main ( int argc, char * argv[]) { SCOTCH_Graph grafdat; SCOTCH_Strat stradat; SCOTCH_Num baseval; SCOTCH_Num partnbr; SCOTCH_Num partnum; SCOTCH_Num * restrict parttax; SCOTCH_Num vertnbr; SCOTCH_Num vertnum; SCOTCH_Num * verttab; SCOTCH_Num * vendtab; SCOTCH_Num * velotab; SCOTCH_Num * vlbltab; SCOTCH_Num * edgetax; SCOTCH_Num * restrict flagtab; SCOTCH_Num * restrict loadtab; SCOTCH_Num loadmin; SCOTCH_Num loadmax; SCOTCH_Num loadsum; double loadavg; FILE * fileptr; SCOTCH_errorProg (argv[0]); if ((argc < 4) || (argc > 5)) { SCOTCH_errorPrint ("main: usage is \"%s []\"\n", argv[0]); exit (1); } if ((partnbr = (SCOTCH_Num) atoi (argv[1])) < 1) { SCOTCH_errorPrint ("main: invalid number of parts (\"%s\")", argv[1]); return (1); } if (SCOTCH_stratInit (&stradat) != 0) { SCOTCH_errorPrint ("main: cannot initialize strategy"); return (1); } if (argc == 5) { if (SCOTCH_stratGraphPartOvl (&stradat, argv[4]) != 0) { SCOTCH_errorPrint ("main: invalid user-provided strategy"); return (1); } } if (SCOTCH_graphInit (&grafdat) != 0) { SCOTCH_errorPrint ("main: cannot initialize graph"); return (1); } if ((fileptr = fopen (argv[2], "r")) == NULL) { SCOTCH_errorPrint ("main: cannot open file (1)"); return (1); } if (SCOTCH_graphLoad (&grafdat, fileptr, -1, 0) != 0) { SCOTCH_errorPrint ("main: cannot load graph"); return (1); } fclose (fileptr); SCOTCH_graphData (&grafdat, &baseval, &vertnbr, &verttab, &vendtab, &velotab, &vlbltab, NULL, &edgetax, NULL); if (((parttax = malloc (vertnbr * sizeof (SCOTCH_Num))) == NULL) || ((flagtab = malloc (partnbr * sizeof (SCOTCH_Num))) == NULL) || ((loadtab = malloc (partnbr * sizeof (SCOTCH_Num))) == NULL)) { SCOTCH_errorPrint ("main: out of memory"); return (1); } if (SCOTCH_graphPartOvl (&grafdat, partnbr, &stradat, parttax) != 0) { /* Parttax is not based yet */ SCOTCH_errorPrint ("main: cannot compute mapping"); return (1); } edgetax -= baseval; parttax -= baseval; memset (loadtab, 0, partnbr * sizeof (SCOTCH_Num)); /* Part loads set to 0 */ memset (flagtab, ~0, partnbr * sizeof (SCOTCH_Num)); /* Flags set to invalid vertex number */ for (vertnum = 0; vertnum < vertnbr; vertnum ++) { SCOTCH_Num veloval; SCOTCH_Num partval; veloval = (velotab == NULL) ? 1 : velotab[vertnum]; partval = parttax[vertnum + baseval]; /* vertnum is not based */ if (partval >= 0) /* If vertex belongs to one part only */ loadtab[partval] += veloval; /* Add vertex load to this part */ else { /* Vertex belongs to several parts */ SCOTCH_Num edgenum; for (edgenum = verttab[vertnum]; edgenum < vendtab[vertnum]; edgenum ++) { SCOTCH_Num vertend; SCOTCH_Num partend; vertend = edgetax[edgenum]; partend = parttax[vertend]; /* vertend is based */ if (partend < 0) /* If neighbor has no identifiable part */ continue; if (flagtab[partend] == vertnum) /* If neighbor part already accounted for, skip it */ continue; loadtab[partend] += veloval; /* Vertex load contributes to this part */ flagtab[partend] = vertnum; /* Record a contribution has been made */ } } } loadsum = loadmax = 0; loadmin = SCOTCH_NUMMAX; for (partnum = 0; partnum < partnbr; partnum ++) { loadsum += loadtab[partnum]; if (loadtab[partnum] > loadmax) loadmax = loadtab[partnum]; if (loadtab[partnum] < loadmin) loadmin = loadtab[partnum]; printf ("M\tCompload[%02ld]\t%ld\n", (long) partnum, (long) loadtab[partnum]); } loadavg = (double) loadsum / (double) partnbr; printf ("M\tCompLoadAvg\t%g\n", (double) loadavg); printf ("M\tCompLoadMax/Avg\t%g\n", (double) loadmax / loadavg); if ((fileptr = fopen (argv[3], "w")) == NULL) { SCOTCH_errorPrint ("main: cannot open file (2)"); return (1); } if (fprintf (fileptr, "%ld\n", (long) vertnbr) == EOF) { SCOTCH_errorPrint ("main: bad output (1)"); return (1); } for (vertnum = 0; vertnum < vertnbr; vertnum ++) { if (fprintf (fileptr, "%ld\t%ld\n", (long) ((vlbltab == NULL) ? vertnum : vlbltab[vertnum]), (long) parttax[vertnum + baseval]) == EOF) { SCOTCH_errorPrint ("main: bad output (2)"); return (1); } } fclose (fileptr); free (loadtab); free (flagtab); free (parttax + baseval); SCOTCH_stratExit (&stradat); SCOTCH_graphExit (&grafdat); exit (0); } scotch-6.0.4.dfsg/src/check/test_scotch_dgraph_redist.c0000644002563400244210000001522512500613420026320 0ustar trophimeutilisateurs du domaine/* Copyright 2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : test_scotch_dgraph_redist.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module tests the operation of **/ /** the SCOTCH_dgraphBand() routine. **/ /** **/ /** DATES : # Version 6.0 : from : 21 feb 2012 **/ /** to 02 mar 2015 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #include #include #if (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) #include #endif /* (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) */ #include #include #include #include #include #include "ptscotch.h" #define errorProg SCOTCH_errorProg #define errorPrint SCOTCH_errorPrint /*********************/ /* */ /* The main routine. */ /* */ /*********************/ int main ( int argc, char * argv[]) { MPI_Comm proccomm; int procglbnbr; /* Number of processes sharing graph data */ int proclocnum; /* Number of this process */ SCOTCH_Num vertglbnbr; SCOTCH_Num vertlocnbr; SCOTCH_Num vertlocnum; SCOTCH_Num * partloctab; SCOTCH_Num baseval; SCOTCH_Dgraph srcgrafdat; SCOTCH_Dgraph dstgrafdat; FILE * file; int procnum; #ifdef SCOTCH_PTHREAD int thrdlvlreqval; int thrdlvlproval; #endif /* SCOTCH_PTHREAD */ errorProg (argv[0]); #ifdef SCOTCH_PTHREAD thrdlvlreqval = MPI_THREAD_MULTIPLE; if (MPI_Init_thread (&argc, &argv, thrdlvlreqval, &thrdlvlproval) != MPI_SUCCESS) errorPrint ("main: Cannot initialize (1)"); if (thrdlvlreqval > thrdlvlproval) errorPrint ("main: MPI implementation is not thread-safe: recompile without SCOTCH_PTHREAD"); #else /* SCOTCH_PTHREAD */ if (MPI_Init (&argc, &argv) != MPI_SUCCESS) errorPrint ("main: Cannot initialize (2)"); #endif /* SCOTCH_PTHREAD */ if (argc != 2) { errorPrint ("main: invalid number of parameters"); exit (1); } proccomm = MPI_COMM_WORLD; MPI_Comm_size (proccomm, &procglbnbr); /* Get communicator data */ MPI_Comm_rank (proccomm, &proclocnum); fprintf (stderr, "Proc %2d of %2d, pid %d\n", proclocnum, procglbnbr, getpid ()); #ifdef SCOTCH_CHECK_NOAUTO if (proclocnum == 0) { /* Synchronize on keybord input */ char c; printf ("Waiting for key press...\n"); scanf ("%c", &c); } #endif /* SCOTCH_CHECK_NOAUTO */ if (MPI_Barrier (proccomm) != MPI_SUCCESS) { /* Synchronize for debug */ errorPrint ("main: cannot communicate"); return (1); } if (SCOTCH_dgraphInit (&srcgrafdat, proccomm) != 0) { /* Initialize source graph */ errorPrint ("main: cannot initialize source graph"); return (1); } if (SCOTCH_dgraphInit (&dstgrafdat, proccomm) != 0) { /* Initialize destination graph */ errorPrint ("main: cannot initialize destination graph"); return (1); } file = NULL; if ((proclocnum == 0) && ((file = fopen (argv[1], "r")) == NULL)) { errorPrint ("main: cannot open graph file"); return (1); } if (SCOTCH_dgraphLoad (&srcgrafdat, file, -1, 0) != 0) { errorPrint ("main: cannot load source graph"); return (1); } if (file != NULL) fclose (file); if (SCOTCH_dgraphCheck (&srcgrafdat) != 0) { errorPrint ("main: invalid source graph"); return (1); } if (MPI_Barrier (proccomm) != MPI_SUCCESS) { /* Synchronize for debug */ errorPrint ("main: cannot communicate"); return (1); } SCOTCH_dgraphData (&srcgrafdat, NULL, &vertglbnbr, &vertlocnbr, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if ((partloctab = malloc (vertlocnbr * sizeof (SCOTCH_Num))) == NULL) { errorPrint ("main: cannot allocate frontier array"); return (1); } for (vertlocnum = 0; vertlocnum < vertlocnbr; vertlocnum ++) /* Create packs of 3 vertices each */ partloctab[vertlocnum] = (vertlocnum / 3) % procglbnbr; if (SCOTCH_dgraphRedist (&srcgrafdat, partloctab, NULL, -1, -1, &dstgrafdat) != 0) { errorPrint ("main: cannot compute redistributed graph"); return (1); } SCOTCH_dgraphExit (&dstgrafdat); SCOTCH_dgraphExit (&srcgrafdat); free (partloctab); MPI_Finalize (); exit (0); } scotch-6.0.4.dfsg/src/check/test_strat_par.c0000644002563400244210000001125112412034737024142 0ustar trophimeutilisateurs du domaine/* Copyright 2012,2013 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : test_strat_seq.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module tests the sequential **/ /** strategy building routines. **/ /** **/ /** DATES : # Version 6.0 : from : 08 jan 2012 **/ /** to 11 oct 2013 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #include #include #if (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) #include #endif /* (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) */ #include #include "ptscotch.h" /*********************/ /* */ /* The main routine. */ /* */ /*********************/ int main ( int argc, char * argv[]) { SCOTCH_Strat stradat; SCOTCH_errorProg (argv[0]); printf ("Parallel mapping strategy, SCOTCH_STRATDEFAULT\n"); SCOTCH_stratInit (&stradat); SCOTCH_stratDgraphMapBuild (&stradat, SCOTCH_STRATDEFAULT, 16, 16, 0.03); SCOTCH_stratExit (&stradat); printf ("Parallel mapping strategy, SCOTCH_STRATRECURSIVE\n"); SCOTCH_stratInit (&stradat); SCOTCH_stratDgraphMapBuild (&stradat, SCOTCH_STRATRECURSIVE, 16, 16, 0.03); SCOTCH_stratExit (&stradat); printf ("Parallel ordering strategy, SCOTCH_STRATDEFAULT\n"); SCOTCH_stratInit (&stradat); SCOTCH_stratDgraphOrderBuild (&stradat, SCOTCH_STRATDEFAULT, 1, 0, 0.2); SCOTCH_stratExit (&stradat); printf ("Parallel ordering strategy, SCOTCH_STRATLEVELMAX\n"); SCOTCH_stratInit (&stradat); SCOTCH_stratDgraphOrderBuild (&stradat, SCOTCH_STRATLEVELMAX, 1, 3, 0.2); SCOTCH_stratExit (&stradat); printf ("Parallel ordering strategy, SCOTCH_STRATLEVELMIN\n"); SCOTCH_stratInit (&stradat); SCOTCH_stratDgraphOrderBuild (&stradat, SCOTCH_STRATLEVELMIN, 1, 3, 0.2); SCOTCH_stratExit (&stradat); printf ("Parallel ordering strategy, SCOTCH_STRATLEVELMAX | SCOTCH_STRATLEVELMIN\n"); SCOTCH_stratInit (&stradat); SCOTCH_stratDgraphOrderBuild (&stradat, SCOTCH_STRATLEVELMAX | SCOTCH_STRATLEVELMIN, 1, 3, 0.2); SCOTCH_stratExit (&stradat); printf ("Parallel ordering strategy, SCOTCH_STRATLEAFSIMPLE\n"); SCOTCH_stratInit (&stradat); SCOTCH_stratDgraphOrderBuild (&stradat, SCOTCH_STRATLEAFSIMPLE, 1, 0, 0.2); SCOTCH_stratExit (&stradat); printf ("Parallel ordering strategy, SCOTCH_STRATSEPASIMPLE\n"); SCOTCH_stratInit (&stradat); SCOTCH_stratDgraphOrderBuild (&stradat, SCOTCH_STRATSEPASIMPLE, 1, 0, 0.2); SCOTCH_stratExit (&stradat); return (0); } scotch-6.0.4.dfsg/src/check/test_scotch_graph_order.c0000644002563400244210000001455512412034737026014 0ustar trophimeutilisateurs du domaine/* Copyright 2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : test_scotch_graph_order.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module tests the operation of **/ /** the SCOTCH_graphOrderCompute*() **/ /** routines. **/ /** **/ /** DATES : # Version 6.0 : from : 05 aug 2014 **/ /** to 29 aug 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #include #if (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) #include #endif /* (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) */ #include #include #include "scotch.h" /*********************/ /* */ /* The main routine. */ /* */ /*********************/ int main ( int argc, char * argv[]) { FILE * fileptr; SCOTCH_Graph grafdat; SCOTCH_Ordering ordedat; SCOTCH_Strat stradat; SCOTCH_Num baseval; SCOTCH_Num vertnbr; SCOTCH_Num vertnum; SCOTCH_Num listnbr; SCOTCH_Num listnum; SCOTCH_Num * listtab; SCOTCH_errorProg (argv[0]); if (SCOTCH_graphInit (&grafdat) != 0) { /* Initialize source graph */ SCOTCH_errorPrint ("main: cannot initialize graph"); return (1); } if ((fileptr = fopen (argv[1], "r")) == NULL) { SCOTCH_errorPrint ("main: cannot open file (1)"); return (1); } if (SCOTCH_graphLoad (&grafdat, fileptr, -1, 0) != 0) { /* Read source graph */ SCOTCH_errorPrint ("main: cannot load graph"); return (1); } fclose (fileptr); SCOTCH_graphData (&grafdat, &baseval, &vertnbr, NULL, NULL, NULL, NULL, NULL, NULL, NULL); listnbr = (vertnbr + 1) / 2; /* Only keep half of the vertices in induced graph */ if ((listtab = malloc (listnbr * sizeof (SCOTCH_Num))) == NULL) { SCOTCH_errorPrint ("main: out of memory (1)"); return (1); } for (listnum = 0, vertnum = baseval + (listnbr / 4); /* Keep only middle half of the vertices */ listnum < listnbr; listnum ++, vertnum ++) listtab[listnum] = vertnum; if ((fileptr = tmpfile ()) == NULL) { /* Open temporary file for resulting output */ SCOTCH_errorPrint ("main: cannot open file (2)"); return (1); } if (SCOTCH_stratInit (&stradat) != 0) { /* Initialize ordering strategy */ SCOTCH_errorPrint ("main: cannot initialize strategy"); return (1); } if (SCOTCH_graphOrderInit (&grafdat, &ordedat, NULL, NULL, NULL, NULL, NULL) != 0) { /* Initialize ordering */ SCOTCH_errorPrint ("main: cannot initialize ordering (1)"); return (1); } if (SCOTCH_graphOrderCompute (&grafdat, &ordedat, &stradat) != 0) { SCOTCH_errorPrint ("main: cannot order graph"); return (1); } if (SCOTCH_graphOrderCheck (&grafdat, &ordedat) != 0) { SCOTCH_errorPrint ("main: invalid ordering (1)"); return (1); } SCOTCH_graphOrderSave (&grafdat, &ordedat, fileptr); /* Test ordering data output routines */ SCOTCH_graphOrderSaveMap (&grafdat, &ordedat, fileptr); SCOTCH_graphOrderSaveTree (&grafdat, &ordedat, fileptr); SCOTCH_graphOrderExit (&grafdat, &ordedat); /* Free computed ordering */ if (SCOTCH_graphOrderInit (&grafdat, &ordedat, NULL, NULL, NULL, NULL, NULL) != 0) { /* Initialize ordering again */ SCOTCH_errorPrint ("main: cannot initialize ordering (2)"); return (1); } if (SCOTCH_graphOrderComputeList (&grafdat, &ordedat, listnbr, listtab, &stradat) != 0) { SCOTCH_errorPrint ("main: cannot order induced graph"); return (1); } if (SCOTCH_graphOrderCheck (&grafdat, &ordedat) != 0) { SCOTCH_errorPrint ("main: invalid ordering (2)"); return (1); } SCOTCH_graphOrderSave (&grafdat, &ordedat, fileptr); /* Test ordering data output routines */ SCOTCH_graphOrderSaveMap (&grafdat, &ordedat, fileptr); SCOTCH_graphOrderSaveTree (&grafdat, &ordedat, fileptr); free (listtab); SCOTCH_stratExit (&stradat); SCOTCH_graphOrderExit (&grafdat, &ordedat); SCOTCH_graphExit (&grafdat); return (0); } scotch-6.0.4.dfsg/src/check/test_scotch_arch.c0000644002563400244210000001120012353354670024422 0ustar trophimeutilisateurs du domaine/* Copyright 2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : test_scotch_arch.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module tests the operation of **/ /** the SCOTCH_arch*() routines. **/ /** **/ /** DATES : # Version 6.0 : from : 25 jun 2014 **/ /** to 25 jun 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #include #if (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) #include #endif /* (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) */ #include #include #include "scotch.h" int SCOTCH_Arch archdat; /*********************/ /* */ /* The main routine. */ /* */ /*********************/ int main ( int argc, char * argv[]) { SCOTCH_Num baseval; SCOTCH_Num vertnbr; SCOTCH_Num vertnum; SCOTCH_Num colonbr; SCOTCH_Num colonum; SCOTCH_Num * colotab; SCOTCH_Num * cnbrtab; SCOTCH_errorProg (argv[0]); if (SCOTCH_graphInit (&grafdat) != 0) { /* Initialize source graph */ SCOTCH_errorPrint ("main: cannot initialize graph"); return (1); } if ((fileptr = fopen (argv[1], "r")) == NULL) { SCOTCH_errorPrint ("main: cannot open file"); return (1); } if (SCOTCH_graphLoad (&grafdat, fileptr, -1, 0) != 0) { /* Read source graph */ SCOTCH_errorPrint ("main: cannot load graph"); return (1); } fclose (fileptr); SCOTCH_graphSize (&grafdat, &vertnbr, NULL); if ((colotab = malloc (vertnbr * sizeof (SCOTCH_Num))) == NULL) { SCOTCH_errorPrint ("main: out of memory (1)"); return (1); } if ((cnbrtab = malloc (vertnbr * sizeof (SCOTCH_Num))) == NULL) { SCOTCH_errorPrint ("main: out of memory (1)"); return (1); } memset (cnbrtab, 0, vertnbr * sizeof (SCOTCH_Num)); if (SCOTCH_graphColor (&grafdat, colotab, &colonbr, 0) != 0) { SCOTCH_errorPrint ("main: cannot color graph"); return (1); } printf ("Number of colors: %ld\n", (long) colonbr); for (vertnum = 0; vertnum < vertnbr; vertnum ++) /* Sum-up color histogram */ cnbrtab[colotab[vertnum]] ++; for (colonum = 0; colonum < colonbr; colonum ++) printf ("Color %5ld: %ld\n", (long) colonum, (long) cnbrtab[colonum]); free (cnbrtab); free (colotab); SCOTCH_graphExit (&grafdat); return (0); } scotch-6.0.4.dfsg/src/check/test_common_thread.c0000644002563400244210000001614712474563610025000 0ustar trophimeutilisateurs du domaine/* Copyright 2012,2014,2015 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : test_common_thread.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module tests the sequential **/ /** strategy building routines. **/ /** **/ /** DATES : # Version 6.0 : from : 04 nov 2012 **/ /** to 01 mar 2015 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE 600 #endif /* _XOPEN_SOURCE */ #ifndef __USE_XOPEN2K #define __USE_XOPEN2K /* For POSIX pthread_barrier_t */ #endif /* __USE_XOPEN2K */ #include #if ((defined COMMON_PTHREAD) || (defined SCOTCH_PTHREAD)) #include #endif /* ((defined COMMON_PTHREAD) || (defined SCOTCH_PTHREAD)) */ #include "../libscotch/module.h" #include "../libscotch/common.h" #define COMPVAL(n) (((n) * ((n) + 1)) / 2) /* ** The type and structure definitions. */ /*+ The block data structure +*/ typedef struct TestThreadGroup_ { ThreadGroupHeader thrddat; /*+ Thread handling data +*/ int redusum; /*+ Value to compare reduction to +*/ } TestThreadGroup; /*+ The thread-specific data block. +*/ typedef struct TestThread_ { ThreadHeader thrddat; /*+ Thread management data +*/ int reduval; /*+ Value to reduce +*/ int scanval; /*+ Value for scan +*/ int dummval; /*+ Dummy value for scan +*/ } TestThread; /*************************/ /* */ /* The threaded routine. */ /* */ /*************************/ #if ((defined COMMON_PTHREAD) || (defined SCOTCH_PTHREAD)) static void testReduce ( TestThread * restrict const tlocptr, /* Pointer to local thread */ void * restrict const vlocptr, /* Pointer to local value */ void * restrict const vremptr) /* Pointer to remote value */ { TestThread * restrict const tremptr = (TestThread *) vremptr; tlocptr->reduval += tremptr->reduval; } static void testScan ( TestThread * restrict const tlocptr, /* Pointer to local thread */ int * restrict const vlocptr, /* Pointer to local value */ int * restrict const vremptr, /* Pointer to remote value */ const int phasval) /* Phase index */ { vlocptr[1 - phasval] = vlocptr[phasval] + ((vremptr == NULL) ? 0 : vremptr[phasval]); } static int testThreads ( TestThread * restrict thrdptr) { TestThreadGroup * restrict const grouptr = (TestThreadGroup *) (thrdptr->thrddat.grouptr); const int thrdnbr = grouptr->thrddat.thrdnbr; const int thrdnum = thrdptr->thrddat.thrdnum; int o; printf ("%d: running\n", thrdnum); o = 0; if (thrdnum == 0) printf ("Performing reduction\n"); threadBarrier (thrdptr); thrdptr->reduval = 1 + thrdptr->thrddat.thrdnum; threadReduce (thrdptr, thrdptr, (ThreadReduceFunc) testReduce, 0); if ((thrdnum == 0) && /* Test reduction result on thread 0 */ (thrdptr->reduval != grouptr->redusum)) { printf ("0: invalid reduction operator\n"); o = 1; } if (thrdnum == 0) printf ("Performing scan\n"); threadBarrier (thrdptr); thrdptr->scanval = 1 + thrdptr->thrddat.thrdnum; threadScan (thrdptr, &thrdptr->scanval, (ThreadScanFunc) testScan); if (thrdptr->scanval != COMPVAL (thrdnum + 1)) { printf ("%d: invalid scan operator\n", thrdnum); o = 1; } threadBarrier (thrdptr); return (o); } #endif /* ((defined COMMON_PTHREAD) || (defined SCOTCH_PTHREAD)) */ /*********************/ /* */ /* The main routine. */ /* */ /*********************/ int main ( int argc, char * argv[]) { TestThreadGroup groudat; #if ((defined COMMON_PTHREAD) || (defined SCOTCH_PTHREAD)) TestThread * restrict thrdtab; int thrdnbr; #endif /* ((defined COMMON_PTHREAD) || (defined SCOTCH_PTHREAD)) */ SCOTCH_errorProg (argv[0]); #if ((defined COMMON_PTHREAD) || (defined SCOTCH_PTHREAD)) thrdnbr = SCOTCH_PTHREAD_NUMBER; groudat.redusum = COMPVAL (thrdnbr); if ((thrdtab = malloc (thrdnbr * sizeof (TestThread))) == NULL) { errorPrint ("main: out of memory"); return (1); } if (threadLaunch (&groudat, thrdtab, sizeof (TestThread), (ThreadLaunchStartFunc) testThreads, (ThreadLaunchJoinFunc) NULL, thrdnbr, THREADCANBARRIER | THREADCANREDUCE | THREADCANSCAN) != 0) { errorPrint ("main: cannot launch or run threads"); return (1); } free (thrdtab); #else /* ((defined COMMON_PTHREAD) || (defined SCOTCH_PTHREAD)) */ printf ("Scotch not compiled with either COMMON_PTHREAD or SCOTCH_PTHREAD\n"); #endif /* ((defined COMMON_PTHREAD) || (defined SCOTCH_PTHREAD)) */ return (0); } scotch-6.0.4.dfsg/src/check/Makefile0000644002563400244210000001732012474563532022413 0ustar trophimeutilisateurs du domaine## Copyright 2011,2012,2014,2015 IPB, Universite de Bordeaux, INRIA & CNRS ## ## This file is part of the Scotch software package for static mapping, ## graph partitioning and sparse matrix ordering. ## ## This software is governed by the CeCILL-C license under French law ## and abiding by the rules of distribution of free software. You can ## use, modify and/or redistribute the software under the terms of the ## CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ## URL: "http://www.cecill.info". ## ## As a counterpart to the access to the source code and rights to copy, ## modify and redistribute granted by the license, users are provided ## only with a limited warranty and the software's author, the holder of ## the economic rights, and the successive licensors have only limited ## liability. ## ## In this respect, the user's attention is drawn to the risks associated ## with loading, using, modifying and/or developing or reproducing the ## software by the user in light of its specific status of free software, ## that may mean that it is complicated to manipulate, and that also ## therefore means that it is reserved for developers and experienced ## professionals having in-depth computer knowledge. Users are therefore ## encouraged to load and test the software's suitability as regards ## their requirements in conditions enabling the security of their ## systems and/or data to be ensured and, more generally, to use and ## operate it in the same conditions as regards security. ## ## The fact that you are presently reading this means that you have had ## knowledge of the CeCILL-C license and that you accept its terms. ## SCOTCHINCLUDEDIR = ../../include SCOTCHLIBDIR = ../../lib SCOTCHBINDIR = ../../bin LIBPTSCOTCH = -lptscotch -lscotch -lptscotcherrexit LIBSCOTCH = -lscotch -lscotcherrexit DEPPTSCOTCH = $(SCOTCHLIBDIR)/libptscotch$(LIB) DEPSCOTCH = $(SCOTCHLIBDIR)/libscotch$(LIB) EXECS = EXECP = mpirun -n 4 ## ## General inference rules. ## include ../Makefile.inc %$(OBJ) : %.c $(CC) $(CFLAGS) $(CLIBFLAGS) -I$(SCOTCHINCLUDEDIR) -c $(<) -o $(@) %$(EXE) : %.c $(CC) $(CFLAGS) -I$(SCOTCHINCLUDEDIR) -L$(SCOTCHLIBDIR) $(<) -o $(@) $(SCOTCHLIBS) $(LDFLAGS) ## ## Project rules. ## .PHONY : check ptcheck clean realclean check : realclean $(MAKE) CC="$(CCS)" CCD="$(CCS)" SCOTCHLIBS="$(LIBSCOTCH)" $(CHECKSCOTCH) ptcheck : realclean $(MAKE) CFLAGS="$(CFLAGS) -DSCOTCH_PTSCOTCH" CC="$(CCP)" SCOTCHLIBS="$(LIBPTSCOTCH)" $(CHECKPTSCOTCH) clean : -$(RM) *~ *$(OBJ) realclean : clean -$(RM) \ test_common_random \ test_common_thread \ test_scotch_graph_coarsen \ test_scotch_graph_coarsen_build \ test_scotch_graph_color \ test_scotch_graph_map \ test_scotch_graph_map_copy \ test_scotch_graph_order \ test_scotch_graph_part_ovl \ test_scotch_dgraph_band \ test_scotch_dgraph_check \ test_scotch_dgraph_coarsen \ test_scotch_dgraph_grow \ test_scotch_dgraph_redist \ test_strat_par \ test_strat_seq ## ## Test cases dependencies. ## CHECKSCOTCH = check_common_random \ check_common_thread \ check_strat_seq \ check_scotch_graph_coarsen \ check_scotch_graph_coarsen_build \ check_scotch_graph_color \ check_scotch_graph_map \ check_scotch_graph_map_copy \ check_scotch_graph_order \ check_scotch_graph_part_ovl \ check_prog_gord \ check_prog_gpart_remap CHECKPTSCOTCH = check_strat_par \ check_scotch_dgraph_check \ check_scotch_dgraph_band \ check_scotch_dgraph_coarsen \ check_scotch_dgraph_grow \ check_scotch_dgraph_redist \ ## ## Todo list. ## check_common_random : test_common_random $(EXECS) ./test_common_random /tmp/rand.dat 0 $(EXECS) ./test_common_random /tmp/rand.dat 1 test_common_random : test_common_random.c \ $(SCOTCHLIBDIR)/libscotch$(LIB) ## check_common_thread : test_common_thread $(EXECS) ./test_common_thread test_common_thread : test_common_thread.c \ $(SCOTCHLIBDIR)/libscotch$(LIB) ## check_dgraph_fold_comm : test_dgraph_fold_comm $(EXECS) ./test_dgraph_fold_comm data/dgraph_fold_comm_1.txt test_dgraph_fold_comm : test_dgraph_fold_comm.c ## check_scotch_dgraph_redist : test_scotch_dgraph_redist $(EXECP) ./test_scotch_dgraph_redist data/bump.grf test_scotch_dgraph_redist : test_scotch_dgraph_redist.c ## check_prog_gord : $(EXECS) $(SCOTCHBINDIR)/gord data/bump.grf /dev/null -vt $(EXECS) $(SCOTCHBINDIR)/gord data/bump_b1.grf /dev/null -vt ## check_prog_gpart_remap : $(EXECS) $(SCOTCHBINDIR)/gpart 32 data/bump_imbal_32.grf /dev/null -rodata/bump_old.map -vmt ## check_scotch_graph_coarsen : test_scotch_graph_coarsen $(EXECS) ./test_scotch_graph_coarsen data/bump_b1.grf test_scotch_graph_coarsen : test_scotch_graph_coarsen.c \ $(SCOTCHLIBDIR)/libscotch$(LIB) ## check_scotch_graph_coarsen_build : test_scotch_graph_coarsen_build $(EXECS) ./test_scotch_graph_coarsen_build data/bump.grf $(EXECS) ./test_scotch_graph_coarsen_build data/bump_b1.grf test_scotch_graph_coarsen_build : test_scotch_graph_coarsen_build.c \ $(SCOTCHLIBDIR)/libscotch$(LIB) ## check_scotch_graph_color : test_scotch_graph_color $(EXECS) ./test_scotch_graph_color data/bump.grf test_scotch_graph_color : test_scotch_graph_color.c \ $(SCOTCHLIBDIR)/libscotch$(LIB) ## check_scotch_graph_map : test_scotch_graph_map $(EXECS) ./test_scotch_graph_map data/m4x4.grf $(EXECS) ./test_scotch_graph_map data/m4x4_b1.grf $(EXECS) ./test_scotch_graph_map data/m16x16.grf $(EXECS) ./test_scotch_graph_map data/m16x16_b1.grf test_scotch_graph_map : test_scotch_graph_map.c \ $(SCOTCHLIBDIR)/libscotch$(LIB) ## check_scotch_graph_map_copy : test_scotch_graph_map_copy $(EXECS) ./test_scotch_graph_map_copy data/bump_b1.grf test_scotch_graph_map_copy : test_scotch_graph_map_copy.c \ $(SCOTCHLIBDIR)/libscotch$(LIB) ## check_scotch_graph_order : test_scotch_graph_order $(EXECS) ./test_scotch_graph_order data/bump.grf $(EXECS) ./test_scotch_graph_order data/bump_b1.grf test_scotch_graph_order : test_scotch_graph_order.c \ $(SCOTCHLIBDIR)/libscotch$(LIB) ## check_scotch_graph_part_ovl : test_scotch_graph_part_ovl $(EXECS) ./test_scotch_graph_part_ovl 4 data/m16x16.grf /dev/null $(EXECS) ./test_scotch_graph_part_ovl 4 data/m16x16_b1.grf /dev/null test_scotch_graph_part_ovl : test_scotch_graph_part_ovl.c \ $(SCOTCHLIBDIR)/libscotch$(LIB) ## check_strat_seq : test_strat_seq $(EXECS) ./test_strat_seq test_strat_seq : test_strat_seq.c \ $(SCOTCHLIBDIR)/libscotch$(LIB) ## check_strat_par : test_strat_par $(EXECS) ./test_strat_par test_strat_par : test_strat_par.c \ $(SCOTCHLIBDIR)/libptscotch$(LIB) ## check_scotch_dgraph_band : test_scotch_dgraph_band $(EXECP) ./test_scotch_dgraph_band data/bump_b1.grf test_scotch_dgraph_band : test_scotch_dgraph_band.c \ $(SCOTCHLIBDIR)/libptscotch$(LIB) ## check_scotch_dgraph_coarsen : test_scotch_dgraph_coarsen $(EXECP) ./test_scotch_dgraph_coarsen data/bump.grf $(EXECP) ./test_scotch_dgraph_coarsen data/bump_b1.grf test_scotch_dgraph_coarsen : test_scotch_dgraph_coarsen.c \ $(SCOTCHLIBDIR)/libptscotch$(LIB) ## check_scotch_dgraph_check : test_scotch_dgraph_check $(EXECP) ./test_scotch_dgraph_check data/bump.grf $(EXECP) ./test_scotch_dgraph_check data/bump_b1.grf test_scotch_dgraph_check : test_scotch_dgraph_check.c \ $(SCOTCHLIBDIR)/libptscotch$(LIB) ## check_scotch_dgraph_grow : test_scotch_dgraph_grow $(EXECP) ./test_scotch_dgraph_grow data/bump.grf test_scotch_dgraph_grow : test_scotch_dgraph_grow.c \ $(SCOTCHLIBDIR)/libptscotch$(LIB) scotch-6.0.4.dfsg/src/check/test_scotch_graph_map_copy.c0000644002563400244210000001544212474564030026506 0ustar trophimeutilisateurs du domaine/* Copyright 2014,2015 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : test_scotch_graph_map_copy.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module tests the operation of **/ /** the SCOTCH_graphMap*() routines in the **/ /** specific case of the "copy" method. **/ /** **/ /** DATES : # Version 6.0 : from : 15 oct 2014 **/ /** to 28 feb 2015 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #include #include #if (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) #include #endif /* (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) */ #include #include #include "scotch.h" #define STRANBR 3 /*********************/ /* */ /* The main routine. */ /* */ /*********************/ int main ( int argc, char * argv[]) { SCOTCH_Mapping mappdat; /* Mapping to compute */ SCOTCH_Mapping mapodat; /* Old mapping */ FILE * fileptr; SCOTCH_Graph grafdat; SCOTCH_Num xdimsiz; int archnum; SCOTCH_Arch archdat; SCOTCH_Strat stratab[STRANBR]; int stranum; int typenum; SCOTCH_Num baseval; SCOTCH_Num vertnbr; SCOTCH_Num vertnum; SCOTCH_Num * parttab; SCOTCH_Num * parotab; SCOTCH_errorProg (argv[0]); if (SCOTCH_graphInit (&grafdat) != 0) { /* Initialize source graph */ SCOTCH_errorPrint ("main: cannot initialize graph"); return (1); } if ((fileptr = fopen (argv[1], "r")) == NULL) { /* Read the givel graph */ SCOTCH_errorPrint ("main: cannot open file (1)"); return (1); } if (SCOTCH_graphLoad (&grafdat, fileptr, -1, 0) != 0) { /* Read source graph */ SCOTCH_errorPrint ("main: cannot load graph"); return (1); } fclose (fileptr); SCOTCH_graphSize (&grafdat, &vertnbr, NULL); if (((parttab = malloc (vertnbr * sizeof (SCOTCH_Num))) == NULL) || ((parotab = malloc (vertnbr * sizeof (SCOTCH_Num))) == NULL)) { SCOTCH_errorPrint ("main: out of memory"); return (1); } for (stranum = 0; stranum < STRANBR; stranum ++) { /* Initialize mapping strategies */ if (SCOTCH_stratInit (&stratab[stranum]) != 0) { SCOTCH_errorPrint ("main: cannot initialize strategy"); return (1); } } SCOTCH_stratGraphMap (&stratab[0], "cf{move=10000,pass=-1,bal=0.05}"); SCOTCH_stratGraphMap (&stratab[1], "m{vert=120,low=cf{move=10000,pass=-1,bal=0.05},asc=b{bnd=f{move=10000,pass=-1,bal=0.05},org=f{move=10000,pass=-1,bal=0.05}}}"); if (SCOTCH_archInit (&archdat) != 0) { SCOTCH_errorPrint ("main: cannot initialize architecture"); return (1); } SCOTCH_archCmplt (&archdat, 5); for (stranum = 0; stranum < (STRANBR - 1); stranum ++) { for (typenum = 0; typenum < 2; typenum ++) { int i; int o; printf ("Strat %d, type %d\n", stranum, typenum); switch (typenum) { case 0 : /* Plain mapping */ if (SCOTCH_graphMapInit (&grafdat, &mappdat, &archdat, parttab) != 0) { /* Initialize new mapping */ SCOTCH_errorPrint ("main: cannot initialize mapping (1)"); return (1); } o = SCOTCH_graphMapCompute (&grafdat, &mappdat, &stratab[STRANBR - 1]); /* Last strategy is plain mapping strategy */ memcpy (parotab, parttab, vertnbr * sizeof (SCOTCH_Num)); /* Use plain mapping as old mapping in the following */ break; case 1 : /* Remapping with copy of the old partition array */ if (SCOTCH_graphMapInit (&grafdat, &mapodat, &archdat, parotab) != 0) { /* Initialize old mapping */ SCOTCH_errorPrint ("main: cannot initialize mapping (2)"); return (1); } o = SCOTCH_graphRemapCompute (&grafdat, &mappdat, &mapodat, 0, NULL, &stratab[stranum]); break; } if (o != 0) { SCOTCH_errorPrint ("main: cannot compute mapping"); return (1); } } SCOTCH_graphMapExit (&grafdat, &mapodat); SCOTCH_graphMapExit (&grafdat, &mappdat); } SCOTCH_archExit (&archdat); for (stranum = 0; stranum < STRANBR; stranum ++) SCOTCH_stratExit (&stratab[stranum]); free (parotab); free (parttab); SCOTCH_graphExit (&grafdat); return (0); } scotch-6.0.4.dfsg/src/check/test_scotch_graph_coarsen_build.c0000644002563400244210000001663512474563753027530 0ustar trophimeutilisateurs du domaine/* Copyright 2015 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : test_scotch_graph_coarsen_build.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module tests the operation of **/ /** the SCOTCH_graphCoarsenBuild() routine. **/ /** **/ /** DATES : # Version 6.0 : from : 24 feb 2015 **/ /** to 26 feb 2015 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #include #include #if (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) #include #endif /* (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) */ #include #include #include "scotch.h" /*********************/ /* */ /* The main routine. */ /* */ /*********************/ int main ( int argc, char * argv[]) { SCOTCH_Num baseval; /* Base value */ SCOTCH_Graph finegrafdat; /* Fine graph */ SCOTCH_Num finevertnbr; /* Number of fine vertices */ SCOTCH_Num finevertnnd; /* Based end of vertex array */ SCOTCH_Num finevertnum; SCOTCH_Num * fineverttax; SCOTCH_Num * finevendtax; SCOTCH_Num * fineedgetax; SCOTCH_Num * finematetax; SCOTCH_Graph coargrafdat; /* Coarse graph */ SCOTCH_Num * coarmulttab; /* Multinode array */ SCOTCH_Num coarvertnbr; /* Number of coarse vertices */ SCOTCH_Num coaredgenbr; FILE * fileptr; SCOTCH_errorProg (argv[0]); if (SCOTCH_graphInit (&finegrafdat) != 0) { /* Initialize fine source graph */ SCOTCH_errorPrint ("main: cannot initialize graph"); return (1); } if ((fileptr = fopen (argv[1], "r")) == NULL) { /* Open fine graph file */ SCOTCH_errorPrint ("main: cannot open file"); return (1); } if (SCOTCH_graphLoad (&finegrafdat, fileptr, -1, 0) != 0) { /* Read fine source graph */ SCOTCH_errorPrint ("main: cannot load graph"); return (1); } fclose (fileptr); SCOTCH_graphData (&finegrafdat, &baseval, &finevertnbr, &fineverttax, &finevendtax, NULL, NULL, NULL, &fineedgetax, NULL); fineverttax -= baseval; finevendtax -= baseval; fineedgetax -= baseval; if ((finematetax = malloc (finevertnbr * sizeof (SCOTCH_Num))) == NULL) { SCOTCH_errorPrint ("main: out of memory (1)"); return (1); } memset (finematetax, ~0, finevertnbr * sizeof (SCOTCH_Num)); /* Set un-based array to "-1"'s */ finematetax -= baseval; /* From now on, base index array */ for (finevertnum = baseval, finevertnnd = finevertnbr + baseval, coarvertnbr = 0; /* Compute simple matching */ finevertnum < finevertnnd; finevertnum ++) { SCOTCH_Num finematenum; if (finematetax[finevertnum] >= 0) /* If vertex already matched */ continue; coarvertnbr ++; /* One more coarse vertex will be created */ finematenum = finevertnum; /* Assume we mate with ourselves */ if (fineverttax[finevertnum] == finevendtax[finevertnum]) { /* If isolated vertex */ while (1) { /* Use first free vertex as a mate */ if (++ finevertnum >= finevertnnd) { /* If no other free vertex available */ finematetax[finematenum] = finematenum; /* Mate isolated vertex with itself */ goto endloop; /* Exit nested loops */ } if (finematetax[finevertnum] < 0) /* If vertex is free, keep it as mate */ break; /* Increment performed in outer loop */ } } else { SCOTCH_Num fineedgenum; for (fineedgenum = fineverttax[finevertnum]; /* Find a suitable mate */ fineedgenum < finevendtax[finevertnum]; fineedgenum ++) { SCOTCH_Num finevertend; finevertend = fineedgetax[fineedgenum]; /* FInd end vertex */ if (finematetax[finevertend] < 0) { /* If vertex is free */ finematenum = finevertend; /* Keep vertex as mate */ break; } } } finematetax[finevertnum] = finematenum; finematetax[finematenum] = finevertnum; } endloop: if ((coarmulttab = malloc (coarvertnbr * 2 * sizeof (SCOTCH_Num))) == NULL) { SCOTCH_errorPrint ("main: out of memory (2)"); return (1); } if (SCOTCH_graphCoarsenBuild (&finegrafdat, &coargrafdat, coarmulttab, coarvertnbr, finematetax + baseval) != 0) { SCOTCH_errorPrint ("main: cannot compute coarse graph"); return (1); } SCOTCH_graphSize (&coargrafdat, &coarvertnbr, &coaredgenbr); printf ("Coarse graph has " SCOTCH_NUMSTRING " vertices and " SCOTCH_NUMSTRING " edges\n", coarvertnbr, coaredgenbr); printf ("Graph coarsened with a ratio of %lg\n", (double) coarvertnbr / (double) finevertnbr); SCOTCH_graphExit (&coargrafdat); SCOTCH_graphExit (&finegrafdat); free (coarmulttab); free (finematetax + baseval); return (0); } scotch-6.0.4.dfsg/src/check/data/0000755002563400244210000000000012374701360021651 5ustar trophimeutilisateurs du domainescotch-6.0.4.dfsg/src/check/data/bump_imbal_32.grf0000644002563400244210000116765512057040307025004 0ustar trophimeutilisateurs du domaine0 9800 57978 0 001 1 3 413 407 6 1 4 9771 43 9772 44 2 4 76 1474 1475 77 1 3 1242 147 148 1 3 693 206 207 1 3 521 348 349 1 4 7 412 413 0 1 4 6 412 8 647 1 4 9 3238 647 7 1 4 3235 3238 8 10 1 4 11 3233 3235 9 1 4 3234 3233 10 12 1 4 3684 3234 11 13 1 4 14 418 3684 12 1 4 15 417 418 13 1 4 14 417 16 3088 1 4 17 3086 3088 15 1 4 16 3086 3087 18 1 4 3087 17 3095 19 1 4 3095 18 3096 20 1 4 21 414 3096 19 1 4 20 414 1171 22 1 4 1171 21 1172 23 1 4 1172 22 1173 24 1 4 1173 23 1526 25 1 4 1526 24 26 9781 1 4 27 3852 9781 25 1 4 28 2179 3852 26 1 4 27 2179 2180 29 1 4 2180 28 30 2503 1 4 31 2505 2503 29 1 4 2508 2505 30 32 1 4 3330 2508 33 31 1 4 3330 32 3331 34 1 4 35 2248 3331 33 1 4 34 2248 2249 36 1 4 2249 35 2250 37 1 4 38 416 2250 36 1 4 39 415 416 37 1 4 38 415 2194 40 1 4 2194 39 2195 41 1 4 2195 40 2196 42 1 3 2196 41 43 1 4 42 2196 9771 1 1 4 9769 9772 1 45 1 4 46 9768 9769 44 1 4 47 427 9768 45 1 4 48 426 427 46 1 4 47 426 49 411 1 4 50 410 411 48 1 4 49 410 51 421 1 4 50 421 422 52 1 4 422 51 4650 53 1 4 4650 52 4651 54 1 4 4657 4651 53 55 1 4 5380 4657 54 56 1 4 57 430 5380 55 1 4 56 430 429 58 1 4 59 408 429 57 1 4 58 408 2218 60 1 4 2218 59 2219 61 1 4 2219 60 2220 62 1 4 2220 61 2221 63 1 4 2221 62 2222 64 1 4 6701 2222 63 65 1 4 6701 64 6703 66 1 4 6703 65 3505 67 1 4 68 3452 3505 66 1 4 69 3451 3452 67 1 4 3441 3451 68 70 2 4 71 2491 3441 69 2 4 70 2491 2492 72 2 4 73 409 2492 71 2 4 72 409 74 428 2 4 73 428 75 1603 2 4 74 1603 1604 76 2 4 2 1474 1604 75 2 4 1475 2 1476 78 2 4 1476 77 1477 79 2 4 1477 78 1478 80 2 4 1478 79 1479 81 2 4 1479 80 1480 82 2 4 1480 81 1481 83 2 4 1481 82 1482 84 2 4 1482 83 1483 85 2 4 86 1160 1483 84 2 4 85 1160 1161 87 2 4 1161 86 1162 88 2 4 1162 87 1163 89 2 4 1163 88 1186 90 2 4 1186 89 1185 91 2 4 1185 90 1187 92 2 4 1187 91 1188 93 2 4 1188 92 1189 94 2 4 1189 93 1190 95 2 4 1190 94 1191 96 2 4 1191 95 1192 97 2 4 1192 96 1193 98 2 4 1193 97 1194 99 2 4 1194 98 1195 100 2 4 1195 99 1196 101 2 4 1196 100 1197 102 2 4 1197 101 1198 103 2 4 1198 102 1199 104 2 4 1199 103 1200 105 2 4 1200 104 1201 106 2 4 1201 105 1202 107 2 4 1202 106 1203 108 2 4 1203 107 1204 109 2 4 1204 108 1205 110 2 4 1205 109 1206 111 2 4 1206 110 1207 112 2 4 1207 111 1208 113 1 4 1208 112 1209 114 1 4 1209 113 1210 115 1 4 1210 114 1211 116 1 4 1211 115 1212 117 1 4 1212 116 1213 118 1 4 1213 117 1214 119 1 4 1214 118 1215 120 1 4 1215 119 1216 121 1 4 1216 120 1217 122 1 4 1217 121 1218 123 1 4 1218 122 1219 124 1 4 1219 123 1220 125 1 4 1220 124 1221 126 1 4 1221 125 1222 127 1 4 1222 126 1223 128 1 4 1223 127 1224 129 1 4 1224 128 1225 130 1 4 1225 129 1226 131 1 4 1226 130 1227 132 1 4 1227 131 1228 133 1 4 1228 132 1229 134 1 4 1229 133 1230 135 1 4 1230 134 1231 136 1 4 1231 135 1232 137 1 4 1232 136 1233 138 1 4 1233 137 1234 139 1 4 1234 138 1235 140 1 4 1235 139 1236 141 1 4 1236 140 1237 142 1 4 1237 141 1238 143 1 4 1238 142 1239 144 1 4 1239 143 1240 145 1 4 1240 144 1241 146 1 4 1241 145 1242 147 1 3 1242 146 3 1 4 1242 3 1243 149 1 4 1243 148 1244 150 1 4 1244 149 1245 151 1 4 1245 150 1246 152 1 4 1246 151 1247 153 1 4 1247 152 1248 154 1 4 155 923 1248 153 1 4 154 923 924 156 1 4 924 155 925 157 1 4 925 156 926 158 1 4 926 157 927 159 1 4 927 158 928 160 1 4 928 159 929 161 1 4 929 160 930 162 1 4 930 161 931 163 1 4 164 651 931 162 1 4 163 651 652 165 1 4 652 164 653 166 1 4 653 165 654 167 1 4 654 166 655 168 1 4 655 167 656 169 1 4 656 168 657 170 1 4 657 169 658 171 1 4 658 170 659 172 1 4 659 171 660 173 1 4 660 172 661 174 1 4 661 173 662 175 1 4 662 174 663 176 1 4 663 175 664 177 1 4 664 176 665 178 1 4 665 177 666 179 1 4 666 178 667 180 1 4 667 179 668 181 1 4 668 180 669 182 1 4 669 181 670 183 1 4 670 182 671 184 1 4 671 183 672 185 1 4 672 184 673 186 1 4 673 185 674 187 1 4 674 186 675 188 1 4 675 187 676 189 1 4 676 188 677 190 1 4 677 189 678 191 1 4 678 190 679 192 1 4 679 191 680 193 1 4 680 192 681 194 1 4 681 193 682 195 1 4 682 194 683 196 1 4 683 195 684 197 1 4 684 196 685 198 1 4 685 197 686 199 1 4 686 198 687 200 1 4 687 199 688 201 1 4 688 200 689 202 1 4 689 201 690 203 1 4 690 202 691 204 1 4 691 203 692 205 1 3 692 204 206 1 4 692 205 693 4 1 3 693 4 208 1 4 693 207 694 209 1 4 694 208 695 210 1 4 695 209 696 211 1 4 696 210 697 212 1 4 697 211 698 213 1 4 698 212 699 214 1 4 699 213 700 215 1 4 700 214 701 216 1 4 701 215 702 217 1 4 702 216 703 218 1 4 703 217 704 219 1 4 704 218 705 220 1 4 705 219 706 221 1 4 706 220 707 222 1 4 707 221 708 223 1 4 708 222 709 224 1 4 709 223 710 225 1 4 710 224 711 226 1 4 711 225 712 227 1 4 712 226 713 228 1 4 713 227 714 229 1 4 714 228 715 230 1 4 715 229 716 231 1 4 716 230 717 232 1 4 717 231 718 233 1 4 718 232 719 234 1 4 719 233 720 235 1 4 720 234 721 236 1 4 721 235 722 237 1 4 722 236 723 238 1 4 723 237 724 239 1 4 724 238 725 240 1 4 725 239 726 241 1 4 726 240 727 242 1 4 727 241 728 243 1 4 728 242 729 244 1 4 729 243 730 245 1 4 730 244 731 246 1 4 731 245 732 247 2 4 732 246 733 248 2 4 733 247 734 249 2 4 734 248 735 250 2 4 735 249 736 251 2 4 736 250 737 252 2 4 737 251 738 253 2 4 738 252 739 254 2 4 739 253 740 255 2 4 740 254 741 256 2 4 741 255 742 257 2 4 258 431 742 256 2 4 257 431 432 259 2 4 432 258 433 260 2 4 433 259 434 261 2 4 434 260 435 262 2 4 435 261 436 263 2 4 436 262 437 264 2 4 437 263 438 265 2 4 438 264 439 266 2 4 439 265 440 267 2 4 440 266 441 268 2 4 441 267 442 269 2 4 442 268 443 270 2 4 443 269 444 271 2 4 444 270 445 272 1 4 445 271 446 273 1 4 446 272 447 274 1 4 447 273 448 275 1 4 448 274 449 276 1 4 449 275 450 277 1 4 450 276 451 278 1 4 451 277 452 279 1 4 452 278 453 280 1 4 453 279 454 281 1 4 454 280 455 282 1 4 455 281 456 283 1 4 456 282 457 284 1 4 457 283 458 285 1 4 458 284 459 286 1 4 459 285 460 287 1 4 460 286 461 288 1 4 461 287 462 289 1 4 462 288 463 290 1 4 463 289 464 291 1 4 464 290 465 292 1 4 465 291 466 293 1 4 466 292 467 294 1 4 467 293 468 295 1 4 468 294 469 296 1 4 469 295 470 297 1 4 470 296 471 298 1 4 471 297 472 299 1 4 472 298 473 300 1 4 473 299 474 301 1 4 474 300 475 302 1 4 475 301 476 303 1 4 476 302 477 304 1 4 477 303 478 305 1 4 478 304 479 306 1 4 479 305 480 307 1 4 480 306 481 308 1 4 481 307 482 309 1 4 482 308 483 310 1 4 483 309 484 311 1 4 484 310 485 312 1 4 485 311 486 313 1 4 486 312 487 314 1 4 487 313 488 315 1 4 488 314 489 316 1 4 489 315 490 317 1 4 490 316 491 318 1 4 491 317 492 319 1 4 492 318 493 320 1 4 493 319 494 321 1 4 494 320 495 322 1 4 495 321 496 323 1 4 496 322 497 324 1 4 497 323 498 325 1 4 498 324 499 326 1 4 499 325 500 327 1 4 500 326 501 328 1 4 501 327 502 329 1 4 502 328 503 330 1 4 503 329 504 331 1 4 504 330 505 332 1 4 505 331 506 333 1 4 506 332 507 334 1 4 507 333 508 335 1 4 508 334 509 336 1 4 509 335 510 337 1 4 510 336 511 338 1 4 511 337 512 339 1 4 512 338 513 340 1 4 513 339 514 341 1 4 514 340 515 342 1 4 515 341 516 343 1 4 516 342 517 344 1 4 517 343 518 345 1 4 518 344 519 346 1 4 519 345 520 347 1 4 520 346 521 348 1 3 521 347 5 1 4 521 5 522 350 1 4 522 349 523 351 1 4 523 350 524 352 1 4 524 351 525 353 1 4 525 352 526 354 1 4 526 353 527 355 1 4 527 354 528 356 1 4 528 355 529 357 1 4 529 356 530 358 1 4 530 357 531 359 1 4 531 358 532 360 1 4 532 359 533 361 1 4 533 360 534 362 1 4 534 361 535 363 1 4 535 362 536 364 1 4 536 363 537 365 1 4 537 364 538 366 1 4 538 365 539 367 1 4 539 366 540 368 1 4 540 367 541 369 1 4 541 368 542 370 1 4 542 369 543 371 1 4 543 370 544 372 1 4 544 371 545 373 1 4 545 372 546 374 1 4 546 373 547 375 1 4 550 547 374 376 1 4 550 375 551 377 1 4 551 376 552 378 1 4 552 377 553 379 1 4 556 553 378 380 1 4 566 556 379 381 1 4 566 380 567 382 1 4 567 381 568 383 1 4 568 382 569 384 1 4 569 383 570 385 1 4 425 570 386 384 1 4 387 423 425 385 1 4 386 423 424 388 1 4 579 424 389 387 1 4 584 579 388 390 1 4 584 389 585 391 1 4 585 390 586 392 1 4 586 391 420 393 1 4 394 419 420 392 1 4 393 419 594 395 1 4 396 596 594 394 1 4 622 596 395 397 1 4 622 396 623 398 1 4 623 397 624 399 1 4 398 624 626 400 1 4 626 399 628 401 1 4 630 628 402 400 1 4 630 401 631 403 1 4 402 631 2097 404 1 4 405 649 2097 403 1 4 648 649 404 406 1 4 648 405 413 407 1 3 413 406 0 1 6 58 59 429 2218 2545 2841 2 6 72 73 2492 2493 1606 428 1 6 49 50 411 4521 4515 421 1 6 49 410 48 426 4514 4515 1 6 6 7 413 647 646 648 1 6 6 412 648 406 407 0 1 6 20 21 1171 3882 3128 3096 1 6 38 39 416 2194 2252 9704 1 6 38 415 37 2250 2251 2252 1 6 14 15 418 3088 3098 3099 1 6 14 417 13 3099 3100 3684 1 6 393 394 420 593 588 594 1 6 393 419 586 392 587 588 1 6 50 51 422 5237 4521 410 1 6 421 51 52 4650 9684 5237 1 6 386 387 424 425 577 575 1 6 423 387 577 578 579 388 1 6 386 423 572 570 385 575 1 6 47 48 427 411 4514 5612 1 6 47 426 46 5612 7500 9768 2 6 73 74 1603 1605 1606 409 1 6 58 408 430 57 2841 9690 1 6 56 57 429 9689 5380 9690 2 6 257 258 432 742 743 744 2 6 431 258 259 433 744 745 2 6 432 259 260 434 745 746 2 6 433 260 261 435 746 747 2 6 434 261 262 436 747 748 2 6 435 262 263 437 748 749 2 6 436 263 264 438 749 750 2 6 437 264 265 439 750 751 2 6 438 265 266 440 751 752 2 6 439 266 267 441 752 753 2 6 440 267 268 442 753 754 2 6 441 268 269 443 754 755 2 6 442 269 270 444 755 756 2 6 443 270 271 445 756 757 2 6 444 271 272 446 757 758 1 6 445 272 273 447 758 759 1 6 446 273 274 448 759 760 1 6 447 274 275 449 760 761 1 6 448 275 276 450 761 762 1 6 449 276 277 451 762 763 1 6 450 277 278 452 763 764 1 6 451 278 279 453 764 765 1 6 452 279 280 454 765 766 1 6 453 280 281 455 766 767 1 6 454 281 282 456 767 768 1 6 455 282 283 457 768 769 1 6 456 283 284 458 769 770 1 6 457 284 285 459 770 771 1 6 458 285 286 460 771 772 1 6 459 286 287 461 772 773 1 6 460 287 288 462 773 774 1 6 461 288 289 463 774 775 1 6 462 289 290 464 775 776 1 6 463 290 291 465 776 777 1 6 464 291 292 466 777 778 1 6 465 292 293 467 778 779 1 6 466 293 294 468 779 780 1 6 467 294 295 469 780 781 1 6 468 295 296 470 781 782 1 6 469 296 297 471 782 783 1 6 470 297 298 472 783 784 1 6 471 298 299 473 784 785 1 6 472 299 300 474 785 786 1 6 473 300 301 475 786 787 1 6 474 301 302 476 787 788 1 6 475 302 303 477 788 789 1 6 476 303 304 478 789 790 1 6 477 304 305 479 790 791 1 6 478 305 306 480 791 792 1 6 479 306 307 481 792 793 1 6 480 307 308 482 793 794 1 6 481 308 309 483 794 795 1 6 482 309 310 484 795 796 1 6 483 310 311 485 796 797 1 6 484 311 312 486 797 798 1 6 485 312 313 487 798 799 1 6 486 313 314 488 799 800 1 6 487 314 315 489 800 801 1 6 488 315 316 490 801 802 1 6 489 316 317 491 802 803 1 6 490 317 318 492 803 804 1 6 491 318 319 493 804 805 1 6 492 319 320 494 805 806 1 6 493 320 321 495 806 807 1 6 494 321 322 496 807 808 1 6 495 322 323 497 808 809 1 6 496 323 324 498 809 810 1 6 497 324 325 499 810 811 1 6 498 325 326 500 811 812 1 6 499 326 327 501 812 813 1 6 500 327 328 502 813 814 1 6 501 328 329 503 814 815 1 6 502 329 330 504 815 816 1 6 503 330 331 505 816 817 1 6 504 331 332 506 817 818 1 6 505 332 333 507 818 819 1 6 506 333 334 508 819 820 1 6 507 334 335 509 820 821 1 6 508 335 336 510 821 822 1 6 509 336 337 511 822 823 1 6 510 337 338 512 823 824 1 6 511 338 339 513 824 825 1 6 512 339 340 514 825 826 1 6 513 340 341 515 826 827 1 6 514 341 342 516 827 828 1 6 515 342 343 517 828 829 1 6 516 343 344 518 829 830 1 6 517 344 345 519 830 831 1 6 518 345 346 520 831 832 1 6 519 346 347 521 832 833 1 7 520 347 348 5 349 522 833 1 6 521 349 350 523 833 834 1 5 522 350 351 524 834 1 6 523 351 352 525 834 835 1 6 524 352 353 526 835 836 1 6 525 353 354 527 836 837 1 6 526 354 355 528 837 838 1 6 527 355 356 529 838 839 1 6 528 356 357 530 839 840 1 6 529 357 358 531 840 841 1 6 530 358 359 532 841 842 1 6 531 359 360 533 842 843 1 6 532 360 361 534 843 844 1 6 533 361 362 535 844 845 1 6 534 362 363 536 845 846 1 6 535 363 364 537 846 847 1 6 536 364 365 538 847 848 1 6 537 365 366 539 848 849 1 6 538 366 367 540 849 850 1 6 539 367 368 541 853 850 1 6 540 368 369 542 855 853 1 6 541 369 370 543 855 856 1 6 542 370 371 544 856 857 1 6 543 371 372 545 857 858 1 6 544 372 373 546 858 859 1 6 545 373 374 547 548 859 1 6 546 374 548 549 550 375 1 6 546 547 549 859 860 861 1 6 548 547 550 861 862 863 1 6 549 547 375 376 551 863 1 6 550 376 377 552 863 864 1 6 551 377 378 553 554 864 1 6 552 378 554 555 556 379 1 6 552 553 555 557 864 865 1 6 554 553 556 557 558 565 1 6 555 553 379 565 566 380 1 6 554 555 558 559 865 866 1 6 557 555 559 560 561 565 1 6 557 558 560 866 867 868 1 6 559 558 561 562 922 868 1 6 560 558 562 563 564 565 1 6 560 561 563 921 920 922 1 6 562 561 564 9743 921 9744 1 6 563 561 565 566 9744 567 1 6 564 561 558 555 556 566 1 6 565 556 380 381 567 564 1 6 566 381 382 568 9744 564 1 6 567 382 383 569 9744 9739 1 6 568 383 384 570 571 9739 1 6 569 384 571 572 425 385 1 6 569 570 572 573 9739 9740 1 6 571 570 425 573 574 575 1 6 571 572 574 9740 9741 916 1 6 573 572 575 576 916 915 1 6 574 572 425 576 577 423 1 6 574 575 577 915 2474 1515 1 6 576 575 423 424 578 1515 1 6 577 424 579 580 581 1515 1 6 578 424 388 580 584 389 1 6 578 579 581 582 583 584 1 6 578 580 582 1515 1516 1517 1 6 581 580 583 1517 1508 1506 1 6 582 580 584 585 589 1506 1 6 583 580 579 389 390 585 1 6 584 390 391 586 589 583 1 6 585 391 392 420 587 589 1 6 586 420 588 589 590 591 1 6 587 420 591 592 593 419 1 6 586 587 590 585 583 1506 1 6 589 587 591 1506 1507 1514 1 6 590 587 588 592 599 1514 1 6 591 588 593 597 598 599 1 6 592 588 419 594 595 597 1 6 593 419 394 595 596 395 1 6 593 594 596 597 621 606 1 6 595 594 621 622 396 395 1 6 593 595 592 598 605 606 1 6 592 597 599 600 604 605 1 6 592 598 600 601 1514 591 1 6 599 598 601 602 603 604 1 6 599 600 602 1513 1514 1539 1 6 601 600 603 1539 1540 1583 1 6 602 600 604 1602 1583 608 1 6 603 600 598 605 607 608 1 6 604 598 597 606 607 614 1 6 605 597 621 620 595 614 1 6 604 605 608 609 610 614 1 6 604 607 609 1602 603 1600 1 6 608 607 610 611 1599 1600 1 6 609 607 611 612 613 614 1 6 609 610 612 6557 1598 1599 1 6 611 610 613 615 3764 6557 1 6 612 610 614 615 616 620 1 6 613 610 620 606 605 607 1 6 612 613 616 617 3760 3764 1 6 615 613 617 618 619 620 1 6 615 616 618 3760 3761 625 1 6 617 616 619 623 624 625 1 6 618 616 620 621 623 622 1 6 619 616 613 614 621 606 1 6 619 620 606 595 596 622 1 6 621 596 396 397 623 619 1 6 622 397 398 624 618 619 1 6 623 398 618 625 626 399 1 6 618 624 626 627 3761 617 1 6 625 624 627 628 399 400 1 6 625 626 628 629 3761 3762 1 6 627 626 629 630 401 400 1 6 627 628 630 635 3762 632 1 6 629 628 401 402 631 632 1 6 630 402 632 633 403 2097 1 6 630 631 633 634 635 629 1 6 632 631 634 2097 650 641 1 6 632 633 635 636 637 641 1 6 632 634 636 3217 3762 629 1 6 635 634 637 638 3217 3218 1 6 636 634 638 639 640 641 1 6 636 637 639 3218 3219 3220 1 6 638 637 640 3220 3239 3240 1 6 639 637 641 642 643 3239 1 6 640 637 642 633 650 634 1 6 640 641 643 644 645 650 1 6 640 642 644 3237 3236 3239 1 6 643 642 645 646 647 3237 1 6 644 642 646 648 649 650 1 5 644 645 647 412 648 1 7 644 646 412 8 3238 3237 7 1 7 412 646 645 649 405 406 413 1 6 648 645 650 405 404 2097 1 6 649 645 633 2097 641 642 1 6 163 164 652 931 932 933 1 6 651 164 165 653 933 934 1 6 652 165 166 654 934 935 1 6 653 166 167 655 935 936 1 6 654 167 168 656 936 937 1 6 655 168 169 657 937 938 1 6 656 169 170 658 938 939 1 6 657 170 171 659 939 940 1 6 658 171 172 660 940 941 1 6 659 172 173 661 941 942 1 6 660 173 174 662 942 943 1 6 661 174 175 663 943 944 1 6 662 175 176 664 944 945 1 6 663 176 177 665 945 946 1 6 664 177 178 666 946 947 1 6 665 178 179 667 947 948 1 6 666 179 180 668 948 949 1 6 667 180 181 669 949 950 1 6 668 181 182 670 950 951 1 6 669 182 183 671 951 952 1 6 670 183 184 672 952 953 1 6 671 184 185 673 953 954 1 6 672 185 186 674 954 955 1 6 673 186 187 675 955 956 1 6 674 187 188 676 956 957 1 6 675 188 189 677 957 958 1 6 676 189 190 678 958 959 1 6 677 190 191 679 959 960 1 6 678 191 192 680 960 961 1 6 679 192 193 681 961 962 1 6 680 193 194 682 962 963 1 6 681 194 195 683 963 964 1 6 682 195 196 684 964 965 1 6 683 196 197 685 965 966 1 6 684 197 198 686 966 967 1 6 685 198 199 687 967 968 1 6 686 199 200 688 968 969 1 6 687 200 201 689 969 970 1 6 688 201 202 690 970 971 1 6 689 202 203 691 971 972 1 6 690 203 204 692 972 973 1 7 691 204 205 206 693 973 694 1 6 692 206 4 207 208 694 1 7 693 208 209 695 973 692 974 1 6 694 209 210 696 974 975 1 6 695 210 211 697 975 976 1 6 696 211 212 698 976 977 1 6 697 212 213 699 977 978 1 6 698 213 214 700 978 979 1 6 699 214 215 701 979 980 1 6 700 215 216 702 980 981 1 6 701 216 217 703 981 982 1 6 702 217 218 704 982 983 1 6 703 218 219 705 983 984 1 6 704 219 220 706 984 985 1 6 705 220 221 707 985 986 1 6 706 221 222 708 986 987 1 6 707 222 223 709 987 988 1 6 708 223 224 710 988 989 1 6 709 224 225 711 989 990 1 6 710 225 226 712 990 991 1 6 711 226 227 713 991 992 1 6 712 227 228 714 992 993 1 6 713 228 229 715 993 994 1 6 714 229 230 716 994 995 1 6 715 230 231 717 995 996 1 6 716 231 232 718 996 997 1 6 717 232 233 719 997 998 1 6 718 233 234 720 998 999 1 6 719 234 235 721 999 1000 1 6 720 235 236 722 1000 1001 1 6 721 236 237 723 1001 1002 1 6 722 237 238 724 1002 1003 1 6 723 238 239 725 1003 1004 1 6 724 239 240 726 1004 1005 1 6 725 240 241 727 1005 1006 1 6 726 241 242 728 1006 1007 1 6 727 242 243 729 1007 1008 1 6 728 243 244 730 1008 1009 1 6 729 244 245 731 1009 1010 1 6 730 245 246 732 1010 1011 2 6 731 246 247 733 1011 1012 2 6 732 247 248 734 1012 1013 2 6 733 248 249 735 1016 1013 2 6 734 249 250 736 1016 1017 2 6 735 250 251 737 1017 1018 2 6 736 251 252 738 1018 1019 2 6 737 252 253 739 1019 1020 2 6 738 253 254 740 1020 1021 2 6 739 254 255 741 1021 1022 2 6 740 255 256 742 1022 1023 2 6 741 256 257 431 743 1023 2 6 742 431 744 1023 1024 1025 2 6 743 431 432 745 1025 1026 2 6 744 432 433 746 1026 1027 2 6 745 433 434 747 1027 1028 2 6 746 434 435 748 1028 1029 2 6 747 435 436 749 1029 1030 2 6 748 436 437 750 1030 1031 2 6 749 437 438 751 1031 1032 2 6 750 438 439 752 1032 1033 2 6 751 439 440 753 1033 1034 2 6 752 440 441 754 1034 1035 2 6 753 441 442 755 1035 1036 2 6 754 442 443 756 1036 1037 2 6 755 443 444 757 1037 1038 2 6 756 444 445 758 1038 1039 1 6 757 445 446 759 1039 1040 1 6 758 446 447 760 1040 1041 1 6 759 447 448 761 1041 1042 1 6 760 448 449 762 1042 1043 1 6 761 449 450 763 1043 1044 1 6 762 450 451 764 1044 1045 1 6 763 451 452 765 1045 1046 1 6 764 452 453 766 1046 1047 1 6 765 453 454 767 1047 1048 1 6 766 454 455 768 1048 1049 1 6 767 455 456 769 1049 1050 1 6 768 456 457 770 1050 1051 1 6 769 457 458 771 1051 1052 1 6 770 458 459 772 1052 1053 1 6 771 459 460 773 1053 1054 1 6 772 460 461 774 1054 1055 1 6 773 461 462 775 1055 1056 1 6 774 462 463 776 1056 1057 1 6 775 463 464 777 1057 1058 1 6 776 464 465 778 1058 1059 1 6 777 465 466 779 1059 1060 1 6 778 466 467 780 1060 1061 1 6 779 467 468 781 1061 1062 1 6 780 468 469 782 1062 1063 1 6 781 469 470 783 1063 1064 1 6 782 470 471 784 1064 1065 1 6 783 471 472 785 1065 1066 1 6 784 472 473 786 1066 1067 1 6 785 473 474 787 1067 1068 1 6 786 474 475 788 1068 1069 1 6 787 475 476 789 1069 1070 1 6 788 476 477 790 1070 1071 1 6 789 477 478 791 1071 1072 1 6 790 478 479 792 1072 1073 1 6 791 479 480 793 1073 1074 1 6 792 480 481 794 1074 1075 1 6 793 481 482 795 1075 1076 1 6 794 482 483 796 1076 1077 1 6 795 483 484 797 1077 1078 1 6 796 484 485 798 1078 1079 1 6 797 485 486 799 1079 1080 1 6 798 486 487 800 1080 1081 1 6 799 487 488 801 1081 1082 1 6 800 488 489 802 1082 1083 1 6 801 489 490 803 1083 1084 1 6 802 490 491 804 1084 1085 1 6 803 491 492 805 1085 1086 1 6 804 492 493 806 1086 1087 1 6 805 493 494 807 1087 1088 1 6 806 494 495 808 1088 1089 1 6 807 495 496 809 1089 1090 1 6 808 496 497 810 1090 1091 1 6 809 497 498 811 1091 1092 1 6 810 498 499 812 1092 1093 1 6 811 499 500 813 1093 1094 1 6 812 500 501 814 1094 1095 1 6 813 501 502 815 1095 1096 1 6 814 502 503 816 1096 1097 1 6 815 503 504 817 1097 1098 1 6 816 504 505 818 1098 1099 1 6 817 505 506 819 1099 1100 1 6 818 506 507 820 1100 1101 1 6 819 507 508 821 1101 1102 1 6 820 508 509 822 1102 1103 1 6 821 509 510 823 1103 1104 1 6 822 510 511 824 1104 1105 1 6 823 511 512 825 1105 1106 1 6 824 512 513 826 1106 1107 1 6 825 513 514 827 1107 1108 1 6 826 514 515 828 1108 1109 1 6 827 515 516 829 1109 1110 1 6 828 516 517 830 1110 1111 1 6 829 517 518 831 1111 1112 1 6 830 518 519 832 1112 1113 1 6 831 519 520 833 1113 1114 1 6 832 520 521 522 834 1114 1 6 833 522 523 524 835 1114 1 7 834 524 525 836 1114 1115 1116 1 6 835 525 526 837 1116 1117 1 6 836 526 527 838 1117 1118 1 6 837 527 528 839 1118 1119 1 6 838 528 529 840 1119 1120 1 6 839 529 530 841 1120 1121 1 6 840 530 531 842 1121 1122 1 6 841 531 532 843 1122 1123 1 6 842 532 533 844 1123 1124 1 6 843 533 534 845 1124 1125 1 6 844 534 535 846 1125 1126 1 6 845 535 536 847 1126 1127 1 6 846 536 537 848 1127 1128 1 6 847 537 538 849 1128 1129 1 6 848 538 539 850 851 1129 1 6 849 539 851 852 853 540 1 6 849 850 852 1129 1130 1131 1 6 851 850 853 854 1131 1132 1 6 852 850 854 855 541 540 1 6 852 853 855 1132 1133 1134 1 6 854 853 541 542 856 1134 1 6 855 542 543 857 1134 1135 1 6 856 543 544 858 1135 1136 1 6 857 544 545 859 1136 1137 1 6 858 545 546 548 860 1137 1 6 859 548 861 1137 1138 1139 1 6 860 548 549 862 1139 1140 1 6 861 549 863 1140 1141 1142 1 6 862 549 550 551 864 1142 1 6 863 551 552 554 865 1142 1 6 864 554 557 866 1142 1143 1 6 865 557 559 867 1143 1144 1 6 866 559 868 869 1144 1145 1 6 867 559 869 870 922 560 1 6 867 868 870 871 1145 1146 1 6 869 868 871 872 873 922 1 6 869 870 872 1146 1147 1148 1 6 871 870 873 874 1151 1148 1 6 872 870 874 875 922 920 1 6 872 873 875 876 1170 1151 1 6 874 873 876 877 919 920 1 6 874 875 877 878 879 1170 1 6 876 875 878 918 882 919 1 6 876 877 879 880 881 882 1 6 876 878 880 884 886 1170 1 6 879 878 881 884 885 891 1 6 880 878 882 883 891 892 1 6 881 878 883 917 918 877 1 6 881 882 912 892 913 917 1 6 879 880 885 886 887 888 1 6 884 880 888 889 890 891 1 6 879 884 887 1964 1169 1170 1 6 886 884 888 1965 1964 2075 1 6 887 884 885 889 2075 2076 1 6 888 885 890 2076 2077 2081 1 6 889 885 891 893 894 2081 1 6 890 885 880 881 892 893 1 6 891 881 893 896 912 883 1 6 891 892 890 894 895 896 1 6 890 893 895 897 898 2081 1 6 894 893 896 897 909 910 1 6 895 893 892 910 911 912 1 6 894 895 898 899 900 909 1 6 894 897 899 901 2081 2080 1 6 898 897 900 901 902 906 1 6 899 897 906 907 908 909 1 6 898 899 902 903 2080 2082 1 6 901 899 903 904 905 906 1 6 901 902 904 2082 2083 2084 1 6 903 902 905 2084 2085 1565 1 6 904 902 906 1563 1564 1565 1 6 905 902 899 900 907 1563 1 6 906 900 908 1543 1563 1536 1 6 907 900 909 1522 1523 1536 1 6 908 900 897 895 910 1522 1 6 909 895 896 911 1520 1522 1 6 910 896 912 1521 1520 914 1 6 911 896 892 883 913 914 1 6 912 883 914 915 916 917 1 6 912 913 915 2474 1521 911 1 6 914 913 916 574 576 2474 1 6 915 913 917 9741 573 574 1 6 916 913 883 882 918 9741 1 6 917 882 877 919 9742 9741 1 6 918 877 875 920 921 9742 1 6 919 875 921 562 922 873 1 6 919 920 562 9743 9742 563 1 6 562 920 873 870 868 560 1 6 154 155 924 1248 1249 1250 1 6 923 155 156 925 1250 1251 1 6 924 156 157 926 1251 1252 1 6 925 157 158 927 1252 1253 1 6 926 158 159 928 1253 1254 1 6 927 159 160 929 1254 1255 1 6 928 160 161 930 1255 1256 1 6 929 161 162 931 1256 1257 1 6 930 162 163 651 932 1257 1 6 931 651 933 1257 1258 1259 1 6 932 651 652 934 1259 1260 1 6 933 652 653 935 1260 1261 1 6 934 653 654 936 1261 1262 1 6 935 654 655 937 1262 1263 1 6 936 655 656 938 1263 1264 1 6 937 656 657 939 1264 1265 1 6 938 657 658 940 1265 1266 1 6 939 658 659 941 1266 1267 1 6 940 659 660 942 1267 1268 1 6 941 660 661 943 1268 1269 1 6 942 661 662 944 1269 1270 1 6 943 662 663 945 1270 1271 1 6 944 663 664 946 1271 1272 1 6 945 664 665 947 1272 1273 1 6 946 665 666 948 1273 1274 1 6 947 666 667 949 1274 1275 1 6 948 667 668 950 1275 1276 1 6 949 668 669 951 1276 1277 1 6 950 669 670 952 1277 1278 1 6 951 670 671 953 1278 1279 1 6 952 671 672 954 1279 1280 1 6 953 672 673 955 1280 1281 1 6 954 673 674 956 1281 1282 1 6 955 674 675 957 1282 1283 1 6 956 675 676 958 1283 1284 1 6 957 676 677 959 1284 1285 1 6 958 677 678 960 1285 1286 1 6 959 678 679 961 1286 1287 1 6 960 679 680 962 1287 1288 1 6 961 680 681 963 1288 1289 1 6 962 681 682 964 1289 1290 1 6 963 682 683 965 1290 1291 1 6 964 683 684 966 1291 1292 1 6 965 684 685 967 1292 1293 1 6 966 685 686 968 1293 1294 1 6 967 686 687 969 1294 1295 1 6 968 687 688 970 1295 1296 1 6 969 688 689 971 1296 1297 1 6 970 689 690 972 1297 1298 1 6 971 690 691 973 1298 1299 1 6 972 691 692 694 974 1299 1 5 973 694 695 975 1299 1 6 974 695 696 976 1299 1300 1 6 975 696 697 977 1300 1301 1 6 976 697 698 978 1301 1302 1 6 977 698 699 979 1302 1303 1 6 978 699 700 980 1303 1304 1 6 979 700 701 981 1304 1305 1 6 980 701 702 982 1305 1306 1 6 981 702 703 983 1306 1307 1 6 982 703 704 984 1307 1308 1 6 983 704 705 985 1308 1309 1 6 984 705 706 986 1309 1310 1 6 985 706 707 987 1310 1311 1 6 986 707 708 988 1311 1312 1 6 987 708 709 989 1312 1313 1 6 988 709 710 990 1313 1314 1 6 989 710 711 991 1314 1315 1 6 990 711 712 992 1315 1316 1 6 991 712 713 993 1316 1317 1 6 992 713 714 994 1317 1318 1 6 993 714 715 995 1318 1319 1 6 994 715 716 996 1319 1320 1 6 995 716 717 997 1320 1321 1 6 996 717 718 998 1321 1322 1 6 997 718 719 999 1322 1323 1 6 998 719 720 1000 1323 1324 1 6 999 720 721 1001 1324 1325 1 6 1000 721 722 1002 1325 1326 1 6 1001 722 723 1003 1326 1327 1 6 1002 723 724 1004 1327 1328 1 6 1003 724 725 1005 1328 1329 1 6 1004 725 726 1006 1329 1330 1 6 1005 726 727 1007 1330 1331 1 6 1006 727 728 1008 1331 1332 1 6 1007 728 729 1009 1332 1333 1 6 1008 729 730 1010 1333 1334 1 6 1009 730 731 1011 1334 1335 2 6 1010 731 732 1012 1335 1336 2 6 1011 732 733 1013 1014 1336 2 6 1012 733 1014 1015 1016 734 2 6 1012 1013 1015 1336 1337 1338 2 6 1014 1013 1016 1338 1339 1340 2 6 1015 1013 734 735 1017 1340 2 6 1016 735 736 1018 1340 1341 2 6 1017 736 737 1019 1341 1342 2 6 1018 737 738 1020 1342 1343 2 6 1019 738 739 1021 1343 1344 2 6 1020 739 740 1022 1344 1345 2 6 1021 740 741 1023 1345 1346 2 6 1022 741 742 743 1024 1346 2 6 1023 743 1025 1346 1347 1348 2 6 1024 743 744 1026 1348 1349 2 6 1025 744 745 1027 1349 1350 2 6 1026 745 746 1028 1350 1351 2 6 1027 746 747 1029 1351 1352 2 6 1028 747 748 1030 1352 1353 2 6 1029 748 749 1031 1353 1354 2 6 1030 749 750 1032 1354 1355 2 6 1031 750 751 1033 1355 1356 2 6 1032 751 752 1034 1356 1357 2 6 1033 752 753 1035 1357 1358 2 6 1034 753 754 1036 1358 1359 2 6 1035 754 755 1037 1359 1360 2 6 1036 755 756 1038 1360 1361 2 6 1037 756 757 1039 1361 1362 1 6 1038 757 758 1040 1362 1363 1 6 1039 758 759 1041 1363 1364 1 6 1040 759 760 1042 1364 1365 1 6 1041 760 761 1043 1365 1366 1 6 1042 761 762 1044 1366 1367 1 6 1043 762 763 1045 1367 1368 1 6 1044 763 764 1046 1368 1369 1 6 1045 764 765 1047 1369 1370 1 6 1046 765 766 1048 1370 1371 1 6 1047 766 767 1049 1371 1372 1 6 1048 767 768 1050 1372 1373 1 6 1049 768 769 1051 1373 1374 1 6 1050 769 770 1052 1374 1375 1 6 1051 770 771 1053 1375 1376 1 6 1052 771 772 1054 1376 1377 1 6 1053 772 773 1055 1377 1378 1 6 1054 773 774 1056 1378 1379 1 6 1055 774 775 1057 1379 1380 1 6 1056 775 776 1058 1380 1381 1 6 1057 776 777 1059 1381 1382 1 6 1058 777 778 1060 1382 1383 1 6 1059 778 779 1061 1383 1384 1 6 1060 779 780 1062 1384 1385 1 6 1061 780 781 1063 1385 1386 1 6 1062 781 782 1064 1386 1387 1 6 1063 782 783 1065 1387 1388 1 6 1064 783 784 1066 1388 1389 1 6 1065 784 785 1067 1389 1390 1 6 1066 785 786 1068 1390 1391 1 6 1067 786 787 1069 1391 1392 1 6 1068 787 788 1070 1392 1393 1 6 1069 788 789 1071 1393 1394 1 6 1070 789 790 1072 1394 1395 1 6 1071 790 791 1073 1395 1396 1 6 1072 791 792 1074 1396 1397 1 6 1073 792 793 1075 1397 1398 1 6 1074 793 794 1076 1398 1399 1 6 1075 794 795 1077 1399 1400 1 6 1076 795 796 1078 1400 1401 1 6 1077 796 797 1079 1401 1402 1 6 1078 797 798 1080 1402 1403 1 6 1079 798 799 1081 1403 1404 1 6 1080 799 800 1082 1404 1405 1 6 1081 800 801 1083 1405 1406 1 6 1082 801 802 1084 1406 1407 1 6 1083 802 803 1085 1407 1408 1 6 1084 803 804 1086 1408 1409 1 6 1085 804 805 1087 1409 1410 1 6 1086 805 806 1088 1410 1411 1 6 1087 806 807 1089 1411 1412 1 6 1088 807 808 1090 1412 1413 1 6 1089 808 809 1091 1413 1414 1 6 1090 809 810 1092 1414 1415 1 6 1091 810 811 1093 1415 1416 1 6 1092 811 812 1094 1416 1417 1 6 1093 812 813 1095 1417 1418 1 6 1094 813 814 1096 1418 1419 1 6 1095 814 815 1097 1419 1420 1 6 1096 815 816 1098 1420 1421 1 6 1097 816 817 1099 1421 1422 1 6 1098 817 818 1100 1422 1423 1 6 1099 818 819 1101 1423 1424 1 6 1100 819 820 1102 1424 1425 1 6 1101 820 821 1103 1425 1426 1 6 1102 821 822 1104 1426 1427 1 6 1103 822 823 1105 1427 1428 1 6 1104 823 824 1106 1428 1429 1 6 1105 824 825 1107 1429 1430 1 6 1106 825 826 1108 1430 1431 1 6 1107 826 827 1109 1431 1432 1 6 1108 827 828 1110 1432 1433 1 6 1109 828 829 1111 1433 1434 1 6 1110 829 830 1112 1434 1435 1 6 1111 830 831 1113 1435 1436 1 6 1112 831 832 1114 1436 1115 1 6 1113 832 833 834 835 1115 1 6 1114 835 1116 1436 1113 1437 1 5 1115 835 836 1117 1437 1 6 1116 836 837 1118 1437 1438 1 6 1117 837 838 1119 1438 1439 1 6 1118 838 839 1120 1439 1440 1 6 1119 839 840 1121 1440 1441 1 6 1120 840 841 1122 1441 1442 1 6 1121 841 842 1123 1442 1443 1 6 1122 842 843 1124 1443 1444 1 6 1123 843 844 1125 1444 1445 1 6 1124 844 845 1126 1445 1446 1 6 1125 845 846 1127 1446 1447 1 6 1126 846 847 1128 1447 1448 1 6 1127 847 848 1129 1448 1449 1 6 1128 848 849 851 1130 1449 1 6 1129 851 1131 1449 1450 1451 1 6 1130 851 852 1132 1451 1452 1 6 1131 852 854 1133 1452 1453 1 6 1132 854 1134 1456 1453 1152 1 6 1133 854 855 856 1135 1152 1 6 1134 856 857 1136 1152 1153 1 6 1135 857 858 1137 1153 1154 1 6 1136 858 859 860 1138 1154 1 6 1137 860 1139 1154 1155 1156 1 6 1138 860 861 1140 1156 1157 1 6 1139 861 862 1141 1157 1158 1 6 1140 862 1142 1158 1159 1143 1 6 1141 862 863 864 865 1143 1 6 1142 865 866 1144 1159 1141 1 6 1143 866 867 1145 1498 1159 1 6 1144 867 869 1146 1498 1499 1 6 1145 869 871 1147 1164 1499 1 6 1146 871 1148 1149 1164 1165 1 6 1147 871 1149 1150 1151 872 1 6 1147 1148 1150 1165 1166 1167 1 6 1149 1148 1151 1167 1168 1169 1 6 1150 1148 872 1169 1170 874 1 6 1134 1135 1153 1473 1456 1133 1 6 1152 1135 1136 1154 1473 1490 1 6 1153 1136 1137 1138 1155 1490 1 6 1154 1138 1156 1490 1491 1492 1 6 1155 1138 1139 1157 1492 1493 1 6 1156 1139 1140 1158 1493 1494 1 6 1157 1140 1141 1159 1497 1494 1 6 1158 1141 1143 1144 1498 1497 2 6 85 86 1161 1483 1484 1488 2 6 1160 86 87 1162 1174 1488 2 6 1161 87 88 1163 1174 1175 2 6 1162 88 89 1175 1177 1186 1 6 1146 1147 1165 1499 1527 1528 1 6 1164 1147 1149 1166 1528 1533 1 6 1165 1149 1167 1535 1533 1541 1 6 1166 1149 1150 1168 1541 1962 1 6 1167 1150 1169 1962 1963 1964 1 6 1168 1150 1151 1170 886 1964 1 6 1169 1151 874 886 879 876 1 6 414 21 22 1172 3337 3882 1 6 1171 22 23 1173 1524 3337 1 6 1172 23 24 1524 1525 1526 2 6 1161 1162 1175 1176 1488 1489 2 6 1174 1162 1176 1163 1177 1178 2 6 1174 1175 1489 1642 1643 1178 2 6 1175 1163 1178 1179 1186 1183 2 6 1175 1177 1179 1180 1643 1176 2 6 1178 1177 1180 1181 1182 1183 2 6 1178 1179 1181 1643 1644 1645 2 6 1180 1179 1182 1645 1646 1647 2 6 1181 1179 1183 1184 3097 1647 2 6 1182 1179 1184 1185 1186 1177 2 6 1182 1183 1185 3097 2241 1187 2 6 1184 1183 1186 90 91 1187 2 6 1185 1183 1177 1163 89 90 2 6 1185 91 92 1188 2241 1184 2 6 1187 92 93 1189 2241 1659 2 6 1188 93 94 1190 1660 1659 2 6 1189 94 95 1191 1662 1660 2 6 1190 95 96 1192 1670 1662 2 6 1191 96 97 1193 1670 1671 2 6 1192 97 98 1194 1671 1672 2 6 1193 98 99 1195 1672 1673 2 6 1194 99 100 1196 1673 1674 2 6 1195 100 101 1197 1674 1675 2 6 1196 101 102 1198 1500 1675 2 6 1197 102 103 1199 1457 1500 2 6 1198 103 104 1200 1457 1458 2 6 1199 104 105 1201 1458 1459 2 6 1200 105 106 1202 1459 1460 2 6 1201 106 107 1203 1460 1685 2 6 1202 107 108 1204 1687 1685 2 6 1203 108 109 1205 1687 1688 2 6 1204 109 110 1206 1688 1689 2 6 1205 110 111 1207 1689 1690 2 6 1206 111 112 1208 1693 1690 1 6 1207 112 113 1209 1693 1694 1 6 1208 113 114 1210 1694 1695 1 6 1209 114 115 1211 1556 1695 1 6 1210 115 116 1212 1546 1556 1 6 1211 116 117 1213 1546 1547 1 6 1212 117 118 1214 1547 1548 1 6 1213 118 119 1215 1548 1549 1 6 1214 119 120 1216 1549 1550 1 6 1215 120 121 1217 1553 1550 1 6 1216 121 122 1218 1555 1553 1 6 1217 122 123 1219 1716 1555 1 6 1218 123 124 1220 1716 1717 1 6 1219 124 125 1221 1717 1718 1 6 1220 125 126 1222 1718 1719 1 6 1221 126 127 1223 1719 1720 1 6 1222 127 128 1224 1720 1721 1 6 1223 128 129 1225 1721 1722 1 6 1224 129 130 1226 1722 1723 1 6 1225 130 131 1227 1726 1723 1 6 1226 131 132 1228 1726 1727 1 6 1227 132 133 1229 1727 1728 1 6 1228 133 134 1230 1728 1729 1 6 1229 134 135 1231 1729 1730 1 6 1230 135 136 1232 1733 1730 1 6 1231 136 137 1233 1733 1734 1 6 1232 137 138 1234 1734 1735 1 6 1233 138 139 1235 1735 1736 1 6 1234 139 140 1236 1736 1737 1 6 1235 140 141 1237 1737 1738 1 6 1236 141 142 1238 1738 1739 1 6 1237 142 143 1239 1739 1740 1 6 1238 143 144 1240 1740 1741 1 6 1239 144 145 1241 1741 1742 1 6 1240 145 146 1242 1742 1743 1 7 1241 146 147 3 148 1243 1743 1 5 1242 148 149 1244 1743 1 6 1243 149 150 1245 1743 1744 1 6 1244 150 151 1246 1744 1745 1 6 1245 151 152 1247 1745 1746 1 6 1246 152 153 1248 1746 1747 1 6 1247 153 154 923 1249 1747 1 6 1248 923 1250 1747 1748 1749 1 6 1249 923 924 1251 1749 1750 1 6 1250 924 925 1252 1750 1751 1 6 1251 925 926 1253 1751 1752 1 6 1252 926 927 1254 1752 1753 1 6 1253 927 928 1255 1753 1754 1 6 1254 928 929 1256 1754 1755 1 6 1255 929 930 1257 1755 1756 1 6 1256 930 931 932 1258 1756 1 6 1257 932 1259 1756 1757 1758 1 6 1258 932 933 1260 1758 1759 1 6 1259 933 934 1261 1759 1760 1 6 1260 934 935 1262 1760 1761 1 6 1261 935 936 1263 1761 1762 1 6 1262 936 937 1264 1762 1763 1 6 1263 937 938 1265 1763 1764 1 6 1264 938 939 1266 1764 1765 1 6 1265 939 940 1267 1765 1766 1 6 1266 940 941 1268 1766 1767 1 6 1267 941 942 1269 1767 1768 1 6 1268 942 943 1270 1768 1769 1 6 1269 943 944 1271 1769 1770 1 6 1270 944 945 1272 1770 1771 1 6 1271 945 946 1273 1771 1772 1 6 1272 946 947 1274 1772 1773 1 6 1273 947 948 1275 1773 1774 1 6 1274 948 949 1276 1774 1775 1 6 1275 949 950 1277 1775 1776 1 6 1276 950 951 1278 1776 1777 1 6 1277 951 952 1279 1777 1778 1 6 1278 952 953 1280 1778 1779 1 6 1279 953 954 1281 1779 1780 1 6 1280 954 955 1282 1780 1781 1 6 1281 955 956 1283 1781 1782 1 6 1282 956 957 1284 1782 1783 1 6 1283 957 958 1285 1783 1784 1 6 1284 958 959 1286 1784 1785 1 6 1285 959 960 1287 1785 1786 1 6 1286 960 961 1288 1786 1787 1 6 1287 961 962 1289 1787 1788 1 6 1288 962 963 1290 1788 1789 1 6 1289 963 964 1291 1789 1790 1 6 1290 964 965 1292 1790 1791 1 6 1291 965 966 1293 1791 1792 1 6 1292 966 967 1294 1792 1793 1 6 1293 967 968 1295 1793 1794 1 6 1294 968 969 1296 1794 1795 1 6 1295 969 970 1297 1795 1796 1 6 1296 970 971 1298 1796 1797 1 6 1297 971 972 1299 1797 1300 1 6 1298 972 973 974 975 1300 1 7 1299 975 976 1301 1797 1298 2100 1 6 1300 976 977 1302 2100 2101 1 6 1301 977 978 1303 2101 2102 1 6 1302 978 979 1304 2102 2103 1 6 1303 979 980 1305 2103 2104 1 6 1304 980 981 1306 2104 2105 1 6 1305 981 982 1307 2105 2106 1 6 1306 982 983 1308 1798 2106 1 6 1307 983 984 1309 1798 1799 1 6 1308 984 985 1310 1799 1800 1 6 1309 985 986 1311 1800 1801 1 6 1310 986 987 1312 1801 1802 1 6 1311 987 988 1313 1802 1803 1 6 1312 988 989 1314 1803 1804 1 6 1313 989 990 1315 1804 1805 1 6 1314 990 991 1316 1805 1806 1 6 1315 991 992 1317 1806 1807 1 6 1316 992 993 1318 1807 1808 1 6 1317 993 994 1319 1808 1809 1 6 1318 994 995 1320 1809 1810 1 6 1319 995 996 1321 1810 1811 1 6 1320 996 997 1322 1811 1812 1 6 1321 997 998 1323 1812 1813 1 6 1322 998 999 1324 1813 1814 1 6 1323 999 1000 1325 1814 1815 1 6 1324 1000 1001 1326 1815 1816 1 6 1325 1001 1002 1327 1816 1817 1 6 1326 1002 1003 1328 1817 1818 1 6 1327 1003 1004 1329 1818 1819 1 6 1328 1004 1005 1330 1819 1820 1 6 1329 1005 1006 1331 1820 1821 1 6 1330 1006 1007 1332 1821 1822 1 6 1331 1007 1008 1333 1822 1823 1 6 1332 1008 1009 1334 1823 1824 1 6 1333 1009 1010 1335 1824 1825 1 6 1334 1010 1011 1336 1825 1826 2 6 1335 1011 1012 1014 1337 1826 2 6 1336 1014 1338 1826 1827 1828 2 6 1337 1014 1015 1339 1828 1829 2 6 1338 1015 1340 1829 1830 1831 2 6 1339 1015 1016 1017 1341 1831 2 6 1340 1017 1018 1342 1831 1832 2 6 1341 1018 1019 1343 1832 1833 2 6 1342 1019 1020 1344 1833 1834 2 6 1343 1020 1021 1345 1834 1835 2 6 1344 1021 1022 1346 1835 1836 2 6 1345 1022 1023 1024 1347 1836 2 6 1346 1024 1348 1836 1837 1838 2 6 1347 1024 1025 1349 1838 1839 2 6 1348 1025 1026 1350 1839 1840 2 6 1349 1026 1027 1351 1840 1841 2 6 1350 1027 1028 1352 1841 1842 2 6 1351 1028 1029 1353 1842 1843 2 6 1352 1029 1030 1354 1843 1844 2 6 1353 1030 1031 1355 1844 1845 2 6 1354 1031 1032 1356 1845 1846 2 6 1355 1032 1033 1357 1846 1847 2 6 1356 1033 1034 1358 1847 1848 2 6 1357 1034 1035 1359 1848 1849 2 6 1358 1035 1036 1360 1849 1850 2 6 1359 1036 1037 1361 1850 1851 2 6 1360 1037 1038 1362 1851 1852 2 6 1361 1038 1039 1363 1852 1853 1 6 1362 1039 1040 1364 1853 1854 1 6 1363 1040 1041 1365 1854 1855 1 6 1364 1041 1042 1366 1855 1856 1 6 1365 1042 1043 1367 1856 1857 1 6 1366 1043 1044 1368 1857 1858 1 6 1367 1044 1045 1369 1858 1859 1 6 1368 1045 1046 1370 1859 1860 1 6 1369 1046 1047 1371 1860 1861 1 6 1370 1047 1048 1372 1861 1862 1 6 1371 1048 1049 1373 1862 1863 1 6 1372 1049 1050 1374 1863 1864 1 6 1373 1050 1051 1375 1864 1865 1 6 1374 1051 1052 1376 1865 1866 1 6 1375 1052 1053 1377 1866 1867 1 6 1376 1053 1054 1378 1867 1868 1 6 1377 1054 1055 1379 1868 1869 1 6 1378 1055 1056 1380 1869 1870 1 6 1379 1056 1057 1381 1870 1871 1 6 1380 1057 1058 1382 1871 1872 1 6 1381 1058 1059 1383 1872 1873 1 6 1382 1059 1060 1384 1873 1874 1 6 1383 1060 1061 1385 1874 1875 1 6 1384 1061 1062 1386 1875 1876 1 6 1385 1062 1063 1387 1876 1877 1 6 1386 1063 1064 1388 1877 1878 1 6 1387 1064 1065 1389 1878 1879 1 6 1388 1065 1066 1390 1879 1880 1 6 1389 1066 1067 1391 1880 1881 1 6 1390 1067 1068 1392 1881 1882 1 6 1391 1068 1069 1393 1882 1883 1 6 1392 1069 1070 1394 1883 1884 1 6 1393 1070 1071 1395 1884 1885 1 6 1394 1071 1072 1396 1885 1886 1 6 1395 1072 1073 1397 1886 1887 1 6 1396 1073 1074 1398 1887 1888 1 6 1397 1074 1075 1399 1888 1889 1 6 1398 1075 1076 1400 1889 1890 1 6 1399 1076 1077 1401 1890 1891 1 6 1400 1077 1078 1402 1891 1892 1 6 1401 1078 1079 1403 1892 1893 1 6 1402 1079 1080 1404 1893 1894 1 6 1403 1080 1081 1405 1894 1895 1 6 1404 1081 1082 1406 1895 1896 1 6 1405 1082 1083 1407 1896 1897 1 6 1406 1083 1084 1408 1897 1898 1 6 1407 1084 1085 1409 1898 1899 1 6 1408 1085 1086 1410 1899 1900 1 6 1409 1086 1087 1411 1900 1901 1 6 1410 1087 1088 1412 1901 1902 1 6 1411 1088 1089 1413 1902 1903 1 6 1412 1089 1090 1414 1903 1904 1 6 1413 1090 1091 1415 1904 1905 1 6 1414 1091 1092 1416 1905 1906 1 6 1415 1092 1093 1417 1906 1907 1 6 1416 1093 1094 1418 1907 1908 1 6 1417 1094 1095 1419 1908 1909 1 6 1418 1095 1096 1420 1909 1910 1 6 1419 1096 1097 1421 1910 1911 1 6 1420 1097 1098 1422 1911 1912 1 6 1421 1098 1099 1423 1912 1913 1 6 1422 1099 1100 1424 1913 1914 1 6 1423 1100 1101 1425 1914 1915 1 6 1424 1101 1102 1426 1915 1916 1 6 1425 1102 1103 1427 1916 1917 1 6 1426 1103 1104 1428 1917 1918 1 6 1427 1104 1105 1429 1918 1919 1 6 1428 1105 1106 1430 1919 1920 1 6 1429 1106 1107 1431 1920 1921 1 6 1430 1107 1108 1432 1921 1922 1 6 1431 1108 1109 1433 1922 1923 1 6 1432 1109 1110 1434 1923 1924 1 6 1433 1110 1111 1435 1924 1925 1 6 1434 1111 1112 1436 1925 1926 1 6 1435 1112 1113 1115 1437 1926 1 6 1436 1115 1116 1117 1438 1926 1 6 1437 1117 1118 1439 1926 1927 1 6 1438 1118 1119 1440 1927 1928 1 6 1439 1119 1120 1441 1928 1929 1 6 1440 1120 1121 1442 1929 1930 1 6 1441 1121 1122 1443 1930 1931 1 6 1442 1122 1123 1444 1931 1932 1 6 1443 1123 1124 1445 1461 1932 1 6 1444 1124 1125 1446 1461 1462 1 6 1445 1125 1126 1447 1462 1463 1 6 1446 1126 1127 1448 1463 1464 1 6 1447 1127 1128 1449 1464 1465 1 6 1448 1128 1129 1130 1450 1465 1 6 1449 1130 1451 1465 1466 1467 1 6 1450 1130 1131 1452 1467 1468 1 6 1451 1131 1132 1453 1454 1468 1 6 1452 1132 1454 1455 1456 1133 1 6 1452 1453 1455 1468 1469 1470 1 6 1454 1453 1456 1470 1471 1472 1 6 1455 1453 1133 1472 1473 1152 2 6 1198 1199 1458 1500 1501 1679 2 6 1457 1199 1200 1459 1679 1680 2 6 1458 1200 1201 1460 1680 1681 2 6 1459 1201 1202 1681 1684 1685 1 6 1444 1445 1462 1932 1933 1934 1 6 1461 1445 1446 1463 1934 1935 1 6 1462 1446 1447 1464 1935 1936 1 6 1463 1447 1448 1465 1936 1937 1 6 1464 1448 1449 1450 1466 1937 1 6 1465 1450 1467 1937 1938 1939 1 6 1466 1450 1451 1468 1939 1940 1 6 1467 1451 1452 1454 1469 1940 1 6 1468 1454 1470 1940 1941 1942 1 6 1469 1454 1455 1471 1942 1943 1 6 1470 1455 1472 1943 1944 1945 1 6 1471 1455 1456 1473 1945 1946 1 6 1472 1456 1152 1153 1490 1946 2 7 76 2 1475 1608 1604 1609 1618 2 6 1474 2 77 1476 1620 1618 2 6 1475 77 78 1477 1620 1621 2 6 1476 78 79 1478 1621 1622 2 6 1477 79 80 1479 1630 1622 2 6 1478 80 81 1480 1630 1631 2 6 1479 81 82 1481 1631 1632 2 6 1480 82 83 1482 1635 1632 2 6 1481 83 84 1483 1485 1635 2 6 1482 84 85 1160 1484 1485 2 6 1483 1160 1485 1486 1487 1488 2 6 1483 1484 1486 1502 1635 1482 2 6 1485 1484 1487 1502 1503 1504 2 6 1486 1484 1488 1504 1505 1489 2 6 1487 1484 1160 1161 1174 1489 2 6 1488 1174 1176 1505 1487 1642 1 6 1473 1153 1154 1155 1491 1946 1 6 1490 1155 1492 1946 1947 1948 1 6 1491 1155 1156 1493 1948 1949 1 6 1492 1156 1157 1494 1495 1949 1 6 1493 1157 1495 1496 1497 1158 1 6 1493 1494 1496 1951 1949 1952 1 6 1495 1494 1497 1952 1530 1529 1 6 1496 1494 1158 1159 1498 1529 1 6 1144 1145 1499 1159 1497 1529 1 6 1498 1145 1146 1164 1527 1529 2 6 1197 1198 1457 1501 1675 1676 2 6 1500 1457 1676 1677 1678 1679 2 6 1485 1486 1503 1637 1634 1635 2 6 1502 1486 1504 1637 1638 1639 2 6 1503 1486 1487 1505 1639 1640 2 6 1504 1487 1489 1640 1641 1642 1 6 583 589 590 1507 1508 582 1 6 1506 590 1508 1509 1513 1514 1 6 1506 1507 1509 1510 1517 582 1 6 1508 1507 1510 1511 1512 1513 1 6 1508 1509 1511 1517 1518 1519 1 6 1510 1509 1512 1523 1519 1537 1 6 1511 1509 1513 1537 1538 1539 1 6 1512 1509 1507 1514 601 1539 1 6 1513 1507 601 599 591 590 1 6 577 578 581 1516 2474 576 1 6 1515 581 1517 1518 1521 2474 1 6 1516 581 582 1508 1510 1518 1 6 1517 1510 1519 1520 1521 1516 1 6 1518 1510 1520 1522 1523 1511 1 6 1518 1519 1521 911 910 1522 1 6 1518 1520 911 1516 2474 914 1 6 910 1520 1519 1523 908 909 1 6 1522 1519 1511 908 1536 1537 1 6 1172 1173 1525 3337 3338 4250 1 6 1524 1173 1526 3130 2205 4250 1 6 1525 1173 24 25 3130 9781 1 6 1499 1164 1528 1529 1530 1531 1 6 1527 1164 1165 1531 1532 1533 1 6 1497 1498 1499 1527 1530 1496 1 6 1529 1527 1531 1952 1496 1953 1 6 1530 1527 1528 1532 1953 1954 1 6 1531 1528 1533 1534 1954 1955 1 6 1532 1528 1534 1535 1166 1165 1 6 1532 1533 1535 1955 1956 1957 1 6 1534 1533 1166 1541 1960 1957 1 6 908 1523 1537 1542 1543 907 1 6 1536 1523 1511 1512 1538 1542 1 6 1537 1512 1539 1540 1545 1542 1 6 1538 1512 1513 601 602 1540 1 6 1539 602 1538 1582 1545 1583 1 6 1535 1166 1167 1960 1961 1962 1 6 1536 1537 1543 1544 1545 1538 1 6 1536 1542 1544 1562 1563 907 1 6 1543 1542 1545 1562 1580 1577 1 6 1544 1542 1538 1582 1580 1540 1 6 1211 1212 1547 1556 1557 1558 1 6 1546 1212 1213 1548 1561 1558 1 6 1547 1213 1214 1549 1710 1561 1 6 1548 1214 1215 1550 1551 1710 1 6 1549 1215 1551 1552 1553 1216 1 6 1549 1550 1552 1710 1711 1712 1 6 1551 1550 1553 1554 1712 1713 1 6 1552 1550 1554 1555 1217 1216 1 6 1552 1553 1555 1713 1714 1715 1 6 1554 1553 1217 1715 1716 1218 1 6 1210 1211 1546 1557 1695 1696 1 6 1556 1546 1558 1559 1696 1697 1 6 1557 1546 1559 1560 1561 1547 1 6 1557 1558 1560 1697 1698 1699 1 6 1559 1558 1561 1699 1700 1709 1 6 1560 1558 1547 1709 1710 1548 1 6 1543 1544 1563 1564 1576 1577 1 6 1543 1562 1564 905 907 906 1 6 1563 1562 905 1565 1566 1576 1 6 905 1564 1566 1567 2085 904 1 6 1565 1564 1567 1568 1569 1576 1 6 1565 1566 1568 2085 3766 3767 1 6 1567 1566 1569 1570 1571 3767 1 6 1568 1566 1570 1574 1575 1576 1 6 1568 1569 1571 1572 1573 1574 1 7 1568 1570 1572 3769 3767 6317 6319 1 5 1571 1570 1573 6319 6320 1 7 1572 1570 1574 6320 6361 6360 2475 1 6 1573 1570 1569 1575 1578 2475 1 6 1574 1569 1576 1577 1578 1579 1 6 1575 1569 1566 1564 1562 1577 1 6 1576 1562 1575 1579 1580 1544 1 6 1574 1575 1579 1586 1587 2475 1 6 1578 1575 1577 1580 1581 1586 1 6 1579 1577 1544 1581 1582 1545 1 6 1579 1580 1582 1584 1585 1586 1 6 1581 1580 1545 1540 1583 1584 1 6 1582 1540 1584 1602 603 602 1 6 1582 1583 1581 1585 1601 1602 1 6 1581 1584 1586 1591 1588 1601 1 6 1581 1585 1579 1578 1587 1588 1 6 1578 1586 1588 1589 2475 2476 1 6 1587 1586 1589 1590 1591 1585 1 6 1587 1588 1590 6354 6353 2476 1 6 1589 1588 1591 1592 1594 6354 1 6 1590 1588 1585 1592 1593 1601 1 6 1590 1591 1593 1594 1595 1596 1 6 1592 1591 1599 1596 1600 1601 1 6 1590 1592 1595 6358 6356 6354 1 6 1594 1592 1596 1597 3970 6358 1 6 1595 1592 1597 1598 1599 1593 1 6 1595 1596 1598 3970 3969 6556 1 6 1597 1596 1599 6556 6557 611 1 6 1598 1596 1593 1600 611 609 1 6 1599 1593 1601 1602 608 609 1 6 1600 1593 1591 1585 1584 1602 1 6 1600 1601 1584 1583 603 608 2 6 74 75 1604 428 1605 1608 2 5 1603 75 76 1608 1474 2 6 428 1603 1606 1607 1608 3519 2 6 428 1605 1607 2493 409 3516 2 6 1606 1605 3518 3516 1613 3519 2 7 1605 1603 1604 1474 1609 1610 3519 2 5 1608 1474 1610 1611 1618 2 6 1608 1609 1611 1612 1613 3519 2 6 1610 1609 1612 1616 1617 1618 2 6 1610 1611 1613 1614 1615 1616 2 7 1610 1612 1614 3518 1607 3519 3523 2 6 1613 1612 1615 3523 3524 3528 2 6 1614 1612 1616 3093 3544 3528 2 6 1615 1612 1611 1617 3093 3094 2 6 1616 1611 1618 1619 3094 1624 2 7 1617 1611 1619 1620 1475 1609 1474 2 6 1617 1618 1620 1621 1623 1624 2 5 1619 1618 1475 1476 1621 2 6 1620 1476 1477 1622 1623 1619 2 6 1621 1477 1623 1629 1630 1478 2 6 1621 1622 1619 1624 1625 1629 2 7 1619 1623 1625 1626 1617 3094 4367 2 6 1624 1623 1626 1627 1628 1629 2 5 1624 1625 1627 4376 4367 2 7 1626 1625 1628 4377 4376 2862 7215 2 6 1627 1625 1629 2861 1633 2862 2 6 1628 1625 1623 1622 1630 2861 2 6 1629 1622 1478 1479 1631 2861 2 6 1630 1479 1480 1632 1633 2861 2 6 1631 1480 1633 1634 1635 1481 2 7 1631 1632 1634 1636 2861 1628 2862 2 6 1633 1632 1635 1636 1637 1502 2 6 1634 1632 1481 1502 1485 1482 2 5 1633 1634 1637 2862 2863 2 7 1636 1634 1502 1503 1638 2863 2864 2 5 1637 1503 1639 2864 2865 2 6 1638 1503 1504 1640 2865 2866 2 6 1639 1504 1505 1641 2866 2867 2 6 1640 1505 1642 2479 2490 2867 2 6 1641 1505 1489 1176 1643 2479 2 6 1642 1176 1178 1180 1644 2479 2 6 1643 1180 1645 2479 2480 2481 2 6 1644 1180 1181 1646 2481 1650 2 6 1645 1181 1647 1648 1649 1650 2 6 1646 1181 1648 1655 3097 1182 2 6 1646 1647 1649 1653 1654 1655 2 6 1646 1648 1650 1651 1652 1653 2 6 1646 1649 1651 2481 1645 2495 2 6 1650 1649 1652 2495 2496 2497 2 6 1651 1649 1653 2497 2498 2499 2 6 1652 1649 1648 1654 2499 2500 2 6 1653 1648 1655 1656 2500 2501 2 6 1654 1648 1647 1656 1657 3097 2 6 1654 1655 1657 1658 2501 2812 2 6 1656 1655 1658 1659 2241 3097 2 6 1656 1657 1659 1660 1661 2812 2 6 1658 1657 1660 1189 1188 2241 2 6 1658 1659 1661 1662 1190 1189 2 6 1658 1660 1662 1663 1664 2812 2 6 1661 1660 1663 1670 1191 1190 2 6 1661 1662 1664 1665 1669 1670 2 6 1661 1663 1665 1666 2812 2811 2 6 1664 1663 1666 1667 1668 1669 2 6 1664 1665 1667 2811 2813 2814 2 6 1666 1665 1668 2814 2815 2816 2 6 1667 1665 1669 2816 2821 2822 2 6 1668 1665 1663 1670 1671 2822 2 6 1669 1663 1662 1191 1192 1671 2 6 1670 1192 1193 1672 2822 1669 2 6 1671 1193 1194 1673 2823 2822 2 6 1672 1194 1195 1674 3147 2823 2 6 1673 1195 1196 1675 3147 3412 2 6 1674 1196 1197 1500 1676 3412 2 6 1675 1500 1501 1677 3412 3413 2 6 1676 1501 1678 3413 3414 3415 2 6 1677 1501 1679 3415 5381 5382 2 6 1678 1501 1457 1458 1680 5381 2 6 1679 1458 1459 1681 1682 5381 2 6 1680 1459 1460 1682 1683 1684 2 6 1680 1681 1683 3774 5383 5381 2 6 1682 1681 1684 3774 3775 3776 2 6 1683 1681 1460 1685 1686 3776 2 6 1684 1460 1686 1687 1203 1202 2 6 1684 1685 1687 3776 3777 3781 2 6 1686 1685 1203 1204 1688 3781 2 6 1687 1204 1205 1689 3781 3782 2 6 1688 1205 1206 1690 1691 3782 2 6 1689 1206 1691 1692 1693 1207 2 6 1689 1690 1692 3782 3783 3784 2 6 1691 1690 1693 3784 3785 3786 2 6 1692 1690 1207 1208 1694 3786 1 6 1693 1208 1209 1695 3786 3416 1 6 1694 1209 1210 1556 1696 3416 1 6 1695 1556 1557 1697 3416 3417 1 6 1696 1557 1559 1698 3417 3418 1 6 1697 1559 1699 1703 2223 3418 1 6 1698 1559 1560 1700 1701 1703 1 6 1699 1560 1701 1702 1708 1709 1 6 1699 1700 1702 1703 1704 1705 1 6 1701 1700 1705 1706 1707 1708 1 6 1699 1701 1704 1698 2223 2224 1 6 1703 1701 1705 2224 2225 2226 1 6 1704 1701 1702 1706 2226 2227 1 6 1705 1702 1707 2227 2228 2229 1 6 1706 1702 1708 2229 2230 2231 1 6 1707 1702 1700 1709 1711 2231 1 6 1708 1700 1560 1561 1710 1711 1 6 1709 1561 1548 1549 1551 1711 1 6 1710 1551 1712 2231 1708 1709 1 6 1711 1551 1552 1713 2232 2231 1 6 1712 1552 1554 1714 2240 2232 1 6 1713 1554 1715 2240 2560 2564 1 6 1714 1554 1555 1716 2564 2565 1 6 1715 1555 1218 1219 1717 2565 1 6 1716 1219 1220 1718 2565 2566 1 6 1717 1220 1221 1719 2569 2566 1 6 1718 1221 1222 1720 3463 2569 1 6 1719 1222 1223 1721 3462 3463 1 6 1720 1223 1224 1722 3469 3462 1 6 1721 1224 1225 1723 1724 3469 1 6 1722 1225 1724 1725 1726 1226 1 6 1722 1723 1725 2172 3467 3469 1 6 1724 1723 1726 2172 2173 2174 1 6 1725 1723 1226 1227 1727 2174 1 6 1726 1227 1228 1728 2174 2175 1 6 1727 1228 1229 1729 2175 2176 1 6 1728 1229 1230 1730 1731 2176 1 6 1729 1230 1731 1732 1733 1231 1 6 1729 1730 1732 2178 2176 2808 1 6 1731 1730 1733 3404 2808 3405 1 6 1732 1730 1231 1232 1734 3405 1 6 1733 1232 1233 1735 3405 3406 1 6 1734 1233 1234 1736 3406 3407 1 6 1735 1234 1235 1737 3407 3408 1 6 1736 1235 1236 1738 3408 3409 1 6 1737 1236 1237 1739 3409 3410 1 6 1738 1237 1238 1740 3410 3411 1 6 1739 1238 1239 1741 3197 3411 1 6 1740 1239 1240 1742 3191 3197 1 6 1741 1240 1241 1743 3191 1744 1 6 1742 1241 1242 1243 1244 1744 1 7 1743 1244 1245 1745 3191 1742 3199 1 6 1744 1245 1246 1746 2893 3199 1 6 1745 1246 1247 1747 2751 2893 1 6 1746 1247 1248 1249 1748 2751 1 6 1747 1249 1749 2233 2751 2752 1 6 1748 1249 1250 1750 2233 2234 1 6 1749 1250 1251 1751 2237 2234 1 6 1750 1251 1252 1752 2247 2237 1 6 1751 1252 1253 1753 2247 2253 1 6 1752 1253 1254 1754 2253 2254 1 6 1753 1254 1255 1755 2254 2255 1 6 1754 1255 1256 1756 2255 2256 1 6 1755 1256 1257 1258 1757 2256 1 6 1756 1258 1758 2256 2257 2258 1 6 1757 1258 1259 1759 2258 2259 1 6 1758 1259 1260 1760 2259 2260 1 6 1759 1260 1261 1761 2260 2261 1 6 1760 1261 1262 1762 2261 2262 1 6 1761 1262 1263 1763 2262 2263 1 6 1762 1263 1264 1764 2263 2264 1 6 1763 1264 1265 1765 2264 2265 1 6 1764 1265 1266 1766 2265 2266 1 6 1765 1266 1267 1767 2266 2267 1 6 1766 1267 1268 1768 2267 2268 1 6 1767 1268 1269 1769 2268 2269 1 6 1768 1269 1270 1770 2269 2270 1 6 1769 1270 1271 1771 2270 2271 1 6 1770 1271 1272 1772 2271 2272 1 6 1771 1272 1273 1773 2272 2273 1 6 1772 1273 1274 1774 2273 2274 1 6 1773 1274 1275 1775 2274 2275 1 6 1774 1275 1276 1776 2275 2276 1 6 1775 1276 1277 1777 2276 2277 1 6 1776 1277 1278 1778 2277 2278 1 6 1777 1278 1279 1779 2278 2279 1 6 1778 1279 1280 1780 2279 2280 1 6 1779 1280 1281 1781 2280 2281 1 6 1780 1281 1282 1782 2281 2282 1 6 1781 1282 1283 1783 2282 2283 1 6 1782 1283 1284 1784 2283 2284 1 6 1783 1284 1285 1785 2284 2285 1 6 1784 1285 1286 1786 2285 2286 1 6 1785 1286 1287 1787 2286 2287 1 6 1786 1287 1288 1788 2287 2288 1 6 1787 1288 1289 1789 2288 2289 1 6 1788 1289 1290 1790 2289 2290 1 6 1789 1290 1291 1791 2290 2291 1 6 1790 1291 1292 1792 2291 2292 1 6 1791 1292 1293 1793 2292 2293 1 6 1792 1293 1294 1794 2293 2294 1 6 1793 1294 1295 1795 2294 2295 1 6 1794 1295 1296 1796 2098 2295 1 6 1795 1296 1297 1797 2098 2099 1 6 1796 1297 1298 1300 2099 2100 1 6 1307 1308 1799 2106 2107 2108 1 6 1798 1308 1309 1800 2108 2109 1 6 1799 1309 1310 1801 2109 2110 1 6 1800 1310 1311 1802 2110 2111 1 6 1801 1311 1312 1803 2111 2112 1 6 1802 1312 1313 1804 2112 2113 1 6 1803 1313 1314 1805 2113 2114 1 6 1804 1314 1315 1806 2114 2115 1 6 1805 1315 1316 1807 2115 2116 1 6 1806 1316 1317 1808 2116 2117 1 6 1807 1317 1318 1809 2117 2118 1 6 1808 1318 1319 1810 2118 2119 1 6 1809 1319 1320 1811 2119 2120 1 6 1810 1320 1321 1812 2120 2121 1 6 1811 1321 1322 1813 2121 2122 1 6 1812 1322 1323 1814 2122 2123 1 6 1813 1323 1324 1815 2123 2124 1 6 1814 1324 1325 1816 2124 2125 1 6 1815 1325 1326 1817 2125 2126 1 6 1816 1326 1327 1818 2126 2127 1 6 1817 1327 1328 1819 2127 2128 1 6 1818 1328 1329 1820 2128 2129 1 6 1819 1329 1330 1821 2129 2130 1 6 1820 1330 1331 1822 2130 2131 1 6 1821 1331 1332 1823 2131 2132 1 6 1822 1332 1333 1824 2132 2133 1 6 1823 1333 1334 1825 2133 2134 1 6 1824 1334 1335 1826 2134 2135 2 6 1825 1335 1336 1337 1827 2135 2 6 1826 1337 1828 2135 2136 2137 2 6 1827 1337 1338 1829 2137 2138 2 6 1828 1338 1339 1830 2138 2139 2 6 1829 1339 1831 2139 2140 2141 2 6 1830 1339 1340 1341 1832 2141 2 6 1831 1341 1342 1833 2141 2142 2 6 1832 1342 1343 1834 2142 2143 2 6 1833 1343 1344 1835 2143 2144 2 6 1834 1344 1345 1836 2144 2145 2 6 1835 1345 1346 1347 1837 2145 2 6 1836 1347 1838 2150 2145 2165 2 6 1837 1347 1348 1839 2165 2166 2 6 1838 1348 1349 1840 2166 2167 2 6 1839 1349 1350 1841 2167 2168 2 6 1840 1350 1351 1842 2171 2168 2 6 1841 1351 1352 1843 2349 2171 2 6 1842 1352 1353 1844 2349 2350 2 6 1843 1353 1354 1845 2350 2351 2 6 1844 1354 1355 1846 2351 2352 2 6 1845 1355 1356 1847 2352 2353 2 6 1846 1356 1357 1848 2353 2354 2 6 1847 1357 1358 1849 2354 2355 2 6 1848 1358 1359 1850 2355 2356 2 6 1849 1359 1360 1851 2356 2357 2 6 1850 1360 1361 1852 2357 2358 2 6 1851 1361 1362 1853 2358 2359 2 6 1852 1362 1363 1854 2359 2360 1 6 1853 1363 1364 1855 2360 2361 1 6 1854 1364 1365 1856 1966 2361 1 6 1855 1365 1366 1857 1966 1967 1 6 1856 1366 1367 1858 1967 1968 1 6 1857 1367 1368 1859 1968 1969 1 6 1858 1368 1369 1860 1969 1970 1 6 1859 1369 1370 1861 1970 1971 1 6 1860 1370 1371 1862 1971 1972 1 6 1861 1371 1372 1863 1972 1973 1 6 1862 1372 1373 1864 1973 1974 1 6 1863 1373 1374 1865 1974 1975 1 6 1864 1374 1375 1866 1975 1976 1 6 1865 1375 1376 1867 1976 1977 1 6 1866 1376 1377 1868 1977 1978 1 6 1867 1377 1378 1869 1978 1979 1 6 1868 1378 1379 1870 1979 1980 1 6 1869 1379 1380 1871 1980 1981 1 6 1870 1380 1381 1872 1981 1982 1 6 1871 1381 1382 1873 1982 1983 1 6 1872 1382 1383 1874 1983 1984 1 6 1873 1383 1384 1875 1984 1985 1 6 1874 1384 1385 1876 1985 1986 1 6 1875 1385 1386 1877 1986 1987 1 6 1876 1386 1387 1878 1987 1988 1 6 1877 1387 1388 1879 1988 1989 1 6 1878 1388 1389 1880 1989 1990 1 6 1879 1389 1390 1881 1990 1991 1 6 1880 1390 1391 1882 1991 1992 1 6 1881 1391 1392 1883 1992 1993 1 6 1882 1392 1393 1884 1993 1994 1 6 1883 1393 1394 1885 1994 1995 1 6 1884 1394 1395 1886 1995 1996 1 6 1885 1395 1396 1887 1996 1997 1 6 1886 1396 1397 1888 1997 1998 1 6 1887 1397 1398 1889 1998 1999 1 6 1888 1398 1399 1890 1999 2000 1 6 1889 1399 1400 1891 2000 2001 1 6 1890 1400 1401 1892 2001 2002 1 6 1891 1401 1402 1893 2002 2003 1 6 1892 1402 1403 1894 2003 2004 1 6 1893 1403 1404 1895 2004 2005 1 6 1894 1404 1405 1896 2005 2006 1 6 1895 1405 1406 1897 2006 2007 1 6 1896 1406 1407 1898 2007 2008 1 6 1897 1407 1408 1899 2008 2009 1 6 1898 1408 1409 1900 2009 2010 1 6 1899 1409 1410 1901 2010 2011 1 6 1900 1410 1411 1902 2011 2012 1 6 1901 1411 1412 1903 2012 2013 1 6 1902 1412 1413 1904 2013 2014 1 6 1903 1413 1414 1905 2014 2015 1 6 1904 1414 1415 1906 2015 2016 1 6 1905 1415 1416 1907 2016 2017 1 6 1906 1416 1417 1908 2017 2018 1 6 1907 1417 1418 1909 2018 2019 1 6 1908 1418 1419 1910 2019 2020 1 6 1909 1419 1420 1911 2020 2021 1 6 1910 1420 1421 1912 2021 2022 1 6 1911 1421 1422 1913 2022 2023 1 6 1912 1422 1423 1914 2023 2024 1 6 1913 1423 1424 1915 2024 2025 1 6 1914 1424 1425 1916 2025 2026 1 6 1915 1425 1426 1917 2026 2027 1 6 1916 1426 1427 1918 2027 2028 1 6 1917 1427 1428 1919 2028 2029 1 6 1918 1428 1429 1920 2029 2030 1 6 1919 1429 1430 1921 2030 2031 1 6 1920 1430 1431 1922 2031 2032 1 6 1921 1431 1432 1923 2032 2033 1 6 1922 1432 1433 1924 2033 2034 1 6 1923 1433 1434 1925 2034 2035 1 6 1924 1434 1435 1926 2035 1927 1 6 1925 1435 1436 1437 1438 1927 1 7 1926 1438 1439 1928 2035 1925 2036 1 6 1927 1439 1440 1929 2036 2037 1 6 1928 1440 1441 1930 2037 2038 1 6 1929 1441 1442 1931 2038 2039 1 6 1930 1442 1443 1932 2039 2040 1 7 1931 1443 1444 1461 1933 2040 2041 1 5 1932 1461 1934 2041 2042 1 6 1933 1461 1462 1935 2042 2043 1 6 1934 1462 1463 1936 2043 2044 1 6 1935 1463 1464 1937 2044 2045 1 6 1936 1464 1465 1466 1938 2045 1 6 1937 1466 1939 2045 2046 2047 1 6 1938 1466 1467 1940 2047 2048 1 6 1939 1467 1468 1469 1941 2048 1 6 1940 1469 1942 2048 2049 2050 1 6 1941 1469 1470 1943 2050 2051 1 6 1942 1470 1471 1944 2051 2052 1 6 1943 1471 1945 2052 2053 2054 1 6 1944 1471 1472 1946 2054 1947 1 6 1945 1472 1473 1490 1491 1947 1 6 1946 1491 1948 2054 1945 2055 1 6 1947 1491 1492 1949 1950 2055 1 6 1948 1492 1950 1951 1495 1493 1 6 1948 1949 1951 2055 2056 2057 1 6 1950 1949 1495 1952 2057 2058 1 6 1951 1495 1496 1530 1953 2058 1 6 1952 1530 1531 1954 2058 2059 1 6 1953 1531 1532 1955 2059 2060 1 6 1954 1532 1534 1956 2060 2061 1 6 1955 1534 1957 1958 2061 2062 1 6 1956 1534 1958 1959 1960 1535 1 6 1956 1957 1959 2062 2063 2064 1 6 1958 1957 1960 2064 2065 2066 1 6 1959 1957 1535 1541 1961 2066 1 6 1960 1541 1962 2066 2067 2068 1 6 1961 1541 1167 1168 1963 2068 1 6 1962 1168 1964 1965 2070 2068 1 6 1963 1168 1965 887 886 1169 1 6 1963 1964 887 2072 2070 2075 1 6 1855 1856 1967 2361 2362 2363 1 6 1966 1856 1857 1968 2363 2364 1 6 1967 1857 1858 1969 2364 2365 1 6 1968 1858 1859 1970 2365 2366 1 6 1969 1859 1860 1971 2366 2367 1 6 1970 1860 1861 1972 2367 2368 1 6 1971 1861 1862 1973 2368 2369 1 6 1972 1862 1863 1974 2369 2370 1 6 1973 1863 1864 1975 2370 2371 1 6 1974 1864 1865 1976 2371 2372 1 6 1975 1865 1866 1977 2372 2373 1 6 1976 1866 1867 1978 2373 2374 1 6 1977 1867 1868 1979 2374 2375 1 6 1978 1868 1869 1980 2375 2376 1 6 1979 1869 1870 1981 2376 2377 1 6 1980 1870 1871 1982 2377 2378 1 6 1981 1871 1872 1983 2378 2379 1 6 1982 1872 1873 1984 2379 2380 1 6 1983 1873 1874 1985 2380 2381 1 6 1984 1874 1875 1986 2381 2382 1 6 1985 1875 1876 1987 2382 2383 1 6 1986 1876 1877 1988 2383 2384 1 6 1987 1877 1878 1989 2384 2385 1 6 1988 1878 1879 1990 2385 2386 1 6 1989 1879 1880 1991 2386 2387 1 6 1990 1880 1881 1992 2387 2388 1 6 1991 1881 1882 1993 2388 2389 1 6 1992 1882 1883 1994 2389 2390 1 6 1993 1883 1884 1995 2390 2391 1 6 1994 1884 1885 1996 2391 2392 1 6 1995 1885 1886 1997 2392 2393 1 6 1996 1886 1887 1998 2393 2394 1 6 1997 1887 1888 1999 2394 2395 1 6 1998 1888 1889 2000 2395 2396 1 6 1999 1889 1890 2001 2396 2397 1 6 2000 1890 1891 2002 2397 2398 1 6 2001 1891 1892 2003 2398 2399 1 6 2002 1892 1893 2004 2399 2400 1 6 2003 1893 1894 2005 2400 2401 1 6 2004 1894 1895 2006 2401 2402 1 6 2005 1895 1896 2007 2402 2403 1 6 2006 1896 1897 2008 2403 2404 1 6 2007 1897 1898 2009 2404 2405 1 6 2008 1898 1899 2010 2405 2406 1 6 2009 1899 1900 2011 2406 2407 1 6 2010 1900 1901 2012 2407 2408 1 6 2011 1901 1902 2013 2408 2409 1 6 2012 1902 1903 2014 2409 2410 1 6 2013 1903 1904 2015 2410 2411 1 6 2014 1904 1905 2016 2411 2412 1 6 2015 1905 1906 2017 2412 2413 1 6 2016 1906 1907 2018 2413 2414 1 6 2017 1907 1908 2019 2414 2415 1 6 2018 1908 1909 2020 2415 2416 1 6 2019 1909 1910 2021 2416 2417 1 6 2020 1910 1911 2022 2417 2418 1 6 2021 1911 1912 2023 2418 2419 1 6 2022 1912 1913 2024 2419 2420 1 6 2023 1913 1914 2025 2420 2421 1 6 2024 1914 1915 2026 2421 2422 1 6 2025 1915 1916 2027 2422 2423 1 6 2026 1916 1917 2028 2423 2424 1 6 2027 1917 1918 2029 2424 2425 1 6 2028 1918 1919 2030 2425 2426 1 6 2029 1919 1920 2031 2426 2427 1 6 2030 1920 1921 2032 2427 2428 1 6 2031 1921 1922 2033 2428 2429 1 6 2032 1922 1923 2034 2429 2430 1 6 2033 1923 1924 2035 2430 2431 1 6 2034 1924 1925 1927 2036 2431 1 5 2035 1927 1928 2037 2431 1 6 2036 1928 1929 2038 2431 2432 1 6 2037 1929 1930 2039 2432 2433 1 6 2038 1930 1931 2040 2433 2434 1 7 2039 1931 1932 2041 2434 2435 2436 1 5 2040 1932 1933 2042 2436 1 7 2041 1933 1934 2043 2436 2437 2438 1 6 2042 1934 1935 2044 2438 2439 1 6 2043 1935 1936 2045 2439 2440 1 6 2044 1936 1937 1938 2046 2440 1 6 2045 1938 2047 2440 2441 2442 1 6 2046 1938 1939 2048 2442 2443 1 6 2047 1939 1940 1941 2049 2443 1 6 2048 1941 2050 2443 2444 2448 1 6 2049 1941 1942 2051 2448 2449 1 6 2050 1942 1943 2052 2449 2450 1 6 2051 1943 1944 2053 2450 2451 1 6 2052 1944 2054 2451 2452 2453 1 6 2053 1944 1945 1947 2055 2453 1 6 2054 1947 1948 1950 2056 2453 1 6 2055 1950 2057 2453 2454 2455 1 6 2056 1950 1951 2058 2455 2456 1 6 2057 1951 1952 1953 2059 2456 1 6 2058 1953 1954 2060 2456 2457 1 6 2059 1954 1955 2061 2457 2458 1 6 2060 1955 1956 2062 2458 2459 1 6 2061 1956 1958 2063 2459 2460 1 6 2062 1958 2064 2460 2461 2462 1 6 2063 1958 1959 2065 2462 2463 1 6 2064 1959 2066 2463 2464 2465 1 6 2065 1959 1960 1961 2067 2465 1 6 2066 1961 2068 2069 2465 2466 1 6 2067 1961 1962 2069 2070 1963 1 6 2067 2068 2070 2071 2466 2469 1 6 2069 2068 1963 2071 2072 1965 1 6 2069 2070 2072 2073 2469 2470 1 6 2071 2070 1965 2073 2074 2075 1 6 2071 2072 2074 2473 2470 2086 1 6 2073 2072 2075 2076 2078 2086 1 6 2074 2072 1965 887 888 2076 1 6 2075 888 889 2077 2078 2074 1 6 2076 889 2078 2079 2080 2081 1 6 2076 2077 2079 2074 2086 2087 1 6 2078 2077 2080 2096 2087 2082 1 6 2079 2077 2081 898 901 2082 1 6 2080 2077 889 890 894 898 1 6 2080 901 903 2083 2096 2079 1 6 2082 903 2084 2096 2095 9776 1 6 2083 903 904 2085 6093 9776 1 6 2084 904 1565 1567 3766 6093 1 6 2074 2078 2087 2088 2473 2073 1 6 2086 2078 2088 2089 2096 2079 1 6 2086 2087 2089 2090 2091 2473 1 6 2088 2087 2090 2094 2095 2096 1 6 2088 2089 2091 2092 2093 2094 1 6 2088 2090 2092 2489 2472 2473 1 6 2091 2090 2093 2489 5947 5948 1 6 2092 2090 2094 3135 5947 3132 1 6 2093 2090 2089 2095 3131 3132 1 6 2094 2089 2096 3131 2083 9776 1 6 2095 2089 2087 2079 2082 2083 1 6 631 403 633 650 649 404 1 6 1795 1796 2099 2295 2296 2297 1 6 2098 1796 1797 2100 2297 2101 1 5 2099 1797 1300 1301 2101 1 6 2100 1301 1302 2102 2297 2099 1 6 2101 1302 1303 2103 2297 2298 1 6 2102 1303 1304 2104 2298 2299 1 6 2103 1304 1305 2105 2299 2300 1 6 2104 1305 1306 2106 2300 2301 1 7 2105 1306 1307 1798 2107 2301 2302 1 5 2106 1798 2108 2302 2303 1 6 2107 1798 1799 2109 2303 2304 1 6 2108 1799 1800 2110 2304 2305 1 6 2109 1800 1801 2111 2305 2306 1 6 2110 1801 1802 2112 2306 2307 1 6 2111 1802 1803 2113 2307 2308 1 6 2112 1803 1804 2114 2308 2309 1 6 2113 1804 1805 2115 2309 2310 1 6 2114 1805 1806 2116 2310 2311 1 6 2115 1806 1807 2117 2311 2312 1 6 2116 1807 1808 2118 2312 2313 1 6 2117 1808 1809 2119 2313 2314 1 6 2118 1809 1810 2120 2314 2315 1 6 2119 1810 1811 2121 2315 2316 1 6 2120 1811 1812 2122 2316 2317 1 6 2121 1812 1813 2123 2317 2318 1 6 2122 1813 1814 2124 2318 2319 1 6 2123 1814 1815 2125 2319 2320 1 6 2124 1815 1816 2126 2320 2321 1 6 2125 1816 1817 2127 2321 2322 1 6 2126 1817 1818 2128 2322 2323 1 6 2127 1818 1819 2129 2323 2324 1 6 2128 1819 1820 2130 2324 2325 1 6 2129 1820 1821 2131 2325 2326 1 6 2130 1821 1822 2132 2326 2327 1 6 2131 1822 1823 2133 2151 2327 1 6 2132 1823 1824 2134 2151 2152 1 6 2133 1824 1825 2135 2152 2153 1 6 2134 1825 1826 1827 2136 2153 2 6 2135 1827 2137 2153 2154 2155 2 6 2136 1827 1828 2138 2155 2156 2 6 2137 1828 1829 2139 2156 2157 2 6 2138 1829 1830 2140 2157 2158 2 6 2139 1830 2141 2146 2158 2159 2 6 2140 1830 1831 1832 2142 2146 2 6 2141 1832 1833 2143 2146 2147 2 6 2142 1833 1834 2144 2147 2148 2 6 2143 1834 1835 2145 2148 2149 2 6 2144 1835 1836 2149 2150 1837 2 6 2140 2141 2142 2147 2159 2160 2 6 2146 2142 2143 2148 2160 2161 2 6 2147 2143 2144 2149 2161 2162 2 6 2148 2144 2145 2150 2162 2163 2 6 2149 2145 1837 2163 2164 2165 1 6 2132 2133 2152 2327 2328 2329 1 6 2151 2133 2134 2153 2329 2330 1 6 2152 2134 2135 2136 2154 2330 2 6 2153 2136 2155 2330 2331 2332 2 6 2154 2136 2137 2156 2332 2333 2 6 2155 2137 2138 2157 2333 2334 2 6 2156 2138 2139 2158 2334 2335 2 6 2157 2139 2140 2159 2335 2336 2 6 2158 2140 2146 2160 2336 2337 2 6 2159 2146 2147 2161 2337 2338 2 6 2160 2147 2148 2162 2338 2339 2 6 2161 2148 2149 2163 2339 2340 2 6 2162 2149 2150 2164 2340 2341 2 6 2163 2150 2165 2341 2342 2343 2 6 2164 2150 1837 1838 2166 2343 2 6 2165 1838 1839 2167 2343 2344 2 6 2166 1839 1840 2168 2169 2344 2 6 2167 1840 2169 2170 2171 1841 2 6 2167 2168 2170 2344 2345 2346 2 6 2169 2168 2171 2346 2347 2348 2 6 2170 2168 1841 2348 2349 1842 1 6 1724 1725 2173 3468 3467 4747 1 6 2172 1725 2174 2804 3395 4747 1 6 2173 1725 1726 1727 2175 2804 1 6 2174 1727 1728 2176 2177 2804 1 6 2175 1728 2177 2178 1731 1729 1 6 2175 2176 2178 2804 2805 2806 1 6 2177 2176 1731 2806 2807 2808 1 6 27 28 2180 2181 3851 3852 1 6 2179 28 29 2181 2182 2503 1 6 2179 2180 2182 2183 2199 3851 1 6 2181 2180 2183 2184 2502 2503 1 6 2181 2182 2184 2185 2198 2199 1 6 2183 2182 2185 2186 2193 2502 1 6 2183 2184 2186 2187 2197 2198 1 6 2185 2184 2187 2188 2192 2193 1 6 2185 2186 2188 2189 2197 9713 1 6 2187 2186 2189 2190 2191 2192 1 7 2187 2188 2190 9709 9708 9712 9713 1 5 2189 2188 2191 9710 9709 1 6 2190 2188 2192 2510 2512 9710 1 6 2191 2188 2186 2193 2510 2506 1 6 2192 2186 2184 2502 2504 2506 1 6 415 39 40 2195 9704 6488 1 6 2194 40 41 2196 6488 9705 1 7 2195 41 42 9705 43 9771 9773 1 6 2185 2187 2198 9713 9714 9720 1 6 2185 2197 2183 2199 2200 9720 1 6 2183 2198 2200 2201 2181 3851 1 6 2199 2198 2201 2202 9720 2217 1 6 2199 2200 2202 2203 3129 3851 1 6 2201 2200 2203 2204 2217 2208 1 6 2201 2202 2204 2205 3129 3130 1 6 2203 2202 2205 2206 2207 2208 1 6 2203 2204 2206 3130 1525 4250 1 6 2205 2204 2207 3343 3341 4250 1 6 2206 2204 2208 2209 3343 3344 1 6 2207 2204 2209 2210 2217 2202 1 6 2207 2208 2210 2211 3344 3345 1 6 2209 2208 2211 2212 2216 2217 1 6 2209 2210 2212 2213 3348 3345 1 6 2211 2210 2213 2214 2215 2216 1 6 2211 2212 2214 6522 6523 3348 1 6 2213 2212 2215 9716 9719 6522 1 6 2214 2212 2216 9716 9715 9714 1 6 2215 2212 2210 2217 9714 9720 1 6 2216 2210 2208 2202 9720 2200 1 6 408 59 60 2219 2545 2546 1 6 2218 60 61 2220 2549 2546 1 6 2219 61 62 2221 2549 2551 1 6 2220 62 63 2222 2551 6702 1 6 2221 63 6701 6700 6702 64 1 6 1698 1703 2224 3418 3419 3420 1 6 2223 1703 1704 2225 3420 3421 1 6 2224 1704 2226 3421 3422 3426 1 6 2225 1704 1705 2227 3426 3427 1 6 2226 1705 1706 2228 3427 3428 1 6 2227 1706 2229 3428 3429 3430 1 6 2228 1706 1707 2230 2238 3430 1 6 2229 1707 2231 2232 2238 2239 1 6 2230 1707 2232 1712 1711 1708 1 6 2230 2231 1712 2239 2240 1713 1 6 1748 1749 2234 2235 2242 2752 1 6 2233 1749 2235 2236 2237 1750 1 6 2233 2234 2236 2242 2243 2244 1 6 2235 2234 2237 2244 2245 2246 1 6 2236 2234 1750 2246 2247 1751 1 6 2229 2230 2239 3430 3431 3435 1 6 2238 2230 2232 2240 3435 2561 1 6 2239 2232 1713 1714 2560 2561 2 6 1187 1188 1659 1657 3097 1184 1 6 2233 2235 2243 2752 2753 2754 1 6 2242 2235 2244 2754 2755 2756 1 6 2243 2235 2236 2245 2756 2757 1 6 2244 2236 2246 2757 2758 2759 1 6 2245 2236 2237 2247 2759 2760 1 6 2246 2237 1751 1752 2253 2760 1 6 34 35 2249 3331 3332 3333 1 6 2248 35 36 2250 3336 3333 1 6 2249 36 37 416 2251 3336 1 7 2250 416 2252 6490 6491 9706 3336 1 5 2251 416 415 6490 9704 1 6 2247 1752 1753 2254 2760 2761 1 6 2253 1753 1754 2255 2761 2762 1 6 2254 1754 1755 2256 2762 2763 1 6 2255 1755 1756 1757 2257 2763 1 6 2256 1757 2258 2763 2764 2765 1 6 2257 1757 1758 2259 2765 2766 1 6 2258 1758 1759 2260 2766 2767 1 6 2259 1759 1760 2261 2767 2768 1 6 2260 1760 1761 2262 2768 2769 1 6 2261 1761 1762 2263 2571 2769 1 6 2262 1762 1763 2264 2571 2572 1 6 2263 1763 1764 2265 2572 2573 1 6 2264 1764 1765 2266 2573 2574 1 6 2265 1765 1766 2267 2574 2575 1 6 2266 1766 1767 2268 2575 2576 1 6 2267 1767 1768 2269 2576 2577 1 6 2268 1768 1769 2270 2577 2578 1 6 2269 1769 1770 2271 2578 2579 1 6 2270 1770 1771 2272 2579 2580 1 6 2271 1771 1772 2273 2580 2581 1 6 2272 1772 1773 2274 2581 2582 1 6 2273 1773 1774 2275 2582 2583 1 6 2274 1774 1775 2276 2583 2584 1 6 2275 1775 1776 2277 2584 2585 1 6 2276 1776 1777 2278 2585 2586 1 6 2277 1777 1778 2279 2586 2587 1 6 2278 1778 1779 2280 2587 2588 1 6 2279 1779 1780 2281 2588 2589 1 6 2280 1780 1781 2282 2589 2590 1 6 2281 1781 1782 2283 2590 2591 1 6 2282 1782 1783 2284 2591 2592 1 6 2283 1783 1784 2285 2592 2593 1 6 2284 1784 1785 2286 2593 2594 1 6 2285 1785 1786 2287 2594 2595 1 6 2286 1786 1787 2288 2595 2596 1 6 2287 1787 1788 2289 2596 2597 1 6 2288 1788 1789 2290 2597 2598 1 6 2289 1789 1790 2291 2598 2599 1 6 2290 1790 1791 2292 2599 2600 1 6 2291 1791 1792 2293 2600 2601 1 6 2292 1792 1793 2294 2601 2602 1 6 2293 1793 1794 2295 2602 2603 1 6 2294 1794 1795 2098 2296 2603 1 6 2295 2098 2297 2603 2604 2605 1 7 2296 2098 2099 2101 2102 2298 2605 1 6 2297 2102 2103 2299 2605 2606 1 6 2298 2103 2104 2300 2606 2607 1 6 2299 2104 2105 2301 2607 2608 1 6 2300 2105 2106 2302 2608 2609 1 6 2301 2106 2107 2303 2609 2610 1 6 2302 2107 2108 2304 2610 2611 1 6 2303 2108 2109 2305 2611 2612 1 6 2304 2109 2110 2306 2612 2613 1 6 2305 2110 2111 2307 2613 2614 1 6 2306 2111 2112 2308 2614 2615 1 6 2307 2112 2113 2309 2615 2616 1 6 2308 2113 2114 2310 2619 2616 1 6 2309 2114 2115 2311 2619 2620 1 6 2310 2115 2116 2312 2620 2621 1 6 2311 2116 2117 2313 2621 2622 1 6 2312 2117 2118 2314 2622 2623 1 6 2313 2118 2119 2315 2623 2624 1 6 2314 2119 2120 2316 2624 2625 1 6 2315 2120 2121 2317 2625 2626 1 6 2316 2121 2122 2318 2626 2627 1 6 2317 2122 2123 2319 2627 2628 1 6 2318 2123 2124 2320 2628 2629 1 6 2319 2124 2125 2321 2629 2630 1 6 2320 2125 2126 2322 2630 2631 1 6 2321 2126 2127 2323 2631 2632 1 6 2322 2127 2128 2324 2632 2633 1 6 2323 2128 2129 2325 2633 2634 1 6 2324 2129 2130 2326 2634 2635 1 6 2325 2130 2131 2327 2635 2636 1 6 2326 2131 2132 2151 2328 2636 1 6 2327 2151 2329 2636 2637 2638 1 6 2328 2151 2152 2330 2641 2638 1 6 2329 2152 2153 2154 2331 2641 2 6 2330 2154 2332 2642 2641 2643 2 6 2331 2154 2155 2333 2643 2644 2 6 2332 2155 2156 2334 2644 2645 2 6 2333 2156 2157 2335 2645 2646 2 6 2334 2157 2158 2336 2646 2647 2 6 2335 2158 2159 2337 2647 2648 2 6 2336 2159 2160 2338 2648 2649 2 6 2337 2160 2161 2339 2649 2650 2 6 2338 2161 2162 2340 2650 2651 2 6 2339 2162 2163 2341 2651 2652 2 6 2340 2163 2164 2342 2652 2653 2 6 2341 2164 2343 2653 2654 2655 2 6 2342 2164 2165 2166 2344 2655 2 6 2343 2166 2167 2169 2345 2655 2 6 2344 2169 2346 2655 2656 2657 2 6 2345 2169 2170 2347 2657 2658 2 6 2346 2170 2348 2658 2659 2660 2 6 2347 2170 2171 2349 2660 2661 2 6 2348 2171 1842 1843 2350 2661 2 6 2349 1843 1844 2351 2661 2662 2 6 2350 1844 1845 2352 2662 2663 2 6 2351 1845 1846 2353 2663 2664 2 6 2352 1846 1847 2354 2664 2665 2 6 2353 1847 1848 2355 2665 2666 2 6 2354 1848 1849 2356 2666 2667 2 6 2355 1849 1850 2357 2667 2668 2 6 2356 1850 1851 2358 2668 2669 2 6 2357 1851 1852 2359 2669 2670 2 6 2358 1852 1853 2360 2670 2671 2 6 2359 1853 1854 2361 2671 2672 1 6 2360 1854 1855 1966 2362 2672 1 6 2361 1966 2363 2672 2673 2674 1 6 2362 1966 1967 2364 2674 2675 1 6 2363 1967 1968 2365 2675 2676 1 6 2364 1968 1969 2366 2676 2677 1 6 2365 1969 1970 2367 2677 2678 1 6 2366 1970 1971 2368 2678 2679 1 6 2367 1971 1972 2369 2679 2680 1 6 2368 1972 1973 2370 2680 2681 1 6 2369 1973 1974 2371 2681 2682 1 6 2370 1974 1975 2372 2682 2683 1 6 2371 1975 1976 2373 2683 2684 1 6 2372 1976 1977 2374 2684 2685 1 6 2373 1977 1978 2375 2685 2686 1 6 2374 1978 1979 2376 2686 2687 1 6 2375 1979 1980 2377 2687 2688 1 6 2376 1980 1981 2378 2688 2689 1 6 2377 1981 1982 2379 2689 2690 1 6 2378 1982 1983 2380 2690 2691 1 6 2379 1983 1984 2381 2691 2692 1 6 2380 1984 1985 2382 2692 2693 1 6 2381 1985 1986 2383 2693 2694 1 6 2382 1986 1987 2384 2694 2695 1 6 2383 1987 1988 2385 2695 2696 1 6 2384 1988 1989 2386 2696 2697 1 6 2385 1989 1990 2387 2697 2698 1 6 2386 1990 1991 2388 2698 2699 1 6 2387 1991 1992 2389 2699 2700 1 6 2388 1992 1993 2390 2700 2701 1 6 2389 1993 1994 2391 2701 2702 1 6 2390 1994 1995 2392 2702 2703 1 6 2391 1995 1996 2393 2703 2704 1 6 2392 1996 1997 2394 2704 2705 1 6 2393 1997 1998 2395 2705 2706 1 6 2394 1998 1999 2396 2706 2707 1 6 2395 1999 2000 2397 2707 2708 1 6 2396 2000 2001 2398 2708 2709 1 6 2397 2001 2002 2399 2513 2709 1 6 2398 2002 2003 2400 2513 2514 1 6 2399 2003 2004 2401 2514 2515 1 6 2400 2004 2005 2402 2515 2516 1 6 2401 2005 2006 2403 2516 2517 1 6 2402 2006 2007 2404 2517 2518 1 6 2403 2007 2008 2405 2518 2519 1 6 2404 2008 2009 2406 2519 2520 1 6 2405 2009 2010 2407 2520 2521 1 6 2406 2010 2011 2408 2521 2522 1 6 2407 2011 2012 2409 2522 2523 1 6 2408 2012 2013 2410 2523 2524 1 6 2409 2013 2014 2411 2524 2525 1 6 2410 2014 2015 2412 2525 2526 1 6 2411 2015 2016 2413 2526 2527 1 6 2412 2016 2017 2414 2527 2528 1 6 2413 2017 2018 2415 2528 2529 1 6 2414 2018 2019 2416 2529 2530 1 6 2415 2019 2020 2417 2530 2531 1 6 2416 2020 2021 2418 2531 2532 1 6 2417 2021 2022 2419 2532 2533 1 6 2418 2022 2023 2420 2533 2534 1 6 2419 2023 2024 2421 2534 2535 1 6 2420 2024 2025 2422 2535 2536 1 6 2421 2025 2026 2423 2536 2537 1 6 2422 2026 2027 2424 2537 2538 1 6 2423 2027 2028 2425 2538 2539 1 6 2424 2028 2029 2426 2539 2540 1 6 2425 2029 2030 2427 2540 2541 1 6 2426 2030 2031 2428 2541 2542 1 6 2427 2031 2032 2429 2542 2543 1 6 2428 2032 2033 2430 2543 2544 1 6 2429 2033 2034 2431 2544 2432 1 6 2430 2034 2035 2036 2037 2432 1 7 2431 2037 2038 2433 2544 2430 2556 1 6 2432 2038 2039 2434 2556 2557 1 6 2433 2039 2040 2435 2557 2558 1 6 2434 2040 2436 2558 2559 2437 1 5 2435 2040 2041 2042 2437 1 6 2436 2042 2438 2559 2435 2745 1 6 2437 2042 2043 2439 2745 2746 1 7 2438 2043 2044 2440 2746 2747 2748 1 6 2439 2044 2045 2046 2441 2748 1 6 2440 2046 2442 2748 2749 2750 1 6 2441 2046 2047 2443 2750 2445 1 6 2442 2047 2048 2049 2444 2445 1 6 2443 2049 2445 2446 2447 2448 1 6 2443 2444 2446 2750 2442 3060 1 6 2445 2444 2447 3060 3061 3062 1 6 2446 2444 2448 3062 3063 3064 1 6 2447 2444 2049 2050 2449 3064 1 6 2448 2050 2051 2450 3064 3065 1 6 2449 2051 2052 2451 3065 3066 1 6 2450 2052 2053 2452 3066 3067 1 6 2451 2053 2453 3067 3068 2454 1 6 2452 2053 2054 2055 2056 2454 1 6 2453 2056 2455 3068 2452 3074 1 6 2454 2056 2057 2456 3074 3075 1 6 2455 2057 2058 2059 2457 3075 1 6 2456 2059 2060 2458 3075 3076 1 6 2457 2060 2061 2459 3076 3077 1 6 2458 2061 2062 2460 3077 3078 1 6 2459 2062 2063 2461 3078 3079 1 6 2460 2063 2462 3079 3080 3081 1 6 2461 2063 2064 2463 3081 3082 1 6 2462 2064 2065 2464 3082 3083 1 6 2463 2065 2465 2467 2482 3083 1 6 2464 2065 2066 2067 2466 2467 1 6 2465 2067 2069 2467 2468 2469 1 6 2465 2466 2468 2464 2482 2483 1 6 2467 2466 2469 2471 2477 2483 1 6 2468 2466 2069 2071 2470 2471 1 6 2469 2071 2471 2472 2473 2073 1 6 2469 2470 2472 2468 2477 2478 1 6 2471 2470 2473 2489 2478 2091 1 6 2472 2470 2073 2091 2088 2086 1 6 1516 1521 914 915 576 1515 1 6 1578 1587 2476 1574 6361 1573 1 6 2475 1587 1589 6353 6359 6361 1 6 2468 2471 2478 2483 2484 2485 1 6 2477 2471 2485 2488 2489 2472 2 6 1642 1643 1644 2480 1641 2490 2 6 2479 1644 2481 2490 2494 2869 2 6 2480 1644 1645 1650 2494 2495 1 6 2464 2467 2483 3085 3083 3926 1 6 2482 2467 2468 2477 2484 3926 1 6 2483 2477 2485 2486 3926 3150 1 6 2484 2477 2478 2486 2487 2488 1 6 2484 2485 2487 3148 3149 3150 1 6 2486 2485 2488 3148 3967 3161 1 6 2487 2485 2478 2489 5948 3967 1 6 2488 2478 2472 2091 2092 5948 2 6 1641 2479 2480 2867 2868 2869 2 6 70 71 2492 3436 3437 3441 2 6 2491 71 72 409 2493 3436 2 6 2492 409 1606 3515 3436 3516 2 6 2480 2481 2495 2869 2870 2871 2 6 2494 2481 1650 1651 2496 2871 2 6 2495 1651 2497 2871 2872 2882 2 6 2496 1651 1652 2498 2882 2883 2 6 2497 1652 2499 2883 4092 4093 2 6 2498 1652 1653 2500 2809 4093 2 6 2499 1653 1654 2501 2809 2810 2 6 2500 1654 1656 2810 2811 2812 1 6 2184 2182 2503 2193 2504 2505 1 6 2502 2182 30 2505 29 2180 1 6 2193 2502 2505 2506 2507 2508 1 6 2504 2502 2508 31 30 2503 1 6 2193 2504 2507 2509 2510 2192 1 6 2506 2504 2508 2509 3330 3880 1 6 2507 2504 2505 31 3330 32 1 6 2506 2507 2510 2511 3880 3881 1 6 2506 2509 2511 2512 2191 2192 1 6 2510 2509 2512 6499 6498 3881 1 6 2510 2511 2191 6498 6500 9710 1 6 2398 2399 2514 2709 2710 2711 1 6 2513 2399 2400 2515 2711 2712 1 6 2514 2400 2401 2516 2712 2713 1 6 2515 2401 2402 2517 2713 2714 1 6 2516 2402 2403 2518 2714 2715 1 6 2517 2403 2404 2519 2715 2716 1 6 2518 2404 2405 2520 2716 2717 1 6 2519 2405 2406 2521 2717 2718 1 6 2520 2406 2407 2522 2718 2719 1 6 2521 2407 2408 2523 2719 2720 1 6 2522 2408 2409 2524 2720 2721 1 6 2523 2409 2410 2525 2721 2722 1 6 2524 2410 2411 2526 2722 2723 1 6 2525 2411 2412 2527 2723 2724 1 6 2526 2412 2413 2528 2724 2725 1 6 2527 2413 2414 2529 2725 2726 1 6 2528 2414 2415 2530 2726 2727 1 6 2529 2415 2416 2531 2727 2728 1 6 2530 2416 2417 2532 2728 2729 1 6 2531 2417 2418 2533 2729 2730 1 6 2532 2418 2419 2534 2730 2731 1 6 2533 2419 2420 2535 2731 2732 1 6 2534 2420 2421 2536 2732 2733 1 6 2535 2421 2422 2537 2733 2734 1 6 2536 2422 2423 2538 2734 2735 1 6 2537 2423 2424 2539 2735 2736 1 6 2538 2424 2425 2540 2736 2737 1 6 2539 2425 2426 2541 2552 2737 1 6 2540 2426 2427 2542 2552 2553 1 6 2541 2427 2428 2543 2553 2554 1 6 2542 2428 2429 2544 2554 2555 1 6 2543 2429 2430 2432 2555 2556 1 6 408 2218 2546 2547 2841 2842 1 6 2545 2218 2547 2548 2549 2219 1 6 2545 2546 2548 2842 2845 2846 1 6 2547 2546 2549 2550 2857 2846 1 6 2548 2546 2219 2220 2550 2551 1 6 2548 2549 2551 6691 2856 2857 1 7 2550 2549 2220 2221 6702 6690 6691 1 6 2540 2541 2553 2737 2738 2739 1 6 2552 2541 2542 2554 2739 2740 1 6 2553 2542 2543 2555 2570 2740 1 6 2554 2543 2544 2556 2570 2557 1 5 2555 2544 2432 2433 2557 1 7 2556 2433 2434 2558 2570 2555 2742 1 5 2557 2434 2435 2559 2742 1 7 2558 2435 2437 2742 2743 2744 2745 1 6 2240 1714 2561 2562 2563 2564 1 6 2240 2560 2562 3435 2239 3446 1 6 2561 2560 2563 3446 3447 3448 1 6 2562 2560 2564 3448 3449 2567 1 6 2563 2560 1714 1715 2565 2567 1 6 2564 1715 1716 1717 2566 2567 1 6 2565 1717 2567 2568 2569 1718 1 6 2565 2566 2568 3449 2563 2564 1 6 2567 2566 2569 3458 3455 3449 1 6 2568 2566 1718 3463 3458 1719 1 6 2554 2555 2557 2740 2741 2742 1 6 2262 2263 2572 2769 2770 2771 1 6 2571 2263 2264 2573 2771 2772 1 6 2572 2264 2265 2574 2772 2773 1 6 2573 2265 2266 2575 2773 2774 1 6 2574 2266 2267 2576 2774 2775 1 6 2575 2267 2268 2577 2775 2776 1 6 2576 2268 2269 2578 2776 2777 1 6 2577 2269 2270 2579 2777 2778 1 6 2578 2270 2271 2580 2778 2779 1 6 2579 2271 2272 2581 2779 2780 1 6 2580 2272 2273 2582 2780 2781 1 6 2581 2273 2274 2583 2781 2782 1 6 2582 2274 2275 2584 2782 2783 1 6 2583 2275 2276 2585 2783 2784 1 6 2584 2276 2277 2586 2784 2785 1 6 2585 2277 2278 2587 2785 2786 1 6 2586 2278 2279 2588 2786 2787 1 6 2587 2279 2280 2589 2787 2788 1 6 2588 2280 2281 2590 2788 2789 1 6 2589 2281 2282 2591 2789 2790 1 6 2590 2282 2283 2592 2790 2791 1 6 2591 2283 2284 2593 2791 2792 1 6 2592 2284 2285 2594 2792 2793 1 6 2593 2285 2286 2595 2793 2794 1 6 2594 2286 2287 2596 2794 2795 1 6 2595 2287 2288 2597 2795 2796 1 6 2596 2288 2289 2598 2796 2797 1 6 2597 2289 2290 2599 2797 2798 1 6 2598 2290 2291 2600 2798 2799 1 6 2599 2291 2292 2601 2799 2800 1 6 2600 2292 2293 2602 2800 2801 1 6 2601 2293 2294 2603 2801 2802 1 6 2602 2294 2295 2296 2604 2802 1 6 2603 2296 2605 2802 2803 2606 1 5 2604 2296 2297 2298 2606 1 7 2605 2298 2299 2607 2803 2604 2826 1 5 2606 2299 2300 2608 2826 1 7 2607 2300 2301 2609 2826 2827 2828 1 6 2608 2301 2302 2610 2828 2829 1 6 2609 2302 2303 2611 2829 2830 1 6 2610 2303 2304 2612 2830 2831 1 6 2611 2304 2305 2613 2831 2832 1 6 2612 2305 2306 2614 2832 2833 1 6 2613 2306 2307 2615 2833 2834 1 6 2614 2307 2308 2616 2617 2834 1 6 2615 2308 2617 2618 2619 2309 1 6 2615 2616 2618 2834 2835 2836 1 6 2617 2616 2619 2836 2837 2838 1 6 2618 2616 2309 2310 2620 2838 1 6 2619 2310 2311 2621 2840 2838 1 6 2620 2311 2312 2622 2959 2840 1 6 2621 2312 2313 2623 2959 2960 1 6 2622 2313 2314 2624 2960 2961 1 6 2623 2314 2315 2625 2961 2962 1 6 2624 2315 2316 2626 2962 2963 1 6 2625 2316 2317 2627 2966 2963 1 6 2626 2317 2318 2628 2966 2967 1 6 2627 2318 2319 2629 2967 2968 1 6 2628 2319 2320 2630 2968 2969 1 6 2629 2320 2321 2631 2969 2970 1 6 2630 2321 2322 2632 2970 2971 1 6 2631 2322 2323 2633 2971 2972 1 6 2632 2323 2324 2634 2972 2973 1 6 2633 2324 2325 2635 2973 2974 1 6 2634 2325 2326 2636 2974 2975 1 6 2635 2326 2327 2328 2637 2975 1 6 2636 2328 2638 2639 2975 2976 1 6 2637 2328 2639 2640 2641 2329 1 6 2637 2638 2640 2976 2977 2978 1 6 2639 2638 2641 2642 2978 2979 1 6 2640 2638 2642 2331 2330 2329 2 6 2640 2641 2331 2643 2979 2980 2 6 2642 2331 2332 2644 2980 2981 2 6 2643 2332 2333 2645 2981 2982 2 6 2644 2333 2334 2646 2982 2983 2 6 2645 2334 2335 2647 2983 2984 2 6 2646 2335 2336 2648 2984 2985 2 6 2647 2336 2337 2649 2985 2986 2 6 2648 2337 2338 2650 2986 2987 2 6 2649 2338 2339 2651 2987 2988 2 6 2650 2339 2340 2652 2988 2989 2 6 2651 2340 2341 2653 2989 2990 2 6 2652 2341 2342 2654 2990 2991 2 6 2653 2342 2655 2991 2992 2656 2 6 2654 2342 2343 2344 2345 2656 2 6 2655 2345 2657 2992 2654 2993 2 6 2656 2345 2346 2658 2993 2994 2 6 2657 2346 2347 2659 2994 2995 2 6 2658 2347 2660 2995 2996 2997 2 6 2659 2347 2348 2661 2997 2998 2 6 2660 2348 2349 2350 2662 2998 2 6 2661 2350 2351 2663 2998 2999 2 6 2662 2351 2352 2664 2999 3000 2 6 2663 2352 2353 2665 3000 3001 2 6 2664 2353 2354 2666 3001 3002 2 6 2665 2354 2355 2667 3002 3565 2 6 2666 2355 2356 2668 3565 3566 2 6 2667 2356 2357 2669 3566 3567 2 6 2668 2357 2358 2670 3567 3568 2 6 2669 2358 2359 2671 3568 3569 2 6 2670 2359 2360 2672 3569 3570 2 6 2671 2360 2361 2362 2673 3570 2 6 2672 2362 2674 3570 3571 3572 1 6 2673 2362 2363 2675 3572 3573 1 6 2674 2363 2364 2676 3391 3573 1 6 2675 2364 2365 2677 3391 3392 1 6 2676 2365 2366 2678 3392 3393 1 6 2677 2366 2367 2679 3393 3394 1 6 2678 2367 2368 2680 3394 3579 1 6 2679 2368 2369 2681 3579 3580 1 6 2680 2369 2370 2682 3580 3581 1 6 2681 2370 2371 2683 3581 3582 1 6 2682 2371 2372 2684 3582 3583 1 6 2683 2372 2373 2685 3583 3584 1 6 2684 2373 2374 2686 3584 3585 1 6 2685 2374 2375 2687 3585 3586 1 6 2686 2375 2376 2688 3586 3587 1 6 2687 2376 2377 2689 3587 3588 1 6 2688 2377 2378 2690 3278 3588 1 6 2689 2378 2379 2691 3278 3279 1 6 2690 2379 2380 2692 3279 3280 1 6 2691 2380 2381 2693 3280 3281 1 6 2692 2381 2382 2694 3281 3282 1 6 2693 2382 2383 2695 3282 3283 1 6 2694 2383 2384 2696 3283 3284 1 6 2695 2384 2385 2697 3284 3285 1 6 2696 2385 2386 2698 3285 3286 1 6 2697 2386 2387 2699 3286 3287 1 6 2698 2387 2388 2700 3287 3288 1 6 2699 2388 2389 2701 3288 3289 1 6 2700 2389 2390 2702 3289 3290 1 6 2701 2390 2391 2703 3003 3290 1 6 2702 2391 2392 2704 3003 3004 1 6 2703 2392 2393 2705 3004 3005 1 6 2704 2393 2394 2706 3005 3006 1 6 2705 2394 2395 2707 3006 3007 1 6 2706 2395 2396 2708 3007 3008 1 6 2707 2396 2397 2709 3008 3009 1 6 2708 2397 2398 2513 2710 3009 1 6 2709 2513 2711 3009 3010 3011 1 6 2710 2513 2514 2712 3011 3012 1 6 2711 2514 2515 2713 3012 3013 1 6 2712 2515 2516 2714 3013 3014 1 6 2713 2516 2517 2715 3014 3015 1 6 2714 2517 2518 2716 3015 3016 1 6 2715 2518 2519 2717 3016 3017 1 6 2716 2519 2520 2718 3017 3018 1 6 2717 2520 2521 2719 3018 3019 1 6 2718 2521 2522 2720 3019 3020 1 6 2719 2522 2523 2721 3020 3021 1 6 2720 2523 2524 2722 3021 3022 1 6 2721 2524 2525 2723 3022 3023 1 6 2722 2525 2526 2724 3023 3024 1 6 2723 2526 2527 2725 3024 3025 1 6 2724 2527 2528 2726 3025 3026 1 6 2725 2528 2529 2727 3026 3027 1 6 2726 2529 2530 2728 3027 3028 1 6 2727 2530 2531 2729 3028 3029 1 6 2728 2531 2532 2730 3029 3030 1 6 2729 2532 2533 2731 3030 3031 1 6 2730 2533 2534 2732 3031 3032 1 6 2731 2534 2535 2733 3032 3033 1 6 2732 2535 2536 2734 3033 3034 1 6 2733 2536 2537 2735 3034 3035 1 6 2734 2537 2538 2736 3035 3036 1 6 2735 2538 2539 2737 3036 3037 1 6 2736 2539 2540 2552 2738 3037 1 6 2737 2552 2739 3037 3038 3039 1 6 2738 2552 2553 2740 3039 3040 1 6 2739 2553 2554 2570 2741 3040 1 6 2740 2570 2742 3040 3041 2743 1 6 2741 2570 2557 2558 2559 2743 1 6 2742 2559 2744 3041 2741 3049 1 5 2743 2559 2745 3049 3050 1 6 2744 2559 2437 2438 2746 3050 1 6 2745 2438 2439 2747 3050 3051 1 6 2746 2439 2748 3051 3052 2749 1 5 2747 2439 2440 2441 2749 1 6 2748 2441 2750 3052 2747 3058 1 7 2749 2441 2442 2445 3058 3059 3060 1 6 1746 1747 1748 2752 2893 2894 1 6 2751 1748 2233 2242 2753 2894 1 6 2752 2242 2754 2894 2895 2896 1 6 2753 2242 2243 2755 2896 2897 1 6 2754 2243 2756 2897 2898 2899 1 6 2755 2243 2244 2757 2899 2900 1 6 2756 2244 2245 2758 2900 2901 1 6 2757 2245 2759 2901 2902 2903 1 6 2758 2245 2246 2760 2903 2904 1 6 2759 2246 2247 2253 2761 2904 1 6 2760 2253 2254 2762 2904 2905 1 6 2761 2254 2255 2763 2905 2906 1 6 2762 2255 2256 2257 2764 2906 1 6 2763 2257 2765 2906 2907 2908 1 6 2764 2257 2258 2766 2908 2909 1 6 2765 2258 2259 2767 2909 2910 1 6 2766 2259 2260 2768 2910 2911 1 6 2767 2260 2261 2769 2911 2912 1 6 2768 2261 2262 2571 2770 2912 1 6 2769 2571 2771 2912 2913 2914 1 6 2770 2571 2572 2772 2914 2915 1 6 2771 2572 2573 2773 2915 2916 1 6 2772 2573 2574 2774 2916 2917 1 6 2773 2574 2575 2775 2917 2918 1 6 2774 2575 2576 2776 2918 2919 1 6 2775 2576 2577 2777 2919 2920 1 6 2776 2577 2578 2778 2920 2921 1 6 2777 2578 2579 2779 2921 2922 1 6 2778 2579 2580 2780 2922 2923 1 6 2779 2580 2581 2781 2923 2924 1 6 2780 2581 2582 2782 2924 2925 1 6 2781 2582 2583 2783 2925 2926 1 6 2782 2583 2584 2784 2926 2927 1 6 2783 2584 2585 2785 2927 2928 1 6 2784 2585 2586 2786 2928 2929 1 6 2785 2586 2587 2787 2929 2930 1 6 2786 2587 2588 2788 2930 2931 1 6 2787 2588 2589 2789 2931 2932 1 6 2788 2589 2590 2790 2932 2933 1 6 2789 2590 2591 2791 2933 2934 1 6 2790 2591 2592 2792 2934 2935 1 6 2791 2592 2593 2793 2935 2936 1 6 2792 2593 2594 2794 2936 2937 1 6 2793 2594 2595 2795 2937 2938 1 6 2794 2595 2596 2796 2938 2939 1 6 2795 2596 2597 2797 2939 2940 1 6 2796 2597 2598 2798 2940 2941 1 6 2797 2598 2599 2799 2941 2942 1 6 2798 2599 2600 2800 2942 2943 1 6 2799 2600 2601 2801 2943 2944 1 6 2800 2601 2602 2802 2944 2824 1 6 2801 2602 2603 2604 2803 2824 1 6 2802 2604 2606 2824 2825 2826 1 6 2173 2174 2175 2177 2805 3395 1 6 2804 2177 2806 3395 3396 3400 1 6 2805 2177 2178 2807 3400 3401 1 6 2806 2178 2808 3401 3402 3403 1 6 2807 2178 1731 3403 3404 1732 2 6 2499 2500 2810 4095 4093 4388 2 6 2809 2500 2501 2811 4388 2813 2 6 2810 2501 2812 1664 1666 2813 2 6 2811 2501 1656 1658 1661 1664 2 6 2811 1666 2814 3139 4388 2810 2 6 2813 1666 1667 2815 2817 3139 2 6 2814 1667 2816 2817 2818 2819 2 6 2815 1667 1668 2819 2820 2821 2 6 2814 2815 2818 3139 3140 3141 2 6 2817 2815 2819 3141 3142 3143 2 6 2818 2815 2816 2820 3143 3144 2 6 2819 2816 2821 3144 3145 3146 2 6 2820 2816 1668 2822 2823 3146 2 6 2821 1668 2823 1672 1671 1669 2 6 2821 2822 1672 3146 3147 1673 1 6 2802 2803 2825 2944 2801 2945 1 6 2824 2803 2826 2945 2946 2827 1 6 2825 2803 2606 2607 2608 2827 1 6 2826 2608 2828 2946 2825 2947 1 5 2827 2608 2609 2829 2947 1 6 2828 2609 2610 2830 2947 2948 1 6 2829 2610 2611 2831 2948 2949 1 6 2830 2611 2612 2832 2949 2950 1 6 2831 2612 2613 2833 2950 2951 1 6 2832 2613 2614 2834 2951 2952 1 7 2833 2614 2615 2617 2835 2952 2953 1 5 2834 2617 2836 2953 2954 1 6 2835 2617 2618 2837 2954 2955 1 6 2836 2618 2838 2839 2955 2956 1 6 2837 2618 2839 2840 2620 2619 1 6 2837 2838 2840 2956 2957 2958 1 6 2839 2838 2620 2958 2959 2621 1 6 408 2545 2842 2843 9690 429 1 6 2841 2545 2843 2844 2547 2845 1 6 2841 2842 2844 3168 9688 9690 1 6 2843 2842 3168 3165 3162 2845 1 6 2842 2547 2846 2847 3162 2844 1 6 2845 2547 2847 2848 2548 2857 1 6 2845 2846 2848 2849 3162 3163 1 6 2847 2846 2849 2850 2851 2857 1 6 2847 2848 2850 2852 2858 3163 1 6 2849 2848 2851 2852 2853 2854 1 6 2850 2848 2854 2855 2856 2857 1 6 2849 2850 2853 2858 2859 2860 1 5 2852 2850 2854 2860 6676 1 7 2853 2850 2851 2855 6676 6677 6678 1 7 2854 2851 2856 6689 6686 6680 6678 1 6 2855 2851 2857 6691 6689 2550 1 6 2856 2851 2848 2550 2548 2846 1 6 2849 2852 2859 3180 3163 6661 1 7 2858 2852 2860 6661 6674 6666 6662 1 6 2859 2852 2853 6675 6674 6676 2 5 1631 1633 1628 1629 1630 2 6 1628 1633 1636 2863 1627 7215 2 7 2862 1636 1637 2864 7216 7215 7217 2 5 2863 1637 1638 2865 7217 2 7 2864 1638 1639 2866 7217 7218 7219 2 7 2865 1639 1640 2867 3189 3214 7219 2 6 2866 1640 1641 2490 2868 3189 2 6 2867 2490 2869 3189 3190 3181 2 6 2868 2490 2480 2494 2870 3181 2 6 2869 2494 2871 2873 2884 3181 2 6 2870 2494 2495 2496 2872 2873 2 6 2871 2496 2873 2874 2881 2882 2 6 2871 2872 2874 2875 2870 2884 2 6 2873 2872 2875 2876 2880 2881 2 6 2873 2874 2876 2877 2884 2885 2 6 2875 2874 2877 2878 2879 2880 2 6 2875 2876 2878 2885 2886 2887 2 6 2877 2876 2879 2887 2888 2889 2 6 2878 2876 2880 2892 2889 7600 2 6 2879 2876 2874 2881 4086 7600 2 6 2880 2874 2872 2882 4086 4087 2 6 2881 2872 2496 2497 2883 4087 2 6 2882 2497 2498 4087 4088 4092 2 6 2870 2873 2875 2885 3181 3182 2 6 2884 2875 2877 2886 3182 3183 2 6 2885 2877 2887 3183 3184 3185 2 6 2886 2877 2878 2888 3188 3185 2 6 2887 2878 2889 2890 3959 3188 2 6 2888 2878 2890 2891 2892 2879 2 6 2888 2889 2891 3961 3959 7592 2 6 2890 2889 2892 7592 7593 7594 2 6 2891 2889 2879 7600 7597 7594 1 6 1745 1746 2751 2894 3199 3198 1 6 2893 2751 2752 2753 2895 3198 1 6 2894 2753 2896 3198 3200 3201 1 6 2895 2753 2754 2897 3201 3202 1 6 2896 2754 2755 2898 3202 3203 1 6 2897 2755 2899 3203 3204 3205 1 6 2898 2755 2756 2900 3205 3206 1 6 2899 2756 2757 2901 3206 3207 1 6 2900 2757 2758 2902 3207 3208 1 6 2901 2758 2903 3208 3209 3210 1 6 2902 2758 2759 2904 3213 3210 1 6 2903 2759 2760 2761 2905 3213 1 6 2904 2761 2762 2906 3483 3213 1 6 2905 2762 2763 2764 2907 3483 1 6 2906 2764 2908 3482 3212 3483 1 7 2907 2764 2765 2909 3500 3482 3697 1 6 2908 2765 2766 2910 3697 3698 1 6 2909 2766 2767 2911 3698 3699 1 6 2910 2767 2768 2912 3699 3700 1 6 2911 2768 2769 2770 2913 3700 1 6 2912 2770 2914 3700 3701 3702 1 6 2913 2770 2771 2915 3702 3703 1 6 2914 2771 2772 2916 3703 3704 1 6 2915 2772 2773 2917 3704 3705 1 6 2916 2773 2774 2918 3705 3706 1 6 2917 2774 2775 2919 3706 3707 1 6 2918 2775 2776 2920 3707 3708 1 6 2919 2776 2777 2921 3708 3709 1 6 2920 2777 2778 2922 3709 3710 1 6 2921 2778 2779 2923 3710 3711 1 6 2922 2779 2780 2924 3711 3712 1 6 2923 2780 2781 2925 3712 3713 1 6 2924 2781 2782 2926 3713 3714 1 6 2925 2782 2783 2927 3714 3715 1 6 2926 2783 2784 2928 3715 3716 1 6 2927 2784 2785 2929 3716 3717 1 6 2928 2785 2786 2930 3717 3718 1 6 2929 2786 2787 2931 3718 3719 1 6 2930 2787 2788 2932 3719 3720 1 6 2931 2788 2789 2933 3720 3721 1 6 2932 2789 2790 2934 3721 3722 1 6 2933 2790 2791 2935 3722 3723 1 6 2934 2791 2792 2936 3723 3724 1 6 2935 2792 2793 2937 3724 3725 1 6 2936 2793 2794 2938 3725 3726 1 6 2937 2794 2795 2939 3726 3727 1 6 2938 2795 2796 2940 3727 3728 1 6 2939 2796 2797 2941 3728 3729 1 6 2940 2797 2798 2942 3729 3730 1 6 2941 2798 2799 2943 3730 3731 1 6 2942 2799 2800 2944 3731 3732 1 6 2943 2800 2801 2824 2945 3732 1 6 2944 2824 2825 2946 3732 3733 1 6 2945 2825 2827 2947 3733 3734 1 6 2946 2827 2828 2829 2948 3734 1 7 2947 2829 2830 2949 3734 3735 3736 1 6 2948 2830 2831 2950 3242 3736 1 6 2949 2831 2832 2951 3242 3243 1 6 2950 2832 2833 2952 3243 3244 1 6 2951 2833 2834 2953 3244 3245 1 5 2952 2834 2835 2954 3245 1 7 2953 2835 2836 2955 3245 3246 3247 1 6 2954 2836 2837 2956 3247 3248 1 6 2955 2837 2839 2957 3248 3249 1 6 2956 2839 2958 3249 3250 3251 1 6 2957 2839 2840 2959 3251 3252 1 6 2958 2840 2621 2622 2960 3252 1 6 2959 2622 2623 2961 3254 3252 1 6 2960 2623 2624 2962 3254 3255 1 6 2961 2624 2625 2963 2964 3255 1 6 2962 2625 2964 2965 2966 2626 1 6 2962 2963 2965 3255 3256 3257 1 6 2964 2963 2966 3257 3258 3259 1 6 2965 2963 2626 2627 2967 3259 1 6 2966 2627 2628 2968 3259 3260 1 6 2967 2628 2629 2969 3260 3261 1 6 2968 2629 2630 2970 3261 3262 1 6 2969 2630 2631 2971 3262 3263 1 6 2970 2631 2632 2972 3263 3264 1 6 2971 2632 2633 2973 3264 3265 1 6 2972 2633 2634 2974 3265 3266 1 6 2973 2634 2635 2975 3266 3267 1 6 2974 2635 2636 2637 2976 3267 1 6 2975 2637 2639 2977 3267 3268 1 6 2976 2639 2978 3268 3269 3270 1 6 2977 2639 2640 2979 3270 3271 2 6 2978 2640 2642 2980 3271 3272 2 6 2979 2642 2643 2981 3272 3273 2 6 2980 2643 2644 2982 3273 3274 2 6 2981 2644 2645 2983 3274 3275 2 6 2982 2645 2646 2984 3275 3276 2 6 2983 2646 2647 2985 3276 3277 2 6 2984 2647 2648 2986 3277 3824 2 6 2985 2648 2649 2987 3545 3824 2 6 2986 2649 2650 2988 3545 3546 2 6 2987 2650 2651 2989 3546 3547 2 6 2988 2651 2652 2990 3547 3548 2 6 2989 2652 2653 2991 3548 3549 2 6 2990 2653 2654 2992 3549 3550 2 6 2991 2654 2656 2993 3550 3551 2 6 2992 2656 2657 2994 3551 3552 2 6 2993 2657 2658 2995 3552 3553 2 6 2994 2658 2659 2996 3553 3554 2 6 2995 2659 2997 3554 3555 3556 2 6 2996 2659 2660 2998 3556 3557 2 6 2997 2660 2661 2662 2999 3557 2 6 2998 2662 2663 3000 3557 3558 2 6 2999 2663 2664 3001 3558 3559 2 6 3000 2664 2665 3002 3559 3560 2 6 3001 2665 2666 3560 3561 3565 1 6 2702 2703 3004 3290 3291 3292 1 6 3003 2703 2704 3005 3292 3293 1 6 3004 2704 2705 3006 3293 3294 1 6 3005 2705 2706 3007 3294 3295 1 6 3006 2706 2707 3008 3295 3296 1 6 3007 2707 2708 3009 3296 3297 1 6 3008 2708 2709 2710 3010 3297 1 6 3009 2710 3011 3297 3298 3299 1 6 3010 2710 2711 3012 3299 3300 1 6 3011 2711 2712 3013 3300 3301 1 6 3012 2712 2713 3014 3301 3302 1 6 3013 2713 2714 3015 3302 3303 1 6 3014 2714 2715 3016 3303 3304 1 6 3015 2715 2716 3017 3304 3305 1 6 3016 2716 2717 3018 3305 3306 1 6 3017 2717 2718 3019 3306 3307 1 6 3018 2718 2719 3020 3307 3308 1 6 3019 2719 2720 3021 3308 3309 1 6 3020 2720 2721 3022 3309 3310 1 6 3021 2721 2722 3023 3310 3311 1 6 3022 2722 2723 3024 3311 3312 1 6 3023 2723 2724 3025 3312 3313 1 6 3024 2724 2725 3026 3313 3314 1 6 3025 2725 2726 3027 3314 3315 1 6 3026 2726 2727 3028 3315 3316 1 6 3027 2727 2728 3029 3316 3317 1 6 3028 2728 2729 3030 3317 3318 1 6 3029 2729 2730 3031 3318 3319 1 6 3030 2730 2731 3032 3319 3320 1 6 3031 2731 2732 3033 3320 3321 1 6 3032 2732 2733 3034 3321 3322 1 6 3033 2733 2734 3035 3042 3322 1 6 3034 2734 2735 3036 3042 3043 1 6 3035 2735 2736 3037 3043 3044 1 6 3036 2736 2737 2738 3038 3044 1 6 3037 2738 3039 3044 3045 3046 1 6 3038 2738 2739 3040 3046 3047 1 6 3039 2739 2740 2741 3041 3047 1 6 3040 2741 2743 3047 3048 3049 1 6 3034 3035 3043 3322 3323 3324 1 6 3042 3035 3036 3044 3324 3325 1 6 3043 3036 3037 3038 3045 3325 1 6 3044 3038 3046 3325 3326 3327 1 6 3045 3038 3039 3047 3053 3327 1 6 3046 3039 3040 3041 3048 3053 1 6 3047 3041 3049 3053 3054 3055 1 6 3048 3041 2743 2744 3050 3055 1 6 3049 2744 2745 2746 3051 3055 1 6 3050 2746 2747 3052 3055 3056 1 6 3051 2747 2749 3056 3057 3058 1 6 3046 3047 3048 3054 3327 3328 1 6 3053 3048 3055 3328 3329 3056 1 6 3054 3048 3049 3050 3051 3056 1 7 3055 3051 3052 3057 3329 3054 3641 1 5 3056 3052 3058 3641 3642 1 7 3057 3052 2749 2750 3059 3642 3643 1 6 3058 2750 3060 3643 3644 3061 1 5 3059 2750 2445 2446 3061 1 6 3060 2446 3062 3644 3059 3910 1 6 3061 2446 2447 3063 3910 3911 1 6 3062 2447 3064 3069 3911 3912 1 6 3063 2447 2448 2449 3065 3069 1 6 3064 2449 2450 3066 3069 3070 1 6 3065 2450 2451 3067 3070 3071 1 6 3066 2451 2452 3068 3071 3072 1 6 3067 2452 2454 3072 3073 3074 1 6 3063 3064 3065 3070 3912 3913 1 6 3069 3065 3066 3071 3913 3914 1 6 3070 3066 3067 3072 3914 3915 1 6 3071 3067 3068 3073 3915 3916 1 6 3072 3068 3074 3916 3917 3918 1 6 3073 3068 2454 2455 3075 3918 1 6 3074 2455 2456 2457 3076 3918 1 6 3075 2457 2458 3077 3349 3918 1 6 3076 2458 2459 3078 3349 3350 1 6 3077 2459 2460 3079 3107 3350 1 6 3078 2460 2461 3080 3107 3108 1 6 3079 2461 3081 3091 3108 3109 1 6 3080 2461 2462 3082 3091 3092 1 6 3081 2462 2463 3083 3084 3092 1 6 3082 2463 3084 3085 2482 2464 1 6 3082 3083 3085 3092 3112 3359 1 6 3084 3083 2482 3926 3152 3359 1 6 16 17 3087 3088 3089 3090 1 6 3086 17 18 3095 3126 3090 1 6 16 3086 3089 3098 417 15 1 6 3088 3086 3090 3098 3103 3104 1 6 3089 3086 3104 3105 3087 3126 1 6 3080 3081 3092 3109 3110 3111 1 6 3091 3081 3082 3084 3111 3112 2 5 1615 1616 3094 4099 3544 2 6 3093 1616 1617 4367 4099 1624 1 6 3087 18 19 3096 3125 3126 1 6 3095 19 20 3125 3128 414 2 6 2241 1657 1655 1647 1182 1184 1 6 3088 3089 417 3099 3102 3103 1 6 417 3098 418 3100 3101 3102 1 6 418 3099 3101 3228 3229 3684 1 6 3100 3099 3102 3226 3228 3498 1 7 3101 3099 3098 3103 3113 3498 3497 1 6 3102 3098 3089 3104 3113 3114 1 6 3103 3089 3090 3105 3106 3114 1 6 3104 3090 3106 3126 3124 3118 1 6 3104 3105 3116 3114 3117 3118 1 6 3078 3079 3108 3350 3351 3352 1 6 3107 3079 3080 3109 3352 3353 1 6 3108 3080 3091 3110 3353 3354 1 6 3109 3091 3111 3354 3355 3356 1 6 3110 3091 3092 3112 3356 3357 1 6 3111 3092 3084 3357 3358 3359 1 5 3102 3103 3114 3115 3497 1 6 3113 3103 3115 3116 3106 3104 1 7 3113 3114 3116 3497 3504 3501 3495 1 6 3115 3114 3106 3117 6712 3504 1 6 3116 3106 3118 3119 6712 6711 1 6 3117 3106 3119 3120 3124 3105 1 6 3117 3118 3120 3121 6711 6713 1 6 3119 3118 3121 3122 3123 3124 1 6 3119 3120 3122 3884 3887 6713 1 6 3121 3120 3123 3127 3883 3884 1 6 3122 3120 3124 3125 3127 3128 1 6 3123 3120 3118 3125 3126 3105 1 6 3123 3124 3126 3128 3095 3096 1 6 3125 3124 3105 3095 3087 3090 1 6 3122 3123 3128 3882 3339 3883 1 6 3127 3123 3125 414 3882 3096 1 6 2201 2203 3130 3851 3852 9781 1 6 3129 2203 2205 1525 1526 9781 1 6 2094 2095 3132 3133 9776 3138 1 6 2094 3131 3133 3134 3135 2093 1 6 3132 3131 3134 3136 3137 3138 1 6 3132 3133 3135 3136 5946 5945 1 6 3132 3134 5945 5943 5947 2093 1 6 3134 3133 3137 6090 6091 5946 1 6 3136 3133 3138 6090 6089 6092 1 6 3137 3133 6092 6093 9776 3131 2 6 2813 2814 2817 3140 4388 4386 2 6 3139 2817 3141 4385 4384 4386 2 6 3140 2817 2818 3142 4390 4385 2 6 3141 2818 3143 7767 4390 7768 2 6 3142 2818 2819 3144 7774 7768 2 6 3143 2819 2820 3145 7774 7775 2 6 3144 2820 3146 4231 7775 9791 2 6 3145 2820 2821 2823 3147 4231 2 6 3146 2823 1673 1674 3412 4231 1 6 2486 2487 3149 3156 3157 3161 1 6 2486 3148 3150 3151 3155 3156 1 6 2486 3149 3151 3152 3926 2484 1 6 3150 3149 3152 3153 3154 3155 1 6 3150 3151 3153 3926 3085 3359 1 6 3152 3151 3154 3358 3359 3360 1 6 3153 3151 3155 3360 3361 3362 1 6 3154 3151 3149 3156 3677 3362 1 6 3155 3149 3148 3157 3158 3677 1 6 3156 3148 3158 3159 3160 3161 1 6 3156 3157 3159 3676 3677 3945 1 6 3158 3157 3160 3945 3946 3962 1 6 3159 3157 3161 3962 3963 3964 1 6 3160 3157 3148 3967 3964 2487 1 6 2845 2847 3163 3164 3165 2844 1 6 3162 2847 3164 3180 2858 2849 1 6 3162 3163 3165 3166 3177 3180 1 6 3162 3164 3166 3167 3168 2844 1 6 3165 3164 3167 3177 3174 3171 1 6 3165 3166 3168 3169 3170 3171 1 6 3165 3167 3169 2843 2844 9688 1 6 3168 3167 3170 9687 9686 9688 1 5 3169 3167 3171 3172 9687 1 6 3170 3167 3172 3173 3174 3166 1 6 3170 3171 3173 9691 9687 6653 1 7 3172 3171 3174 3175 6654 6652 6653 1 6 3173 3171 3175 3176 3177 3166 1 5 3173 3174 3176 3450 6654 1 6 3175 3174 3177 3178 3179 3450 1 6 3176 3174 3178 3166 3164 3180 1 6 3176 3177 3179 3180 6660 6661 1 6 3176 3178 3450 6657 6659 6660 1 6 3177 3164 3178 3163 2858 6661 2 6 2869 2870 2884 3182 3190 2868 2 6 3181 2884 2885 3183 3216 3190 2 6 3182 2885 2886 3184 3193 3216 2 6 3183 2886 3185 3186 3192 3193 2 6 3184 2886 3186 3187 3188 2887 2 6 3184 3185 3187 3192 3196 7584 2 6 3186 3185 3188 3958 7586 7584 2 6 3187 3185 2887 3958 3959 2888 2 6 2867 2868 3190 2866 3214 3215 2 6 3189 2868 3181 3215 3216 3182 1 6 1741 1742 1744 3197 3198 3199 2 6 3184 3186 3193 3194 3195 3196 2 6 3184 3192 3194 7222 3216 3183 2 7 3193 3192 3195 7222 7221 7204 7203 2 6 3194 3192 3196 7196 7197 7203 2 6 3195 3192 3186 7583 7196 7584 1 6 1740 1741 3191 3198 3411 3200 1 7 3197 3191 3199 2893 2894 2895 3200 1 5 3198 3191 1744 1745 2893 1 6 3198 2895 3201 3411 3197 9751 1 6 3200 2895 2896 3202 3470 9751 1 6 3201 2896 2897 3203 3470 3471 1 6 3202 2897 2898 3204 3471 3472 1 6 3203 2898 3205 3472 3473 3474 1 6 3204 2898 2899 3206 3474 3475 1 6 3205 2899 2900 3207 3475 3476 1 6 3206 2900 2901 3208 3476 3477 1 6 3207 2901 2902 3209 3477 3478 1 6 3208 2902 3210 3211 3478 3479 1 6 3209 2902 3211 3212 3213 2903 1 6 3209 3210 3212 3479 3480 3481 1 7 3211 3210 3213 3481 3482 2907 3483 1 6 3212 3210 2903 3483 2905 2904 2 6 2866 3189 3215 7220 7219 7221 2 6 3214 3189 3190 3216 7221 7222 2 6 3215 3190 3182 7222 3193 3183 1 6 635 636 3218 4040 3763 3762 1 6 3217 636 638 3219 3484 4040 1 6 3218 638 3220 3221 3222 3484 1 6 3219 638 639 3221 3240 3241 1 6 3219 3220 3222 3223 3224 3241 1 6 3219 3221 3223 3484 3485 3486 1 6 3222 3221 3224 3225 3486 3487 1 6 3223 3221 3225 3226 3227 3241 1 6 3223 3224 3226 3493 3487 3494 1 7 3225 3224 3227 3228 3101 3494 3498 1 6 3226 3224 3228 3229 3230 3241 1 5 3226 3227 3101 3100 3229 1 6 3100 3228 3227 3230 3231 3684 1 6 3229 3227 3231 3232 3241 3240 1 6 3229 3230 3232 3233 3234 3684 1 6 3231 3230 3233 3240 3239 3236 1 7 3231 3232 3234 11 10 3235 3236 1 5 3231 3233 11 3684 12 1 6 10 3233 3236 3237 3238 9 1 6 3235 3233 3237 643 3239 3232 1 6 3235 3236 3238 647 644 643 1 5 3235 3237 9 8 647 1 6 643 3236 640 639 3240 3232 1 6 639 3239 3220 3241 3230 3232 1 6 3220 3240 3221 3224 3227 3230 1 6 2949 2950 3243 3736 3737 3738 1 6 3242 2950 2951 3244 3738 3739 1 6 3243 2951 2952 3245 3739 3740 1 7 3244 2952 2953 2954 3246 3740 3741 1 5 3245 2954 3247 3741 3742 1 6 3246 2954 2955 3248 3742 3743 1 6 3247 2955 2956 3249 3743 3744 1 6 3248 2956 2957 3250 3744 3745 1 6 3249 2957 3251 3745 3746 3747 1 6 3250 2957 2958 3252 3253 3747 1 6 3251 2958 3253 3254 2960 2959 1 6 3251 3252 3254 3747 3748 3749 1 6 3253 3252 2960 2961 3255 3749 1 6 3254 2961 2962 2964 3256 3749 1 6 3255 2964 3257 3749 3750 3751 1 6 3256 2964 2965 3258 3751 3752 1 6 3257 2965 3259 3752 3753 3754 1 6 3258 2965 2966 2967 3260 3754 1 6 3259 2967 2968 3261 3754 3755 1 6 3260 2968 2969 3262 3755 3756 1 6 3261 2969 2970 3263 3756 3757 1 6 3262 2970 2971 3264 3757 3758 1 6 3263 2971 2972 3265 3758 3759 1 7 3264 2972 2973 3266 3759 4054 4051 1 5 3265 2973 2974 3267 4054 1 6 3266 2974 2975 2976 3268 4054 1 7 3267 2976 2977 3269 4054 4053 4055 1 5 3268 2977 3270 4055 4056 1 6 3269 2977 2978 3271 4056 4057 2 6 3270 2978 2979 3272 4057 4058 2 6 3271 2979 2980 3273 4058 4059 2 6 3272 2980 2981 3274 4059 4060 2 6 3273 2981 2982 3275 4060 4061 2 6 3274 2982 2983 3276 4064 4061 2 6 3275 2983 2984 3277 4064 4065 2 6 3276 2984 2985 3826 4065 3824 1 6 2689 2690 3279 3588 3589 3590 1 6 3278 2690 2691 3280 3590 3591 1 6 3279 2691 2692 3281 3591 3592 1 6 3280 2692 2693 3282 3592 3593 1 6 3281 2693 2694 3283 3593 3594 1 6 3282 2694 2695 3284 3594 3595 1 6 3283 2695 2696 3285 3595 3596 1 6 3284 2696 2697 3286 3596 3597 1 6 3285 2697 2698 3287 3597 3598 1 6 3286 2698 2699 3288 3598 3599 1 6 3287 2699 2700 3289 3599 3600 1 6 3288 2700 2701 3290 3600 3601 1 6 3289 2701 2702 3003 3291 3601 1 6 3290 3003 3292 3601 3602 3603 1 6 3291 3003 3004 3293 3603 3604 1 6 3292 3004 3005 3294 3604 3605 1 6 3293 3005 3006 3295 3605 3606 1 6 3294 3006 3007 3296 3606 3607 1 6 3295 3007 3008 3297 3607 3608 1 6 3296 3008 3009 3010 3298 3608 1 6 3297 3010 3299 3608 3609 3610 1 6 3298 3010 3011 3300 3610 3611 1 6 3299 3011 3012 3301 3611 3612 1 6 3300 3012 3013 3302 3612 3613 1 6 3301 3013 3014 3303 3613 3614 1 6 3302 3014 3015 3304 3614 3615 1 6 3303 3015 3016 3305 3615 3616 1 6 3304 3016 3017 3306 3616 3617 1 6 3305 3017 3018 3307 3617 3618 1 6 3306 3018 3019 3308 3618 3619 1 6 3307 3019 3020 3309 3619 3620 1 6 3308 3020 3021 3310 3620 3621 1 6 3309 3021 3022 3311 3621 3622 1 6 3310 3022 3023 3312 3622 3623 1 6 3311 3023 3024 3313 3623 3624 1 6 3312 3024 3025 3314 3624 3625 1 6 3313 3025 3026 3315 3625 3626 1 6 3314 3026 3027 3316 3626 3627 1 6 3315 3027 3028 3317 3627 3628 1 6 3316 3028 3029 3318 3628 3629 1 6 3317 3029 3030 3319 3629 3630 1 6 3318 3030 3031 3320 3630 3631 1 6 3319 3031 3032 3321 3631 3632 1 6 3320 3032 3033 3322 3632 3633 1 6 3321 3033 3034 3042 3323 3633 1 6 3322 3042 3324 3633 3634 3635 1 6 3323 3042 3043 3325 3635 3636 1 6 3324 3043 3044 3045 3326 3636 1 6 3325 3045 3327 3636 3637 3638 1 6 3326 3045 3046 3053 3328 3638 1 6 3327 3053 3054 3329 3638 3639 1 6 3328 3054 3056 3639 3640 3641 1 6 2507 2508 32 33 3331 3880 1 6 3330 33 34 2248 3332 3880 1 6 3331 2248 3333 3334 3880 3881 1 6 3332 2248 3334 3335 3336 2249 1 6 3332 3333 3335 9707 6499 3881 1 6 3334 3333 3336 9706 6492 9707 1 6 3335 3333 2249 2250 2251 9706 1 6 1171 1172 1524 3338 3339 3882 1 6 3337 1524 3339 3340 3341 4250 1 6 3337 3338 3340 3882 3127 3883 1 6 3339 3338 3341 3342 3885 3883 1 6 3340 3338 3342 3343 2206 4250 1 6 3340 3341 3343 3861 6717 3885 1 6 3342 3341 2206 2207 3344 3861 1 6 3343 2207 2209 3345 3346 3861 1 6 3344 2209 3346 3347 3348 2211 1 6 3344 3345 3347 3861 3862 3863 1 6 3346 3345 3348 6532 3863 6524 1 6 3347 3345 2211 2213 6523 6524 1 6 3076 3077 3350 3918 3917 3919 1 6 3349 3077 3078 3107 3351 3919 1 6 3350 3107 3352 3919 3920 3921 1 6 3351 3107 3108 3353 3921 3922 1 6 3352 3108 3109 3354 3922 3923 1 6 3353 3109 3110 3355 3923 3924 1 6 3354 3110 3356 3924 3925 3374 1 6 3355 3110 3111 3357 3368 3374 1 6 3356 3111 3112 3358 3367 3368 1 6 3357 3112 3359 3153 3360 3367 1 6 3358 3112 3153 3085 3152 3084 1 6 3358 3153 3154 3361 3363 3367 1 6 3360 3154 3362 3363 3364 3678 1 6 3361 3154 3155 3677 3675 3678 1 6 3360 3361 3364 3365 3366 3367 1 6 3363 3361 3365 3678 3667 3668 1 6 3363 3364 3366 3373 3370 3668 1 6 3363 3365 3367 3368 3369 3370 1 6 3363 3366 3368 3360 3358 3357 1 6 3367 3366 3369 3357 3356 3374 1 6 3368 3366 3370 3371 3374 3375 1 6 3369 3366 3371 3372 3373 3365 1 6 3369 3370 3372 3375 3376 3377 1 6 3371 3370 3373 3377 3378 3379 1 6 3372 3370 3365 3379 3380 3668 1 6 3356 3368 3369 3375 3925 3355 1 7 3374 3369 3371 3376 3943 3925 4342 1 5 3375 3371 3377 4342 4343 1 6 3376 3371 3372 3378 4343 4344 1 6 3377 3372 3379 3645 4347 4344 1 6 3378 3372 3373 3380 3381 3645 1 6 3379 3373 3381 3382 3668 3656 1 6 3379 3380 3382 3383 3384 3645 1 6 3381 3380 3383 3390 3387 3656 1 6 3381 3382 3384 3385 3386 3387 1 6 3381 3383 3385 3645 3646 3647 1 6 3384 3383 3386 3647 3648 3649 1 6 3385 3383 3387 3388 3649 3650 1 6 3386 3383 3388 3389 3390 3382 1 6 3386 3387 3389 3650 3651 3652 1 6 3388 3387 3390 3652 3653 3654 1 6 3389 3387 3382 3654 3655 3656 1 6 2675 2676 3392 3573 3574 3575 1 6 3391 2676 2677 3393 3575 3576 1 6 3392 2677 2678 3394 3576 3577 1 6 3393 2678 2679 3577 3578 3579 1 6 2173 2804 2805 3396 3397 4747 1 6 3395 2805 3397 3398 3399 3400 1 6 3395 3396 3398 3892 4747 4746 1 6 3397 3396 3399 3892 3893 3894 1 6 3398 3396 3400 3894 3895 3896 1 6 3399 3396 2805 2806 3401 3896 1 6 3400 2806 2807 3402 3896 3897 1 6 3401 2807 3403 3897 3898 3899 1 6 3402 2807 2808 3404 3899 3900 1 6 3403 2808 1732 3405 3679 3900 1 6 3404 1732 1733 1734 3406 3679 1 6 3405 1734 1735 3407 3679 3680 1 6 3406 1735 1736 3408 3680 3681 1 6 3407 1736 1737 3409 3683 3681 1 6 3408 1737 1738 3410 3470 3683 1 6 3409 1738 1739 3411 9751 3470 1 6 3410 1739 1740 3197 3200 9751 2 6 3147 1674 1675 1676 3413 4231 2 6 3412 1676 1677 3414 9791 4231 2 6 3413 1677 3415 7778 7776 9791 2 6 3414 1677 1678 7778 7779 5382 1 6 1695 1696 3417 3786 1694 3787 1 6 3416 1696 1697 3418 3787 3789 1 6 3417 1697 1698 2223 3419 3789 1 6 3418 2223 3420 3789 3790 3791 1 6 3419 2223 2224 3421 3791 3792 1 6 3420 2224 2225 3422 3423 3792 1 6 3421 2225 3423 3424 3425 3426 1 6 3421 3422 3424 3794 3792 3795 1 6 3423 3422 3425 3795 3796 3797 1 6 3424 3422 3426 3797 3798 3799 1 6 3425 3422 2225 2226 3427 3799 1 6 3426 2226 2227 3428 3799 3800 1 6 3427 2227 2228 3429 3800 3801 1 6 3428 2228 3430 3801 3802 3432 1 6 3429 2228 2229 2238 3431 3432 1 6 3430 2238 3432 3433 3434 3435 1 6 3430 3431 3433 3442 3802 3429 1 6 3432 3431 3434 3442 3443 3444 1 6 3433 3431 3435 3444 3445 3446 1 6 3434 3431 2238 2239 2561 3446 2 6 2491 2492 3437 3438 3515 2493 2 6 2491 3436 3438 3439 3440 3441 2 6 3437 3436 3439 3513 3514 3515 2 6 3437 3438 3440 3508 3509 3513 2 6 3437 3439 3441 3451 3453 3508 2 6 3437 3440 2491 70 3451 69 1 6 3432 3433 3443 3802 3803 3804 1 6 3442 3433 3444 3804 3805 3806 1 6 3443 3433 3434 3445 3806 3807 1 6 3444 3434 3446 3807 3808 3447 1 6 3445 3434 3435 2561 2562 3447 1 6 3446 2562 3448 3808 3445 4107 1 6 3447 2562 2563 3449 3454 4107 1 6 3448 2563 2567 3454 3455 2568 1 7 3175 3176 3179 6655 6654 6656 6657 1 6 3441 3440 69 68 3452 3453 1 6 68 3451 3453 67 3505 3506 1 6 3452 3451 3440 3506 3507 3508 1 6 3448 3449 3455 3456 4107 4108 1 6 3454 3449 3456 3457 3458 2568 1 6 3454 3455 3457 3464 4110 4108 1 6 3456 3455 3458 3459 3460 3464 1 6 3457 3455 3459 3463 2569 2568 1 6 3457 3458 3460 3461 3462 3463 1 6 3457 3459 3461 3464 3465 3466 1 6 3460 3459 3462 3466 3467 3469 1 6 3461 3459 3463 1721 3469 1720 1 6 3462 3459 3458 2569 1720 1719 1 6 3456 3457 3460 3465 4394 4110 1 6 3464 3460 3466 4404 4394 4745 1 6 3465 3460 3461 3467 3468 4745 1 6 3466 3461 3468 2172 1724 3469 1 6 3466 3467 2172 4745 4746 4747 1 6 1724 3467 1722 1721 3462 3461 1 7 3201 3202 3471 9751 3410 3409 3683 1 6 3470 3202 3203 3472 3681 3683 1 6 3471 3203 3204 3473 3682 3681 1 6 3472 3204 3474 3685 3902 3682 1 6 3473 3204 3205 3475 3685 3686 1 6 3474 3205 3206 3476 3686 3687 1 6 3475 3206 3207 3477 3687 3688 1 6 3476 3207 3208 3478 3688 3689 1 6 3477 3208 3209 3479 3689 3690 1 6 3478 3209 3211 3480 3690 3691 1 6 3479 3211 3481 3499 3694 3691 1 6 3480 3211 3212 3482 3499 3500 1 5 3481 3212 2907 3500 2908 1 5 2907 3212 3213 2905 2906 1 6 3218 3219 3222 3485 4039 4040 1 6 3484 3222 3486 3489 3968 4039 1 6 3485 3222 3223 3487 3488 3489 1 6 3486 3223 3488 3492 3493 3225 1 6 3486 3487 3489 3490 3491 3492 1 6 3486 3488 3490 3485 3968 3969 1 6 3489 3488 3491 3969 3970 3971 1 6 3490 3488 3492 3971 9747 6555 1 6 3491 3488 3487 3493 3496 9747 1 6 3492 3487 3225 3494 3495 3496 1 6 3493 3225 3226 3495 3497 3498 1 6 3493 3494 3496 3497 3501 3115 1 6 3493 3495 3492 3501 3502 9747 1 6 3495 3494 3498 3102 3113 3115 1 5 3497 3494 3226 3101 3102 1 6 3480 3481 3500 3694 3695 3696 1 6 3499 3481 3482 2908 3696 3697 1 6 3496 3495 3502 3503 3504 3115 1 6 3496 3501 3503 9747 6706 9748 1 6 3502 3501 3504 6712 6710 9748 1 5 3503 3501 3115 6712 3116 1 6 67 3452 3506 6697 6703 66 1 6 3505 3452 3453 3507 6697 6704 1 6 3506 3453 3508 3510 4522 6704 2 6 3507 3453 3440 3439 3509 3510 2 6 3508 3439 3510 3511 3512 3513 2 6 3508 3509 3511 3770 3507 4522 2 6 3510 3509 3512 3770 3771 3772 2 6 3511 3509 3513 3772 3773 3520 2 6 3512 3509 3439 3438 3514 3520 2 6 3513 3438 3515 3520 3521 3517 2 6 3514 3438 3436 2493 3516 3517 2 6 3515 2493 3517 3518 1607 1606 2 6 3515 3516 3518 3521 3514 3522 2 6 3517 3516 1607 1613 3522 3523 2 5 1613 1607 1605 1608 1610 2 6 3513 3514 3521 3773 3512 4531 2 6 3520 3514 3517 3522 4116 4531 2 6 3521 3517 3518 3523 3525 4116 2 6 3522 3518 1613 1614 3524 3525 2 6 3523 1614 3525 3526 3527 3528 2 6 3523 3524 3526 3522 4116 4117 2 6 3525 3524 3527 3529 4117 4118 2 6 3526 3524 3528 3529 3530 3543 2 6 3527 3524 1614 3543 3544 1615 2 6 3526 3527 3530 3531 4118 9786 2 6 3529 3527 3531 3532 3542 3543 2 6 3529 3530 3532 3533 9786 9787 2 6 3531 3530 3533 3534 3541 3542 2 6 3531 3532 3534 3535 9787 9788 2 6 3533 3532 3535 3536 3540 3541 2 6 3533 3534 3536 3537 9788 7178 2 6 3535 3534 3537 3538 3539 3540 2 6 3535 3536 3538 7182 7179 7178 2 6 3537 3536 3539 7182 7183 7184 2 6 3538 3536 3540 7184 7185 7212 2 6 3539 3536 3534 3541 7212 4372 2 6 3540 3534 3532 3542 4372 4097 2 6 3541 3532 3530 3543 4096 4097 2 6 3542 3530 3527 3528 3544 4096 2 6 3543 3528 1615 4099 4096 3093 2 6 2986 2987 3546 3824 3825 3829 2 6 3545 2987 2988 3547 3829 3830 2 6 3546 2988 2989 3548 3830 3831 2 6 3547 2989 2990 3549 3831 3832 2 6 3548 2990 2991 3550 3832 3833 2 6 3549 2991 2992 3551 3809 3833 2 6 3550 2992 2993 3552 3809 3810 2 6 3551 2993 2994 3553 3810 3811 2 6 3552 2994 2995 3554 3811 3812 2 6 3553 2995 2996 3555 3812 3813 2 6 3554 2996 3556 3813 3814 3815 2 6 3555 2996 2997 3557 3815 3816 2 6 3556 2997 2998 2999 3558 3816 2 6 3557 2999 3000 3559 3816 3817 2 6 3558 3000 3001 3560 3817 3818 2 6 3559 3001 3002 3561 3562 3818 2 6 3560 3002 3562 3563 3564 3565 2 6 3560 3561 3563 3818 3819 3820 2 6 3562 3561 3564 3820 3821 3822 2 6 3563 3561 3565 3822 3823 3566 2 6 3564 3561 3002 2666 2667 3566 2 6 3565 2667 2668 3567 3823 3564 2 6 3566 2668 2669 3568 3850 3823 2 6 3567 2669 2670 3569 3879 3850 2 6 3568 2670 2671 3570 3891 3879 2 6 3569 2671 2672 2673 3571 3891 2 6 3570 2673 3572 4237 3891 4257 2 6 3571 2673 2674 3573 4257 4258 1 6 3572 2674 2675 3391 3574 4258 1 6 3573 3391 3575 4258 4259 4263 1 6 3574 3391 3392 3576 4263 4264 1 6 3575 3392 3393 3577 4264 4265 1 6 3576 3393 3394 3578 4265 4266 1 6 3577 3394 3579 4266 4267 4268 1 6 3578 3394 2679 2680 3580 4268 1 6 3579 2680 2681 3581 4141 4268 1 6 3580 2681 2682 3582 4141 4142 1 6 3581 2682 2683 3583 4142 4143 1 6 3582 2683 2684 3584 4143 4144 1 6 3583 2684 2685 3585 4144 4145 1 6 3584 2685 2686 3586 4145 4146 1 6 3585 2686 2687 3587 4146 4147 1 6 3586 2687 2688 3588 4147 4148 1 6 3587 2688 2689 3278 3589 4148 1 6 3588 3278 3590 4148 4149 4150 1 6 3589 3278 3279 3591 4150 4151 1 6 3590 3279 3280 3592 4151 4152 1 6 3591 3280 3281 3593 4152 4153 1 6 3592 3281 3282 3594 4153 4154 1 6 3593 3282 3283 3595 4154 4155 1 6 3594 3283 3284 3596 4155 4156 1 6 3595 3284 3285 3597 4156 4157 1 6 3596 3285 3286 3598 4157 4158 1 6 3597 3286 3287 3599 4158 4159 1 6 3598 3287 3288 3600 4159 4160 1 6 3599 3288 3289 3601 4160 4161 1 6 3600 3289 3290 3291 3602 4161 1 6 3601 3291 3603 4161 4162 4163 1 6 3602 3291 3292 3604 4163 4164 1 6 3603 3292 3293 3605 4164 4165 1 6 3604 3293 3294 3606 4165 4166 1 6 3605 3294 3295 3607 4166 4167 1 6 3606 3295 3296 3608 4167 4168 1 6 3607 3296 3297 3298 3609 4168 1 6 3608 3298 3610 4168 4169 4170 1 6 3609 3298 3299 3611 4170 4171 1 6 3610 3299 3300 3612 4171 4172 1 6 3611 3300 3301 3613 4172 4173 1 6 3612 3301 3302 3614 4173 4174 1 6 3613 3302 3303 3615 4174 4175 1 6 3614 3303 3304 3616 4175 4176 1 6 3615 3304 3305 3617 4176 4177 1 6 3616 3305 3306 3618 4177 4178 1 6 3617 3306 3307 3619 4178 4179 1 6 3618 3307 3308 3620 4179 4180 1 6 3619 3308 3309 3621 4180 4181 1 6 3620 3309 3310 3622 4181 4182 1 6 3621 3310 3311 3623 4182 4183 1 6 3622 3311 3312 3624 4183 4184 1 6 3623 3312 3313 3625 4184 4185 1 6 3624 3313 3314 3626 4185 4186 1 6 3625 3314 3315 3627 4186 4187 1 6 3626 3315 3316 3628 4187 4188 1 6 3627 3316 3317 3629 4188 4189 1 6 3628 3317 3318 3630 4189 4190 1 6 3629 3318 3319 3631 4190 4191 1 6 3630 3319 3320 3632 4191 4192 1 6 3631 3320 3321 3633 4192 4193 1 6 3632 3321 3322 3323 3634 4193 1 6 3633 3323 3635 3903 4193 4194 1 6 3634 3323 3324 3636 3903 3904 1 6 3635 3324 3325 3326 3637 3904 1 6 3636 3326 3638 3904 3905 3906 1 6 3637 3326 3327 3328 3639 3906 1 6 3638 3328 3329 3640 3906 3907 1 6 3639 3329 3641 3907 3908 3642 1 5 3640 3329 3056 3057 3642 1 7 3641 3057 3058 3643 3908 3640 3927 1 6 3642 3058 3059 3644 3909 3927 1 5 3643 3059 3061 3909 3910 1 6 3381 3384 3646 3379 3378 4347 1 6 3645 3384 3647 4347 4348 4349 1 6 3646 3384 3385 3648 4352 4349 1 6 3647 3385 3649 3657 4352 4353 1 6 3648 3385 3386 3650 3657 3658 1 6 3649 3386 3388 3651 3658 3659 1 6 3650 3388 3652 3659 3660 3661 1 6 3651 3388 3389 3653 3661 3662 1 6 3652 3389 3654 3662 3663 3664 1 6 3653 3389 3390 3655 3664 3665 1 6 3654 3390 3656 3665 3666 3667 1 6 3655 3390 3382 3667 3668 3380 1 6 3648 3649 3658 4353 4354 4358 1 6 3657 3649 3650 3659 4371 4358 1 6 3658 3650 3651 3660 9793 4371 1 6 3659 3651 3661 4906 4908 9793 1 6 3660 3651 3652 3662 3669 4906 1 6 3661 3652 3653 3663 3669 3670 1 6 3662 3653 3664 3670 3671 3672 1 6 3663 3653 3654 3665 3672 3673 1 6 3664 3654 3655 3666 3673 3674 1 6 3665 3655 3667 3674 3675 3678 1 6 3666 3655 3656 3668 3364 3678 1 6 3667 3656 3380 3364 3365 3373 1 6 3661 3662 3670 4903 4905 4906 1 6 3669 3662 3663 3671 4902 4903 1 6 3670 3663 3672 5918 4902 3951 1 6 3671 3663 3664 3673 3950 3951 1 6 3672 3664 3665 3674 3944 3950 1 6 3673 3665 3666 3675 3676 3944 1 6 3674 3666 3676 3677 3362 3678 1 6 3674 3675 3677 3158 3944 3945 1 6 3676 3675 3158 3156 3155 3362 1 6 3362 3675 3361 3364 3667 3666 1 6 3404 3405 3406 3680 3900 3901 1 6 3679 3406 3407 3681 3682 3901 1 7 3680 3407 3682 3472 3471 3683 3408 1 6 3680 3681 3472 3901 3902 3473 1 5 3471 3681 3408 3409 3470 1 7 418 3100 3229 3231 3234 12 13 1 7 3473 3474 3686 3902 4665 4664 4688 1 5 3685 3474 3475 3687 4688 1 7 3686 3475 3476 3688 4688 4689 4690 1 6 3687 3476 3477 3689 4690 4691 1 6 3688 3477 3478 3690 4691 4692 1 6 3689 3478 3479 3691 3692 4692 1 6 3690 3479 3692 3693 3694 3480 1 6 3690 3691 3693 4692 4693 4694 1 6 3692 3691 3694 4694 4695 4696 1 6 3693 3691 3480 3499 3695 4696 1 6 3694 3499 3696 4696 4697 4698 1 6 3695 3499 3500 3697 4698 4699 1 6 3696 3500 2908 2909 3698 4699 1 6 3697 2909 2910 3699 3972 4699 1 6 3698 2910 2911 3700 3972 3973 1 6 3699 2911 2912 2913 3701 3973 1 6 3700 2913 3702 3973 3974 3975 1 6 3701 2913 2914 3703 3975 3976 1 6 3702 2914 2915 3704 3976 3977 1 6 3703 2915 2916 3705 3977 3978 1 6 3704 2916 2917 3706 3978 3979 1 6 3705 2917 2918 3707 3979 3980 1 6 3706 2918 2919 3708 3980 3981 1 6 3707 2919 2920 3709 3981 3982 1 6 3708 2920 2921 3710 3982 3983 1 6 3709 2921 2922 3711 3983 3984 1 6 3710 2922 2923 3712 3984 3985 1 6 3711 2923 2924 3713 3985 3986 1 6 3712 2924 2925 3714 3986 3987 1 6 3713 2925 2926 3715 3987 3988 1 6 3714 2926 2927 3716 3988 3989 1 6 3715 2927 2928 3717 3989 3990 1 6 3716 2928 2929 3718 3990 3991 1 6 3717 2929 2930 3719 3991 3992 1 6 3718 2930 2931 3720 3992 3993 1 6 3719 2931 2932 3721 3993 3994 1 6 3720 2932 2933 3722 3994 3995 1 6 3721 2933 2934 3723 3995 3996 1 6 3722 2934 2935 3724 3996 3997 1 6 3723 2935 2936 3725 3997 3998 1 6 3724 2936 2937 3726 3998 3999 1 6 3725 2937 2938 3727 3999 4000 1 6 3726 2938 2939 3728 4000 4001 1 6 3727 2939 2940 3729 4001 4002 1 6 3728 2940 2941 3730 4002 4003 1 6 3729 2941 2942 3731 4003 4004 1 6 3730 2942 2943 3732 4004 4005 1 6 3731 2943 2944 2945 3733 4005 1 6 3732 2945 2946 3734 4005 4006 1 6 3733 2946 2947 2948 3735 4006 1 6 3734 2948 3736 4006 4007 3737 1 5 3735 2948 2949 3242 3737 1 6 3736 3242 3738 4007 3735 4012 1 6 3737 3242 3243 3739 4012 4013 1 6 3738 3243 3244 3740 4013 4014 1 6 3739 3244 3245 3741 4014 4015 1 6 3740 3245 3246 3742 4015 4016 1 6 3741 3246 3247 3743 4016 4017 1 6 3742 3247 3248 3744 4017 4018 1 6 3743 3248 3249 3745 4018 4019 1 6 3744 3249 3250 3746 4019 4020 1 6 3745 3250 3747 4020 4021 4022 1 6 3746 3250 3251 3253 3748 4022 1 6 3747 3253 3749 4022 4023 4024 1 7 3748 3253 3254 3255 3256 3750 4024 1 5 3749 3256 3751 4024 4025 1 6 3750 3256 3257 3752 4025 4026 1 6 3751 3257 3258 3753 4029 4026 1 7 3752 3258 3754 4037 4029 4046 3755 1 5 3753 3258 3259 3260 3755 1 6 3754 3260 3261 3756 4046 3753 1 6 3755 3261 3262 3757 4046 4047 1 6 3756 3262 3263 3758 4047 4048 1 6 3757 3263 3264 3759 4048 4049 1 6 3758 3264 3265 4049 4050 4051 1 6 615 617 3761 3764 3765 3763 1 6 3760 617 625 627 3762 3763 1 6 3761 627 3763 3217 635 629 1 6 3761 3762 3765 3760 4040 3217 1 6 615 3760 3765 4038 6557 612 1 6 3764 3760 3763 4038 4039 4040 1 5 2085 1567 3767 3768 6093 1 6 3766 1567 3768 3769 1571 1568 1 6 3766 3767 3769 6092 6093 6094 1 7 3768 3767 1571 6094 6088 6317 6318 1 6 3510 3511 3771 4522 4523 4524 1 6 3770 3511 3772 4524 4525 4528 2 6 3771 3511 3512 3773 4528 4529 2 6 3772 3512 3520 4529 4530 4531 2 6 1682 1683 3775 5391 5385 5383 2 6 3774 1683 3776 5620 5391 3778 2 6 3775 1683 1684 1686 3777 3778 2 6 3776 1686 3778 3779 3780 3781 2 6 3776 3777 3779 7791 5620 3775 2 6 3778 3777 3780 7798 7792 7791 2 6 3779 3777 3781 7798 3783 3782 2 6 3780 3777 1686 1687 1688 3782 2 6 3781 1688 1689 1691 3783 3780 2 6 3782 1691 3784 7798 3780 7799 2 6 3783 1691 1692 3785 7799 7800 2 6 3784 1692 3786 3787 3788 7800 1 6 3785 1692 1693 1694 3416 3787 1 6 3786 3416 3417 3785 3788 3789 2 6 3785 3787 3789 7800 7801 3790 1 6 3788 3787 3417 3418 3419 3790 2 6 3789 3419 3791 7801 3788 7802 1 6 3790 3419 3420 3792 3793 7802 1 6 3791 3420 3793 3794 3423 3421 1 6 3791 3792 3794 7802 7803 7804 1 6 3793 3792 3423 3795 7804 7805 1 6 3794 3423 3424 3796 7809 7805 1 6 3795 3424 3797 3952 7809 7810 1 6 3796 3424 3425 3798 3952 3953 1 6 3797 3425 3799 3953 3954 3955 1 6 3798 3425 3426 3427 3800 3955 1 6 3799 3427 3428 3801 3955 3956 1 6 3800 3428 3429 3802 3956 3957 1 6 3801 3429 3432 3442 3803 3957 1 6 3802 3442 3804 3957 4100 4239 1 6 3803 3442 3443 3805 4100 4101 1 6 3804 3443 3806 4101 4102 4103 1 6 3805 3443 3444 3807 4103 4104 1 6 3806 3444 3445 3808 4104 4105 1 6 3807 3445 3447 4105 4106 4107 2 6 3550 3551 3810 3833 3834 3835 2 6 3809 3551 3552 3811 3835 3836 2 6 3810 3552 3553 3812 3836 3837 2 6 3811 3553 3554 3813 3837 3838 2 6 3812 3554 3555 3814 3838 3839 2 6 3813 3555 3815 3839 3840 3841 2 6 3814 3555 3556 3816 3841 3842 2 6 3815 3556 3557 3558 3817 3842 2 6 3816 3558 3559 3818 3842 3843 2 6 3817 3559 3560 3562 3819 3843 2 6 3818 3562 3820 3843 3844 3845 2 6 3819 3562 3563 3821 3845 3846 2 6 3820 3563 3822 3846 3847 3848 2 6 3821 3563 3564 3823 3848 3849 2 6 3822 3564 3566 3849 3850 3567 2 6 2986 3545 3825 3826 3277 2985 2 6 3824 3545 3826 3827 3828 3829 2 6 3824 3825 3827 4069 4065 3277 2 6 3826 3825 3828 4756 4069 4763 2 6 3827 3825 3829 4763 4764 4765 2 6 3828 3825 3545 3546 3830 4765 2 6 3829 3546 3547 3831 4765 4766 2 6 3830 3547 3548 3832 4766 4767 2 6 3831 3548 3549 3833 4770 4767 2 6 3832 3549 3550 3809 3834 4770 2 6 3833 3809 3835 5016 4770 5024 2 6 3834 3809 3810 3836 5024 5025 2 6 3835 3810 3811 3837 5025 5026 2 6 3836 3811 3812 3838 4405 5026 2 6 3837 3812 3813 3839 3864 4405 2 6 3838 3813 3814 3840 3864 3865 2 6 3839 3814 3841 3865 3866 3867 2 6 3840 3814 3815 3842 3853 3867 2 6 3841 3815 3816 3817 3843 3853 2 6 3842 3817 3818 3819 3844 3853 2 6 3843 3819 3845 3853 3854 3855 2 6 3844 3819 3820 3846 3855 3856 2 6 3845 3820 3821 3847 3856 3857 2 6 3846 3821 3848 3860 3857 3876 2 6 3847 3821 3822 3849 3876 3877 2 6 3848 3822 3823 3850 3877 3878 2 6 3849 3823 3567 3878 3879 3568 1 6 2181 2199 2179 3852 2201 3129 1 6 2179 3851 27 26 3129 9781 2 6 3841 3842 3843 3844 3854 3867 2 6 3853 3844 3855 3867 3868 3869 2 6 3854 3844 3845 3856 3869 3870 2 6 3855 3845 3846 3857 3858 3870 2 6 3856 3846 3858 3859 3860 3847 2 6 3856 3857 3859 3870 3871 3872 2 6 3858 3857 3860 3872 3873 3874 2 6 3859 3857 3847 3874 3875 3876 1 6 3343 3344 3346 3862 6717 3342 1 6 3861 3346 3863 6716 6715 6717 1 7 3862 3346 6532 6531 3347 6533 6716 2 6 3838 3839 3865 4405 4406 4407 2 6 3864 3839 3840 3866 4407 4408 2 6 3865 3840 3867 4408 4409 3868 2 6 3866 3840 3841 3853 3854 3868 2 6 3867 3854 3869 4409 3866 4420 2 6 3868 3854 3855 3870 4420 4421 2 6 3869 3855 3856 3858 3871 4421 2 6 3870 3858 3872 4421 4422 4423 2 6 3871 3858 3859 3873 4423 4424 2 6 3872 3859 3874 4424 4425 4426 2 6 3873 3859 3860 3875 4426 4427 2 6 3874 3860 3876 4427 4428 3888 2 6 3875 3860 3847 3848 3877 3888 2 6 3876 3848 3849 3878 3888 3889 2 6 3877 3849 3850 3879 3889 3890 2 6 3878 3850 3568 3890 3891 3569 1 6 2507 3330 2509 3881 3331 3332 1 6 2509 3880 3334 6499 2511 3332 1 6 3337 3339 3127 1171 414 3128 1 6 3127 3339 3122 3884 3885 3340 1 6 3122 3883 3885 3886 3887 3121 1 6 3884 3883 3886 3342 6717 3340 1 6 3884 3885 3887 6538 6715 6717 1 6 3884 3886 3121 6713 6714 6538 2 6 3876 3877 3889 4428 3875 4251 2 6 3888 3877 3878 3890 4236 4251 2 6 3889 3878 3879 3891 4236 4237 2 6 3890 3879 3569 4237 3571 3570 1 6 3397 3398 3893 4746 4744 4743 1 6 3892 3398 3894 4743 4748 4749 1 6 3893 3398 3399 3895 4752 4749 1 6 3894 3399 3896 4661 4758 4752 1 6 3895 3399 3400 3401 3897 4661 1 6 3896 3401 3402 3898 4661 4662 1 6 3897 3402 3899 4662 4663 4664 1 6 3898 3402 3403 3900 4664 4665 1 6 3899 3403 3404 3679 3901 4665 1 6 3900 3679 3680 3682 3902 4665 1 5 3901 3682 3473 4665 3685 1 6 3634 3635 3904 4194 4195 4196 1 6 3903 3635 3636 3637 3905 4196 1 6 3904 3637 3906 4196 4197 4198 1 6 3905 3637 3638 3639 3907 4198 1 6 3906 3639 3640 3908 4198 4199 1 6 3907 3640 3642 3927 4199 4200 1 5 3643 3644 3910 3927 3928 1 7 3909 3644 3061 3062 3911 3928 3929 1 7 3910 3062 3063 3912 3929 3930 3931 1 6 3911 3063 3069 3913 3931 3932 1 6 3912 3069 3070 3914 3932 3933 1 6 3913 3070 3071 3915 3933 3934 1 6 3914 3071 3072 3916 3934 3935 1 6 3915 3072 3073 3917 3935 3936 1 6 3916 3073 3918 3349 3919 3936 1 6 3917 3073 3074 3075 3076 3349 1 6 3917 3349 3350 3351 3920 3936 1 6 3919 3351 3921 3936 3937 3938 1 6 3920 3351 3352 3922 3938 3939 1 6 3921 3352 3353 3923 3939 3940 1 6 3922 3353 3354 3924 3940 3941 1 6 3923 3354 3355 3925 3941 3942 1 6 3924 3355 3374 3942 3943 3375 1 6 3085 2482 2483 2484 3150 3152 1 6 3908 3642 3643 3909 3928 4200 1 6 3927 3909 3910 3929 4200 4201 1 6 3928 3910 3911 3930 4201 4202 1 6 3929 3911 3931 4202 4203 4204 1 5 3930 3911 3912 3932 4204 1 6 3931 3912 3913 3933 4204 4205 1 6 3932 3913 3914 3934 4205 4206 1 6 3933 3914 3915 3935 4206 4207 1 6 3934 3915 3916 3936 4207 3937 1 6 3935 3916 3917 3919 3920 3937 1 6 3936 3920 3938 4207 3935 4335 1 6 3937 3920 3921 3939 4335 4336 1 6 3938 3921 3922 3940 4336 4337 1 6 3939 3922 3923 3941 4337 4338 1 6 3940 3923 3924 3942 4338 4339 1 6 3941 3924 3925 3943 4339 4340 1 6 3942 3925 3375 4340 4341 4342 1 6 3673 3674 3676 3945 3950 3947 1 6 3944 3676 3158 3159 3946 3947 1 6 3945 3159 3947 3948 5922 3962 1 6 3945 3946 3948 3949 3950 3944 1 6 3947 3946 3949 5920 5921 5922 1 6 3947 3948 3950 3951 5919 5920 1 6 3947 3949 3951 3672 3673 3944 1 6 3950 3949 3672 5918 3671 5919 1 6 3796 3797 3953 7810 7811 7812 1 6 3952 3797 3798 3954 7812 7813 1 6 3953 3798 3955 7813 7814 7815 1 6 3954 3798 3799 3800 3956 7815 1 6 3955 3800 3801 3957 4238 7815 1 6 3956 3801 3802 3803 4238 4239 2 6 3187 3188 3959 3960 7588 7586 2 6 3958 3188 3960 3961 2890 2888 2 6 3958 3959 3961 7588 7589 7590 2 6 3960 3959 2890 7590 7591 7592 1 6 3159 3160 3963 5922 3946 5923 1 6 3962 3160 3964 3965 5923 5924 1 6 3963 3160 3965 3966 3967 3161 1 6 3963 3964 3966 5924 5942 5943 1 6 3965 3964 3967 5943 5948 5947 1 6 3966 3964 3161 5948 2488 2487 1 6 3485 3489 3969 6556 4038 4039 1 6 3968 3489 3490 3970 1597 6556 1 6 3969 3490 3971 6358 1595 1597 1 6 3970 3490 3491 6555 6357 6358 1 6 3698 3699 3973 4699 4700 4701 1 6 3972 3699 3700 3701 3974 4701 1 6 3973 3701 3975 4701 4702 4703 1 6 3974 3701 3702 3976 4703 4704 1 6 3975 3702 3703 3977 4704 4705 1 6 3976 3703 3704 3978 4705 4706 1 6 3977 3704 3705 3979 4706 4707 1 6 3978 3705 3706 3980 4707 4708 1 6 3979 3706 3707 3981 4708 4709 1 6 3980 3707 3708 3982 4709 4710 1 6 3981 3708 3709 3983 4710 4711 1 6 3982 3709 3710 3984 4711 4712 1 6 3983 3710 3711 3985 4712 4713 1 6 3984 3711 3712 3986 4713 4714 1 6 3985 3712 3713 3987 4714 4715 1 6 3986 3713 3714 3988 4715 4716 1 6 3987 3714 3715 3989 4716 4717 1 6 3988 3715 3716 3990 4717 4718 1 6 3989 3716 3717 3991 4718 4719 1 6 3990 3717 3718 3992 4719 4720 1 6 3991 3718 3719 3993 4720 4721 1 6 3992 3719 3720 3994 4439 4721 1 6 3993 3720 3721 3995 4439 4440 1 6 3994 3721 3722 3996 4440 4441 1 6 3995 3722 3723 3997 4441 4442 1 6 3996 3723 3724 3998 4442 4443 1 6 3997 3724 3725 3999 4443 4444 1 6 3998 3725 3726 4000 4444 4445 1 6 3999 3726 3727 4001 4445 4446 1 6 4000 3727 3728 4002 4070 4446 1 6 4001 3728 3729 4003 4008 4070 1 6 4002 3729 3730 4004 4008 4009 1 6 4003 3730 3731 4005 4009 4010 1 6 4004 3731 3732 3733 4006 4010 1 6 4005 3733 3734 3735 4007 4010 1 6 4006 3735 3737 4010 4011 4012 1 6 4002 4003 4009 4070 4071 4072 1 6 4008 4003 4004 4010 4072 4011 1 6 4009 4004 4005 4006 4007 4011 1 6 4010 4007 4012 4072 4009 4073 1 6 4011 4007 3737 3738 4013 4073 1 6 4012 3738 3739 4014 4073 4074 1 7 4013 3739 3740 4015 4074 4075 4076 1 6 4014 3740 3741 4016 4076 4077 1 6 4015 3741 3742 4017 4077 4078 1 6 4016 3742 3743 4018 4078 4079 1 6 4017 3743 3744 4019 4079 4080 1 6 4018 3744 3745 4020 4080 4081 1 6 4019 3745 3746 4021 4081 4082 1 6 4020 3746 4022 4030 4082 4083 1 6 4021 3746 3747 3748 4023 4030 1 6 4022 3748 4024 4030 4031 4032 1 6 4023 3748 3749 3750 4025 4032 1 6 4024 3750 3751 4026 4027 4032 1 6 4025 3751 4027 4028 4029 3752 1 6 4025 4026 4028 4032 4033 4034 1 6 4027 4026 4029 4034 4035 4036 1 6 4028 4026 3752 4036 4037 3753 1 6 4021 4022 4023 4031 4083 4084 1 6 4030 4023 4032 4084 4085 4033 1 6 4031 4023 4024 4025 4027 4033 1 6 4032 4027 4034 4085 4031 4462 1 6 4033 4027 4028 4035 4041 4462 1 6 4034 4028 4036 4041 4042 4043 1 6 4035 4028 4029 4037 4043 4044 1 6 4036 4029 3753 4044 4045 4046 1 6 3764 3765 4039 6556 6557 3968 1 6 4038 3765 4040 3968 3485 3484 1 6 4039 3765 3763 3217 3484 3218 1 6 4034 4035 4042 4462 4463 4464 1 6 4041 4035 4043 4464 4465 4466 1 6 4042 4035 4036 4044 4466 4467 1 6 4043 4036 4037 4045 4467 4468 1 6 4044 4037 4046 4468 4469 4047 1 6 4045 4037 3753 3755 3756 4047 1 6 4046 3756 3757 4048 4469 4045 1 6 4047 3757 3758 4049 4469 4470 1 6 4048 3758 3759 4050 4470 4209 1 6 4049 3759 4051 4052 4208 4209 1 6 4050 3759 4052 4053 4054 3265 1 6 4050 4051 4053 4208 4221 4222 1 6 4052 4051 4054 3268 4055 4222 1 6 4053 4051 3265 3266 3267 3268 1 5 4053 3268 3269 4056 4222 1 7 4055 3269 3270 4057 4222 4223 4224 2 7 4056 3270 3271 4058 4224 4225 4226 2 6 4057 3271 3272 4059 4226 4227 2 6 4058 3272 3273 4060 4227 4228 2 6 4059 3273 3274 4061 4062 4228 2 6 4060 3274 4062 4063 4064 3275 2 6 4060 4061 4063 4230 4228 4502 2 6 4062 4061 4064 4066 4067 4502 2 6 4063 4061 3275 3276 4065 4066 2 6 4064 3276 4066 4069 3826 3277 2 6 4064 4065 4063 4067 4068 4069 2 6 4063 4066 4068 4513 4502 4754 2 6 4067 4066 4069 4754 4755 4756 2 6 4068 4066 4065 3826 4756 3827 1 6 4001 4002 4008 4071 4446 4447 1 6 4070 4008 4072 4447 4448 4449 1 6 4071 4008 4009 4011 4073 4449 1 6 4072 4011 4012 4013 4074 4449 1 6 4073 4013 4014 4075 4449 4450 1 6 4074 4014 4076 4450 4451 4452 1 5 4075 4014 4015 4077 4452 1 6 4076 4015 4016 4078 4452 4453 1 6 4077 4016 4017 4079 4453 4454 1 6 4078 4017 4018 4080 4454 4455 1 6 4079 4018 4019 4081 4455 4456 1 6 4080 4019 4020 4082 4456 4457 1 6 4081 4020 4021 4083 4457 4458 1 6 4082 4021 4030 4084 4458 4459 1 6 4083 4030 4031 4085 4459 4460 1 6 4084 4031 4033 4460 4461 4462 2 6 2880 2881 4087 4089 7599 7600 2 6 4086 2881 2882 2883 4088 4089 2 6 4087 2883 4089 4090 4091 4092 2 7 4087 4088 4090 7598 7599 4086 7751 2 6 4089 4088 4091 7751 7753 4379 2 6 4090 4088 4092 4094 4378 4379 2 6 4091 4088 2883 2498 4093 4094 2 6 4092 2498 4094 4095 2809 2499 2 6 4092 4093 4095 4091 4378 4387 2 6 4094 4093 2809 4387 4386 4388 2 6 3542 3543 4097 4098 4099 3544 2 6 3542 4096 4098 4365 4372 3541 2 6 4097 4096 4099 4365 4366 4367 2 6 4098 4096 3544 4367 3094 3093 1 6 3803 3804 4101 4239 4240 4241 1 6 4100 3804 3805 4102 4241 4242 1 6 4101 3805 4103 4242 4243 4244 1 6 4102 3805 3806 4104 4111 4244 1 6 4103 3806 3807 4105 4111 4112 1 6 4104 3807 3808 4106 4112 4113 1 6 4105 3808 4107 4108 4109 4113 1 6 4106 3808 3447 3448 3454 4108 1 6 4107 3454 4106 4109 4110 3456 1 6 4106 4108 4110 4113 4114 4115 1 6 4109 4108 3456 4115 4394 3464 1 6 4103 4104 4112 4244 4245 4246 1 6 4111 4104 4105 4113 4249 4246 1 6 4112 4105 4106 4109 4114 4249 1 6 4113 4109 4115 4249 4391 4392 1 6 4114 4109 4110 4392 4393 4394 2 7 3522 3525 4117 4530 4531 3521 4119 2 5 4116 3525 3526 4118 4119 2 6 4117 3526 4119 4120 3529 9786 2 7 4117 4118 4120 4121 9784 4530 4116 2 6 4119 4118 4121 4122 9786 9789 2 6 4119 4120 4122 4123 4395 9784 2 6 4121 4120 4123 4124 9789 7172 2 6 4121 4122 4124 4125 4126 4395 2 6 4123 4122 4125 7171 4140 7172 2 6 4123 4124 4126 4127 4128 4140 2 6 4123 4125 4127 4395 4396 4397 1 6 4126 4125 4128 4129 4130 4397 1 6 4127 4125 4129 4136 4139 4140 1 6 4127 4128 4130 4131 4135 4136 1 6 4127 4129 4131 4132 4397 4398 1 6 4130 4129 4132 4133 4134 4135 1 6 4130 4131 4133 4401 4398 4410 1 6 4132 4131 4134 4410 4411 4412 1 6 4133 4131 4135 4412 4413 7164 1 6 4134 4131 4129 4136 4137 7164 1 6 4135 4129 4128 4137 4138 4139 1 6 4135 4136 4138 7163 7161 7164 1 6 4137 4136 4139 7168 7163 7169 1 6 4138 4136 4128 4140 7169 7170 2 6 4139 4128 4125 7170 7171 4124 1 6 3580 3581 4142 4268 4269 4270 1 6 4141 3581 3582 4143 4270 4271 1 6 4142 3582 3583 4144 4271 4272 1 6 4143 3583 3584 4145 4272 4273 1 6 4144 3584 3585 4146 4273 4274 1 6 4145 3585 3586 4147 4274 4275 1 6 4146 3586 3587 4148 4275 4276 1 6 4147 3587 3588 3589 4149 4276 1 6 4148 3589 4150 4276 4277 4278 1 6 4149 3589 3590 4151 4278 4279 1 6 4150 3590 3591 4152 4279 4280 1 6 4151 3591 3592 4153 4280 4281 1 6 4152 3592 3593 4154 4281 4282 1 6 4153 3593 3594 4155 4282 4283 1 6 4154 3594 3595 4156 4283 4284 1 6 4155 3595 3596 4157 4284 4285 1 6 4156 3596 3597 4158 4285 4286 1 6 4157 3597 3598 4159 4286 4287 1 6 4158 3598 3599 4160 4287 4288 1 6 4159 3599 3600 4161 4288 4289 1 6 4160 3600 3601 3602 4162 4289 1 6 4161 3602 4163 4289 4290 4291 1 6 4162 3602 3603 4164 4291 4292 1 6 4163 3603 3604 4165 4292 4293 1 6 4164 3604 3605 4166 4293 4294 1 6 4165 3605 3606 4167 4294 4295 1 6 4166 3606 3607 4168 4295 4296 1 6 4167 3607 3608 3609 4169 4296 1 6 4168 3609 4170 4296 4297 4298 1 6 4169 3609 3610 4171 4298 4299 1 6 4170 3610 3611 4172 4299 4300 1 6 4171 3611 3612 4173 4300 4301 1 6 4172 3612 3613 4174 4301 4302 1 6 4173 3613 3614 4175 4302 4303 1 6 4174 3614 3615 4176 4303 4304 1 6 4175 3615 3616 4177 4304 4305 1 6 4176 3616 3617 4178 4305 4306 1 6 4177 3617 3618 4179 4306 4307 1 6 4178 3618 3619 4180 4307 4308 1 6 4179 3619 3620 4181 4308 4309 1 6 4180 3620 3621 4182 4309 4310 1 6 4181 3621 3622 4183 4310 4311 1 6 4182 3622 3623 4184 4311 4312 1 6 4183 3623 3624 4185 4312 4313 1 6 4184 3624 3625 4186 4313 4314 1 6 4185 3625 3626 4187 4314 4315 1 6 4186 3626 3627 4188 4315 4316 1 6 4187 3627 3628 4189 4316 4317 1 6 4188 3628 3629 4190 4317 4318 1 6 4189 3629 3630 4191 4318 4319 1 6 4190 3630 3631 4192 4319 4320 1 6 4191 3631 3632 4193 4320 4321 1 6 4192 3632 3633 3634 4194 4321 1 6 4193 3634 3903 4195 4321 4322 1 6 4194 3903 4196 4322 4323 4324 1 6 4195 3903 3904 3905 4197 4324 1 6 4196 3905 4198 4324 4325 4326 1 6 4197 3905 3906 3907 4199 4326 1 6 4198 3907 3908 4200 4326 4327 1 6 4199 3908 3927 3928 4201 4327 1 6 4200 3928 3929 4202 4327 4328 1 6 4201 3929 3930 4203 4328 4329 1 6 4202 3930 4204 4329 4330 4331 1 6 4203 3930 3931 3932 4205 4331 1 6 4204 3932 3933 4206 4331 4332 1 6 4205 3933 3934 4207 4332 4333 1 7 4206 3934 3935 3937 4333 4334 4335 1 6 4050 4052 4209 4210 4211 4221 1 6 4050 4208 4210 4470 4049 4477 1 6 4209 4208 4211 4212 4477 4478 1 6 4210 4208 4212 4213 4220 4221 1 6 4210 4211 4213 4214 4478 4479 1 6 4212 4211 4214 4215 4216 4220 1 6 4212 4213 4215 4479 4480 4481 1 6 4214 4213 4216 4217 4481 4482 1 6 4215 4213 4217 4218 4219 4220 1 6 4215 4216 4218 4232 4482 4483 1 6 4217 4216 4219 4232 4233 4234 1 6 4218 4216 4220 4224 4234 4223 1 6 4219 4216 4213 4211 4221 4223 1 6 4220 4211 4208 4052 4222 4223 1 6 4221 4052 4053 4055 4056 4223 1 6 4222 4056 4224 4221 4220 4219 2 6 4223 4056 4057 4225 4234 4219 2 6 4224 4057 4226 4235 4234 4488 2 5 4225 4057 4058 4227 4488 2 7 4226 4058 4059 4228 4229 4487 4488 2 6 4227 4059 4229 4230 4062 4060 2 6 4227 4228 4230 4489 4487 4500 2 6 4229 4228 4062 4500 4501 4502 2 6 3147 3412 3146 3145 9791 3413 1 6 4217 4218 4233 4483 4484 4485 2 6 4232 4218 4234 4235 4485 4486 2 6 4233 4218 4235 4225 4224 4219 2 6 4233 4234 4225 4486 4487 4488 2 6 3889 3890 4237 4251 4252 4256 2 6 4236 3890 3891 3571 4256 4257 1 6 3956 3957 4239 7815 7816 4503 1 6 4238 3957 3803 4100 4240 4503 1 6 4239 4100 4241 4503 4504 4505 1 6 4240 4100 4101 4242 4505 4506 1 6 4241 4101 4102 4243 4416 4506 1 6 4242 4102 4244 4416 4417 4418 1 6 4243 4102 4103 4111 4245 4418 1 6 4244 4111 4246 4247 4418 4419 1 6 4245 4111 4247 4248 4249 4112 1 6 4245 4246 4248 4419 7829 7830 1 6 4247 4246 4249 4391 4739 7830 1 6 4248 4246 4112 4113 4114 4391 1 6 3341 3338 1524 1525 2205 2206 2 6 3889 4236 4252 4253 4428 3888 2 6 4251 4236 4253 4254 4255 4256 2 6 4251 4252 4254 4647 4428 6892 2 6 4253 4252 4255 4729 4730 6892 2 6 4254 4252 4256 4729 4261 4260 2 6 4255 4252 4236 4237 4257 4260 2 6 4256 4237 3571 3572 4258 4260 2 6 4257 3572 3573 3574 4259 4260 2 6 4258 3574 4260 4261 4262 4263 2 6 4258 4259 4261 4256 4257 4255 2 6 4260 4259 4262 4732 4729 4255 2 6 4261 4259 4263 6901 4732 6902 1 6 4262 4259 3574 3575 4264 6902 1 6 4263 3575 3576 4265 5231 6902 1 6 4264 3576 3577 4266 5231 5232 1 6 4265 3577 3578 4267 5232 5233 1 6 4266 3578 4268 5233 5234 4269 1 6 4267 3578 3579 3580 4141 4269 1 6 4268 4141 4270 5234 4267 5451 1 6 4269 4141 4142 4271 5451 5452 1 6 4270 4142 4143 4272 5452 5453 1 6 4271 4143 4144 4273 5453 5454 1 6 4272 4144 4145 4274 5457 5454 1 6 4273 4145 4146 4275 5469 5457 1 6 4274 4146 4147 4276 5469 5470 1 6 4275 4147 4148 4149 4277 5470 1 6 4276 4149 4278 5470 5471 5472 1 6 4277 4149 4150 4279 5472 5473 1 6 4278 4150 4151 4280 5473 5474 1 6 4279 4151 4152 4281 5046 5474 1 6 4280 4152 4153 4282 5046 5047 1 6 4281 4153 4154 4283 5047 5048 1 6 4282 4154 4155 4284 5048 5049 1 6 4283 4155 4156 4285 5049 5050 1 6 4284 4156 4157 4286 5050 5051 1 6 4285 4157 4158 4287 5051 5052 1 6 4286 4158 4159 4288 4923 5052 1 6 4287 4159 4160 4289 4923 4924 1 6 4288 4160 4161 4162 4290 4924 1 6 4289 4162 4291 4924 4925 4926 1 6 4290 4162 4163 4292 4926 4927 1 6 4291 4163 4164 4293 4927 4928 1 6 4292 4164 4165 4294 4928 4929 1 6 4293 4165 4166 4295 4929 4930 1 6 4294 4166 4167 4296 4930 4931 1 6 4295 4167 4168 4169 4297 4931 1 6 4296 4169 4298 4771 4931 4932 1 6 4297 4169 4170 4299 4771 4772 1 6 4298 4170 4171 4300 4772 4773 1 6 4299 4171 4172 4301 4773 4774 1 6 4300 4172 4173 4302 4774 4775 1 6 4301 4173 4174 4303 4775 4776 1 6 4302 4174 4175 4304 4776 4777 1 6 4303 4175 4176 4305 4777 4778 1 6 4304 4176 4177 4306 4778 4779 1 6 4305 4177 4178 4307 4779 4780 1 6 4306 4178 4179 4308 4780 4781 1 6 4307 4179 4180 4309 4781 4782 1 6 4308 4180 4181 4310 4566 4782 1 6 4309 4181 4182 4311 4566 4567 1 6 4310 4182 4183 4312 4567 4568 1 6 4311 4183 4184 4313 4568 4569 1 6 4312 4184 4185 4314 4569 4570 1 6 4313 4185 4186 4315 4570 4571 1 6 4314 4186 4187 4316 4571 4572 1 6 4315 4187 4188 4317 4572 4573 1 6 4316 4188 4189 4318 4573 4574 1 6 4317 4189 4190 4319 4574 4575 1 6 4318 4190 4191 4320 4575 4576 1 6 4319 4191 4192 4321 4576 4577 1 6 4320 4192 4193 4194 4322 4577 1 6 4321 4194 4195 4323 4577 4578 1 6 4322 4195 4324 4578 4579 4580 1 6 4323 4195 4196 4197 4325 4580 1 6 4324 4197 4326 4580 4581 4582 1 6 4325 4197 4198 4199 4327 4582 1 6 4326 4199 4200 4201 4328 4582 1 6 4327 4201 4202 4329 4582 4583 1 6 4328 4202 4203 4330 4583 4584 1 6 4329 4203 4331 4584 4585 4589 1 7 4330 4203 4204 4205 4332 4589 4590 1 6 4331 4205 4206 4333 4590 4591 1 6 4332 4206 4207 4334 4591 4592 1 6 4333 4207 4335 4336 4429 4592 1 5 4334 4207 3937 3938 4336 1 6 4335 3938 3939 4337 4334 4429 1 6 4336 3939 3940 4338 4429 4430 1 6 4337 3940 3941 4339 4430 4431 1 6 4338 3941 3942 4340 4431 4432 1 6 4339 3942 3943 4341 4432 4433 1 6 4340 3943 4342 4433 4434 4435 1 6 4341 3943 3375 3376 4343 4435 1 6 4342 3376 3377 4344 4345 4435 1 6 4343 3377 4345 4346 4347 3378 1 6 4343 4344 4346 4435 4436 4437 1 6 4345 4344 4347 4437 4438 4348 1 6 4346 4344 3378 3645 3646 4348 1 6 4347 3646 4349 4350 4438 4346 1 6 4348 3646 4350 4351 4352 3647 1 6 4348 4349 4351 4601 4438 4602 1 6 4350 4349 4352 4602 4603 4604 1 6 4351 4349 3647 3648 4353 4604 1 6 4352 3648 3657 4354 4355 4604 1 6 4353 3657 4355 4356 4357 4358 1 6 4353 4354 4356 4604 4605 4606 1 6 4355 4354 4357 4361 4362 4606 1 6 4356 4354 4358 4359 4360 4361 1 6 4357 4354 4359 4371 3658 3657 1 6 4357 4358 4360 4368 4369 4371 1 6 4357 4359 4361 4364 4368 4614 1 6 4357 4360 4356 4362 4363 4364 1 6 4356 4361 4363 4606 4607 4608 1 6 4362 4361 4364 4611 4608 4612 1 6 4363 4361 4360 4612 4613 4614 2 6 4097 4098 4366 4372 4373 4374 2 6 4365 4098 4367 4374 4375 4376 2 7 4366 4098 4099 3094 4376 1626 1624 1 6 4360 4359 4369 4370 4614 4615 1 6 4368 4359 4370 4371 9794 9793 1 6 4368 4369 9794 4642 4637 4615 1 6 4369 4359 4358 3658 9793 3659 2 6 4097 4365 4373 7212 3540 3541 2 6 4372 4365 4374 7212 7210 7209 2 6 4373 4365 4366 4375 7209 7213 2 6 4374 4366 4376 4377 7213 7214 2 6 4375 4366 4367 4377 1627 1626 2 5 4375 4376 1627 7214 7215 2 6 4091 4094 4379 4380 4381 4387 2 7 4091 4378 4380 7753 4090 7752 7754 2 6 4379 4378 4381 4382 7754 7755 2 6 4380 4378 4382 4383 4384 4387 2 6 4380 4381 4383 7755 7756 7764 2 6 4382 4381 4384 4385 4389 7764 2 6 4383 4381 4385 3140 4386 4387 2 6 4383 4384 3140 4389 4390 3141 2 6 3140 4384 4387 4095 4388 3139 2 6 4386 4384 4381 4378 4094 4095 2 6 4386 4095 2809 2810 2813 3139 2 6 4383 4385 4390 7764 7765 7766 2 6 4389 4385 3141 7766 7767 3142 1 6 4249 4114 4392 4248 4739 4740 1 6 4391 4114 4115 4393 4402 4740 1 6 4392 4115 4394 4402 4403 4404 1 6 4393 4115 4110 3464 4404 3465 2 5 4121 4123 4126 4396 9784 2 7 4395 4126 4397 4399 4528 4529 9784 1 6 4396 4126 4127 4130 4398 4399 1 6 4397 4130 4399 4400 4401 4132 1 6 4397 4398 4400 4525 4528 4396 1 5 4399 4398 4401 4527 4525 1 7 4400 4398 4132 4410 4534 4527 4535 1 6 4392 4393 4403 4740 4741 4742 1 6 4402 4393 4404 4742 4743 4744 1 6 4403 4393 4394 3465 4744 4745 2 6 3837 3838 3864 4406 5026 5027 2 6 4405 3864 4407 5027 5028 5029 2 6 4406 3864 3865 4408 5029 5030 2 6 4407 3865 3866 4409 5030 5031 2 6 4408 3866 3868 4420 5031 5032 1 6 4401 4132 4133 4411 4535 4536 1 6 4410 4133 4412 4545 4539 4536 1 6 4411 4133 4134 4413 4414 4545 1 6 4412 4134 4414 4415 7164 7165 1 6 4412 4413 4415 4545 4544 4648 1 6 4414 4413 4649 4648 7165 7166 1 6 4242 4243 4417 4506 4507 4508 1 6 4416 4243 4418 4508 4509 4510 1 6 4417 4243 4244 4245 4419 4510 1 6 4418 4245 4247 7828 4510 7829 2 6 4409 3868 3869 4421 5032 5033 2 6 4420 3869 3870 3871 4422 5033 2 6 4421 3871 4423 5033 5034 5035 2 6 4422 3871 3872 4424 5035 5036 2 6 4423 3872 3873 4425 4643 5036 2 6 4424 3873 4426 4643 4644 4645 2 6 4425 3873 3874 4427 4645 4646 2 6 4426 3874 3875 4428 4646 4647 2 6 4427 3875 3888 4647 4253 4251 1 6 4334 4336 4337 4430 4592 4593 1 6 4429 4337 4338 4431 4593 4594 1 6 4430 4338 4339 4432 4594 4595 1 6 4431 4339 4340 4433 4595 4596 1 6 4432 4340 4341 4434 4596 4597 1 6 4433 4341 4435 4597 4598 4436 1 6 4434 4341 4342 4343 4345 4436 1 6 4435 4345 4437 4598 4434 4599 1 6 4436 4345 4346 4438 4599 4600 1 6 4437 4346 4348 4600 4601 4350 1 6 3993 3994 4440 4721 4722 4723 1 6 4439 3994 3995 4441 4723 4724 1 6 4440 3995 3996 4442 4724 4725 1 6 4441 3996 3997 4443 4725 4726 1 6 4442 3997 3998 4444 4726 4727 1 6 4443 3998 3999 4445 4727 4728 1 6 4444 3999 4000 4446 4728 4658 1 6 4445 4000 4001 4070 4447 4658 1 6 4446 4070 4071 4448 4658 4659 1 6 4447 4071 4449 4659 4660 4450 1 6 4448 4071 4072 4073 4074 4450 1 6 4449 4074 4075 4451 4660 4448 1 6 4450 4075 4452 4669 4738 4660 1 6 4451 4075 4076 4077 4453 4669 1 6 4452 4077 4078 4454 4669 4670 1 6 4453 4078 4079 4455 4670 4671 1 6 4454 4079 4080 4456 4671 4672 1 6 4455 4080 4081 4457 4672 4673 1 6 4456 4081 4082 4458 4673 4674 1 6 4457 4082 4083 4459 4674 4675 1 6 4458 4083 4084 4460 4675 4676 1 6 4459 4084 4085 4461 4676 4677 1 6 4460 4085 4462 4677 4678 4679 1 7 4461 4085 4033 4034 4041 4463 4679 1 5 4462 4041 4464 4679 4680 1 6 4463 4041 4042 4465 4471 4680 1 6 4464 4042 4466 4471 4472 4473 1 6 4465 4042 4043 4467 4473 4474 1 6 4466 4043 4044 4468 4474 4475 1 6 4467 4044 4045 4469 4475 4476 1 6 4468 4045 4047 4048 4470 4476 1 6 4469 4048 4049 4209 4476 4477 1 6 4464 4465 4472 4680 4681 4682 1 6 4471 4465 4473 4682 4683 4684 1 6 4472 4465 4466 4474 4684 4685 1 6 4473 4466 4467 4475 4685 4686 1 6 4474 4467 4468 4476 4686 4687 1 6 4475 4468 4469 4470 4477 4687 1 6 4476 4470 4209 4210 4478 4687 1 6 4477 4210 4212 4479 4687 5213 1 6 4478 4212 4214 4480 5213 5214 1 6 4479 4214 4481 5214 5215 5216 1 6 4480 4214 4215 4482 4490 5216 1 6 4481 4215 4217 4483 4490 4491 1 6 4482 4217 4232 4484 4491 4492 1 6 4483 4232 4485 4492 4493 4494 2 6 4484 4232 4233 4486 4494 4495 2 6 4485 4233 4235 4487 4489 4495 2 6 4486 4235 4488 4227 4489 4229 2 5 4487 4235 4227 4226 4225 2 6 4486 4487 4229 4495 4496 4500 1 6 4481 4482 4491 4981 4989 5216 1 6 4490 4482 4483 4492 4981 4982 1 6 4491 4483 4484 4493 4982 4983 1 6 4492 4484 4494 4983 4984 4985 2 6 4493 4484 4485 4495 4985 4497 2 6 4494 4485 4486 4489 4496 4497 2 6 4495 4489 4497 4498 4499 4500 2 6 4495 4496 4498 4985 4494 4986 2 6 4497 4496 4499 4986 4987 4988 2 5 4498 4496 4500 4988 4511 2 7 4499 4496 4489 4229 4230 4501 4511 2 6 4500 4230 4502 4511 4512 4513 2 6 4501 4230 4062 4513 4067 4063 1 6 4239 4240 4504 7816 4238 7817 1 6 4503 4240 4505 7817 7818 7819 1 6 4504 4240 4241 4506 7819 7820 1 6 4505 4241 4242 4416 4507 7820 1 6 4506 4416 4508 7820 7821 7822 1 6 4507 4416 4417 4509 7822 7823 1 6 4508 4417 4510 7823 7824 7825 1 6 4509 4417 4418 7825 7828 4419 2 7 4500 4501 4512 4988 4499 5002 4999 2 6 4511 4501 4513 4754 4759 5002 2 5 4512 4501 4502 4067 4754 1 6 426 411 4515 4516 5611 5612 1 6 4514 411 4516 4517 4521 410 1 6 4514 4515 4517 4518 5611 5615 1 6 4516 4515 4518 4519 4520 4521 1 6 4516 4517 4519 9734 7508 5615 1 6 4518 4517 4520 5235 9734 9678 1 6 4519 4517 4521 5235 5236 5237 1 6 4520 4517 4515 410 5237 421 1 7 3507 3510 3770 4523 6693 6695 6704 1 6 4522 3770 4524 6694 6693 4532 1 6 4523 3770 3771 4525 4526 4532 1 7 4524 3771 4526 4527 4400 4399 4528 1 6 4524 4525 4527 4532 4533 4534 1 5 4526 4525 4400 4534 4401 1 6 4399 4525 3771 3772 4529 4396 2 6 4528 3772 3773 4530 4396 9784 2 6 4529 3773 4531 4116 4119 9784 2 5 4530 3773 4116 3521 3520 1 6 4524 4526 4533 5156 4523 6694 1 6 4532 4526 4534 5156 5157 4666 1 6 4533 4526 4527 4401 4535 4666 1 6 4534 4401 4410 4536 4537 4666 1 6 4535 4410 4537 4538 4539 4411 1 6 4535 4536 4538 4666 4667 4668 1 6 4537 4536 4539 4540 4546 4668 1 6 4538 4536 4540 4541 4545 4411 1 6 4538 4539 4541 4542 4546 4547 1 6 4540 4539 4542 4543 4544 4545 1 6 4540 4541 4543 4550 4547 4551 1 6 4542 4541 4544 4551 4552 4553 1 6 4543 4541 4545 4414 4648 4553 1 6 4544 4541 4539 4411 4412 4414 1 6 4538 4540 4547 4548 9762 4668 1 6 4546 4540 4548 4549 4550 4542 1 6 4546 4547 4549 4557 4560 9762 1 6 4548 4547 4550 4557 4558 4559 1 6 4549 4547 4542 4551 6763 4559 1 6 4550 4542 4543 4552 7144 6763 1 6 4551 4543 4553 4554 7145 7144 1 6 4552 4543 4554 4555 4544 4648 1 6 4552 4553 4555 4556 7145 7146 1 6 4554 4553 4556 4648 4649 7153 1 6 4554 4555 7146 7148 7149 7153 1 6 4548 4549 4558 4560 4561 4562 1 6 4557 4549 4559 4565 4562 6764 1 6 4558 4549 6763 6762 6764 4550 1 7 4548 4557 4561 9762 9761 6675 9792 1 6 4560 4557 4562 4563 6674 6675 1 6 4561 4557 4563 4564 4565 4558 1 6 4561 4562 4564 6665 6666 6674 1 6 4563 4562 4565 6673 6665 6790 1 6 4564 4562 4558 6764 6765 6790 1 6 4309 4310 4567 4782 4783 4784 1 6 4566 4310 4311 4568 4784 4785 1 6 4567 4311 4312 4569 4785 4786 1 6 4568 4312 4313 4570 4786 4787 1 6 4569 4313 4314 4571 4787 4788 1 6 4570 4314 4315 4572 4788 4789 1 6 4571 4315 4316 4573 4789 4790 1 6 4572 4316 4317 4574 4790 4791 1 6 4573 4317 4318 4575 4791 4792 1 6 4574 4318 4319 4576 4792 4793 1 6 4575 4319 4320 4577 4793 4794 1 6 4576 4320 4321 4322 4578 4794 1 6 4577 4322 4323 4579 4794 4795 1 6 4578 4323 4580 4795 4796 4797 1 6 4579 4323 4324 4325 4581 4797 1 6 4580 4325 4582 4797 4798 4583 1 6 4581 4325 4326 4327 4328 4583 1 6 4582 4328 4329 4584 4798 4581 1 7 4583 4329 4330 4585 4586 4804 4798 1 6 4584 4330 4586 4587 4588 4589 1 5 4584 4585 4587 4804 4805 1 6 4586 4585 4588 4805 4806 4807 1 6 4587 4585 4589 4807 4808 4809 1 6 4588 4585 4330 4331 4590 4809 1 5 4589 4331 4332 4591 4809 1 6 4590 4332 4333 4592 4809 4810 1 6 4591 4333 4334 4429 4593 4810 1 6 4592 4429 4430 4594 4810 4811 1 6 4593 4430 4431 4595 4811 4812 1 6 4594 4431 4432 4596 4812 4813 1 6 4595 4432 4433 4597 4813 4814 1 6 4596 4433 4434 4598 4814 4815 1 6 4597 4434 4436 4599 4815 4816 1 6 4598 4436 4437 4600 4816 4817 1 6 4599 4437 4438 4601 4817 4818 1 6 4600 4438 4350 4602 4821 4818 1 6 4601 4350 4351 4603 4821 4822 1 6 4602 4351 4604 4825 4822 4826 1 7 4603 4351 4352 4353 4355 4605 4826 1 5 4604 4355 4606 4826 4827 1 6 4605 4355 4356 4362 4607 4827 1 5 4606 4362 4608 4609 4827 1 6 4607 4362 4609 4610 4611 4363 1 7 4607 4608 4610 4827 4828 4829 4830 1 6 4609 4608 4611 4830 4831 4832 1 6 4610 4608 4363 4612 4832 4834 1 6 4611 4363 4364 4613 4837 4834 1 6 4612 4364 4614 4616 4617 4837 1 6 4613 4364 4360 4368 4615 4616 1 7 4614 4368 4616 4637 4634 4619 4370 1 6 4614 4615 4613 4617 4618 4619 1 6 4613 4616 4618 4837 4622 4838 1 6 4617 4616 4619 4620 4621 4622 1 6 4618 4616 4620 4633 4634 4615 1 6 4618 4619 4621 4628 4629 4633 1 6 4618 4620 4622 4623 4624 4628 1 6 4618 4621 4623 4840 4838 4617 1 6 4622 4621 4624 4625 4840 4841 1 6 4623 4621 4625 4626 4627 4628 1 6 4623 4624 4626 4841 4860 4853 1 6 4625 4624 4627 4860 4861 4862 1 6 4626 4624 4628 4862 4863 4630 1 6 4627 4624 4621 4620 4629 4630 1 6 4628 4620 4630 4631 4632 4633 1 6 4628 4629 4631 4863 4627 4864 1 6 4630 4629 4632 4638 4868 4864 1 6 4631 4629 4633 4638 4639 4635 1 6 4632 4629 4620 4619 4634 4635 1 6 4633 4619 4635 4636 4637 4615 1 6 4633 4634 4636 4639 4632 4640 1 6 4635 4634 4637 4640 4641 4642 1 5 4636 4634 4615 4642 4370 1 6 4631 4632 4639 4868 4912 9760 1 6 4638 4632 4635 4640 4912 4913 1 6 4639 4635 4636 4641 4916 4913 1 6 4640 4636 4642 4910 4916 4909 1 7 4641 4636 4637 4908 4909 9794 4370 2 6 4424 4425 4644 5036 5037 5044 2 6 4643 4425 4645 5045 5044 6889 2 6 4644 4425 4426 4646 6890 6889 2 6 4645 4426 4427 4647 6890 6891 2 6 4646 4427 4428 4253 6891 6892 1 6 4544 4414 4553 4555 4649 4415 1 6 4555 4648 4415 7166 7154 7153 1 6 422 52 53 4651 4652 9684 1 6 4650 53 4652 4653 4657 54 1 6 4650 4651 4653 4654 9683 9684 1 6 4652 4651 4654 4655 4656 4657 1 6 4652 4653 4655 9682 9680 9683 1 6 4654 4653 4656 9682 9685 9686 1 7 4655 4653 4657 5380 9688 9686 9689 1 6 4656 4653 4651 54 5380 55 1 6 4446 4447 4659 4728 4445 4736 1 6 4658 4447 4448 4660 4736 4737 1 6 4659 4448 4450 4737 4738 4451 1 6 3895 3896 3897 4662 7841 4758 1 6 4661 3897 3898 4663 7841 7842 1 6 4662 3898 4664 7842 4689 4688 1 6 4663 3898 3899 4665 3685 4688 1 6 4664 3899 3900 3901 3902 3685 1 6 4534 4535 4537 4667 5157 4533 1 6 4666 4537 4668 9750 5157 9761 1 6 4667 4537 4538 9761 9762 4546 1 7 4451 4452 4453 4670 4980 4738 5194 1 6 4669 4453 4454 4671 5194 5195 1 6 4670 4454 4455 4672 5195 5196 1 6 4671 4455 4456 4673 5196 5197 1 6 4672 4456 4457 4674 5197 5198 1 6 4673 4457 4458 4675 5198 5199 1 6 4674 4458 4459 4676 5199 5200 1 6 4675 4459 4460 4677 5200 5201 1 6 4676 4460 4461 4678 5201 5202 1 6 4677 4461 4679 5202 5203 5204 1 6 4678 4461 4462 4463 4680 5204 1 7 4679 4463 4464 4471 4681 5204 5205 1 5 4680 4471 4682 5205 5206 1 7 4681 4471 4472 4683 5206 5207 5208 1 5 4682 4472 4684 5208 5209 1 7 4683 4472 4473 4685 5209 5210 5211 1 6 4684 4473 4474 4686 5211 5212 1 6 4685 4474 4475 4687 5212 5213 1 6 4686 4475 4476 4477 4478 5213 1 6 4664 3685 3686 3687 4689 4663 1 6 4688 3687 4690 7842 4663 7843 1 6 4689 3687 3688 4691 7843 7844 1 6 4690 3688 3689 4692 5158 7844 1 6 4691 3689 3690 3692 4693 5158 1 6 4692 3692 4694 5158 5159 5160 1 6 4693 3692 3693 4695 5160 5161 1 6 4694 3693 4696 5161 5162 5163 1 6 4695 3693 3694 3695 4697 5163 1 6 4696 3695 4698 5163 5164 5165 1 6 4697 3695 3696 4699 5165 4700 1 6 4698 3696 3697 3698 3972 4700 1 6 4699 3972 4701 5165 4698 7854 1 6 4700 3972 3973 3974 4702 7854 1 6 4701 3974 4703 7308 7854 7855 1 6 4702 3974 3975 4704 7308 7309 1 6 4703 3975 3976 4705 7309 7310 1 6 4704 3976 3977 4706 7310 7311 1 6 4705 3977 3978 4707 7311 7312 1 6 4706 3978 3979 4708 5170 7312 1 6 4707 3979 3980 4709 5170 5171 1 6 4708 3980 3981 4710 5171 5172 1 6 4709 3981 3982 4711 5172 5173 1 6 4710 3982 3983 4712 5173 5174 1 6 4711 3983 3984 4713 5174 5175 1 6 4712 3984 3985 4714 5175 5176 1 6 4713 3985 3986 4715 5176 5177 1 6 4714 3986 3987 4716 4965 5177 1 6 4715 3987 3988 4717 4965 4966 1 6 4716 3988 3989 4718 4966 4967 1 6 4717 3989 3990 4719 4967 4968 1 6 4718 3990 3991 4720 4968 4969 1 6 4719 3991 3992 4721 4969 4970 1 6 4720 3992 3993 4439 4722 4970 1 6 4721 4439 4723 4970 4971 4972 1 6 4722 4439 4440 4724 4972 4973 1 6 4723 4440 4441 4725 4973 4974 1 6 4724 4441 4442 4726 4733 4974 1 6 4725 4442 4443 4727 4733 4734 1 6 4726 4443 4444 4728 4734 4735 1 6 4727 4444 4445 4658 4735 4736 2 6 4254 4255 4730 4731 4732 4261 2 6 4254 4729 4731 6892 6893 6894 2 6 4730 4729 4732 6894 6895 6896 2 6 4731 4729 4261 6896 6901 4262 1 6 4725 4726 4734 4974 4975 4976 1 6 4733 4726 4727 4735 4976 4977 1 6 4734 4727 4728 4736 4977 4978 1 6 4735 4728 4658 4659 4737 4978 1 6 4736 4659 4660 4738 4978 4979 1 6 4737 4660 4451 4979 4980 4669 1 6 4248 4391 4740 5003 7830 7831 1 6 4739 4391 4392 4402 4741 5003 1 6 4740 4402 4742 4753 5003 5004 1 6 4741 4402 4403 4743 4753 4748 1 6 4742 4403 4744 3892 3893 4748 1 6 4743 4403 4404 4745 4746 3892 1 6 4744 4404 3465 3466 3468 4746 1 6 4745 3468 4747 3397 3892 4744 1 6 4746 3468 2172 2173 3395 3397 1 6 4743 3893 4749 4750 4753 4742 1 6 4748 3893 4750 4751 4752 3894 1 6 4748 4749 4751 5005 4753 7837 1 6 4750 4749 4752 4757 7837 7838 1 6 4751 4749 3894 4757 4758 3895 1 6 4741 4742 4748 5004 5005 4750 2 7 4513 4067 4068 4755 4512 4759 4760 2 5 4754 4068 4756 4760 4761 2 7 4755 4068 4069 3827 4761 4762 4763 1 6 4751 4752 4758 7838 7839 7840 1 6 4757 4752 3895 7840 7841 4661 2 6 4512 4754 4760 5006 5002 5001 2 5 4759 4754 4755 4761 5006 2 7 4760 4755 4756 4762 5006 5007 5008 2 6 4761 4756 4763 5008 5009 5010 2 6 4762 4756 3827 3828 4764 5010 2 6 4763 3828 4765 5010 5011 5012 2 6 4764 3828 3829 3830 4766 5012 2 6 4765 3830 3831 4767 4768 5012 2 6 4766 3831 4768 4769 4770 3832 2 7 4766 4767 4769 5012 5011 5013 5014 2 6 4768 4767 4770 5014 5015 5016 2 6 4769 4767 3832 5016 3834 3833 1 6 4297 4298 4772 4932 4933 4934 1 6 4771 4298 4299 4773 4934 4935 1 6 4772 4299 4300 4774 4935 4936 1 6 4773 4300 4301 4775 4936 4937 1 6 4774 4301 4302 4776 4937 4938 1 6 4775 4302 4303 4777 4938 4939 1 6 4776 4303 4304 4778 4939 4940 1 6 4777 4304 4305 4779 4940 4941 1 6 4778 4305 4306 4780 4941 4942 1 6 4779 4306 4307 4781 4942 4943 1 6 4780 4307 4308 4782 4943 4944 1 6 4781 4308 4309 4566 4783 4944 1 6 4782 4566 4784 4944 4945 4946 1 6 4783 4566 4567 4785 4946 4947 1 6 4784 4567 4568 4786 4947 4948 1 6 4785 4568 4569 4787 4948 4949 1 6 4786 4569 4570 4788 4949 4950 1 6 4787 4570 4571 4789 4950 4951 1 6 4788 4571 4572 4790 4951 4952 1 6 4789 4572 4573 4791 4952 4953 1 6 4790 4573 4574 4792 4953 4954 1 6 4791 4574 4575 4793 4799 4954 1 6 4792 4575 4576 4794 4799 4800 1 6 4793 4576 4577 4578 4795 4800 1 6 4794 4578 4579 4796 4800 4801 1 6 4795 4579 4797 4801 4802 4803 1 6 4796 4579 4580 4581 4798 4803 1 6 4797 4581 4583 4803 4804 4584 1 6 4792 4793 4800 4954 4955 4956 1 6 4799 4793 4794 4795 4801 4956 1 6 4800 4795 4796 4802 4956 4957 1 6 4801 4796 4803 4957 4958 4959 1 6 4802 4796 4797 4798 4804 4959 1 6 4803 4798 4584 4586 4805 4959 1 6 4804 4586 4587 4806 4918 4959 1 6 4805 4587 4807 4918 4919 4920 1 6 4806 4587 4588 4808 4920 4921 1 6 4807 4588 4809 4921 4922 4810 1 6 4808 4588 4589 4590 4591 4810 1 7 4809 4591 4592 4593 4811 4922 4808 1 5 4810 4593 4594 4812 4922 1 6 4811 4594 4595 4813 4964 4922 1 6 4812 4595 4596 4814 5093 4964 1 6 4813 4596 4597 4815 5093 5094 1 6 4814 4597 4598 4816 5094 5095 1 6 4815 4598 4599 4817 5095 5096 1 6 4816 4599 4600 4818 4819 5096 1 6 4817 4600 4819 4820 4821 4601 1 6 4817 4818 4820 5096 5097 5098 1 6 4819 4818 4821 5098 5099 4823 1 6 4820 4818 4601 4602 4822 4823 1 6 4821 4602 4823 4824 4825 4603 1 6 4821 4822 4824 5099 4820 5100 1 6 4823 4822 4825 5100 5101 5102 1 6 4824 4822 4603 4826 5102 5103 1 6 4825 4603 4604 4605 4827 5103 1 7 4826 4605 4606 4607 4609 4828 5103 1 6 4827 4609 4829 5103 5102 5104 1 6 4828 4609 4830 5104 5105 5106 1 6 4829 4609 4610 4831 5106 5107 1 6 4830 4610 4832 4833 5113 5107 1 5 4831 4610 4611 4833 4834 1 6 4831 4832 4834 4835 5113 5114 1 7 4833 4832 4611 4835 4836 4837 4612 1 6 4833 4834 4836 5114 4845 4844 1 6 4835 4834 4837 4838 4839 4844 1 6 4836 4834 4612 4613 4617 4838 1 6 4836 4837 4839 4840 4622 4617 1 6 4836 4838 4840 4842 4843 4844 1 6 4839 4838 4622 4623 4841 4842 1 6 4840 4623 4842 4625 4852 4853 1 6 4840 4841 4839 4843 4852 4850 1 6 4839 4842 4844 4845 4846 4850 1 5 4839 4843 4845 4835 4836 1 7 4844 4843 4846 4847 5114 4835 5115 1 6 4845 4843 4847 4848 4849 4850 1 6 4845 4846 4848 5117 5115 5118 1 6 4847 4846 4849 5118 5119 5120 1 6 4848 4846 4850 4851 5120 5121 1 6 4849 4846 4851 4852 4842 4843 1 6 4849 4850 4852 4854 4855 5121 1 6 4851 4850 4842 4841 4853 4854 1 6 4852 4841 4854 4857 4860 4625 1 6 4851 4852 4853 4855 4856 4857 1 6 4851 4854 4856 5121 5122 5123 1 6 4855 4854 4857 4858 5123 5124 1 6 4856 4854 4853 4858 4859 4860 1 6 4856 4857 4859 5124 5125 5129 1 6 4858 4857 4860 5129 5130 4861 1 6 4859 4857 4853 4625 4626 4861 1 6 4860 4626 4862 5130 4859 5131 1 6 4861 4626 4627 4863 4865 5131 1 6 4862 4627 4630 4864 4865 4866 1 6 4863 4630 4866 4867 4868 4631 1 6 4862 4863 4866 5131 5132 5136 1 6 4865 4863 4864 4867 5136 5137 1 6 4866 4864 4868 4869 4870 5137 1 6 4867 4864 4631 4638 4869 9760 1 6 4867 4868 4870 4871 4872 9760 1 6 4867 4869 4871 5137 5138 5139 1 6 4870 4869 4872 4873 5150 5139 1 6 4871 4869 4873 4874 4875 9760 1 6 4871 4872 4874 5149 5147 5150 1 6 4873 4872 4875 4876 4877 5149 1 6 4874 4872 4876 9760 4912 4914 1 6 4874 4875 4877 4878 4879 4914 1 6 4874 4876 4878 5155 5149 4882 1 6 4877 4876 4879 4880 4881 4882 1 6 4878 4876 4880 4914 4915 9753 1 7 4878 4879 4881 9753 9754 9756 9757 1 6 4878 4880 4882 4883 4884 9757 1 6 4878 4881 4883 5155 4877 5369 1 6 4882 4881 4884 4885 5369 5370 1 6 4883 4881 4885 4886 9757 4895 1 6 4883 4884 4886 4887 4888 5370 1 6 4885 4884 4887 4894 4891 4895 1 6 4885 4886 4888 4889 4890 4891 1 6 4885 4887 4889 5372 5370 5899 1 6 4888 4887 4890 5898 5896 5899 1 6 4889 4887 4891 4892 5898 5901 1 6 4890 4887 4892 4893 4894 4886 1 6 4890 4891 4893 5901 5902 5903 1 6 4892 4891 4894 5912 5903 5913 1 6 4893 4891 4886 4895 4896 5913 1 7 4894 4886 4896 4897 9757 9756 4884 1 6 4894 4895 4897 4898 4899 5913 1 5 4896 4895 4898 9756 9759 1 6 4896 4897 4899 4900 4901 9759 1 6 4896 4898 4900 5913 5914 5917 1 6 4899 4898 4901 4902 5917 5918 1 6 4900 4898 4902 4903 4904 9759 1 6 4900 4901 4903 5918 3671 3670 1 6 4902 4901 4904 4905 3669 3670 1 6 4903 4901 4905 9754 4911 9759 1 6 4903 4904 3669 4906 4907 4911 1 6 3669 4905 4907 4908 3661 3660 1 6 4906 4905 4908 4909 4910 4911 1 7 4906 4907 4909 4642 3660 9793 9794 1 5 4908 4907 4910 4642 4641 1 6 4909 4907 4911 4917 4916 4641 1 6 4910 4907 4905 9754 4917 4904 1 6 4638 4639 4913 4914 9760 4875 1 6 4912 4639 4914 4915 4916 4640 1 6 4912 4913 4915 4875 4876 4879 1 6 4914 4913 4916 4917 9753 4879 1 6 4915 4913 4917 4910 4641 4640 1 6 4915 4916 4910 9753 9754 4911 1 6 4805 4806 4919 4959 4958 4960 1 6 4918 4806 4920 4960 4961 4962 1 6 4919 4806 4807 4921 4962 4963 1 6 4920 4807 4808 4922 4963 4964 1 6 4921 4808 4810 4964 4812 4811 1 6 4287 4288 4924 5052 5053 5054 1 6 4923 4288 4289 4290 4925 5054 1 6 4924 4290 4926 5054 5055 5056 1 6 4925 4290 4291 4927 5056 5057 1 6 4926 4291 4292 4928 5057 5058 1 6 4927 4292 4293 4929 5058 5059 1 6 4928 4293 4294 4930 5059 5060 1 6 4929 4294 4295 4931 5060 5061 1 6 4930 4295 4296 4297 4932 5061 1 6 4931 4297 4771 4933 5061 5062 1 6 4932 4771 4934 5062 5063 5064 1 6 4933 4771 4772 4935 5064 5065 1 6 4934 4772 4773 4936 5065 5066 1 6 4935 4773 4774 4937 5066 5067 1 6 4936 4774 4775 4938 5067 5068 1 6 4937 4775 4776 4939 5068 5069 1 6 4938 4776 4777 4940 5069 5070 1 6 4939 4777 4778 4941 5070 5071 1 6 4940 4778 4779 4942 5071 5072 1 6 4941 4779 4780 4943 5072 5073 1 6 4942 4780 4781 4944 5073 5074 1 6 4943 4781 4782 4783 4945 5074 1 6 4944 4783 4946 5074 5075 5076 1 6 4945 4783 4784 4947 5076 5077 1 6 4946 4784 4785 4948 5077 5078 1 6 4947 4785 4786 4949 5078 5079 1 6 4948 4786 4787 4950 5079 5080 1 6 4949 4787 4788 4951 5080 5081 1 6 4950 4788 4789 4952 5081 5082 1 6 4951 4789 4790 4953 5082 5083 1 6 4952 4790 4791 4954 5083 5084 1 6 4953 4791 4792 4799 4955 5084 1 6 4954 4799 4956 5084 5085 5086 1 6 4955 4799 4800 4801 4957 5086 1 6 4956 4801 4802 4958 5088 5086 1 6 4957 4802 4959 4918 4960 5088 1 6 4958 4802 4803 4804 4805 4918 1 6 4958 4918 4919 4961 5088 5089 1 6 4960 4919 4962 5089 5090 5091 1 6 4961 4919 4920 4963 5091 5092 1 6 4962 4920 4921 4964 5092 5093 1 6 4963 4921 4922 4812 5093 4813 1 6 4715 4716 4966 5177 5178 5179 1 6 4965 4716 4717 4967 5179 5180 1 6 4966 4717 4718 4968 5180 5181 1 6 4967 4718 4719 4969 5181 5182 1 6 4968 4719 4720 4970 5182 5183 1 6 4969 4720 4721 4722 4971 5183 1 6 4970 4722 4972 5183 5184 5185 1 6 4971 4722 4723 4973 5185 5186 1 6 4972 4723 4724 4974 5186 5187 1 6 4973 4724 4725 4733 4975 5187 1 6 4974 4733 4976 5187 5188 5189 1 6 4975 4733 4734 4977 5189 5190 1 6 4976 4734 4735 4978 5190 5191 1 6 4977 4735 4736 4737 4979 5191 1 6 4978 4737 4738 4980 5191 5192 1 6 4979 4738 4669 5192 5193 5194 1 6 4490 4491 4982 4989 4990 4991 1 6 4981 4491 4492 4983 4991 4992 1 6 4982 4492 4493 4984 4992 4993 1 6 4983 4493 4985 4993 4994 4995 2 6 4984 4493 4494 4497 4986 4995 2 6 4985 4497 4498 4987 4995 4996 2 6 4986 4498 4988 4996 4997 4998 2 6 4987 4498 4499 4511 4998 4999 1 6 4490 4981 4990 5216 5217 5218 1 6 4989 4981 4991 5218 5219 5220 1 6 4990 4981 4982 4992 5220 5221 1 6 4991 4982 4983 4993 5221 5222 1 6 4992 4983 4984 4994 5222 5223 1 6 4993 4984 4995 5223 5224 5225 2 6 4994 4984 4985 4986 4996 5225 2 6 4995 4986 4987 4997 5225 5226 2 6 4996 4987 4998 5226 5227 5228 2 6 4997 4987 4988 4999 5000 5228 2 6 4998 4988 5000 5001 5002 4511 2 6 4998 4999 5001 5228 5229 5230 2 7 5000 4999 5002 4759 5006 5166 5230 2 5 5001 4999 4511 4512 4759 1 6 4739 4740 4741 5004 7831 7834 1 6 5003 4741 4753 5005 7834 7835 1 6 5004 4753 4750 7835 7836 7837 2 7 4759 4760 4761 5007 5021 5001 5166 2 6 5006 4761 5008 5021 5022 5023 2 6 5007 4761 4762 5009 5023 5018 2 6 5008 4762 5010 5011 5017 5018 2 5 5009 4762 4763 4764 5011 2 7 5010 4764 5012 4768 5013 5009 5017 2 5 5011 4764 4765 4766 4768 2 6 5011 4768 5014 5020 5017 5241 2 6 5013 4768 4769 5015 5241 5242 2 6 5014 4769 5016 5242 5243 5024 2 5 5015 4769 4770 3834 5024 2 6 5009 5011 5018 5019 5020 5013 2 7 5009 5017 5019 5023 5008 5238 6833 2 6 5018 5017 5020 5238 5239 5240 2 5 5019 5017 5013 5240 5241 2 5 5006 5007 5022 5166 5167 2 6 5021 5007 5023 5167 5168 5169 2 6 5022 5007 5008 5018 5169 6833 2 7 5016 3834 3835 5025 5243 5015 5244 2 6 5024 3835 3836 5026 5244 5245 2 6 5025 3836 3837 4405 5027 5245 2 6 5026 4405 4406 5028 5245 5246 2 6 5027 4406 5029 5249 5246 6844 2 6 5028 4406 4407 5030 6844 6845 2 6 5029 4407 4408 5031 6845 6846 2 6 5030 4408 4409 5032 6849 6846 2 6 5031 4409 4420 5033 6849 6850 2 6 5032 4420 4421 4422 5034 6850 2 6 5033 4422 5035 6850 6851 6852 2 6 5034 4422 4423 5036 6852 5038 2 6 5035 4423 4424 4643 5037 5038 2 6 5036 4643 5038 5039 5040 5044 2 6 5036 5037 5039 6852 5035 6853 2 6 5038 5037 5040 5041 6856 6853 2 6 5039 5037 5041 5042 5043 5044 2 6 5039 5040 5042 6858 6856 6863 2 6 5041 5040 5043 6878 6879 6863 2 6 5042 5040 5044 5045 6880 6878 2 6 5043 5040 5045 4644 4643 5037 2 6 5043 5044 4644 6880 6881 6889 1 6 4280 4281 5047 5474 5475 5476 1 6 5046 4281 4282 5048 5476 5477 1 6 5047 4282 4283 5049 5477 5478 1 6 5048 4283 4284 5050 5478 5479 1 6 5049 4284 4285 5051 5479 5480 1 6 5050 4285 4286 5052 5480 5481 1 6 5051 4286 4287 4923 5053 5481 1 6 5052 4923 5054 5481 5482 5483 1 6 5053 4923 4924 4925 5055 5483 1 6 5054 4925 5056 5483 5484 5485 1 6 5055 4925 4926 5057 5485 5486 1 6 5056 4926 4927 5058 5486 5487 1 6 5057 4927 4928 5059 5487 5488 1 6 5058 4928 4929 5060 5488 5489 1 6 5059 4929 4930 5061 5489 5490 1 6 5060 4930 4931 4932 5062 5490 1 6 5061 4932 4933 5063 5490 5491 1 6 5062 4933 5064 5250 5491 5492 1 6 5063 4933 4934 5065 5250 5251 1 6 5064 4934 4935 5066 5251 5252 1 6 5065 4935 4936 5067 5252 5253 1 6 5066 4936 4937 5068 5253 5254 1 6 5067 4937 4938 5069 5254 5255 1 6 5068 4938 4939 5070 5255 5256 1 6 5069 4939 4940 5071 5256 5257 1 6 5070 4940 4941 5072 5257 5258 1 6 5071 4941 4942 5073 5258 5259 1 6 5072 4942 4943 5074 5259 5260 1 6 5073 4943 4944 4945 5075 5260 1 6 5074 4945 5076 5260 5261 5262 1 6 5075 4945 4946 5077 5262 5263 1 6 5076 4946 4947 5078 5263 5264 1 6 5077 4947 4948 5079 5264 5265 1 6 5078 4948 4949 5080 5265 5266 1 6 5079 4949 4950 5081 5266 5267 1 6 5080 4950 4951 5082 5267 5268 1 6 5081 4951 4952 5083 5268 5269 1 6 5082 4952 4953 5084 5269 5270 1 6 5083 4953 4954 4955 5085 5270 1 6 5084 4955 5086 5087 5270 5271 1 6 5085 4955 4956 5087 5088 4957 1 6 5085 5086 5088 5271 5272 5089 1 6 5087 5086 4957 4958 4960 5089 1 6 5088 4960 4961 5090 5272 5087 1 6 5089 4961 5091 5272 5273 5274 1 6 5090 4961 4962 5092 5274 5275 1 6 5091 4962 4963 5093 5275 5276 1 7 5092 4963 4964 4813 4814 5094 5276 1 6 5093 4814 4815 5095 5276 5277 1 6 5094 4815 4816 5096 5277 5278 1 6 5095 4816 4817 4819 5097 5278 1 6 5096 4819 5098 5278 5279 5280 1 6 5097 4819 4820 5099 5280 5281 1 6 5098 4820 4823 5100 5281 5282 1 6 5099 4823 4824 5101 5282 5152 1 6 5100 4824 5102 5104 5151 5152 1 6 5101 4824 4825 5103 4828 5104 1 5 5102 4825 4826 4827 4828 1 6 5102 4828 4829 5105 5101 5151 1 7 5104 4829 5106 5154 5151 5287 5288 1 6 5105 4829 4830 5107 5108 5288 1 6 5106 4830 5108 5109 5113 4831 1 6 5106 5107 5109 5110 5288 5289 1 6 5108 5107 5110 5111 5112 5113 1 6 5108 5109 5111 5289 5290 5294 1 6 5110 5109 5112 5294 5295 5116 1 6 5111 5109 5113 5114 5115 5116 1 6 5112 5109 5107 4831 4833 5114 1 6 5113 4833 4835 4845 5115 5112 1 6 5114 4845 5112 5116 5117 4847 1 6 5112 5115 5117 5295 5111 5296 1 6 5116 5115 4847 5118 5299 5296 1 6 5117 4847 4848 5119 5299 5300 1 6 5118 4848 5120 5300 5301 5302 1 5 5119 4848 4849 5121 5302 1 6 5120 4849 4851 4855 5122 5302 1 6 5121 4855 5123 5318 5302 5319 1 6 5122 4855 4856 5124 5321 5319 1 6 5123 4856 4858 5125 5126 5321 1 6 5124 4858 5126 5127 5128 5129 1 6 5124 5125 5127 5322 5321 5323 1 6 5126 5125 5128 5323 5324 5328 1 6 5127 5125 5129 5336 5328 5337 1 6 5128 5125 4858 4859 5130 5337 1 6 5129 4859 4861 5131 5337 5338 1 7 5130 4861 4862 4865 5132 5133 5338 1 6 5131 4865 5133 5134 5135 5136 1 5 5131 5132 5134 5338 5339 1 6 5133 5132 5135 5339 5340 5341 1 6 5134 5132 5136 5346 5344 5341 1 6 5135 5132 4865 4866 5137 5346 1 6 5136 4866 4867 4870 5138 5346 1 6 5137 4870 5139 5140 5344 5346 1 6 5138 4870 5140 5141 4871 5150 1 6 5138 5139 5141 5142 5345 5344 1 6 5140 5139 5142 5143 5144 5150 1 6 5140 5141 5143 5345 5360 5359 1 7 5142 5141 5144 5145 5360 5357 5361 1 6 5143 5141 5145 5146 5147 5150 1 6 5143 5144 5146 5361 5362 5366 1 5 5145 5144 5147 5148 5366 1 6 5146 5144 5148 5149 4873 5150 1 7 5146 5147 5149 5155 5366 5367 5368 1 6 5148 5147 4873 5155 4877 4874 1 6 4873 5147 4871 5139 5141 5144 1 6 5101 5104 5152 5153 5154 5105 1 6 5101 5151 5153 5282 5100 5283 1 6 5152 5151 5154 5283 5284 5285 1 6 5153 5151 5105 5285 5286 5287 1 6 5148 5149 4877 4882 5368 5369 1 7 4532 4533 5157 6682 6683 6684 6694 1 6 5156 4533 4666 6682 9750 4667 1 5 4691 4692 4693 5159 7844 1 7 5158 4693 5160 7844 7845 7846 7847 1 6 5159 4693 4694 5161 7847 7848 1 6 5160 4694 4695 5162 7848 7849 1 6 5161 4695 5163 7849 7850 7851 1 6 5162 4695 4696 4697 5164 7851 1 6 5163 4697 5165 7851 7852 7853 1 6 5164 4697 4698 4700 7853 7854 2 5 5001 5006 5021 5167 5230 2 8 5166 5021 5022 5168 5229 5230 6826 6824 2 6 5167 5022 5169 6826 6827 6830 2 7 5168 5022 5023 6830 6831 6832 6833 1 6 4707 4708 5171 7312 7313 7314 1 6 5170 4708 4709 5172 7314 7315 1 6 5171 4709 4710 5173 7315 7316 1 6 5172 4710 4711 5174 7316 7317 1 6 5173 4711 4712 5175 7317 7318 1 6 5174 4712 4713 5176 7318 7319 1 6 5175 4713 4714 5177 7319 7320 1 6 5176 4714 4715 4965 5178 7320 1 6 5177 4965 5179 7320 7321 7322 1 6 5178 4965 4966 5180 7322 7323 1 6 5179 4966 4967 5181 5411 7323 1 6 5180 4967 4968 5182 5411 5412 1 6 5181 4968 4969 5183 5412 5413 1 6 5182 4969 4970 4971 5184 5413 1 6 5183 4971 5185 5413 5414 5415 1 6 5184 4971 4972 5186 5403 5415 1 6 5185 4972 4973 5187 5403 5404 1 6 5186 4973 4974 4975 5188 5404 1 6 5187 4975 5189 5404 5405 5406 1 6 5188 4975 4976 5190 5406 5407 1 6 5189 4976 4977 5191 5407 5408 1 6 5190 4977 4978 4979 5192 5408 1 6 5191 4979 4980 5193 5408 5409 1 6 5192 4980 5194 5409 5410 5195 1 5 5193 4980 4669 4670 5195 1 6 5194 4670 4671 5196 5410 5193 1 7 5195 4671 4672 5197 5423 5410 5431 1 5 5196 4672 4673 5198 5431 1 7 5197 4673 4674 5199 5431 5432 5433 1 6 5198 4674 4675 5200 5433 5434 1 6 5199 4675 4676 5201 5434 5435 1 6 5200 4676 4677 5202 5435 5436 1 6 5201 4677 4678 5203 5436 5437 1 6 5202 4678 5204 5437 5438 5439 1 6 5203 4678 4679 4680 5205 5439 1 5 5204 4680 4681 5206 5439 1 7 5205 4681 4682 5207 5439 5440 5441 1 6 5206 4682 5208 5441 5442 5443 1 6 5207 4682 4683 5209 5424 5443 1 7 5208 4683 4684 5210 5424 5425 5426 1 5 5209 4684 5211 5426 5427 1 7 5210 4684 4685 5212 5427 5215 5214 1 5 5211 4685 4686 5213 5214 1 6 5212 4686 4687 4478 4479 5214 1 6 5213 4479 4480 5215 5211 5212 1 6 5214 4480 5216 5427 5211 5217 1 6 5215 4480 4481 4490 4989 5217 1 7 5216 4989 5218 5447 5427 5215 6810 1 6 5217 4989 4990 5219 6810 6811 1 6 5218 4990 5220 6811 6812 6813 1 6 5219 4990 4991 5221 6813 6814 1 5 5220 4991 4992 5222 6814 1 7 5221 4992 4993 5223 6814 6815 6816 1 5 5222 4993 4994 5224 6816 1 7 5223 4994 5225 6816 6817 6818 6819 2 6 5224 4994 4995 4996 5226 6819 2 6 5225 4996 4997 5227 6819 6820 2 6 5226 4997 5228 6820 6821 6822 2 6 5227 4997 4998 5000 5229 6822 2 7 5228 5000 5230 5167 6822 6823 6824 2 5 5229 5000 5167 5166 5001 1 6 4264 4265 5232 6902 6903 5458 1 6 5231 4265 4266 5233 5448 5458 1 6 5232 4266 4267 5234 5448 5449 1 6 5233 4267 4269 5449 5450 5451 1 6 4519 4520 5236 9677 9678 9679 1 6 5235 4520 5237 9679 9683 9684 1 6 5236 4520 4521 422 9684 421 2 6 5018 5019 5239 6832 6833 6834 2 6 5238 5019 5240 5648 6834 6835 2 6 5239 5019 5020 5241 5648 5649 2 7 5240 5020 5013 5014 5242 5649 5650 2 5 5241 5014 5015 5243 5650 2 7 5242 5015 5024 5244 5652 5650 5653 2 6 5243 5024 5025 5245 5653 5247 2 6 5244 5025 5026 5027 5246 5247 2 6 5245 5027 5247 5248 5249 5028 2 6 5245 5246 5248 5653 5244 6840 2 6 5247 5246 5249 6841 6840 6842 2 6 5248 5246 5028 6842 6843 6844 1 6 5063 5064 5251 5492 5493 5494 1 6 5250 5064 5065 5252 5494 5495 1 6 5251 5065 5066 5253 5495 5496 1 6 5252 5066 5067 5254 5496 5497 1 6 5253 5067 5068 5255 5497 5498 1 6 5254 5068 5069 5256 5498 5499 1 6 5255 5069 5070 5257 5499 5500 1 6 5256 5070 5071 5258 5500 5501 1 6 5257 5071 5072 5259 5501 5502 1 6 5258 5072 5073 5260 5502 5503 1 6 5259 5073 5074 5075 5261 5503 1 6 5260 5075 5262 5503 5504 5505 1 6 5261 5075 5076 5263 5505 5506 1 6 5262 5076 5077 5264 5506 5507 1 6 5263 5077 5078 5265 5507 5508 1 6 5264 5078 5079 5266 5508 5509 1 6 5265 5079 5080 5267 5509 5510 1 6 5266 5080 5081 5268 5510 5511 1 6 5267 5081 5082 5269 5511 5512 1 6 5268 5082 5083 5270 5512 5513 1 6 5269 5083 5084 5085 5271 5513 1 6 5270 5085 5087 5272 5513 5514 1 6 5271 5087 5089 5090 5273 5514 1 6 5272 5090 5274 5514 5515 5516 1 6 5273 5090 5091 5275 5519 5516 1 6 5274 5091 5092 5276 5519 5277 1 5 5275 5092 5093 5094 5277 1 6 5276 5094 5095 5278 5519 5275 1 6 5277 5095 5096 5097 5279 5519 1 6 5278 5097 5280 5519 5518 5520 1 6 5279 5097 5098 5281 5520 5377 1 6 5280 5098 5099 5282 5376 5377 1 6 5281 5099 5100 5152 5283 5376 1 6 5282 5152 5153 5284 5379 5376 1 6 5283 5153 5285 5524 5379 5525 1 6 5284 5153 5154 5286 5525 5526 1 6 5285 5154 5287 5526 5527 5291 1 6 5286 5154 5105 5288 5291 5289 1 5 5287 5105 5106 5108 5289 1 6 5288 5108 5110 5290 5291 5287 1 6 5289 5110 5291 5292 5293 5294 1 7 5289 5290 5292 5527 5286 5287 5528 1 6 5291 5290 5293 5528 5529 5533 1 5 5292 5290 5294 5533 5534 1 6 5293 5290 5110 5111 5295 5534 1 6 5294 5111 5116 5296 5297 5534 1 6 5295 5116 5297 5298 5299 5117 1 6 5295 5296 5298 5534 5535 5542 1 6 5297 5296 5299 5542 5543 5544 1 6 5298 5296 5117 5118 5300 5544 1 6 5299 5118 5119 5301 5304 5544 1 6 5300 5119 5302 5303 5304 5305 1 7 5301 5119 5303 5318 5122 5120 5121 1 6 5301 5302 5308 5305 5309 5318 1 6 5300 5301 5305 5306 5543 5544 1 6 5304 5301 5306 5307 5308 5303 1 6 5304 5305 5307 5543 5545 5546 1 6 5306 5305 5308 5311 5312 5546 1 6 5307 5305 5303 5309 5310 5311 1 6 5308 5303 5310 5316 5317 5318 1 6 5308 5309 5311 5314 5315 5316 1 6 5308 5310 5307 5312 5313 5314 1 6 5307 5311 5313 5546 5547 5548 1 6 5312 5311 5314 5548 5549 5550 1 6 5313 5311 5310 5315 5553 5550 1 6 5314 5310 5316 5555 5553 5558 1 6 5315 5310 5309 5317 5558 5559 1 6 5316 5309 5318 5319 5320 5559 1 6 5317 5309 5303 5302 5122 5319 1 6 5318 5122 5317 5320 5321 5123 1 6 5317 5319 5321 5322 5559 5560 1 6 5320 5319 5322 5126 5124 5123 1 6 5320 5321 5126 5323 5560 5561 1 6 5322 5126 5127 5324 5325 5561 1 6 5323 5127 5325 5326 5327 5328 1 6 5323 5324 5326 5561 5562 5563 1 6 5325 5324 5327 5572 5563 5573 1 6 5326 5324 5328 5329 5330 5573 1 6 5327 5324 5329 5336 5128 5127 1 6 5327 5328 5330 5331 5332 5336 1 6 5327 5329 5331 5573 5574 5575 1 6 5330 5329 5332 5333 5575 5576 1 6 5331 5329 5333 5334 5335 5336 1 6 5331 5332 5334 5576 5577 5578 1 6 5333 5332 5335 5578 5340 5339 1 6 5334 5332 5336 5337 5338 5339 1 6 5335 5332 5329 5328 5128 5337 1 6 5336 5128 5129 5130 5335 5338 1 6 5335 5337 5130 5131 5133 5339 1 6 5338 5133 5134 5340 5334 5335 1 6 5339 5134 5341 5342 5578 5334 1 6 5340 5134 5342 5343 5344 5135 1 6 5340 5341 5343 5348 5349 5578 1 6 5342 5341 5344 5345 5347 5348 1 7 5343 5341 5345 5140 5138 5346 5135 1 6 5343 5344 5140 5142 5347 5359 1 5 5138 5344 5135 5136 5137 1 6 5343 5345 5348 5351 5352 5359 1 6 5343 5347 5342 5349 5350 5351 1 6 5342 5348 5350 5578 5577 5579 1 6 5349 5348 5351 5579 5580 5584 1 6 5350 5348 5347 5352 5353 5584 1 6 5351 5347 5353 5354 5355 5359 1 6 5351 5352 5354 5608 5584 5609 1 6 5353 5352 5355 5356 5807 5609 1 6 5354 5352 5356 5357 5359 5360 1 6 5354 5355 5357 5358 5807 5808 1 6 5356 5355 5358 5360 5143 5361 1 7 5356 5357 5808 5809 5810 5363 5361 1 6 5355 5352 5347 5360 5142 5345 1 5 5355 5359 5142 5143 5357 1 6 5357 5143 5145 5362 5363 5358 1 6 5361 5145 5363 5364 5365 5366 1 5 5361 5362 5364 5810 5358 1 6 5363 5362 5365 5810 5811 5402 1 7 5364 5362 5366 5402 5401 5367 5375 1 6 5365 5362 5145 5146 5148 5367 1 6 5366 5148 5368 5374 5365 5375 1 6 5367 5148 5155 5369 5371 5374 1 6 5368 5155 4882 4883 5370 5371 1 6 5369 4883 5371 5372 4888 4885 1 6 5369 5370 5372 5373 5374 5368 1 6 5371 5370 5373 4888 5393 5899 1 6 5371 5372 5374 5375 5392 5393 1 5 5371 5373 5375 5368 5367 1 6 5374 5373 5392 5365 5367 5401 1 6 5281 5282 5377 5378 5379 5283 1 6 5281 5376 5378 5520 5280 5521 1 6 5377 5376 5379 5521 5522 5523 1 6 5378 5376 5283 5523 5524 5284 1 6 4656 4657 55 9689 430 56 2 6 1679 1680 1678 5382 5383 1682 2 6 1678 5381 5383 5384 7779 3415 2 6 5382 5381 5384 5385 3774 1682 2 6 5382 5383 5385 5386 7779 7780 2 6 5384 5383 5386 5387 5391 3774 2 6 5384 5385 5387 5388 7780 7781 2 6 5386 5385 5388 5389 5390 5391 2 6 5386 5387 5389 5616 7781 7782 2 6 5388 5387 5390 5616 5617 5618 2 6 5389 5387 5391 5618 5619 5620 2 6 5390 5387 5385 3774 5620 3775 1 6 5375 5373 5393 5394 5401 5398 1 6 5392 5373 5394 5372 5395 5899 1 6 5392 5393 5395 5396 5397 5398 1 5 5394 5393 5396 5899 5894 1 6 5394 5395 5397 5893 5890 5894 1 6 5394 5396 5398 5399 5889 5890 1 6 5394 5397 5399 5400 5401 5392 1 6 5398 5397 5400 5880 5888 5889 1 7 5398 5399 5401 5402 5887 5881 5880 1 6 5398 5400 5402 5365 5375 5392 1 6 5401 5400 5887 5811 5364 5365 1 6 5185 5186 5404 5415 5416 5417 1 6 5403 5186 5187 5188 5405 5417 1 6 5404 5188 5406 5417 5418 5419 1 6 5405 5188 5189 5407 5419 5420 1 6 5406 5189 5190 5408 5420 5421 1 6 5407 5190 5191 5192 5409 5421 1 6 5408 5192 5193 5410 5421 5422 1 6 5409 5193 5195 5422 5423 5196 1 6 5180 5181 5412 7323 7324 7325 1 6 5411 5181 5182 5413 7325 7326 1 6 5412 5182 5183 5184 5414 7326 1 6 5413 5184 5415 7326 7327 7328 1 6 5414 5184 5185 5403 5416 7328 1 6 5415 5403 5417 7328 7329 7330 1 6 5416 5403 5404 5405 5418 7330 1 6 5417 5405 5419 6791 7330 7331 1 6 5418 5405 5406 5420 6791 6792 1 6 5419 5406 5407 5421 5428 6792 1 6 5420 5407 5408 5409 5422 5428 1 6 5421 5409 5410 5423 5428 5429 1 6 5422 5410 5196 5429 5430 5431 1 6 5208 5209 5425 5443 5444 5445 1 6 5424 5209 5426 5445 5446 5447 1 5 5425 5209 5210 5427 5447 1 6 5426 5210 5211 5215 5447 5217 1 6 5420 5421 5422 5429 6792 6793 1 6 5428 5422 5423 5430 6793 6794 1 6 5429 5423 5431 6794 6795 5432 1 6 5430 5423 5196 5197 5198 5432 1 5 5431 5198 5433 6795 5430 1 6 5432 5198 5199 5434 6795 6796 1 6 5433 5199 5200 5435 6796 6797 1 6 5434 5200 5201 5436 6797 6798 1 6 5435 5201 5202 5437 6798 6799 1 6 5436 5202 5203 5438 6799 6800 1 6 5437 5203 5439 6800 6801 6802 1 7 5438 5203 5204 5205 5206 5440 6802 1 5 5439 5206 5441 6802 6803 1 6 5440 5206 5207 5442 6803 6804 1 6 5441 5207 5443 6804 6805 5444 1 5 5442 5207 5208 5424 5444 1 6 5443 5424 5445 6805 5442 6806 1 6 5444 5424 5425 5446 6806 6807 1 6 5445 5425 5447 6807 6808 6809 1 7 5446 5425 5426 5427 5217 6809 6810 1 6 5232 5233 5449 5458 5459 5460 1 6 5448 5233 5234 5450 5460 5461 1 6 5449 5234 5451 5461 5462 5463 1 6 5450 5234 4269 4270 5452 5463 1 6 5451 4270 4271 5453 5463 5464 1 6 5452 4271 4272 5454 5455 5464 1 6 5453 4272 5455 5456 5457 4273 1 6 5453 5454 5456 5464 5465 5466 1 6 5455 5454 5457 5466 5467 5468 1 6 5456 5454 4273 5468 5469 4274 1 6 5232 5448 5459 6903 5231 6904 1 6 5458 5448 5460 6904 6905 6906 1 6 5459 5448 5449 5461 6906 6907 1 6 5460 5449 5450 5462 6907 6908 1 6 5461 5450 5463 6908 6909 6910 1 6 5462 5450 5451 5452 5464 6910 1 6 5463 5452 5453 5455 5465 6910 1 6 5464 5455 5466 6910 6911 6912 1 6 5465 5455 5456 5467 6912 6913 1 6 5466 5456 5468 6913 6914 6915 1 6 5467 5456 5457 5469 6915 6916 1 6 5468 5457 4274 4275 5470 6916 1 6 5469 4275 4276 4277 5471 6916 1 6 5470 4277 5472 6916 6917 6918 1 6 5471 4277 4278 5473 6918 6919 1 6 5472 4278 4279 5474 6919 6920 1 6 5473 4279 4280 5046 5475 6920 1 6 5474 5046 5476 6920 6921 6922 1 6 5475 5046 5047 5477 6922 6923 1 6 5476 5047 5048 5478 6923 6924 1 6 5477 5048 5049 5479 6924 6925 1 6 5478 5049 5050 5480 6925 6926 1 6 5479 5050 5051 5481 5654 6926 1 6 5480 5051 5052 5053 5482 5654 1 6 5481 5053 5483 5654 5655 5656 1 6 5482 5053 5054 5055 5484 5656 1 6 5483 5055 5485 5656 5657 5658 1 6 5484 5055 5056 5486 5658 5659 1 6 5485 5056 5057 5487 5659 5660 1 6 5486 5057 5058 5488 5660 5661 1 6 5487 5058 5059 5489 5621 5661 1 6 5488 5059 5060 5490 5621 5622 1 6 5489 5060 5061 5062 5491 5622 1 6 5490 5062 5063 5492 5622 5623 1 6 5491 5063 5250 5493 5623 5624 1 6 5492 5250 5494 5624 5625 5626 1 6 5493 5250 5251 5495 5626 5627 1 6 5494 5251 5252 5496 5627 5628 1 6 5495 5252 5253 5497 5628 5629 1 6 5496 5253 5254 5498 5629 5630 1 6 5497 5254 5255 5499 5630 5631 1 6 5498 5255 5256 5500 5631 5632 1 6 5499 5256 5257 5501 5632 5633 1 6 5500 5257 5258 5502 5633 5634 1 6 5501 5258 5259 5503 5634 5635 1 6 5502 5259 5260 5261 5504 5635 1 6 5503 5261 5505 5635 5636 5637 1 6 5504 5261 5262 5506 5637 5638 1 6 5505 5262 5263 5507 5638 5639 1 6 5506 5263 5264 5508 5639 5640 1 6 5507 5264 5265 5509 5640 5641 1 6 5508 5265 5266 5510 5641 5642 1 6 5509 5266 5267 5511 5642 5643 1 6 5510 5267 5268 5512 5643 5644 1 6 5511 5268 5269 5513 5644 5645 1 6 5512 5269 5270 5271 5514 5645 1 6 5513 5271 5272 5273 5515 5645 1 6 5514 5273 5516 5517 5645 5646 1 6 5515 5273 5517 5518 5519 5274 1 6 5515 5516 5518 5646 5647 5520 1 5 5517 5516 5519 5279 5520 1 7 5518 5516 5274 5275 5277 5278 5279 1 7 5518 5279 5280 5377 5521 5647 5517 1 5 5520 5377 5378 5522 5647 1 7 5521 5378 5523 5685 5647 5684 5686 1 6 5522 5378 5379 5524 5687 5686 1 6 5523 5379 5284 5525 5687 5688 1 6 5524 5284 5285 5526 5688 5689 1 6 5525 5285 5286 5527 5689 5690 1 6 5526 5286 5291 5528 5690 5691 1 6 5527 5291 5292 5529 5530 5691 1 6 5528 5292 5530 5531 5532 5533 1 5 5528 5529 5531 5691 5692 1 6 5530 5529 5532 5692 5693 5694 1 7 5531 5529 5533 5694 5695 5538 5536 1 6 5532 5529 5292 5293 5534 5536 1 7 5533 5293 5294 5295 5297 5535 5536 1 6 5534 5297 5536 5537 5541 5542 1 6 5534 5535 5537 5538 5532 5533 1 6 5536 5535 5538 5539 5540 5541 1 6 5536 5537 5539 5695 5532 5696 1 6 5538 5537 5540 5696 5697 5698 1 7 5539 5537 5541 5698 5699 5700 9795 1 5 5540 5537 5535 5542 9795 1 6 5541 5535 5297 5298 5543 9795 1 7 5542 5298 5544 5304 5306 5545 9795 1 5 5543 5298 5304 5300 5299 1 6 5543 5306 5546 5701 5700 9795 1 6 5545 5306 5307 5312 5547 5701 1 6 5546 5312 5548 5701 5702 5703 1 6 5547 5312 5313 5549 5703 5704 1 6 5548 5313 5550 5551 5704 5705 1 6 5549 5313 5551 5552 5553 5314 1 6 5549 5550 5552 5705 5706 5707 1 6 5551 5550 5553 5554 5707 5708 1 6 5552 5550 5314 5554 5555 5315 1 6 5552 5553 5555 5556 5708 5709 1 6 5554 5553 5315 5556 5557 5558 1 6 5554 5555 5557 5709 5710 5711 1 6 5556 5555 5558 5714 5711 5715 1 6 5557 5555 5315 5316 5559 5715 1 6 5558 5316 5317 5320 5560 5715 1 6 5559 5320 5322 5561 5716 5715 1 6 5560 5322 5323 5325 5562 5716 1 6 5561 5325 5563 5564 5717 5716 1 6 5562 5325 5564 5565 5572 5326 1 6 5562 5563 5565 5566 5717 5713 1 6 5564 5563 5566 5567 5571 5572 1 6 5564 5565 5567 5568 5753 5713 1 6 5566 5565 5568 5569 5570 5571 1 6 5566 5567 5569 5752 5753 5754 1 6 5568 5567 5570 5754 5755 5770 1 6 5569 5567 5571 5769 5767 5770 1 6 5570 5567 5565 5572 5769 5771 1 6 5571 5565 5563 5326 5573 5771 1 6 5572 5326 5327 5330 5574 5771 1 6 5573 5330 5575 5771 5772 5773 1 6 5574 5330 5331 5576 5773 5594 1 7 5575 5331 5333 5577 5594 5589 5774 1 6 5576 5333 5578 5349 5579 5774 1 6 5577 5333 5334 5340 5342 5349 1 6 5577 5349 5350 5580 5581 5774 1 6 5579 5350 5581 5582 5583 5584 1 6 5579 5580 5582 5585 5586 5774 1 6 5581 5580 5583 5585 5605 5606 1 6 5582 5580 5584 5606 5607 5608 1 6 5583 5580 5350 5351 5608 5353 1 6 5581 5582 5586 5587 5605 5597 1 6 5581 5585 5587 5588 5589 5774 1 6 5586 5585 5588 5595 5596 5597 1 6 5586 5587 5589 5590 5591 5595 1 6 5586 5588 5590 5594 5576 5774 1 6 5589 5588 5591 5592 5594 5773 1 6 5590 5588 5592 5593 5595 5778 1 6 5590 5591 5593 5773 5772 5775 1 6 5592 5591 5775 5776 5777 5778 1 5 5589 5590 5773 5575 5576 1 6 5591 5588 5587 5596 5778 5779 1 6 5595 5587 5597 5598 5599 5779 1 6 5596 5587 5598 5602 5605 5585 1 6 5596 5597 5599 5600 5601 5602 1 6 5596 5598 5600 5779 5780 5781 1 6 5599 5598 5601 5781 5789 5790 1 6 5600 5598 5602 5603 5790 5791 1 6 5601 5598 5603 5604 5597 5605 1 6 5601 5602 5604 5794 5791 5795 1 6 5603 5602 5795 5796 5606 5605 1 6 5602 5597 5585 5582 5606 5604 1 6 5605 5582 5583 5607 5796 5604 1 6 5606 5583 5608 5610 5798 5796 1 6 5607 5583 5584 5353 5609 5610 1 7 5608 5353 5610 5800 5806 5807 5354 1 5 5608 5609 5607 5800 5798 1 6 4514 4516 5612 5613 5614 5615 1 6 4514 5611 5613 427 426 7500 1 6 5612 5611 5614 7500 7501 7505 1 6 5613 5611 5615 7505 7506 7507 1 6 5614 5611 4516 7507 7508 4518 2 6 5388 5389 5617 7782 7783 7784 2 6 5616 5389 5618 7784 7785 7786 2 6 5617 5389 5390 5619 7786 7789 2 6 5618 5390 5620 7789 7790 7791 2 6 5619 5390 5391 3775 3778 7791 1 6 5488 5489 5622 5661 5662 5663 1 6 5621 5489 5490 5491 5623 5663 1 6 5622 5491 5492 5624 5663 5664 1 6 5623 5492 5493 5625 5664 5665 1 6 5624 5493 5626 5665 5666 5667 1 6 5625 5493 5494 5627 5667 5668 1 6 5626 5494 5495 5628 5668 5669 1 6 5627 5495 5496 5629 5669 5670 1 6 5628 5496 5497 5630 5670 5671 1 6 5629 5497 5498 5631 5671 5672 1 6 5630 5498 5499 5632 5672 5673 1 6 5631 5499 5500 5633 5673 5674 1 6 5632 5500 5501 5634 5674 5675 1 6 5633 5501 5502 5635 5675 5676 1 6 5634 5502 5503 5504 5636 5676 1 6 5635 5504 5637 5676 5677 5678 1 6 5636 5504 5505 5638 5678 5679 1 6 5637 5505 5506 5639 5679 5680 1 6 5638 5506 5507 5640 5680 5681 1 6 5639 5507 5508 5641 5681 5682 1 6 5640 5508 5509 5642 5682 5683 1 6 5641 5509 5510 5643 5683 5684 1 6 5642 5510 5511 5644 5684 5685 1 6 5643 5511 5512 5645 5685 5646 1 6 5644 5512 5513 5514 5515 5646 1 6 5645 5515 5517 5647 5685 5644 1 6 5646 5517 5520 5685 5522 5521 2 6 5239 5240 5649 6835 6836 6837 2 6 5648 5240 5241 5650 5651 6837 2 6 5649 5241 5651 5652 5243 5242 2 6 5649 5650 5652 6837 6838 6839 2 6 5651 5650 5243 5653 6839 6840 2 5 5652 5243 5244 5247 6840 1 6 5480 5481 5482 5655 6926 6927 1 6 5654 5482 5656 6927 6928 6929 1 6 5655 5482 5483 5484 5657 6929 1 6 5656 5484 5658 6929 6930 6931 1 6 5657 5484 5485 5659 5831 6931 1 6 5658 5485 5486 5660 5831 5832 1 6 5659 5486 5487 5661 5832 5833 1 6 5660 5487 5488 5621 5662 5833 1 6 5661 5621 5663 5833 5834 5835 1 6 5662 5621 5622 5623 5664 5835 1 6 5663 5623 5624 5665 5835 5813 1 6 5664 5624 5625 5666 5812 5813 1 6 5665 5625 5667 5812 5816 5817 1 6 5666 5625 5626 5668 5859 5817 1 6 5667 5626 5627 5669 5859 5860 1 6 5668 5627 5628 5670 5860 5861 1 6 5669 5628 5629 5671 5861 5862 1 6 5670 5629 5630 5672 5862 5863 1 6 5671 5630 5631 5673 5863 5864 1 6 5672 5631 5632 5674 5864 5865 1 6 5673 5632 5633 5675 5865 5866 1 6 5674 5633 5634 5676 5866 5867 1 6 5675 5634 5635 5636 5677 5867 1 6 5676 5636 5678 5867 5868 5693 1 6 5677 5636 5637 5679 5693 5869 1 6 5678 5637 5638 5680 5869 5870 1 6 5679 5638 5639 5681 5870 5871 1 6 5680 5639 5640 5682 5871 5688 1 6 5681 5640 5641 5683 5688 5687 1 6 5682 5641 5642 5684 5686 5687 1 6 5683 5642 5643 5685 5522 5686 1 6 5684 5643 5644 5646 5647 5522 1 5 5684 5522 5683 5687 5523 1 6 5683 5686 5523 5524 5688 5682 1 7 5687 5524 5525 5689 5871 5681 5682 1 5 5688 5525 5526 5690 5871 1 7 5689 5526 5527 5691 5871 5870 5692 1 5 5690 5527 5528 5530 5692 1 7 5691 5530 5531 5693 5870 5690 5869 1 7 5692 5531 5694 5868 5677 5678 5869 1 6 5693 5531 5532 5695 9698 5868 1 6 5694 5532 5538 5696 9699 9698 1 6 5695 5538 5539 5697 5718 9699 1 6 5696 5539 5698 5718 5719 5720 1 6 5697 5539 5540 5699 5720 5721 1 6 5698 5540 5700 5701 5721 5722 1 5 5699 5540 5701 5545 9795 1 7 5699 5700 5545 5546 5547 5702 5722 1 6 5701 5547 5703 5722 5723 5727 1 6 5702 5547 5548 5704 5727 5728 1 6 5703 5548 5549 5705 5728 5729 1 6 5704 5549 5551 5706 5732 5729 1 6 5705 5551 5707 5732 5733 5734 1 6 5706 5551 5552 5708 5737 5734 1 6 5707 5552 5554 5709 5737 5738 1 6 5708 5554 5556 5710 5747 5738 1 6 5709 5556 5711 5712 5747 5748 1 6 5710 5556 5712 5713 5714 5557 1 6 5710 5711 5713 5748 5749 5753 1 7 5712 5711 5714 5717 5564 5753 5566 1 6 5713 5711 5557 5715 5716 5717 1 6 5714 5557 5716 5560 5559 5558 1 6 5714 5715 5717 5562 5561 5560 1 5 5714 5716 5562 5564 5713 1 7 5696 5697 5719 9696 5865 9697 9699 1 6 5718 5697 5720 9696 9695 9700 1 6 5719 5697 5698 5721 9700 9701 1 7 5720 5698 5699 5722 5723 5724 9701 1 5 5721 5699 5701 5702 5723 1 7 5722 5702 5721 5724 5725 5726 5727 1 6 5721 5723 5725 6095 9701 9702 1 6 5724 5723 5726 6095 6096 6097 1 6 5725 5723 5727 6097 5730 5728 1 5 5726 5723 5702 5703 5728 1 6 5727 5703 5704 5729 5730 5726 1 6 5728 5704 5730 5731 5732 5705 1 7 5728 5729 5731 6097 5726 6098 6099 1 6 5730 5729 5732 6099 6100 6101 1 6 5731 5729 5705 5706 5733 6101 1 6 5732 5706 5734 5735 6101 6102 1 6 5733 5706 5735 5736 5737 5707 1 6 5733 5734 5736 6105 6102 6106 1 6 5735 5734 5737 6106 6107 5739 1 6 5736 5734 5707 5708 5738 5739 1 6 5737 5708 5739 5740 5747 5709 1 6 5737 5738 5740 5741 6107 5736 1 6 5739 5738 5741 5742 5746 5747 1 6 5739 5740 5742 5743 6107 6108 1 6 5741 5740 5743 5744 5745 5746 1 6 5741 5742 5744 6111 6108 6112 1 6 5743 5742 5745 6112 6113 6114 1 6 5744 5742 5746 5750 6121 6114 1 6 5745 5742 5740 5747 5748 5750 1 6 5746 5740 5738 5709 5710 5748 1 6 5747 5710 5712 5749 5746 5750 1 6 5748 5712 5750 5751 5752 5753 1 6 5746 5748 5745 5749 5751 6121 1 5 5750 5749 5752 6121 5949 1 6 5751 5749 5753 5568 5754 5949 1 6 5752 5749 5712 5713 5568 5566 1 6 5752 5568 5569 5755 5756 5949 1 6 5754 5569 5756 5757 5758 5770 1 6 5754 5755 5757 5949 5950 5951 1 6 5756 5755 5758 5759 5951 5952 1 6 5757 5755 5759 5760 5761 5770 1 6 5757 5758 5760 5952 5953 5957 1 6 5759 5758 5761 5762 5763 5957 1 6 5760 5758 5762 5766 5767 5770 1 6 5760 5761 5763 5764 5765 5766 1 6 5760 5762 5764 5957 5958 5988 1 6 5763 5762 5765 5989 5988 5990 1 6 5764 5762 5766 5990 5991 5776 1 6 5765 5762 5761 5767 5768 5776 1 6 5766 5761 5768 5769 5570 5770 1 6 5766 5767 5769 5772 5775 5776 1 6 5768 5767 5570 5571 5771 5772 1 6 5570 5767 5569 5761 5755 5758 1 6 5769 5571 5572 5573 5574 5772 1 7 5771 5574 5773 5592 5775 5769 5768 1 6 5772 5574 5575 5594 5590 5592 1 6 5589 5576 5586 5581 5579 5577 1 5 5772 5592 5593 5776 5768 1 7 5775 5593 5777 5991 5765 5768 5766 1 6 5776 5593 5778 5992 5991 5782 1 6 5777 5593 5591 5595 5779 5782 1 6 5778 5595 5596 5599 5780 5782 1 6 5779 5599 5781 5782 5783 5784 1 6 5780 5599 5600 5784 5785 5789 1 6 5779 5780 5783 5992 5777 5778 1 6 5782 5780 5784 5993 5992 5996 1 7 5783 5780 5781 5785 5786 5996 5997 1 6 5784 5781 5786 5787 5788 5789 1 6 5784 5785 5787 5997 5998 5999 1 6 5786 5785 5788 6002 5999 6003 1 6 5787 5785 5789 6009 6003 6199 1 6 5788 5785 5781 5600 5790 6199 1 6 5789 5600 5601 5791 5792 6199 1 6 5790 5601 5792 5793 5794 5603 1 6 5790 5791 5793 6198 6199 6197 1 6 5792 5791 5794 6197 6200 6221 1 6 5793 5791 5603 5795 6221 6219 1 6 5794 5603 5604 5796 5797 6219 1 6 5795 5604 5797 5798 5607 5606 1 6 5795 5796 5798 5799 6218 6219 1 6 5797 5796 5607 5799 5800 5610 1 6 5797 5798 5800 5801 5802 6218 1 7 5799 5798 5610 5609 5801 5805 5806 1 6 5799 5800 5802 5803 5804 5805 1 6 5799 5801 5803 6217 6209 6218 1 6 5802 5801 5804 5823 5824 6217 1 6 5803 5801 5805 5823 5830 5839 1 6 5804 5801 5800 5806 5808 5839 1 5 5805 5800 5609 5807 5808 1 5 5806 5609 5354 5356 5808 1 7 5807 5356 5358 5809 5839 5805 5806 1 6 5808 5358 5810 5838 5839 5886 1 7 5809 5358 5363 5364 5811 5885 5886 1 6 5810 5364 5884 5885 5887 5402 1 6 5665 5666 5813 5814 5815 5816 1 6 5665 5812 5814 5835 5664 5842 1 6 5813 5812 5815 5842 5843 5844 1 6 5814 5812 5816 5819 5820 5844 1 6 5815 5812 5666 5817 5818 5819 1 6 5816 5666 5818 5859 5857 5667 1 6 5816 5817 5819 5822 5857 5854 1 6 5816 5818 5815 5820 5821 5822 1 6 5815 5819 5821 5844 5845 5846 1 6 5820 5819 5822 5852 5849 5846 1 6 5821 5819 5818 5852 5853 5854 1 6 5803 5804 5824 5825 5826 5830 1 5 5803 5823 5825 6216 6217 1 7 5824 5823 5826 5827 6216 6215 6021 1 6 5825 5823 5827 5828 5829 5830 1 6 5825 5826 5828 6019 6020 6021 1 6 5827 5826 5829 5836 5872 6019 1 6 5828 5826 5830 5836 5837 5838 1 6 5829 5826 5823 5804 5838 5839 1 6 5658 5659 5832 6931 6932 6933 1 6 5831 5659 5660 5833 5840 6933 1 6 5832 5660 5661 5662 5834 5840 1 6 5833 5662 5835 5840 5841 5842 1 6 5834 5662 5663 5664 5813 5842 1 6 5828 5829 5837 5872 5873 5883 1 6 5836 5829 5838 5885 5883 5886 1 6 5837 5829 5830 5839 5809 5886 1 6 5838 5830 5809 5808 5805 5804 1 6 5832 5833 5834 5841 6933 6934 1 6 5840 5834 5842 6934 6935 5843 1 6 5841 5834 5835 5813 5814 5843 1 6 5842 5814 5844 6018 6935 5841 1 6 5843 5814 5815 5820 5845 6018 1 6 5844 5820 5846 5847 6018 6940 1 6 5845 5820 5847 5848 5849 5821 1 6 5845 5846 5848 6940 6941 6942 1 6 5847 5846 5849 5850 6945 6942 1 6 5848 5846 5850 5851 5852 5821 1 5 5848 5849 5851 6945 6385 1 6 5850 5849 5852 6103 6104 6385 1 6 5851 5849 5821 5822 5853 6103 1 6 5852 5822 5854 5855 6100 6103 1 6 5853 5822 5855 5856 5857 5818 1 6 5853 5854 5856 6098 6099 6100 1 6 5855 5854 5857 5858 6384 6098 1 6 5856 5854 5858 5859 5817 5818 1 6 5856 5857 5859 5860 6383 6384 1 6 5858 5857 5817 5667 5668 5860 1 6 5859 5668 5669 5861 6383 5858 1 6 5860 5669 5670 5862 9703 6383 1 6 5861 5670 5671 5863 9694 9703 1 6 5862 5671 5672 5864 9694 9695 1 6 5863 5672 5673 5865 9695 9696 1 7 5864 5673 5674 5866 9696 5718 9697 1 5 5865 5674 5675 5867 9697 1 7 5866 5675 5676 5677 5868 9697 9698 1 5 5867 5677 5693 5694 9698 1 5 5693 5678 5679 5870 5692 1 6 5869 5679 5680 5871 5690 5692 1 6 5870 5680 5681 5688 5689 5690 1 6 5828 5836 5873 5874 9736 6019 1 6 5872 5836 5874 5875 5882 5883 1 6 5872 5873 5875 5876 9736 6041 1 6 5874 5873 5876 5877 5878 5882 1 6 5874 5875 5877 6048 6041 6042 1 6 5876 5875 5878 5879 6049 6048 1 6 5877 5875 5879 5880 5881 5882 1 6 5877 5878 5880 6049 6050 5888 1 6 5879 5878 5881 5400 5399 5888 1 6 5880 5878 5882 5884 5887 5400 1 6 5881 5878 5875 5873 5883 5884 1 6 5882 5873 5836 5884 5885 5837 1 6 5882 5883 5885 5811 5881 5887 1 6 5884 5883 5837 5811 5810 5886 1 5 5810 5885 5837 5838 5809 1 5 5881 5884 5811 5402 5400 1 6 5880 5399 5889 6053 6050 5879 1 6 5888 5399 5397 5890 5891 6053 1 6 5889 5397 5891 5892 5893 5396 1 6 5889 5890 5892 6056 6053 6057 1 6 5891 5890 5893 6057 6058 6059 1 6 5892 5890 5396 5894 5895 6059 1 6 5893 5396 5895 5896 5899 5395 1 6 5893 5894 5896 5897 6059 6061 1 6 5895 5894 5897 5898 4889 5899 1 6 5895 5896 5898 5900 6061 6062 1 6 5897 5896 4889 4890 5900 5901 1 7 4889 5896 5894 5395 5393 5372 4888 1 6 5897 5898 5901 6065 6062 6066 1 6 5900 5898 4890 4892 5902 6066 1 6 5901 4892 5903 5904 5905 6066 1 6 5902 4892 5904 5911 5912 4893 1 6 5902 5903 5905 5906 5907 5911 1 6 5902 5904 5906 6066 6070 6067 1 7 5905 5904 5907 5908 6075 6072 6070 1 6 5906 5904 5908 5909 5910 5911 1 5 5906 5907 5909 5934 6075 1 7 5908 5907 5910 5932 5929 5933 5934 1 6 5909 5907 5911 5932 9752 5915 1 6 5910 5907 5904 5903 5912 5915 1 6 5911 5903 4893 5913 5914 5915 1 6 5912 4893 4894 4896 4899 5914 1 6 5913 4899 5912 5915 5916 5917 1 6 5912 5914 5916 5911 9752 5910 1 6 5915 5914 5917 9752 9755 9758 1 6 5916 5914 4899 4900 5918 9758 1 7 5917 4900 4902 3671 3951 5919 9758 1 6 5918 3951 3949 5920 9755 9758 1 5 5919 3949 3948 5921 9755 1 6 5920 3948 5922 5930 5931 9755 1 6 5921 3948 3946 3962 5923 5930 1 6 5922 3962 3963 5924 5925 5930 1 6 5923 3963 3965 5925 5926 5942 1 6 5923 5924 5926 5927 5929 5930 1 6 5925 5924 5927 5928 5941 5942 1 5 5925 5926 5928 5929 5933 1 7 5927 5926 5935 5933 5936 5940 5941 1 7 5925 5927 5930 5931 5932 5909 5933 1 6 5925 5929 5931 5923 5922 5921 1 6 5930 5929 5921 5932 9752 9755 1 5 5931 5929 5909 5910 9752 1 6 5909 5929 5934 5935 5928 5927 1 6 5909 5933 5935 6074 6075 5908 1 6 5934 5933 5928 5936 5937 6074 1 6 5935 5928 5937 5938 5939 5940 1 5 5935 5936 5938 6074 6076 1 6 5937 5936 5939 6076 6077 6086 1 6 5938 5936 5940 6087 6086 6091 1 7 5939 5936 5928 5941 5944 6091 5946 1 5 5940 5928 5926 5942 5944 1 6 5941 5926 5924 3965 5943 5944 1 7 5942 3965 3966 5944 5945 3135 5947 1 6 5942 5943 5941 5940 5945 5946 1 5 5944 5943 5946 3134 3135 1 6 5944 5945 3134 6091 5940 3136 1 6 3135 5943 2093 2092 5948 3966 1 6 2092 5947 3966 3967 2488 2489 1 6 5754 5756 5950 5752 5751 6121 1 6 5949 5756 5951 6166 6120 6121 1 6 5950 5756 5757 5952 6166 6164 1 6 5951 5757 5759 5953 5954 6164 1 6 5952 5759 5954 5955 5956 5957 1 6 5952 5953 5955 6162 6161 6164 1 6 5954 5953 5956 5960 5967 6162 1 6 5955 5953 5957 5958 5959 5960 1 6 5956 5953 5759 5760 5763 5958 1 6 5957 5763 5956 5959 5963 5988 1 6 5956 5958 5960 5961 5962 5963 1 6 5956 5959 5961 5964 5967 5955 1 6 5960 5959 5962 5964 5965 5982 1 6 5961 5959 5963 5983 5982 5984 1 6 5962 5959 5958 5987 5984 5988 1 6 5960 5961 5965 5966 5967 5968 1 6 5964 5961 5966 5982 5980 5971 1 6 5964 5965 5968 5969 5970 5971 1 6 5960 5964 5955 5968 6163 6162 1 7 5967 5964 5966 5969 6156 6157 6163 1 6 5968 5966 5970 6447 6445 6156 1 6 5969 5966 5971 5972 6447 6448 1 6 5970 5966 5972 5973 5965 5980 1 6 5970 5971 5973 5974 5975 6448 1 6 5972 5971 5974 5978 5979 5980 1 6 5972 5973 5975 5976 5977 5978 1 6 5972 5974 5976 6448 6449 6450 1 6 5975 5974 5977 6450 6608 6609 1 6 5976 5974 5978 6609 6612 6613 1 6 5977 5974 5973 5979 6613 6614 1 6 5978 5973 5980 5981 6640 6614 1 6 5979 5973 5981 5982 5965 5971 1 6 5979 5980 5982 5983 6640 6641 1 6 5981 5980 5983 5962 5961 5965 1 6 5981 5982 5962 5984 5985 6641 1 6 5983 5962 5985 5986 5987 5963 1 6 5983 5984 5986 6643 6641 6168 1 6 5985 5984 5987 5994 6167 6168 1 6 5986 5984 5963 5988 5989 5994 1 6 5987 5963 5958 5989 5764 5763 1 6 5987 5988 5764 5990 5993 5994 1 6 5989 5764 5765 5991 5992 5993 1 5 5990 5765 5992 5777 5776 1 6 5990 5991 5777 5993 5783 5782 1 7 5990 5992 5783 5989 5994 5995 5996 1 6 5989 5993 5995 5986 5987 6167 1 6 5994 5993 5996 5997 5998 6167 1 5 5995 5993 5783 5784 5997 1 5 5995 5996 5998 5784 5786 1 7 5995 5997 5786 5999 6000 6169 6167 1 6 5998 5786 6000 6001 6002 5787 1 5 5998 5999 6001 6169 6170 1 6 6000 5999 6002 6170 6171 6005 1 6 6001 5999 5787 6003 6004 6005 1 6 6002 5787 6004 6008 6009 5788 1 6 6002 6003 6005 6006 6007 6008 1 6 6002 6004 6006 6171 6001 6172 1 6 6005 6004 6007 6010 6172 6173 1 6 6006 6004 6008 6010 6011 6015 1 6 6007 6004 6003 6009 6017 6015 1 6 6008 6003 5788 6198 6017 6199 1 6 6006 6007 6011 6012 6179 6173 1 6 6010 6007 6012 6013 6014 6015 1 6 6010 6011 6013 6180 6179 6186 1 6 6012 6011 6014 6190 6187 6186 1 6 6013 6011 6015 6016 6190 6191 1 6 6014 6011 6016 6017 6008 6007 1 6 6014 6015 6017 6191 6194 6195 1 6 6016 6015 6008 6198 6195 6009 1 6 5843 5844 5845 6937 6935 6940 1 6 5827 5828 6020 9736 6038 5872 1 6 5827 6019 6021 6022 6023 6038 1 6 5827 6020 6022 6215 5825 6222 1 6 6021 6020 6023 6024 6025 6222 1 6 6022 6020 6024 6037 6028 6038 1 6 6022 6023 6025 6026 6027 6028 1 6 6022 6024 6026 6222 6225 6223 1 6 6025 6024 6027 6225 6226 6032 1 6 6026 6024 6028 6029 6031 6032 1 6 6027 6024 6029 6030 6037 6023 1 6 6027 6028 6030 6031 6033 6034 1 6 6029 6028 6034 6035 6036 6037 1 6 6027 6029 6032 6033 6247 6239 1 6 6027 6031 6226 6026 6227 6239 1 6 6031 6029 6034 6247 6246 6248 1 6 6033 6029 6030 6035 6248 6249 1 6 6034 6030 6036 6249 6263 6264 1 6 6035 6030 6037 6039 6040 6264 1 6 6036 6030 6028 6023 6038 6039 1 6 6037 6023 6039 9736 6019 6020 1 6 6037 6038 6036 6040 6041 9736 1 7 6036 6039 6041 6042 6043 6265 6264 1 6 6040 6039 6042 9736 5874 5876 1 6 6040 6041 6043 6044 6048 5876 1 5 6040 6042 6044 6045 6265 1 6 6043 6042 6045 6046 6047 6048 1 7 6043 6044 6046 6262 6265 6261 6266 1 6 6045 6044 6047 6269 6266 6280 1 6 6046 6044 6048 6049 6051 6280 1 6 6047 6044 6042 6049 5877 5876 1 6 6047 6048 5877 5879 6050 6051 1 6 6049 5879 6051 6052 6053 5888 1 6 6049 6050 6052 6054 6280 6047 1 6 6051 6050 6053 6054 6055 6056 1 6 6052 6050 5888 5889 6056 5891 1 7 6051 6052 6055 6279 6280 6278 6281 1 6 6054 6052 6056 6283 6281 6284 1 6 6055 6052 6053 5891 6057 6284 1 6 6056 5891 5892 6058 6060 6284 1 6 6057 5892 6059 6060 6287 6288 1 6 6058 5892 5893 5895 6061 6288 1 6 6057 6058 6284 6285 6286 6287 1 6 6059 5895 5897 6062 6063 6288 1 6 6061 5897 6063 6064 6065 5900 1 7 6061 6062 6064 6288 6291 6289 6292 1 5 6063 6062 6065 6292 6068 1 6 6064 6062 5900 6066 6067 6068 1 6 6065 5900 5901 5902 5905 6067 1 6 6065 6066 6068 6069 6070 5905 1 7 6065 6067 6069 6292 6064 6293 6294 1 5 6068 6067 6070 6071 6294 1 6 6069 6067 5905 6071 6072 5906 1 7 6069 6070 6072 6073 6296 6294 6297 1 6 6071 6070 6073 6074 6075 5906 1 6 6071 6072 6074 6297 6078 6076 1 7 6073 6072 6075 5934 5935 5937 6076 1 5 6074 6072 5934 5908 5906 1 6 6074 5937 5938 6077 6078 6073 1 6 6076 5938 6078 6079 6086 6083 1 6 6076 6077 6079 6080 6297 6073 1 6 6078 6077 6080 6081 6082 6083 1 6 6078 6079 6081 6297 6298 6301 1 6 6080 6079 6082 6301 6302 6314 1 6 6081 6079 6083 6084 6313 6314 1 6 6082 6079 6084 6085 6086 6077 1 7 6082 6083 6085 6088 6313 6315 6318 1 6 6084 6083 6086 6087 6088 6089 1 6 6085 6083 6087 5939 5938 6077 1 6 6085 6086 5939 6089 6090 6091 1 6 6084 6085 6089 6094 3769 6318 1 7 6088 6085 6087 6090 3137 6092 6094 1 5 6089 6087 6091 3136 3137 1 6 6090 6087 5939 5940 5946 3136 1 6 6089 3137 3138 6093 3768 6094 1 7 6092 3138 3768 3766 2085 2084 9776 1 5 6092 3768 3769 6088 6089 1 6 5724 5725 6096 6383 9702 9703 1 6 6095 5725 6097 6098 6383 6384 1 5 6096 5725 5726 5730 6098 1 7 6096 6097 5730 6099 6384 5856 5855 1 5 6098 5730 5731 6100 5855 1 7 6099 5731 6101 6102 6103 5855 5853 1 5 6100 5731 5732 5733 6102 1 7 6101 5733 6100 6103 6104 6105 5735 1 6 6100 6102 6104 5853 5852 5851 1 6 6103 6102 6105 5851 6385 6386 1 5 6104 6102 5735 6106 6386 1 7 6105 5735 5736 6107 6386 6387 6109 1 6 6106 5736 5739 5741 6108 6109 1 6 6107 5741 6109 6110 6111 5743 1 6 6107 6108 6110 6387 6106 6388 1 6 6109 6108 6111 6388 6389 6390 1 6 6110 6108 5743 6112 6393 6390 1 6 6111 5743 5744 6113 6115 6393 1 6 6112 5744 6114 6115 6116 6117 1 6 6113 5744 6120 6117 6121 5745 1 6 6112 6113 6116 6393 9737 9738 1 6 6115 6113 6117 6118 6122 9738 1 6 6116 6113 6118 6119 6120 6114 1 6 6116 6117 6119 6122 6123 6165 1 5 6118 6117 6120 6166 6165 1 6 6119 6117 6114 6121 6166 5950 1 7 6120 6114 5745 5750 5751 5949 5950 1 6 6116 6118 6123 6124 6131 9738 1 6 6122 6118 6124 6125 6165 6160 1 6 6122 6123 6125 6126 6127 6131 1 6 6124 6123 6126 6152 6160 6158 1 6 6124 6125 6127 6128 6151 6152 1 6 6124 6126 6128 6129 6130 6131 1 6 6127 6126 6129 6150 6149 6151 1 6 6127 6128 6130 6150 6137 6134 1 6 6127 6129 6131 6132 6133 6134 1 6 6127 6130 6132 9738 6122 6124 1 6 6131 6130 6133 6398 9737 9738 1 6 6132 6130 6134 6135 6397 6398 1 6 6133 6130 6135 6136 6137 6129 1 6 6133 6134 6136 6397 6399 6400 1 6 6135 6134 6137 6138 6400 6401 1 6 6136 6134 6138 6139 6150 6129 1 6 6136 6137 6139 6140 6401 6402 1 6 6138 6137 6140 6141 6148 6150 1 6 6138 6139 6141 6142 6402 6403 1 6 6140 6139 6142 6143 6144 6148 1 6 6140 6141 6143 6403 6404 6405 1 6 6142 6141 6144 6145 6405 6436 1 6 6143 6141 6145 6146 6147 6148 1 6 6143 6144 6146 6437 6436 6438 1 6 6145 6144 6147 6438 6439 6440 1 6 6146 6144 6148 6149 6440 6441 1 6 6147 6144 6141 6139 6149 6150 1 6 6147 6148 6150 6128 6151 6441 1 6 6149 6148 6139 6137 6129 6128 1 6 6149 6128 6126 6152 6153 6441 1 6 6151 6126 6125 6153 6154 6158 1 6 6151 6152 6154 6155 6441 6442 1 6 6153 6152 6155 6156 6157 6158 1 6 6153 6154 6156 6444 6442 6445 1 6 6155 6154 6157 5969 6445 5968 1 6 6156 6154 6158 6159 5968 6163 1 6 6157 6154 6152 6159 6160 6125 1 6 6157 6158 6160 6161 6162 6163 1 6 6159 6158 6125 6161 6123 6165 1 6 6159 6160 6162 5954 6164 6165 1 6 6159 6161 6163 5967 5955 5954 1 5 6159 6162 5967 6157 5968 1 6 5954 6161 6165 6166 5951 5952 1 7 6164 6161 6166 6119 6118 6123 6160 1 6 6164 6165 6119 6120 5950 5951 1 6 5994 5995 5986 6168 6169 5998 1 6 5986 6167 6169 6643 5985 9783 1 6 6168 6167 5998 6000 6170 9783 1 7 6169 6000 6001 6171 6789 9783 9782 1 7 6170 6001 6005 6172 6788 6786 6789 1 6 6171 6005 6006 6173 6174 6788 1 6 6172 6006 6174 6175 6010 6179 1 6 6172 6173 6175 6176 6784 6788 1 6 6174 6173 6176 6177 6178 6179 1 6 6174 6175 6177 6782 6781 6784 1 6 6176 6175 6178 9796 6782 9797 1 6 6177 6175 6179 6180 6181 9796 1 6 6178 6175 6180 6012 6010 6173 1 6 6178 6179 6181 6182 6186 6012 1 6 6178 6180 6182 6183 9796 9799 1 6 6181 6180 6183 6184 6185 6186 1 6 6181 6182 6184 6362 6645 9799 1 6 6183 6182 6185 6362 6363 6367 1 6 6184 6182 6186 6187 6188 6367 1 6 6185 6182 6180 6187 6012 6013 1 6 6185 6186 6188 6189 6190 6013 1 6 6185 6187 6189 6367 6368 6369 1 6 6188 6187 6190 6369 6372 6192 1 6 6189 6187 6013 6014 6191 6192 1 6 6190 6014 6016 6192 6193 6194 1 6 6190 6191 6193 6372 6189 6373 1 6 6192 6191 6194 6382 6373 6203 1 6 6193 6191 6016 6195 6196 6203 1 6 6194 6016 6196 6197 6198 6017 1 6 6194 6195 6197 6200 6201 6203 1 6 6196 6195 6198 5792 5793 6200 1 6 6197 6195 6017 6009 6199 5792 1 6 6198 6009 5792 5790 5789 5788 1 6 6197 5793 6196 6201 6202 6221 1 6 6196 6200 6202 6203 6204 6205 1 6 6201 6200 6205 6206 6220 6221 1 6 6196 6201 6204 6382 6193 6194 1 6 6203 6201 6205 6382 6459 6381 1 6 6204 6201 6202 6206 6207 6459 1 6 6205 6202 6207 6208 6209 6220 1 6 6205 6206 6208 6210 6211 6459 1 6 6207 6206 6209 6210 6214 6217 1 6 6208 6206 5802 6217 6218 6220 1 6 6207 6208 6211 6212 6213 6214 1 6 6207 6210 6212 6456 6458 6459 1 7 6211 6210 6213 6223 6224 6454 6456 1 5 6212 6210 6214 6215 6223 1 6 6213 6210 6208 6215 6216 6217 1 7 6213 6214 6216 5825 6021 6222 6223 1 5 6215 6214 6217 5824 5825 1 7 6216 6214 5824 5803 5802 6209 6208 1 6 5802 6209 5799 5797 6219 6220 1 6 5797 6218 6220 6221 5794 5795 1 6 6219 6218 6209 6206 6202 6221 1 6 6219 6220 6202 6200 5793 5794 1 5 6215 6021 6022 6025 6223 1 7 6215 6222 6213 6212 6224 6225 6025 1 7 6212 6223 6225 6454 6231 6226 6228 1 5 6224 6223 6025 6026 6226 1 6 6225 6026 6032 6227 6228 6224 1 6 6226 6032 6228 6229 6238 6239 1 6 6226 6227 6229 6230 6231 6224 1 6 6228 6227 6230 6237 6234 6238 1 6 6228 6229 6231 6232 6233 6234 1 6 6228 6230 6232 6454 6224 6455 1 6 6231 6230 6233 6455 6460 6461 1 6 6232 6230 6234 6235 6461 6462 1 6 6233 6230 6235 6236 6237 6229 1 6 6233 6234 6236 6462 6463 6471 1 6 6235 6234 6237 6473 6471 6476 1 6 6236 6234 6229 6238 6476 6241 1 6 6237 6229 6227 6239 6240 6241 1 6 6238 6227 6240 6247 6031 6032 1 6 6238 6239 6241 6242 6243 6247 1 6 6238 6240 6242 6476 6237 6477 1 6 6241 6240 6243 6244 6477 6479 1 6 6242 6240 6244 6245 6246 6247 1 6 6242 6243 6245 6481 6479 6482 1 6 6244 6243 6246 6482 6253 6251 1 6 6245 6243 6247 6033 6248 6251 1 6 6246 6243 6240 6239 6031 6033 1 6 6246 6033 6034 6249 6250 6251 1 6 6248 6034 6035 6250 6263 6255 1 6 6248 6249 6251 6252 6254 6255 1 6 6248 6250 6252 6253 6245 6246 1 6 6251 6250 6253 6254 6484 6485 1 6 6251 6252 6482 6245 6483 6484 1 6 6252 6250 6255 6256 6257 6485 1 6 6254 6250 6256 6263 6260 6249 1 6 6254 6255 6257 6258 6259 6260 1 6 6254 6256 6258 6485 6493 6494 1 6 6257 6256 6259 6494 6495 6496 1 7 6258 6256 6260 6261 6496 6273 6267 1 6 6259 6256 6261 6262 6263 6255 1 6 6259 6260 6262 6045 6266 6267 1 6 6261 6260 6263 6264 6265 6045 1 6 6262 6260 6264 6255 6249 6035 1 6 6262 6263 6265 6035 6040 6036 1 5 6262 6264 6045 6043 6040 1 6 6045 6261 6267 6268 6269 6046 1 6 6261 6266 6268 6272 6273 6259 1 6 6267 6266 6269 6270 6271 6272 1 6 6268 6266 6046 6270 6279 6280 1 6 6268 6269 6271 6277 6278 6279 1 6 6268 6270 6272 6275 6276 6277 1 6 6268 6271 6267 6273 6274 6275 1 6 6267 6272 6274 6496 6259 6497 1 6 6273 6272 6275 6500 6497 6501 1 6 6274 6272 6271 6276 6501 6502 1 6 6275 6271 6277 6502 6503 6504 1 6 6276 6271 6270 6278 6504 6505 1 7 6277 6270 6279 6054 6281 6282 6505 1 5 6278 6270 6269 6280 6054 1 6 6279 6269 6046 6054 6051 6047 1 5 6278 6054 6282 6283 6055 1 6 6278 6281 6283 6506 6505 6507 1 6 6282 6281 6055 6284 6507 6285 1 6 6283 6055 6056 6057 6060 6285 1 6 6284 6060 6286 6507 6283 6508 1 7 6285 6060 6287 6508 6328 6511 6290 1 6 6286 6060 6058 6288 6289 6290 1 6 6287 6058 6059 6061 6063 6289 1 5 6287 6288 6290 6291 6063 1 5 6287 6289 6291 6328 6286 1 7 6290 6289 6063 6292 6326 6327 6328 1 6 6291 6063 6064 6068 6293 6326 1 6 6292 6068 6294 6295 6325 6326 1 6 6293 6068 6069 6295 6296 6071 1 6 6293 6294 6296 6299 6324 6325 1 6 6295 6294 6071 6297 6298 6299 1 6 6296 6071 6073 6078 6080 6298 1 6 6297 6080 6296 6299 6300 6301 1 5 6296 6298 6300 6324 6295 1 6 6299 6298 6301 6303 6323 6324 1 6 6300 6298 6080 6081 6302 6303 1 6 6301 6081 6303 6304 6308 6314 1 6 6301 6302 6304 6305 6323 6300 1 6 6303 6302 6305 6306 6307 6308 1 6 6303 6304 6306 6323 6337 6338 1 6 6305 6304 6307 6338 6341 6342 1 6 6306 6304 6308 6309 6342 6343 1 6 6307 6304 6302 6309 6310 6314 1 6 6307 6308 6310 6311 6343 6346 1 6 6309 6308 6311 6312 6313 6314 1 6 6309 6310 6312 6321 6322 6346 1 6 6311 6310 6313 6315 6316 6321 1 6 6312 6310 6314 6082 6084 6315 1 6 6313 6310 6082 6081 6302 6308 1 6 6313 6084 6312 6316 6317 6318 1 6 6312 6315 6317 6319 6320 6321 1 6 6316 6315 6318 3769 1571 6319 1 5 6317 6315 3769 6084 6088 1 5 6317 1571 1572 6320 6316 1 7 6319 1572 1573 6316 6321 6322 6360 1 5 6316 6320 6322 6312 6311 1 7 6321 6320 6311 6347 6346 6348 6360 1 6 6303 6305 6300 6324 6335 6337 1 7 6300 6323 6299 6295 6325 6336 6335 1 6 6295 6324 6293 6326 6336 6331 1 6 6293 6325 6292 6291 6327 6331 1 6 6291 6326 6328 6329 6330 6331 1 6 6291 6327 6329 6511 6286 6290 1 6 6328 6327 6330 6510 6511 6519 1 7 6329 6327 6331 6332 6333 6519 6518 1 6 6330 6327 6332 6336 6325 6326 1 6 6330 6331 6333 6334 6335 6336 1 5 6330 6332 6334 6518 6520 1 6 6333 6332 6335 6520 6528 6529 1 7 6334 6332 6336 6324 6323 6337 6529 1 5 6335 6332 6331 6325 6324 1 6 6335 6323 6305 6338 6339 6529 1 6 6337 6305 6306 6339 6340 6341 1 6 6337 6338 6340 6530 6527 6529 1 5 6339 6338 6341 6545 6530 1 6 6340 6338 6306 6342 6546 6545 1 6 6341 6306 6307 6343 6344 6546 1 6 6342 6307 6344 6345 6346 6309 1 6 6342 6343 6345 6546 6543 6547 1 6 6344 6343 6346 6347 6549 6547 1 6 6345 6343 6347 6322 6311 6309 1 6 6345 6346 6322 6348 6349 6549 1 6 6347 6322 6349 6350 6359 6360 1 6 6347 6348 6350 6351 6550 6549 1 6 6349 6348 6351 6352 6353 6359 1 6 6349 6350 6352 6552 6550 6553 1 6 6351 6350 6353 6354 6355 6553 1 6 6352 6350 6354 1589 2476 6359 1 7 6352 6353 6355 6356 1594 1590 1589 1 6 6352 6354 6356 6357 6553 6554 1 5 6355 6354 6357 6358 1594 1 6 6355 6356 6358 6554 6555 3971 1 6 6357 6356 1594 3971 3970 1595 1 6 2476 6353 6350 6348 6360 6361 1 6 6359 6348 6361 1573 6320 6322 1 5 6359 6360 1573 2475 2476 1 6 6183 6184 6363 6364 6644 6645 1 6 6362 6184 6364 6365 6366 6367 1 6 6362 6363 6365 6644 6648 6649 1 6 6364 6363 6366 9727 9673 6649 1 6 6365 6363 6367 9727 9728 6368 1 6 6366 6363 6184 6185 6188 6368 1 6 6367 6188 6369 6370 9728 6366 1 6 6368 6188 6189 6370 6371 6372 1 6 6368 6369 6371 9728 9729 9730 1 6 6370 6369 6372 6374 6375 9730 1 6 6371 6369 6189 6192 6373 6374 1 6 6372 6192 6374 6382 6380 6193 1 6 6372 6373 6371 6375 6376 6380 1 6 6371 6374 6376 6377 6467 9730 1 6 6375 6374 6377 6378 6379 6380 1 5 6375 6376 6378 9693 6467 1 7 6377 6376 6379 6457 6455 6460 9693 1 6 6378 6376 6380 6381 6457 6458 1 6 6379 6376 6381 6382 6373 6374 1 6 6379 6380 6382 6459 6458 6204 1 6 6381 6380 6373 6193 6203 6204 1 7 6095 6096 6384 9703 5861 5860 5858 1 5 6383 6096 6098 5856 5858 1 6 5851 6104 6386 6945 5850 6946 1 7 6385 6104 6105 6106 6387 6946 6947 1 5 6386 6106 6109 6388 6947 1 6 6387 6109 6110 6389 6947 6948 1 6 6388 6110 6390 6391 6948 6949 1 6 6389 6110 6391 6392 6393 6111 1 6 6389 6390 6392 6394 6395 6949 1 6 6391 6390 6393 6394 9737 6398 1 6 6392 6390 6111 6112 6115 9737 1 6 6391 6392 6395 6396 6397 6398 1 6 6391 6394 6396 6949 6950 6951 1 6 6395 6394 6397 6951 6952 6399 1 6 6396 6394 6398 6133 6135 6399 1 6 6397 6394 6133 6132 9737 6392 1 6 6397 6135 6400 6952 6396 6953 1 6 6399 6135 6136 6401 6953 6954 1 6 6400 6136 6138 6402 6954 6960 1 6 6401 6138 6140 6403 6960 6410 1 6 6402 6140 6142 6404 6408 6410 1 6 6403 6142 6405 6406 6407 6408 1 6 6404 6142 6143 6406 6436 6434 1 6 6404 6405 6407 6431 6429 6434 1 6 6404 6406 6408 6409 6428 6429 1 6 6404 6407 6409 6403 6410 6411 1 6 6408 6407 6411 6412 6413 6428 1 6 6403 6408 6411 6959 6960 6402 1 6 6410 6408 6409 6412 6959 6961 1 6 6411 6409 6413 6414 6963 6961 1 6 6412 6409 6414 6415 6427 6428 1 6 6412 6413 6415 6416 6963 6964 1 6 6414 6413 6416 6417 6418 6427 1 6 6414 6415 6417 6558 6559 6964 1 6 6416 6415 6418 6419 6558 6565 1 6 6417 6415 6419 6420 6427 6424 1 6 6417 6418 6420 6421 6573 6565 1 6 6419 6418 6421 6422 6423 6424 1 6 6419 6420 6422 6573 6572 6574 1 6 6421 6420 6423 6580 6577 6574 1 6 6422 6420 6424 6425 6580 6581 1 6 6423 6420 6425 6426 6427 6418 1 6 6423 6424 6426 6584 6581 6430 1 6 6425 6424 6427 6428 6429 6430 1 6 6426 6424 6418 6415 6413 6428 1 6 6427 6413 6409 6407 6426 6429 1 6 6426 6428 6407 6430 6431 6406 1 6 6426 6429 6431 6432 6584 6425 1 6 6430 6429 6406 6432 6433 6434 1 6 6430 6431 6433 6584 6585 6586 1 6 6432 6431 6434 6435 6589 6586 1 6 6433 6431 6435 6436 6405 6406 1 6 6433 6434 6436 6437 6589 6590 1 6 6435 6434 6405 6437 6145 6143 1 6 6435 6436 6145 6438 6590 6591 1 6 6437 6145 6146 6439 6591 6592 1 6 6438 6146 6440 6595 6592 6443 1 6 6439 6146 6147 6441 6442 6443 1 6 6440 6147 6149 6151 6153 6442 1 6 6441 6153 6440 6443 6444 6155 1 6 6440 6442 6444 6595 6439 6453 1 6 6443 6442 6155 6445 6446 6453 1 6 6444 6155 6446 6447 5969 6156 1 6 6444 6445 6447 6449 6452 6453 1 6 6446 6445 5969 5970 6448 6449 1 5 6447 5970 5972 5975 6449 1 7 6448 5975 6447 6450 6451 6452 6446 1 7 6449 5975 5976 6451 6607 6598 6608 1 6 6449 6450 6452 6596 6597 6598 1 5 6449 6451 6446 6453 6596 1 6 6446 6452 6595 6443 6444 6596 1 5 6212 6224 6231 6455 6456 1 7 6454 6231 6456 6457 6378 6232 6460 1 6 6454 6455 6457 6458 6211 6212 1 5 6456 6455 6378 6379 6458 1 6 6457 6379 6456 6211 6459 6381 1 6 6211 6458 6207 6381 6204 6205 1 5 6455 6232 6461 9693 6378 1 6 6460 6232 6233 6462 6465 9693 1 6 6461 6233 6235 6463 6464 6465 1 6 6462 6235 6464 6469 6470 6471 1 6 6462 6463 6465 6466 6468 6469 1 6 6462 6464 6461 6466 6467 9693 1 6 6465 6464 6467 6468 9731 9732 1 7 6465 6466 9693 6377 6375 9730 9731 1 6 6466 6464 6469 7509 7510 9732 1 7 6468 6464 6463 6470 7507 7509 7506 1 6 6469 6463 6471 6472 7506 7505 1 6 6470 6463 6235 6472 6473 6236 1 6 6470 6471 6473 6474 7504 7505 1 6 6472 6471 6236 6474 6475 6476 1 7 6472 6473 6475 7503 7504 9692 9780 1 6 6474 6473 6476 6477 6478 9692 1 6 6475 6473 6236 6237 6241 6477 1 6 6476 6241 6242 6475 6478 6479 1 7 6475 6477 6479 6480 9692 9778 9779 1 6 6478 6477 6242 6480 6481 6244 1 6 6478 6479 6481 6487 9705 9778 1 6 6480 6479 6244 6482 6486 6487 1 6 6481 6244 6245 6253 6483 6486 1 5 6482 6253 6484 6486 6489 1 7 6483 6253 6252 6485 6489 6490 6491 1 7 6484 6252 6254 6257 6491 6492 6493 1 6 6482 6483 6481 6487 6488 6489 1 5 6481 6486 6488 9705 6480 1 7 6487 6486 6489 9704 2194 2195 9705 1 6 6488 6486 6483 6484 6490 9704 1 6 6489 6484 6491 2251 2252 9704 1 6 6490 6484 6485 6492 2251 9706 1 6 6491 6485 6493 9706 3335 9707 1 5 6492 6485 6257 6494 9707 1 6 6493 6257 6258 6495 9707 6499 1 6 6494 6258 6496 6497 6498 6499 1 5 6495 6258 6259 6273 6497 1 6 6496 6273 6495 6498 6500 6274 1 6 6495 6497 6499 2511 2512 6500 1 7 6495 6498 2511 3334 9707 3881 6494 1 6 2512 6498 6497 6274 6501 9710 1 6 6500 6274 6275 6502 9709 9710 1 6 6501 6275 6276 6503 9708 9709 1 6 6502 6276 6504 6512 9708 9711 1 6 6503 6276 6277 6505 6506 6512 1 5 6504 6277 6506 6282 6278 1 7 6504 6505 6282 6507 6512 6513 6509 1 6 6506 6282 6283 6285 6508 6509 1 6 6507 6285 6286 6509 6510 6511 1 6 6507 6508 6510 6513 6506 6514 1 7 6509 6508 6511 6329 6514 6515 6519 1 5 6510 6508 6329 6328 6286 1 6 6503 6504 6506 6513 9711 9717 1 5 6512 6506 6509 6514 9717 1 7 6513 6509 6510 6515 6516 9717 9718 1 6 6514 6510 6516 6517 6518 6519 1 6 6514 6515 6517 9718 9719 6522 1 6 6516 6515 6518 6520 6521 6522 1 6 6517 6515 6519 6330 6333 6520 1 5 6518 6515 6510 6329 6330 1 7 6518 6333 6334 6517 6521 6525 6528 1 6 6517 6520 6522 6523 6524 6525 1 7 6517 6521 6523 2214 9719 6516 2213 1 5 6522 6521 6524 2213 3348 1 7 6523 6521 6525 6526 3348 3347 6532 1 6 6524 6521 6520 6526 6527 6528 1 6 6524 6525 6527 6530 6531 6532 1 6 6526 6525 6528 6530 6339 6529 1 5 6527 6525 6520 6334 6529 1 6 6528 6334 6335 6339 6527 6337 1 7 6526 6527 6531 6340 6545 6339 6534 1 6 6526 6530 6532 3863 6533 6534 1 5 6526 6531 3863 3347 6524 1 6 3863 6531 6534 6535 6536 6716 1 6 6533 6531 6535 6544 6545 6530 1 6 6533 6534 6536 6537 6544 6541 1 6 6533 6535 6537 6538 6715 6716 1 6 6536 6535 6538 6539 6540 6541 1 7 6536 6537 6539 6714 3887 3886 6715 1 6 6538 6537 6540 6714 6718 6719 1 6 6539 6537 6541 6542 6719 6708 1 6 6540 6537 6542 6543 6544 6535 1 6 6540 6541 6543 6547 6548 6708 1 6 6542 6541 6544 6546 6344 6547 1 6 6543 6541 6535 6534 6545 6546 1 6 6544 6534 6546 6341 6340 6530 1 6 6544 6545 6543 6341 6342 6344 1 6 6543 6344 6542 6548 6549 6345 1 6 6542 6547 6549 6550 6551 6708 1 6 6548 6547 6345 6347 6550 6349 1 6 6548 6549 6551 6552 6351 6349 1 6 6548 6550 6552 6705 6707 6708 1 6 6551 6550 6351 6553 6554 6705 1 5 6552 6351 6352 6355 6554 1 6 6553 6355 6357 6555 6552 6705 1 7 6554 6357 3971 6705 6706 9747 3491 1 6 3969 1597 1598 6557 4038 3968 1 6 6556 1598 4038 3764 612 611 1 6 6416 6417 6559 6560 6564 6565 1 6 6416 6558 6560 6561 6964 6965 1 6 6559 6558 6561 6562 6563 6564 1 6 6559 6560 6562 6965 6966 6967 1 6 6561 6560 6563 6985 6983 6967 1 6 6562 6560 6564 6985 6986 6567 1 6 6563 6560 6558 6565 6566 6567 1 6 6564 6558 6417 6566 6573 6419 1 6 6564 6565 6567 6568 6569 6573 1 6 6564 6566 6568 6986 6563 6987 1 6 6567 6566 6569 6570 6990 6987 1 6 6568 6566 6570 6571 6572 6573 1 6 6568 6569 6571 6997 6990 6998 1 6 6570 6569 6572 6575 7001 6998 1 6 6571 6569 6573 6421 6574 6575 1 6 6572 6569 6566 6565 6419 6421 1 6 6572 6421 6575 6576 6577 6422 1 6 6572 6574 6576 7003 7001 6571 1 6 6575 6574 6577 6578 7003 7004 1 6 6576 6574 6578 6579 6580 6422 1 6 6576 6577 6579 7004 7005 7006 1 6 6578 6577 6580 7006 7007 6582 1 6 6579 6577 6422 6423 6581 6582 1 6 6580 6423 6582 6583 6584 6425 1 6 6580 6581 6583 7007 6579 7008 1 6 6582 6581 6584 6720 7008 6585 1 6 6583 6581 6425 6430 6432 6585 1 6 6584 6432 6586 6587 6720 6583 1 6 6585 6432 6587 6588 6589 6433 1 6 6585 6586 6588 6720 6721 6728 1 6 6587 6586 6589 6728 6729 6730 1 6 6588 6586 6433 6435 6590 6730 1 6 6589 6435 6437 6591 6730 6731 1 6 6590 6437 6438 6592 6593 6731 1 6 6591 6438 6593 6594 6595 6439 1 6 6591 6592 6594 6731 6732 6733 1 7 6593 6592 6595 6600 6733 6597 6596 1 6 6594 6592 6439 6443 6453 6596 1 6 6595 6453 6452 6451 6597 6594 1 6 6596 6451 6598 6599 6600 6594 1 6 6597 6451 6599 6606 6607 6450 1 6 6597 6598 6600 6601 6602 6606 1 5 6597 6599 6601 6733 6594 1 6 6600 6599 6602 6603 6734 6733 1 6 6601 6599 6603 6604 6605 6606 1 7 6601 6602 6604 6734 6735 6736 6737 1 5 6603 6602 6605 6737 6738 1 7 6604 6602 6606 6738 6739 6748 6745 1 6 6605 6602 6599 6598 6607 6748 1 6 6606 6598 6450 6608 6747 6748 1 6 6607 6450 5976 6609 6610 6747 1 6 6608 5976 5977 6610 6611 6612 1 6 6608 6609 6611 6747 6746 6749 1 6 6610 6609 6612 6619 6620 6749 1 6 6611 6609 5977 6613 6616 6619 1 6 6612 5977 5978 6614 6615 6616 1 6 6613 5978 6615 6639 6640 5979 1 6 6613 6614 6616 6617 6638 6639 1 6 6613 6615 6617 6618 6619 6612 1 6 6616 6615 6618 6636 6637 6638 1 6 6616 6617 6619 6621 6622 6636 1 6 6616 6618 6612 6611 6620 6621 1 6 6611 6619 6621 6750 6749 6626 1 6 6620 6619 6618 6622 6623 6626 1 6 6621 6618 6623 6624 6635 6636 1 6 6621 6622 6624 6625 6626 6627 1 6 6623 6622 6625 6633 6634 6635 1 6 6623 6624 6627 6628 6632 6633 1 6 6621 6623 6627 6750 6620 6751 1 6 6626 6623 6625 6628 6629 6751 1 6 6627 6625 6629 6630 6631 6632 1 6 6627 6628 6630 6756 6753 6751 1 6 6629 6628 6631 6756 6757 6758 1 6 6630 6628 6632 6758 6766 6767 1 6 6631 6628 6625 6633 6767 6768 1 6 6632 6625 6624 6634 6768 6769 1 6 6633 6624 6635 6769 6770 6771 1 6 6634 6624 6622 6636 9785 6771 1 6 6635 6622 6618 6617 6637 9785 1 6 6636 6617 6638 6785 6783 9785 1 6 6637 6617 6615 6639 9777 6785 1 6 6638 6615 6614 6640 9777 6642 1 6 6639 6614 5979 5981 6641 6642 1 6 6640 5981 5983 6642 6643 5985 1 7 6640 6641 6643 9777 6639 6787 9782 1 6 6642 6641 5985 6168 9782 9783 1 6 6362 6364 6645 6646 6647 6648 1 6 6362 6644 6183 6646 9724 9799 1 6 6645 6644 6647 9723 9724 6655 1 6 6646 6644 6648 6652 6654 6655 1 6 6647 6644 6364 6649 6650 6652 1 6 6648 6364 6650 6651 9673 6365 1 6 6648 6649 6651 6652 6653 9670 1 6 6650 6649 9670 9671 9672 9673 1 6 6648 6650 6653 6647 6654 3173 1 6 6652 6650 9670 9691 3172 3173 1 6 6647 6652 3173 6655 3450 3175 1 6 6647 6654 3450 6656 9723 6646 1 6 6655 3450 6657 6658 9721 9723 1 6 6656 3450 6658 3179 6659 6667 1 6 6656 6657 6667 6668 6669 9721 1 6 6657 3179 6660 6663 6664 6667 1 6 6659 3179 3178 6661 6662 6663 1 6 6660 3178 3180 2858 2859 6662 1 5 6660 6661 6663 6666 2859 1 6 6660 6662 6659 6664 6665 6666 1 6 6659 6663 6665 6667 6668 6672 1 7 6664 6663 6666 6672 6673 4564 4563 1 6 6665 6663 6662 4563 6674 2859 1 5 6659 6664 6668 6658 6657 1 7 6667 6664 6658 6669 6670 6671 6672 1 6 6658 6668 6670 6774 6775 9721 1 6 6669 6668 6671 6773 6772 6774 1 6 6670 6668 6672 6673 6790 6773 1 5 6671 6668 6664 6665 6673 1 5 6672 6665 4564 6671 6790 1 6 4563 6666 4561 6675 2860 2859 1 6 4561 6674 2860 6676 4560 9792 1 6 6675 2860 2853 2854 6677 9792 1 6 6676 2854 6678 6679 6681 9792 1 5 6677 2854 6679 6680 2855 1 6 6677 6678 6680 6681 6682 6683 1 6 6679 6678 6685 6683 6686 2855 1 6 6677 6679 6682 9750 9761 9792 1 6 6681 6679 6683 5156 5157 9750 1 6 6682 6679 5156 6684 6685 6680 1 6 5156 6683 6685 6692 6693 6694 1 6 6684 6683 6680 6686 6687 6692 1 6 6685 6680 6687 6688 6689 2855 1 6 6685 6686 6688 6692 6696 6699 1 6 6687 6686 6689 6690 6699 6700 1 6 6688 6686 6690 6691 2856 2855 1 6 6688 6689 6691 6700 6702 2551 1 5 6690 6689 2856 2550 2551 1 6 6685 6687 6684 6693 6695 6696 1 6 6684 6692 6694 4523 4522 6695 1 5 6684 6693 4523 4532 5156 1 6 4522 6693 6692 6696 6697 6704 1 6 6695 6692 6687 6697 6698 6699 1 7 6695 6696 6698 6703 3505 3506 6704 1 6 6697 6696 6699 6700 6701 6703 1 5 6698 6696 6687 6688 6700 1 7 6699 6688 6690 6698 6701 2222 6702 1 6 6698 6700 2222 64 65 6703 1 5 2222 6700 6690 2551 2221 1 6 6698 6701 65 66 6697 3505 1 5 6697 3506 3507 4522 6695 1 7 6552 6554 6555 6706 6551 6707 9749 1 6 6705 6555 9747 3502 9748 9749 1 6 6551 6705 6708 6709 6710 9749 1 7 6551 6707 6709 6719 6540 6548 6542 1 6 6708 6707 6710 6711 6718 6719 1 7 6709 6707 6711 6712 3503 9748 9749 1 7 6709 6710 6712 3117 3119 6713 6718 1 6 6711 6710 3503 3504 3116 3117 1 6 6711 3119 3121 3887 6714 6718 1 5 6713 3887 6538 6539 6718 1 6 6538 3886 6536 6716 3862 6717 1 5 6536 6715 6533 3863 3862 1 6 3862 6715 3861 3342 3885 3886 1 6 6714 6539 6713 6711 6709 6719 1 5 6718 6539 6540 6709 6708 1 6 6585 6587 6721 6722 7008 6583 1 6 6720 6587 6722 6723 6727 6728 1 6 6720 6721 6723 6724 7009 7008 1 6 6722 6721 6724 6725 6726 6727 1 6 6722 6723 6725 7009 7010 7011 1 6 6724 6723 6726 7022 7011 7023 1 6 6725 6723 6727 7023 7026 7027 1 6 6726 6723 6721 6728 7027 7030 1 6 6727 6721 6587 6588 6729 7030 1 6 6728 6588 6730 7030 7031 7032 1 6 6729 6588 6589 6590 6731 7032 1 6 6730 6590 6591 6593 6732 7032 1 6 6731 6593 6733 6734 7032 7033 1 6 6732 6593 6734 6601 6600 6594 1 6 6732 6733 6601 6603 6735 7033 1 6 6734 6603 6736 7033 7034 7035 1 6 6735 6603 6737 6740 7035 7036 1 5 6736 6603 6604 6738 6740 1 7 6737 6604 6605 6739 6740 6741 6742 1 6 6738 6605 6742 6743 6744 6745 1 6 6736 6737 6738 6741 7036 7037 1 6 6740 6738 6742 7037 7038 7039 1 6 6741 6738 6739 6743 7039 7040 1 7 6742 6739 6744 7040 7041 6754 7042 1 5 6743 6739 6745 6746 7042 1 6 6744 6739 6746 6747 6748 6605 1 7 6744 6745 6747 6610 6749 6750 7042 1 6 6746 6745 6748 6607 6608 6610 1 5 6747 6745 6607 6605 6606 1 5 6746 6610 6750 6620 6611 1 7 6746 6749 6620 6626 6751 6752 7042 1 6 6750 6626 6752 6753 6629 6627 1 5 6750 6751 6753 6754 7042 1 6 6752 6751 6754 6755 6756 6629 1 7 6752 6753 6755 7041 6743 7042 7141 1 5 6754 6753 6756 7141 6759 1 6 6755 6753 6629 6630 6757 6759 1 6 6756 6630 6758 6759 6760 6761 1 6 6757 6630 6631 6761 6762 6766 1 6 6756 6757 6760 7141 6755 7142 1 6 6759 6757 6761 7142 7143 7144 1 6 6760 6757 6758 6762 6763 7144 1 6 6761 6758 6763 4559 6764 6766 1 6 6761 6762 4559 4551 7144 4550 1 6 4559 6762 4558 4565 6765 6766 1 5 4565 6764 6766 6790 6767 1 6 6765 6764 6762 6758 6631 6767 1 6 6766 6631 6632 6768 6790 6765 1 6 6767 6632 6633 6769 6773 6790 1 6 6768 6633 6634 6770 6772 6773 1 6 6769 6634 6771 6772 6777 6778 1 6 6770 6634 6778 6779 6635 9785 1 6 6769 6770 6773 6670 6774 6777 1 6 6769 6772 6670 6671 6790 6768 1 6 6670 6772 6669 6775 6776 6777 1 6 6669 6774 6776 9721 9722 9798 1 7 6775 6774 6777 6778 6780 9797 9798 1 5 6776 6774 6772 6770 6778 1 6 6777 6770 6771 6779 6780 6776 1 6 6778 6771 6780 6781 6783 9785 1 6 6778 6779 6781 6782 6776 9797 1 6 6780 6779 6782 6176 6783 6784 1 5 6780 6781 6176 6177 9797 1 6 6781 6779 6784 6785 6637 9785 1 7 6781 6783 6176 6174 6785 6786 6788 1 7 6784 6783 6786 6787 9777 6638 6637 1 6 6784 6785 6787 6788 6171 6789 1 6 6786 6785 9777 6642 9782 6789 1 5 6784 6786 6171 6172 6174 1 5 6171 6786 6170 6787 9782 1 8 6671 6673 6773 4564 4565 6765 6768 6767 1 6 5418 5419 6792 7331 7332 7333 1 6 6791 5419 5420 5428 6793 7333 1 6 6792 5428 5429 6794 7333 7334 1 6 6793 5429 5430 6795 7334 7335 1 6 6794 5430 5432 5433 6796 7335 1 6 6795 5433 5434 6797 7335 7336 1 6 6796 5434 5435 6798 7336 7337 1 6 6797 5435 5436 6799 7337 7338 1 6 6798 5436 5437 6800 7338 7339 1 6 6799 5437 5438 6801 7339 7340 1 6 6800 5438 6802 7340 7341 7342 1 6 6801 5438 5439 5440 6803 7342 1 6 6802 5440 5441 6804 7342 7343 1 6 6803 5441 5442 6805 7343 7344 1 6 6804 5442 5444 6806 7344 7345 1 6 6805 5444 5445 6807 7345 7346 1 6 6806 5445 5446 6808 7346 7347 1 6 6807 5446 6809 7347 7348 7349 1 6 6808 5446 5447 6810 7349 6811 1 5 6809 5447 5217 5218 6811 1 6 6810 5218 5219 6812 7349 6809 1 5 6811 5219 6813 7349 7350 1 6 6812 5219 5220 6814 7350 7351 1 7 6813 5220 5221 5222 6815 7351 7352 1 5 6814 5222 6816 7352 7353 1 7 6815 5222 5223 5224 6817 7353 7354 1 5 6816 5224 6818 7354 7355 2 6 6817 5224 6819 7355 7356 7357 2 6 6818 5224 5225 5226 6820 7357 2 5 6819 5226 5227 6821 7357 2 6 6820 5227 6822 7357 7358 7359 2 7 6821 5227 5228 5229 6823 7359 7360 2 5 6822 5229 6824 6825 7360 2 5 6823 5229 6825 6826 5167 2 7 6823 6824 6826 6827 6828 7362 7360 2 5 6825 6824 5167 5168 6827 2 6 6826 5168 6825 6828 6829 6830 2 6 6825 6827 6829 7362 7363 7364 2 6 6828 6827 6830 7364 7365 7366 2 6 6829 6827 5168 5169 6831 7366 2 7 6830 5169 6832 7366 7367 7368 6834 2 5 6831 5169 6833 5238 6834 2 5 6832 5169 5238 5018 5023 2 6 6832 5238 5239 6835 7368 6831 2 6 6834 5239 5648 6836 7375 7368 2 7 6835 5648 6837 7375 7374 7376 7377 2 6 6836 5648 5649 5651 6838 7377 2 6 6837 5651 6839 7377 7378 7379 2 6 6838 5651 5652 6840 6841 7379 2 6 6839 5652 5653 5247 6841 5248 2 6 6839 6840 5248 6842 7379 7380 2 6 6841 5248 5249 6843 7380 7381 2 6 6842 5249 6844 7381 7382 7383 2 6 6843 5249 5028 5029 6845 7383 2 6 6844 5029 5030 6846 6847 7383 2 6 6845 5030 6847 6848 6849 5031 2 6 6845 6846 6848 7384 7383 7385 2 6 6847 6846 6849 7385 7386 7387 2 6 6848 6846 5031 5032 6850 7387 2 6 6849 5032 5033 5034 6851 7387 2 6 6850 5034 6852 7387 7388 6854 2 6 6851 5034 5035 5038 6853 6854 2 6 6852 5038 6854 6855 6856 5039 2 6 6852 6853 6855 7388 6851 7389 2 6 6854 6853 6856 6857 6859 7389 2 6 6855 6853 5039 6857 6858 5041 2 6 6855 6856 6858 6859 6860 6861 2 6 6857 6856 5041 6861 6862 6863 2 6 6855 6857 6860 7389 7390 7397 2 6 6859 6857 6861 7397 7398 7399 2 6 6860 6857 6858 6862 7399 7400 2 6 6861 6858 6863 6864 6865 7400 2 6 6862 6858 6864 5042 6879 5041 2 6 6862 6863 6865 6866 6879 6873 2 6 6862 6864 6866 6867 7400 7401 2 6 6865 6864 6867 6868 6872 6873 2 6 6865 6866 6868 6869 7401 7402 2 6 6867 6866 6869 6870 6871 6872 2 6 6867 6868 6870 7405 7402 7406 2 6 6869 6868 6871 7412 7406 7413 2 6 6870 6868 6872 7419 7416 7413 2 6 6871 6868 6866 6873 6874 7419 2 6 6872 6866 6874 6875 6864 6879 2 6 6872 6873 6875 6876 7419 7418 2 6 6874 6873 6876 6877 6878 6879 2 6 6874 6875 6877 6883 6884 7418 2 6 6876 6875 6878 6880 6882 6883 2 6 6877 6875 6879 6880 5043 5042 2 6 6878 6875 5042 6863 6864 6873 2 6 6877 6878 5043 5045 6881 6882 2 6 6880 5045 6882 6887 6888 6889 2 6 6880 6881 6877 6883 6886 6887 2 6 6877 6882 6876 6884 6885 6886 2 6 6876 6883 6885 7418 7420 7426 2 6 6884 6883 6886 7426 7427 7428 2 6 6885 6883 6882 6887 7428 7429 2 6 6886 6882 6881 6888 7429 7430 2 6 6887 6881 6889 6890 7430 7433 2 6 6888 6881 5045 6890 4645 4644 2 6 6888 6889 4645 4646 6891 7433 2 6 6890 4646 4647 6892 7433 6893 2 6 6891 4647 4253 4254 4730 6893 2 6 6892 4730 6894 7433 6891 7432 2 6 6893 4730 4731 6895 6897 7432 2 6 6894 4731 6896 6897 6898 6899 2 6 6895 4731 4732 6899 6900 6901 2 6 6894 6895 6898 7432 7431 7434 2 6 6897 6895 6899 7434 7435 7436 2 6 6898 6895 6896 6900 7436 7437 1 6 6899 6896 6901 7437 6904 6903 2 6 6900 6896 4732 4262 6902 6903 1 6 6901 4262 4263 4264 5231 6903 1 6 6902 5231 5458 6904 6900 6901 1 6 6903 5458 5459 6905 7437 6900 1 6 6904 5459 6906 7437 7438 7439 1 6 6905 5459 5460 6907 7439 7440 1 6 6906 5460 5461 6908 7262 7440 1 6 6907 5461 5462 6909 7262 7263 1 6 6908 5462 6910 7263 7264 6911 1 6 6909 5462 5463 5464 5465 6911 1 6 6910 5465 6912 7264 6909 7265 1 6 6911 5465 5466 6913 7265 7266 1 6 6912 5466 5467 6914 7266 7267 1 6 6913 5467 6915 7267 7268 7269 1 6 6914 5467 5468 6916 6917 7269 1 6 6915 5468 5469 5470 5471 6917 1 6 6915 6916 5471 6918 7269 7270 1 6 6917 5471 5472 6919 7270 7271 1 6 6918 5472 5473 6920 7271 7272 1 6 6919 5473 5474 5475 6921 7272 1 6 6920 5475 6922 7274 7272 7275 1 6 6921 5475 5476 6923 7275 7276 1 6 6922 5476 5477 6924 7276 7277 1 6 6923 5477 5478 6925 7277 7278 1 6 6924 5478 5479 6926 7278 7279 1 6 6925 5479 5480 5654 6927 7279 1 6 6926 5654 5655 6928 7281 7279 1 6 6927 5655 6929 7281 7282 7283 1 6 6928 5655 5656 5657 6930 7283 1 6 6929 5657 6931 7283 7284 7285 1 6 6930 5657 5658 5831 6932 7285 1 6 6931 5831 6933 7285 7286 7287 1 6 6932 5831 5832 5840 6934 7287 1 6 6933 5840 5841 6935 6936 7287 1 6 6934 5841 5843 6936 6937 6018 1 6 6934 6935 6937 6938 7287 7288 1 6 6936 6935 6018 6938 6939 6940 1 6 6936 6937 6939 7288 7289 7290 1 6 6938 6937 6940 7290 7291 6941 1 6 6939 6937 6018 5845 5847 6941 1 6 6940 5847 6942 6943 7291 6939 1 6 6941 5847 6943 6944 6945 5848 1 6 6941 6942 6944 7291 7292 7293 1 6 6943 6942 6945 7293 7294 7295 1 7 6944 6942 5848 5850 6385 6946 7295 1 6 6945 6385 6386 6947 7295 7296 1 6 6946 6386 6387 6388 6948 7296 1 6 6947 6388 6389 6949 7296 7297 1 7 6948 6389 6391 6395 6950 7297 7298 1 6 6949 6395 6951 7298 7300 7301 1 6 6950 6395 6396 6952 7043 7301 1 6 6951 6396 6399 6953 7043 7044 1 6 6952 6399 6400 6954 6955 7044 1 6 6953 6400 6401 6955 6956 6960 1 6 6953 6954 6956 6957 7044 7045 1 6 6955 6954 6957 6958 6959 6960 1 6 6955 6956 6958 7045 7048 7049 1 6 6957 6956 6959 6961 6962 7049 1 6 6958 6956 6960 6410 6411 6961 1 6 6959 6956 6954 6401 6402 6410 1 6 6959 6411 6958 6962 6963 6412 1 6 6958 6961 6963 7051 7049 7052 1 6 6962 6961 6412 6414 6964 7052 1 6 6963 6414 6416 6559 6965 7052 1 6 6964 6559 6561 6966 7052 6971 1 6 6965 6561 6967 6968 6970 6971 1 6 6966 6561 6968 6969 6562 6983 1 6 6966 6967 6969 6970 6974 6975 1 6 6968 6967 6981 6975 6982 6983 1 6 6966 6968 6971 6972 6973 6974 1 6 6966 6970 6972 7052 6965 7051 1 6 6971 6970 6973 7051 7050 7053 1 6 6972 6970 6974 7062 7053 7063 1 6 6973 6970 6968 6975 6976 7063 1 6 6974 6968 6976 6977 6981 6969 1 6 6974 6975 6977 6978 7063 7064 1 6 6976 6975 6978 6979 6980 6981 1 6 6976 6977 6979 7064 7065 7066 1 6 6978 6977 6980 7066 7067 7071 1 6 6979 6977 6981 7071 7072 7073 1 6 6980 6977 6975 6969 6982 7073 1 6 6981 6969 6983 6984 7073 7074 1 6 6982 6969 6984 6985 6562 6967 1 6 6982 6983 6985 7074 7075 7076 1 6 6984 6983 6562 6563 6986 7076 1 6 6985 6563 6567 6987 6988 7076 1 6 6986 6567 6988 6989 6990 6568 1 6 6986 6987 6989 6991 7076 7077 1 6 6988 6987 6990 6991 6992 6996 1 6 6989 6987 6996 6997 6570 6568 1 6 6988 6989 6992 6993 7077 7078 1 6 6991 6989 6993 6994 6995 6996 1 6 6991 6992 6994 7078 7081 7082 1 6 6993 6992 6995 7082 7085 7086 1 6 6994 6992 6996 7086 7087 7088 1 6 6995 6992 6989 6990 6997 7088 1 6 6996 6990 6570 6998 6999 7088 1 6 6997 6570 6999 7000 7001 6571 1 6 6997 6998 7000 7088 7089 7092 1 6 6999 6998 7001 7002 7092 7093 1 6 7000 6998 7002 7003 6575 6571 1 6 7000 7001 7003 7093 7094 7095 1 6 7002 7001 6575 6576 7004 7095 1 6 7003 6576 6578 7005 7095 7096 1 6 7004 6578 7006 7096 7097 7098 1 6 7005 6578 6579 7007 7012 7098 1 6 7006 6579 6582 7008 7009 7012 1 6 7007 6582 7009 6722 6720 6583 1 6 7007 7008 6722 6724 7010 7012 1 6 7009 6724 7011 7012 7013 7014 1 6 7010 6724 7022 7020 7014 6725 1 6 7009 7010 7007 7006 7013 7098 1 6 7012 7010 7014 7015 7098 7099 1 6 7013 7010 7015 7016 7020 7011 1 6 7013 7014 7016 7017 7099 7100 1 6 7015 7014 7017 7018 7019 7020 1 6 7015 7016 7018 7107 7100 7113 1 6 7017 7016 7019 7114 7113 7115 1 6 7018 7016 7020 7021 7115 7116 1 6 7019 7016 7014 7021 7022 7011 1 6 7019 7020 7022 7024 7116 7117 1 6 7021 7020 7011 6725 7023 7024 1 6 7022 6725 6726 7024 7025 7026 1 6 7021 7022 7023 7025 7117 7118 1 6 7024 7023 7026 7118 7119 7120 1 6 7025 7023 6726 7027 7028 7120 1 6 7026 6726 6727 7028 7029 7030 1 6 7026 7027 7029 7122 7120 7123 1 6 7028 7027 7030 7123 7034 7031 1 6 7029 7027 6727 6728 6729 7031 1 6 7030 6729 7032 7034 7029 7033 1 6 7031 6729 6730 6731 6732 7033 1 6 7032 6732 6734 6735 7034 7031 1 6 7033 6735 7035 7123 7029 7031 1 5 7034 6735 6736 7036 7123 1 6 7035 6736 6740 7037 7123 7122 1 7 7036 6740 6741 7038 7122 7124 7125 1 6 7037 6741 7039 7135 7125 7136 1 6 7038 6741 6742 7040 7136 7137 1 6 7039 6742 6743 7041 7137 7138 1 5 7040 6743 6754 7141 7138 1 6 6754 6743 6744 6746 6750 6752 1 6 6951 6952 7044 7301 7302 7046 1 6 7043 6952 6953 6955 7045 7046 1 6 7044 6955 6957 7046 7047 7048 1 6 7044 7045 7047 7302 7043 7303 1 6 7046 7045 7048 7303 7056 7054 1 6 7047 7045 6957 7049 7050 7054 1 6 7048 6957 7050 7051 6962 6958 1 6 7048 7049 7051 6972 7053 7054 1 6 7050 7049 6962 7052 6971 6972 1 6 7051 6962 6963 6964 6965 6971 1 6 7050 6972 7054 7055 7062 6973 1 6 7050 7053 7055 7056 7047 7048 1 6 7054 7053 7056 7057 7058 7062 1 6 7054 7055 7057 7303 7047 7304 1 6 7056 7055 7058 7059 7307 7304 1 6 7057 7055 7059 7060 7061 7062 1 6 7057 7058 7060 7307 7476 7477 1 6 7059 7058 7061 7477 7478 7479 1 6 7060 7058 7062 7063 7064 7479 1 6 7061 7058 7055 7053 6973 7063 1 6 7062 6973 6974 6976 7061 7064 1 6 7061 7063 6976 6978 7065 7479 1 6 7064 6978 7066 7479 7480 7481 1 6 7065 6978 6979 7067 7068 7481 1 6 7066 6979 7068 7069 7070 7071 1 6 7066 7067 7069 7483 7481 7462 1 6 7068 7067 7070 7462 7484 7485 1 6 7069 7067 7071 7485 7486 7487 1 6 7070 7067 6979 6980 7072 7487 1 6 7071 6980 7073 7487 7488 7492 1 6 7072 6980 6981 6982 7074 7492 1 6 7073 6982 6984 7075 7493 7492 1 6 7074 6984 7076 7493 7079 7077 1 6 7075 6984 6985 6986 6988 7077 1 6 7076 6988 6991 7078 7079 7075 1 6 7077 6991 6993 7079 7080 7081 1 6 7077 7078 7080 7691 7493 7075 1 6 7079 7078 7081 7223 7224 7691 1 6 7080 7078 6993 7082 7083 7223 1 6 7081 6993 6994 7083 7084 7085 1 6 7081 7082 7084 7226 7223 7227 1 6 7083 7082 7085 7227 7228 7229 1 6 7084 7082 6994 7086 7232 7229 1 6 7085 6994 6995 7087 7232 7233 1 6 7086 6995 7088 7089 7090 7233 1 6 7087 6995 6996 6997 6999 7089 1 6 7088 6999 7087 7090 7091 7092 1 6 7087 7089 7091 7233 7234 7235 1 6 7090 7089 7092 7235 7236 7237 1 6 7091 7089 6999 7000 7093 7237 1 6 7092 7000 7002 7094 7237 7238 1 6 7093 7002 7095 7238 7239 7103 1 6 7094 7002 7003 7004 7096 7103 1 6 7095 7004 7005 7097 7102 7103 1 6 7096 7005 7098 7099 7101 7102 1 6 7097 7005 7006 7012 7013 7099 1 6 7098 7013 7015 7100 7101 7097 1 6 7099 7015 7101 7106 7107 7017 1 6 7099 7100 7097 7102 7105 7106 1 6 7097 7101 7096 7103 7104 7105 1 6 7096 7102 7104 7239 7094 7095 1 6 7103 7102 7105 7241 7239 7242 1 6 7104 7102 7101 7106 7242 7243 1 6 7105 7101 7100 7107 7108 7243 1 6 7106 7100 7017 7108 7109 7113 1 6 7106 7107 7109 7110 7243 7244 1 6 7108 7107 7110 7111 7112 7113 1 6 7108 7109 7111 7247 7244 7248 1 6 7110 7109 7112 7248 7249 7250 1 6 7111 7109 7113 7114 7250 7251 1 6 7112 7109 7114 7018 7017 7107 1 6 7112 7113 7018 7115 7251 7254 1 6 7114 7018 7019 7116 7254 7255 1 6 7115 7019 7021 7117 7258 7255 1 6 7116 7021 7024 7118 7258 7259 1 6 7117 7024 7025 7119 7259 7128 1 6 7118 7025 7120 7121 7127 7128 1 6 7119 7025 7121 7122 7028 7026 1 6 7119 7120 7122 7124 7126 7127 1 7 7121 7120 7028 7123 7036 7037 7124 1 6 7122 7028 7029 7034 7035 7036 1 5 7122 7037 7125 7126 7121 1 5 7124 7037 7126 7135 7038 1 7 7124 7125 7121 7127 7130 7131 7135 1 6 7121 7126 7119 7128 7129 7130 1 6 7119 7127 7129 7261 7259 7118 1 6 7128 7127 7130 7261 7532 7530 1 6 7129 7127 7126 7131 7132 7532 1 6 7130 7126 7132 7133 7134 7135 1 6 7130 7131 7133 7532 7531 7533 1 6 7132 7131 7134 7533 7534 7535 1 6 7133 7131 7135 7535 7536 7136 1 6 7134 7131 7126 7125 7038 7136 1 6 7135 7038 7039 7137 7536 7134 1 6 7136 7039 7040 7138 7139 7536 1 6 7137 7040 7139 7140 7141 7041 1 6 7137 7138 7140 7148 7150 7536 1 6 7139 7138 7141 7142 7147 7148 1 7 7140 7138 7041 6754 6755 6759 7142 1 6 7140 7141 6759 6760 7143 7147 1 6 7142 6760 7144 7145 7146 7147 1 7 7143 6760 7145 4552 4551 6763 6761 1 5 7143 7144 4552 4554 7146 1 6 7145 4554 4556 7143 7147 7148 1 5 7143 7146 7148 7140 7142 1 7 7147 7146 4556 7140 7139 7149 7150 1 6 7148 4556 7150 7151 7152 7153 1 6 7148 7149 7139 7151 7536 7535 1 6 7150 7149 7152 7535 7534 7537 1 6 7151 7149 7153 7154 7155 7537 1 6 7152 7149 7154 4649 4555 4556 1 6 7152 7153 7155 7156 7166 4649 1 6 7152 7154 7156 7157 7537 7538 1 6 7155 7154 7157 7158 7159 7166 1 6 7155 7156 7158 7538 7539 7554 1 6 7157 7156 7159 7160 7554 7555 1 6 7158 7156 7160 7161 7162 7166 1 6 7158 7159 7161 7163 7167 7555 1 6 7160 7159 7162 7163 4137 7164 1 5 7161 7159 7164 7165 7166 1 6 7160 7161 4137 7167 7168 4138 1 7 4137 7161 7162 7165 4413 4134 4135 1 5 7164 7162 4413 4415 7166 1 7 4415 7165 7162 7159 7156 7154 4649 1 6 7160 7163 7168 7555 7556 7560 1 7 7167 7163 4138 7169 7560 7561 7562 1 5 7168 4138 4139 7170 7562 2 7 7169 4139 4140 7171 7562 7563 7564 2 6 7170 4140 4124 7172 7173 7564 2 6 7171 4124 7173 7174 4122 9789 2 6 7171 7172 7174 7175 7176 7564 2 6 7173 7172 7175 9788 9787 9789 2 6 7173 7174 7176 7177 7178 9788 2 7 7173 7175 7177 7564 7563 7568 7569 2 6 7176 7175 7178 7179 7180 7569 2 6 7177 7175 7179 9788 3535 3537 2 6 7177 7178 7180 7181 7182 3537 2 6 7177 7179 7181 7570 7569 7571 2 6 7180 7179 7182 7571 7572 7573 2 6 7181 7179 3537 3538 7183 7573 2 6 7182 3538 7184 7575 7573 7187 2 6 7183 3538 3539 7185 7186 7187 2 6 7184 3539 7186 7211 7210 7212 2 6 7184 7185 7187 7188 7211 7192 2 6 7184 7186 7188 7189 7575 7183 2 6 7187 7186 7189 7190 7191 7192 2 6 7187 7188 7190 7575 7576 7579 2 6 7189 7188 7191 7193 7579 7580 2 6 7190 7188 7192 7193 7194 7198 2 6 7191 7188 7198 7199 7211 7186 2 6 7190 7191 7194 7195 7580 7581 2 6 7193 7191 7195 7196 7197 7198 2 6 7193 7194 7196 7581 7582 7583 2 6 7195 7194 7197 7583 3196 3195 2 6 7196 7194 7198 3195 7200 7203 2 6 7197 7194 7191 7192 7199 7200 2 6 7198 7192 7200 7201 7211 7208 2 6 7198 7199 7201 7202 7203 7197 2 6 7200 7199 7202 7206 7207 7208 2 6 7200 7201 7203 7204 7205 7206 2 6 7200 7202 7204 3194 3195 7197 2 6 7203 7202 7205 7220 7221 3194 2 6 7204 7202 7206 9745 7218 7220 2 6 7205 7202 7201 7207 9745 9746 2 6 7206 7201 7208 7209 9746 7213 2 6 7207 7201 7209 7210 7211 7199 2 6 7207 7208 7210 4373 4374 7213 2 6 7209 7208 7211 7185 7212 4373 2 6 7210 7208 7199 7192 7186 7185 2 6 7210 7185 3539 3540 4372 4373 2 6 7209 4374 4375 7214 9746 7207 2 6 7213 4375 4377 7215 7216 9746 2 6 7214 4377 7216 2863 1627 2862 2 6 7214 7215 2863 7217 9745 9746 2 6 7216 2863 2864 2865 7218 9745 2 6 7217 2865 7219 7220 7205 9745 2 5 7218 2865 7220 3214 2866 2 6 7218 7219 3214 7221 7205 7204 2 6 7220 3214 3215 7222 3194 7204 2 5 7221 3215 3216 3193 3194 1 6 7080 7081 7224 7225 7226 7083 1 6 7080 7223 7225 7691 7690 7692 1 6 7224 7223 7226 7692 7693 7674 1 6 7225 7223 7083 7227 7674 7694 1 6 7226 7083 7084 7228 7694 7695 1 6 7227 7084 7229 7230 7695 7696 1 6 7228 7084 7230 7231 7232 7085 1 6 7228 7229 7231 7696 7697 7701 1 6 7230 7229 7232 7701 7702 7703 1 6 7231 7229 7085 7086 7233 7703 1 6 7232 7086 7087 7090 7234 7703 1 6 7233 7090 7235 7718 7704 7703 1 6 7234 7090 7091 7236 7718 7717 1 6 7235 7091 7237 7717 7719 7720 1 6 7236 7091 7092 7093 7238 7720 1 6 7237 7093 7094 7239 7240 7720 1 6 7238 7094 7103 7240 7241 7104 1 6 7238 7239 7241 7720 7721 7722 1 6 7240 7239 7104 7242 7722 7725 1 6 7241 7104 7105 7243 7245 7725 1 6 7242 7105 7106 7108 7244 7245 1 6 7243 7108 7245 7246 7247 7110 1 6 7243 7244 7246 7728 7725 7242 1 6 7245 7244 7247 7964 7728 7965 1 6 7246 7244 7110 7248 7965 7966 1 6 7247 7110 7111 7249 7966 7967 1 6 7248 7111 7250 7511 7967 7968 1 6 7249 7111 7112 7251 7252 7511 1 6 7250 7112 7114 7252 7253 7254 1 6 7250 7251 7253 7511 7512 7516 1 6 7252 7251 7254 7256 9775 7516 1 6 7253 7251 7114 7115 7255 7256 1 6 7254 7115 7256 7257 7258 7116 1 6 7254 7255 7257 7523 7253 9775 1 6 7256 7255 7258 7260 7524 7523 1 6 7257 7255 7116 7117 7259 7260 1 6 7258 7117 7118 7260 7261 7128 1 6 7258 7259 7261 7529 7524 7257 1 6 7260 7259 7128 7129 7530 7529 1 6 6907 6908 7263 7440 7442 7443 1 6 7262 6908 6909 7264 7443 7444 1 6 7263 6909 6911 7265 7444 7445 1 6 7264 6911 6912 7266 7445 7446 1 6 7265 6912 6913 7267 7449 7446 1 6 7266 6913 6914 7268 7449 7450 1 6 7267 6914 7269 7450 7451 7452 1 6 7268 6914 6915 6917 7270 7452 1 6 7269 6917 6918 7271 7452 7453 1 6 7270 6918 6919 7272 7273 7453 1 6 7271 6919 7273 7274 6921 6920 1 6 7271 7272 7274 7453 7454 7455 1 6 7273 7272 6921 7275 7455 7456 1 6 7274 6921 6922 7276 7456 7457 1 6 7275 6922 6923 7277 7457 7458 1 6 7276 6923 6924 7278 7458 7459 1 6 7277 6924 6925 7279 7280 7459 1 6 7278 6925 7280 7281 6927 6926 1 6 7278 7279 7281 7459 7460 7464 1 6 7280 7279 6927 6928 7282 7464 1 6 7281 6928 7283 7464 7465 7466 1 6 7282 6928 6929 6930 7284 7466 1 6 7283 6930 7285 7466 7467 7468 1 6 7284 6930 6931 6932 7286 7468 1 6 7285 6932 7287 7468 7469 7288 1 6 7286 6932 6933 6934 6936 7288 1 6 7287 6936 6938 7289 7469 7286 1 6 7288 6938 7290 7469 7470 7471 1 6 7289 6938 6939 7291 7471 7472 1 6 7290 6939 6941 6943 7292 7472 1 6 7291 6943 7293 7472 7473 7474 1 6 7292 6943 6944 7294 7474 7299 1 6 7293 6944 7295 7297 7298 7299 1 6 7294 6944 6945 6946 7296 7297 1 5 7295 6946 6947 6948 7297 1 6 7296 6948 6949 7295 7294 7298 1 6 7294 7297 6949 6950 7299 7300 1 5 7294 7298 7300 7474 7293 1 7 7299 7298 6950 7301 7474 7305 7302 1 5 7300 6950 6951 7043 7302 1 6 7301 7043 7046 7303 7305 7300 1 6 7302 7046 7047 7056 7304 7305 1 6 7303 7056 7305 7306 7307 7057 1 6 7303 7304 7306 7474 7300 7302 1 6 7305 7304 7307 7474 7473 7475 1 6 7306 7304 7057 7059 7475 7476 1 5 4702 4703 7309 7855 7856 1 6 7308 4703 4704 7310 7856 7857 1 6 7309 4704 4705 7311 7857 7858 1 6 7310 4705 4706 7312 7858 7859 1 6 7311 4706 4707 5170 7313 7859 1 6 7312 5170 7314 7859 7860 7861 1 6 7313 5170 5171 7315 7861 7862 1 6 7314 5171 5172 7316 7862 7863 1 6 7315 5172 5173 7317 7863 7864 1 6 7316 5173 5174 7318 7864 7865 1 6 7317 5174 5175 7319 7865 7866 1 6 7318 5175 5176 7320 7866 7867 1 6 7319 5176 5177 5178 7321 7867 1 6 7320 5178 7322 7867 7868 7869 1 6 7321 5178 5179 7323 7869 7870 1 6 7322 5179 5180 5411 7324 7870 1 6 7323 5411 7325 7870 7871 7872 1 6 7324 5411 5412 7326 7872 7873 1 6 7325 5412 5413 5414 7327 7873 1 6 7326 5414 7328 7873 7874 7875 1 6 7327 5414 5415 5416 7329 7875 1 6 7328 5416 7330 7875 7876 7877 1 6 7329 5416 5417 5418 7331 7877 1 6 7330 5418 6791 7332 7877 7878 1 6 7331 6791 7333 7878 7879 7880 1 6 7332 6791 6792 6793 7334 7880 1 6 7333 6793 6794 7335 7880 7881 1 6 7334 6794 6795 6796 7336 7881 1 6 7335 6796 6797 7337 7881 7882 1 6 7336 6797 6798 7338 7882 7883 1 6 7337 6798 6799 7339 7883 7884 1 6 7338 6799 6800 7340 7884 7885 1 6 7339 6800 6801 7341 7885 7886 1 6 7340 6801 7342 7886 7887 7888 1 6 7341 6801 6802 6803 7343 7888 1 6 7342 6803 6804 7344 7888 7889 1 6 7343 6804 6805 7345 7889 7890 1 6 7344 6805 6806 7346 7890 7891 1 6 7345 6806 6807 7347 7891 7892 1 6 7346 6807 6808 7348 7892 7893 1 6 7347 6808 7349 7893 7894 7895 1 7 7348 6808 6809 6811 6812 7350 7895 1 6 7349 6812 6813 7351 7895 7896 1 6 7350 6813 6814 7352 7896 7897 1 5 7351 6814 6815 7353 7897 1 7 7352 6815 6816 7354 7897 7898 7899 1 5 7353 6816 6817 7355 7899 2 7 7354 6817 6818 7356 7899 7900 7901 2 6 7355 6818 7357 7901 7902 7903 2 7 7356 6818 6819 6820 6821 7358 7903 2 6 7357 6821 7359 7903 7904 7905 2 6 7358 6821 6822 7360 7361 7905 2 6 7359 6822 6823 7361 7362 6825 2 6 7359 7360 7362 7905 7906 7907 2 6 7361 7360 6825 6828 7363 7907 2 6 7362 6828 7364 7907 7908 7909 2 5 7363 6828 6829 7365 7909 2 7 7364 6829 7366 7369 7371 7909 7910 2 6 7365 6829 6830 6831 7367 7369 2 6 7366 6831 7368 7369 7370 7375 2 5 7367 6831 7375 6835 6834 2 6 7366 7367 7370 7365 7371 7372 2 6 7369 7367 7372 7373 7374 7375 2 6 7365 7369 7372 7910 7911 7912 2 6 7371 7369 7370 7373 7912 7913 2 6 7372 7370 7374 7913 7914 7915 2 6 7373 7370 7375 6836 7376 7915 2 6 7374 7370 7367 7368 6835 6836 2 6 7374 6836 7377 7915 7916 7917 2 6 7376 6836 6837 6838 7378 7917 2 5 7377 6838 7379 7601 7917 2 6 7378 6838 6839 6841 7380 7601 2 6 7379 6841 6842 7381 7601 7602 2 6 7380 6842 6843 7382 7605 7602 2 6 7381 6843 7383 7384 7605 7606 2 6 7382 6843 7384 6847 6845 6844 2 6 7382 7383 6847 7385 7606 7607 2 6 7384 6847 6848 7386 7607 7392 2 6 7385 6848 7387 7388 7391 7392 2 6 7386 6848 6849 6850 6851 7388 2 6 7387 6851 6854 7389 7391 7386 2 6 7388 6854 6855 6859 7390 7391 2 6 7389 6859 7391 7396 7393 7397 2 6 7389 7390 7388 7386 7392 7393 2 6 7386 7391 7393 7394 7607 7385 2 6 7392 7391 7394 7395 7396 7390 2 6 7392 7393 7395 7607 7608 7611 2 6 7394 7393 7396 7611 7612 7622 2 6 7395 7393 7390 7397 7622 7623 2 6 7396 7390 6859 6860 7398 7623 2 5 7397 6860 7399 7623 7624 2 6 7398 6860 6861 7400 7624 7625 2 7 7399 6861 6862 6865 7401 7625 7626 2 6 7400 6865 6867 7402 7403 7626 2 6 7401 6867 7403 7404 7405 6869 2 6 7401 7402 7404 7626 7627 7628 2 6 7403 7402 7405 7408 7628 7629 2 6 7404 7402 6869 7406 7407 7408 2 6 7405 6869 7407 7411 7412 6870 2 6 7405 7406 7408 7409 7410 7411 2 6 7405 7407 7404 7409 7632 7629 2 6 7408 7407 7410 7632 7633 7634 2 6 7409 7407 7411 7634 7635 7642 2 6 7410 7407 7406 7412 7642 7643 2 6 7411 7406 6870 7413 7414 7643 2 6 7412 6870 7414 7415 7416 6871 2 6 7412 7413 7415 7643 7644 7645 2 6 7414 7413 7416 7417 7645 7646 2 6 7415 7413 7417 7418 7419 6871 2 6 7415 7416 7418 7420 7421 7646 2 7 7417 7416 7419 6874 6876 6884 7420 2 5 7418 7416 6871 6872 6874 2 6 7418 6884 7417 7421 7422 7426 2 6 7417 7420 7422 7423 7646 7647 2 6 7421 7420 7423 7424 7425 7426 1 6 7421 7422 7424 7647 7648 7649 1 6 7423 7422 7425 7649 7650 7651 2 6 7424 7422 7426 7651 7652 7427 2 6 7425 7422 7420 6884 6885 7427 2 6 7426 6885 7428 7652 7425 7653 2 6 7427 6885 6886 7429 7653 7654 2 6 7428 6886 6887 7430 7431 7654 2 6 7429 6887 6888 7431 7432 7433 2 6 7429 7430 7432 6897 7434 7654 2 6 7431 7430 7433 6893 6894 6897 2 6 7432 7430 6888 6890 6891 6893 2 6 7431 6897 6898 7435 7655 7654 2 6 7434 6898 7436 7655 7656 7660 1 6 7435 6898 6899 7437 7660 7438 1 6 7436 6899 6900 6904 6905 7438 1 6 7437 6905 7439 7660 7436 7661 1 6 7438 6905 6906 7440 7441 7661 1 6 7439 6906 6907 7262 7441 7442 1 6 7439 7440 7442 7661 7662 7663 1 6 7441 7440 7262 7443 7663 7664 1 6 7442 7262 7263 7444 7664 7665 1 6 7443 7263 7264 7445 7665 7666 1 6 7444 7264 7265 7446 7447 7666 1 6 7445 7265 7447 7448 7449 7266 1 6 7445 7446 7448 7668 7666 7671 1 6 7447 7446 7449 7671 7676 7673 1 6 7448 7446 7266 7267 7450 7676 1 6 7449 7267 7268 7451 7676 7677 1 6 7450 7268 7452 7677 7678 7682 1 6 7451 7268 7269 7270 7453 7682 1 6 7452 7270 7271 7273 7454 7682 1 6 7453 7273 7455 7682 7681 7683 1 6 7454 7273 7274 7456 7686 7683 1 6 7455 7274 7275 7457 7686 7687 1 6 7456 7275 7276 7458 7687 7688 1 6 7457 7276 7277 7459 7688 7461 1 6 7458 7277 7278 7280 7460 7461 1 6 7459 7280 7461 7462 7463 7464 1 6 7459 7460 7462 7688 7458 7484 1 7 7461 7460 7463 7483 7068 7069 7484 1 6 7462 7460 7464 7483 7482 7465 1 6 7463 7460 7280 7281 7282 7465 1 6 7464 7282 7466 7482 7463 7494 1 6 7465 7282 7283 7284 7467 7494 1 6 7466 7284 7468 7494 7495 7496 1 6 7467 7284 7285 7286 7469 7496 1 6 7468 7286 7288 7289 7470 7496 1 6 7469 7289 7471 7496 7497 7498 1 6 7470 7289 7290 7472 7498 7475 1 6 7471 7290 7291 7292 7473 7475 1 5 7472 7292 7474 7306 7475 1 7 7473 7292 7293 7299 7300 7305 7306 1 7 7473 7306 7307 7476 7498 7471 7472 1 5 7475 7307 7059 7477 7498 1 6 7476 7059 7060 7478 7497 7498 1 7 7477 7060 7479 7480 7497 7495 7499 1 6 7478 7060 7061 7064 7065 7480 1 6 7478 7479 7065 7481 7482 7499 1 6 7480 7065 7482 7483 7068 7066 1 7 7480 7481 7483 7463 7465 7494 7499 1 5 7482 7481 7068 7462 7463 1 5 7462 7069 7485 7688 7461 1 6 7484 7069 7070 7486 7687 7688 1 6 7485 7070 7487 7686 7687 7685 1 7 7486 7070 7071 7072 7488 7489 7685 1 6 7487 7072 7489 7490 7491 7492 1 5 7487 7488 7490 7685 7684 1 6 7489 7488 7491 7684 7689 7690 1 6 7490 7488 7492 7493 7690 7691 1 6 7491 7488 7493 7074 7073 7072 1 6 7491 7492 7074 7075 7691 7079 1 6 7482 7465 7466 7467 7495 7499 1 6 7494 7467 7496 7497 7478 7499 1 6 7495 7467 7468 7469 7470 7497 1 6 7496 7470 7498 7477 7478 7495 1 6 7497 7470 7471 7477 7476 7475 1 5 7495 7478 7480 7482 7494 1 6 427 5612 5613 7501 7502 9768 1 6 7500 5613 7502 7503 7504 7505 1 6 7500 7501 7503 9768 9769 9770 1 6 7502 7501 7504 6474 9770 9780 1 5 7503 7501 6474 6472 7505 1 7 6472 7504 7501 5613 5614 7506 6470 1 5 7505 5614 7507 6469 6470 1 6 7506 5614 5615 7508 7509 6469 1 6 7507 5615 7509 7510 9734 4518 1 5 7507 7508 7510 6469 6468 1 6 7509 7508 6468 9732 9733 9734 1 6 7249 7250 7252 7512 7513 7968 1 6 7511 7252 7513 7514 7515 7516 1 6 7511 7512 7514 7968 7969 7970 1 6 7513 7512 7515 7970 7971 7972 1 6 7514 7512 7516 7517 7518 7972 1 6 7515 7512 7252 7517 9775 7253 1 6 7515 7516 7518 7519 7520 9775 1 6 7515 7517 7519 7972 7973 7977 1 6 7518 7517 7520 7521 7977 7978 1 6 7519 7517 7521 7522 7523 9775 1 6 7519 7520 7522 7989 7978 7526 1 6 7521 7520 7523 7524 7525 7526 1 6 7522 7520 7524 7256 7257 9775 1 6 7522 7523 7525 7260 7529 7257 1 6 7522 7524 7526 7527 7528 7529 1 6 7522 7525 7527 7989 7521 7990 1 6 7526 7525 7528 7990 7546 7545 1 6 7527 7525 7529 7530 7531 7545 1 6 7528 7525 7530 7261 7260 7524 1 6 7528 7529 7261 7531 7532 7129 1 7 7528 7530 7532 7132 7533 7543 7545 1 5 7531 7530 7129 7130 7132 1 6 7531 7132 7133 7534 7544 7543 1 6 7533 7133 7535 7151 7537 7544 1 6 7534 7133 7134 7536 7150 7151 1 6 7535 7134 7136 7137 7139 7150 1 6 7534 7151 7152 7155 7538 7544 1 6 7537 7155 7157 7539 7540 7544 1 6 7538 7157 7540 7541 7553 7554 1 6 7538 7539 7541 7542 7543 7544 1 6 7540 7539 7542 7547 7553 7550 1 6 7540 7541 7543 7545 7546 7547 1 6 7540 7542 7544 7533 7531 7545 1 6 7540 7543 7533 7534 7537 7538 1 6 7531 7543 7542 7546 7527 7528 1 6 7545 7542 7547 7548 7990 7527 1 6 7546 7542 7541 7548 7549 7550 1 6 7546 7547 7549 7990 7989 7991 1 6 7548 7547 7550 7551 7991 7992 1 6 7549 7547 7551 7552 7553 7541 1 6 7549 7550 7552 7992 7994 7995 1 7 7551 7550 7553 7557 7556 7558 7995 1 6 7552 7550 7541 7539 7554 7557 1 6 7553 7539 7157 7158 7555 7557 1 6 7554 7158 7160 7167 7556 7557 1 7 7555 7167 7557 7552 7558 7559 7560 1 5 7555 7556 7554 7553 7552 2 5 7552 7556 7559 7995 7996 2 7 7558 7556 7560 7996 7999 7566 7561 1 5 7559 7556 7167 7168 7561 2 6 7560 7168 7562 7565 7566 7559 2 6 7561 7168 7169 7170 7563 7565 2 6 7562 7170 7564 7176 7565 7568 2 5 7563 7170 7171 7173 7176 2 6 7562 7563 7561 7566 7567 7568 2 6 7561 7565 7567 7999 7559 8000 2 6 7566 7565 7568 7569 7570 8000 2 5 7567 7565 7563 7176 7569 2 6 7568 7176 7567 7570 7180 7177 2 6 7567 7569 7180 7571 8000 8001 2 6 7570 7180 7181 7572 8001 8002 2 6 7571 7181 7573 7574 8002 8003 2 6 7572 7181 7574 7575 7183 7182 2 6 7572 7573 7575 7576 7577 8003 2 6 7574 7573 7183 7187 7189 7576 2 6 7575 7189 7574 7577 7578 7579 2 6 7574 7576 7578 8003 8004 8005 2 6 7577 7576 7579 8005 8006 8007 2 6 7578 7576 7189 7190 7580 8007 2 6 7579 7190 7193 7581 8007 8008 2 6 7580 7193 7195 7582 8008 8009 2 6 7581 7195 7583 7585 8012 8009 2 6 7582 7195 7196 3196 7584 7585 2 6 7583 3196 3186 7585 7586 3187 2 6 7583 7584 7586 7587 7582 8012 2 6 7585 7584 7587 7588 3958 3187 2 6 7585 7586 7588 7729 8013 8012 2 6 7587 7586 3958 3960 7589 7729 2 6 7588 3960 7590 7729 7730 7731 2 6 7589 3960 3961 7591 7731 7732 2 6 7590 3961 7592 7738 7732 7739 2 6 7591 3961 2890 2891 7593 7739 2 6 7592 2891 7594 7595 7739 7740 2 6 7593 2891 7595 7596 7597 2892 2 6 7593 7594 7596 7740 7741 7745 2 6 7595 7594 7597 7598 7745 7746 2 6 7596 7594 7598 7599 7600 2892 2 6 7596 7597 7599 4089 7746 7751 2 5 7598 7597 7600 4089 4086 2 6 7599 7597 4086 2880 2879 2892 2 7 7378 7379 7380 7602 7603 7917 7918 2 6 7601 7380 7603 7604 7605 7381 2 6 7601 7602 7604 7926 7920 7918 2 5 7603 7602 7605 7926 7927 2 7 7604 7602 7381 7382 7606 7609 7927 2 6 7605 7382 7384 7607 7608 7609 2 6 7606 7384 7385 7392 7394 7608 2 6 7607 7394 7606 7609 7610 7611 2 6 7606 7608 7610 7929 7927 7605 2 6 7609 7608 7611 7613 7616 7929 2 6 7610 7608 7394 7395 7612 7613 2 6 7611 7395 7613 7614 7621 7622 2 6 7611 7612 7614 7615 7616 7610 2 6 7613 7612 7615 7619 7620 7621 2 6 7613 7614 7616 7617 7618 7619 2 6 7613 7615 7617 8157 7929 7610 2 6 7616 7615 7618 8155 8157 8156 2 6 7617 7615 7619 8156 8158 8159 2 6 7618 7615 7614 7620 8159 8160 2 6 7619 7614 7621 8160 8161 8162 2 6 7620 7614 7612 7622 8162 8163 2 6 7621 7612 7395 7396 7623 8163 2 6 7622 7396 7397 7398 7624 8163 2 6 7623 7398 7399 7625 8163 8164 2 6 7624 7399 7400 7626 8164 7627 2 5 7625 7400 7401 7403 7627 2 6 7626 7403 7628 8164 7625 8165 2 6 7627 7403 7404 7629 7630 8165 2 6 7628 7404 7630 7631 7632 7408 2 6 7628 7629 7631 8165 8166 8167 2 6 7630 7629 7632 8170 8167 8171 2 6 7631 7629 7408 7409 7633 8171 2 6 7632 7409 7634 8173 8171 8174 2 6 7633 7409 7410 7635 7636 8174 2 6 7634 7410 7636 7637 7641 7642 2 6 7634 7635 7637 7638 8174 8175 2 6 7636 7635 7638 7639 7640 7641 2 6 7636 7637 7639 8175 8176 8177 2 6 7638 7637 7640 8177 8178 8179 2 6 7639 7637 7641 8179 8180 8181 2 6 7640 7637 7635 7642 8181 8182 2 6 7641 7635 7410 7411 7643 8182 2 6 7642 7411 7412 7414 7644 8182 2 6 7643 7414 7645 8183 8182 8184 2 6 7644 7414 7415 7646 8184 8185 2 6 7645 7415 7417 7421 7647 8185 1 6 7646 7421 7423 7648 8185 8186 1 6 7647 7423 7649 8186 8187 8188 1 6 7648 7423 7424 7650 8188 8189 1 6 7649 7424 7651 8189 8190 8191 1 6 7650 7424 7425 7652 8191 8192 2 6 7651 7425 7427 7653 8192 7657 2 6 7652 7427 7428 7654 7655 7657 2 6 7653 7428 7429 7655 7434 7431 2 6 7653 7654 7434 7435 7656 7657 2 6 7655 7435 7657 7658 7659 7660 2 6 7655 7656 7658 8192 7652 7653 1 6 7657 7656 7659 8192 8193 8194 1 6 7658 7656 7660 8194 7662 7661 1 6 7659 7656 7435 7436 7438 7661 1 6 7660 7438 7439 7441 7662 7659 1 6 7661 7441 7663 8194 7659 8195 1 6 7662 7441 7442 7664 8208 8195 1 6 7663 7442 7443 7665 8208 8207 1 6 7664 7443 7444 7666 7667 8207 1 6 7665 7444 7667 7668 7447 7445 1 6 7665 7666 7668 7669 8206 8207 1 6 7667 7666 7447 7669 7670 7671 1 6 7667 7668 7670 7698 8206 9790 1 6 7669 7668 7671 7672 7695 9790 1 6 7670 7668 7447 7448 7672 7673 1 6 7670 7671 7673 7674 7695 7694 1 6 7672 7671 7674 7675 7676 7448 1 7 7672 7673 7675 7693 7225 7226 7694 1 6 7674 7673 7676 7677 7679 7693 1 6 7675 7673 7448 7449 7450 7677 1 6 7676 7450 7451 7678 7679 7675 1 6 7677 7451 7679 7680 7681 7682 1 7 7677 7678 7680 7675 7693 7692 7689 1 5 7679 7678 7681 7689 7684 1 6 7680 7678 7682 7454 7683 7684 1 6 7681 7678 7451 7452 7453 7454 1 6 7681 7454 7684 7685 7686 7455 1 7 7681 7683 7685 7489 7490 7689 7680 1 6 7684 7683 7686 7486 7487 7489 1 6 7685 7683 7455 7456 7687 7486 1 6 7686 7456 7457 7486 7485 7688 1 6 7485 7687 7457 7458 7461 7484 1 6 7684 7490 7690 7692 7679 7680 1 6 7689 7490 7491 7691 7224 7692 1 6 7690 7491 7493 7079 7080 7224 1 6 7690 7224 7225 7693 7679 7689 1 5 7692 7225 7674 7675 7679 1 5 7674 7226 7227 7695 7672 1 7 7694 7227 7228 7696 7670 7672 9790 1 6 7695 7228 7230 7697 7698 9790 1 6 7696 7230 7698 7699 7700 7701 1 6 7696 7697 7699 8206 7669 9790 1 6 7698 7697 7700 8205 8203 8206 1 6 7699 7697 7701 8318 8205 7707 1 6 7700 7697 7230 7231 7702 7707 1 6 7701 7231 7703 7704 7705 7707 1 6 7702 7231 7704 7234 7233 7232 1 6 7702 7703 7705 7706 7718 7234 1 6 7702 7704 7706 7707 7708 7709 1 6 7705 7704 7709 7710 7711 7718 1 6 7702 7705 7708 8318 7700 7701 1 6 7707 7705 7709 8318 8481 8317 1 6 7708 7705 7706 7710 8481 8482 1 6 7709 7706 7711 7712 7713 8482 1 6 7710 7706 7712 7716 7717 7718 1 6 7710 7711 7713 7714 7715 7716 1 6 7710 7712 7714 8482 8483 8484 1 6 7713 7712 7715 8484 9765 8486 1 6 7714 7712 7716 9765 7723 9767 1 6 7715 7712 7711 7717 9767 7719 1 6 7716 7711 7718 7235 7236 7719 1 6 7717 7711 7706 7704 7234 7235 1 6 7717 7236 7720 9767 7716 7721 1 6 7719 7236 7237 7238 7240 7721 1 6 7720 7240 7722 7723 9767 7719 1 6 7721 7240 7241 7723 7724 7725 1 7 7721 7722 7724 7726 9765 7715 9767 1 6 7723 7722 7725 7726 7727 7728 1 6 7724 7722 7728 7245 7242 7241 1 6 7723 7724 7727 7962 9765 9764 1 6 7726 7724 7728 7962 7963 7964 1 6 7727 7724 7725 7245 7964 7246 2 6 7587 7588 7589 7730 8013 8014 2 6 7729 7589 7731 8014 8015 7734 2 6 7730 7589 7590 7732 7733 7734 2 6 7731 7590 7733 7737 7738 7591 2 6 7731 7732 7734 7735 7736 7737 2 6 7731 7733 7735 8015 7730 8016 2 6 7734 7733 7736 8016 8017 8018 2 6 7735 7733 7737 8018 8019 8020 2 6 7736 7733 7732 7738 8020 8021 2 6 7737 7732 7591 7739 9766 8021 2 6 7738 7591 7592 7593 7740 9766 2 6 7739 7593 7595 7741 7742 9766 2 6 7740 7595 7742 7743 7744 7745 2 6 7740 7741 7743 8025 8023 9766 2 6 7742 7741 7744 8025 8026 8027 2 6 7743 7741 7745 7747 7748 8027 2 6 7744 7741 7595 7596 7746 7747 2 6 7745 7596 7598 7747 7750 7751 2 6 7745 7746 7744 7748 7749 7750 2 6 7744 7747 7749 8027 8031 8032 2 6 7748 7747 7750 8032 8036 7759 2 6 7749 7747 7746 7751 7752 7759 2 7 7750 7746 7598 4089 4090 7752 7753 2 7 7750 7751 7753 4379 7754 7758 7759 2 4 7752 7751 4090 4379 2 5 7752 4379 4380 7755 7758 2 6 7754 4380 4382 7756 7757 7758 2 6 7755 4382 7757 7762 7763 7764 2 6 7755 7756 7758 7760 7761 7762 2 6 7755 7757 7754 7752 7759 7760 2 6 7752 7758 7760 8036 7749 7750 2 5 7759 7758 7757 7761 8036 2 7 7760 7757 7762 8036 8640 8635 8035 2 7 7761 7757 7756 7763 8852 8639 8640 2 6 7762 7756 7764 7765 8852 8853 2 6 7763 7756 4382 4383 4389 7765 2 6 7763 7764 4389 7766 8319 8853 2 6 7765 4389 4390 7767 8319 8320 2 6 7766 4390 3142 7768 7769 8320 2 6 7767 3142 7769 7770 7774 3143 2 6 7767 7768 7770 7771 8322 8320 2 6 7769 7768 7771 7772 7773 7774 2 6 7769 7770 7772 8322 8323 8324 2 6 7771 7770 7773 8324 8325 7777 2 6 7772 7770 7774 7775 7776 7777 2 6 7773 7770 7768 3143 3144 7775 2 6 7774 3144 7773 7776 3145 9791 2 6 7773 7775 7777 7778 3414 9791 2 6 7773 7776 7778 8325 7772 8326 2 6 7777 7776 3414 3415 7779 8326 2 6 7778 3415 5382 5384 7780 8326 2 6 7779 5384 5386 7781 8326 8327 2 6 7780 5386 5388 7782 8329 8327 2 6 7781 5388 5616 7783 8329 8330 2 6 7782 5616 7784 8330 8331 8332 2 6 7783 5616 5617 7785 8037 8332 2 6 7784 5617 7786 7787 8037 8038 2 6 7785 5617 5618 7787 7788 7789 2 6 7785 7786 7788 8038 8039 8040 2 6 7787 7786 7789 8045 8040 7794 2 6 7788 7786 5618 5619 7790 7794 2 6 7789 5619 7791 7792 7793 7794 2 6 7790 5619 7792 3779 3778 5620 2 6 7790 7791 7793 7797 7798 3779 2 6 7790 7792 7794 7795 7796 7797 2 6 7790 7793 7795 8045 7788 7789 2 6 7794 7793 7796 8045 8046 8047 2 6 7795 7793 7797 8048 8047 8049 2 6 7796 7793 7792 7798 8049 7799 2 6 7797 7792 3779 3780 3783 7799 2 6 7798 3783 3784 7800 8049 7797 2 6 7799 3784 3785 3788 7801 8049 2 6 7800 3788 3790 7802 8048 8049 2 6 7801 3790 3791 3793 7803 8048 2 6 7802 3793 7804 7806 8047 8048 2 6 7803 3793 3794 7805 7806 7807 2 6 7804 3794 7807 7808 7809 3795 2 6 7803 7804 7807 8046 8047 8343 2 6 7806 7804 7805 7808 8344 8343 2 6 7807 7805 7809 8344 8345 7930 2 6 7808 7805 3795 3796 7810 7930 1 6 7809 3796 3952 7811 7930 7931 1 6 7810 3952 7812 7931 7932 7936 1 6 7811 3952 3953 7813 7936 7937 1 6 7812 3953 3954 7814 7937 7938 1 6 7813 3954 7815 7938 7939 7816 1 6 7814 3954 3955 3956 4238 7816 1 6 7815 4238 4503 7817 7939 7814 1 6 7816 4503 4504 7818 7939 7940 1 6 7817 4504 7819 7940 7941 7942 1 6 7818 4504 4505 7820 7942 7943 1 6 7819 4505 4506 4507 7821 7943 1 6 7820 4507 7822 7943 7944 7945 1 6 7821 4507 4508 7823 7945 7946 1 6 7822 4508 4509 7824 7946 7947 1 6 7823 4509 7825 7826 7947 7948 1 6 7824 4509 4510 7826 7827 7828 1 6 7824 7825 7827 7948 7949 7950 1 6 7826 7825 7828 7950 7951 7952 1 6 7827 7825 4510 4419 7829 7952 1 6 7828 4419 4247 7830 7952 7832 1 6 7829 4247 4248 4739 7831 7832 1 6 7830 4739 5003 7832 7833 7834 1 6 7830 7831 7833 7952 7829 7953 1 6 7832 7831 7834 7953 7954 7955 1 6 7833 7831 5003 5004 7835 7955 1 6 7834 5004 5005 7836 7955 7956 1 6 7835 5005 7837 7956 7957 7958 1 6 7836 5005 4750 4751 7838 7958 1 6 7837 4751 4757 7839 7958 7959 1 6 7838 4757 7840 7959 7960 7846 1 6 7839 4757 4758 7841 7846 7961 1 6 7840 4758 4661 4662 7842 7961 1 6 7841 4662 4663 4689 7843 7961 1 6 7842 4689 4690 7844 7961 7845 1 6 7843 4690 4691 5158 5159 7845 1 5 7844 5159 7846 7961 7843 1 7 7845 5159 7847 7960 7839 7840 7961 1 6 7846 5159 5160 7848 8082 7960 1 6 7847 5160 5161 7849 8082 8083 1 6 7848 5161 5162 7850 8083 8084 1 6 7849 5162 7851 8084 8085 8086 1 6 7850 5162 5163 5164 7852 8086 1 6 7851 5164 7853 8086 8087 8088 1 6 7852 5164 5165 7854 8088 8089 1 7 7853 5165 4700 4701 4702 7855 8089 1 5 7854 4702 7308 7856 8089 1 7 7855 7308 7309 7857 8089 8090 8091 1 7 7856 7309 7310 7858 8091 8092 8093 1 6 7857 7310 7311 7859 8093 8094 1 6 7858 7311 7312 7313 7860 8094 1 6 7859 7313 7861 8094 8095 8096 1 6 7860 7313 7314 7862 8096 8097 1 6 7861 7314 7315 7863 8097 8098 1 6 7862 7315 7316 7864 8098 8099 1 6 7863 7316 7317 7865 8099 8100 1 6 7864 7317 7318 7866 8100 8101 1 6 7865 7318 7319 7867 8101 8102 1 6 7866 7319 7320 7321 7868 8102 1 6 7867 7321 7869 8102 8103 8104 1 6 7868 7321 7322 7870 8104 8105 1 6 7869 7322 7323 7324 7871 8105 1 6 7870 7324 7872 8105 8106 8107 1 6 7871 7324 7325 7873 8107 8108 1 6 7872 7325 7326 7327 7874 8108 1 6 7873 7327 7875 8108 8109 8110 1 6 7874 7327 7328 7329 7876 8110 1 6 7875 7329 7877 8110 8111 8112 1 6 7876 7329 7330 7331 7878 8112 1 6 7877 7331 7332 7879 8112 8113 1 6 7878 7332 7880 8113 8114 8115 1 6 7879 7332 7333 7334 7881 8115 1 6 7880 7334 7335 7336 7882 8115 1 6 7881 7336 7337 7883 8115 8116 1 7 7882 7337 7338 7884 8116 8117 8118 1 6 7883 7338 7339 7885 8118 8119 1 6 7884 7339 7340 7886 8119 8120 1 6 7885 7340 7341 7887 8120 8121 1 6 7886 7341 7888 8121 8122 8123 1 6 7887 7341 7342 7343 7889 8123 1 6 7888 7343 7344 7890 8123 8124 1 6 7889 7344 7345 7891 8124 8125 1 6 7890 7345 7346 7892 8125 8126 1 6 7891 7346 7347 7893 8126 8127 1 6 7892 7347 7348 7894 8127 8128 1 6 7893 7348 7895 8128 8129 8130 1 6 7894 7348 7349 7350 7896 8130 1 6 7895 7350 7351 7897 8130 8131 1 7 7896 7351 7352 7353 7898 8131 8132 1 5 7897 7353 7899 8132 8133 1 7 7898 7353 7354 7355 7900 8133 8134 2 6 7899 7355 7901 8134 8135 8136 2 5 7900 7355 7356 7902 8136 2 7 7901 7356 7903 8136 8137 8138 7904 2 5 7902 7356 7357 7358 7904 2 6 7903 7358 7905 8138 7902 8139 2 6 7904 7358 7359 7361 7906 8139 2 6 7905 7361 7907 8139 8140 8141 2 6 7906 7361 7362 7363 7908 8141 2 6 7907 7363 7909 8141 8142 8143 2 6 7908 7363 7364 7365 7910 8143 2 6 7909 7365 7371 7911 8143 8144 2 6 7910 7371 7912 8144 8145 8146 2 5 7911 7371 7372 7913 8146 2 7 7912 7372 7373 7914 8146 8147 8148 2 6 7913 7373 7915 8148 8149 8150 2 6 7914 7373 7374 7376 7916 8150 2 6 7915 7376 7917 7918 7919 8150 2 6 7916 7376 7377 7378 7601 7918 2 6 7917 7601 7916 7919 7920 7603 2 6 7916 7918 7920 7921 7922 8150 2 6 7919 7918 7921 7925 7926 7603 2 6 7919 7920 7922 7923 7924 7925 2 6 7919 7921 7923 8150 8151 8149 2 6 7922 7921 7924 8151 8152 8153 2 6 7923 7921 7925 8153 8154 8155 2 6 7924 7921 7920 7926 8155 7928 2 6 7925 7920 7603 7604 7927 7928 2 6 7926 7604 7928 7929 7609 7605 2 6 7926 7927 7929 8155 7925 8157 2 6 7928 7927 7609 8157 7616 7610 2 6 7809 7810 7931 8050 8345 7808 1 6 7930 7810 7811 7932 7933 8050 1 6 7931 7811 7933 7934 7935 7936 1 6 7931 7932 7934 8050 8051 8052 1 6 7933 7932 7935 8052 8053 8057 1 6 7934 7932 7936 8059 8057 8060 1 6 7935 7932 7811 7812 7937 8060 1 6 7936 7812 7813 7938 8060 8061 1 6 7937 7813 7814 7939 8061 8062 1 6 7938 7814 7816 7817 7940 8062 1 6 7939 7817 7818 7941 8062 8063 1 6 7940 7818 7942 8063 8064 8065 1 6 7941 7818 7819 7943 8065 8066 1 6 7942 7819 7820 7821 7944 8066 1 6 7943 7821 7945 8066 8067 8068 1 6 7944 7821 7822 7946 8068 8069 1 6 7945 7822 7823 7947 8069 8070 1 6 7946 7823 7824 7948 8070 8071 1 6 7947 7824 7826 7949 8071 8072 1 6 7948 7826 7950 8072 8073 8074 1 6 7949 7826 7827 7951 8074 8075 1 6 7950 7827 7952 8075 8076 7953 1 6 7951 7827 7828 7829 7832 7953 1 6 7952 7832 7833 7954 8076 7951 1 6 7953 7833 7955 8076 8077 8078 1 6 7954 7833 7834 7835 7956 8078 1 6 7955 7835 7836 7957 8078 8079 1 6 7956 7836 7958 8079 8080 8081 1 6 7957 7836 7837 7838 7959 8081 1 6 7958 7838 7839 7960 8081 8082 1 5 7959 7839 7846 8082 7847 1 6 7846 7840 7841 7842 7843 7845 1 6 7726 7727 7963 8466 8468 9764 1 6 7962 7727 7964 8466 8487 8488 1 6 7963 7727 7728 7246 7965 8488 1 6 7964 7246 7247 7966 8488 8489 1 6 7965 7247 7248 7967 8489 8490 1 6 7966 7248 7249 7968 8490 8491 1 6 7967 7249 7511 7513 7969 8491 2 6 7968 7513 7970 8493 8491 8494 2 6 7969 7513 7514 7971 8494 8495 2 6 7970 7514 7972 8495 8496 7974 1 6 7971 7514 7515 7518 7973 7974 1 6 7972 7518 7974 7975 7976 7977 2 6 7972 7973 7975 8496 7971 8497 2 6 7974 7973 7976 8500 8497 7981 2 6 7975 7973 7977 7979 7980 7981 1 6 7976 7973 7518 7519 7978 7979 1 6 7977 7519 7979 7988 7989 7521 1 6 7977 7978 7976 7980 7987 7988 2 6 7976 7979 7981 7982 7986 7987 2 6 7976 7980 7982 7983 8500 7975 2 6 7981 7980 7983 7984 7985 7986 2 6 7981 7982 7984 8500 8501 8502 2 6 7983 7982 7985 8502 8503 8504 2 6 7984 7982 7986 8504 8505 8506 2 6 7985 7982 7980 7987 8506 7993 1 7 7986 7980 7979 7988 7991 7992 7993 1 5 7987 7979 7978 7989 7991 1 7 7988 7978 7521 7526 7990 7548 7991 1 5 7989 7526 7527 7546 7548 1 6 7989 7548 7549 7992 7987 7988 1 6 7991 7549 7551 7987 7993 7994 2 6 7987 7992 7994 8506 7986 8507 2 6 7993 7992 7551 8507 7997 7995 2 6 7551 7552 7558 7996 7997 7994 2 6 7995 7558 7559 7997 7998 7999 2 6 7995 7996 7998 8507 7994 8508 2 6 7997 7996 7999 8508 8509 8510 2 6 7998 7996 7559 7566 8000 8510 2 6 7999 7566 7567 7570 8001 8510 2 7 8000 7570 7571 8002 8510 8522 8511 2 6 8001 7571 7572 8003 8522 8523 2 7 8002 7572 7574 7577 8004 8520 8523 2 7 8003 7577 8005 8519 8517 8520 8541 2 5 8004 7577 7578 8006 8541 2 6 8005 7578 8007 8610 8540 8541 2 6 8006 7578 7579 7580 8008 8610 2 6 8007 7580 7581 8009 8010 8610 2 6 8008 7581 8010 8011 8012 7582 2 8 8008 8009 8011 8609 8537 8538 8540 8610 2 5 8010 8009 8012 8013 8609 2 6 8011 8009 8013 7587 7582 7585 2 7 8011 8012 7587 7729 8014 8608 8609 2 6 8013 7729 7730 8015 8607 8608 2 6 8014 7730 7734 8016 8611 8607 2 6 8015 7734 7735 8017 8611 8612 2 6 8016 7735 8018 8612 8613 8614 2 6 8017 7735 7736 8019 8614 8615 2 6 8018 7736 8020 8615 8618 8619 2 6 8019 7736 7737 8021 8022 8619 2 6 8020 7737 8022 8023 9766 7738 2 6 8020 8021 8023 8024 8619 8620 2 6 8022 8021 8024 8025 7742 9766 2 6 8022 8023 8025 8620 8621 8028 2 6 8024 8023 7742 7743 8026 8028 2 6 8025 7743 8027 8028 8029 8030 2 6 8026 7743 7744 7748 8030 8031 2 6 8025 8026 8029 8621 8024 8622 2 6 8028 8026 8030 8628 8622 8629 2 6 8029 8026 8027 8031 8033 8629 2 6 8030 8027 7748 8032 8033 8034 2 6 8031 7748 7749 8034 8035 8036 2 6 8030 8031 8034 8629 8630 8631 2 6 8033 8031 8032 8035 8631 8632 2 6 8034 8032 8036 7761 8635 8632 2 6 8035 8032 7749 7759 7760 7761 2 6 7784 7785 8038 8332 8333 8334 2 6 8037 7785 7787 8039 8041 8334 2 6 8038 7787 8040 8041 8042 8043 2 6 8039 7787 8043 8044 8045 7788 2 6 8038 8039 8042 8334 8335 8336 2 6 8041 8039 8043 8336 8337 8341 2 6 8042 8039 8040 8044 8341 8342 2 6 8043 8040 8045 8342 8343 8046 2 6 8044 8040 7788 7794 7795 8046 2 6 8045 7795 8047 7806 8343 8044 2 6 8046 7795 7806 7803 8048 7796 2 6 7803 8047 7796 7802 7801 8049 2 6 7801 8048 7796 7797 7799 7800 2 6 7930 7931 7933 8051 8345 8346 2 6 8050 7933 8052 8346 8347 8348 1 6 8051 7933 7934 8053 8054 8348 1 6 8052 7934 8054 8055 8056 8057 2 6 8052 8053 8055 8348 8349 8350 2 6 8054 8053 8056 8350 8351 8352 1 6 8055 8053 8057 8058 8352 8353 1 6 8056 8053 8058 8059 7935 7934 1 6 8056 8057 8059 8353 8354 8355 1 6 8058 8057 7935 8060 8355 8356 1 6 8059 7935 7936 7937 8061 8356 1 6 8060 7937 7938 8062 8356 8358 1 6 8061 7938 7939 7940 8063 8358 1 6 8062 7940 7941 8064 8359 8358 1 6 8063 7941 8065 8359 8360 8361 1 6 8064 7941 7942 8066 8361 8362 1 6 8065 7942 7943 7944 8067 8362 1 6 8066 7944 8068 8362 8363 8364 1 6 8067 7944 7945 8069 8364 8365 1 6 8068 7945 7946 8070 8365 8366 1 6 8069 7946 7947 8071 8366 8367 1 6 8070 7947 7948 8072 8367 8368 1 6 8071 7948 7949 8073 8368 8369 1 6 8072 7949 8074 8369 8370 8371 1 6 8073 7949 7950 8075 8371 8372 1 6 8074 7950 7951 8076 8372 8373 1 6 8075 7951 7953 7954 8077 8373 1 6 8076 7954 8078 8375 8373 8376 1 6 8077 7954 7955 7956 8079 8376 1 6 8078 7956 7957 8080 8376 8377 1 6 8079 7957 8081 8209 8377 8378 1 6 8080 7957 7958 7959 8082 8209 1 7 8081 7959 7960 7847 7848 8083 8209 1 6 8082 7848 7849 8084 8209 8210 1 6 8083 7849 7850 8085 8210 8211 1 6 8084 7850 8086 8211 8212 8213 1 6 8085 7850 7851 7852 8087 8213 1 6 8086 7852 8088 8213 8214 8215 1 6 8087 7852 7853 8089 8215 8090 1 6 8088 7853 7854 7855 7856 8090 1 5 8089 7856 8091 8215 8088 1 7 8090 7856 7857 8092 8215 8216 8217 1 5 8091 7857 8093 8217 8218 1 6 8092 7857 7858 8094 8218 8219 1 6 8093 7858 7859 7860 8095 8219 1 6 8094 7860 8096 8219 8220 8221 1 6 8095 7860 7861 8097 8221 8222 1 6 8096 7861 7862 8098 8222 8223 1 6 8097 7862 7863 8099 8223 8224 1 6 8098 7863 7864 8100 8224 8225 1 6 8099 7864 7865 8101 8225 8226 1 6 8100 7865 7866 8102 8226 8227 1 6 8101 7866 7867 7868 8103 8227 1 6 8102 7868 8104 8227 8228 8229 1 6 8103 7868 7869 8105 8229 8230 1 6 8104 7869 7870 7871 8106 8230 1 6 8105 7871 8107 8230 8231 8232 1 6 8106 7871 7872 8108 8232 8233 1 6 8107 7872 7873 7874 8109 8233 1 6 8108 7874 8110 8233 8234 8235 1 6 8109 7874 7875 7876 8111 8235 1 6 8110 7876 8112 8235 8236 8237 1 6 8111 7876 7877 7878 8113 8237 1 6 8112 7878 7879 8114 8237 8238 1 6 8113 7879 8115 8238 8239 8116 1 6 8114 7879 7880 7881 7882 8116 1 6 8115 7882 7883 8117 8239 8114 1 6 8116 7883 8118 8239 8240 8241 1 5 8117 7883 7884 8119 8241 1 6 8118 7884 7885 8120 8241 8242 1 6 8119 7885 7886 8121 8242 8243 1 6 8120 7886 7887 8122 8243 8244 1 6 8121 7887 8123 8244 8245 8246 1 6 8122 7887 7888 7889 8124 8246 1 6 8123 7889 7890 8125 8246 8247 1 6 8124 7890 7891 8126 8247 8248 1 6 8125 7891 7892 8127 8248 8249 1 6 8126 7892 7893 8128 8249 8250 1 6 8127 7893 7894 8129 8250 8251 1 6 8128 7894 8130 8251 8252 8253 1 6 8129 7894 7895 7896 8131 8253 1 6 8130 7896 7897 8132 8253 8254 1 5 8131 7897 7898 8133 8254 1 7 8132 7898 7899 8134 8254 8255 8256 2 5 8133 7899 7900 8135 8256 2 7 8134 7900 8136 8256 8257 8258 8259 2 6 8135 7900 7901 7902 8137 8259 2 6 8136 7902 8138 8259 8260 8261 2 6 8137 7902 7904 8139 8261 8262 2 6 8138 7904 7905 7906 8140 8262 2 6 8139 7906 8141 8262 8263 8264 2 6 8140 7906 7907 7908 8142 8264 2 6 8141 7908 8143 8264 8265 8266 2 6 8142 7908 7909 7910 8144 8266 2 6 8143 7910 7911 8145 8266 8267 2 6 8144 7911 8146 8267 8268 8269 2 6 8145 7911 7912 7913 8147 8269 2 6 8146 7913 8148 8269 8270 8271 2 6 8147 7913 7914 8149 8151 8271 2 5 8148 7914 8150 8151 7922 2 6 8149 7914 7915 7916 7919 7922 2 7 8148 8149 7922 7923 8152 8271 8272 2 5 8151 7923 8153 8272 8273 2 7 8152 7923 7924 8154 8273 8274 8275 2 6 8153 7924 8155 8156 8275 8276 2 7 8154 7924 8156 7925 7928 8157 7617 2 6 8154 8155 7617 7618 8158 8276 2 5 8155 7928 7929 7616 7617 2 6 8156 7618 8159 8276 8277 8278 2 6 8158 7618 7619 8160 8278 8279 2 7 8159 7619 7620 8161 8279 8280 8281 2 5 8160 7620 8162 8281 8282 2 7 8161 7620 7621 8163 8282 8283 8164 2 6 8162 7621 7622 7623 7624 8164 2 7 8163 7624 7625 7627 8165 8283 8162 2 6 8164 7627 7628 7630 8166 8283 2 6 8165 7630 8167 8168 8283 8282 2 6 8166 7630 8168 8169 8170 7631 2 6 8166 8167 8169 8282 8284 8285 2 6 8168 8167 8170 8285 8286 8287 2 6 8169 8167 7631 8171 8172 8287 2 6 8170 7631 8172 8173 7633 7632 2 6 8170 8171 8173 8287 8288 8289 2 6 8172 8171 7633 8174 8289 8290 2 6 8173 7633 7634 7636 8175 8290 2 6 8174 7636 7638 8176 8290 8291 2 6 8175 7638 8177 8291 8292 8293 2 6 8176 7638 7639 8178 8293 8294 2 6 8177 7639 8179 8294 8295 8296 2 6 8178 7639 7640 8180 8296 8297 2 6 8179 7640 8181 8307 8297 8308 2 6 8180 7640 7641 8182 8183 8308 2 6 8181 7641 8183 7644 7643 7642 2 6 8181 8182 7644 8184 8308 8309 2 6 8183 7644 7645 8185 8309 8310 2 7 8184 7645 7646 7647 8186 8310 8311 1 6 8185 7647 7648 8187 8311 8312 1 6 8186 7648 8188 8312 8313 8314 1 6 8187 7648 7649 8189 8314 8315 1 6 8188 7649 7650 8190 8315 8200 1 6 8189 7650 8191 8197 8199 8200 1 6 8190 7650 7651 8192 8197 8193 1 6 8191 7651 7652 7657 7658 8193 1 6 8192 7658 8194 8196 8197 8191 1 6 8193 7658 7659 7662 8195 8196 1 6 8194 7662 8196 8208 8204 7663 1 6 8194 8195 8193 8197 8198 8204 1 6 8193 8196 8198 8199 8190 8191 1 6 8197 8196 8199 8202 8203 8204 1 6 8197 8198 8190 8200 8201 8202 1 6 8190 8199 8201 8315 8189 8316 1 6 8200 8199 8202 8316 8317 8318 1 6 8201 8199 8198 8203 8205 8318 1 6 8202 8198 8204 8205 7699 8206 1 7 8203 8198 8206 8207 8208 8195 8196 1 5 8202 8203 7699 8318 7700 1 7 7699 8203 8204 7698 7669 7667 8207 1 6 7667 8206 8204 8208 7664 7665 1 5 8207 8204 8195 7663 7664 1 6 8080 8081 8082 8083 8210 8378 1 5 8209 8083 8084 8211 8378 1 6 8210 8084 8085 8212 8378 8379 1 6 8211 8085 8213 8379 8380 8381 1 6 8212 8085 8086 8087 8214 8381 1 6 8213 8087 8215 8381 8382 8216 1 6 8214 8087 8088 8090 8091 8216 1 6 8215 8091 8217 8382 8214 8383 1 6 8216 8091 8092 8218 8383 8384 1 6 8217 8092 8093 8219 8384 8385 1 6 8218 8093 8094 8095 8220 8385 1 5 8219 8095 8221 8385 8386 1 6 8220 8095 8096 8222 8386 8387 1 6 8221 8096 8097 8223 8387 8388 1 6 8222 8097 8098 8224 8388 8389 1 6 8223 8098 8099 8225 8389 8390 1 6 8224 8099 8100 8226 8390 8391 1 6 8225 8100 8101 8227 8391 8392 1 6 8226 8101 8102 8103 8228 8392 1 6 8227 8103 8229 8392 8393 8394 1 6 8228 8103 8104 8230 8394 8395 1 6 8229 8104 8105 8106 8231 8395 1 6 8230 8106 8232 8395 8396 8397 1 6 8231 8106 8107 8233 8397 8398 1 6 8232 8107 8108 8109 8234 8398 1 6 8233 8109 8235 8398 8399 8400 1 6 8234 8109 8110 8111 8236 8400 1 6 8235 8111 8237 8400 8401 8402 1 6 8236 8111 8112 8113 8238 8402 1 6 8237 8113 8114 8239 8402 8403 1 6 8238 8114 8116 8117 8240 8403 1 6 8239 8117 8241 8403 8404 8405 1 6 8240 8117 8118 8119 8242 8405 1 6 8241 8119 8120 8243 8405 8406 1 6 8242 8120 8121 8244 8406 8407 1 6 8243 8121 8122 8245 8407 8408 1 6 8244 8122 8246 8408 8409 8410 1 6 8245 8122 8123 8124 8247 8410 1 6 8246 8124 8125 8248 8410 8411 1 6 8247 8125 8126 8249 8411 8412 1 6 8248 8126 8127 8250 8412 8413 1 6 8249 8127 8128 8251 8413 8414 1 6 8250 8128 8129 8252 8414 8415 1 6 8251 8129 8253 8415 8416 8417 1 6 8252 8129 8130 8131 8254 8417 1 7 8253 8131 8132 8133 8255 8417 8418 1 5 8254 8133 8256 8418 8419 2 7 8255 8133 8134 8135 8257 8419 8420 2 5 8256 8135 8258 8420 8421 2 6 8257 8135 8259 8421 8422 8260 2 5 8258 8135 8136 8137 8260 2 6 8259 8137 8261 8422 8258 8423 2 6 8260 8137 8138 8262 8423 8424 2 6 8261 8138 8139 8140 8263 8424 2 6 8262 8140 8264 8424 8425 8426 2 6 8263 8140 8141 8142 8265 8426 2 6 8264 8142 8266 8426 8427 8428 2 7 8265 8142 8143 8144 8267 8428 8429 2 6 8266 8144 8145 8268 8429 8430 2 6 8267 8145 8269 8430 8431 8432 2 6 8268 8145 8146 8147 8270 8432 2 6 8269 8147 8271 8432 8433 8434 2 6 8270 8147 8148 8151 8272 8434 2 5 8271 8151 8152 8273 8434 2 7 8272 8152 8153 8274 8434 8435 8436 2 6 8273 8153 8275 8436 8437 8438 2 6 8274 8153 8154 8276 8438 8277 2 5 8275 8154 8156 8158 8277 2 6 8276 8158 8278 8438 8275 8439 2 6 8277 8158 8159 8279 8439 8440 2 7 8278 8159 8160 8280 8440 8441 8445 2 6 8279 8160 8281 8445 8446 8284 2 5 8280 8160 8161 8282 8284 2 7 8281 8161 8162 8283 8166 8168 8284 2 5 8282 8162 8164 8165 8166 2 6 8282 8168 8285 8446 8280 8281 2 6 8284 8168 8169 8286 8446 8447 2 6 8285 8169 8287 8447 8449 8450 2 6 8286 8169 8170 8172 8288 8450 2 6 8287 8172 8289 8450 8451 8452 2 6 8288 8172 8173 8290 8452 8453 2 6 8289 8173 8174 8175 8291 8453 2 6 8290 8175 8176 8292 8453 8454 2 6 8291 8176 8293 8454 8455 8456 2 6 8292 8176 8177 8294 8456 8457 2 6 8293 8177 8178 8295 8457 8458 2 6 8294 8178 8296 8461 8458 8299 2 6 8295 8178 8179 8297 8298 8299 2 6 8296 8179 8298 8307 8305 8180 2 6 8296 8297 8299 8300 8301 8305 2 6 8296 8298 8300 8461 8295 8462 2 6 8299 8298 8301 8302 8462 8463 2 6 8300 8298 8302 8303 8304 8305 2 6 8300 8301 8303 8463 8464 8465 2 6 8302 8301 8304 8465 8466 8467 2 6 8303 8301 8305 8306 8470 8467 2 6 8304 8301 8298 8306 8307 8297 2 6 8304 8305 8307 8470 8471 8472 2 6 8306 8305 8297 8180 8308 8472 2 6 8307 8180 8181 8183 8309 8472 2 6 8308 8183 8184 8310 8472 8473 2 6 8309 8184 8185 8311 8473 8474 1 5 8310 8185 8186 8312 8474 1 6 8311 8186 8187 8313 8474 8475 1 6 8312 8187 8314 8478 8475 8479 1 6 8313 8187 8188 8315 8479 8480 1 6 8314 8188 8189 8200 8316 8480 1 5 8315 8200 8201 8317 8480 1 6 8316 8201 8318 8480 8481 7708 1 7 8317 8201 8202 8205 7700 7707 7708 2 6 7765 7766 8320 8321 8853 8854 2 6 8319 7766 7767 8321 8322 7769 2 7 8319 8320 8322 8854 8855 8856 8323 2 5 8321 8320 7769 7771 8323 2 6 8322 7771 8324 8856 8321 8857 2 6 8323 7771 7772 8325 8857 8328 2 6 8324 7772 7777 8326 8327 8328 2 6 8325 7777 7778 7779 7780 8327 2 6 8326 7780 8325 8328 8329 7781 2 6 8325 8327 8329 8857 8324 8858 2 6 8328 8327 7781 7782 8330 8858 2 6 8329 7782 7783 8331 8858 8859 2 6 8330 7783 8332 8865 8862 8859 2 6 8331 7783 7784 8037 8333 8865 2 6 8332 8037 8334 8866 8865 8867 2 6 8333 8037 8038 8041 8335 8867 2 6 8334 8041 8336 8867 8868 8869 2 6 8335 8041 8042 8337 8338 8869 2 6 8336 8042 8338 8339 8340 8341 2 6 8336 8337 8339 8869 8870 8874 2 6 8338 8337 8340 8874 8875 8347 2 6 8339 8337 8341 8347 8346 8876 2 6 8340 8337 8042 8043 8342 8876 2 6 8341 8043 8044 8343 8344 8876 2 6 8342 8044 8344 7807 7806 8046 2 6 8342 8343 7807 7808 8345 8876 2 6 8344 7808 7930 8050 8346 8876 2 6 8345 8050 8051 8347 8340 8876 2 6 8346 8051 8348 8875 8339 8340 2 6 8347 8051 8052 8054 8349 8875 2 6 8348 8054 8350 8902 8875 8901 2 6 8349 8054 8055 8351 8901 8903 2 6 8350 8055 8352 8903 8904 8905 1 6 8351 8055 8056 8353 8905 8906 1 6 8352 8056 8058 8354 8906 8907 1 6 8353 8058 8355 8907 8908 8909 1 6 8354 8058 8059 8356 8357 8909 1 6 8355 8059 8060 8061 8357 8358 1 6 8355 8356 8358 8359 8909 8910 1 6 8357 8356 8061 8062 8359 8063 1 6 8357 8358 8063 8064 8360 8910 1 6 8359 8064 8361 8912 8910 8913 1 6 8360 8064 8065 8362 8913 8914 1 6 8361 8065 8066 8067 8363 8914 1 6 8362 8067 8364 8916 8914 8917 1 6 8363 8067 8068 8365 8917 8918 1 6 8364 8068 8069 8366 8918 8919 1 6 8365 8069 8070 8367 8919 8920 1 6 8366 8070 8071 8368 8920 8921 1 6 8367 8071 8072 8369 8921 8922 1 6 8368 8072 8073 8370 8922 8923 1 6 8369 8073 8371 8923 8924 8925 1 6 8370 8073 8074 8372 8925 8926 1 6 8371 8074 8075 8373 8374 8926 1 6 8372 8075 8076 8374 8375 8077 1 6 8372 8373 8375 8926 8927 8928 1 6 8374 8373 8077 8376 8928 8929 1 6 8375 8077 8078 8079 8377 8929 1 6 8376 8079 8080 8378 8929 8379 1 6 8377 8080 8209 8210 8211 8379 1 7 8378 8211 8212 8380 8929 8377 8930 1 5 8379 8212 8381 8930 8931 1 7 8380 8212 8213 8214 8382 8743 8931 1 6 8381 8214 8216 8383 8641 8743 1 6 8382 8216 8217 8384 8641 8642 1 6 8383 8217 8218 8385 8642 8643 1 6 8384 8218 8219 8220 8386 8643 1 7 8385 8220 8221 8387 8643 8644 8645 1 6 8386 8221 8222 8388 8645 8646 1 6 8387 8222 8223 8389 8646 8647 1 6 8388 8223 8224 8390 8647 8648 1 7 8389 8224 8225 8391 8648 8649 8650 1 6 8390 8225 8226 8392 8650 8651 1 6 8391 8226 8227 8228 8393 8651 1 6 8392 8228 8394 8651 8652 8653 1 6 8393 8228 8229 8395 8653 8654 1 6 8394 8229 8230 8231 8396 8654 1 5 8395 8231 8397 8654 8655 1 6 8396 8231 8232 8398 8655 8656 1 7 8397 8232 8233 8234 8399 8656 8657 1 5 8398 8234 8400 8657 8658 1 7 8399 8234 8235 8236 8401 8658 8659 1 5 8400 8236 8402 8659 8660 1 6 8401 8236 8237 8238 8403 8660 1 6 8402 8238 8239 8240 8404 8660 1 6 8403 8240 8405 8660 8661 8662 1 6 8404 8240 8241 8242 8406 8662 1 6 8405 8242 8243 8407 8662 8663 1 7 8406 8243 8244 8408 8663 8664 8665 1 6 8407 8244 8245 8409 8665 8666 1 6 8408 8245 8410 8666 8667 8668 1 6 8409 8245 8246 8247 8411 8668 1 6 8410 8247 8248 8412 8668 8669 1 6 8411 8248 8249 8413 8669 8670 1 6 8412 8249 8250 8414 8670 8671 1 6 8413 8250 8251 8415 8671 8672 1 6 8414 8251 8252 8416 8672 8673 1 6 8415 8252 8417 8673 8674 8675 1 6 8416 8252 8253 8254 8418 8675 1 6 8417 8254 8255 8419 8675 8676 2 6 8418 8255 8256 8420 8676 8677 2 6 8419 8256 8257 8421 8677 8678 2 6 8420 8257 8258 8422 8678 8679 2 6 8421 8258 8260 8423 8679 8680 2 7 8422 8260 8261 8424 8680 8681 8682 2 6 8423 8261 8262 8263 8425 8682 2 6 8424 8263 8426 8682 8683 8687 2 6 8425 8263 8264 8265 8427 8687 2 6 8426 8265 8428 8687 8688 8689 2 6 8427 8265 8266 8429 8689 8690 2 5 8428 8266 8267 8430 8690 2 6 8429 8267 8268 8431 8542 8690 2 6 8430 8268 8432 8542 8543 8544 2 6 8431 8268 8269 8270 8433 8544 2 6 8432 8270 8434 8544 8545 8546 2 7 8433 8270 8271 8272 8273 8435 8546 2 6 8434 8273 8436 8546 8547 8548 2 6 8435 8273 8274 8437 8548 8549 2 6 8436 8274 8438 8549 8550 8439 2 5 8437 8274 8275 8277 8439 2 7 8438 8277 8278 8440 8550 8437 8551 2 6 8439 8278 8279 8441 8442 8551 2 6 8440 8279 8442 8443 8444 8445 2 6 8440 8441 8443 8551 8552 8553 2 6 8442 8441 8444 8553 8554 8555 2 7 8443 8441 8445 8446 8447 8448 8555 2 5 8444 8441 8279 8280 8446 2 6 8445 8280 8284 8285 8447 8444 2 6 8446 8285 8286 8444 8448 8449 2 5 8444 8447 8449 8555 8556 2 6 8448 8447 8286 8450 8556 8557 2 7 8449 8286 8287 8288 8451 8557 8558 2 6 8450 8288 8452 8558 8559 8560 2 6 8451 8288 8289 8453 8560 8561 2 6 8452 8289 8290 8291 8454 8561 2 6 8453 8291 8292 8455 8561 8562 2 6 8454 8292 8456 8562 8563 8564 2 6 8455 8292 8293 8457 8564 8565 2 6 8456 8293 8294 8458 8459 8565 2 6 8457 8294 8459 8460 8461 8295 2 6 8457 8458 8460 8565 8566 8567 2 6 8459 8458 8461 8567 8568 8569 2 6 8460 8458 8295 8299 8462 8569 2 6 8461 8299 8300 8463 8569 8570 2 6 8462 8300 8302 8464 8570 8571 2 6 8463 8302 8465 8571 8572 8573 2 6 8464 8302 8303 8466 8573 8487 2 7 8465 8303 8467 8468 7962 7963 8487 2 6 8466 8303 8468 8469 8470 8304 1 6 8466 8467 8469 7962 9763 9764 1 7 8468 8467 8470 9094 8485 9763 8486 2 6 8469 8467 8304 8306 8471 9094 2 6 8470 8306 8472 8476 9094 8473 2 6 8471 8306 8307 8308 8309 8473 2 6 8472 8309 8310 8474 8476 8471 1 6 8473 8310 8311 8312 8475 8476 1 6 8474 8312 8476 8477 8478 8313 1 7 8474 8475 8477 8485 9094 8471 8473 1 6 8476 8475 8478 8483 8484 8485 1 6 8477 8475 8313 8479 8483 8482 1 6 8478 8313 8314 8480 8482 8481 1 6 8479 8314 8315 8316 8317 8481 1 6 8480 8317 7708 7709 8482 8479 1 7 8481 7709 7710 7713 8483 8478 8479 1 5 8482 7713 8484 8477 8478 1 6 8483 7713 7714 8477 8485 8486 1 6 8477 8484 8486 8469 9094 8476 1 6 8485 8484 9765 9763 8469 7714 2 5 8466 7963 8488 8573 8465 2 7 8487 7963 7964 7965 8489 8573 8574 2 5 8488 7965 7966 8490 8574 2 7 8489 7966 7967 8491 8492 8574 8575 2 6 8490 7967 8492 8493 7969 7968 2 5 8490 8491 8493 8575 8576 2 6 8492 8491 7969 8494 8576 8577 2 6 8493 7969 7970 8495 8577 8578 2 6 8494 7970 7971 8496 8578 8579 2 6 8495 7971 7974 8497 8498 8579 2 6 8496 7974 8498 8499 8500 7975 2 6 8496 8497 8499 8579 8580 8581 2 6 8498 8497 8500 8581 8582 8501 2 6 8499 8497 7975 7981 7983 8501 2 6 8500 7983 8502 8582 8499 8583 2 6 8501 7983 7984 8503 8586 8583 2 6 8502 7984 8504 8527 8586 8526 2 6 8503 7984 7985 8505 8526 8588 2 6 8504 7985 8506 8588 8513 8589 2 6 8505 7985 7986 7993 8507 8589 2 6 8506 7993 7994 7997 8508 8589 2 6 8507 7997 7998 8509 8513 8589 2 6 8508 7998 8510 8511 8512 8513 2 6 8509 7998 7999 8000 8001 8511 2 6 8509 8510 8512 8521 8522 8001 2 6 8509 8511 8513 8514 8515 8521 2 7 8509 8512 8514 8588 8505 8589 8508 2 6 8513 8512 8515 8516 8526 8588 2 6 8514 8512 8516 8517 8520 8521 2 6 8514 8515 8517 8518 8524 8526 2 6 8516 8515 8518 8519 8004 8520 2 6 8516 8517 8519 8524 8525 8531 2 6 8518 8517 8004 8541 8539 8531 2 6 8004 8517 8003 8515 8521 8523 2 6 8520 8515 8512 8511 8522 8523 2 5 8521 8511 8001 8002 8523 2 5 8522 8002 8521 8520 8003 2 6 8516 8518 8525 8526 8527 8528 2 6 8524 8518 8528 8529 8530 8531 2 7 8516 8524 8527 8503 8504 8588 8514 2 5 8526 8524 8528 8586 8503 2 6 8527 8524 8525 8529 8587 8586 2 6 8528 8525 8530 8602 8587 8603 2 6 8529 8525 8531 8532 8533 8603 2 6 8530 8525 8532 8519 8539 8518 2 6 8530 8531 8533 8534 8538 8539 2 6 8530 8532 8534 8535 8603 8604 2 6 8533 8532 8535 8536 8537 8538 2 6 8533 8534 8536 8604 8605 8606 2 6 8535 8534 8537 8606 8607 8608 2 6 8536 8534 8538 8608 8609 8010 2 6 8537 8534 8532 8539 8540 8010 2 6 8538 8532 8540 8541 8519 8531 2 6 8538 8539 8541 8010 8610 8006 2 6 8540 8539 8519 8006 8005 8004 2 6 8430 8431 8543 8690 8691 8692 2 6 8542 8431 8544 8692 8693 8694 2 6 8543 8431 8432 8433 8545 8694 2 6 8544 8433 8546 8694 8695 8547 2 5 8545 8433 8434 8435 8547 2 6 8546 8435 8548 8695 8545 8696 2 6 8547 8435 8436 8549 8696 8697 2 6 8548 8436 8437 8550 8697 8698 2 6 8549 8437 8439 8551 8698 8552 2 5 8550 8439 8440 8442 8552 2 7 8551 8442 8553 8698 8550 8699 8700 2 6 8552 8442 8443 8554 8700 8701 2 6 8553 8443 8555 8701 8702 8703 2 6 8554 8443 8444 8448 8556 8703 2 6 8555 8448 8449 8557 8703 8704 2 6 8556 8449 8450 8558 8704 8705 2 6 8557 8450 8451 8559 8705 8706 2 6 8558 8451 8560 8706 8707 8708 2 5 8559 8451 8452 8561 8708 2 6 8560 8452 8453 8454 8562 8708 2 6 8561 8454 8455 8563 8708 8709 2 6 8562 8455 8564 8709 8710 8711 2 6 8563 8455 8456 8565 8711 8712 2 7 8564 8456 8457 8459 8566 8712 8713 2 5 8565 8459 8567 8713 8714 2 6 8566 8459 8460 8568 8714 8715 2 6 8567 8460 8569 8715 8716 8717 2 6 8568 8460 8461 8462 8570 8717 2 7 8569 8462 8463 8571 8590 8592 8717 2 5 8570 8463 8464 8572 8590 2 7 8571 8464 8573 8574 8575 8576 8590 2 6 8572 8464 8465 8487 8488 8574 2 6 8573 8488 8489 8490 8575 8572 2 5 8574 8490 8492 8576 8572 2 7 8575 8492 8493 8577 8572 8590 8591 2 6 8576 8493 8494 8578 8594 8591 2 6 8577 8494 8495 8579 8594 8595 2 6 8578 8495 8496 8498 8580 8595 2 6 8579 8498 8581 8595 8596 8597 2 6 8580 8498 8499 8582 8597 8598 2 6 8581 8499 8501 8583 8584 8598 2 6 8582 8501 8584 8585 8586 8502 2 6 8582 8583 8585 8598 8599 8600 2 6 8584 8583 8586 8587 8600 8601 2 7 8585 8583 8587 8528 8527 8503 8502 2 6 8585 8586 8528 8601 8602 8529 2 5 8526 8504 8505 8513 8514 2 5 8513 8505 8506 8508 8507 2 6 8572 8576 8591 8571 8570 8592 2 6 8590 8576 8592 8593 8594 8577 2 5 8570 8590 8591 8593 8717 2 7 8592 8591 8594 8717 8716 8718 8719 2 6 8593 8591 8577 8578 8595 8719 2 7 8594 8578 8579 8580 8596 8719 8720 2 6 8595 8580 8597 8720 8721 8722 2 6 8596 8580 8581 8598 8722 8723 2 6 8597 8581 8582 8584 8599 8723 2 6 8598 8584 8600 8723 8724 8725 2 6 8599 8584 8585 8601 8725 8726 2 6 8600 8585 8587 8602 8726 8727 2 5 8601 8587 8529 8603 8727 2 6 8602 8529 8530 8533 8604 8727 2 6 8603 8533 8535 8605 8727 8728 2 6 8604 8535 8606 8728 8731 8732 2 6 8605 8535 8536 8607 8611 8732 2 6 8606 8536 8608 8611 8015 8014 2 6 8607 8536 8537 8609 8014 8013 2 5 8608 8537 8010 8013 8011 2 5 8010 8540 8008 8007 8006 2 6 8606 8607 8015 8016 8612 8732 2 6 8611 8016 8017 8613 8732 8733 2 6 8612 8017 8614 8733 8734 8735 2 6 8613 8017 8018 8615 8616 8735 2 6 8614 8018 8019 8616 8617 8618 2 6 8614 8615 8617 8735 8736 8737 2 6 8616 8615 8618 8737 8738 8739 2 6 8617 8615 8019 8619 8739 8742 2 6 8618 8019 8020 8022 8620 8742 2 6 8619 8022 8024 8621 8624 8742 2 6 8620 8024 8028 8622 8623 8624 2 6 8621 8028 8623 8627 8628 8029 2 6 8621 8622 8624 8625 8626 8627 2 6 8621 8623 8625 8741 8742 8620 2 6 8624 8623 8626 8837 8741 8838 2 6 8625 8623 8627 8838 8839 8840 2 6 8626 8623 8622 8628 8840 8841 2 6 8627 8622 8029 8629 8841 8842 2 6 8628 8029 8030 8033 8630 8842 2 6 8629 8033 8631 8842 8843 8844 2 6 8630 8033 8034 8632 8633 8844 2 6 8631 8034 8633 8634 8635 8035 2 6 8631 8632 8634 8844 8845 8846 2 6 8633 8632 8635 8636 8637 8846 2 6 8634 8632 8636 8640 7761 8035 2 6 8634 8635 8637 8638 8639 8640 2 6 8634 8636 8638 8846 8848 8849 2 6 8637 8636 8639 8849 8850 8851 2 6 8638 8636 8640 8851 8852 7762 2 5 8639 8636 8635 7761 7762 1 6 8382 8383 8642 8743 8744 8745 1 6 8641 8383 8384 8643 8745 8746 1 6 8642 8384 8385 8386 8644 8746 1 6 8643 8386 8645 8746 8747 8748 1 6 8644 8386 8387 8646 8748 8749 1 6 8645 8387 8388 8647 8749 8750 1 6 8646 8388 8389 8648 8750 8751 1 6 8647 8389 8390 8649 8751 8752 1 6 8648 8390 8650 8752 8753 8754 1 5 8649 8390 8391 8651 8754 1 6 8650 8391 8392 8393 8652 8754 1 6 8651 8393 8653 8754 8755 8756 1 6 8652 8393 8394 8654 8756 8757 1 6 8653 8394 8395 8396 8655 8757 1 6 8654 8396 8397 8656 8757 8758 1 7 8655 8397 8398 8657 8758 8759 8760 1 5 8656 8398 8399 8658 8760 1 7 8657 8399 8400 8659 8760 8761 8762 1 5 8658 8400 8401 8660 8762 1 8 8659 8401 8402 8403 8404 8661 8762 8763 1 5 8660 8404 8662 8763 8764 1 6 8661 8404 8405 8406 8663 8764 1 6 8662 8406 8407 8664 8764 8765 1 6 8663 8407 8665 8765 8766 8767 1 5 8664 8407 8408 8666 8767 1 6 8665 8408 8409 8667 8767 8768 1 6 8666 8409 8668 8768 8769 8770 1 6 8667 8409 8410 8411 8669 8770 1 6 8668 8411 8412 8670 8770 8771 1 6 8669 8412 8413 8671 8771 8772 1 6 8670 8413 8414 8672 8772 8773 1 6 8671 8414 8415 8673 8773 8774 1 6 8672 8415 8416 8674 8774 8775 1 6 8673 8416 8675 8775 8776 8777 1 6 8674 8416 8417 8418 8676 8777 1 6 8675 8418 8419 8677 8777 8778 2 6 8676 8419 8420 8678 8778 8779 2 6 8677 8420 8421 8679 8779 8780 2 6 8678 8421 8422 8680 8780 8781 2 6 8679 8422 8423 8681 8781 8782 2 6 8680 8423 8682 8782 8783 8684 2 6 8681 8423 8424 8425 8683 8684 2 6 8682 8425 8684 8685 8686 8687 2 5 8682 8683 8685 8783 8681 2 6 8684 8683 8686 8783 8784 8785 2 6 8685 8683 8687 8785 8786 8787 2 7 8686 8683 8425 8426 8427 8688 8787 2 5 8687 8427 8689 8787 8788 2 6 8688 8427 8428 8690 8788 8789 2 7 8689 8428 8429 8430 8542 8691 8789 2 6 8690 8542 8692 8789 8790 8791 2 5 8691 8542 8543 8693 8791 2 7 8692 8543 8694 8791 8792 8793 8794 2 6 8693 8543 8544 8545 8695 8794 2 6 8694 8545 8547 8696 8794 8795 2 7 8695 8547 8548 8697 8795 8796 8797 2 6 8696 8548 8549 8698 8797 8798 2 6 8697 8549 8550 8552 8699 8798 2 6 8698 8552 8700 8798 8799 8800 2 6 8699 8552 8553 8701 8800 8803 2 6 8700 8553 8554 8702 8803 8804 2 6 8701 8554 8703 8804 8805 8806 2 6 8702 8554 8555 8556 8704 8806 2 6 8703 8556 8557 8705 8806 8807 2 6 8704 8557 8558 8706 8807 8808 2 6 8705 8558 8559 8707 8808 8809 2 6 8706 8559 8708 8809 8810 8811 2 7 8707 8559 8560 8561 8562 8709 8811 2 5 8708 8562 8563 8710 8811 2 7 8709 8563 8711 8811 8812 8813 8814 2 6 8710 8563 8564 8712 8814 8815 2 6 8711 8564 8565 8713 8815 8816 2 5 8712 8565 8566 8714 8816 2 7 8713 8566 8567 8715 8816 8817 8818 2 6 8714 8567 8568 8716 8818 8819 2 6 8715 8568 8717 8593 8718 8819 2 6 8716 8568 8569 8570 8592 8593 2 6 8716 8593 8719 8819 8820 8720 2 5 8718 8593 8594 8595 8720 2 6 8719 8595 8596 8721 8820 8718 2 6 8720 8596 8722 8820 8821 8822 2 5 8721 8596 8597 8723 8822 2 6 8722 8597 8598 8599 8724 8822 2 6 8723 8599 8725 8822 8823 8824 2 6 8724 8599 8600 8726 8824 8825 2 6 8725 8600 8601 8727 8825 8729 2 7 8726 8601 8602 8603 8604 8728 8729 2 6 8727 8604 8605 8729 8730 8731 2 5 8727 8728 8730 8825 8726 2 6 8729 8728 8731 8825 8827 8828 2 6 8730 8728 8605 8732 8828 8829 2 7 8731 8605 8606 8611 8612 8733 8829 2 6 8732 8612 8613 8734 8830 8829 2 6 8733 8613 8735 8830 8831 8736 2 5 8734 8613 8614 8616 8736 2 6 8735 8616 8737 8831 8734 8832 2 6 8736 8616 8617 8738 8832 8833 2 6 8737 8617 8739 8740 8833 8834 2 6 8738 8617 8618 8740 8741 8742 2 6 8738 8739 8741 8834 8835 8836 2 7 8740 8739 8742 8624 8836 8837 8625 2 6 8741 8739 8624 8620 8619 8618 1 6 8381 8382 8641 8744 8931 8932 1 5 8743 8641 8745 8932 8933 1 6 8744 8641 8642 8746 8933 8934 1 6 8745 8642 8643 8644 8747 8934 1 6 8746 8644 8748 8934 8935 8936 1 6 8747 8644 8645 8749 8936 8937 1 6 8748 8645 8646 8750 8937 8938 1 6 8749 8646 8647 8751 8938 8939 1 6 8750 8647 8648 8752 8939 8940 1 6 8751 8648 8649 8753 8940 8941 1 6 8752 8649 8754 8941 8942 8943 1 7 8753 8649 8650 8651 8652 8755 8943 1 5 8754 8652 8756 8943 8944 1 6 8755 8652 8653 8757 8944 8945 1 6 8756 8653 8654 8655 8758 8945 1 7 8757 8655 8656 8759 8945 8946 8947 1 5 8758 8656 8760 8947 8948 1 6 8759 8656 8657 8658 8761 8948 1 6 8760 8658 8762 8948 8949 8950 1 6 8761 8658 8659 8660 8763 8950 1 5 8762 8660 8661 8764 8950 1 7 8763 8661 8662 8663 8765 8950 8951 1 6 8764 8663 8664 8766 8951 8952 1 6 8765 8664 8767 8952 8953 8954 1 6 8766 8664 8665 8666 8768 8954 1 6 8767 8666 8667 8769 8954 8955 1 6 8768 8667 8770 8955 8956 8957 1 6 8769 8667 8668 8669 8771 8957 1 6 8770 8669 8670 8772 8957 8958 1 6 8771 8670 8671 8773 8958 8959 1 6 8772 8671 8672 8774 8959 8960 1 6 8773 8672 8673 8775 8960 8961 1 6 8774 8673 8674 8776 8961 8962 1 6 8775 8674 8777 8962 8963 8964 1 6 8776 8674 8675 8676 8778 8964 1 6 8777 8676 8677 8779 8964 8965 2 6 8778 8677 8678 8780 8965 8966 2 6 8779 8678 8679 8781 8966 8967 2 6 8780 8679 8680 8782 8967 8968 2 6 8781 8680 8681 8783 8968 8969 2 6 8782 8681 8684 8685 8784 8969 2 6 8783 8685 8785 8969 8970 8971 2 6 8784 8685 8686 8786 8971 8972 2 6 8785 8686 8787 8972 8973 8974 2 6 8786 8686 8687 8688 8788 8974 2 6 8787 8688 8689 8789 8974 8975 2 6 8788 8689 8690 8691 8790 8975 2 6 8789 8691 8791 8975 8976 8977 2 6 8790 8691 8692 8693 8792 8977 2 6 8791 8693 8793 8977 8978 8979 2 6 8792 8693 8794 8979 8980 8795 2 5 8793 8693 8694 8695 8795 2 6 8794 8695 8696 8796 8980 8793 2 6 8795 8696 8797 8980 8981 8982 2 6 8796 8696 8697 8798 8982 8799 2 5 8797 8697 8698 8699 8799 2 6 8798 8699 8800 8801 8982 8797 2 6 8799 8699 8700 8801 8802 8803 2 6 8799 8800 8802 8982 8983 8984 2 6 8801 8800 8803 8984 8985 8986 2 6 8802 8800 8700 8701 8804 8986 2 6 8803 8701 8702 8805 8986 8987 2 6 8804 8702 8806 8987 8988 8989 2 6 8805 8702 8703 8704 8807 8989 2 6 8806 8704 8705 8808 8989 8990 2 7 8807 8705 8706 8809 8992 8990 8993 2 5 8808 8706 8707 8810 8993 2 6 8809 8707 8811 8993 8994 8812 2 6 8810 8707 8708 8709 8710 8812 2 6 8811 8710 8813 8994 8810 8995 2 6 8812 8710 8814 8995 8996 8997 2 6 8813 8710 8711 8815 8997 8998 2 5 8814 8711 8712 8816 8998 2 7 8815 8712 8713 8714 8817 8998 8999 2 6 8816 8714 8818 8999 9000 9001 2 6 8817 8714 8715 8819 9001 9002 2 6 8818 8715 8716 8718 8820 9002 2 6 8819 8718 8720 8721 8821 9002 2 6 8820 8721 8822 9002 9003 8823 2 6 8821 8721 8722 8723 8724 8823 2 6 8822 8724 8824 9003 8821 9004 2 6 8823 8724 8725 8825 8826 9004 2 7 8824 8725 8726 8729 8730 8826 8827 2 6 8824 8825 8827 9004 9005 9006 2 6 8826 8825 8730 8828 9012 9006 2 6 8827 8730 8731 8829 8830 9012 2 5 8828 8731 8830 8733 8732 2 7 8828 8829 8733 8734 8831 9011 9012 2 6 8830 8734 8736 8832 9013 9011 2 7 8831 8736 8737 8833 9013 9014 9015 2 6 8832 8737 8738 8834 9015 9016 2 6 8833 8738 8740 8835 9016 9017 2 6 8834 8740 8836 9017 9018 9019 2 6 8835 8740 8741 8837 9019 9020 2 5 8836 8741 8625 8838 9020 2 6 8837 8625 8626 8839 9020 9021 2 6 8838 8626 8840 9021 9022 9023 2 6 8839 8626 8627 8841 9023 9024 2 6 8840 8627 8628 8842 9024 9025 2 6 8841 8628 8629 8630 8843 9025 2 6 8842 8630 8844 9025 9026 9030 2 6 8843 8630 8631 8633 8845 9030 2 6 8844 8633 8846 8847 9031 9030 2 6 8845 8633 8634 8637 8847 8848 2 6 8845 8846 8848 9031 9032 9033 2 6 8847 8846 8637 8849 9042 9033 2 6 8848 8637 8638 8850 9043 9042 2 6 8849 8638 8851 9043 9044 9045 2 6 8850 8638 8639 8852 9045 9048 2 6 8851 8639 7762 7763 8853 9048 2 6 8852 7763 7765 8319 8854 9048 2 6 8853 8319 8321 8855 9047 9048 2 6 8854 8321 8856 9047 9049 9050 2 5 8855 8321 8323 8857 9050 2 7 8856 8323 8324 8328 8858 9050 8860 2 6 8857 8328 8329 8330 8859 8860 2 6 8858 8330 8860 8861 8862 8331 2 6 8858 8859 8861 9050 8857 9051 2 6 8860 8859 8862 8863 9051 9052 2 6 8861 8859 8863 8864 8865 8331 2 6 8861 8862 8864 8877 9058 9052 2 6 8863 8862 8865 8866 8877 8878 2 6 8864 8862 8866 8333 8332 8331 2 6 8864 8865 8333 8867 8878 8879 2 6 8866 8333 8334 8335 8868 8879 2 6 8867 8335 8869 8879 8880 8871 2 6 8868 8335 8336 8338 8870 8871 2 6 8869 8338 8871 8872 8873 8874 2 6 8869 8870 8872 8894 8880 8868 2 6 8871 8870 8873 8896 8894 8897 2 6 8872 8870 8874 8897 8898 8902 2 6 8873 8870 8338 8339 8875 8902 2 6 8874 8339 8347 8902 8349 8348 2 6 8346 8340 8341 8342 8344 8345 2 5 8863 8864 8878 9058 8882 2 6 8877 8864 8866 8879 8881 8882 2 6 8878 8866 8867 8868 8880 8881 2 6 8879 8868 8881 8893 8894 8871 2 6 8879 8880 8878 8882 8883 8893 2 6 8878 8881 8883 8884 9058 8877 2 6 8882 8881 8884 8885 8892 8893 2 6 8882 8883 8885 8886 8887 9058 2 6 8884 8883 8886 8890 8891 8892 2 6 8884 8885 8887 8888 8889 8890 2 6 8884 8886 8888 9058 9057 9059 2 6 8887 8886 8889 9059 9060 9061 2 6 8888 8886 8890 9061 9062 9063 2 6 8889 8886 8885 8891 9063 9064 2 6 8890 8885 8892 9064 9065 9066 2 6 8891 8885 8883 8893 9066 8895 2 6 8892 8883 8881 8880 8894 8895 2 6 8893 8880 8895 8896 8872 8871 2 6 8893 8894 8896 9066 8892 9067 2 6 8895 8894 8872 8897 9067 9068 2 6 8896 8872 8873 8898 8899 9068 2 6 8897 8873 8899 8900 8901 8902 2 6 8897 8898 8900 9068 9069 9070 2 6 8899 8898 8901 9070 9071 8903 2 6 8900 8898 8902 8349 8350 8903 2 6 8901 8898 8873 8874 8875 8349 2 6 8901 8350 8351 8904 9071 8900 2 6 8903 8351 8905 9071 9072 9073 1 6 8904 8351 8352 8906 9073 9074 1 6 8905 8352 8353 8907 9074 9075 1 6 8906 8353 8354 8908 9075 9076 1 6 8907 8354 8909 9076 9077 8911 1 6 8908 8354 8355 8357 8910 8911 1 6 8909 8357 8911 8912 8360 8359 1 6 8909 8910 8912 9077 8908 9078 1 6 8911 8910 8360 8913 9078 9079 1 6 8912 8360 8361 8914 8915 9079 1 6 8913 8361 8362 8915 8916 8363 1 6 8913 8914 8916 9079 9080 9081 1 6 8915 8914 8363 8917 9081 9082 1 6 8916 8363 8364 8918 9082 9083 1 6 8917 8364 8365 8919 9083 9084 1 6 8918 8365 8366 8920 9093 9084 1 6 8919 8366 8367 8921 9093 9100 1 6 8920 8367 8368 8922 9100 9101 1 6 8921 8368 8369 8923 9101 9102 1 6 8922 8369 8370 8924 9102 9103 1 6 8923 8370 8925 9103 9104 9105 1 6 8924 8370 8371 8926 9105 9106 1 6 8925 8371 8372 8374 8927 9106 1 6 8926 8374 8928 9106 9107 8931 1 6 8927 8374 8375 8929 8931 8930 1 6 8928 8375 8376 8377 8379 8930 1 5 8929 8379 8380 8931 8928 1 8 8930 8380 8381 8743 8932 9107 8927 8928 1 5 8931 8743 8744 8933 9107 1 8 8932 8744 8745 8934 9107 9106 9105 9108 1 6 8933 8745 8746 8747 8935 9108 1 6 8934 8747 8936 9108 9109 9110 1 6 8935 8747 8748 8937 9110 9111 1 6 8936 8748 8749 8938 9111 9112 1 6 8937 8749 8750 8939 9112 9113 1 6 8938 8750 8751 8940 9113 9114 1 6 8939 8751 8752 8941 9114 9115 1 6 8940 8752 8753 8942 9115 9116 1 6 8941 8753 8943 9116 9117 8944 1 5 8942 8753 8754 8755 8944 1 7 8943 8755 8756 8945 9117 8942 9118 1 7 8944 8756 8757 8758 8946 9118 9119 1 5 8945 8758 8947 9119 9120 1 6 8946 8758 8759 8948 9120 9121 1 7 8947 8759 8760 8761 8949 9121 9122 1 6 8948 8761 8950 9122 9123 8951 1 6 8949 8761 8762 8763 8764 8951 1 6 8950 8764 8765 8952 9123 8949 1 6 8951 8765 8766 8953 9123 9124 1 6 8952 8766 8954 9124 9125 9126 1 6 8953 8766 8767 8768 8955 9126 1 6 8954 8768 8769 8956 9126 9127 1 6 8955 8769 8957 9127 9128 9129 1 6 8956 8769 8770 8771 8958 9129 1 6 8957 8771 8772 8959 9129 9130 1 6 8958 8772 8773 8960 9130 9131 1 6 8959 8773 8774 8961 9131 9132 1 6 8960 8774 8775 8962 9132 9133 1 6 8961 8775 8776 8963 9133 9134 1 6 8962 8776 8964 9134 9135 9136 1 6 8963 8776 8777 8778 8965 9136 1 6 8964 8778 8779 8966 9136 9137 2 6 8965 8779 8780 8967 9137 9138 2 6 8966 8780 8781 8968 9138 9139 2 6 8967 8781 8782 8969 9139 9140 2 7 8968 8782 8783 8784 8970 9140 9141 2 5 8969 8784 8971 9141 9142 2 7 8970 8784 8785 8972 9142 9143 9144 2 6 8971 8785 8786 8973 9144 9145 2 6 8972 8786 8974 9145 9146 9147 2 6 8973 8786 8787 8788 8975 9147 2 6 8974 8788 8789 8790 8976 9147 2 6 8975 8790 8977 9147 9148 9149 2 6 8976 8790 8791 8792 8978 9149 2 6 8977 8792 8979 9149 9150 9151 2 6 8978 8792 8793 8980 9151 9152 2 6 8979 8793 8795 8796 8981 9152 2 6 8980 8796 8982 9152 9153 8983 2 6 8981 8796 8797 8799 8801 8983 2 6 8982 8801 8984 9153 8981 9154 2 6 8983 8801 8802 8985 9154 9155 2 6 8984 8802 8986 9155 9156 9157 2 7 8985 8802 8803 8804 8987 9157 9158 2 5 8986 8804 8805 8988 9158 2 7 8987 8805 8989 8990 8991 9158 9159 2 5 8988 8805 8806 8807 8990 2 6 8989 8807 8988 8991 8992 8808 2 6 8988 8990 8992 9159 9160 9161 2 6 8991 8990 8808 8993 9164 9161 2 6 8992 8808 8809 8810 8994 9164 2 6 8993 8810 8812 8995 9164 9165 2 7 8994 8812 8813 8996 9165 9167 9168 2 5 8995 8813 8997 9168 9169 2 6 8996 8813 8814 8998 9169 9170 2 7 8997 8814 8815 8816 8999 9170 9171 2 5 8998 8816 8817 9000 9171 2 6 8999 8817 9001 9171 9172 9173 2 6 9000 8817 8818 9002 9173 9003 2 6 9001 8818 8819 8820 8821 9003 2 6 9002 8821 8823 9004 9173 9001 2 6 9003 8823 8824 8826 9005 9173 2 6 9004 8826 9006 9007 9008 9173 2 6 9005 8826 9007 9011 9012 8827 2 6 9005 9006 9008 9009 9010 9011 2 6 9005 9007 9009 9173 9172 9174 2 5 9008 9007 9010 9174 9177 2 6 9009 9007 9011 9013 9177 9014 2 7 9010 9007 9006 9012 9013 8831 8830 2 5 9011 9006 8830 8828 8827 2 5 9010 9011 8831 8832 9014 2 6 9013 8832 9015 9177 9010 9178 2 6 9014 8832 8833 9016 9181 9178 2 5 9015 8833 8834 9017 9181 2 7 9016 8834 8835 9018 9181 9182 9188 2 6 9017 8835 9019 9188 9189 9190 2 6 9018 8835 8836 9020 9190 9191 2 6 9019 8836 8837 8838 9021 9191 2 6 9020 8838 8839 9022 9191 9192 2 6 9021 8839 9023 9192 9195 9196 2 6 9022 8839 8840 9024 9196 9197 2 6 9023 8840 8841 9025 9197 9027 2 6 9024 8841 8842 8843 9026 9027 2 6 9025 8843 9027 9028 9029 9030 2 6 9025 9026 9028 9197 9024 9198 2 6 9027 9026 9029 9198 9199 9203 2 5 9028 9026 9030 9031 9203 2 6 9029 9026 8843 9031 8845 8844 2 7 9029 9030 8845 8847 9032 9203 9204 2 6 9031 8847 9033 9034 9204 9205 2 6 9032 8847 9034 9035 9042 8848 2 6 9032 9033 9035 9036 9037 9205 2 6 9034 9033 9036 9040 9041 9042 2 6 9034 9035 9037 9038 9039 9040 2 6 9034 9036 9038 9205 9206 9207 2 6 9037 9036 9039 9207 9208 9209 2 6 9038 9036 9040 9209 9062 9061 2 6 9039 9036 9035 9041 9061 9060 2 6 9040 9035 9042 9043 9060 9210 2 6 9041 9035 9033 8848 9043 8849 2 6 9041 9042 8849 8850 9044 9210 2 7 9043 8850 9045 9046 9055 9056 9210 2 6 9044 8850 8851 9046 9047 9048 2 6 9044 9045 9047 9053 9055 9049 2 6 9046 9045 9048 8854 8855 9049 2 6 9047 9045 8851 8854 8853 8852 2 6 9047 8855 9050 9051 9053 9046 2 6 9049 8855 8856 8857 8860 9051 2 6 9050 8860 8861 9052 9053 9049 2 6 9051 8861 9053 9054 9058 8863 2 6 9051 9052 9054 9055 9046 9049 2 6 9053 9052 9055 9056 9057 9058 2 5 9053 9054 9046 9044 9056 2 6 9044 9055 9054 9057 9059 9210 2 5 9056 9054 9058 8887 9059 2 8 9057 9054 9052 8863 8877 8882 8884 8887 2 6 9057 8887 8888 9060 9210 9056 2 6 9059 8888 9061 9040 9041 9210 2 6 9060 8888 8889 9062 9039 9040 2 6 9061 8889 9063 9209 9039 9211 2 6 9062 8889 8890 9064 9211 9212 2 6 9063 8890 8891 9065 9212 9213 2 6 9064 8891 9066 9213 9214 9215 2 6 9065 8891 8892 8895 9067 9215 2 6 9066 8895 8896 9068 9215 9216 2 6 9067 8896 8897 8899 9069 9216 2 6 9068 8899 9070 9216 9217 9218 2 6 9069 8899 8900 9071 9218 9219 2 7 9070 8900 8903 8904 9072 9219 9220 2 5 9071 8904 9073 9220 9221 1 7 9072 8904 8905 9074 9221 9222 9223 1 6 9073 8905 8906 9075 9223 9225 1 6 9074 8906 8907 9076 9225 9226 1 5 9075 8907 8908 9077 9226 1 7 9076 8908 8911 9078 9226 9227 9228 1 5 9077 8911 8912 9079 9228 1 6 9078 8912 8913 8915 9080 9228 1 6 9079 8915 9081 9228 9229 9230 1 6 9080 8915 8916 9082 9230 9231 1 6 9081 8916 8917 9083 9231 9232 1 6 9082 8917 8918 9084 9085 9232 1 6 9083 8918 9085 9086 9093 8919 1 6 9083 9084 9086 9087 9232 9233 1 6 9085 9084 9087 9088 9092 9093 1 6 9085 9086 9088 9089 9233 9234 1 6 9087 9086 9089 9090 9091 9092 1 6 9087 9088 9090 9095 9234 9235 1 6 9089 9088 9091 9095 9096 9097 1 6 9090 9088 9092 9097 9098 9099 1 6 9091 9088 9086 9093 9099 9100 1 6 9092 9086 9084 8919 8920 9100 1 5 8469 8470 8485 8476 8471 1 6 9089 9090 9096 9235 9236 9237 1 6 9095 9090 9097 9237 9238 9239 1 6 9096 9090 9091 9098 9239 9240 1 6 9097 9091 9099 9240 9241 9242 1 6 9098 9091 9092 9100 9242 9101 1 6 9099 9092 9093 8920 8921 9101 1 6 9100 8921 8922 9102 9242 9099 1 6 9101 8922 8923 9103 9242 9243 1 6 9102 8923 8924 9104 9243 9244 1 6 9103 8924 9105 9109 9244 9108 1 6 9104 8924 8925 9106 8933 9108 1 6 9105 8925 8926 8927 9107 8933 1 5 9106 8927 8931 8932 8933 1 6 9105 8933 8934 8935 9109 9104 1 5 9108 8935 9110 9244 9104 1 7 9109 8935 8936 9111 9245 9244 9348 1 6 9110 8936 8937 9112 9350 9348 1 5 9111 8937 8938 9113 9350 1 6 9112 8938 8939 9114 9350 9351 1 6 9113 8939 8940 9115 9351 9352 1 6 9114 8940 8941 9116 9352 9353 1 6 9115 8941 8942 9117 9246 9353 1 6 9116 8942 8944 9118 9246 9247 1 6 9117 8944 8945 9119 9247 9248 1 5 9118 8945 8946 9120 9248 1 7 9119 8946 8947 9121 9248 9249 9250 1 6 9120 8947 8948 9122 9250 9251 1 5 9121 8948 8949 9123 9251 1 6 9122 8949 8951 8952 9124 9251 1 6 9123 8952 8953 9125 9251 9252 1 6 9124 8953 9126 9252 9253 9254 1 6 9125 8953 8954 8955 9127 9254 1 6 9126 8955 8956 9128 9254 9255 1 6 9127 8956 9129 9255 9256 9257 1 6 9128 8956 8957 8958 9130 9257 1 6 9129 8958 8959 9131 9257 9258 1 6 9130 8959 8960 9132 9258 9259 1 6 9131 8960 8961 9133 9259 9260 1 6 9132 8961 8962 9134 9260 9261 1 6 9133 8962 8963 9135 9261 9262 1 6 9134 8963 9136 9262 9263 9264 1 6 9135 8963 8964 8965 9137 9264 1 6 9136 8965 8966 9138 9264 9265 2 6 9137 8966 8967 9139 9265 9266 2 6 9138 8967 8968 9140 9266 9267 2 6 9139 8968 8969 9141 9267 9268 2 5 9140 8969 8970 9142 9268 2 7 9141 8970 8971 9143 9268 9269 9270 2 6 9142 8971 9144 9270 9271 9272 2 5 9143 8971 8972 9145 9272 2 6 9144 8972 8973 9146 9272 9273 2 6 9145 8973 9147 9273 9274 9148 2 6 9146 8973 8974 8975 8976 9148 2 6 9147 8976 9149 9274 9146 9275 2 6 9148 8976 8977 8978 9150 9275 2 6 9149 8978 9151 9275 9276 9277 2 6 9150 8978 8979 9152 9277 9278 2 7 9151 8979 8980 8981 9153 9278 9279 2 6 9152 8981 8983 9154 9279 9280 2 6 9153 8983 8984 9155 9280 9281 2 6 9154 8984 8985 9156 9281 9282 2 6 9155 8985 9157 9282 9283 9284 2 6 9156 8985 8986 9158 9284 9285 2 6 9157 8986 8987 8988 9159 9285 2 6 9158 8988 8991 9160 9285 9286 2 6 9159 8991 9161 9162 9286 9287 2 6 9160 8991 9162 9163 9164 8992 2 6 9160 9161 9163 9287 9288 9289 2 6 9162 9161 9164 9165 9166 9289 2 6 9163 9161 8992 8993 8994 9165 2 6 9164 8994 8995 9163 9166 9167 2 6 9163 9165 9167 9289 9290 9186 2 6 9166 9165 8995 9168 9186 9185 2 6 9167 8995 8996 9169 9185 9184 2 7 9168 8996 8997 9170 9184 9179 9176 2 6 9169 8997 8998 9171 9176 9175 2 6 9170 8998 8999 9000 9172 9175 2 6 9171 9000 9173 9008 9174 9175 2 7 9172 9000 9001 9003 9004 9005 9008 2 6 9172 9008 9009 9175 9176 9177 2 5 9172 9174 9176 9170 9171 2 6 9175 9174 9177 9179 9169 9170 2 7 9176 9174 9009 9010 9014 9178 9179 2 6 9177 9014 9179 9180 9181 9015 2 6 9177 9178 9180 9184 9169 9176 2 6 9179 9178 9181 9182 9183 9184 2 6 9180 9178 9015 9016 9017 9182 2 6 9181 9017 9180 9183 9187 9188 2 6 9180 9182 9184 9185 9186 9187 2 6 9180 9183 9185 9168 9169 9179 2 5 9184 9183 9186 9167 9168 2 6 9185 9183 9187 9290 9166 9167 2 6 9186 9183 9182 9188 9290 9291 2 6 9187 9182 9017 9018 9189 9291 2 5 9188 9018 9190 9291 9292 2 6 9189 9018 9019 9191 9292 9193 2 6 9190 9019 9020 9021 9192 9193 2 6 9191 9021 9022 9193 9194 9195 2 6 9191 9192 9194 9292 9190 9293 2 6 9193 9192 9195 9293 9294 9295 2 6 9194 9192 9022 9196 9295 9296 2 6 9195 9022 9023 9197 9302 9296 2 7 9196 9023 9024 9027 9198 9302 9303 2 6 9197 9027 9028 9199 9200 9303 2 6 9198 9028 9200 9201 9202 9203 2 6 9198 9199 9201 9303 9301 9304 2 6 9200 9199 9202 9304 9305 9306 2 6 9201 9199 9203 9306 9307 9204 2 6 9202 9199 9028 9029 9031 9204 2 7 9203 9031 9032 9205 9307 9202 9206 2 5 9204 9032 9034 9037 9206 2 6 9205 9037 9207 9307 9204 9308 2 6 9206 9037 9038 9208 9308 9309 2 6 9207 9038 9209 9309 9310 9314 2 6 9208 9038 9039 9062 9211 9314 2 6 9060 9041 9043 9059 9056 9044 2 6 9209 9062 9063 9212 9314 9315 2 6 9211 9063 9064 9213 9315 9316 2 6 9212 9064 9065 9214 9319 9316 2 6 9213 9065 9215 9319 9320 9321 2 6 9214 9065 9066 9067 9216 9321 2 6 9215 9067 9068 9069 9217 9321 2 7 9216 9069 9218 9321 9320 9322 9323 2 5 9217 9069 9070 9219 9323 2 7 9218 9070 9071 9220 9323 9324 9325 2 5 9219 9071 9072 9221 9325 2 7 9220 9072 9073 9222 9325 9326 9327 1 6 9221 9073 9223 9224 9327 9328 1 5 9222 9073 9074 9224 9225 1 6 9222 9223 9225 9328 9329 9330 1 6 9224 9223 9074 9075 9226 9330 1 7 9225 9075 9076 9077 9227 9330 9331 1 6 9226 9077 9228 9331 9332 9229 1 6 9227 9077 9078 9079 9080 9229 1 7 9228 9080 9230 9332 9227 9333 9334 1 6 9229 9080 9081 9231 9334 9335 1 6 9230 9081 9082 9232 9335 9336 1 7 9231 9082 9083 9085 9233 9336 9337 1 5 9232 9085 9087 9234 9337 1 7 9233 9087 9089 9235 9337 9338 9339 1 5 9234 9089 9095 9236 9339 1 7 9235 9095 9237 9339 9340 9341 9342 1 6 9236 9095 9096 9238 9342 9343 1 6 9237 9096 9239 9343 9344 9345 1 6 9238 9096 9097 9240 9345 9346 1 6 9239 9097 9098 9241 9346 9347 1 6 9240 9098 9242 9347 9245 9243 1 6 9241 9098 9099 9101 9102 9243 1 6 9242 9102 9103 9244 9245 9241 1 6 9243 9103 9245 9110 9109 9104 1 6 9243 9244 9110 9347 9241 9348 1 6 9116 9117 9247 9353 9354 9355 1 6 9246 9117 9118 9248 9355 9356 1 6 9247 9118 9119 9120 9249 9356 1 6 9248 9120 9250 9356 9357 9358 1 6 9249 9120 9121 9251 9358 9252 1 6 9250 9121 9122 9123 9124 9252 1 7 9251 9124 9125 9253 9358 9250 9359 1 5 9252 9125 9254 9359 9360 1 7 9253 9125 9126 9127 9255 9360 9361 1 6 9254 9127 9128 9256 9361 9362 1 6 9255 9128 9257 9362 9363 9364 1 6 9256 9128 9129 9130 9258 9364 1 7 9257 9130 9131 9259 9364 9365 9366 1 6 9258 9131 9132 9260 9366 9367 1 6 9259 9132 9133 9261 9367 9368 1 6 9260 9133 9134 9262 9368 9369 1 6 9261 9134 9135 9263 9369 9370 1 6 9262 9135 9264 9370 9371 9372 1 6 9263 9135 9136 9137 9265 9372 1 6 9264 9137 9138 9266 9372 9373 2 6 9265 9138 9139 9267 9373 9374 2 6 9266 9139 9140 9268 9374 9375 2 7 9267 9140 9141 9142 9269 9375 9376 2 5 9268 9142 9270 9376 9377 2 6 9269 9142 9143 9271 9377 9381 2 6 9270 9143 9272 9381 9382 9383 2 6 9271 9143 9144 9145 9273 9383 2 6 9272 9145 9146 9274 9383 9384 2 6 9273 9146 9148 9275 9384 9385 2 7 9274 9148 9149 9150 9276 9385 9386 2 5 9275 9150 9277 9386 9388 2 6 9276 9150 9151 9278 9388 9389 2 6 9277 9151 9152 9279 9389 9390 2 6 9278 9152 9153 9280 9390 9391 2 5 9279 9153 9154 9281 9391 2 6 9280 9154 9155 9282 9393 9391 2 6 9281 9155 9156 9283 9393 9394 2 6 9282 9156 9284 9394 9395 9396 2 6 9283 9156 9157 9285 9396 9397 2 6 9284 9157 9158 9159 9286 9397 2 6 9285 9159 9160 9287 9397 9398 2 5 9286 9160 9162 9288 9398 2 7 9287 9162 9289 9398 9399 9400 9401 2 6 9288 9162 9163 9166 9290 9401 2 7 9289 9166 9186 9187 9291 9402 9401 2 6 9290 9187 9188 9189 9292 9402 2 7 9291 9189 9190 9193 9293 9402 9400 2 6 9292 9193 9194 9294 9400 9403 2 6 9293 9194 9295 9403 9404 9405 2 6 9294 9194 9195 9296 9297 9405 2 6 9295 9195 9297 9298 9302 9196 2 6 9295 9296 9298 9299 9405 9406 2 6 9297 9296 9299 9300 9301 9302 2 6 9297 9298 9300 9409 9406 9410 2 6 9299 9298 9301 9410 9411 9412 2 7 9300 9298 9302 9303 9200 9304 9412 2 6 9301 9298 9296 9196 9197 9303 2 5 9302 9197 9198 9200 9301 2 5 9301 9200 9201 9305 9412 2 7 9304 9201 9306 9412 9413 9414 9418 2 5 9305 9201 9202 9307 9418 2 6 9306 9202 9204 9206 9308 9418 2 6 9307 9206 9207 9309 9417 9418 2 6 9308 9207 9208 9310 9311 9417 2 6 9309 9208 9311 9312 9313 9314 2 6 9309 9310 9312 9416 9417 9419 2 6 9311 9310 9313 9419 9420 9424 2 7 9312 9310 9314 9424 9425 9317 9315 2 6 9313 9310 9208 9209 9211 9315 2 6 9314 9211 9212 9316 9317 9313 2 6 9315 9212 9317 9318 9319 9213 2 6 9315 9316 9318 9425 9313 9426 2 6 9317 9316 9319 9426 9427 9428 2 6 9318 9316 9213 9214 9320 9428 2 6 9319 9214 9321 9217 9322 9428 2 5 9320 9214 9215 9216 9217 2 6 9320 9217 9323 9428 9429 9430 2 6 9322 9217 9218 9219 9324 9430 2 6 9323 9219 9325 9430 9431 9432 2 6 9324 9219 9220 9221 9326 9432 2 6 9325 9221 9327 9432 9433 9434 2 6 9326 9221 9222 9328 9434 9435 1 5 9327 9222 9224 9329 9435 1 7 9328 9224 9330 9435 9436 9437 9438 1 6 9329 9224 9225 9226 9331 9438 1 6 9330 9226 9227 9332 9438 9439 1 6 9331 9227 9229 9333 9442 9439 1 6 9332 9229 9334 9442 9443 9446 1 5 9333 9229 9230 9335 9446 1 6 9334 9230 9231 9336 9446 9447 1 6 9335 9231 9232 9337 9447 9448 1 6 9336 9232 9233 9234 9338 9448 1 6 9337 9234 9339 9448 9449 9450 1 6 9338 9234 9235 9236 9340 9450 1 6 9339 9236 9341 9450 9451 9452 1 6 9340 9236 9342 9452 9453 9454 1 6 9341 9236 9237 9343 9454 9455 1 5 9342 9237 9238 9344 9455 1 7 9343 9238 9345 9455 9456 9457 9458 1 6 9344 9238 9239 9346 9458 9349 1 5 9345 9239 9240 9347 9349 1 6 9346 9240 9241 9245 9348 9349 1 6 9347 9245 9349 9350 9111 9110 1 7 9347 9348 9350 9458 9345 9346 9351 1 6 9349 9348 9111 9112 9113 9351 1 7 9350 9113 9114 9352 9458 9349 9459 1 6 9351 9114 9115 9353 9459 9460 1 6 9352 9115 9116 9246 9354 9460 1 6 9353 9246 9355 9460 9461 9462 1 6 9354 9246 9247 9356 9462 9463 1 6 9355 9247 9248 9249 9357 9463 1 6 9356 9249 9358 9463 9464 9465 1 6 9357 9249 9250 9252 9359 9465 1 5 9358 9252 9253 9360 9465 1 7 9359 9253 9254 9361 9465 9466 9467 1 5 9360 9254 9255 9362 9467 1 6 9361 9255 9256 9363 9467 9468 1 6 9362 9256 9364 9468 9469 9470 1 6 9363 9256 9257 9258 9365 9470 1 6 9364 9258 9366 9470 9471 9472 1 5 9365 9258 9259 9367 9472 1 6 9366 9259 9260 9368 9472 9473 1 6 9367 9260 9261 9369 9473 9474 1 6 9368 9261 9262 9370 9474 9475 1 6 9369 9262 9263 9371 9475 9476 1 6 9370 9263 9372 9476 9477 9478 1 6 9371 9263 9264 9265 9373 9478 1 6 9372 9265 9266 9374 9478 9479 2 6 9373 9266 9267 9375 9479 9480 2 6 9374 9267 9268 9376 9480 9481 2 6 9375 9268 9269 9377 9378 9481 2 7 9376 9269 9270 9378 9379 9380 9381 2 5 9376 9377 9379 9481 9482 2 6 9378 9377 9380 9482 9483 9484 2 6 9379 9377 9381 9484 9485 9382 2 5 9380 9377 9270 9271 9382 2 6 9381 9271 9383 9485 9380 9486 2 7 9382 9271 9272 9273 9384 9486 9487 2 6 9383 9273 9274 9385 9487 9488 2 6 9384 9274 9275 9386 9387 9488 2 5 9385 9275 9276 9387 9388 2 6 9385 9386 9388 9488 9489 9490 2 7 9387 9386 9276 9277 9389 9490 9491 2 6 9388 9277 9278 9390 9491 9492 2 6 9389 9278 9279 9391 9392 9492 2 6 9390 9279 9392 9393 9281 9280 2 6 9390 9391 9393 9492 9493 9494 2 6 9392 9391 9281 9282 9394 9494 2 6 9393 9282 9283 9395 9494 9495 2 6 9394 9283 9396 9495 9496 9497 2 6 9395 9283 9284 9397 9498 9497 2 6 9396 9284 9285 9286 9398 9498 2 6 9397 9286 9287 9288 9399 9498 2 6 9398 9288 9400 9498 9404 9403 2 7 9399 9288 9401 9402 9292 9293 9403 2 5 9400 9288 9402 9290 9289 2 5 9400 9401 9290 9291 9292 2 5 9400 9293 9294 9404 9399 2 6 9403 9294 9405 9498 9399 9407 2 6 9404 9294 9295 9297 9406 9407 2 6 9405 9297 9407 9408 9409 9299 2 6 9405 9406 9408 9497 9498 9404 2 6 9407 9406 9409 9496 9497 9499 2 6 9408 9406 9299 9410 9499 9500 2 6 9409 9299 9300 9411 9500 9501 2 6 9410 9300 9412 9501 9502 9413 2 6 9411 9300 9301 9304 9305 9413 2 6 9412 9305 9414 9415 9502 9411 2 6 9413 9305 9415 9416 9417 9418 2 6 9413 9414 9416 9502 9503 9504 2 6 9415 9414 9417 9311 9419 9504 2 6 9416 9414 9418 9308 9309 9311 2 6 9417 9414 9308 9307 9306 9305 2 6 9416 9311 9312 9420 9421 9504 2 6 9419 9312 9421 9422 9423 9424 2 6 9419 9420 9422 9504 9505 9506 2 6 9421 9420 9423 9506 9507 9508 2 6 9422 9420 9424 9511 9508 9512 2 6 9423 9420 9312 9313 9425 9512 2 5 9424 9313 9317 9426 9512 2 6 9425 9317 9318 9427 9512 9513 2 6 9426 9318 9428 9513 9514 9429 2 6 9427 9318 9319 9320 9322 9429 2 6 9428 9322 9430 9517 9514 9427 2 6 9429 9322 9323 9324 9431 9517 2 6 9430 9324 9432 9524 9517 9525 2 6 9431 9324 9325 9326 9433 9525 2 6 9432 9326 9434 9525 9526 9527 2 6 9433 9326 9327 9435 9527 9528 2 6 9434 9327 9328 9329 9436 9528 2 6 9435 9329 9437 9528 9530 9531 1 6 9436 9329 9438 9531 9532 9440 1 6 9437 9329 9330 9331 9439 9440 1 6 9438 9331 9440 9441 9442 9332 1 5 9438 9439 9441 9532 9437 1 7 9440 9439 9442 9443 9444 9532 9533 1 5 9441 9439 9332 9333 9443 1 6 9442 9333 9441 9444 9445 9446 1 5 9441 9443 9445 9533 9534 1 6 9444 9443 9446 9534 9535 9536 1 7 9445 9443 9333 9334 9335 9447 9536 1 6 9446 9335 9336 9448 9536 9537 1 6 9447 9336 9337 9338 9449 9537 1 6 9448 9338 9450 9537 9538 9451 1 5 9449 9338 9339 9340 9451 1 7 9450 9340 9452 9538 9449 9539 9540 1 6 9451 9340 9341 9453 9540 9541 1 6 9452 9341 9454 9541 9542 9543 1 6 9453 9341 9342 9455 9543 9544 1 6 9454 9342 9343 9344 9456 9544 1 6 9455 9344 9457 9544 9545 9461 1 6 9456 9344 9458 9461 9460 9459 1 6 9457 9344 9345 9349 9351 9459 1 5 9458 9351 9352 9460 9457 1 6 9459 9352 9353 9354 9461 9457 1 6 9460 9354 9462 9545 9456 9457 1 5 9461 9354 9355 9463 9545 1 7 9462 9355 9356 9357 9464 9545 9546 1 6 9463 9357 9465 9546 9547 9548 1 7 9464 9357 9358 9359 9360 9466 9548 1 6 9465 9360 9467 9548 9549 9550 1 6 9466 9360 9361 9362 9468 9550 1 6 9467 9362 9363 9469 9550 9551 1 6 9468 9363 9470 9551 9552 9553 1 6 9469 9363 9364 9365 9471 9553 1 6 9470 9365 9472 9553 9554 9555 1 6 9471 9365 9366 9367 9473 9555 1 6 9472 9367 9368 9474 9555 9556 1 6 9473 9368 9369 9475 9556 9557 1 6 9474 9369 9370 9476 9557 9558 1 6 9475 9370 9371 9477 9558 9559 1 6 9476 9371 9478 9559 9560 9561 1 6 9477 9371 9372 9373 9479 9561 1 6 9478 9373 9374 9480 9561 9562 2 6 9479 9374 9375 9481 9562 9563 2 6 9480 9375 9376 9378 9482 9563 2 6 9481 9378 9379 9483 9563 9564 2 6 9482 9379 9484 9564 9565 9566 2 6 9483 9379 9380 9485 9566 9567 2 6 9484 9380 9382 9486 9567 9568 2 6 9485 9382 9383 9487 9568 9569 2 6 9486 9383 9384 9488 9569 9570 2 6 9487 9384 9385 9387 9489 9570 2 6 9488 9387 9490 9570 9571 9572 2 6 9489 9387 9388 9491 9572 9573 2 6 9490 9388 9389 9492 9573 9574 2 6 9491 9389 9390 9392 9493 9574 2 6 9492 9392 9494 9574 9575 9576 2 6 9493 9392 9393 9394 9495 9576 2 6 9494 9394 9395 9496 9576 9577 2 6 9495 9395 9497 9408 9499 9577 2 6 9496 9395 9408 9407 9498 9396 2 7 9407 9497 9396 9397 9398 9399 9404 2 5 9496 9408 9409 9500 9577 2 7 9499 9409 9410 9501 9577 9578 9579 2 6 9500 9410 9411 9502 9579 9580 2 6 9501 9411 9413 9415 9503 9580 2 6 9502 9415 9504 9580 9581 9582 2 7 9503 9415 9416 9419 9421 9505 9582 2 5 9504 9421 9506 9582 9583 2 6 9505 9421 9422 9507 9583 9584 2 6 9506 9422 9508 9509 9584 9585 2 6 9507 9422 9509 9510 9511 9423 2 6 9507 9508 9510 9585 9586 9587 2 6 9509 9508 9511 9518 9587 9521 2 6 9510 9508 9423 9512 9518 9519 2 7 9511 9423 9424 9425 9426 9513 9519 2 6 9512 9426 9427 9514 9515 9519 2 6 9513 9427 9515 9516 9517 9429 2 6 9513 9514 9516 9519 9518 9520 2 6 9515 9514 9517 9523 9520 9524 2 6 9516 9514 9429 9430 9524 9431 2 6 9510 9511 9519 9515 9520 9521 2 5 9518 9511 9512 9513 9515 2 6 9518 9515 9521 9522 9523 9516 2 6 9518 9520 9522 9587 9510 9588 2 6 9521 9520 9523 9588 9589 9590 2 6 9522 9520 9516 9524 9590 9591 2 6 9523 9516 9517 9431 9525 9591 2 7 9524 9431 9432 9433 9526 9591 9592 2 5 9525 9433 9527 9592 9593 2 6 9526 9433 9434 9528 9529 9593 2 6 9527 9434 9435 9436 9529 9530 2 6 9527 9528 9530 9593 9594 9595 2 6 9529 9528 9436 9531 9595 9596 2 6 9530 9436 9437 9532 9596 9597 1 7 9531 9437 9440 9441 9533 9597 9598 1 5 9532 9441 9444 9534 9598 1 7 9533 9444 9445 9535 9598 9599 9600 1 6 9534 9445 9536 9600 9601 9602 1 7 9535 9445 9446 9447 9537 9602 9603 1 6 9536 9447 9448 9449 9538 9603 1 6 9537 9449 9451 9539 9603 9604 1 6 9538 9451 9540 9604 9605 9606 1 6 9539 9451 9452 9541 9606 9607 1 5 9540 9452 9453 9542 9607 1 7 9541 9453 9543 9607 9608 9609 9610 1 5 9542 9453 9454 9544 9610 1 7 9543 9454 9455 9456 9545 9610 9546 1 6 9544 9456 9461 9462 9463 9546 1 6 9545 9463 9464 9547 9610 9544 1 6 9546 9464 9548 9610 9609 9549 1 5 9547 9464 9465 9466 9549 1 6 9548 9466 9550 9609 9547 9611 1 6 9549 9466 9467 9468 9551 9611 1 6 9550 9468 9469 9552 9611 9612 1 6 9551 9469 9553 9612 9613 9614 1 6 9552 9469 9470 9471 9554 9614 1 6 9553 9471 9555 9614 9615 9616 1 6 9554 9471 9472 9473 9556 9616 1 6 9555 9473 9474 9557 9616 9617 1 6 9556 9474 9475 9558 9617 9618 1 6 9557 9475 9476 9559 9618 9619 1 6 9558 9476 9477 9560 9619 9620 1 6 9559 9477 9561 9620 9621 9622 1 6 9560 9477 9478 9479 9562 9622 1 6 9561 9479 9480 9563 9622 9623 2 6 9562 9480 9481 9482 9564 9623 2 6 9563 9482 9483 9565 9623 9624 2 6 9564 9483 9566 9624 9625 9626 2 6 9565 9483 9484 9567 9626 9627 2 6 9566 9484 9485 9568 9627 9628 2 7 9567 9485 9486 9569 9628 9629 9630 2 6 9568 9486 9487 9570 9630 9631 2 6 9569 9487 9488 9489 9571 9631 2 6 9570 9489 9572 9631 9632 9633 2 6 9571 9489 9490 9573 9633 9634 2 6 9572 9490 9491 9574 9634 9635 2 6 9573 9491 9492 9493 9575 9635 2 6 9574 9493 9576 9635 9636 9578 2 6 9575 9493 9494 9495 9577 9578 2 6 9576 9495 9496 9499 9500 9578 2 6 9577 9500 9579 9636 9575 9576 2 6 9578 9500 9501 9580 9636 9581 2 5 9579 9501 9502 9503 9581 2 6 9580 9503 9582 9636 9579 9637 2 6 9581 9503 9504 9505 9583 9637 2 6 9582 9505 9506 9584 9637 9638 2 6 9583 9506 9507 9585 9638 9633 2 6 9584 9507 9509 9586 9633 9632 2 6 9585 9509 9587 9632 9639 9629 2 6 9586 9509 9510 9521 9588 9629 2 6 9587 9521 9522 9589 9629 9628 2 6 9588 9522 9590 9628 9627 9640 2 6 9589 9522 9523 9591 9640 9641 2 6 9590 9523 9524 9525 9592 9641 2 6 9591 9525 9526 9593 9641 9642 2 7 9592 9526 9527 9529 9594 9642 9643 2 5 9593 9529 9595 9643 9644 2 6 9594 9529 9530 9596 9644 9645 2 6 9595 9530 9531 9597 9645 9646 1 6 9596 9531 9532 9598 9646 9647 1 6 9597 9532 9533 9534 9599 9647 1 5 9598 9534 9600 9647 9648 1 7 9599 9534 9535 9601 9648 9649 9650 1 5 9600 9535 9602 9650 9651 1 6 9601 9535 9536 9603 9651 9604 1 5 9602 9536 9537 9538 9604 1 6 9603 9538 9539 9605 9651 9602 1 6 9604 9539 9606 9651 9652 9653 1 6 9605 9539 9540 9607 9653 9613 1 6 9606 9540 9541 9542 9608 9613 1 6 9607 9542 9609 9613 9612 9611 1 6 9608 9542 9610 9547 9549 9611 1 6 9609 9542 9543 9544 9546 9547 1 6 9609 9549 9550 9551 9612 9608 1 5 9611 9551 9552 9613 9608 1 7 9612 9552 9614 9653 9606 9607 9608 1 6 9613 9552 9553 9554 9615 9653 1 6 9614 9554 9616 9653 9652 9654 1 6 9615 9554 9555 9556 9617 9654 1 6 9616 9556 9557 9618 9654 9655 1 6 9617 9557 9558 9619 9655 9656 1 6 9618 9558 9559 9620 9656 9657 1 6 9619 9559 9560 9621 9657 9658 1 6 9620 9560 9622 9658 9659 9660 1 6 9621 9560 9561 9562 9623 9660 2 6 9622 9562 9563 9564 9624 9660 2 7 9623 9564 9565 9625 9660 9661 9662 2 5 9624 9565 9626 9662 9663 2 7 9625 9565 9566 9627 9663 9664 9640 2 6 9626 9566 9567 9628 9589 9640 2 6 9627 9567 9568 9629 9588 9589 2 7 9628 9568 9630 9639 9586 9587 9588 2 5 9629 9568 9569 9631 9639 2 6 9630 9569 9570 9571 9632 9639 2 6 9631 9571 9633 9585 9586 9639 2 7 9632 9571 9572 9634 9638 9584 9585 2 6 9633 9572 9573 9635 9637 9638 2 6 9634 9573 9574 9575 9636 9637 2 6 9635 9575 9578 9579 9581 9637 2 7 9636 9581 9582 9583 9638 9635 9634 2 5 9637 9583 9584 9633 9634 2 5 9632 9586 9629 9630 9631 2 6 9627 9589 9590 9641 9664 9626 2 6 9640 9590 9591 9592 9642 9664 2 6 9641 9592 9593 9643 9664 9663 2 6 9642 9593 9594 9644 9663 9662 2 7 9643 9594 9595 9645 9662 9661 9665 2 7 9644 9595 9596 9646 9665 9659 9666 1 6 9645 9596 9597 9647 9666 9667 1 6 9646 9597 9598 9599 9648 9667 1 6 9647 9599 9600 9649 9667 9668 1 6 9648 9600 9650 9668 9656 9655 1 6 9649 9600 9601 9651 9655 9669 1 7 9650 9601 9602 9604 9605 9652 9669 1 6 9651 9605 9653 9615 9654 9669 1 6 9652 9605 9606 9613 9614 9615 1 6 9652 9615 9616 9617 9655 9669 1 7 9654 9617 9618 9656 9649 9650 9669 1 6 9655 9618 9619 9657 9668 9649 1 5 9656 9619 9620 9658 9668 1 6 9657 9620 9621 9659 9668 9666 1 6 9658 9621 9660 9665 9645 9666 2 7 9659 9621 9622 9623 9624 9661 9665 2 5 9660 9624 9662 9644 9665 2 6 9661 9624 9625 9663 9643 9644 2 6 9662 9625 9626 9664 9642 9643 2 5 9663 9626 9640 9641 9642 2 5 9661 9644 9645 9659 9660 1 6 9659 9645 9646 9667 9668 9658 1 5 9666 9646 9647 9648 9668 1 7 9667 9648 9649 9656 9657 9658 9666 1 5 9655 9650 9651 9652 9654 1 6 6653 6650 6651 9671 9691 9681 1 6 9670 6651 9672 9676 9680 9681 1 6 9671 6651 9673 9674 9675 9676 1 6 9672 6651 9674 6649 9727 6365 1 6 9672 9673 9675 9725 9726 9727 1 6 9672 9674 9676 9677 9678 9725 1 6 9672 9675 9677 9679 9680 9671 1 5 9676 9675 9678 5235 9679 1 7 9677 9675 5235 9734 4519 9725 9733 1 6 9677 5235 5236 9676 9680 9683 1 7 9676 9679 9671 9681 9682 4654 9683 1 6 9671 9680 9682 9691 9670 9685 1 5 9681 9680 4654 4655 9685 1 6 4654 9680 9679 5236 4652 9684 1 6 4652 9683 4650 422 5237 5236 1 6 9682 4655 9686 9687 9691 9681 1 6 9685 4655 9687 3169 9688 4656 1 6 9685 9686 3169 3170 9691 3172 1 7 3169 9686 4656 9689 3168 2843 9690 1 5 9688 4656 5380 430 9690 1 6 2843 9688 9689 430 2841 429 1 6 9685 9687 3172 6653 9670 9681 1 6 6475 6478 6474 9779 9774 9780 1 6 6460 6461 6465 6467 6377 6378 1 6 5862 5863 9695 9702 9703 9700 1 6 9694 5863 5864 9696 5719 9700 1 5 9695 5864 5865 5718 5719 1 6 5718 5865 5866 5867 9698 9699 1 6 9697 5867 9699 5695 5694 5868 1 5 9697 9698 5695 5696 5718 1 6 9695 5719 5720 9701 9702 9694 1 5 9700 5720 5721 5724 9702 1 6 9701 5724 6095 9703 9694 9700 1 6 9702 6095 6383 9694 5862 5861 1 6 6490 2252 415 2194 6488 6489 1 7 6488 2195 6487 6480 2196 9773 9778 1 5 2251 6491 3336 6492 3335 1 6 3335 6492 3334 6499 6493 6494 1 6 6502 6503 9709 2189 9711 9712 1 6 6502 9708 2189 6501 9710 2190 1 6 6501 9709 6500 2190 2191 2512 1 7 9708 6503 6512 9712 9715 9716 9717 1 5 9708 9711 2189 9713 9715 1 6 2189 9712 2187 2197 9714 9715 1 6 2197 9713 9715 2215 2216 9720 1 6 9714 9713 9712 9711 9716 2215 1 7 9715 9711 9717 9718 9719 2214 2215 1 6 9716 9711 6512 6513 6514 9718 1 5 9717 6514 6516 9719 9716 1 5 9718 6516 9716 2214 6522 1 6 9714 2216 2217 2200 2198 2197 1 6 6669 6775 9722 9723 6656 6658 1 5 9721 6775 9723 9724 9798 1 6 9721 9722 9724 6646 6656 6655 1 6 9723 9722 6646 6645 9799 9798 1 6 9675 9674 9726 9678 9733 9735 1 6 9725 9674 9727 9729 9735 9728 1 6 9726 9674 9673 6365 6366 9728 1 6 9727 6366 6368 6370 9729 9726 1 6 9728 6370 9730 9731 9735 9726 1 6 9729 6370 6371 6375 6467 9731 1 6 9730 6467 6466 9732 9735 9729 1 6 9731 6466 6468 7510 9733 9735 1 6 9732 7510 9734 9735 9678 9725 1 6 9733 7510 7508 4518 4519 9678 1 6 9732 9733 9731 9729 9726 9725 1 6 6041 6039 6038 6019 5872 5874 1 6 6132 6398 6392 6393 6115 9738 1 6 9737 6115 6116 6132 6131 6122 1 6 569 571 9740 9744 568 9743 1 6 9739 571 573 9741 9742 9743 1 6 9740 573 916 917 9742 918 1 6 9740 9741 918 9743 921 919 1 6 9740 9742 921 563 9744 9739 1 6 9743 563 564 567 568 9739 2 6 7205 7206 9746 7218 7217 7216 2 6 9745 7206 7207 7213 7216 7214 1 6 3491 3492 3496 3502 6706 6555 1 5 6706 3502 9749 3503 6710 1 5 6706 9748 6710 6707 6705 1 5 6682 5157 4667 6681 9761 1 5 3201 3470 3410 3200 3411 1 6 5932 5910 5915 5916 9755 5931 1 5 4915 4917 9754 4880 4879 1 7 9753 4917 4911 4880 9756 4904 9759 1 7 9752 5916 5931 5921 5920 5919 9758 1 6 4880 9754 9757 4895 4897 9759 1 5 4880 9756 4895 4884 4881 1 5 5919 9755 5918 5916 5917 1 6 9754 4904 4901 4898 4897 9756 1 6 4638 4912 4875 4872 4869 4868 1 7 6681 9750 4667 4668 9762 4560 9792 1 5 9761 4668 4546 4548 4560 1 5 8468 8469 9764 9765 8486 1 5 8468 9763 9765 7726 7962 1 7 9764 9763 8486 7714 7715 7723 7726 2 6 8023 8021 7738 7739 7740 7742 1 5 7723 7715 7716 7719 7721 1 6 427 7500 7502 9769 46 45 1 6 9768 7502 9770 9772 44 45 1 7 9769 7502 7503 9771 9772 9774 9780 1 7 2196 43 1 9772 9770 9773 9774 1 5 9771 1 9770 9769 44 1 6 2196 9771 9774 9705 9778 9779 1 6 9773 9771 9770 9779 9692 9780 1 6 7253 7256 7523 7520 7517 7516 1 6 2095 2083 2084 6093 3138 3131 1 5 6638 6639 6642 6787 6785 1 5 9705 9773 9779 6478 6480 1 5 9778 9773 9774 9692 6478 1 5 9692 9774 6474 9770 7503 1 6 3852 3129 26 25 1526 3130 1 6 6787 6642 6643 9783 6789 6170 1 5 9782 6643 6168 6169 6170 2 6 4396 4529 4395 4121 4119 4530 1 6 6637 6783 6779 6636 6635 6771 2 6 4118 3529 3531 9787 9789 4120 2 6 9786 3531 3533 9788 7174 9789 2 6 9787 3533 3535 7178 7175 7174 2 6 9787 7174 9786 4120 4122 7172 1 5 7670 7695 7696 7698 7669 2 6 7775 3145 4231 3413 3414 7776 1 6 4560 6675 6676 6677 6681 9761 1 6 3659 3660 4908 9794 4369 4371 1 5 9793 4908 4642 4370 4369 1 6 5543 5545 5700 5540 5541 5542 1 6 6177 6178 9797 9798 6181 9799 1 6 6782 6177 9796 9798 6776 6780 1 7 9797 9796 6776 9799 9724 9722 6775 1 6 9796 6181 6183 6645 9724 9798 scotch-6.0.4.dfsg/src/check/data/bump_old.map0000644002563400244210000022077112057040317024156 0ustar trophimeutilisateurs du domaine9800 0 24 1 18 2 0 3 14 4 11 5 30 6 24 7 24 8 24 9 24 10 24 11 24 12 24 13 24 14 24 15 27 16 27 17 27 18 27 19 27 20 27 21 27 22 27 23 27 24 27 25 27 26 27 27 27 28 27 29 27 30 27 31 27 32 27 33 27 34 27 35 27 36 27 37 18 38 18 39 18 40 18 41 18 42 18 43 18 44 18 45 18 46 18 47 18 48 18 49 18 50 18 51 18 52 16 53 16 54 16 55 16 56 16 57 16 58 16 59 16 60 16 61 16 62 16 63 16 64 16 65 16 66 16 67 16 68 16 69 16 70 0 71 0 72 0 73 0 74 0 75 0 76 0 77 0 78 0 79 0 80 0 81 0 82 0 83 0 84 2 85 2 86 2 87 2 88 2 89 2 90 2 91 2 92 2 93 2 94 2 95 2 96 3 97 3 98 3 99 3 100 3 101 3 102 3 103 3 104 3 105 3 106 3 107 3 108 3 109 3 110 3 111 3 112 3 113 13 114 13 115 13 116 13 117 13 118 13 119 13 120 13 121 13 122 13 123 13 124 14 125 14 126 14 127 14 128 14 129 14 130 14 131 14 132 14 133 14 134 14 135 14 136 14 137 14 138 14 139 14 140 14 141 14 142 14 143 14 144 14 145 14 146 14 147 14 148 14 149 14 150 14 151 14 152 14 153 14 154 14 155 14 156 14 157 15 158 15 159 15 160 15 161 15 162 15 163 15 164 15 165 15 166 15 167 15 168 15 169 15 170 15 171 15 172 15 173 15 174 15 175 15 176 8 177 8 178 8 179 8 180 8 181 8 182 8 183 8 184 8 185 8 186 8 187 8 188 11 189 11 190 11 191 11 192 11 193 11 194 11 195 11 196 11 197 11 198 11 199 11 200 11 201 11 202 11 203 11 204 11 205 11 206 11 207 11 208 11 209 11 210 11 211 11 212 11 213 11 214 11 215 11 216 11 217 11 218 11 219 11 220 11 221 11 222 11 223 11 224 10 225 10 226 10 227 10 228 10 229 10 230 10 231 10 232 10 233 10 234 10 235 10 236 10 237 10 238 10 239 10 240 10 241 10 242 10 243 10 244 10 245 10 246 10 247 4 248 4 249 4 250 4 251 4 252 4 253 4 254 4 255 4 256 4 257 4 258 5 259 5 260 5 261 5 262 5 263 5 264 5 265 5 266 5 267 5 268 5 269 5 270 5 271 5 272 20 273 20 274 20 275 20 276 20 277 20 278 20 279 20 280 20 281 20 282 20 283 20 284 20 285 20 286 20 287 20 288 20 289 22 290 22 291 22 292 22 293 22 294 22 295 22 296 22 297 22 298 22 299 22 300 22 301 22 302 22 303 22 304 22 305 22 306 22 307 22 308 22 309 22 310 22 311 22 312 22 313 22 314 28 315 28 316 28 317 28 318 28 319 28 320 28 321 28 322 28 323 28 324 30 325 30 326 30 327 30 328 30 329 30 330 30 331 30 332 30 333 30 334 30 335 30 336 30 337 30 338 30 339 30 340 30 341 30 342 30 343 30 344 30 345 30 346 30 347 30 348 30 349 30 350 30 351 30 352 30 353 30 354 30 355 30 356 31 357 31 358 31 359 31 360 31 361 31 362 31 363 31 364 31 365 31 366 31 367 31 368 31 369 31 370 31 371 31 372 25 373 25 374 25 375 25 376 25 377 25 378 25 379 25 380 25 381 25 382 25 383 25 384 25 385 25 386 24 387 24 388 24 389 24 390 24 391 24 392 24 393 24 394 24 395 24 396 24 397 24 398 24 399 24 400 24 401 24 402 24 403 24 404 24 405 24 406 24 407 24 408 16 409 0 410 18 411 18 412 24 413 24 414 27 415 18 416 18 417 24 418 24 419 24 420 24 421 18 422 18 423 24 424 24 425 25 426 18 427 18 428 0 429 16 430 16 431 4 432 5 433 5 434 5 435 5 436 5 437 5 438 5 439 5 440 5 441 5 442 5 443 5 444 5 445 5 446 20 447 20 448 20 449 20 450 20 451 20 452 20 453 20 454 20 455 20 456 20 457 20 458 20 459 20 460 20 461 20 462 22 463 22 464 22 465 22 466 22 467 22 468 22 469 22 470 22 471 22 472 22 473 22 474 22 475 22 476 22 477 22 478 22 479 22 480 22 481 22 482 22 483 22 484 22 485 22 486 22 487 28 488 28 489 28 490 28 491 28 492 28 493 28 494 28 495 28 496 28 497 28 498 30 499 30 500 30 501 30 502 30 503 30 504 30 505 30 506 30 507 30 508 30 509 30 510 30 511 30 512 30 513 30 514 30 515 30 516 30 517 30 518 30 519 30 520 30 521 30 522 30 523 30 524 30 525 30 526 30 527 30 528 30 529 31 530 31 531 31 532 31 533 31 534 31 535 31 536 31 537 31 538 31 539 31 540 31 541 31 542 31 543 31 544 31 545 25 546 25 547 25 548 25 549 25 550 25 551 25 552 25 553 25 554 25 555 25 556 25 557 25 558 25 559 25 560 25 561 25 562 25 563 25 564 25 565 25 566 25 567 25 568 25 569 25 570 25 571 25 572 25 573 25 574 25 575 24 576 24 577 24 578 24 579 24 580 24 581 24 582 24 583 24 584 24 585 24 586 24 587 24 588 24 589 24 590 24 591 24 592 24 593 24 594 24 595 24 596 24 597 24 598 24 599 24 600 24 601 24 602 24 603 24 604 24 605 24 606 24 607 24 608 24 609 24 610 24 611 24 612 24 613 24 614 24 615 24 616 24 617 24 618 24 619 24 620 24 621 24 622 24 623 24 624 24 625 24 626 24 627 24 628 24 629 24 630 24 631 24 632 24 633 24 634 24 635 24 636 24 637 24 638 24 639 24 640 24 641 24 642 24 643 24 644 24 645 24 646 24 647 24 648 24 649 24 650 24 651 15 652 15 653 15 654 15 655 15 656 15 657 15 658 15 659 15 660 15 661 15 662 15 663 15 664 8 665 8 666 8 667 8 668 8 669 8 670 8 671 8 672 8 673 8 674 8 675 11 676 11 677 11 678 11 679 11 680 11 681 11 682 11 683 11 684 11 685 11 686 11 687 11 688 11 689 11 690 11 691 11 692 11 693 11 694 11 695 11 696 11 697 11 698 11 699 11 700 11 701 11 702 11 703 11 704 11 705 11 706 11 707 11 708 11 709 10 710 10 711 10 712 10 713 10 714 10 715 10 716 10 717 10 718 10 719 10 720 10 721 10 722 10 723 10 724 10 725 10 726 10 727 10 728 10 729 10 730 10 731 10 732 4 733 4 734 4 735 4 736 4 737 4 738 4 739 4 740 4 741 4 742 4 743 4 744 4 745 5 746 5 747 5 748 5 749 5 750 5 751 5 752 5 753 5 754 5 755 5 756 5 757 5 758 20 759 20 760 20 761 20 762 20 763 20 764 20 765 20 766 20 767 20 768 20 769 20 770 20 771 20 772 20 773 20 774 20 775 22 776 22 777 22 778 22 779 22 780 22 781 22 782 22 783 22 784 22 785 22 786 22 787 22 788 22 789 22 790 22 791 22 792 22 793 22 794 22 795 22 796 22 797 22 798 22 799 28 800 28 801 28 802 28 803 28 804 28 805 28 806 28 807 28 808 28 809 28 810 28 811 30 812 30 813 30 814 30 815 30 816 30 817 30 818 30 819 30 820 30 821 30 822 30 823 30 824 30 825 30 826 30 827 30 828 30 829 30 830 30 831 30 832 30 833 30 834 30 835 30 836 30 837 30 838 30 839 30 840 31 841 31 842 31 843 31 844 31 845 31 846 31 847 31 848 31 849 31 850 31 851 31 852 31 853 31 854 31 855 31 856 31 857 31 858 31 859 25 860 25 861 25 862 25 863 25 864 25 865 25 866 25 867 25 868 25 869 25 870 25 871 25 872 25 873 25 874 25 875 25 876 25 877 25 878 25 879 25 880 25 881 25 882 25 883 25 884 25 885 25 886 25 887 25 888 25 889 25 890 25 891 25 892 25 893 25 894 25 895 24 896 24 897 24 898 25 899 24 900 24 901 25 902 24 903 25 904 24 905 24 906 24 907 24 908 24 909 24 910 24 911 24 912 24 913 24 914 24 915 24 916 25 917 25 918 25 919 25 920 25 921 25 922 25 923 14 924 14 925 14 926 15 927 15 928 15 929 15 930 15 931 15 932 15 933 15 934 15 935 15 936 15 937 15 938 15 939 15 940 15 941 15 942 15 943 15 944 15 945 15 946 8 947 8 948 8 949 8 950 8 951 8 952 8 953 8 954 8 955 8 956 8 957 11 958 11 959 11 960 11 961 11 962 11 963 11 964 11 965 11 966 11 967 11 968 11 969 11 970 11 971 11 972 11 973 11 974 11 975 11 976 11 977 11 978 11 979 11 980 11 981 11 982 11 983 11 984 11 985 11 986 11 987 11 988 10 989 10 990 10 991 10 992 10 993 10 994 10 995 10 996 10 997 10 998 10 999 10 1000 10 1001 10 1002 10 1003 10 1004 10 1005 10 1006 10 1007 10 1008 10 1009 10 1010 10 1011 4 1012 4 1013 4 1014 4 1015 4 1016 4 1017 4 1018 4 1019 4 1020 4 1021 4 1022 4 1023 4 1024 4 1025 4 1026 4 1027 5 1028 5 1029 5 1030 5 1031 5 1032 5 1033 5 1034 5 1035 5 1036 5 1037 5 1038 5 1039 20 1040 20 1041 20 1042 20 1043 20 1044 20 1045 20 1046 20 1047 20 1048 20 1049 20 1050 20 1051 20 1052 20 1053 20 1054 20 1055 20 1056 22 1057 22 1058 22 1059 22 1060 22 1061 22 1062 22 1063 22 1064 22 1065 22 1066 22 1067 22 1068 22 1069 22 1070 22 1071 22 1072 22 1073 22 1074 22 1075 22 1076 22 1077 22 1078 22 1079 22 1080 22 1081 28 1082 28 1083 28 1084 28 1085 28 1086 28 1087 28 1088 28 1089 28 1090 28 1091 28 1092 28 1093 30 1094 30 1095 30 1096 30 1097 30 1098 30 1099 30 1100 30 1101 30 1102 30 1103 30 1104 30 1105 30 1106 30 1107 30 1108 30 1109 30 1110 30 1111 30 1112 30 1113 30 1114 30 1115 30 1116 30 1117 30 1118 30 1119 30 1120 30 1121 31 1122 31 1123 31 1124 31 1125 31 1126 31 1127 31 1128 31 1129 31 1130 31 1131 31 1132 31 1133 31 1134 31 1135 31 1136 31 1137 31 1138 31 1139 25 1140 25 1141 25 1142 25 1143 25 1144 25 1145 25 1146 25 1147 25 1148 25 1149 25 1150 25 1151 25 1152 31 1153 31 1154 31 1155 31 1156 31 1157 25 1158 25 1159 25 1160 2 1161 2 1162 2 1163 2 1164 25 1165 25 1166 25 1167 25 1168 25 1169 25 1170 25 1171 27 1172 27 1173 27 1174 2 1175 2 1176 2 1177 2 1178 2 1179 2 1180 2 1181 2 1182 2 1183 2 1184 2 1185 2 1186 2 1187 2 1188 2 1189 2 1190 2 1191 2 1192 3 1193 3 1194 3 1195 3 1196 3 1197 3 1198 3 1199 3 1200 3 1201 3 1202 3 1203 3 1204 3 1205 3 1206 3 1207 3 1208 13 1209 13 1210 13 1211 13 1212 13 1213 13 1214 13 1215 13 1216 13 1217 13 1218 13 1219 13 1220 14 1221 14 1222 14 1223 14 1224 14 1225 14 1226 14 1227 14 1228 14 1229 14 1230 14 1231 14 1232 14 1233 14 1234 14 1235 14 1236 14 1237 14 1238 14 1239 14 1240 14 1241 14 1242 14 1243 14 1244 14 1245 14 1246 14 1247 14 1248 14 1249 14 1250 14 1251 14 1252 14 1253 15 1254 15 1255 15 1256 15 1257 15 1258 15 1259 15 1260 15 1261 15 1262 15 1263 15 1264 15 1265 15 1266 15 1267 15 1268 15 1269 15 1270 15 1271 15 1272 8 1273 8 1274 8 1275 8 1276 8 1277 8 1278 8 1279 8 1280 8 1281 8 1282 8 1283 11 1284 11 1285 11 1286 11 1287 11 1288 11 1289 11 1290 11 1291 11 1292 11 1293 11 1294 11 1295 11 1296 11 1297 11 1298 11 1299 11 1300 11 1301 11 1302 11 1303 11 1304 11 1305 11 1306 11 1307 11 1308 11 1309 11 1310 11 1311 11 1312 10 1313 10 1314 10 1315 10 1316 10 1317 10 1318 10 1319 10 1320 10 1321 10 1322 10 1323 10 1324 10 1325 10 1326 10 1327 10 1328 10 1329 10 1330 10 1331 10 1332 10 1333 10 1334 10 1335 10 1336 4 1337 4 1338 4 1339 4 1340 4 1341 4 1342 4 1343 4 1344 4 1345 4 1346 4 1347 4 1348 4 1349 4 1350 4 1351 5 1352 5 1353 5 1354 5 1355 5 1356 5 1357 5 1358 5 1359 5 1360 5 1361 5 1362 5 1363 20 1364 20 1365 20 1366 20 1367 20 1368 20 1369 20 1370 20 1371 20 1372 20 1373 20 1374 20 1375 20 1376 20 1377 20 1378 20 1379 20 1380 22 1381 22 1382 22 1383 22 1384 22 1385 22 1386 22 1387 22 1388 22 1389 22 1390 22 1391 22 1392 22 1393 22 1394 22 1395 22 1396 22 1397 22 1398 22 1399 22 1400 22 1401 22 1402 22 1403 22 1404 22 1405 28 1406 28 1407 28 1408 28 1409 28 1410 28 1411 28 1412 28 1413 28 1414 28 1415 28 1416 28 1417 30 1418 30 1419 30 1420 30 1421 30 1422 30 1423 30 1424 30 1425 30 1426 30 1427 30 1428 30 1429 30 1430 30 1431 30 1432 30 1433 30 1434 30 1435 30 1436 30 1437 30 1438 30 1439 30 1440 30 1441 30 1442 31 1443 31 1444 31 1445 31 1446 31 1447 31 1448 31 1449 31 1450 31 1451 31 1452 31 1453 31 1454 31 1455 31 1456 31 1457 3 1458 3 1459 3 1460 3 1461 31 1462 31 1463 31 1464 31 1465 31 1466 31 1467 31 1468 31 1469 31 1470 31 1471 31 1472 31 1473 31 1474 0 1475 0 1476 0 1477 0 1478 0 1479 0 1480 0 1481 0 1482 2 1483 2 1484 2 1485 2 1486 2 1487 2 1488 2 1489 2 1490 31 1491 31 1492 31 1493 25 1494 25 1495 25 1496 25 1497 25 1498 25 1499 25 1500 3 1501 3 1502 0 1503 0 1504 2 1505 2 1506 24 1507 24 1508 24 1509 24 1510 24 1511 24 1512 24 1513 24 1514 24 1515 24 1516 24 1517 24 1518 24 1519 24 1520 24 1521 24 1522 24 1523 24 1524 27 1525 27 1526 27 1527 25 1528 25 1529 25 1530 25 1531 25 1532 25 1533 25 1534 25 1535 25 1536 24 1537 24 1538 24 1539 24 1540 24 1541 25 1542 24 1543 24 1544 24 1545 24 1546 13 1547 13 1548 13 1549 13 1550 13 1551 13 1552 13 1553 13 1554 13 1555 13 1556 13 1557 13 1558 13 1559 13 1560 13 1561 13 1562 24 1563 24 1564 24 1565 24 1566 24 1567 24 1568 24 1569 24 1570 24 1571 26 1572 26 1573 24 1574 24 1575 24 1576 24 1577 24 1578 24 1579 24 1580 24 1581 24 1582 24 1583 24 1584 24 1585 24 1586 24 1587 24 1588 24 1589 24 1590 24 1591 24 1592 24 1593 24 1594 24 1595 24 1596 24 1597 24 1598 24 1599 24 1600 24 1601 24 1602 24 1603 0 1604 0 1605 0 1606 0 1607 0 1608 0 1609 0 1610 0 1611 0 1612 0 1613 0 1614 0 1615 0 1616 0 1617 0 1618 0 1619 0 1620 0 1621 0 1622 0 1623 0 1624 0 1625 0 1626 0 1627 0 1628 0 1629 0 1630 0 1631 0 1632 0 1633 0 1634 0 1635 0 1636 0 1637 0 1638 0 1639 0 1640 2 1641 2 1642 2 1643 2 1644 2 1645 2 1646 2 1647 2 1648 2 1649 2 1650 2 1651 2 1652 2 1653 2 1654 2 1655 2 1656 2 1657 2 1658 2 1659 2 1660 2 1661 2 1662 2 1663 2 1664 2 1665 2 1666 2 1667 2 1668 3 1669 2 1670 2 1671 3 1672 3 1673 3 1674 3 1675 3 1676 3 1677 3 1678 3 1679 3 1680 3 1681 3 1682 3 1683 3 1684 3 1685 3 1686 3 1687 3 1688 3 1689 3 1690 3 1691 3 1692 3 1693 3 1694 13 1695 13 1696 13 1697 13 1698 13 1699 13 1700 13 1701 13 1702 13 1703 13 1704 13 1705 13 1706 13 1707 13 1708 13 1709 13 1710 13 1711 13 1712 13 1713 13 1714 13 1715 13 1716 13 1717 14 1718 14 1719 14 1720 14 1721 14 1722 14 1723 14 1724 14 1725 14 1726 14 1727 14 1728 14 1729 14 1730 14 1731 14 1732 14 1733 14 1734 14 1735 14 1736 14 1737 14 1738 14 1739 14 1740 14 1741 14 1742 14 1743 14 1744 14 1745 14 1746 14 1747 14 1748 14 1749 14 1750 14 1751 14 1752 14 1753 15 1754 15 1755 15 1756 15 1757 15 1758 15 1759 15 1760 15 1761 15 1762 15 1763 15 1764 15 1765 15 1766 15 1767 15 1768 15 1769 15 1770 15 1771 15 1772 8 1773 8 1774 8 1775 8 1776 8 1777 8 1778 8 1779 8 1780 8 1781 8 1782 11 1783 11 1784 11 1785 11 1786 11 1787 11 1788 11 1789 11 1790 11 1791 11 1792 11 1793 11 1794 11 1795 11 1796 11 1797 11 1798 11 1799 11 1800 11 1801 11 1802 10 1803 10 1804 10 1805 10 1806 10 1807 10 1808 10 1809 10 1810 10 1811 10 1812 10 1813 10 1814 10 1815 10 1816 10 1817 10 1818 10 1819 10 1820 10 1821 10 1822 10 1823 10 1824 10 1825 10 1826 4 1827 4 1828 4 1829 4 1830 4 1831 4 1832 4 1833 4 1834 4 1835 4 1836 4 1837 4 1838 4 1839 4 1840 4 1841 4 1842 5 1843 5 1844 5 1845 5 1846 5 1847 5 1848 5 1849 5 1850 5 1851 5 1852 5 1853 5 1854 20 1855 20 1856 20 1857 20 1858 20 1859 20 1860 20 1861 20 1862 20 1863 20 1864 20 1865 20 1866 20 1867 20 1868 20 1869 20 1870 20 1871 22 1872 22 1873 22 1874 22 1875 22 1876 22 1877 22 1878 22 1879 22 1880 22 1881 22 1882 22 1883 22 1884 22 1885 22 1886 22 1887 22 1888 22 1889 22 1890 22 1891 22 1892 22 1893 22 1894 22 1895 22 1896 28 1897 28 1898 28 1899 28 1900 28 1901 28 1902 28 1903 28 1904 28 1905 28 1906 28 1907 28 1908 30 1909 30 1910 30 1911 30 1912 30 1913 30 1914 30 1915 30 1916 30 1917 30 1918 30 1919 30 1920 30 1921 30 1922 30 1923 30 1924 30 1925 30 1926 30 1927 30 1928 30 1929 30 1930 30 1931 31 1932 31 1933 31 1934 31 1935 31 1936 31 1937 31 1938 31 1939 31 1940 31 1941 31 1942 31 1943 31 1944 31 1945 31 1946 31 1947 31 1948 31 1949 31 1950 31 1951 25 1952 25 1953 25 1954 25 1955 25 1956 25 1957 25 1958 25 1959 25 1960 25 1961 25 1962 25 1963 25 1964 25 1965 25 1966 20 1967 20 1968 20 1969 20 1970 20 1971 20 1972 20 1973 20 1974 20 1975 20 1976 20 1977 20 1978 20 1979 20 1980 20 1981 20 1982 22 1983 22 1984 22 1985 22 1986 22 1987 22 1988 22 1989 22 1990 22 1991 22 1992 22 1993 22 1994 22 1995 22 1996 22 1997 22 1998 22 1999 22 2000 22 2001 22 2002 22 2003 22 2004 22 2005 22 2006 28 2007 28 2008 28 2009 28 2010 28 2011 28 2012 28 2013 28 2014 28 2015 28 2016 28 2017 28 2018 30 2019 30 2020 30 2021 30 2022 30 2023 30 2024 30 2025 30 2026 30 2027 30 2028 30 2029 30 2030 30 2031 30 2032 30 2033 30 2034 30 2035 30 2036 30 2037 30 2038 30 2039 30 2040 31 2041 31 2042 31 2043 31 2044 31 2045 31 2046 31 2047 31 2048 31 2049 31 2050 31 2051 31 2052 31 2053 31 2054 31 2055 31 2056 31 2057 25 2058 25 2059 25 2060 25 2061 25 2062 25 2063 25 2064 25 2065 25 2066 25 2067 25 2068 25 2069 25 2070 25 2071 25 2072 25 2073 25 2074 25 2075 25 2076 25 2077 25 2078 25 2079 25 2080 25 2081 25 2082 25 2083 25 2084 25 2085 24 2086 25 2087 25 2088 25 2089 25 2090 25 2091 25 2092 25 2093 25 2094 25 2095 25 2096 25 2097 24 2098 11 2099 11 2100 11 2101 11 2102 11 2103 11 2104 11 2105 11 2106 11 2107 11 2108 11 2109 11 2110 11 2111 10 2112 10 2113 10 2114 10 2115 10 2116 10 2117 10 2118 10 2119 10 2120 10 2121 10 2122 10 2123 10 2124 10 2125 10 2126 10 2127 10 2128 10 2129 10 2130 10 2131 10 2132 10 2133 10 2134 10 2135 10 2136 4 2137 4 2138 4 2139 4 2140 4 2141 4 2142 4 2143 4 2144 4 2145 4 2146 4 2147 4 2148 4 2149 4 2150 4 2151 10 2152 10 2153 10 2154 4 2155 4 2156 4 2157 4 2158 4 2159 4 2160 4 2161 4 2162 4 2163 4 2164 4 2165 4 2166 4 2167 4 2168 4 2169 4 2170 5 2171 5 2172 14 2173 14 2174 14 2175 14 2176 14 2177 14 2178 14 2179 27 2180 27 2181 27 2182 27 2183 27 2184 27 2185 27 2186 27 2187 27 2188 27 2189 27 2190 27 2191 27 2192 27 2193 27 2194 18 2195 18 2196 18 2197 27 2198 27 2199 27 2200 27 2201 27 2202 27 2203 27 2204 27 2205 27 2206 27 2207 27 2208 27 2209 27 2210 27 2211 27 2212 27 2213 27 2214 27 2215 27 2216 27 2217 27 2218 16 2219 16 2220 16 2221 16 2222 16 2223 13 2224 13 2225 13 2226 13 2227 13 2228 13 2229 13 2230 13 2231 13 2232 13 2233 14 2234 14 2235 14 2236 14 2237 14 2238 13 2239 13 2240 13 2241 2 2242 14 2243 14 2244 14 2245 14 2246 14 2247 14 2248 27 2249 27 2250 27 2251 27 2252 18 2253 14 2254 15 2255 15 2256 15 2257 15 2258 15 2259 15 2260 15 2261 15 2262 15 2263 15 2264 15 2265 15 2266 15 2267 15 2268 15 2269 15 2270 15 2271 15 2272 8 2273 8 2274 8 2275 8 2276 8 2277 8 2278 8 2279 8 2280 8 2281 8 2282 8 2283 11 2284 11 2285 11 2286 11 2287 11 2288 11 2289 11 2290 11 2291 11 2292 11 2293 11 2294 11 2295 11 2296 11 2297 11 2298 11 2299 11 2300 11 2301 11 2302 11 2303 11 2304 11 2305 11 2306 11 2307 10 2308 10 2309 10 2310 10 2311 10 2312 10 2313 10 2314 10 2315 10 2316 10 2317 10 2318 10 2319 10 2320 10 2321 10 2322 10 2323 10 2324 10 2325 10 2326 10 2327 10 2328 10 2329 10 2330 10 2331 4 2332 4 2333 4 2334 4 2335 4 2336 4 2337 4 2338 4 2339 4 2340 4 2341 4 2342 4 2343 4 2344 4 2345 4 2346 5 2347 5 2348 5 2349 5 2350 5 2351 5 2352 5 2353 5 2354 5 2355 5 2356 5 2357 5 2358 5 2359 5 2360 5 2361 20 2362 20 2363 20 2364 20 2365 20 2366 20 2367 20 2368 20 2369 20 2370 20 2371 20 2372 20 2373 20 2374 20 2375 20 2376 20 2377 20 2378 20 2379 22 2380 22 2381 22 2382 22 2383 22 2384 22 2385 22 2386 22 2387 22 2388 22 2389 22 2390 22 2391 22 2392 22 2393 22 2394 22 2395 22 2396 22 2397 22 2398 22 2399 22 2400 22 2401 22 2402 28 2403 28 2404 28 2405 28 2406 28 2407 28 2408 28 2409 28 2410 28 2411 28 2412 28 2413 28 2414 28 2415 30 2416 30 2417 30 2418 30 2419 30 2420 30 2421 30 2422 30 2423 30 2424 30 2425 30 2426 30 2427 30 2428 30 2429 30 2430 30 2431 30 2432 30 2433 30 2434 30 2435 31 2436 31 2437 31 2438 31 2439 31 2440 31 2441 31 2442 31 2443 31 2444 31 2445 31 2446 31 2447 31 2448 31 2449 31 2450 31 2451 31 2452 31 2453 31 2454 31 2455 25 2456 25 2457 25 2458 25 2459 25 2460 25 2461 25 2462 25 2463 25 2464 25 2465 25 2466 25 2467 25 2468 25 2469 25 2470 25 2471 25 2472 25 2473 25 2474 24 2475 24 2476 24 2477 25 2478 25 2479 2 2480 2 2481 2 2482 25 2483 25 2484 25 2485 25 2486 25 2487 25 2488 25 2489 25 2490 2 2491 0 2492 0 2493 0 2494 2 2495 2 2496 2 2497 2 2498 2 2499 2 2500 2 2501 2 2502 27 2503 27 2504 27 2505 27 2506 27 2507 27 2508 27 2509 27 2510 27 2511 27 2512 27 2513 22 2514 22 2515 22 2516 28 2517 28 2518 28 2519 28 2520 28 2521 28 2522 28 2523 28 2524 28 2525 28 2526 28 2527 28 2528 28 2529 28 2530 30 2531 30 2532 30 2533 30 2534 30 2535 30 2536 30 2537 30 2538 30 2539 30 2540 30 2541 30 2542 30 2543 30 2544 30 2545 16 2546 16 2547 16 2548 16 2549 16 2550 16 2551 16 2552 30 2553 30 2554 30 2555 30 2556 30 2557 30 2558 30 2559 31 2560 13 2561 13 2562 13 2563 13 2564 13 2565 14 2566 14 2567 14 2568 14 2569 14 2570 30 2571 15 2572 15 2573 15 2574 15 2575 15 2576 15 2577 15 2578 15 2579 15 2580 8 2581 8 2582 8 2583 8 2584 8 2585 8 2586 8 2587 8 2588 8 2589 8 2590 8 2591 8 2592 11 2593 11 2594 11 2595 11 2596 11 2597 11 2598 11 2599 11 2600 11 2601 11 2602 11 2603 11 2604 11 2605 11 2606 11 2607 11 2608 11 2609 11 2610 11 2611 11 2612 11 2613 11 2614 10 2615 10 2616 10 2617 10 2618 10 2619 10 2620 10 2621 10 2622 10 2623 10 2624 10 2625 10 2626 10 2627 10 2628 10 2629 10 2630 10 2631 10 2632 10 2633 10 2634 10 2635 10 2636 10 2637 10 2638 10 2639 10 2640 10 2641 10 2642 4 2643 4 2644 4 2645 4 2646 4 2647 4 2648 4 2649 4 2650 4 2651 4 2652 4 2653 4 2654 4 2655 4 2656 4 2657 5 2658 5 2659 5 2660 5 2661 5 2662 5 2663 5 2664 5 2665 5 2666 5 2667 5 2668 5 2669 5 2670 5 2671 5 2672 5 2673 5 2674 20 2675 20 2676 20 2677 20 2678 20 2679 20 2680 20 2681 20 2682 20 2683 20 2684 20 2685 20 2686 20 2687 20 2688 20 2689 20 2690 20 2691 22 2692 22 2693 22 2694 22 2695 22 2696 22 2697 22 2698 22 2699 22 2700 22 2701 22 2702 22 2703 22 2704 22 2705 22 2706 22 2707 22 2708 22 2709 22 2710 22 2711 22 2712 22 2713 28 2714 28 2715 28 2716 28 2717 28 2718 28 2719 28 2720 28 2721 28 2722 28 2723 28 2724 28 2725 28 2726 28 2727 30 2728 30 2729 30 2730 30 2731 30 2732 30 2733 30 2734 30 2735 30 2736 30 2737 30 2738 30 2739 30 2740 30 2741 30 2742 30 2743 31 2744 31 2745 31 2746 31 2747 31 2748 31 2749 31 2750 31 2751 14 2752 14 2753 14 2754 14 2755 14 2756 14 2757 14 2758 14 2759 14 2760 14 2761 14 2762 15 2763 15 2764 15 2765 15 2766 15 2767 15 2768 15 2769 15 2770 15 2771 15 2772 15 2773 15 2774 15 2775 15 2776 15 2777 15 2778 15 2779 15 2780 8 2781 8 2782 8 2783 8 2784 8 2785 8 2786 8 2787 8 2788 8 2789 8 2790 8 2791 8 2792 11 2793 11 2794 11 2795 11 2796 11 2797 11 2798 11 2799 11 2800 11 2801 11 2802 11 2803 11 2804 14 2805 14 2806 14 2807 14 2808 14 2809 2 2810 2 2811 2 2812 2 2813 2 2814 2 2815 2 2816 3 2817 2 2818 2 2819 3 2820 3 2821 3 2822 3 2823 3 2824 11 2825 11 2826 11 2827 11 2828 11 2829 11 2830 11 2831 11 2832 11 2833 11 2834 10 2835 10 2836 10 2837 10 2838 10 2839 10 2840 10 2841 16 2842 16 2843 16 2844 16 2845 16 2846 16 2847 16 2848 16 2849 16 2850 16 2851 16 2852 16 2853 16 2854 16 2855 16 2856 16 2857 16 2858 16 2859 16 2860 16 2861 0 2862 0 2863 0 2864 0 2865 0 2866 0 2867 2 2868 2 2869 2 2870 2 2871 2 2872 2 2873 2 2874 2 2875 2 2876 2 2877 2 2878 2 2879 2 2880 2 2881 2 2882 2 2883 2 2884 2 2885 2 2886 2 2887 2 2888 2 2889 2 2890 2 2891 2 2892 2 2893 14 2894 14 2895 14 2896 14 2897 14 2898 14 2899 14 2900 14 2901 14 2902 14 2903 14 2904 14 2905 15 2906 15 2907 15 2908 15 2909 15 2910 15 2911 15 2912 15 2913 15 2914 15 2915 15 2916 15 2917 15 2918 15 2919 15 2920 15 2921 15 2922 15 2923 8 2924 8 2925 8 2926 8 2927 8 2928 8 2929 8 2930 8 2931 8 2932 8 2933 8 2934 8 2935 8 2936 11 2937 11 2938 11 2939 11 2940 11 2941 11 2942 11 2943 11 2944 11 2945 11 2946 11 2947 11 2948 11 2949 11 2950 11 2951 11 2952 11 2953 10 2954 10 2955 10 2956 10 2957 10 2958 10 2959 10 2960 10 2961 10 2962 10 2963 10 2964 10 2965 10 2966 10 2967 10 2968 10 2969 10 2970 10 2971 10 2972 10 2973 10 2974 10 2975 10 2976 10 2977 10 2978 10 2979 4 2980 4 2981 4 2982 4 2983 4 2984 4 2985 4 2986 4 2987 4 2988 4 2989 4 2990 4 2991 4 2992 4 2993 5 2994 5 2995 5 2996 5 2997 5 2998 5 2999 5 3000 5 3001 5 3002 5 3003 22 3004 22 3005 22 3006 22 3007 22 3008 22 3009 22 3010 22 3011 22 3012 22 3013 28 3014 28 3015 28 3016 28 3017 28 3018 28 3019 28 3020 28 3021 28 3022 28 3023 28 3024 28 3025 28 3026 28 3027 30 3028 30 3029 30 3030 30 3031 30 3032 30 3033 30 3034 30 3035 30 3036 30 3037 30 3038 30 3039 30 3040 30 3041 31 3042 30 3043 30 3044 30 3045 31 3046 31 3047 31 3048 31 3049 31 3050 31 3051 31 3052 31 3053 31 3054 31 3055 31 3056 31 3057 31 3058 31 3059 31 3060 31 3061 31 3062 31 3063 31 3064 31 3065 31 3066 31 3067 31 3068 31 3069 31 3070 31 3071 31 3072 31 3073 25 3074 25 3075 25 3076 25 3077 25 3078 25 3079 25 3080 25 3081 25 3082 25 3083 25 3084 25 3085 25 3086 27 3087 27 3088 27 3089 27 3090 27 3091 25 3092 25 3093 0 3094 0 3095 27 3096 27 3097 2 3098 24 3099 24 3100 24 3101 24 3102 24 3103 24 3104 27 3105 27 3106 27 3107 25 3108 25 3109 25 3110 25 3111 25 3112 25 3113 24 3114 24 3115 24 3116 24 3117 27 3118 27 3119 27 3120 27 3121 27 3122 27 3123 27 3124 27 3125 27 3126 27 3127 27 3128 27 3129 27 3130 27 3131 25 3132 25 3133 25 3134 25 3135 25 3136 25 3137 25 3138 25 3139 2 3140 2 3141 2 3142 2 3143 3 3144 3 3145 3 3146 3 3147 3 3148 25 3149 25 3150 25 3151 25 3152 25 3153 25 3154 25 3155 25 3156 25 3157 26 3158 26 3159 26 3160 26 3161 25 3162 16 3163 16 3164 16 3165 16 3166 16 3167 16 3168 16 3169 16 3170 16 3171 16 3172 16 3173 16 3174 16 3175 16 3176 16 3177 16 3178 16 3179 16 3180 16 3181 2 3182 2 3183 2 3184 0 3185 0 3186 0 3187 0 3188 0 3189 2 3190 2 3191 14 3192 0 3193 0 3194 0 3195 0 3196 0 3197 14 3198 14 3199 14 3200 14 3201 14 3202 14 3203 14 3204 14 3205 14 3206 14 3207 14 3208 14 3209 15 3210 15 3211 15 3212 15 3213 15 3214 0 3215 0 3216 0 3217 24 3218 24 3219 24 3220 24 3221 24 3222 24 3223 24 3224 24 3225 24 3226 24 3227 24 3228 24 3229 24 3230 24 3231 24 3232 24 3233 24 3234 24 3235 24 3236 24 3237 24 3238 24 3239 24 3240 24 3241 24 3242 11 3243 11 3244 11 3245 11 3246 10 3247 10 3248 10 3249 10 3250 10 3251 10 3252 10 3253 10 3254 10 3255 10 3256 10 3257 10 3258 10 3259 10 3260 10 3261 10 3262 10 3263 10 3264 10 3265 10 3266 10 3267 10 3268 10 3269 10 3270 10 3271 4 3272 4 3273 4 3274 4 3275 4 3276 4 3277 4 3278 20 3279 20 3280 22 3281 22 3282 22 3283 22 3284 22 3285 22 3286 22 3287 22 3288 22 3289 22 3290 22 3291 22 3292 22 3293 22 3294 22 3295 22 3296 22 3297 22 3298 22 3299 22 3300 22 3301 28 3302 28 3303 28 3304 28 3305 28 3306 28 3307 28 3308 28 3309 28 3310 28 3311 28 3312 28 3313 28 3314 28 3315 28 3316 30 3317 30 3318 30 3319 30 3320 30 3321 30 3322 30 3323 30 3324 30 3325 30 3326 31 3327 31 3328 31 3329 31 3330 27 3331 27 3332 27 3333 27 3334 27 3335 27 3336 27 3337 27 3338 27 3339 27 3340 27 3341 27 3342 27 3343 27 3344 27 3345 27 3346 27 3347 27 3348 27 3349 25 3350 25 3351 25 3352 25 3353 25 3354 25 3355 25 3356 25 3357 25 3358 25 3359 25 3360 25 3361 25 3362 25 3363 25 3364 25 3365 25 3366 25 3367 25 3368 25 3369 25 3370 25 3371 29 3372 29 3373 25 3374 25 3375 29 3376 29 3377 29 3378 29 3379 29 3380 25 3381 29 3382 25 3383 29 3384 29 3385 29 3386 29 3387 26 3388 26 3389 26 3390 26 3391 20 3392 20 3393 20 3394 20 3395 14 3396 14 3397 14 3398 14 3399 14 3400 14 3401 14 3402 14 3403 14 3404 14 3405 14 3406 14 3407 14 3408 14 3409 14 3410 14 3411 14 3412 3 3413 3 3414 3 3415 3 3416 13 3417 13 3418 13 3419 13 3420 13 3421 13 3422 13 3423 13 3424 13 3425 13 3426 13 3427 13 3428 13 3429 13 3430 13 3431 13 3432 13 3433 13 3434 13 3435 13 3436 0 3437 0 3438 0 3439 0 3440 0 3441 0 3442 13 3443 13 3444 13 3445 13 3446 13 3447 13 3448 13 3449 14 3450 16 3451 16 3452 16 3453 16 3454 14 3455 14 3456 14 3457 14 3458 14 3459 14 3460 14 3461 14 3462 14 3463 14 3464 14 3465 14 3466 14 3467 14 3468 14 3469 14 3470 14 3471 14 3472 14 3473 14 3474 14 3475 14 3476 14 3477 14 3478 14 3479 15 3480 15 3481 15 3482 15 3483 15 3484 24 3485 24 3486 24 3487 24 3488 24 3489 24 3490 24 3491 24 3492 24 3493 24 3494 24 3495 24 3496 24 3497 24 3498 24 3499 15 3500 15 3501 24 3502 24 3503 24 3504 24 3505 16 3506 16 3507 16 3508 0 3509 0 3510 0 3511 0 3512 0 3513 0 3514 0 3515 0 3516 0 3517 0 3518 0 3519 0 3520 0 3521 0 3522 0 3523 0 3524 0 3525 0 3526 0 3527 0 3528 0 3529 0 3530 0 3531 0 3532 0 3533 0 3534 0 3535 0 3536 0 3537 0 3538 0 3539 0 3540 0 3541 0 3542 0 3543 0 3544 0 3545 4 3546 4 3547 4 3548 4 3549 4 3550 4 3551 4 3552 5 3553 5 3554 5 3555 5 3556 5 3557 5 3558 5 3559 5 3560 5 3561 5 3562 5 3563 5 3564 5 3565 5 3566 5 3567 5 3568 5 3569 5 3570 5 3571 5 3572 5 3573 20 3574 20 3575 20 3576 20 3577 20 3578 20 3579 20 3580 20 3581 20 3582 20 3583 20 3584 20 3585 20 3586 20 3587 20 3588 20 3589 20 3590 20 3591 20 3592 22 3593 22 3594 22 3595 22 3596 22 3597 22 3598 22 3599 22 3600 22 3601 22 3602 22 3603 22 3604 22 3605 22 3606 22 3607 22 3608 22 3609 22 3610 22 3611 22 3612 28 3613 28 3614 28 3615 28 3616 28 3617 28 3618 28 3619 28 3620 28 3621 28 3622 28 3623 28 3624 28 3625 28 3626 28 3627 28 3628 30 3629 30 3630 30 3631 30 3632 30 3633 30 3634 30 3635 30 3636 30 3637 31 3638 31 3639 31 3640 31 3641 31 3642 31 3643 31 3644 31 3645 29 3646 29 3647 29 3648 29 3649 29 3650 29 3651 26 3652 26 3653 26 3654 26 3655 26 3656 25 3657 29 3658 29 3659 29 3660 26 3661 26 3662 26 3663 26 3664 26 3665 26 3666 26 3667 25 3668 25 3669 26 3670 26 3671 26 3672 26 3673 26 3674 26 3675 26 3676 26 3677 25 3678 25 3679 14 3680 14 3681 14 3682 14 3683 14 3684 24 3685 14 3686 14 3687 14 3688 14 3689 14 3690 15 3691 15 3692 15 3693 15 3694 15 3695 15 3696 15 3697 15 3698 15 3699 15 3700 15 3701 15 3702 15 3703 15 3704 15 3705 15 3706 15 3707 15 3708 15 3709 15 3710 15 3711 8 3712 8 3713 8 3714 8 3715 8 3716 8 3717 8 3718 8 3719 8 3720 8 3721 8 3722 8 3723 8 3724 8 3725 11 3726 11 3727 11 3728 11 3729 11 3730 11 3731 11 3732 11 3733 11 3734 11 3735 11 3736 11 3737 11 3738 11 3739 11 3740 11 3741 11 3742 10 3743 10 3744 10 3745 10 3746 10 3747 10 3748 10 3749 10 3750 10 3751 10 3752 10 3753 10 3754 10 3755 10 3756 10 3757 10 3758 10 3759 10 3760 24 3761 24 3762 24 3763 24 3764 24 3765 24 3766 24 3767 24 3768 24 3769 26 3770 16 3771 16 3772 0 3773 0 3774 3 3775 3 3776 3 3777 3 3778 3 3779 3 3780 3 3781 3 3782 3 3783 3 3784 3 3785 3 3786 13 3787 13 3788 3 3789 13 3790 3 3791 13 3792 13 3793 13 3794 13 3795 13 3796 13 3797 13 3798 13 3799 13 3800 13 3801 13 3802 13 3803 13 3804 13 3805 13 3806 13 3807 13 3808 13 3809 4 3810 4 3811 5 3812 5 3813 5 3814 5 3815 5 3816 5 3817 5 3818 5 3819 5 3820 5 3821 5 3822 5 3823 5 3824 4 3825 4 3826 4 3827 4 3828 4 3829 4 3830 4 3831 4 3832 4 3833 4 3834 4 3835 4 3836 4 3837 5 3838 5 3839 5 3840 5 3841 5 3842 5 3843 5 3844 5 3845 5 3846 5 3847 5 3848 5 3849 5 3850 5 3851 27 3852 27 3853 5 3854 5 3855 5 3856 5 3857 5 3858 5 3859 5 3860 5 3861 27 3862 27 3863 27 3864 5 3865 5 3866 5 3867 5 3868 5 3869 5 3870 5 3871 5 3872 5 3873 5 3874 5 3875 5 3876 5 3877 5 3878 5 3879 5 3880 27 3881 27 3882 27 3883 27 3884 27 3885 27 3886 27 3887 27 3888 5 3889 5 3890 5 3891 5 3892 14 3893 14 3894 14 3895 14 3896 14 3897 14 3898 14 3899 14 3900 14 3901 14 3902 14 3903 30 3904 30 3905 31 3906 31 3907 31 3908 31 3909 31 3910 31 3911 31 3912 31 3913 31 3914 31 3915 31 3916 31 3917 25 3918 25 3919 25 3920 31 3921 31 3922 31 3923 31 3924 29 3925 29 3926 25 3927 31 3928 31 3929 31 3930 31 3931 31 3932 31 3933 31 3934 31 3935 31 3936 31 3937 31 3938 31 3939 31 3940 31 3941 29 3942 29 3943 29 3944 26 3945 26 3946 26 3947 26 3948 26 3949 26 3950 26 3951 26 3952 13 3953 13 3954 13 3955 13 3956 13 3957 13 3958 0 3959 0 3960 0 3961 1 3962 26 3963 26 3964 25 3965 26 3966 25 3967 25 3968 24 3969 24 3970 24 3971 24 3972 15 3973 15 3974 15 3975 15 3976 15 3977 15 3978 15 3979 15 3980 15 3981 15 3982 15 3983 15 3984 8 3985 8 3986 8 3987 8 3988 8 3989 8 3990 8 3991 8 3992 8 3993 8 3994 8 3995 8 3996 8 3997 8 3998 8 3999 11 4000 11 4001 11 4002 11 4003 11 4004 11 4005 11 4006 11 4007 11 4008 11 4009 11 4010 11 4011 11 4012 11 4013 11 4014 11 4015 11 4016 11 4017 10 4018 10 4019 10 4020 10 4021 9 4022 10 4023 10 4024 10 4025 10 4026 10 4027 10 4028 10 4029 10 4030 9 4031 9 4032 10 4033 9 4034 9 4035 9 4036 9 4037 10 4038 24 4039 24 4040 24 4041 9 4042 9 4043 9 4044 9 4045 10 4046 10 4047 10 4048 10 4049 10 4050 10 4051 10 4052 10 4053 10 4054 10 4055 10 4056 10 4057 4 4058 4 4059 4 4060 4 4061 4 4062 4 4063 4 4064 4 4065 4 4066 4 4067 4 4068 4 4069 4 4070 11 4071 11 4072 11 4073 11 4074 11 4075 11 4076 11 4077 11 4078 8 4079 8 4080 8 4081 8 4082 9 4083 9 4084 9 4085 9 4086 2 4087 2 4088 2 4089 2 4090 2 4091 2 4092 2 4093 2 4094 2 4095 2 4096 0 4097 0 4098 0 4099 0 4100 13 4101 13 4102 13 4103 13 4104 13 4105 13 4106 13 4107 13 4108 13 4109 13 4110 13 4111 13 4112 13 4113 13 4114 14 4115 14 4116 0 4117 0 4118 0 4119 0 4120 0 4121 0 4122 0 4123 0 4124 0 4125 0 4126 0 4127 16 4128 16 4129 16 4130 16 4131 16 4132 16 4133 16 4134 16 4135 16 4136 16 4137 16 4138 16 4139 16 4140 0 4141 20 4142 20 4143 20 4144 20 4145 20 4146 20 4147 20 4148 20 4149 20 4150 20 4151 20 4152 20 4153 22 4154 22 4155 22 4156 22 4157 22 4158 22 4159 22 4160 22 4161 22 4162 22 4163 22 4164 22 4165 22 4166 22 4167 22 4168 22 4169 22 4170 22 4171 22 4172 28 4173 28 4174 28 4175 28 4176 28 4177 28 4178 28 4179 28 4180 28 4181 28 4182 28 4183 28 4184 28 4185 28 4186 28 4187 28 4188 28 4189 30 4190 30 4191 30 4192 30 4193 30 4194 30 4195 30 4196 31 4197 31 4198 31 4199 31 4200 31 4201 31 4202 31 4203 31 4204 31 4205 31 4206 31 4207 31 4208 10 4209 10 4210 9 4211 9 4212 9 4213 9 4214 9 4215 9 4216 9 4217 9 4218 9 4219 9 4220 9 4221 10 4222 10 4223 10 4224 4 4225 4 4226 4 4227 4 4228 4 4229 4 4230 4 4231 3 4232 9 4233 4 4234 4 4235 4 4236 5 4237 5 4238 13 4239 13 4240 13 4241 13 4242 13 4243 13 4244 13 4245 13 4246 13 4247 13 4248 13 4249 13 4250 27 4251 5 4252 5 4253 5 4254 5 4255 5 4256 5 4257 5 4258 5 4259 5 4260 5 4261 5 4262 5 4263 20 4264 20 4265 20 4266 20 4267 20 4268 20 4269 20 4270 20 4271 20 4272 20 4273 20 4274 20 4275 20 4276 20 4277 20 4278 20 4279 20 4280 20 4281 23 4282 23 4283 23 4284 23 4285 23 4286 23 4287 22 4288 22 4289 22 4290 22 4291 22 4292 22 4293 22 4294 22 4295 22 4296 22 4297 22 4298 22 4299 22 4300 22 4301 28 4302 28 4303 28 4304 28 4305 28 4306 28 4307 28 4308 28 4309 28 4310 28 4311 28 4312 28 4313 28 4314 28 4315 28 4316 28 4317 28 4318 30 4319 30 4320 30 4321 30 4322 30 4323 31 4324 31 4325 31 4326 31 4327 31 4328 31 4329 31 4330 31 4331 31 4332 31 4333 31 4334 31 4335 31 4336 31 4337 31 4338 31 4339 29 4340 29 4341 29 4342 29 4343 29 4344 29 4345 29 4346 29 4347 29 4348 29 4349 29 4350 29 4351 29 4352 29 4353 29 4354 29 4355 29 4356 29 4357 29 4358 29 4359 29 4360 29 4361 29 4362 29 4363 29 4364 29 4365 0 4366 0 4367 0 4368 29 4369 29 4370 29 4371 29 4372 0 4373 0 4374 0 4375 0 4376 0 4377 0 4378 2 4379 2 4380 2 4381 2 4382 2 4383 2 4384 2 4385 2 4386 2 4387 2 4388 2 4389 2 4390 2 4391 14 4392 14 4393 14 4394 14 4395 0 4396 0 4397 16 4398 16 4399 16 4400 16 4401 16 4402 14 4403 14 4404 14 4405 5 4406 5 4407 5 4408 5 4409 5 4410 16 4411 16 4412 16 4413 16 4414 16 4415 16 4416 13 4417 13 4418 13 4419 13 4420 5 4421 5 4422 5 4423 5 4424 5 4425 5 4426 5 4427 5 4428 5 4429 31 4430 31 4431 29 4432 29 4433 29 4434 29 4435 29 4436 29 4437 29 4438 29 4439 8 4440 8 4441 8 4442 8 4443 8 4444 8 4445 11 4446 11 4447 11 4448 11 4449 11 4450 11 4451 11 4452 11 4453 8 4454 8 4455 8 4456 8 4457 9 4458 9 4459 9 4460 9 4461 9 4462 9 4463 9 4464 9 4465 9 4466 9 4467 9 4468 9 4469 10 4470 10 4471 9 4472 9 4473 9 4474 9 4475 9 4476 9 4477 9 4478 9 4479 9 4480 9 4481 9 4482 9 4483 9 4484 9 4485 4 4486 4 4487 4 4488 4 4489 4 4490 9 4491 9 4492 9 4493 9 4494 4 4495 4 4496 4 4497 4 4498 4 4499 4 4500 4 4501 4 4502 4 4503 13 4504 13 4505 13 4506 13 4507 13 4508 13 4509 13 4510 13 4511 4 4512 4 4513 4 4514 18 4515 18 4516 18 4517 18 4518 18 4519 18 4520 18 4521 18 4522 16 4523 16 4524 16 4525 16 4526 16 4527 16 4528 16 4529 0 4530 0 4531 0 4532 16 4533 16 4534 16 4535 16 4536 16 4537 16 4538 16 4539 16 4540 16 4541 16 4542 16 4543 16 4544 16 4545 16 4546 16 4547 16 4548 16 4549 16 4550 16 4551 16 4552 16 4553 16 4554 16 4555 16 4556 17 4557 16 4558 16 4559 16 4560 16 4561 16 4562 16 4563 16 4564 16 4565 16 4566 28 4567 28 4568 28 4569 28 4570 28 4571 28 4572 28 4573 28 4574 28 4575 30 4576 30 4577 30 4578 30 4579 31 4580 31 4581 31 4582 31 4583 31 4584 31 4585 31 4586 31 4587 31 4588 31 4589 31 4590 31 4591 31 4592 31 4593 31 4594 29 4595 29 4596 29 4597 29 4598 29 4599 29 4600 29 4601 29 4602 29 4603 29 4604 29 4605 29 4606 29 4607 29 4608 29 4609 29 4610 29 4611 29 4612 29 4613 29 4614 29 4615 29 4616 29 4617 29 4618 29 4619 29 4620 26 4621 29 4622 29 4623 29 4624 29 4625 29 4626 29 4627 26 4628 26 4629 26 4630 26 4631 26 4632 26 4633 26 4634 26 4635 26 4636 26 4637 26 4638 26 4639 26 4640 26 4641 26 4642 26 4643 5 4644 5 4645 5 4646 5 4647 5 4648 16 4649 16 4650 16 4651 16 4652 16 4653 16 4654 16 4655 16 4656 16 4657 16 4658 11 4659 11 4660 11 4661 14 4662 14 4663 14 4664 14 4665 14 4666 16 4667 16 4668 16 4669 8 4670 8 4671 8 4672 8 4673 9 4674 9 4675 9 4676 9 4677 9 4678 9 4679 9 4680 9 4681 9 4682 9 4683 9 4684 9 4685 9 4686 9 4687 9 4688 14 4689 14 4690 14 4691 14 4692 14 4693 15 4694 15 4695 15 4696 15 4697 15 4698 15 4699 15 4700 15 4701 15 4702 15 4703 15 4704 15 4705 15 4706 15 4707 15 4708 15 4709 15 4710 15 4711 15 4712 8 4713 8 4714 8 4715 8 4716 8 4717 8 4718 8 4719 8 4720 8 4721 8 4722 8 4723 8 4724 8 4725 8 4726 8 4727 8 4728 8 4729 5 4730 5 4731 5 4732 5 4733 8 4734 8 4735 8 4736 8 4737 8 4738 8 4739 14 4740 14 4741 14 4742 14 4743 14 4744 14 4745 14 4746 14 4747 14 4748 14 4749 14 4750 14 4751 14 4752 14 4753 14 4754 4 4755 4 4756 4 4757 14 4758 14 4759 4 4760 4 4761 4 4762 4 4763 4 4764 4 4765 4 4766 4 4767 4 4768 4 4769 4 4770 4 4771 23 4772 23 4773 23 4774 23 4775 28 4776 28 4777 28 4778 28 4779 28 4780 28 4781 28 4782 28 4783 28 4784 28 4785 28 4786 28 4787 28 4788 28 4789 28 4790 28 4791 28 4792 28 4793 30 4794 30 4795 31 4796 31 4797 31 4798 31 4799 28 4800 31 4801 31 4802 31 4803 31 4804 31 4805 31 4806 31 4807 31 4808 31 4809 31 4810 31 4811 29 4812 29 4813 29 4814 29 4815 29 4816 29 4817 29 4818 29 4819 29 4820 29 4821 29 4822 29 4823 29 4824 29 4825 29 4826 29 4827 29 4828 29 4829 29 4830 29 4831 29 4832 29 4833 29 4834 29 4835 29 4836 29 4837 29 4838 29 4839 29 4840 29 4841 29 4842 29 4843 29 4844 29 4845 29 4846 29 4847 29 4848 29 4849 29 4850 29 4851 29 4852 29 4853 29 4854 29 4855 29 4856 29 4857 29 4858 29 4859 29 4860 29 4861 29 4862 26 4863 26 4864 26 4865 26 4866 26 4867 26 4868 26 4869 26 4870 26 4871 26 4872 26 4873 26 4874 26 4875 26 4876 26 4877 26 4878 26 4879 26 4880 26 4881 26 4882 26 4883 26 4884 26 4885 26 4886 26 4887 26 4888 26 4889 26 4890 26 4891 26 4892 26 4893 26 4894 26 4895 26 4896 26 4897 26 4898 26 4899 26 4900 26 4901 26 4902 26 4903 26 4904 26 4905 26 4906 26 4907 26 4908 26 4909 26 4910 26 4911 26 4912 26 4913 26 4914 26 4915 26 4916 26 4917 26 4918 31 4919 29 4920 29 4921 29 4922 29 4923 23 4924 22 4925 23 4926 23 4927 23 4928 23 4929 23 4930 23 4931 23 4932 23 4933 23 4934 23 4935 23 4936 23 4937 23 4938 28 4939 28 4940 28 4941 28 4942 28 4943 28 4944 28 4945 28 4946 28 4947 28 4948 28 4949 28 4950 28 4951 28 4952 28 4953 28 4954 28 4955 28 4956 31 4957 31 4958 31 4959 31 4960 29 4961 29 4962 29 4963 29 4964 29 4965 8 4966 8 4967 8 4968 8 4969 8 4970 8 4971 8 4972 8 4973 8 4974 8 4975 8 4976 8 4977 8 4978 8 4979 8 4980 8 4981 9 4982 9 4983 9 4984 9 4985 4 4986 4 4987 4 4988 4 4989 9 4990 9 4991 9 4992 9 4993 9 4994 9 4995 4 4996 4 4997 4 4998 4 4999 4 5000 4 5001 4 5002 4 5003 14 5004 14 5005 14 5006 4 5007 4 5008 4 5009 4 5010 4 5011 4 5012 4 5013 4 5014 4 5015 4 5016 4 5017 4 5018 4 5019 4 5020 4 5021 4 5022 4 5023 4 5024 4 5025 4 5026 4 5027 4 5028 4 5029 5 5030 5 5031 5 5032 5 5033 5 5034 5 5035 5 5036 5 5037 5 5038 5 5039 5 5040 5 5041 5 5042 5 5043 5 5044 5 5045 5 5046 23 5047 23 5048 23 5049 23 5050 23 5051 23 5052 23 5053 23 5054 23 5055 23 5056 23 5057 23 5058 23 5059 23 5060 23 5061 23 5062 23 5063 23 5064 23 5065 23 5066 23 5067 23 5068 23 5069 28 5070 28 5071 28 5072 28 5073 28 5074 28 5075 28 5076 28 5077 28 5078 28 5079 28 5080 28 5081 28 5082 28 5083 28 5084 28 5085 28 5086 28 5087 29 5088 29 5089 29 5090 29 5091 29 5092 29 5093 29 5094 29 5095 29 5096 29 5097 29 5098 29 5099 29 5100 29 5101 29 5102 29 5103 29 5104 29 5105 29 5106 29 5107 29 5108 29 5109 29 5110 29 5111 29 5112 29 5113 29 5114 29 5115 29 5116 29 5117 29 5118 29 5119 29 5120 29 5121 29 5122 29 5123 29 5124 29 5125 19 5126 19 5127 19 5128 19 5129 19 5130 19 5131 26 5132 26 5133 19 5134 19 5135 26 5136 26 5137 26 5138 26 5139 26 5140 26 5141 26 5142 26 5143 26 5144 26 5145 26 5146 26 5147 26 5148 26 5149 26 5150 26 5151 29 5152 29 5153 29 5154 29 5155 26 5156 16 5157 16 5158 14 5159 14 5160 15 5161 15 5162 15 5163 15 5164 15 5165 15 5166 4 5167 4 5168 7 5169 7 5170 15 5171 15 5172 15 5173 15 5174 8 5175 8 5176 8 5177 8 5178 8 5179 8 5180 8 5181 8 5182 8 5183 8 5184 8 5185 8 5186 8 5187 8 5188 8 5189 8 5190 8 5191 8 5192 8 5193 8 5194 8 5195 8 5196 8 5197 9 5198 9 5199 9 5200 9 5201 9 5202 9 5203 9 5204 9 5205 9 5206 9 5207 9 5208 9 5209 9 5210 9 5211 9 5212 9 5213 9 5214 9 5215 9 5216 9 5217 9 5218 9 5219 9 5220 9 5221 9 5222 9 5223 9 5224 9 5225 4 5226 4 5227 4 5228 4 5229 4 5230 4 5231 20 5232 20 5233 20 5234 20 5235 18 5236 18 5237 18 5238 4 5239 4 5240 4 5241 4 5242 4 5243 4 5244 4 5245 4 5246 4 5247 4 5248 4 5249 4 5250 23 5251 23 5252 23 5253 23 5254 23 5255 23 5256 28 5257 28 5258 28 5259 28 5260 28 5261 28 5262 28 5263 28 5264 28 5265 28 5266 28 5267 28 5268 28 5269 28 5270 28 5271 28 5272 29 5273 29 5274 29 5275 29 5276 29 5277 29 5278 29 5279 29 5280 29 5281 29 5282 29 5283 29 5284 29 5285 29 5286 29 5287 29 5288 29 5289 29 5290 29 5291 29 5292 29 5293 29 5294 29 5295 29 5296 29 5297 29 5298 29 5299 29 5300 29 5301 29 5302 29 5303 19 5304 29 5305 19 5306 19 5307 19 5308 19 5309 19 5310 19 5311 19 5312 19 5313 19 5314 19 5315 19 5316 19 5317 19 5318 19 5319 19 5320 19 5321 19 5322 19 5323 19 5324 19 5325 19 5326 19 5327 19 5328 19 5329 19 5330 19 5331 19 5332 19 5333 19 5334 19 5335 19 5336 19 5337 19 5338 19 5339 19 5340 19 5341 19 5342 19 5343 19 5344 26 5345 26 5346 26 5347 18 5348 19 5349 19 5350 19 5351 18 5352 18 5353 18 5354 18 5355 18 5356 18 5357 18 5358 18 5359 18 5360 18 5361 26 5362 26 5363 26 5364 26 5365 26 5366 26 5367 26 5368 26 5369 26 5370 26 5371 26 5372 26 5373 26 5374 26 5375 26 5376 29 5377 29 5378 29 5379 29 5380 16 5381 3 5382 3 5383 3 5384 3 5385 3 5386 3 5387 3 5388 3 5389 3 5390 3 5391 3 5392 26 5393 26 5394 26 5395 26 5396 26 5397 26 5398 26 5399 26 5400 26 5401 26 5402 26 5403 8 5404 8 5405 8 5406 8 5407 8 5408 8 5409 8 5410 8 5411 8 5412 8 5413 8 5414 8 5415 8 5416 8 5417 8 5418 8 5419 8 5420 8 5421 8 5422 8 5423 8 5424 9 5425 9 5426 9 5427 9 5428 8 5429 8 5430 9 5431 9 5432 9 5433 9 5434 9 5435 9 5436 9 5437 9 5438 9 5439 9 5440 9 5441 9 5442 9 5443 9 5444 9 5445 9 5446 9 5447 9 5448 20 5449 20 5450 20 5451 20 5452 20 5453 20 5454 20 5455 20 5456 20 5457 20 5458 20 5459 20 5460 20 5461 20 5462 20 5463 20 5464 20 5465 20 5466 20 5467 20 5468 20 5469 20 5470 20 5471 20 5472 20 5473 20 5474 20 5475 23 5476 23 5477 23 5478 23 5479 23 5480 23 5481 23 5482 23 5483 23 5484 23 5485 23 5486 23 5487 23 5488 23 5489 23 5490 23 5491 23 5492 23 5493 23 5494 23 5495 23 5496 23 5497 23 5498 23 5499 23 5500 28 5501 28 5502 28 5503 28 5504 28 5505 28 5506 28 5507 28 5508 28 5509 28 5510 28 5511 28 5512 28 5513 28 5514 29 5515 29 5516 29 5517 29 5518 29 5519 29 5520 29 5521 29 5522 29 5523 29 5524 29 5525 29 5526 29 5527 29 5528 29 5529 29 5530 29 5531 29 5532 29 5533 29 5534 29 5535 29 5536 29 5537 29 5538 29 5539 29 5540 29 5541 29 5542 29 5543 29 5544 29 5545 19 5546 19 5547 19 5548 19 5549 19 5550 19 5551 19 5552 19 5553 19 5554 19 5555 19 5556 19 5557 19 5558 19 5559 19 5560 19 5561 19 5562 19 5563 19 5564 19 5565 19 5566 19 5567 19 5568 19 5569 19 5570 19 5571 19 5572 19 5573 19 5574 19 5575 19 5576 19 5577 19 5578 19 5579 19 5580 19 5581 19 5582 19 5583 18 5584 18 5585 19 5586 19 5587 19 5588 19 5589 19 5590 19 5591 19 5592 19 5593 19 5594 19 5595 19 5596 19 5597 19 5598 19 5599 19 5600 19 5601 19 5602 19 5603 18 5604 18 5605 19 5606 18 5607 18 5608 18 5609 18 5610 18 5611 18 5612 18 5613 18 5614 18 5615 18 5616 3 5617 3 5618 3 5619 3 5620 3 5621 23 5622 23 5623 23 5624 23 5625 23 5626 23 5627 23 5628 23 5629 23 5630 23 5631 23 5632 23 5633 28 5634 28 5635 28 5636 28 5637 28 5638 28 5639 28 5640 28 5641 29 5642 29 5643 29 5644 29 5645 29 5646 29 5647 29 5648 4 5649 4 5650 4 5651 4 5652 4 5653 4 5654 23 5655 23 5656 23 5657 23 5658 23 5659 23 5660 23 5661 23 5662 23 5663 23 5664 23 5665 23 5666 23 5667 23 5668 23 5669 23 5670 23 5671 23 5672 23 5673 23 5674 28 5675 28 5676 28 5677 29 5678 29 5679 29 5680 29 5681 29 5682 29 5683 29 5684 29 5685 29 5686 29 5687 29 5688 29 5689 29 5690 29 5691 29 5692 29 5693 29 5694 29 5695 29 5696 29 5697 23 5698 23 5699 19 5700 19 5701 19 5702 19 5703 19 5704 19 5705 19 5706 19 5707 19 5708 19 5709 19 5710 19 5711 19 5712 19 5713 19 5714 19 5715 19 5716 19 5717 19 5718 29 5719 23 5720 23 5721 23 5722 19 5723 23 5724 23 5725 23 5726 23 5727 19 5728 19 5729 19 5730 23 5731 23 5732 19 5733 19 5734 19 5735 19 5736 19 5737 19 5738 19 5739 19 5740 19 5741 19 5742 19 5743 19 5744 19 5745 19 5746 19 5747 19 5748 19 5749 19 5750 19 5751 19 5752 19 5753 19 5754 19 5755 19 5756 19 5757 19 5758 19 5759 19 5760 19 5761 19 5762 19 5763 19 5764 19 5765 19 5766 19 5767 19 5768 19 5769 19 5770 19 5771 19 5772 19 5773 19 5774 19 5775 19 5776 19 5777 19 5778 19 5779 19 5780 19 5781 19 5782 19 5783 19 5784 19 5785 19 5786 19 5787 19 5788 18 5789 18 5790 18 5791 18 5792 18 5793 18 5794 18 5795 18 5796 18 5797 18 5798 18 5799 18 5800 18 5801 18 5802 18 5803 18 5804 18 5805 18 5806 18 5807 18 5808 18 5809 18 5810 26 5811 26 5812 23 5813 23 5814 23 5815 23 5816 23 5817 23 5818 23 5819 23 5820 23 5821 23 5822 23 5823 18 5824 18 5825 18 5826 18 5827 18 5828 18 5829 18 5830 18 5831 23 5832 23 5833 23 5834 23 5835 23 5836 18 5837 18 5838 18 5839 18 5840 23 5841 23 5842 23 5843 23 5844 23 5845 23 5846 23 5847 23 5848 23 5849 23 5850 23 5851 23 5852 23 5853 23 5854 23 5855 23 5856 23 5857 23 5858 23 5859 23 5860 23 5861 23 5862 23 5863 23 5864 23 5865 29 5866 29 5867 29 5868 29 5869 29 5870 29 5871 29 5872 18 5873 26 5874 26 5875 26 5876 27 5877 27 5878 26 5879 27 5880 26 5881 26 5882 26 5883 26 5884 26 5885 26 5886 18 5887 26 5888 27 5889 27 5890 26 5891 27 5892 26 5893 26 5894 26 5895 26 5896 26 5897 26 5898 26 5899 26 5900 26 5901 26 5902 26 5903 26 5904 26 5905 26 5906 26 5907 26 5908 26 5909 26 5910 26 5911 26 5912 26 5913 26 5914 26 5915 26 5916 26 5917 26 5918 26 5919 26 5920 26 5921 26 5922 26 5923 26 5924 26 5925 26 5926 26 5927 26 5928 26 5929 26 5930 26 5931 26 5932 26 5933 26 5934 26 5935 26 5936 26 5937 26 5938 26 5939 26 5940 26 5941 26 5942 26 5943 25 5944 25 5945 25 5946 25 5947 25 5948 25 5949 19 5950 19 5951 19 5952 19 5953 19 5954 19 5955 19 5956 19 5957 19 5958 19 5959 19 5960 19 5961 19 5962 19 5963 19 5964 19 5965 19 5966 19 5967 19 5968 19 5969 17 5970 17 5971 19 5972 17 5973 17 5974 17 5975 17 5976 17 5977 17 5978 17 5979 19 5980 19 5981 19 5982 19 5983 19 5984 19 5985 19 5986 19 5987 19 5988 19 5989 19 5990 19 5991 19 5992 19 5993 19 5994 19 5995 19 5996 19 5997 19 5998 19 5999 19 6000 19 6001 19 6002 19 6003 18 6004 18 6005 19 6006 18 6007 18 6008 18 6009 18 6010 18 6011 18 6012 18 6013 18 6014 18 6015 18 6016 18 6017 18 6018 23 6019 18 6020 18 6021 18 6022 18 6023 18 6024 18 6025 18 6026 18 6027 18 6028 18 6029 18 6030 18 6031 18 6032 18 6033 18 6034 18 6035 18 6036 18 6037 18 6038 18 6039 18 6040 27 6041 27 6042 27 6043 27 6044 27 6045 27 6046 27 6047 27 6048 27 6049 27 6050 27 6051 27 6052 27 6053 27 6054 27 6055 27 6056 27 6057 27 6058 26 6059 26 6060 27 6061 26 6062 26 6063 26 6064 26 6065 26 6066 26 6067 26 6068 26 6069 26 6070 26 6071 26 6072 26 6073 26 6074 26 6075 26 6076 26 6077 26 6078 26 6079 26 6080 26 6081 26 6082 26 6083 26 6084 26 6085 26 6086 26 6087 26 6088 26 6089 26 6090 26 6091 26 6092 25 6093 25 6094 26 6095 23 6096 23 6097 23 6098 23 6099 23 6100 23 6101 23 6102 23 6103 23 6104 23 6105 23 6106 19 6107 19 6108 19 6109 19 6110 19 6111 19 6112 19 6113 19 6114 19 6115 19 6116 19 6117 19 6118 19 6119 19 6120 19 6121 19 6122 19 6123 19 6124 19 6125 19 6126 19 6127 19 6128 19 6129 19 6130 19 6131 19 6132 19 6133 19 6134 19 6135 19 6136 19 6137 19 6138 19 6139 19 6140 19 6141 17 6142 17 6143 17 6144 17 6145 17 6146 17 6147 17 6148 17 6149 17 6150 19 6151 17 6152 17 6153 17 6154 17 6155 17 6156 17 6157 19 6158 19 6159 19 6160 19 6161 19 6162 19 6163 19 6164 19 6165 19 6166 19 6167 19 6168 19 6169 19 6170 19 6171 19 6172 19 6173 18 6174 16 6175 16 6176 16 6177 16 6178 16 6179 18 6180 18 6181 16 6182 18 6183 16 6184 18 6185 18 6186 18 6187 18 6188 18 6189 18 6190 18 6191 18 6192 18 6193 18 6194 18 6195 18 6196 18 6197 18 6198 18 6199 18 6200 18 6201 18 6202 18 6203 18 6204 18 6205 18 6206 18 6207 18 6208 18 6209 18 6210 18 6211 18 6212 18 6213 18 6214 18 6215 18 6216 18 6217 18 6218 18 6219 18 6220 18 6221 18 6222 18 6223 18 6224 18 6225 18 6226 18 6227 18 6228 18 6229 18 6230 18 6231 18 6232 18 6233 18 6234 18 6235 18 6236 18 6237 18 6238 18 6239 18 6240 18 6241 18 6242 18 6243 18 6244 18 6245 18 6246 18 6247 18 6248 18 6249 18 6250 18 6251 18 6252 18 6253 18 6254 27 6255 27 6256 27 6257 27 6258 27 6259 27 6260 27 6261 27 6262 27 6263 27 6264 27 6265 27 6266 27 6267 27 6268 27 6269 27 6270 27 6271 27 6272 27 6273 27 6274 27 6275 27 6276 27 6277 27 6278 27 6279 27 6280 27 6281 27 6282 27 6283 27 6284 27 6285 27 6286 27 6287 27 6288 26 6289 27 6290 27 6291 27 6292 26 6293 26 6294 26 6295 26 6296 26 6297 26 6298 26 6299 26 6300 26 6301 26 6302 26 6303 26 6304 26 6305 26 6306 27 6307 26 6308 26 6309 26 6310 26 6311 26 6312 26 6313 26 6314 26 6315 26 6316 26 6317 26 6318 26 6319 26 6320 26 6321 26 6322 26 6323 26 6324 26 6325 27 6326 27 6327 27 6328 27 6329 27 6330 27 6331 27 6332 27 6333 27 6334 27 6335 27 6336 27 6337 27 6338 27 6339 27 6340 27 6341 27 6342 27 6343 26 6344 27 6345 27 6346 26 6347 27 6348 24 6349 24 6350 24 6351 24 6352 24 6353 24 6354 24 6355 24 6356 24 6357 24 6358 24 6359 24 6360 24 6361 24 6362 16 6363 16 6364 16 6365 16 6366 18 6367 18 6368 18 6369 18 6370 18 6371 18 6372 18 6373 18 6374 18 6375 18 6376 18 6377 18 6378 18 6379 18 6380 18 6381 18 6382 18 6383 23 6384 23 6385 23 6386 23 6387 19 6388 19 6389 19 6390 19 6391 19 6392 19 6393 19 6394 19 6395 23 6396 21 6397 19 6398 19 6399 21 6400 21 6401 21 6402 21 6403 21 6404 21 6405 17 6406 21 6407 21 6408 21 6409 21 6410 21 6411 21 6412 21 6413 21 6414 21 6415 21 6416 21 6417 21 6418 21 6419 21 6420 21 6421 21 6422 21 6423 21 6424 21 6425 21 6426 21 6427 21 6428 21 6429 21 6430 21 6431 21 6432 21 6433 17 6434 17 6435 17 6436 17 6437 17 6438 17 6439 17 6440 17 6441 17 6442 17 6443 17 6444 17 6445 17 6446 17 6447 17 6448 17 6449 17 6450 17 6451 17 6452 17 6453 17 6454 18 6455 18 6456 18 6457 18 6458 18 6459 18 6460 18 6461 18 6462 18 6463 18 6464 18 6465 18 6466 18 6467 18 6468 18 6469 18 6470 18 6471 18 6472 18 6473 18 6474 18 6475 18 6476 18 6477 18 6478 18 6479 18 6480 18 6481 18 6482 18 6483 18 6484 18 6485 27 6486 18 6487 18 6488 18 6489 18 6490 18 6491 27 6492 27 6493 27 6494 27 6495 27 6496 27 6497 27 6498 27 6499 27 6500 27 6501 27 6502 27 6503 27 6504 27 6505 27 6506 27 6507 27 6508 27 6509 27 6510 27 6511 27 6512 27 6513 27 6514 27 6515 27 6516 27 6517 27 6518 27 6519 27 6520 27 6521 27 6522 27 6523 27 6524 27 6525 27 6526 27 6527 27 6528 27 6529 27 6530 27 6531 27 6532 27 6533 27 6534 27 6535 27 6536 27 6537 27 6538 27 6539 27 6540 27 6541 27 6542 27 6543 27 6544 27 6545 27 6546 27 6547 27 6548 27 6549 27 6550 24 6551 24 6552 24 6553 24 6554 24 6555 24 6556 24 6557 24 6558 21 6559 21 6560 21 6561 21 6562 21 6563 21 6564 21 6565 21 6566 21 6567 21 6568 21 6569 21 6570 21 6571 21 6572 21 6573 21 6574 21 6575 21 6576 21 6577 21 6578 21 6579 21 6580 21 6581 21 6582 21 6583 21 6584 21 6585 21 6586 17 6587 17 6588 17 6589 17 6590 17 6591 17 6592 17 6593 17 6594 17 6595 17 6596 17 6597 17 6598 17 6599 17 6600 17 6601 17 6602 17 6603 17 6604 17 6605 17 6606 17 6607 17 6608 17 6609 17 6610 17 6611 17 6612 17 6613 17 6614 17 6615 17 6616 17 6617 17 6618 17 6619 17 6620 17 6621 17 6622 17 6623 17 6624 17 6625 17 6626 17 6627 17 6628 17 6629 17 6630 17 6631 16 6632 16 6633 16 6634 16 6635 16 6636 17 6637 17 6638 17 6639 17 6640 19 6641 19 6642 19 6643 19 6644 16 6645 16 6646 16 6647 16 6648 16 6649 16 6650 16 6651 16 6652 16 6653 16 6654 16 6655 16 6656 16 6657 16 6658 16 6659 16 6660 16 6661 16 6662 16 6663 16 6664 16 6665 16 6666 16 6667 16 6668 16 6669 16 6670 16 6671 16 6672 16 6673 16 6674 16 6675 16 6676 16 6677 16 6678 16 6679 16 6680 16 6681 16 6682 16 6683 16 6684 16 6685 16 6686 16 6687 16 6688 16 6689 16 6690 16 6691 16 6692 16 6693 16 6694 16 6695 16 6696 16 6697 16 6698 16 6699 16 6700 16 6701 16 6702 16 6703 16 6704 16 6705 24 6706 24 6707 24 6708 27 6709 27 6710 24 6711 27 6712 24 6713 27 6714 27 6715 27 6716 27 6717 27 6718 27 6719 27 6720 17 6721 17 6722 17 6723 17 6724 17 6725 17 6726 17 6727 17 6728 17 6729 17 6730 17 6731 17 6732 17 6733 17 6734 17 6735 17 6736 17 6737 17 6738 17 6739 17 6740 17 6741 17 6742 17 6743 17 6744 17 6745 17 6746 17 6747 17 6748 17 6749 17 6750 17 6751 17 6752 17 6753 17 6754 17 6755 17 6756 17 6757 17 6758 16 6759 17 6760 17 6761 16 6762 16 6763 16 6764 16 6765 16 6766 16 6767 16 6768 16 6769 16 6770 16 6771 16 6772 16 6773 16 6774 16 6775 16 6776 16 6777 16 6778 16 6779 16 6780 16 6781 16 6782 16 6783 16 6784 16 6785 17 6786 19 6787 19 6788 19 6789 19 6790 16 6791 8 6792 8 6793 8 6794 9 6795 9 6796 9 6797 9 6798 9 6799 9 6800 9 6801 9 6802 9 6803 9 6804 9 6805 9 6806 9 6807 9 6808 9 6809 9 6810 9 6811 9 6812 9 6813 9 6814 9 6815 9 6816 9 6817 9 6818 6 6819 6 6820 6 6821 6 6822 6 6823 6 6824 6 6825 6 6826 6 6827 6 6828 6 6829 7 6830 7 6831 7 6832 7 6833 4 6834 7 6835 7 6836 7 6837 4 6838 4 6839 4 6840 4 6841 4 6842 4 6843 4 6844 4 6845 5 6846 5 6847 5 6848 5 6849 5 6850 5 6851 5 6852 5 6853 5 6854 5 6855 5 6856 5 6857 7 6858 7 6859 7 6860 7 6861 7 6862 7 6863 7 6864 7 6865 7 6866 7 6867 7 6868 7 6869 7 6870 7 6871 7 6872 7 6873 7 6874 7 6875 7 6876 7 6877 5 6878 5 6879 7 6880 5 6881 5 6882 5 6883 5 6884 7 6885 5 6886 5 6887 5 6888 5 6889 5 6890 5 6891 5 6892 5 6893 5 6894 5 6895 5 6896 5 6897 5 6898 5 6899 5 6900 20 6901 5 6902 20 6903 20 6904 20 6905 20 6906 20 6907 20 6908 20 6909 20 6910 20 6911 20 6912 20 6913 20 6914 20 6915 20 6916 20 6917 20 6918 20 6919 20 6920 20 6921 23 6922 23 6923 23 6924 23 6925 23 6926 23 6927 23 6928 23 6929 23 6930 23 6931 23 6932 23 6933 23 6934 23 6935 23 6936 23 6937 23 6938 23 6939 23 6940 23 6941 23 6942 23 6943 23 6944 23 6945 23 6946 23 6947 23 6948 23 6949 23 6950 23 6951 23 6952 21 6953 21 6954 21 6955 21 6956 21 6957 21 6958 21 6959 21 6960 21 6961 21 6962 21 6963 21 6964 21 6965 21 6966 21 6967 21 6968 21 6969 21 6970 21 6971 21 6972 21 6973 21 6974 21 6975 21 6976 21 6977 21 6978 21 6979 21 6980 21 6981 21 6982 21 6983 21 6984 21 6985 21 6986 21 6987 21 6988 21 6989 21 6990 21 6991 21 6992 21 6993 21 6994 21 6995 21 6996 21 6997 21 6998 21 6999 21 7000 21 7001 21 7002 21 7003 21 7004 21 7005 21 7006 17 7007 17 7008 17 7009 17 7010 17 7011 17 7012 17 7013 17 7014 17 7015 17 7016 17 7017 17 7018 17 7019 17 7020 17 7021 17 7022 17 7023 17 7024 17 7025 17 7026 17 7027 17 7028 17 7029 17 7030 17 7031 17 7032 17 7033 17 7034 17 7035 17 7036 17 7037 17 7038 17 7039 17 7040 17 7041 17 7042 17 7043 23 7044 21 7045 21 7046 23 7047 23 7048 21 7049 21 7050 21 7051 21 7052 21 7053 23 7054 23 7055 23 7056 23 7057 23 7058 23 7059 23 7060 23 7061 23 7062 23 7063 23 7064 23 7065 23 7066 21 7067 21 7068 23 7069 23 7070 21 7071 21 7072 21 7073 21 7074 21 7075 21 7076 21 7077 21 7078 21 7079 21 7080 21 7081 21 7082 21 7083 21 7084 21 7085 21 7086 21 7087 21 7088 21 7089 21 7090 21 7091 21 7092 21 7093 21 7094 21 7095 21 7096 21 7097 17 7098 17 7099 17 7100 17 7101 17 7102 21 7103 21 7104 21 7105 21 7106 17 7107 17 7108 17 7109 17 7110 17 7111 17 7112 17 7113 17 7114 17 7115 17 7116 17 7117 17 7118 17 7119 17 7120 17 7121 17 7122 17 7123 17 7124 17 7125 17 7126 17 7127 17 7128 17 7129 17 7130 17 7131 17 7132 17 7133 17 7134 17 7135 17 7136 17 7137 17 7138 17 7139 17 7140 17 7141 17 7142 17 7143 17 7144 16 7145 16 7146 17 7147 17 7148 17 7149 17 7150 17 7151 17 7152 17 7153 17 7154 17 7155 17 7156 17 7157 17 7158 17 7159 16 7160 16 7161 16 7162 16 7163 16 7164 16 7165 16 7166 16 7167 16 7168 16 7169 16 7170 0 7171 0 7172 0 7173 0 7174 0 7175 0 7176 0 7177 0 7178 0 7179 0 7180 0 7181 0 7182 0 7183 0 7184 0 7185 0 7186 0 7187 0 7188 0 7189 0 7190 0 7191 0 7192 0 7193 0 7194 0 7195 0 7196 0 7197 0 7198 0 7199 0 7200 0 7201 0 7202 0 7203 0 7204 0 7205 0 7206 0 7207 0 7208 0 7209 0 7210 0 7211 0 7212 0 7213 0 7214 0 7215 0 7216 0 7217 0 7218 0 7219 0 7220 0 7221 0 7222 0 7223 21 7224 21 7225 21 7226 21 7227 21 7228 21 7229 21 7230 21 7231 21 7232 21 7233 21 7234 21 7235 21 7236 21 7237 21 7238 21 7239 21 7240 21 7241 21 7242 21 7243 21 7244 21 7245 21 7246 21 7247 21 7248 17 7249 17 7250 17 7251 17 7252 17 7253 17 7254 17 7255 17 7256 17 7257 17 7258 17 7259 17 7260 17 7261 17 7262 20 7263 20 7264 20 7265 20 7266 20 7267 20 7268 20 7269 20 7270 20 7271 20 7272 20 7273 20 7274 23 7275 23 7276 23 7277 23 7278 23 7279 23 7280 23 7281 23 7282 23 7283 23 7284 23 7285 23 7286 23 7287 23 7288 23 7289 23 7290 23 7291 23 7292 23 7293 23 7294 23 7295 23 7296 23 7297 23 7298 23 7299 23 7300 23 7301 23 7302 23 7303 23 7304 23 7305 23 7306 23 7307 23 7308 15 7309 15 7310 15 7311 15 7312 15 7313 15 7314 15 7315 15 7316 15 7317 8 7318 8 7319 8 7320 8 7321 8 7322 8 7323 8 7324 8 7325 8 7326 8 7327 8 7328 8 7329 8 7330 8 7331 8 7332 8 7333 8 7334 9 7335 9 7336 9 7337 9 7338 9 7339 9 7340 9 7341 9 7342 9 7343 9 7344 9 7345 9 7346 9 7347 9 7348 9 7349 9 7350 9 7351 9 7352 9 7353 9 7354 9 7355 6 7356 6 7357 6 7358 6 7359 6 7360 6 7361 6 7362 6 7363 6 7364 6 7365 7 7366 7 7367 7 7368 7 7369 7 7370 7 7371 7 7372 7 7373 7 7374 7 7375 7 7376 7 7377 7 7378 7 7379 4 7380 4 7381 4 7382 4 7383 4 7384 5 7385 5 7386 5 7387 5 7388 5 7389 5 7390 7 7391 7 7392 7 7393 7 7394 7 7395 7 7396 7 7397 7 7398 7 7399 7 7400 7 7401 7 7402 7 7403 7 7404 7 7405 7 7406 7 7407 7 7408 7 7409 7 7410 7 7411 7 7412 7 7413 7 7414 7 7415 7 7416 7 7417 7 7418 7 7419 7 7420 7 7421 7 7422 7 7423 21 7424 21 7425 7 7426 7 7427 5 7428 5 7429 5 7430 5 7431 5 7432 5 7433 5 7434 5 7435 5 7436 20 7437 20 7438 20 7439 20 7440 20 7441 20 7442 20 7443 20 7444 20 7445 20 7446 20 7447 20 7448 20 7449 20 7450 20 7451 20 7452 20 7453 20 7454 21 7455 21 7456 23 7457 23 7458 23 7459 23 7460 23 7461 23 7462 23 7463 23 7464 23 7465 23 7466 23 7467 23 7468 23 7469 23 7470 23 7471 23 7472 23 7473 23 7474 23 7475 23 7476 23 7477 23 7478 23 7479 23 7480 23 7481 23 7482 23 7483 23 7484 23 7485 23 7486 21 7487 21 7488 21 7489 21 7490 21 7491 21 7492 21 7493 21 7494 23 7495 23 7496 23 7497 23 7498 23 7499 23 7500 18 7501 18 7502 18 7503 18 7504 18 7505 18 7506 18 7507 18 7508 18 7509 18 7510 18 7511 17 7512 17 7513 17 7514 17 7515 17 7516 17 7517 17 7518 17 7519 17 7520 17 7521 17 7522 17 7523 17 7524 17 7525 17 7526 17 7527 17 7528 17 7529 17 7530 17 7531 17 7532 17 7533 17 7534 17 7535 17 7536 17 7537 17 7538 17 7539 17 7540 17 7541 17 7542 17 7543 17 7544 17 7545 17 7546 17 7547 17 7548 17 7549 17 7550 17 7551 17 7552 17 7553 17 7554 17 7555 17 7556 17 7557 17 7558 0 7559 0 7560 16 7561 0 7562 0 7563 0 7564 0 7565 0 7566 0 7567 0 7568 0 7569 0 7570 0 7571 0 7572 0 7573 0 7574 0 7575 0 7576 0 7577 0 7578 0 7579 0 7580 0 7581 0 7582 0 7583 0 7584 0 7585 0 7586 0 7587 0 7588 0 7589 0 7590 1 7591 1 7592 2 7593 2 7594 2 7595 2 7596 2 7597 2 7598 2 7599 2 7600 2 7601 7 7602 7 7603 7 7604 7 7605 7 7606 7 7607 7 7608 7 7609 7 7610 7 7611 7 7612 7 7613 7 7614 7 7615 7 7616 7 7617 7 7618 7 7619 7 7620 7 7621 7 7622 7 7623 7 7624 7 7625 7 7626 7 7627 7 7628 7 7629 7 7630 7 7631 7 7632 7 7633 7 7634 7 7635 7 7636 7 7637 7 7638 7 7639 7 7640 7 7641 7 7642 7 7643 7 7644 7 7645 7 7646 7 7647 21 7648 21 7649 21 7650 21 7651 21 7652 5 7653 5 7654 5 7655 5 7656 5 7657 5 7658 20 7659 20 7660 20 7661 20 7662 20 7663 20 7664 20 7665 20 7666 20 7667 20 7668 20 7669 21 7670 21 7671 20 7672 21 7673 21 7674 21 7675 21 7676 20 7677 20 7678 21 7679 21 7680 21 7681 21 7682 21 7683 21 7684 21 7685 21 7686 21 7687 23 7688 23 7689 21 7690 21 7691 21 7692 21 7693 21 7694 21 7695 21 7696 21 7697 21 7698 21 7699 21 7700 21 7701 21 7702 21 7703 21 7704 21 7705 21 7706 21 7707 21 7708 21 7709 21 7710 21 7711 21 7712 21 7713 21 7714 21 7715 21 7716 21 7717 21 7718 21 7719 21 7720 21 7721 21 7722 21 7723 21 7724 21 7725 21 7726 21 7727 21 7728 21 7729 0 7730 1 7731 1 7732 1 7733 1 7734 1 7735 1 7736 1 7737 1 7738 1 7739 2 7740 2 7741 2 7742 2 7743 2 7744 2 7745 2 7746 2 7747 2 7748 2 7749 2 7750 2 7751 2 7752 2 7753 2 7754 2 7755 2 7756 2 7757 2 7758 2 7759 2 7760 2 7761 2 7762 2 7763 2 7764 2 7765 2 7766 3 7767 3 7768 3 7769 3 7770 3 7771 3 7772 3 7773 3 7774 3 7775 3 7776 3 7777 3 7778 3 7779 3 7780 3 7781 3 7782 3 7783 3 7784 3 7785 3 7786 3 7787 3 7788 3 7789 3 7790 3 7791 3 7792 3 7793 3 7794 3 7795 3 7796 3 7797 3 7798 3 7799 3 7800 3 7801 3 7802 3 7803 3 7804 3 7805 3 7806 3 7807 3 7808 3 7809 3 7810 13 7811 13 7812 13 7813 13 7814 13 7815 13 7816 13 7817 13 7818 13 7819 13 7820 13 7821 13 7822 13 7823 13 7824 13 7825 13 7826 13 7827 13 7828 13 7829 13 7830 13 7831 14 7832 13 7833 14 7834 14 7835 14 7836 14 7837 14 7838 14 7839 14 7840 14 7841 14 7842 14 7843 14 7844 14 7845 14 7846 14 7847 14 7848 15 7849 15 7850 15 7851 15 7852 15 7853 15 7854 15 7855 15 7856 15 7857 15 7858 15 7859 15 7860 15 7861 15 7862 15 7863 15 7864 8 7865 8 7866 8 7867 8 7868 8 7869 8 7870 8 7871 8 7872 8 7873 8 7874 8 7875 8 7876 8 7877 8 7878 8 7879 9 7880 9 7881 9 7882 9 7883 9 7884 9 7885 9 7886 9 7887 9 7888 9 7889 9 7890 9 7891 9 7892 9 7893 9 7894 9 7895 9 7896 9 7897 9 7898 9 7899 9 7900 6 7901 6 7902 6 7903 6 7904 6 7905 6 7906 6 7907 6 7908 6 7909 6 7910 7 7911 7 7912 7 7913 7 7914 7 7915 7 7916 7 7917 7 7918 7 7919 7 7920 7 7921 7 7922 7 7923 7 7924 7 7925 7 7926 7 7927 7 7928 7 7929 7 7930 3 7931 13 7932 13 7933 13 7934 13 7935 13 7936 13 7937 13 7938 13 7939 13 7940 13 7941 13 7942 13 7943 13 7944 13 7945 13 7946 13 7947 13 7948 13 7949 13 7950 13 7951 13 7952 13 7953 13 7954 14 7955 14 7956 14 7957 14 7958 14 7959 14 7960 14 7961 14 7962 21 7963 21 7964 21 7965 21 7966 21 7967 17 7968 17 7969 1 7970 1 7971 1 7972 17 7973 17 7974 1 7975 1 7976 1 7977 17 7978 17 7979 17 7980 1 7981 1 7982 1 7983 1 7984 1 7985 1 7986 1 7987 17 7988 17 7989 17 7990 17 7991 17 7992 17 7993 0 7994 0 7995 0 7996 0 7997 0 7998 0 7999 0 8000 0 8001 0 8002 0 8003 0 8004 0 8005 0 8006 0 8007 0 8008 0 8009 0 8010 0 8011 0 8012 0 8013 0 8014 1 8015 1 8016 1 8017 1 8018 1 8019 1 8020 1 8021 1 8022 1 8023 2 8024 2 8025 2 8026 2 8027 2 8028 2 8029 2 8030 2 8031 2 8032 2 8033 2 8034 2 8035 2 8036 2 8037 3 8038 3 8039 3 8040 3 8041 3 8042 3 8043 3 8044 3 8045 3 8046 3 8047 3 8048 3 8049 3 8050 3 8051 3 8052 13 8053 13 8054 3 8055 3 8056 13 8057 13 8058 13 8059 13 8060 13 8061 13 8062 13 8063 13 8064 13 8065 13 8066 13 8067 13 8068 13 8069 13 8070 13 8071 13 8072 13 8073 13 8074 13 8075 13 8076 13 8077 14 8078 14 8079 14 8080 15 8081 14 8082 14 8083 15 8084 15 8085 15 8086 15 8087 15 8088 15 8089 15 8090 15 8091 15 8092 15 8093 15 8094 15 8095 15 8096 15 8097 15 8098 15 8099 12 8100 8 8101 8 8102 8 8103 8 8104 8 8105 8 8106 8 8107 8 8108 8 8109 8 8110 8 8111 8 8112 8 8113 9 8114 9 8115 9 8116 9 8117 9 8118 9 8119 9 8120 9 8121 9 8122 9 8123 9 8124 9 8125 9 8126 9 8127 9 8128 9 8129 9 8130 9 8131 9 8132 9 8133 9 8134 6 8135 6 8136 6 8137 6 8138 6 8139 6 8140 6 8141 6 8142 6 8143 6 8144 7 8145 7 8146 7 8147 7 8148 7 8149 7 8150 7 8151 7 8152 7 8153 7 8154 7 8155 7 8156 7 8157 7 8158 7 8159 7 8160 7 8161 7 8162 7 8163 7 8164 7 8165 7 8166 7 8167 7 8168 7 8169 7 8170 7 8171 7 8172 7 8173 7 8174 7 8175 7 8176 7 8177 1 8178 1 8179 7 8180 7 8181 7 8182 7 8183 7 8184 7 8185 7 8186 21 8187 21 8188 21 8189 21 8190 21 8191 21 8192 21 8193 21 8194 20 8195 20 8196 21 8197 21 8198 21 8199 21 8200 21 8201 21 8202 21 8203 21 8204 21 8205 21 8206 21 8207 20 8208 20 8209 15 8210 15 8211 15 8212 15 8213 15 8214 15 8215 15 8216 15 8217 15 8218 15 8219 15 8220 15 8221 15 8222 15 8223 15 8224 12 8225 12 8226 8 8227 8 8228 8 8229 8 8230 8 8231 8 8232 8 8233 8 8234 8 8235 8 8236 9 8237 9 8238 9 8239 9 8240 9 8241 9 8242 9 8243 9 8244 9 8245 9 8246 9 8247 9 8248 9 8249 9 8250 9 8251 9 8252 9 8253 9 8254 9 8255 9 8256 6 8257 6 8258 6 8259 6 8260 6 8261 6 8262 6 8263 6 8264 6 8265 6 8266 6 8267 7 8268 7 8269 7 8270 7 8271 7 8272 7 8273 7 8274 7 8275 7 8276 7 8277 7 8278 7 8279 7 8280 7 8281 7 8282 7 8283 7 8284 7 8285 7 8286 7 8287 7 8288 7 8289 7 8290 7 8291 7 8292 1 8293 1 8294 1 8295 1 8296 1 8297 7 8298 1 8299 1 8300 1 8301 1 8302 1 8303 1 8304 7 8305 7 8306 7 8307 7 8308 7 8309 7 8310 7 8311 21 8312 21 8313 21 8314 21 8315 21 8316 21 8317 21 8318 21 8319 3 8320 3 8321 3 8322 3 8323 3 8324 3 8325 3 8326 3 8327 3 8328 3 8329 3 8330 3 8331 3 8332 3 8333 3 8334 3 8335 3 8336 3 8337 3 8338 3 8339 3 8340 3 8341 3 8342 3 8343 3 8344 3 8345 3 8346 3 8347 3 8348 3 8349 3 8350 3 8351 3 8352 13 8353 13 8354 13 8355 13 8356 13 8357 13 8358 13 8359 13 8360 13 8361 13 8362 13 8363 13 8364 13 8365 13 8366 13 8367 13 8368 13 8369 13 8370 13 8371 13 8372 13 8373 13 8374 13 8375 15 8376 15 8377 15 8378 15 8379 15 8380 15 8381 15 8382 15 8383 15 8384 15 8385 15 8386 15 8387 15 8388 12 8389 12 8390 12 8391 12 8392 8 8393 8 8394 8 8395 8 8396 8 8397 8 8398 8 8399 9 8400 9 8401 9 8402 9 8403 9 8404 9 8405 9 8406 9 8407 9 8408 9 8409 9 8410 9 8411 9 8412 9 8413 9 8414 12 8415 12 8416 12 8417 9 8418 9 8419 6 8420 6 8421 6 8422 6 8423 6 8424 6 8425 6 8426 6 8427 6 8428 6 8429 6 8430 7 8431 7 8432 7 8433 7 8434 7 8435 7 8436 7 8437 7 8438 7 8439 7 8440 7 8441 7 8442 7 8443 7 8444 7 8445 7 8446 7 8447 7 8448 7 8449 7 8450 7 8451 7 8452 7 8453 7 8454 1 8455 1 8456 1 8457 1 8458 1 8459 1 8460 1 8461 1 8462 1 8463 1 8464 1 8465 1 8466 1 8467 7 8468 21 8469 21 8470 7 8471 7 8472 7 8473 7 8474 21 8475 21 8476 21 8477 21 8478 21 8479 21 8480 21 8481 21 8482 21 8483 21 8484 21 8485 21 8486 21 8487 1 8488 1 8489 1 8490 1 8491 1 8492 1 8493 1 8494 1 8495 1 8496 1 8497 1 8498 1 8499 1 8500 1 8501 1 8502 1 8503 1 8504 1 8505 0 8506 0 8507 0 8508 0 8509 0 8510 0 8511 0 8512 0 8513 0 8514 0 8515 0 8516 1 8517 0 8518 1 8519 0 8520 0 8521 0 8522 0 8523 0 8524 1 8525 1 8526 1 8527 1 8528 1 8529 1 8530 1 8531 1 8532 1 8533 1 8534 1 8535 1 8536 1 8537 0 8538 0 8539 0 8540 0 8541 0 8542 7 8543 7 8544 7 8545 7 8546 7 8547 7 8548 7 8549 7 8550 7 8551 7 8552 7 8553 7 8554 7 8555 7 8556 7 8557 7 8558 7 8559 1 8560 1 8561 1 8562 1 8563 1 8564 1 8565 1 8566 1 8567 1 8568 1 8569 1 8570 1 8571 1 8572 1 8573 1 8574 1 8575 1 8576 1 8577 1 8578 1 8579 1 8580 1 8581 1 8582 1 8583 1 8584 1 8585 1 8586 1 8587 1 8588 0 8589 0 8590 1 8591 1 8592 1 8593 1 8594 1 8595 1 8596 1 8597 1 8598 1 8599 1 8600 1 8601 1 8602 1 8603 1 8604 1 8605 1 8606 1 8607 1 8608 0 8609 0 8610 0 8611 1 8612 1 8613 1 8614 1 8615 1 8616 1 8617 1 8618 1 8619 1 8620 1 8621 2 8622 2 8623 2 8624 1 8625 1 8626 2 8627 2 8628 2 8629 2 8630 2 8631 2 8632 2 8633 2 8634 2 8635 2 8636 2 8637 2 8638 2 8639 2 8640 2 8641 15 8642 15 8643 15 8644 12 8645 12 8646 12 8647 12 8648 12 8649 12 8650 12 8651 12 8652 12 8653 8 8654 8 8655 8 8656 8 8657 9 8658 9 8659 9 8660 9 8661 9 8662 9 8663 9 8664 9 8665 9 8666 9 8667 9 8668 9 8669 9 8670 9 8671 12 8672 12 8673 12 8674 12 8675 12 8676 12 8677 6 8678 6 8679 6 8680 6 8681 6 8682 6 8683 6 8684 6 8685 6 8686 6 8687 6 8688 6 8689 6 8690 6 8691 6 8692 7 8693 7 8694 7 8695 7 8696 7 8697 7 8698 7 8699 7 8700 7 8701 7 8702 7 8703 7 8704 7 8705 7 8706 1 8707 1 8708 1 8709 1 8710 1 8711 1 8712 1 8713 1 8714 1 8715 1 8716 1 8717 1 8718 1 8719 1 8720 1 8721 1 8722 1 8723 1 8724 1 8725 1 8726 1 8727 1 8728 1 8729 1 8730 1 8731 1 8732 1 8733 1 8734 1 8735 1 8736 1 8737 1 8738 1 8739 1 8740 1 8741 1 8742 1 8743 15 8744 15 8745 12 8746 12 8747 12 8748 12 8749 12 8750 12 8751 12 8752 12 8753 12 8754 12 8755 12 8756 12 8757 8 8758 8 8759 9 8760 9 8761 9 8762 9 8763 9 8764 9 8765 9 8766 9 8767 9 8768 9 8769 9 8770 9 8771 9 8772 12 8773 12 8774 12 8775 12 8776 12 8777 12 8778 12 8779 6 8780 6 8781 6 8782 6 8783 6 8784 6 8785 6 8786 6 8787 6 8788 6 8789 6 8790 6 8791 6 8792 6 8793 7 8794 7 8795 7 8796 7 8797 7 8798 7 8799 7 8800 7 8801 7 8802 7 8803 7 8804 7 8805 7 8806 7 8807 7 8808 1 8809 1 8810 1 8811 1 8812 1 8813 1 8814 1 8815 1 8816 1 8817 1 8818 1 8819 1 8820 1 8821 1 8822 1 8823 1 8824 1 8825 1 8826 1 8827 1 8828 1 8829 1 8830 1 8831 1 8832 1 8833 1 8834 1 8835 1 8836 1 8837 1 8838 1 8839 2 8840 2 8841 2 8842 2 8843 2 8844 2 8845 2 8846 2 8847 2 8848 2 8849 2 8850 2 8851 2 8852 2 8853 2 8854 3 8855 3 8856 3 8857 3 8858 3 8859 3 8860 3 8861 3 8862 3 8863 3 8864 3 8865 3 8866 3 8867 3 8868 3 8869 3 8870 3 8871 3 8872 3 8873 3 8874 3 8875 3 8876 3 8877 3 8878 3 8879 3 8880 3 8881 3 8882 3 8883 3 8884 3 8885 3 8886 3 8887 3 8888 3 8889 3 8890 3 8891 3 8892 3 8893 3 8894 3 8895 3 8896 3 8897 3 8898 3 8899 3 8900 3 8901 3 8902 3 8903 3 8904 3 8905 13 8906 13 8907 13 8908 13 8909 13 8910 13 8911 13 8912 13 8913 13 8914 13 8915 13 8916 13 8917 13 8918 13 8919 13 8920 13 8921 13 8922 13 8923 13 8924 12 8925 13 8926 13 8927 13 8928 15 8929 15 8930 15 8931 15 8932 15 8933 12 8934 12 8935 12 8936 12 8937 12 8938 12 8939 12 8940 12 8941 12 8942 12 8943 12 8944 12 8945 12 8946 12 8947 9 8948 9 8949 9 8950 9 8951 9 8952 9 8953 9 8954 9 8955 9 8956 9 8957 9 8958 12 8959 12 8960 12 8961 12 8962 12 8963 12 8964 12 8965 12 8966 6 8967 6 8968 6 8969 6 8970 6 8971 6 8972 6 8973 6 8974 6 8975 6 8976 6 8977 6 8978 6 8979 6 8980 7 8981 7 8982 7 8983 7 8984 7 8985 7 8986 7 8987 7 8988 7 8989 7 8990 1 8991 1 8992 1 8993 1 8994 1 8995 1 8996 1 8997 1 8998 1 8999 1 9000 1 9001 1 9002 1 9003 1 9004 1 9005 1 9006 1 9007 1 9008 1 9009 1 9010 1 9011 1 9012 1 9013 1 9014 1 9015 1 9016 1 9017 1 9018 1 9019 1 9020 1 9021 1 9022 2 9023 2 9024 2 9025 2 9026 2 9027 2 9028 2 9029 2 9030 2 9031 2 9032 2 9033 2 9034 2 9035 2 9036 2 9037 2 9038 2 9039 2 9040 2 9041 2 9042 2 9043 2 9044 3 9045 2 9046 3 9047 3 9048 2 9049 3 9050 3 9051 3 9052 3 9053 3 9054 3 9055 3 9056 3 9057 3 9058 3 9059 3 9060 3 9061 3 9062 3 9063 3 9064 3 9065 3 9066 3 9067 3 9068 3 9069 3 9070 3 9071 3 9072 3 9073 13 9074 13 9075 13 9076 13 9077 13 9078 13 9079 13 9080 12 9081 12 9082 12 9083 12 9084 12 9085 12 9086 12 9087 12 9088 12 9089 12 9090 12 9091 12 9092 12 9093 12 9094 21 9095 12 9096 12 9097 12 9098 12 9099 12 9100 12 9101 12 9102 12 9103 12 9104 12 9105 12 9106 13 9107 13 9108 12 9109 12 9110 12 9111 12 9112 12 9113 12 9114 12 9115 12 9116 12 9117 12 9118 12 9119 12 9120 12 9121 9 9122 9 9123 9 9124 9 9125 9 9126 9 9127 9 9128 12 9129 12 9130 12 9131 12 9132 12 9133 12 9134 12 9135 12 9136 12 9137 12 9138 6 9139 6 9140 6 9141 6 9142 6 9143 6 9144 6 9145 6 9146 6 9147 6 9148 6 9149 6 9150 6 9151 6 9152 6 9153 6 9154 6 9155 6 9156 6 9157 7 9158 7 9159 1 9160 1 9161 1 9162 1 9163 1 9164 1 9165 1 9166 1 9167 1 9168 1 9169 1 9170 1 9171 1 9172 1 9173 1 9174 1 9175 1 9176 1 9177 1 9178 1 9179 1 9180 1 9181 1 9182 1 9183 1 9184 1 9185 1 9186 1 9187 1 9188 1 9189 1 9190 1 9191 1 9192 1 9193 1 9194 1 9195 2 9196 2 9197 2 9198 2 9199 2 9200 2 9201 2 9202 2 9203 2 9204 2 9205 2 9206 2 9207 2 9208 2 9209 3 9210 3 9211 3 9212 3 9213 3 9214 3 9215 3 9216 3 9217 3 9218 3 9219 3 9220 3 9221 6 9222 13 9223 13 9224 13 9225 13 9226 13 9227 13 9228 13 9229 12 9230 12 9231 12 9232 12 9233 12 9234 12 9235 12 9236 12 9237 12 9238 12 9239 12 9240 12 9241 12 9242 12 9243 12 9244 12 9245 12 9246 12 9247 12 9248 12 9249 12 9250 9 9251 9 9252 9 9253 9 9254 9 9255 12 9256 12 9257 12 9258 12 9259 12 9260 12 9261 12 9262 12 9263 12 9264 12 9265 12 9266 6 9267 6 9268 6 9269 6 9270 6 9271 6 9272 6 9273 6 9274 6 9275 6 9276 6 9277 6 9278 6 9279 6 9280 6 9281 6 9282 6 9283 6 9284 6 9285 7 9286 1 9287 1 9288 1 9289 1 9290 1 9291 1 9292 1 9293 1 9294 1 9295 2 9296 2 9297 2 9298 2 9299 2 9300 2 9301 2 9302 2 9303 2 9304 2 9305 2 9306 2 9307 2 9308 2 9309 2 9310 2 9311 6 9312 6 9313 3 9314 3 9315 3 9316 3 9317 3 9318 3 9319 3 9320 3 9321 3 9322 3 9323 3 9324 6 9325 6 9326 6 9327 6 9328 13 9329 13 9330 13 9331 13 9332 12 9333 12 9334 12 9335 12 9336 12 9337 12 9338 12 9339 12 9340 12 9341 12 9342 12 9343 12 9344 12 9345 12 9346 12 9347 12 9348 12 9349 12 9350 12 9351 12 9352 12 9353 12 9354 12 9355 12 9356 12 9357 12 9358 12 9359 12 9360 12 9361 12 9362 12 9363 12 9364 12 9365 12 9366 12 9367 12 9368 12 9369 12 9370 12 9371 12 9372 12 9373 12 9374 6 9375 6 9376 6 9377 6 9378 6 9379 6 9380 6 9381 6 9382 6 9383 6 9384 6 9385 6 9386 6 9387 6 9388 6 9389 6 9390 6 9391 6 9392 6 9393 6 9394 6 9395 6 9396 6 9397 1 9398 1 9399 1 9400 1 9401 1 9402 1 9403 1 9404 1 9405 2 9406 2 9407 2 9408 2 9409 2 9410 2 9411 2 9412 2 9413 2 9414 2 9415 6 9416 6 9417 2 9418 2 9419 6 9420 6 9421 6 9422 6 9423 6 9424 6 9425 6 9426 6 9427 6 9428 3 9429 6 9430 6 9431 6 9432 6 9433 6 9434 6 9435 6 9436 6 9437 12 9438 13 9439 12 9440 12 9441 12 9442 12 9443 12 9444 12 9445 12 9446 12 9447 12 9448 12 9449 12 9450 12 9451 12 9452 12 9453 12 9454 12 9455 12 9456 12 9457 12 9458 12 9459 12 9460 12 9461 12 9462 12 9463 12 9464 12 9465 12 9466 12 9467 12 9468 12 9469 12 9470 12 9471 12 9472 12 9473 12 9474 12 9475 12 9476 12 9477 12 9478 12 9479 12 9480 6 9481 6 9482 6 9483 6 9484 6 9485 6 9486 6 9487 6 9488 6 9489 6 9490 6 9491 6 9492 6 9493 6 9494 6 9495 6 9496 6 9497 2 9498 1 9499 6 9500 6 9501 6 9502 6 9503 6 9504 6 9505 6 9506 6 9507 6 9508 6 9509 6 9510 6 9511 6 9512 6 9513 6 9514 6 9515 6 9516 6 9517 6 9518 6 9519 6 9520 6 9521 6 9522 6 9523 6 9524 6 9525 6 9526 6 9527 6 9528 6 9529 6 9530 6 9531 6 9532 12 9533 12 9534 12 9535 12 9536 12 9537 12 9538 12 9539 12 9540 12 9541 12 9542 12 9543 12 9544 12 9545 12 9546 12 9547 12 9548 12 9549 12 9550 12 9551 12 9552 12 9553 12 9554 12 9555 12 9556 12 9557 12 9558 12 9559 12 9560 12 9561 12 9562 12 9563 6 9564 6 9565 6 9566 6 9567 6 9568 6 9569 6 9570 6 9571 6 9572 6 9573 6 9574 6 9575 6 9576 6 9577 6 9578 6 9579 6 9580 6 9581 6 9582 6 9583 6 9584 6 9585 6 9586 6 9587 6 9588 6 9589 6 9590 6 9591 6 9592 6 9593 6 9594 6 9595 6 9596 6 9597 12 9598 12 9599 12 9600 12 9601 12 9602 12 9603 12 9604 12 9605 12 9606 12 9607 12 9608 12 9609 12 9610 12 9611 12 9612 12 9613 12 9614 12 9615 12 9616 12 9617 12 9618 12 9619 12 9620 12 9621 12 9622 12 9623 6 9624 6 9625 6 9626 6 9627 6 9628 6 9629 6 9630 6 9631 6 9632 6 9633 6 9634 6 9635 6 9636 6 9637 6 9638 6 9639 6 9640 6 9641 6 9642 6 9643 6 9644 6 9645 6 9646 12 9647 12 9648 12 9649 12 9650 12 9651 12 9652 12 9653 12 9654 12 9655 12 9656 12 9657 12 9658 12 9659 12 9660 6 9661 6 9662 6 9663 6 9664 6 9665 6 9666 12 9667 12 9668 12 9669 12 9670 16 9671 16 9672 16 9673 16 9674 18 9675 18 9676 16 9677 18 9678 18 9679 18 9680 16 9681 16 9682 16 9683 18 9684 18 9685 16 9686 16 9687 16 9688 16 9689 16 9690 16 9691 16 9692 18 9693 18 9694 23 9695 23 9696 23 9697 29 9698 29 9699 29 9700 23 9701 23 9702 23 9703 23 9704 18 9705 18 9706 27 9707 27 9708 27 9709 27 9710 27 9711 27 9712 27 9713 27 9714 27 9715 27 9716 27 9717 27 9718 27 9719 27 9720 27 9721 16 9722 16 9723 16 9724 16 9725 18 9726 18 9727 18 9728 18 9729 18 9730 18 9731 18 9732 18 9733 18 9734 18 9735 18 9736 18 9737 19 9738 19 9739 25 9740 25 9741 25 9742 25 9743 25 9744 25 9745 0 9746 0 9747 24 9748 24 9749 24 9750 16 9751 14 9752 26 9753 26 9754 26 9755 26 9756 26 9757 26 9758 26 9759 26 9760 26 9761 16 9762 16 9763 21 9764 21 9765 21 9766 2 9767 21 9768 18 9769 18 9770 18 9771 18 9772 18 9773 18 9774 18 9775 17 9776 25 9777 17 9778 18 9779 18 9780 18 9781 27 9782 19 9783 19 9784 0 9785 16 9786 0 9787 0 9788 0 9789 0 9790 21 9791 3 9792 16 9793 29 9794 29 9795 29 9796 16 9797 16 9798 16 9799 16 scotch-6.0.4.dfsg/src/check/data/m4x4_b1.grf0000644002563400244210000000024312374677307023543 0ustar trophimeutilisateurs du domaine0 16 48 1 000 2 2 5 3 1 3 6 3 2 4 7 2 3 8 3 1 6 9 4 2 5 7 10 4 3 6 8 11 3 4 7 12 3 5 10 13 4 6 9 11 14 4 7 10 12 15 3 8 11 16 2 9 14 3 10 13 15 3 11 14 16 2 12 15 scotch-6.0.4.dfsg/src/check/data/bump.grf0000644002563400244210000112143511660573050023323 0ustar trophimeutilisateurs du domaine0 9800 57978 0 000 3 413 407 6 4 9771 43 9772 44 4 76 1474 1475 77 3 1242 147 148 3 693 206 207 3 521 348 349 4 7 412 413 0 4 6 412 8 647 4 9 3238 647 7 4 3235 3238 8 10 4 11 3233 3235 9 4 3234 3233 10 12 4 3684 3234 11 13 4 14 418 3684 12 4 15 417 418 13 4 14 417 16 3088 4 17 3086 3088 15 4 16 3086 3087 18 4 3087 17 3095 19 4 3095 18 3096 20 4 21 414 3096 19 4 20 414 1171 22 4 1171 21 1172 23 4 1172 22 1173 24 4 1173 23 1526 25 4 1526 24 26 9781 4 27 3852 9781 25 4 28 2179 3852 26 4 27 2179 2180 29 4 2180 28 30 2503 4 31 2505 2503 29 4 2508 2505 30 32 4 3330 2508 33 31 4 3330 32 3331 34 4 35 2248 3331 33 4 34 2248 2249 36 4 2249 35 2250 37 4 38 416 2250 36 4 39 415 416 37 4 38 415 2194 40 4 2194 39 2195 41 4 2195 40 2196 42 3 2196 41 43 4 42 2196 9771 1 4 9769 9772 1 45 4 46 9768 9769 44 4 47 427 9768 45 4 48 426 427 46 4 47 426 49 411 4 50 410 411 48 4 49 410 51 421 4 50 421 422 52 4 422 51 4650 53 4 4650 52 4651 54 4 4657 4651 53 55 4 5380 4657 54 56 4 57 430 5380 55 4 56 430 429 58 4 59 408 429 57 4 58 408 2218 60 4 2218 59 2219 61 4 2219 60 2220 62 4 2220 61 2221 63 4 2221 62 2222 64 4 6701 2222 63 65 4 6701 64 6703 66 4 6703 65 3505 67 4 68 3452 3505 66 4 69 3451 3452 67 4 3441 3451 68 70 4 71 2491 3441 69 4 70 2491 2492 72 4 73 409 2492 71 4 72 409 74 428 4 73 428 75 1603 4 74 1603 1604 76 4 2 1474 1604 75 4 1475 2 1476 78 4 1476 77 1477 79 4 1477 78 1478 80 4 1478 79 1479 81 4 1479 80 1480 82 4 1480 81 1481 83 4 1481 82 1482 84 4 1482 83 1483 85 4 86 1160 1483 84 4 85 1160 1161 87 4 1161 86 1162 88 4 1162 87 1163 89 4 1163 88 1186 90 4 1186 89 1185 91 4 1185 90 1187 92 4 1187 91 1188 93 4 1188 92 1189 94 4 1189 93 1190 95 4 1190 94 1191 96 4 1191 95 1192 97 4 1192 96 1193 98 4 1193 97 1194 99 4 1194 98 1195 100 4 1195 99 1196 101 4 1196 100 1197 102 4 1197 101 1198 103 4 1198 102 1199 104 4 1199 103 1200 105 4 1200 104 1201 106 4 1201 105 1202 107 4 1202 106 1203 108 4 1203 107 1204 109 4 1204 108 1205 110 4 1205 109 1206 111 4 1206 110 1207 112 4 1207 111 1208 113 4 1208 112 1209 114 4 1209 113 1210 115 4 1210 114 1211 116 4 1211 115 1212 117 4 1212 116 1213 118 4 1213 117 1214 119 4 1214 118 1215 120 4 1215 119 1216 121 4 1216 120 1217 122 4 1217 121 1218 123 4 1218 122 1219 124 4 1219 123 1220 125 4 1220 124 1221 126 4 1221 125 1222 127 4 1222 126 1223 128 4 1223 127 1224 129 4 1224 128 1225 130 4 1225 129 1226 131 4 1226 130 1227 132 4 1227 131 1228 133 4 1228 132 1229 134 4 1229 133 1230 135 4 1230 134 1231 136 4 1231 135 1232 137 4 1232 136 1233 138 4 1233 137 1234 139 4 1234 138 1235 140 4 1235 139 1236 141 4 1236 140 1237 142 4 1237 141 1238 143 4 1238 142 1239 144 4 1239 143 1240 145 4 1240 144 1241 146 4 1241 145 1242 147 3 1242 146 3 4 1242 3 1243 149 4 1243 148 1244 150 4 1244 149 1245 151 4 1245 150 1246 152 4 1246 151 1247 153 4 1247 152 1248 154 4 155 923 1248 153 4 154 923 924 156 4 924 155 925 157 4 925 156 926 158 4 926 157 927 159 4 927 158 928 160 4 928 159 929 161 4 929 160 930 162 4 930 161 931 163 4 164 651 931 162 4 163 651 652 165 4 652 164 653 166 4 653 165 654 167 4 654 166 655 168 4 655 167 656 169 4 656 168 657 170 4 657 169 658 171 4 658 170 659 172 4 659 171 660 173 4 660 172 661 174 4 661 173 662 175 4 662 174 663 176 4 663 175 664 177 4 664 176 665 178 4 665 177 666 179 4 666 178 667 180 4 667 179 668 181 4 668 180 669 182 4 669 181 670 183 4 670 182 671 184 4 671 183 672 185 4 672 184 673 186 4 673 185 674 187 4 674 186 675 188 4 675 187 676 189 4 676 188 677 190 4 677 189 678 191 4 678 190 679 192 4 679 191 680 193 4 680 192 681 194 4 681 193 682 195 4 682 194 683 196 4 683 195 684 197 4 684 196 685 198 4 685 197 686 199 4 686 198 687 200 4 687 199 688 201 4 688 200 689 202 4 689 201 690 203 4 690 202 691 204 4 691 203 692 205 3 692 204 206 4 692 205 693 4 3 693 4 208 4 693 207 694 209 4 694 208 695 210 4 695 209 696 211 4 696 210 697 212 4 697 211 698 213 4 698 212 699 214 4 699 213 700 215 4 700 214 701 216 4 701 215 702 217 4 702 216 703 218 4 703 217 704 219 4 704 218 705 220 4 705 219 706 221 4 706 220 707 222 4 707 221 708 223 4 708 222 709 224 4 709 223 710 225 4 710 224 711 226 4 711 225 712 227 4 712 226 713 228 4 713 227 714 229 4 714 228 715 230 4 715 229 716 231 4 716 230 717 232 4 717 231 718 233 4 718 232 719 234 4 719 233 720 235 4 720 234 721 236 4 721 235 722 237 4 722 236 723 238 4 723 237 724 239 4 724 238 725 240 4 725 239 726 241 4 726 240 727 242 4 727 241 728 243 4 728 242 729 244 4 729 243 730 245 4 730 244 731 246 4 731 245 732 247 4 732 246 733 248 4 733 247 734 249 4 734 248 735 250 4 735 249 736 251 4 736 250 737 252 4 737 251 738 253 4 738 252 739 254 4 739 253 740 255 4 740 254 741 256 4 741 255 742 257 4 258 431 742 256 4 257 431 432 259 4 432 258 433 260 4 433 259 434 261 4 434 260 435 262 4 435 261 436 263 4 436 262 437 264 4 437 263 438 265 4 438 264 439 266 4 439 265 440 267 4 440 266 441 268 4 441 267 442 269 4 442 268 443 270 4 443 269 444 271 4 444 270 445 272 4 445 271 446 273 4 446 272 447 274 4 447 273 448 275 4 448 274 449 276 4 449 275 450 277 4 450 276 451 278 4 451 277 452 279 4 452 278 453 280 4 453 279 454 281 4 454 280 455 282 4 455 281 456 283 4 456 282 457 284 4 457 283 458 285 4 458 284 459 286 4 459 285 460 287 4 460 286 461 288 4 461 287 462 289 4 462 288 463 290 4 463 289 464 291 4 464 290 465 292 4 465 291 466 293 4 466 292 467 294 4 467 293 468 295 4 468 294 469 296 4 469 295 470 297 4 470 296 471 298 4 471 297 472 299 4 472 298 473 300 4 473 299 474 301 4 474 300 475 302 4 475 301 476 303 4 476 302 477 304 4 477 303 478 305 4 478 304 479 306 4 479 305 480 307 4 480 306 481 308 4 481 307 482 309 4 482 308 483 310 4 483 309 484 311 4 484 310 485 312 4 485 311 486 313 4 486 312 487 314 4 487 313 488 315 4 488 314 489 316 4 489 315 490 317 4 490 316 491 318 4 491 317 492 319 4 492 318 493 320 4 493 319 494 321 4 494 320 495 322 4 495 321 496 323 4 496 322 497 324 4 497 323 498 325 4 498 324 499 326 4 499 325 500 327 4 500 326 501 328 4 501 327 502 329 4 502 328 503 330 4 503 329 504 331 4 504 330 505 332 4 505 331 506 333 4 506 332 507 334 4 507 333 508 335 4 508 334 509 336 4 509 335 510 337 4 510 336 511 338 4 511 337 512 339 4 512 338 513 340 4 513 339 514 341 4 514 340 515 342 4 515 341 516 343 4 516 342 517 344 4 517 343 518 345 4 518 344 519 346 4 519 345 520 347 4 520 346 521 348 3 521 347 5 4 521 5 522 350 4 522 349 523 351 4 523 350 524 352 4 524 351 525 353 4 525 352 526 354 4 526 353 527 355 4 527 354 528 356 4 528 355 529 357 4 529 356 530 358 4 530 357 531 359 4 531 358 532 360 4 532 359 533 361 4 533 360 534 362 4 534 361 535 363 4 535 362 536 364 4 536 363 537 365 4 537 364 538 366 4 538 365 539 367 4 539 366 540 368 4 540 367 541 369 4 541 368 542 370 4 542 369 543 371 4 543 370 544 372 4 544 371 545 373 4 545 372 546 374 4 546 373 547 375 4 550 547 374 376 4 550 375 551 377 4 551 376 552 378 4 552 377 553 379 4 556 553 378 380 4 566 556 379 381 4 566 380 567 382 4 567 381 568 383 4 568 382 569 384 4 569 383 570 385 4 425 570 386 384 4 387 423 425 385 4 386 423 424 388 4 579 424 389 387 4 584 579 388 390 4 584 389 585 391 4 585 390 586 392 4 586 391 420 393 4 394 419 420 392 4 393 419 594 395 4 396 596 594 394 4 622 596 395 397 4 622 396 623 398 4 623 397 624 399 4 398 624 626 400 4 626 399 628 401 4 630 628 402 400 4 630 401 631 403 4 402 631 2097 404 4 405 649 2097 403 4 648 649 404 406 4 648 405 413 407 3 413 406 0 6 58 59 429 2218 2545 2841 6 72 73 2492 2493 1606 428 6 49 50 411 4521 4515 421 6 49 410 48 426 4514 4515 6 6 7 413 647 646 648 6 6 412 648 406 407 0 6 20 21 1171 3882 3128 3096 6 38 39 416 2194 2252 9704 6 38 415 37 2250 2251 2252 6 14 15 418 3088 3098 3099 6 14 417 13 3099 3100 3684 6 393 394 420 593 588 594 6 393 419 586 392 587 588 6 50 51 422 5237 4521 410 6 421 51 52 4650 9684 5237 6 386 387 424 425 577 575 6 423 387 577 578 579 388 6 386 423 572 570 385 575 6 47 48 427 411 4514 5612 6 47 426 46 5612 7500 9768 6 73 74 1603 1605 1606 409 6 58 408 430 57 2841 9690 6 56 57 429 9689 5380 9690 6 257 258 432 742 743 744 6 431 258 259 433 744 745 6 432 259 260 434 745 746 6 433 260 261 435 746 747 6 434 261 262 436 747 748 6 435 262 263 437 748 749 6 436 263 264 438 749 750 6 437 264 265 439 750 751 6 438 265 266 440 751 752 6 439 266 267 441 752 753 6 440 267 268 442 753 754 6 441 268 269 443 754 755 6 442 269 270 444 755 756 6 443 270 271 445 756 757 6 444 271 272 446 757 758 6 445 272 273 447 758 759 6 446 273 274 448 759 760 6 447 274 275 449 760 761 6 448 275 276 450 761 762 6 449 276 277 451 762 763 6 450 277 278 452 763 764 6 451 278 279 453 764 765 6 452 279 280 454 765 766 6 453 280 281 455 766 767 6 454 281 282 456 767 768 6 455 282 283 457 768 769 6 456 283 284 458 769 770 6 457 284 285 459 770 771 6 458 285 286 460 771 772 6 459 286 287 461 772 773 6 460 287 288 462 773 774 6 461 288 289 463 774 775 6 462 289 290 464 775 776 6 463 290 291 465 776 777 6 464 291 292 466 777 778 6 465 292 293 467 778 779 6 466 293 294 468 779 780 6 467 294 295 469 780 781 6 468 295 296 470 781 782 6 469 296 297 471 782 783 6 470 297 298 472 783 784 6 471 298 299 473 784 785 6 472 299 300 474 785 786 6 473 300 301 475 786 787 6 474 301 302 476 787 788 6 475 302 303 477 788 789 6 476 303 304 478 789 790 6 477 304 305 479 790 791 6 478 305 306 480 791 792 6 479 306 307 481 792 793 6 480 307 308 482 793 794 6 481 308 309 483 794 795 6 482 309 310 484 795 796 6 483 310 311 485 796 797 6 484 311 312 486 797 798 6 485 312 313 487 798 799 6 486 313 314 488 799 800 6 487 314 315 489 800 801 6 488 315 316 490 801 802 6 489 316 317 491 802 803 6 490 317 318 492 803 804 6 491 318 319 493 804 805 6 492 319 320 494 805 806 6 493 320 321 495 806 807 6 494 321 322 496 807 808 6 495 322 323 497 808 809 6 496 323 324 498 809 810 6 497 324 325 499 810 811 6 498 325 326 500 811 812 6 499 326 327 501 812 813 6 500 327 328 502 813 814 6 501 328 329 503 814 815 6 502 329 330 504 815 816 6 503 330 331 505 816 817 6 504 331 332 506 817 818 6 505 332 333 507 818 819 6 506 333 334 508 819 820 6 507 334 335 509 820 821 6 508 335 336 510 821 822 6 509 336 337 511 822 823 6 510 337 338 512 823 824 6 511 338 339 513 824 825 6 512 339 340 514 825 826 6 513 340 341 515 826 827 6 514 341 342 516 827 828 6 515 342 343 517 828 829 6 516 343 344 518 829 830 6 517 344 345 519 830 831 6 518 345 346 520 831 832 6 519 346 347 521 832 833 7 520 347 348 5 349 522 833 6 521 349 350 523 833 834 5 522 350 351 524 834 6 523 351 352 525 834 835 6 524 352 353 526 835 836 6 525 353 354 527 836 837 6 526 354 355 528 837 838 6 527 355 356 529 838 839 6 528 356 357 530 839 840 6 529 357 358 531 840 841 6 530 358 359 532 841 842 6 531 359 360 533 842 843 6 532 360 361 534 843 844 6 533 361 362 535 844 845 6 534 362 363 536 845 846 6 535 363 364 537 846 847 6 536 364 365 538 847 848 6 537 365 366 539 848 849 6 538 366 367 540 849 850 6 539 367 368 541 853 850 6 540 368 369 542 855 853 6 541 369 370 543 855 856 6 542 370 371 544 856 857 6 543 371 372 545 857 858 6 544 372 373 546 858 859 6 545 373 374 547 548 859 6 546 374 548 549 550 375 6 546 547 549 859 860 861 6 548 547 550 861 862 863 6 549 547 375 376 551 863 6 550 376 377 552 863 864 6 551 377 378 553 554 864 6 552 378 554 555 556 379 6 552 553 555 557 864 865 6 554 553 556 557 558 565 6 555 553 379 565 566 380 6 554 555 558 559 865 866 6 557 555 559 560 561 565 6 557 558 560 866 867 868 6 559 558 561 562 922 868 6 560 558 562 563 564 565 6 560 561 563 921 920 922 6 562 561 564 9743 921 9744 6 563 561 565 566 9744 567 6 564 561 558 555 556 566 6 565 556 380 381 567 564 6 566 381 382 568 9744 564 6 567 382 383 569 9744 9739 6 568 383 384 570 571 9739 6 569 384 571 572 425 385 6 569 570 572 573 9739 9740 6 571 570 425 573 574 575 6 571 572 574 9740 9741 916 6 573 572 575 576 916 915 6 574 572 425 576 577 423 6 574 575 577 915 2474 1515 6 576 575 423 424 578 1515 6 577 424 579 580 581 1515 6 578 424 388 580 584 389 6 578 579 581 582 583 584 6 578 580 582 1515 1516 1517 6 581 580 583 1517 1508 1506 6 582 580 584 585 589 1506 6 583 580 579 389 390 585 6 584 390 391 586 589 583 6 585 391 392 420 587 589 6 586 420 588 589 590 591 6 587 420 591 592 593 419 6 586 587 590 585 583 1506 6 589 587 591 1506 1507 1514 6 590 587 588 592 599 1514 6 591 588 593 597 598 599 6 592 588 419 594 595 597 6 593 419 394 595 596 395 6 593 594 596 597 621 606 6 595 594 621 622 396 395 6 593 595 592 598 605 606 6 592 597 599 600 604 605 6 592 598 600 601 1514 591 6 599 598 601 602 603 604 6 599 600 602 1513 1514 1539 6 601 600 603 1539 1540 1583 6 602 600 604 1602 1583 608 6 603 600 598 605 607 608 6 604 598 597 606 607 614 6 605 597 621 620 595 614 6 604 605 608 609 610 614 6 604 607 609 1602 603 1600 6 608 607 610 611 1599 1600 6 609 607 611 612 613 614 6 609 610 612 6557 1598 1599 6 611 610 613 615 3764 6557 6 612 610 614 615 616 620 6 613 610 620 606 605 607 6 612 613 616 617 3760 3764 6 615 613 617 618 619 620 6 615 616 618 3760 3761 625 6 617 616 619 623 624 625 6 618 616 620 621 623 622 6 619 616 613 614 621 606 6 619 620 606 595 596 622 6 621 596 396 397 623 619 6 622 397 398 624 618 619 6 623 398 618 625 626 399 6 618 624 626 627 3761 617 6 625 624 627 628 399 400 6 625 626 628 629 3761 3762 6 627 626 629 630 401 400 6 627 628 630 635 3762 632 6 629 628 401 402 631 632 6 630 402 632 633 403 2097 6 630 631 633 634 635 629 6 632 631 634 2097 650 641 6 632 633 635 636 637 641 6 632 634 636 3217 3762 629 6 635 634 637 638 3217 3218 6 636 634 638 639 640 641 6 636 637 639 3218 3219 3220 6 638 637 640 3220 3239 3240 6 639 637 641 642 643 3239 6 640 637 642 633 650 634 6 640 641 643 644 645 650 6 640 642 644 3237 3236 3239 6 643 642 645 646 647 3237 6 644 642 646 648 649 650 5 644 645 647 412 648 7 644 646 412 8 3238 3237 7 7 412 646 645 649 405 406 413 6 648 645 650 405 404 2097 6 649 645 633 2097 641 642 6 163 164 652 931 932 933 6 651 164 165 653 933 934 6 652 165 166 654 934 935 6 653 166 167 655 935 936 6 654 167 168 656 936 937 6 655 168 169 657 937 938 6 656 169 170 658 938 939 6 657 170 171 659 939 940 6 658 171 172 660 940 941 6 659 172 173 661 941 942 6 660 173 174 662 942 943 6 661 174 175 663 943 944 6 662 175 176 664 944 945 6 663 176 177 665 945 946 6 664 177 178 666 946 947 6 665 178 179 667 947 948 6 666 179 180 668 948 949 6 667 180 181 669 949 950 6 668 181 182 670 950 951 6 669 182 183 671 951 952 6 670 183 184 672 952 953 6 671 184 185 673 953 954 6 672 185 186 674 954 955 6 673 186 187 675 955 956 6 674 187 188 676 956 957 6 675 188 189 677 957 958 6 676 189 190 678 958 959 6 677 190 191 679 959 960 6 678 191 192 680 960 961 6 679 192 193 681 961 962 6 680 193 194 682 962 963 6 681 194 195 683 963 964 6 682 195 196 684 964 965 6 683 196 197 685 965 966 6 684 197 198 686 966 967 6 685 198 199 687 967 968 6 686 199 200 688 968 969 6 687 200 201 689 969 970 6 688 201 202 690 970 971 6 689 202 203 691 971 972 6 690 203 204 692 972 973 7 691 204 205 206 693 973 694 6 692 206 4 207 208 694 7 693 208 209 695 973 692 974 6 694 209 210 696 974 975 6 695 210 211 697 975 976 6 696 211 212 698 976 977 6 697 212 213 699 977 978 6 698 213 214 700 978 979 6 699 214 215 701 979 980 6 700 215 216 702 980 981 6 701 216 217 703 981 982 6 702 217 218 704 982 983 6 703 218 219 705 983 984 6 704 219 220 706 984 985 6 705 220 221 707 985 986 6 706 221 222 708 986 987 6 707 222 223 709 987 988 6 708 223 224 710 988 989 6 709 224 225 711 989 990 6 710 225 226 712 990 991 6 711 226 227 713 991 992 6 712 227 228 714 992 993 6 713 228 229 715 993 994 6 714 229 230 716 994 995 6 715 230 231 717 995 996 6 716 231 232 718 996 997 6 717 232 233 719 997 998 6 718 233 234 720 998 999 6 719 234 235 721 999 1000 6 720 235 236 722 1000 1001 6 721 236 237 723 1001 1002 6 722 237 238 724 1002 1003 6 723 238 239 725 1003 1004 6 724 239 240 726 1004 1005 6 725 240 241 727 1005 1006 6 726 241 242 728 1006 1007 6 727 242 243 729 1007 1008 6 728 243 244 730 1008 1009 6 729 244 245 731 1009 1010 6 730 245 246 732 1010 1011 6 731 246 247 733 1011 1012 6 732 247 248 734 1012 1013 6 733 248 249 735 1016 1013 6 734 249 250 736 1016 1017 6 735 250 251 737 1017 1018 6 736 251 252 738 1018 1019 6 737 252 253 739 1019 1020 6 738 253 254 740 1020 1021 6 739 254 255 741 1021 1022 6 740 255 256 742 1022 1023 6 741 256 257 431 743 1023 6 742 431 744 1023 1024 1025 6 743 431 432 745 1025 1026 6 744 432 433 746 1026 1027 6 745 433 434 747 1027 1028 6 746 434 435 748 1028 1029 6 747 435 436 749 1029 1030 6 748 436 437 750 1030 1031 6 749 437 438 751 1031 1032 6 750 438 439 752 1032 1033 6 751 439 440 753 1033 1034 6 752 440 441 754 1034 1035 6 753 441 442 755 1035 1036 6 754 442 443 756 1036 1037 6 755 443 444 757 1037 1038 6 756 444 445 758 1038 1039 6 757 445 446 759 1039 1040 6 758 446 447 760 1040 1041 6 759 447 448 761 1041 1042 6 760 448 449 762 1042 1043 6 761 449 450 763 1043 1044 6 762 450 451 764 1044 1045 6 763 451 452 765 1045 1046 6 764 452 453 766 1046 1047 6 765 453 454 767 1047 1048 6 766 454 455 768 1048 1049 6 767 455 456 769 1049 1050 6 768 456 457 770 1050 1051 6 769 457 458 771 1051 1052 6 770 458 459 772 1052 1053 6 771 459 460 773 1053 1054 6 772 460 461 774 1054 1055 6 773 461 462 775 1055 1056 6 774 462 463 776 1056 1057 6 775 463 464 777 1057 1058 6 776 464 465 778 1058 1059 6 777 465 466 779 1059 1060 6 778 466 467 780 1060 1061 6 779 467 468 781 1061 1062 6 780 468 469 782 1062 1063 6 781 469 470 783 1063 1064 6 782 470 471 784 1064 1065 6 783 471 472 785 1065 1066 6 784 472 473 786 1066 1067 6 785 473 474 787 1067 1068 6 786 474 475 788 1068 1069 6 787 475 476 789 1069 1070 6 788 476 477 790 1070 1071 6 789 477 478 791 1071 1072 6 790 478 479 792 1072 1073 6 791 479 480 793 1073 1074 6 792 480 481 794 1074 1075 6 793 481 482 795 1075 1076 6 794 482 483 796 1076 1077 6 795 483 484 797 1077 1078 6 796 484 485 798 1078 1079 6 797 485 486 799 1079 1080 6 798 486 487 800 1080 1081 6 799 487 488 801 1081 1082 6 800 488 489 802 1082 1083 6 801 489 490 803 1083 1084 6 802 490 491 804 1084 1085 6 803 491 492 805 1085 1086 6 804 492 493 806 1086 1087 6 805 493 494 807 1087 1088 6 806 494 495 808 1088 1089 6 807 495 496 809 1089 1090 6 808 496 497 810 1090 1091 6 809 497 498 811 1091 1092 6 810 498 499 812 1092 1093 6 811 499 500 813 1093 1094 6 812 500 501 814 1094 1095 6 813 501 502 815 1095 1096 6 814 502 503 816 1096 1097 6 815 503 504 817 1097 1098 6 816 504 505 818 1098 1099 6 817 505 506 819 1099 1100 6 818 506 507 820 1100 1101 6 819 507 508 821 1101 1102 6 820 508 509 822 1102 1103 6 821 509 510 823 1103 1104 6 822 510 511 824 1104 1105 6 823 511 512 825 1105 1106 6 824 512 513 826 1106 1107 6 825 513 514 827 1107 1108 6 826 514 515 828 1108 1109 6 827 515 516 829 1109 1110 6 828 516 517 830 1110 1111 6 829 517 518 831 1111 1112 6 830 518 519 832 1112 1113 6 831 519 520 833 1113 1114 6 832 520 521 522 834 1114 6 833 522 523 524 835 1114 7 834 524 525 836 1114 1115 1116 6 835 525 526 837 1116 1117 6 836 526 527 838 1117 1118 6 837 527 528 839 1118 1119 6 838 528 529 840 1119 1120 6 839 529 530 841 1120 1121 6 840 530 531 842 1121 1122 6 841 531 532 843 1122 1123 6 842 532 533 844 1123 1124 6 843 533 534 845 1124 1125 6 844 534 535 846 1125 1126 6 845 535 536 847 1126 1127 6 846 536 537 848 1127 1128 6 847 537 538 849 1128 1129 6 848 538 539 850 851 1129 6 849 539 851 852 853 540 6 849 850 852 1129 1130 1131 6 851 850 853 854 1131 1132 6 852 850 854 855 541 540 6 852 853 855 1132 1133 1134 6 854 853 541 542 856 1134 6 855 542 543 857 1134 1135 6 856 543 544 858 1135 1136 6 857 544 545 859 1136 1137 6 858 545 546 548 860 1137 6 859 548 861 1137 1138 1139 6 860 548 549 862 1139 1140 6 861 549 863 1140 1141 1142 6 862 549 550 551 864 1142 6 863 551 552 554 865 1142 6 864 554 557 866 1142 1143 6 865 557 559 867 1143 1144 6 866 559 868 869 1144 1145 6 867 559 869 870 922 560 6 867 868 870 871 1145 1146 6 869 868 871 872 873 922 6 869 870 872 1146 1147 1148 6 871 870 873 874 1151 1148 6 872 870 874 875 922 920 6 872 873 875 876 1170 1151 6 874 873 876 877 919 920 6 874 875 877 878 879 1170 6 876 875 878 918 882 919 6 876 877 879 880 881 882 6 876 878 880 884 886 1170 6 879 878 881 884 885 891 6 880 878 882 883 891 892 6 881 878 883 917 918 877 6 881 882 912 892 913 917 6 879 880 885 886 887 888 6 884 880 888 889 890 891 6 879 884 887 1964 1169 1170 6 886 884 888 1965 1964 2075 6 887 884 885 889 2075 2076 6 888 885 890 2076 2077 2081 6 889 885 891 893 894 2081 6 890 885 880 881 892 893 6 891 881 893 896 912 883 6 891 892 890 894 895 896 6 890 893 895 897 898 2081 6 894 893 896 897 909 910 6 895 893 892 910 911 912 6 894 895 898 899 900 909 6 894 897 899 901 2081 2080 6 898 897 900 901 902 906 6 899 897 906 907 908 909 6 898 899 902 903 2080 2082 6 901 899 903 904 905 906 6 901 902 904 2082 2083 2084 6 903 902 905 2084 2085 1565 6 904 902 906 1563 1564 1565 6 905 902 899 900 907 1563 6 906 900 908 1543 1563 1536 6 907 900 909 1522 1523 1536 6 908 900 897 895 910 1522 6 909 895 896 911 1520 1522 6 910 896 912 1521 1520 914 6 911 896 892 883 913 914 6 912 883 914 915 916 917 6 912 913 915 2474 1521 911 6 914 913 916 574 576 2474 6 915 913 917 9741 573 574 6 916 913 883 882 918 9741 6 917 882 877 919 9742 9741 6 918 877 875 920 921 9742 6 919 875 921 562 922 873 6 919 920 562 9743 9742 563 6 562 920 873 870 868 560 6 154 155 924 1248 1249 1250 6 923 155 156 925 1250 1251 6 924 156 157 926 1251 1252 6 925 157 158 927 1252 1253 6 926 158 159 928 1253 1254 6 927 159 160 929 1254 1255 6 928 160 161 930 1255 1256 6 929 161 162 931 1256 1257 6 930 162 163 651 932 1257 6 931 651 933 1257 1258 1259 6 932 651 652 934 1259 1260 6 933 652 653 935 1260 1261 6 934 653 654 936 1261 1262 6 935 654 655 937 1262 1263 6 936 655 656 938 1263 1264 6 937 656 657 939 1264 1265 6 938 657 658 940 1265 1266 6 939 658 659 941 1266 1267 6 940 659 660 942 1267 1268 6 941 660 661 943 1268 1269 6 942 661 662 944 1269 1270 6 943 662 663 945 1270 1271 6 944 663 664 946 1271 1272 6 945 664 665 947 1272 1273 6 946 665 666 948 1273 1274 6 947 666 667 949 1274 1275 6 948 667 668 950 1275 1276 6 949 668 669 951 1276 1277 6 950 669 670 952 1277 1278 6 951 670 671 953 1278 1279 6 952 671 672 954 1279 1280 6 953 672 673 955 1280 1281 6 954 673 674 956 1281 1282 6 955 674 675 957 1282 1283 6 956 675 676 958 1283 1284 6 957 676 677 959 1284 1285 6 958 677 678 960 1285 1286 6 959 678 679 961 1286 1287 6 960 679 680 962 1287 1288 6 961 680 681 963 1288 1289 6 962 681 682 964 1289 1290 6 963 682 683 965 1290 1291 6 964 683 684 966 1291 1292 6 965 684 685 967 1292 1293 6 966 685 686 968 1293 1294 6 967 686 687 969 1294 1295 6 968 687 688 970 1295 1296 6 969 688 689 971 1296 1297 6 970 689 690 972 1297 1298 6 971 690 691 973 1298 1299 6 972 691 692 694 974 1299 5 973 694 695 975 1299 6 974 695 696 976 1299 1300 6 975 696 697 977 1300 1301 6 976 697 698 978 1301 1302 6 977 698 699 979 1302 1303 6 978 699 700 980 1303 1304 6 979 700 701 981 1304 1305 6 980 701 702 982 1305 1306 6 981 702 703 983 1306 1307 6 982 703 704 984 1307 1308 6 983 704 705 985 1308 1309 6 984 705 706 986 1309 1310 6 985 706 707 987 1310 1311 6 986 707 708 988 1311 1312 6 987 708 709 989 1312 1313 6 988 709 710 990 1313 1314 6 989 710 711 991 1314 1315 6 990 711 712 992 1315 1316 6 991 712 713 993 1316 1317 6 992 713 714 994 1317 1318 6 993 714 715 995 1318 1319 6 994 715 716 996 1319 1320 6 995 716 717 997 1320 1321 6 996 717 718 998 1321 1322 6 997 718 719 999 1322 1323 6 998 719 720 1000 1323 1324 6 999 720 721 1001 1324 1325 6 1000 721 722 1002 1325 1326 6 1001 722 723 1003 1326 1327 6 1002 723 724 1004 1327 1328 6 1003 724 725 1005 1328 1329 6 1004 725 726 1006 1329 1330 6 1005 726 727 1007 1330 1331 6 1006 727 728 1008 1331 1332 6 1007 728 729 1009 1332 1333 6 1008 729 730 1010 1333 1334 6 1009 730 731 1011 1334 1335 6 1010 731 732 1012 1335 1336 6 1011 732 733 1013 1014 1336 6 1012 733 1014 1015 1016 734 6 1012 1013 1015 1336 1337 1338 6 1014 1013 1016 1338 1339 1340 6 1015 1013 734 735 1017 1340 6 1016 735 736 1018 1340 1341 6 1017 736 737 1019 1341 1342 6 1018 737 738 1020 1342 1343 6 1019 738 739 1021 1343 1344 6 1020 739 740 1022 1344 1345 6 1021 740 741 1023 1345 1346 6 1022 741 742 743 1024 1346 6 1023 743 1025 1346 1347 1348 6 1024 743 744 1026 1348 1349 6 1025 744 745 1027 1349 1350 6 1026 745 746 1028 1350 1351 6 1027 746 747 1029 1351 1352 6 1028 747 748 1030 1352 1353 6 1029 748 749 1031 1353 1354 6 1030 749 750 1032 1354 1355 6 1031 750 751 1033 1355 1356 6 1032 751 752 1034 1356 1357 6 1033 752 753 1035 1357 1358 6 1034 753 754 1036 1358 1359 6 1035 754 755 1037 1359 1360 6 1036 755 756 1038 1360 1361 6 1037 756 757 1039 1361 1362 6 1038 757 758 1040 1362 1363 6 1039 758 759 1041 1363 1364 6 1040 759 760 1042 1364 1365 6 1041 760 761 1043 1365 1366 6 1042 761 762 1044 1366 1367 6 1043 762 763 1045 1367 1368 6 1044 763 764 1046 1368 1369 6 1045 764 765 1047 1369 1370 6 1046 765 766 1048 1370 1371 6 1047 766 767 1049 1371 1372 6 1048 767 768 1050 1372 1373 6 1049 768 769 1051 1373 1374 6 1050 769 770 1052 1374 1375 6 1051 770 771 1053 1375 1376 6 1052 771 772 1054 1376 1377 6 1053 772 773 1055 1377 1378 6 1054 773 774 1056 1378 1379 6 1055 774 775 1057 1379 1380 6 1056 775 776 1058 1380 1381 6 1057 776 777 1059 1381 1382 6 1058 777 778 1060 1382 1383 6 1059 778 779 1061 1383 1384 6 1060 779 780 1062 1384 1385 6 1061 780 781 1063 1385 1386 6 1062 781 782 1064 1386 1387 6 1063 782 783 1065 1387 1388 6 1064 783 784 1066 1388 1389 6 1065 784 785 1067 1389 1390 6 1066 785 786 1068 1390 1391 6 1067 786 787 1069 1391 1392 6 1068 787 788 1070 1392 1393 6 1069 788 789 1071 1393 1394 6 1070 789 790 1072 1394 1395 6 1071 790 791 1073 1395 1396 6 1072 791 792 1074 1396 1397 6 1073 792 793 1075 1397 1398 6 1074 793 794 1076 1398 1399 6 1075 794 795 1077 1399 1400 6 1076 795 796 1078 1400 1401 6 1077 796 797 1079 1401 1402 6 1078 797 798 1080 1402 1403 6 1079 798 799 1081 1403 1404 6 1080 799 800 1082 1404 1405 6 1081 800 801 1083 1405 1406 6 1082 801 802 1084 1406 1407 6 1083 802 803 1085 1407 1408 6 1084 803 804 1086 1408 1409 6 1085 804 805 1087 1409 1410 6 1086 805 806 1088 1410 1411 6 1087 806 807 1089 1411 1412 6 1088 807 808 1090 1412 1413 6 1089 808 809 1091 1413 1414 6 1090 809 810 1092 1414 1415 6 1091 810 811 1093 1415 1416 6 1092 811 812 1094 1416 1417 6 1093 812 813 1095 1417 1418 6 1094 813 814 1096 1418 1419 6 1095 814 815 1097 1419 1420 6 1096 815 816 1098 1420 1421 6 1097 816 817 1099 1421 1422 6 1098 817 818 1100 1422 1423 6 1099 818 819 1101 1423 1424 6 1100 819 820 1102 1424 1425 6 1101 820 821 1103 1425 1426 6 1102 821 822 1104 1426 1427 6 1103 822 823 1105 1427 1428 6 1104 823 824 1106 1428 1429 6 1105 824 825 1107 1429 1430 6 1106 825 826 1108 1430 1431 6 1107 826 827 1109 1431 1432 6 1108 827 828 1110 1432 1433 6 1109 828 829 1111 1433 1434 6 1110 829 830 1112 1434 1435 6 1111 830 831 1113 1435 1436 6 1112 831 832 1114 1436 1115 6 1113 832 833 834 835 1115 6 1114 835 1116 1436 1113 1437 5 1115 835 836 1117 1437 6 1116 836 837 1118 1437 1438 6 1117 837 838 1119 1438 1439 6 1118 838 839 1120 1439 1440 6 1119 839 840 1121 1440 1441 6 1120 840 841 1122 1441 1442 6 1121 841 842 1123 1442 1443 6 1122 842 843 1124 1443 1444 6 1123 843 844 1125 1444 1445 6 1124 844 845 1126 1445 1446 6 1125 845 846 1127 1446 1447 6 1126 846 847 1128 1447 1448 6 1127 847 848 1129 1448 1449 6 1128 848 849 851 1130 1449 6 1129 851 1131 1449 1450 1451 6 1130 851 852 1132 1451 1452 6 1131 852 854 1133 1452 1453 6 1132 854 1134 1456 1453 1152 6 1133 854 855 856 1135 1152 6 1134 856 857 1136 1152 1153 6 1135 857 858 1137 1153 1154 6 1136 858 859 860 1138 1154 6 1137 860 1139 1154 1155 1156 6 1138 860 861 1140 1156 1157 6 1139 861 862 1141 1157 1158 6 1140 862 1142 1158 1159 1143 6 1141 862 863 864 865 1143 6 1142 865 866 1144 1159 1141 6 1143 866 867 1145 1498 1159 6 1144 867 869 1146 1498 1499 6 1145 869 871 1147 1164 1499 6 1146 871 1148 1149 1164 1165 6 1147 871 1149 1150 1151 872 6 1147 1148 1150 1165 1166 1167 6 1149 1148 1151 1167 1168 1169 6 1150 1148 872 1169 1170 874 6 1134 1135 1153 1473 1456 1133 6 1152 1135 1136 1154 1473 1490 6 1153 1136 1137 1138 1155 1490 6 1154 1138 1156 1490 1491 1492 6 1155 1138 1139 1157 1492 1493 6 1156 1139 1140 1158 1493 1494 6 1157 1140 1141 1159 1497 1494 6 1158 1141 1143 1144 1498 1497 6 85 86 1161 1483 1484 1488 6 1160 86 87 1162 1174 1488 6 1161 87 88 1163 1174 1175 6 1162 88 89 1175 1177 1186 6 1146 1147 1165 1499 1527 1528 6 1164 1147 1149 1166 1528 1533 6 1165 1149 1167 1535 1533 1541 6 1166 1149 1150 1168 1541 1962 6 1167 1150 1169 1962 1963 1964 6 1168 1150 1151 1170 886 1964 6 1169 1151 874 886 879 876 6 414 21 22 1172 3337 3882 6 1171 22 23 1173 1524 3337 6 1172 23 24 1524 1525 1526 6 1161 1162 1175 1176 1488 1489 6 1174 1162 1176 1163 1177 1178 6 1174 1175 1489 1642 1643 1178 6 1175 1163 1178 1179 1186 1183 6 1175 1177 1179 1180 1643 1176 6 1178 1177 1180 1181 1182 1183 6 1178 1179 1181 1643 1644 1645 6 1180 1179 1182 1645 1646 1647 6 1181 1179 1183 1184 3097 1647 6 1182 1179 1184 1185 1186 1177 6 1182 1183 1185 3097 2241 1187 6 1184 1183 1186 90 91 1187 6 1185 1183 1177 1163 89 90 6 1185 91 92 1188 2241 1184 6 1187 92 93 1189 2241 1659 6 1188 93 94 1190 1660 1659 6 1189 94 95 1191 1662 1660 6 1190 95 96 1192 1670 1662 6 1191 96 97 1193 1670 1671 6 1192 97 98 1194 1671 1672 6 1193 98 99 1195 1672 1673 6 1194 99 100 1196 1673 1674 6 1195 100 101 1197 1674 1675 6 1196 101 102 1198 1500 1675 6 1197 102 103 1199 1457 1500 6 1198 103 104 1200 1457 1458 6 1199 104 105 1201 1458 1459 6 1200 105 106 1202 1459 1460 6 1201 106 107 1203 1460 1685 6 1202 107 108 1204 1687 1685 6 1203 108 109 1205 1687 1688 6 1204 109 110 1206 1688 1689 6 1205 110 111 1207 1689 1690 6 1206 111 112 1208 1693 1690 6 1207 112 113 1209 1693 1694 6 1208 113 114 1210 1694 1695 6 1209 114 115 1211 1556 1695 6 1210 115 116 1212 1546 1556 6 1211 116 117 1213 1546 1547 6 1212 117 118 1214 1547 1548 6 1213 118 119 1215 1548 1549 6 1214 119 120 1216 1549 1550 6 1215 120 121 1217 1553 1550 6 1216 121 122 1218 1555 1553 6 1217 122 123 1219 1716 1555 6 1218 123 124 1220 1716 1717 6 1219 124 125 1221 1717 1718 6 1220 125 126 1222 1718 1719 6 1221 126 127 1223 1719 1720 6 1222 127 128 1224 1720 1721 6 1223 128 129 1225 1721 1722 6 1224 129 130 1226 1722 1723 6 1225 130 131 1227 1726 1723 6 1226 131 132 1228 1726 1727 6 1227 132 133 1229 1727 1728 6 1228 133 134 1230 1728 1729 6 1229 134 135 1231 1729 1730 6 1230 135 136 1232 1733 1730 6 1231 136 137 1233 1733 1734 6 1232 137 138 1234 1734 1735 6 1233 138 139 1235 1735 1736 6 1234 139 140 1236 1736 1737 6 1235 140 141 1237 1737 1738 6 1236 141 142 1238 1738 1739 6 1237 142 143 1239 1739 1740 6 1238 143 144 1240 1740 1741 6 1239 144 145 1241 1741 1742 6 1240 145 146 1242 1742 1743 7 1241 146 147 3 148 1243 1743 5 1242 148 149 1244 1743 6 1243 149 150 1245 1743 1744 6 1244 150 151 1246 1744 1745 6 1245 151 152 1247 1745 1746 6 1246 152 153 1248 1746 1747 6 1247 153 154 923 1249 1747 6 1248 923 1250 1747 1748 1749 6 1249 923 924 1251 1749 1750 6 1250 924 925 1252 1750 1751 6 1251 925 926 1253 1751 1752 6 1252 926 927 1254 1752 1753 6 1253 927 928 1255 1753 1754 6 1254 928 929 1256 1754 1755 6 1255 929 930 1257 1755 1756 6 1256 930 931 932 1258 1756 6 1257 932 1259 1756 1757 1758 6 1258 932 933 1260 1758 1759 6 1259 933 934 1261 1759 1760 6 1260 934 935 1262 1760 1761 6 1261 935 936 1263 1761 1762 6 1262 936 937 1264 1762 1763 6 1263 937 938 1265 1763 1764 6 1264 938 939 1266 1764 1765 6 1265 939 940 1267 1765 1766 6 1266 940 941 1268 1766 1767 6 1267 941 942 1269 1767 1768 6 1268 942 943 1270 1768 1769 6 1269 943 944 1271 1769 1770 6 1270 944 945 1272 1770 1771 6 1271 945 946 1273 1771 1772 6 1272 946 947 1274 1772 1773 6 1273 947 948 1275 1773 1774 6 1274 948 949 1276 1774 1775 6 1275 949 950 1277 1775 1776 6 1276 950 951 1278 1776 1777 6 1277 951 952 1279 1777 1778 6 1278 952 953 1280 1778 1779 6 1279 953 954 1281 1779 1780 6 1280 954 955 1282 1780 1781 6 1281 955 956 1283 1781 1782 6 1282 956 957 1284 1782 1783 6 1283 957 958 1285 1783 1784 6 1284 958 959 1286 1784 1785 6 1285 959 960 1287 1785 1786 6 1286 960 961 1288 1786 1787 6 1287 961 962 1289 1787 1788 6 1288 962 963 1290 1788 1789 6 1289 963 964 1291 1789 1790 6 1290 964 965 1292 1790 1791 6 1291 965 966 1293 1791 1792 6 1292 966 967 1294 1792 1793 6 1293 967 968 1295 1793 1794 6 1294 968 969 1296 1794 1795 6 1295 969 970 1297 1795 1796 6 1296 970 971 1298 1796 1797 6 1297 971 972 1299 1797 1300 6 1298 972 973 974 975 1300 7 1299 975 976 1301 1797 1298 2100 6 1300 976 977 1302 2100 2101 6 1301 977 978 1303 2101 2102 6 1302 978 979 1304 2102 2103 6 1303 979 980 1305 2103 2104 6 1304 980 981 1306 2104 2105 6 1305 981 982 1307 2105 2106 6 1306 982 983 1308 1798 2106 6 1307 983 984 1309 1798 1799 6 1308 984 985 1310 1799 1800 6 1309 985 986 1311 1800 1801 6 1310 986 987 1312 1801 1802 6 1311 987 988 1313 1802 1803 6 1312 988 989 1314 1803 1804 6 1313 989 990 1315 1804 1805 6 1314 990 991 1316 1805 1806 6 1315 991 992 1317 1806 1807 6 1316 992 993 1318 1807 1808 6 1317 993 994 1319 1808 1809 6 1318 994 995 1320 1809 1810 6 1319 995 996 1321 1810 1811 6 1320 996 997 1322 1811 1812 6 1321 997 998 1323 1812 1813 6 1322 998 999 1324 1813 1814 6 1323 999 1000 1325 1814 1815 6 1324 1000 1001 1326 1815 1816 6 1325 1001 1002 1327 1816 1817 6 1326 1002 1003 1328 1817 1818 6 1327 1003 1004 1329 1818 1819 6 1328 1004 1005 1330 1819 1820 6 1329 1005 1006 1331 1820 1821 6 1330 1006 1007 1332 1821 1822 6 1331 1007 1008 1333 1822 1823 6 1332 1008 1009 1334 1823 1824 6 1333 1009 1010 1335 1824 1825 6 1334 1010 1011 1336 1825 1826 6 1335 1011 1012 1014 1337 1826 6 1336 1014 1338 1826 1827 1828 6 1337 1014 1015 1339 1828 1829 6 1338 1015 1340 1829 1830 1831 6 1339 1015 1016 1017 1341 1831 6 1340 1017 1018 1342 1831 1832 6 1341 1018 1019 1343 1832 1833 6 1342 1019 1020 1344 1833 1834 6 1343 1020 1021 1345 1834 1835 6 1344 1021 1022 1346 1835 1836 6 1345 1022 1023 1024 1347 1836 6 1346 1024 1348 1836 1837 1838 6 1347 1024 1025 1349 1838 1839 6 1348 1025 1026 1350 1839 1840 6 1349 1026 1027 1351 1840 1841 6 1350 1027 1028 1352 1841 1842 6 1351 1028 1029 1353 1842 1843 6 1352 1029 1030 1354 1843 1844 6 1353 1030 1031 1355 1844 1845 6 1354 1031 1032 1356 1845 1846 6 1355 1032 1033 1357 1846 1847 6 1356 1033 1034 1358 1847 1848 6 1357 1034 1035 1359 1848 1849 6 1358 1035 1036 1360 1849 1850 6 1359 1036 1037 1361 1850 1851 6 1360 1037 1038 1362 1851 1852 6 1361 1038 1039 1363 1852 1853 6 1362 1039 1040 1364 1853 1854 6 1363 1040 1041 1365 1854 1855 6 1364 1041 1042 1366 1855 1856 6 1365 1042 1043 1367 1856 1857 6 1366 1043 1044 1368 1857 1858 6 1367 1044 1045 1369 1858 1859 6 1368 1045 1046 1370 1859 1860 6 1369 1046 1047 1371 1860 1861 6 1370 1047 1048 1372 1861 1862 6 1371 1048 1049 1373 1862 1863 6 1372 1049 1050 1374 1863 1864 6 1373 1050 1051 1375 1864 1865 6 1374 1051 1052 1376 1865 1866 6 1375 1052 1053 1377 1866 1867 6 1376 1053 1054 1378 1867 1868 6 1377 1054 1055 1379 1868 1869 6 1378 1055 1056 1380 1869 1870 6 1379 1056 1057 1381 1870 1871 6 1380 1057 1058 1382 1871 1872 6 1381 1058 1059 1383 1872 1873 6 1382 1059 1060 1384 1873 1874 6 1383 1060 1061 1385 1874 1875 6 1384 1061 1062 1386 1875 1876 6 1385 1062 1063 1387 1876 1877 6 1386 1063 1064 1388 1877 1878 6 1387 1064 1065 1389 1878 1879 6 1388 1065 1066 1390 1879 1880 6 1389 1066 1067 1391 1880 1881 6 1390 1067 1068 1392 1881 1882 6 1391 1068 1069 1393 1882 1883 6 1392 1069 1070 1394 1883 1884 6 1393 1070 1071 1395 1884 1885 6 1394 1071 1072 1396 1885 1886 6 1395 1072 1073 1397 1886 1887 6 1396 1073 1074 1398 1887 1888 6 1397 1074 1075 1399 1888 1889 6 1398 1075 1076 1400 1889 1890 6 1399 1076 1077 1401 1890 1891 6 1400 1077 1078 1402 1891 1892 6 1401 1078 1079 1403 1892 1893 6 1402 1079 1080 1404 1893 1894 6 1403 1080 1081 1405 1894 1895 6 1404 1081 1082 1406 1895 1896 6 1405 1082 1083 1407 1896 1897 6 1406 1083 1084 1408 1897 1898 6 1407 1084 1085 1409 1898 1899 6 1408 1085 1086 1410 1899 1900 6 1409 1086 1087 1411 1900 1901 6 1410 1087 1088 1412 1901 1902 6 1411 1088 1089 1413 1902 1903 6 1412 1089 1090 1414 1903 1904 6 1413 1090 1091 1415 1904 1905 6 1414 1091 1092 1416 1905 1906 6 1415 1092 1093 1417 1906 1907 6 1416 1093 1094 1418 1907 1908 6 1417 1094 1095 1419 1908 1909 6 1418 1095 1096 1420 1909 1910 6 1419 1096 1097 1421 1910 1911 6 1420 1097 1098 1422 1911 1912 6 1421 1098 1099 1423 1912 1913 6 1422 1099 1100 1424 1913 1914 6 1423 1100 1101 1425 1914 1915 6 1424 1101 1102 1426 1915 1916 6 1425 1102 1103 1427 1916 1917 6 1426 1103 1104 1428 1917 1918 6 1427 1104 1105 1429 1918 1919 6 1428 1105 1106 1430 1919 1920 6 1429 1106 1107 1431 1920 1921 6 1430 1107 1108 1432 1921 1922 6 1431 1108 1109 1433 1922 1923 6 1432 1109 1110 1434 1923 1924 6 1433 1110 1111 1435 1924 1925 6 1434 1111 1112 1436 1925 1926 6 1435 1112 1113 1115 1437 1926 6 1436 1115 1116 1117 1438 1926 6 1437 1117 1118 1439 1926 1927 6 1438 1118 1119 1440 1927 1928 6 1439 1119 1120 1441 1928 1929 6 1440 1120 1121 1442 1929 1930 6 1441 1121 1122 1443 1930 1931 6 1442 1122 1123 1444 1931 1932 6 1443 1123 1124 1445 1461 1932 6 1444 1124 1125 1446 1461 1462 6 1445 1125 1126 1447 1462 1463 6 1446 1126 1127 1448 1463 1464 6 1447 1127 1128 1449 1464 1465 6 1448 1128 1129 1130 1450 1465 6 1449 1130 1451 1465 1466 1467 6 1450 1130 1131 1452 1467 1468 6 1451 1131 1132 1453 1454 1468 6 1452 1132 1454 1455 1456 1133 6 1452 1453 1455 1468 1469 1470 6 1454 1453 1456 1470 1471 1472 6 1455 1453 1133 1472 1473 1152 6 1198 1199 1458 1500 1501 1679 6 1457 1199 1200 1459 1679 1680 6 1458 1200 1201 1460 1680 1681 6 1459 1201 1202 1681 1684 1685 6 1444 1445 1462 1932 1933 1934 6 1461 1445 1446 1463 1934 1935 6 1462 1446 1447 1464 1935 1936 6 1463 1447 1448 1465 1936 1937 6 1464 1448 1449 1450 1466 1937 6 1465 1450 1467 1937 1938 1939 6 1466 1450 1451 1468 1939 1940 6 1467 1451 1452 1454 1469 1940 6 1468 1454 1470 1940 1941 1942 6 1469 1454 1455 1471 1942 1943 6 1470 1455 1472 1943 1944 1945 6 1471 1455 1456 1473 1945 1946 6 1472 1456 1152 1153 1490 1946 7 76 2 1475 1608 1604 1609 1618 6 1474 2 77 1476 1620 1618 6 1475 77 78 1477 1620 1621 6 1476 78 79 1478 1621 1622 6 1477 79 80 1479 1630 1622 6 1478 80 81 1480 1630 1631 6 1479 81 82 1481 1631 1632 6 1480 82 83 1482 1635 1632 6 1481 83 84 1483 1485 1635 6 1482 84 85 1160 1484 1485 6 1483 1160 1485 1486 1487 1488 6 1483 1484 1486 1502 1635 1482 6 1485 1484 1487 1502 1503 1504 6 1486 1484 1488 1504 1505 1489 6 1487 1484 1160 1161 1174 1489 6 1488 1174 1176 1505 1487 1642 6 1473 1153 1154 1155 1491 1946 6 1490 1155 1492 1946 1947 1948 6 1491 1155 1156 1493 1948 1949 6 1492 1156 1157 1494 1495 1949 6 1493 1157 1495 1496 1497 1158 6 1493 1494 1496 1951 1949 1952 6 1495 1494 1497 1952 1530 1529 6 1496 1494 1158 1159 1498 1529 6 1144 1145 1499 1159 1497 1529 6 1498 1145 1146 1164 1527 1529 6 1197 1198 1457 1501 1675 1676 6 1500 1457 1676 1677 1678 1679 6 1485 1486 1503 1637 1634 1635 6 1502 1486 1504 1637 1638 1639 6 1503 1486 1487 1505 1639 1640 6 1504 1487 1489 1640 1641 1642 6 583 589 590 1507 1508 582 6 1506 590 1508 1509 1513 1514 6 1506 1507 1509 1510 1517 582 6 1508 1507 1510 1511 1512 1513 6 1508 1509 1511 1517 1518 1519 6 1510 1509 1512 1523 1519 1537 6 1511 1509 1513 1537 1538 1539 6 1512 1509 1507 1514 601 1539 6 1513 1507 601 599 591 590 6 577 578 581 1516 2474 576 6 1515 581 1517 1518 1521 2474 6 1516 581 582 1508 1510 1518 6 1517 1510 1519 1520 1521 1516 6 1518 1510 1520 1522 1523 1511 6 1518 1519 1521 911 910 1522 6 1518 1520 911 1516 2474 914 6 910 1520 1519 1523 908 909 6 1522 1519 1511 908 1536 1537 6 1172 1173 1525 3337 3338 4250 6 1524 1173 1526 3130 2205 4250 6 1525 1173 24 25 3130 9781 6 1499 1164 1528 1529 1530 1531 6 1527 1164 1165 1531 1532 1533 6 1497 1498 1499 1527 1530 1496 6 1529 1527 1531 1952 1496 1953 6 1530 1527 1528 1532 1953 1954 6 1531 1528 1533 1534 1954 1955 6 1532 1528 1534 1535 1166 1165 6 1532 1533 1535 1955 1956 1957 6 1534 1533 1166 1541 1960 1957 6 908 1523 1537 1542 1543 907 6 1536 1523 1511 1512 1538 1542 6 1537 1512 1539 1540 1545 1542 6 1538 1512 1513 601 602 1540 6 1539 602 1538 1582 1545 1583 6 1535 1166 1167 1960 1961 1962 6 1536 1537 1543 1544 1545 1538 6 1536 1542 1544 1562 1563 907 6 1543 1542 1545 1562 1580 1577 6 1544 1542 1538 1582 1580 1540 6 1211 1212 1547 1556 1557 1558 6 1546 1212 1213 1548 1561 1558 6 1547 1213 1214 1549 1710 1561 6 1548 1214 1215 1550 1551 1710 6 1549 1215 1551 1552 1553 1216 6 1549 1550 1552 1710 1711 1712 6 1551 1550 1553 1554 1712 1713 6 1552 1550 1554 1555 1217 1216 6 1552 1553 1555 1713 1714 1715 6 1554 1553 1217 1715 1716 1218 6 1210 1211 1546 1557 1695 1696 6 1556 1546 1558 1559 1696 1697 6 1557 1546 1559 1560 1561 1547 6 1557 1558 1560 1697 1698 1699 6 1559 1558 1561 1699 1700 1709 6 1560 1558 1547 1709 1710 1548 6 1543 1544 1563 1564 1576 1577 6 1543 1562 1564 905 907 906 6 1563 1562 905 1565 1566 1576 6 905 1564 1566 1567 2085 904 6 1565 1564 1567 1568 1569 1576 6 1565 1566 1568 2085 3766 3767 6 1567 1566 1569 1570 1571 3767 6 1568 1566 1570 1574 1575 1576 6 1568 1569 1571 1572 1573 1574 7 1568 1570 1572 3769 3767 6317 6319 5 1571 1570 1573 6319 6320 7 1572 1570 1574 6320 6361 6360 2475 6 1573 1570 1569 1575 1578 2475 6 1574 1569 1576 1577 1578 1579 6 1575 1569 1566 1564 1562 1577 6 1576 1562 1575 1579 1580 1544 6 1574 1575 1579 1586 1587 2475 6 1578 1575 1577 1580 1581 1586 6 1579 1577 1544 1581 1582 1545 6 1579 1580 1582 1584 1585 1586 6 1581 1580 1545 1540 1583 1584 6 1582 1540 1584 1602 603 602 6 1582 1583 1581 1585 1601 1602 6 1581 1584 1586 1591 1588 1601 6 1581 1585 1579 1578 1587 1588 6 1578 1586 1588 1589 2475 2476 6 1587 1586 1589 1590 1591 1585 6 1587 1588 1590 6354 6353 2476 6 1589 1588 1591 1592 1594 6354 6 1590 1588 1585 1592 1593 1601 6 1590 1591 1593 1594 1595 1596 6 1592 1591 1599 1596 1600 1601 6 1590 1592 1595 6358 6356 6354 6 1594 1592 1596 1597 3970 6358 6 1595 1592 1597 1598 1599 1593 6 1595 1596 1598 3970 3969 6556 6 1597 1596 1599 6556 6557 611 6 1598 1596 1593 1600 611 609 6 1599 1593 1601 1602 608 609 6 1600 1593 1591 1585 1584 1602 6 1600 1601 1584 1583 603 608 6 74 75 1604 428 1605 1608 5 1603 75 76 1608 1474 6 428 1603 1606 1607 1608 3519 6 428 1605 1607 2493 409 3516 6 1606 1605 3518 3516 1613 3519 7 1605 1603 1604 1474 1609 1610 3519 5 1608 1474 1610 1611 1618 6 1608 1609 1611 1612 1613 3519 6 1610 1609 1612 1616 1617 1618 6 1610 1611 1613 1614 1615 1616 7 1610 1612 1614 3518 1607 3519 3523 6 1613 1612 1615 3523 3524 3528 6 1614 1612 1616 3093 3544 3528 6 1615 1612 1611 1617 3093 3094 6 1616 1611 1618 1619 3094 1624 7 1617 1611 1619 1620 1475 1609 1474 6 1617 1618 1620 1621 1623 1624 5 1619 1618 1475 1476 1621 6 1620 1476 1477 1622 1623 1619 6 1621 1477 1623 1629 1630 1478 6 1621 1622 1619 1624 1625 1629 7 1619 1623 1625 1626 1617 3094 4367 6 1624 1623 1626 1627 1628 1629 5 1624 1625 1627 4376 4367 7 1626 1625 1628 4377 4376 2862 7215 6 1627 1625 1629 2861 1633 2862 6 1628 1625 1623 1622 1630 2861 6 1629 1622 1478 1479 1631 2861 6 1630 1479 1480 1632 1633 2861 6 1631 1480 1633 1634 1635 1481 7 1631 1632 1634 1636 2861 1628 2862 6 1633 1632 1635 1636 1637 1502 6 1634 1632 1481 1502 1485 1482 5 1633 1634 1637 2862 2863 7 1636 1634 1502 1503 1638 2863 2864 5 1637 1503 1639 2864 2865 6 1638 1503 1504 1640 2865 2866 6 1639 1504 1505 1641 2866 2867 6 1640 1505 1642 2479 2490 2867 6 1641 1505 1489 1176 1643 2479 6 1642 1176 1178 1180 1644 2479 6 1643 1180 1645 2479 2480 2481 6 1644 1180 1181 1646 2481 1650 6 1645 1181 1647 1648 1649 1650 6 1646 1181 1648 1655 3097 1182 6 1646 1647 1649 1653 1654 1655 6 1646 1648 1650 1651 1652 1653 6 1646 1649 1651 2481 1645 2495 6 1650 1649 1652 2495 2496 2497 6 1651 1649 1653 2497 2498 2499 6 1652 1649 1648 1654 2499 2500 6 1653 1648 1655 1656 2500 2501 6 1654 1648 1647 1656 1657 3097 6 1654 1655 1657 1658 2501 2812 6 1656 1655 1658 1659 2241 3097 6 1656 1657 1659 1660 1661 2812 6 1658 1657 1660 1189 1188 2241 6 1658 1659 1661 1662 1190 1189 6 1658 1660 1662 1663 1664 2812 6 1661 1660 1663 1670 1191 1190 6 1661 1662 1664 1665 1669 1670 6 1661 1663 1665 1666 2812 2811 6 1664 1663 1666 1667 1668 1669 6 1664 1665 1667 2811 2813 2814 6 1666 1665 1668 2814 2815 2816 6 1667 1665 1669 2816 2821 2822 6 1668 1665 1663 1670 1671 2822 6 1669 1663 1662 1191 1192 1671 6 1670 1192 1193 1672 2822 1669 6 1671 1193 1194 1673 2823 2822 6 1672 1194 1195 1674 3147 2823 6 1673 1195 1196 1675 3147 3412 6 1674 1196 1197 1500 1676 3412 6 1675 1500 1501 1677 3412 3413 6 1676 1501 1678 3413 3414 3415 6 1677 1501 1679 3415 5381 5382 6 1678 1501 1457 1458 1680 5381 6 1679 1458 1459 1681 1682 5381 6 1680 1459 1460 1682 1683 1684 6 1680 1681 1683 3774 5383 5381 6 1682 1681 1684 3774 3775 3776 6 1683 1681 1460 1685 1686 3776 6 1684 1460 1686 1687 1203 1202 6 1684 1685 1687 3776 3777 3781 6 1686 1685 1203 1204 1688 3781 6 1687 1204 1205 1689 3781 3782 6 1688 1205 1206 1690 1691 3782 6 1689 1206 1691 1692 1693 1207 6 1689 1690 1692 3782 3783 3784 6 1691 1690 1693 3784 3785 3786 6 1692 1690 1207 1208 1694 3786 6 1693 1208 1209 1695 3786 3416 6 1694 1209 1210 1556 1696 3416 6 1695 1556 1557 1697 3416 3417 6 1696 1557 1559 1698 3417 3418 6 1697 1559 1699 1703 2223 3418 6 1698 1559 1560 1700 1701 1703 6 1699 1560 1701 1702 1708 1709 6 1699 1700 1702 1703 1704 1705 6 1701 1700 1705 1706 1707 1708 6 1699 1701 1704 1698 2223 2224 6 1703 1701 1705 2224 2225 2226 6 1704 1701 1702 1706 2226 2227 6 1705 1702 1707 2227 2228 2229 6 1706 1702 1708 2229 2230 2231 6 1707 1702 1700 1709 1711 2231 6 1708 1700 1560 1561 1710 1711 6 1709 1561 1548 1549 1551 1711 6 1710 1551 1712 2231 1708 1709 6 1711 1551 1552 1713 2232 2231 6 1712 1552 1554 1714 2240 2232 6 1713 1554 1715 2240 2560 2564 6 1714 1554 1555 1716 2564 2565 6 1715 1555 1218 1219 1717 2565 6 1716 1219 1220 1718 2565 2566 6 1717 1220 1221 1719 2569 2566 6 1718 1221 1222 1720 3463 2569 6 1719 1222 1223 1721 3462 3463 6 1720 1223 1224 1722 3469 3462 6 1721 1224 1225 1723 1724 3469 6 1722 1225 1724 1725 1726 1226 6 1722 1723 1725 2172 3467 3469 6 1724 1723 1726 2172 2173 2174 6 1725 1723 1226 1227 1727 2174 6 1726 1227 1228 1728 2174 2175 6 1727 1228 1229 1729 2175 2176 6 1728 1229 1230 1730 1731 2176 6 1729 1230 1731 1732 1733 1231 6 1729 1730 1732 2178 2176 2808 6 1731 1730 1733 3404 2808 3405 6 1732 1730 1231 1232 1734 3405 6 1733 1232 1233 1735 3405 3406 6 1734 1233 1234 1736 3406 3407 6 1735 1234 1235 1737 3407 3408 6 1736 1235 1236 1738 3408 3409 6 1737 1236 1237 1739 3409 3410 6 1738 1237 1238 1740 3410 3411 6 1739 1238 1239 1741 3197 3411 6 1740 1239 1240 1742 3191 3197 6 1741 1240 1241 1743 3191 1744 6 1742 1241 1242 1243 1244 1744 7 1743 1244 1245 1745 3191 1742 3199 6 1744 1245 1246 1746 2893 3199 6 1745 1246 1247 1747 2751 2893 6 1746 1247 1248 1249 1748 2751 6 1747 1249 1749 2233 2751 2752 6 1748 1249 1250 1750 2233 2234 6 1749 1250 1251 1751 2237 2234 6 1750 1251 1252 1752 2247 2237 6 1751 1252 1253 1753 2247 2253 6 1752 1253 1254 1754 2253 2254 6 1753 1254 1255 1755 2254 2255 6 1754 1255 1256 1756 2255 2256 6 1755 1256 1257 1258 1757 2256 6 1756 1258 1758 2256 2257 2258 6 1757 1258 1259 1759 2258 2259 6 1758 1259 1260 1760 2259 2260 6 1759 1260 1261 1761 2260 2261 6 1760 1261 1262 1762 2261 2262 6 1761 1262 1263 1763 2262 2263 6 1762 1263 1264 1764 2263 2264 6 1763 1264 1265 1765 2264 2265 6 1764 1265 1266 1766 2265 2266 6 1765 1266 1267 1767 2266 2267 6 1766 1267 1268 1768 2267 2268 6 1767 1268 1269 1769 2268 2269 6 1768 1269 1270 1770 2269 2270 6 1769 1270 1271 1771 2270 2271 6 1770 1271 1272 1772 2271 2272 6 1771 1272 1273 1773 2272 2273 6 1772 1273 1274 1774 2273 2274 6 1773 1274 1275 1775 2274 2275 6 1774 1275 1276 1776 2275 2276 6 1775 1276 1277 1777 2276 2277 6 1776 1277 1278 1778 2277 2278 6 1777 1278 1279 1779 2278 2279 6 1778 1279 1280 1780 2279 2280 6 1779 1280 1281 1781 2280 2281 6 1780 1281 1282 1782 2281 2282 6 1781 1282 1283 1783 2282 2283 6 1782 1283 1284 1784 2283 2284 6 1783 1284 1285 1785 2284 2285 6 1784 1285 1286 1786 2285 2286 6 1785 1286 1287 1787 2286 2287 6 1786 1287 1288 1788 2287 2288 6 1787 1288 1289 1789 2288 2289 6 1788 1289 1290 1790 2289 2290 6 1789 1290 1291 1791 2290 2291 6 1790 1291 1292 1792 2291 2292 6 1791 1292 1293 1793 2292 2293 6 1792 1293 1294 1794 2293 2294 6 1793 1294 1295 1795 2294 2295 6 1794 1295 1296 1796 2098 2295 6 1795 1296 1297 1797 2098 2099 6 1796 1297 1298 1300 2099 2100 6 1307 1308 1799 2106 2107 2108 6 1798 1308 1309 1800 2108 2109 6 1799 1309 1310 1801 2109 2110 6 1800 1310 1311 1802 2110 2111 6 1801 1311 1312 1803 2111 2112 6 1802 1312 1313 1804 2112 2113 6 1803 1313 1314 1805 2113 2114 6 1804 1314 1315 1806 2114 2115 6 1805 1315 1316 1807 2115 2116 6 1806 1316 1317 1808 2116 2117 6 1807 1317 1318 1809 2117 2118 6 1808 1318 1319 1810 2118 2119 6 1809 1319 1320 1811 2119 2120 6 1810 1320 1321 1812 2120 2121 6 1811 1321 1322 1813 2121 2122 6 1812 1322 1323 1814 2122 2123 6 1813 1323 1324 1815 2123 2124 6 1814 1324 1325 1816 2124 2125 6 1815 1325 1326 1817 2125 2126 6 1816 1326 1327 1818 2126 2127 6 1817 1327 1328 1819 2127 2128 6 1818 1328 1329 1820 2128 2129 6 1819 1329 1330 1821 2129 2130 6 1820 1330 1331 1822 2130 2131 6 1821 1331 1332 1823 2131 2132 6 1822 1332 1333 1824 2132 2133 6 1823 1333 1334 1825 2133 2134 6 1824 1334 1335 1826 2134 2135 6 1825 1335 1336 1337 1827 2135 6 1826 1337 1828 2135 2136 2137 6 1827 1337 1338 1829 2137 2138 6 1828 1338 1339 1830 2138 2139 6 1829 1339 1831 2139 2140 2141 6 1830 1339 1340 1341 1832 2141 6 1831 1341 1342 1833 2141 2142 6 1832 1342 1343 1834 2142 2143 6 1833 1343 1344 1835 2143 2144 6 1834 1344 1345 1836 2144 2145 6 1835 1345 1346 1347 1837 2145 6 1836 1347 1838 2150 2145 2165 6 1837 1347 1348 1839 2165 2166 6 1838 1348 1349 1840 2166 2167 6 1839 1349 1350 1841 2167 2168 6 1840 1350 1351 1842 2171 2168 6 1841 1351 1352 1843 2349 2171 6 1842 1352 1353 1844 2349 2350 6 1843 1353 1354 1845 2350 2351 6 1844 1354 1355 1846 2351 2352 6 1845 1355 1356 1847 2352 2353 6 1846 1356 1357 1848 2353 2354 6 1847 1357 1358 1849 2354 2355 6 1848 1358 1359 1850 2355 2356 6 1849 1359 1360 1851 2356 2357 6 1850 1360 1361 1852 2357 2358 6 1851 1361 1362 1853 2358 2359 6 1852 1362 1363 1854 2359 2360 6 1853 1363 1364 1855 2360 2361 6 1854 1364 1365 1856 1966 2361 6 1855 1365 1366 1857 1966 1967 6 1856 1366 1367 1858 1967 1968 6 1857 1367 1368 1859 1968 1969 6 1858 1368 1369 1860 1969 1970 6 1859 1369 1370 1861 1970 1971 6 1860 1370 1371 1862 1971 1972 6 1861 1371 1372 1863 1972 1973 6 1862 1372 1373 1864 1973 1974 6 1863 1373 1374 1865 1974 1975 6 1864 1374 1375 1866 1975 1976 6 1865 1375 1376 1867 1976 1977 6 1866 1376 1377 1868 1977 1978 6 1867 1377 1378 1869 1978 1979 6 1868 1378 1379 1870 1979 1980 6 1869 1379 1380 1871 1980 1981 6 1870 1380 1381 1872 1981 1982 6 1871 1381 1382 1873 1982 1983 6 1872 1382 1383 1874 1983 1984 6 1873 1383 1384 1875 1984 1985 6 1874 1384 1385 1876 1985 1986 6 1875 1385 1386 1877 1986 1987 6 1876 1386 1387 1878 1987 1988 6 1877 1387 1388 1879 1988 1989 6 1878 1388 1389 1880 1989 1990 6 1879 1389 1390 1881 1990 1991 6 1880 1390 1391 1882 1991 1992 6 1881 1391 1392 1883 1992 1993 6 1882 1392 1393 1884 1993 1994 6 1883 1393 1394 1885 1994 1995 6 1884 1394 1395 1886 1995 1996 6 1885 1395 1396 1887 1996 1997 6 1886 1396 1397 1888 1997 1998 6 1887 1397 1398 1889 1998 1999 6 1888 1398 1399 1890 1999 2000 6 1889 1399 1400 1891 2000 2001 6 1890 1400 1401 1892 2001 2002 6 1891 1401 1402 1893 2002 2003 6 1892 1402 1403 1894 2003 2004 6 1893 1403 1404 1895 2004 2005 6 1894 1404 1405 1896 2005 2006 6 1895 1405 1406 1897 2006 2007 6 1896 1406 1407 1898 2007 2008 6 1897 1407 1408 1899 2008 2009 6 1898 1408 1409 1900 2009 2010 6 1899 1409 1410 1901 2010 2011 6 1900 1410 1411 1902 2011 2012 6 1901 1411 1412 1903 2012 2013 6 1902 1412 1413 1904 2013 2014 6 1903 1413 1414 1905 2014 2015 6 1904 1414 1415 1906 2015 2016 6 1905 1415 1416 1907 2016 2017 6 1906 1416 1417 1908 2017 2018 6 1907 1417 1418 1909 2018 2019 6 1908 1418 1419 1910 2019 2020 6 1909 1419 1420 1911 2020 2021 6 1910 1420 1421 1912 2021 2022 6 1911 1421 1422 1913 2022 2023 6 1912 1422 1423 1914 2023 2024 6 1913 1423 1424 1915 2024 2025 6 1914 1424 1425 1916 2025 2026 6 1915 1425 1426 1917 2026 2027 6 1916 1426 1427 1918 2027 2028 6 1917 1427 1428 1919 2028 2029 6 1918 1428 1429 1920 2029 2030 6 1919 1429 1430 1921 2030 2031 6 1920 1430 1431 1922 2031 2032 6 1921 1431 1432 1923 2032 2033 6 1922 1432 1433 1924 2033 2034 6 1923 1433 1434 1925 2034 2035 6 1924 1434 1435 1926 2035 1927 6 1925 1435 1436 1437 1438 1927 7 1926 1438 1439 1928 2035 1925 2036 6 1927 1439 1440 1929 2036 2037 6 1928 1440 1441 1930 2037 2038 6 1929 1441 1442 1931 2038 2039 6 1930 1442 1443 1932 2039 2040 7 1931 1443 1444 1461 1933 2040 2041 5 1932 1461 1934 2041 2042 6 1933 1461 1462 1935 2042 2043 6 1934 1462 1463 1936 2043 2044 6 1935 1463 1464 1937 2044 2045 6 1936 1464 1465 1466 1938 2045 6 1937 1466 1939 2045 2046 2047 6 1938 1466 1467 1940 2047 2048 6 1939 1467 1468 1469 1941 2048 6 1940 1469 1942 2048 2049 2050 6 1941 1469 1470 1943 2050 2051 6 1942 1470 1471 1944 2051 2052 6 1943 1471 1945 2052 2053 2054 6 1944 1471 1472 1946 2054 1947 6 1945 1472 1473 1490 1491 1947 6 1946 1491 1948 2054 1945 2055 6 1947 1491 1492 1949 1950 2055 6 1948 1492 1950 1951 1495 1493 6 1948 1949 1951 2055 2056 2057 6 1950 1949 1495 1952 2057 2058 6 1951 1495 1496 1530 1953 2058 6 1952 1530 1531 1954 2058 2059 6 1953 1531 1532 1955 2059 2060 6 1954 1532 1534 1956 2060 2061 6 1955 1534 1957 1958 2061 2062 6 1956 1534 1958 1959 1960 1535 6 1956 1957 1959 2062 2063 2064 6 1958 1957 1960 2064 2065 2066 6 1959 1957 1535 1541 1961 2066 6 1960 1541 1962 2066 2067 2068 6 1961 1541 1167 1168 1963 2068 6 1962 1168 1964 1965 2070 2068 6 1963 1168 1965 887 886 1169 6 1963 1964 887 2072 2070 2075 6 1855 1856 1967 2361 2362 2363 6 1966 1856 1857 1968 2363 2364 6 1967 1857 1858 1969 2364 2365 6 1968 1858 1859 1970 2365 2366 6 1969 1859 1860 1971 2366 2367 6 1970 1860 1861 1972 2367 2368 6 1971 1861 1862 1973 2368 2369 6 1972 1862 1863 1974 2369 2370 6 1973 1863 1864 1975 2370 2371 6 1974 1864 1865 1976 2371 2372 6 1975 1865 1866 1977 2372 2373 6 1976 1866 1867 1978 2373 2374 6 1977 1867 1868 1979 2374 2375 6 1978 1868 1869 1980 2375 2376 6 1979 1869 1870 1981 2376 2377 6 1980 1870 1871 1982 2377 2378 6 1981 1871 1872 1983 2378 2379 6 1982 1872 1873 1984 2379 2380 6 1983 1873 1874 1985 2380 2381 6 1984 1874 1875 1986 2381 2382 6 1985 1875 1876 1987 2382 2383 6 1986 1876 1877 1988 2383 2384 6 1987 1877 1878 1989 2384 2385 6 1988 1878 1879 1990 2385 2386 6 1989 1879 1880 1991 2386 2387 6 1990 1880 1881 1992 2387 2388 6 1991 1881 1882 1993 2388 2389 6 1992 1882 1883 1994 2389 2390 6 1993 1883 1884 1995 2390 2391 6 1994 1884 1885 1996 2391 2392 6 1995 1885 1886 1997 2392 2393 6 1996 1886 1887 1998 2393 2394 6 1997 1887 1888 1999 2394 2395 6 1998 1888 1889 2000 2395 2396 6 1999 1889 1890 2001 2396 2397 6 2000 1890 1891 2002 2397 2398 6 2001 1891 1892 2003 2398 2399 6 2002 1892 1893 2004 2399 2400 6 2003 1893 1894 2005 2400 2401 6 2004 1894 1895 2006 2401 2402 6 2005 1895 1896 2007 2402 2403 6 2006 1896 1897 2008 2403 2404 6 2007 1897 1898 2009 2404 2405 6 2008 1898 1899 2010 2405 2406 6 2009 1899 1900 2011 2406 2407 6 2010 1900 1901 2012 2407 2408 6 2011 1901 1902 2013 2408 2409 6 2012 1902 1903 2014 2409 2410 6 2013 1903 1904 2015 2410 2411 6 2014 1904 1905 2016 2411 2412 6 2015 1905 1906 2017 2412 2413 6 2016 1906 1907 2018 2413 2414 6 2017 1907 1908 2019 2414 2415 6 2018 1908 1909 2020 2415 2416 6 2019 1909 1910 2021 2416 2417 6 2020 1910 1911 2022 2417 2418 6 2021 1911 1912 2023 2418 2419 6 2022 1912 1913 2024 2419 2420 6 2023 1913 1914 2025 2420 2421 6 2024 1914 1915 2026 2421 2422 6 2025 1915 1916 2027 2422 2423 6 2026 1916 1917 2028 2423 2424 6 2027 1917 1918 2029 2424 2425 6 2028 1918 1919 2030 2425 2426 6 2029 1919 1920 2031 2426 2427 6 2030 1920 1921 2032 2427 2428 6 2031 1921 1922 2033 2428 2429 6 2032 1922 1923 2034 2429 2430 6 2033 1923 1924 2035 2430 2431 6 2034 1924 1925 1927 2036 2431 5 2035 1927 1928 2037 2431 6 2036 1928 1929 2038 2431 2432 6 2037 1929 1930 2039 2432 2433 6 2038 1930 1931 2040 2433 2434 7 2039 1931 1932 2041 2434 2435 2436 5 2040 1932 1933 2042 2436 7 2041 1933 1934 2043 2436 2437 2438 6 2042 1934 1935 2044 2438 2439 6 2043 1935 1936 2045 2439 2440 6 2044 1936 1937 1938 2046 2440 6 2045 1938 2047 2440 2441 2442 6 2046 1938 1939 2048 2442 2443 6 2047 1939 1940 1941 2049 2443 6 2048 1941 2050 2443 2444 2448 6 2049 1941 1942 2051 2448 2449 6 2050 1942 1943 2052 2449 2450 6 2051 1943 1944 2053 2450 2451 6 2052 1944 2054 2451 2452 2453 6 2053 1944 1945 1947 2055 2453 6 2054 1947 1948 1950 2056 2453 6 2055 1950 2057 2453 2454 2455 6 2056 1950 1951 2058 2455 2456 6 2057 1951 1952 1953 2059 2456 6 2058 1953 1954 2060 2456 2457 6 2059 1954 1955 2061 2457 2458 6 2060 1955 1956 2062 2458 2459 6 2061 1956 1958 2063 2459 2460 6 2062 1958 2064 2460 2461 2462 6 2063 1958 1959 2065 2462 2463 6 2064 1959 2066 2463 2464 2465 6 2065 1959 1960 1961 2067 2465 6 2066 1961 2068 2069 2465 2466 6 2067 1961 1962 2069 2070 1963 6 2067 2068 2070 2071 2466 2469 6 2069 2068 1963 2071 2072 1965 6 2069 2070 2072 2073 2469 2470 6 2071 2070 1965 2073 2074 2075 6 2071 2072 2074 2473 2470 2086 6 2073 2072 2075 2076 2078 2086 6 2074 2072 1965 887 888 2076 6 2075 888 889 2077 2078 2074 6 2076 889 2078 2079 2080 2081 6 2076 2077 2079 2074 2086 2087 6 2078 2077 2080 2096 2087 2082 6 2079 2077 2081 898 901 2082 6 2080 2077 889 890 894 898 6 2080 901 903 2083 2096 2079 6 2082 903 2084 2096 2095 9776 6 2083 903 904 2085 6093 9776 6 2084 904 1565 1567 3766 6093 6 2074 2078 2087 2088 2473 2073 6 2086 2078 2088 2089 2096 2079 6 2086 2087 2089 2090 2091 2473 6 2088 2087 2090 2094 2095 2096 6 2088 2089 2091 2092 2093 2094 6 2088 2090 2092 2489 2472 2473 6 2091 2090 2093 2489 5947 5948 6 2092 2090 2094 3135 5947 3132 6 2093 2090 2089 2095 3131 3132 6 2094 2089 2096 3131 2083 9776 6 2095 2089 2087 2079 2082 2083 6 631 403 633 650 649 404 6 1795 1796 2099 2295 2296 2297 6 2098 1796 1797 2100 2297 2101 5 2099 1797 1300 1301 2101 6 2100 1301 1302 2102 2297 2099 6 2101 1302 1303 2103 2297 2298 6 2102 1303 1304 2104 2298 2299 6 2103 1304 1305 2105 2299 2300 6 2104 1305 1306 2106 2300 2301 7 2105 1306 1307 1798 2107 2301 2302 5 2106 1798 2108 2302 2303 6 2107 1798 1799 2109 2303 2304 6 2108 1799 1800 2110 2304 2305 6 2109 1800 1801 2111 2305 2306 6 2110 1801 1802 2112 2306 2307 6 2111 1802 1803 2113 2307 2308 6 2112 1803 1804 2114 2308 2309 6 2113 1804 1805 2115 2309 2310 6 2114 1805 1806 2116 2310 2311 6 2115 1806 1807 2117 2311 2312 6 2116 1807 1808 2118 2312 2313 6 2117 1808 1809 2119 2313 2314 6 2118 1809 1810 2120 2314 2315 6 2119 1810 1811 2121 2315 2316 6 2120 1811 1812 2122 2316 2317 6 2121 1812 1813 2123 2317 2318 6 2122 1813 1814 2124 2318 2319 6 2123 1814 1815 2125 2319 2320 6 2124 1815 1816 2126 2320 2321 6 2125 1816 1817 2127 2321 2322 6 2126 1817 1818 2128 2322 2323 6 2127 1818 1819 2129 2323 2324 6 2128 1819 1820 2130 2324 2325 6 2129 1820 1821 2131 2325 2326 6 2130 1821 1822 2132 2326 2327 6 2131 1822 1823 2133 2151 2327 6 2132 1823 1824 2134 2151 2152 6 2133 1824 1825 2135 2152 2153 6 2134 1825 1826 1827 2136 2153 6 2135 1827 2137 2153 2154 2155 6 2136 1827 1828 2138 2155 2156 6 2137 1828 1829 2139 2156 2157 6 2138 1829 1830 2140 2157 2158 6 2139 1830 2141 2146 2158 2159 6 2140 1830 1831 1832 2142 2146 6 2141 1832 1833 2143 2146 2147 6 2142 1833 1834 2144 2147 2148 6 2143 1834 1835 2145 2148 2149 6 2144 1835 1836 2149 2150 1837 6 2140 2141 2142 2147 2159 2160 6 2146 2142 2143 2148 2160 2161 6 2147 2143 2144 2149 2161 2162 6 2148 2144 2145 2150 2162 2163 6 2149 2145 1837 2163 2164 2165 6 2132 2133 2152 2327 2328 2329 6 2151 2133 2134 2153 2329 2330 6 2152 2134 2135 2136 2154 2330 6 2153 2136 2155 2330 2331 2332 6 2154 2136 2137 2156 2332 2333 6 2155 2137 2138 2157 2333 2334 6 2156 2138 2139 2158 2334 2335 6 2157 2139 2140 2159 2335 2336 6 2158 2140 2146 2160 2336 2337 6 2159 2146 2147 2161 2337 2338 6 2160 2147 2148 2162 2338 2339 6 2161 2148 2149 2163 2339 2340 6 2162 2149 2150 2164 2340 2341 6 2163 2150 2165 2341 2342 2343 6 2164 2150 1837 1838 2166 2343 6 2165 1838 1839 2167 2343 2344 6 2166 1839 1840 2168 2169 2344 6 2167 1840 2169 2170 2171 1841 6 2167 2168 2170 2344 2345 2346 6 2169 2168 2171 2346 2347 2348 6 2170 2168 1841 2348 2349 1842 6 1724 1725 2173 3468 3467 4747 6 2172 1725 2174 2804 3395 4747 6 2173 1725 1726 1727 2175 2804 6 2174 1727 1728 2176 2177 2804 6 2175 1728 2177 2178 1731 1729 6 2175 2176 2178 2804 2805 2806 6 2177 2176 1731 2806 2807 2808 6 27 28 2180 2181 3851 3852 6 2179 28 29 2181 2182 2503 6 2179 2180 2182 2183 2199 3851 6 2181 2180 2183 2184 2502 2503 6 2181 2182 2184 2185 2198 2199 6 2183 2182 2185 2186 2193 2502 6 2183 2184 2186 2187 2197 2198 6 2185 2184 2187 2188 2192 2193 6 2185 2186 2188 2189 2197 9713 6 2187 2186 2189 2190 2191 2192 7 2187 2188 2190 9709 9708 9712 9713 5 2189 2188 2191 9710 9709 6 2190 2188 2192 2510 2512 9710 6 2191 2188 2186 2193 2510 2506 6 2192 2186 2184 2502 2504 2506 6 415 39 40 2195 9704 6488 6 2194 40 41 2196 6488 9705 7 2195 41 42 9705 43 9771 9773 6 2185 2187 2198 9713 9714 9720 6 2185 2197 2183 2199 2200 9720 6 2183 2198 2200 2201 2181 3851 6 2199 2198 2201 2202 9720 2217 6 2199 2200 2202 2203 3129 3851 6 2201 2200 2203 2204 2217 2208 6 2201 2202 2204 2205 3129 3130 6 2203 2202 2205 2206 2207 2208 6 2203 2204 2206 3130 1525 4250 6 2205 2204 2207 3343 3341 4250 6 2206 2204 2208 2209 3343 3344 6 2207 2204 2209 2210 2217 2202 6 2207 2208 2210 2211 3344 3345 6 2209 2208 2211 2212 2216 2217 6 2209 2210 2212 2213 3348 3345 6 2211 2210 2213 2214 2215 2216 6 2211 2212 2214 6522 6523 3348 6 2213 2212 2215 9716 9719 6522 6 2214 2212 2216 9716 9715 9714 6 2215 2212 2210 2217 9714 9720 6 2216 2210 2208 2202 9720 2200 6 408 59 60 2219 2545 2546 6 2218 60 61 2220 2549 2546 6 2219 61 62 2221 2549 2551 6 2220 62 63 2222 2551 6702 6 2221 63 6701 6700 6702 64 6 1698 1703 2224 3418 3419 3420 6 2223 1703 1704 2225 3420 3421 6 2224 1704 2226 3421 3422 3426 6 2225 1704 1705 2227 3426 3427 6 2226 1705 1706 2228 3427 3428 6 2227 1706 2229 3428 3429 3430 6 2228 1706 1707 2230 2238 3430 6 2229 1707 2231 2232 2238 2239 6 2230 1707 2232 1712 1711 1708 6 2230 2231 1712 2239 2240 1713 6 1748 1749 2234 2235 2242 2752 6 2233 1749 2235 2236 2237 1750 6 2233 2234 2236 2242 2243 2244 6 2235 2234 2237 2244 2245 2246 6 2236 2234 1750 2246 2247 1751 6 2229 2230 2239 3430 3431 3435 6 2238 2230 2232 2240 3435 2561 6 2239 2232 1713 1714 2560 2561 6 1187 1188 1659 1657 3097 1184 6 2233 2235 2243 2752 2753 2754 6 2242 2235 2244 2754 2755 2756 6 2243 2235 2236 2245 2756 2757 6 2244 2236 2246 2757 2758 2759 6 2245 2236 2237 2247 2759 2760 6 2246 2237 1751 1752 2253 2760 6 34 35 2249 3331 3332 3333 6 2248 35 36 2250 3336 3333 6 2249 36 37 416 2251 3336 7 2250 416 2252 6490 6491 9706 3336 5 2251 416 415 6490 9704 6 2247 1752 1753 2254 2760 2761 6 2253 1753 1754 2255 2761 2762 6 2254 1754 1755 2256 2762 2763 6 2255 1755 1756 1757 2257 2763 6 2256 1757 2258 2763 2764 2765 6 2257 1757 1758 2259 2765 2766 6 2258 1758 1759 2260 2766 2767 6 2259 1759 1760 2261 2767 2768 6 2260 1760 1761 2262 2768 2769 6 2261 1761 1762 2263 2571 2769 6 2262 1762 1763 2264 2571 2572 6 2263 1763 1764 2265 2572 2573 6 2264 1764 1765 2266 2573 2574 6 2265 1765 1766 2267 2574 2575 6 2266 1766 1767 2268 2575 2576 6 2267 1767 1768 2269 2576 2577 6 2268 1768 1769 2270 2577 2578 6 2269 1769 1770 2271 2578 2579 6 2270 1770 1771 2272 2579 2580 6 2271 1771 1772 2273 2580 2581 6 2272 1772 1773 2274 2581 2582 6 2273 1773 1774 2275 2582 2583 6 2274 1774 1775 2276 2583 2584 6 2275 1775 1776 2277 2584 2585 6 2276 1776 1777 2278 2585 2586 6 2277 1777 1778 2279 2586 2587 6 2278 1778 1779 2280 2587 2588 6 2279 1779 1780 2281 2588 2589 6 2280 1780 1781 2282 2589 2590 6 2281 1781 1782 2283 2590 2591 6 2282 1782 1783 2284 2591 2592 6 2283 1783 1784 2285 2592 2593 6 2284 1784 1785 2286 2593 2594 6 2285 1785 1786 2287 2594 2595 6 2286 1786 1787 2288 2595 2596 6 2287 1787 1788 2289 2596 2597 6 2288 1788 1789 2290 2597 2598 6 2289 1789 1790 2291 2598 2599 6 2290 1790 1791 2292 2599 2600 6 2291 1791 1792 2293 2600 2601 6 2292 1792 1793 2294 2601 2602 6 2293 1793 1794 2295 2602 2603 6 2294 1794 1795 2098 2296 2603 6 2295 2098 2297 2603 2604 2605 7 2296 2098 2099 2101 2102 2298 2605 6 2297 2102 2103 2299 2605 2606 6 2298 2103 2104 2300 2606 2607 6 2299 2104 2105 2301 2607 2608 6 2300 2105 2106 2302 2608 2609 6 2301 2106 2107 2303 2609 2610 6 2302 2107 2108 2304 2610 2611 6 2303 2108 2109 2305 2611 2612 6 2304 2109 2110 2306 2612 2613 6 2305 2110 2111 2307 2613 2614 6 2306 2111 2112 2308 2614 2615 6 2307 2112 2113 2309 2615 2616 6 2308 2113 2114 2310 2619 2616 6 2309 2114 2115 2311 2619 2620 6 2310 2115 2116 2312 2620 2621 6 2311 2116 2117 2313 2621 2622 6 2312 2117 2118 2314 2622 2623 6 2313 2118 2119 2315 2623 2624 6 2314 2119 2120 2316 2624 2625 6 2315 2120 2121 2317 2625 2626 6 2316 2121 2122 2318 2626 2627 6 2317 2122 2123 2319 2627 2628 6 2318 2123 2124 2320 2628 2629 6 2319 2124 2125 2321 2629 2630 6 2320 2125 2126 2322 2630 2631 6 2321 2126 2127 2323 2631 2632 6 2322 2127 2128 2324 2632 2633 6 2323 2128 2129 2325 2633 2634 6 2324 2129 2130 2326 2634 2635 6 2325 2130 2131 2327 2635 2636 6 2326 2131 2132 2151 2328 2636 6 2327 2151 2329 2636 2637 2638 6 2328 2151 2152 2330 2641 2638 6 2329 2152 2153 2154 2331 2641 6 2330 2154 2332 2642 2641 2643 6 2331 2154 2155 2333 2643 2644 6 2332 2155 2156 2334 2644 2645 6 2333 2156 2157 2335 2645 2646 6 2334 2157 2158 2336 2646 2647 6 2335 2158 2159 2337 2647 2648 6 2336 2159 2160 2338 2648 2649 6 2337 2160 2161 2339 2649 2650 6 2338 2161 2162 2340 2650 2651 6 2339 2162 2163 2341 2651 2652 6 2340 2163 2164 2342 2652 2653 6 2341 2164 2343 2653 2654 2655 6 2342 2164 2165 2166 2344 2655 6 2343 2166 2167 2169 2345 2655 6 2344 2169 2346 2655 2656 2657 6 2345 2169 2170 2347 2657 2658 6 2346 2170 2348 2658 2659 2660 6 2347 2170 2171 2349 2660 2661 6 2348 2171 1842 1843 2350 2661 6 2349 1843 1844 2351 2661 2662 6 2350 1844 1845 2352 2662 2663 6 2351 1845 1846 2353 2663 2664 6 2352 1846 1847 2354 2664 2665 6 2353 1847 1848 2355 2665 2666 6 2354 1848 1849 2356 2666 2667 6 2355 1849 1850 2357 2667 2668 6 2356 1850 1851 2358 2668 2669 6 2357 1851 1852 2359 2669 2670 6 2358 1852 1853 2360 2670 2671 6 2359 1853 1854 2361 2671 2672 6 2360 1854 1855 1966 2362 2672 6 2361 1966 2363 2672 2673 2674 6 2362 1966 1967 2364 2674 2675 6 2363 1967 1968 2365 2675 2676 6 2364 1968 1969 2366 2676 2677 6 2365 1969 1970 2367 2677 2678 6 2366 1970 1971 2368 2678 2679 6 2367 1971 1972 2369 2679 2680 6 2368 1972 1973 2370 2680 2681 6 2369 1973 1974 2371 2681 2682 6 2370 1974 1975 2372 2682 2683 6 2371 1975 1976 2373 2683 2684 6 2372 1976 1977 2374 2684 2685 6 2373 1977 1978 2375 2685 2686 6 2374 1978 1979 2376 2686 2687 6 2375 1979 1980 2377 2687 2688 6 2376 1980 1981 2378 2688 2689 6 2377 1981 1982 2379 2689 2690 6 2378 1982 1983 2380 2690 2691 6 2379 1983 1984 2381 2691 2692 6 2380 1984 1985 2382 2692 2693 6 2381 1985 1986 2383 2693 2694 6 2382 1986 1987 2384 2694 2695 6 2383 1987 1988 2385 2695 2696 6 2384 1988 1989 2386 2696 2697 6 2385 1989 1990 2387 2697 2698 6 2386 1990 1991 2388 2698 2699 6 2387 1991 1992 2389 2699 2700 6 2388 1992 1993 2390 2700 2701 6 2389 1993 1994 2391 2701 2702 6 2390 1994 1995 2392 2702 2703 6 2391 1995 1996 2393 2703 2704 6 2392 1996 1997 2394 2704 2705 6 2393 1997 1998 2395 2705 2706 6 2394 1998 1999 2396 2706 2707 6 2395 1999 2000 2397 2707 2708 6 2396 2000 2001 2398 2708 2709 6 2397 2001 2002 2399 2513 2709 6 2398 2002 2003 2400 2513 2514 6 2399 2003 2004 2401 2514 2515 6 2400 2004 2005 2402 2515 2516 6 2401 2005 2006 2403 2516 2517 6 2402 2006 2007 2404 2517 2518 6 2403 2007 2008 2405 2518 2519 6 2404 2008 2009 2406 2519 2520 6 2405 2009 2010 2407 2520 2521 6 2406 2010 2011 2408 2521 2522 6 2407 2011 2012 2409 2522 2523 6 2408 2012 2013 2410 2523 2524 6 2409 2013 2014 2411 2524 2525 6 2410 2014 2015 2412 2525 2526 6 2411 2015 2016 2413 2526 2527 6 2412 2016 2017 2414 2527 2528 6 2413 2017 2018 2415 2528 2529 6 2414 2018 2019 2416 2529 2530 6 2415 2019 2020 2417 2530 2531 6 2416 2020 2021 2418 2531 2532 6 2417 2021 2022 2419 2532 2533 6 2418 2022 2023 2420 2533 2534 6 2419 2023 2024 2421 2534 2535 6 2420 2024 2025 2422 2535 2536 6 2421 2025 2026 2423 2536 2537 6 2422 2026 2027 2424 2537 2538 6 2423 2027 2028 2425 2538 2539 6 2424 2028 2029 2426 2539 2540 6 2425 2029 2030 2427 2540 2541 6 2426 2030 2031 2428 2541 2542 6 2427 2031 2032 2429 2542 2543 6 2428 2032 2033 2430 2543 2544 6 2429 2033 2034 2431 2544 2432 6 2430 2034 2035 2036 2037 2432 7 2431 2037 2038 2433 2544 2430 2556 6 2432 2038 2039 2434 2556 2557 6 2433 2039 2040 2435 2557 2558 6 2434 2040 2436 2558 2559 2437 5 2435 2040 2041 2042 2437 6 2436 2042 2438 2559 2435 2745 6 2437 2042 2043 2439 2745 2746 7 2438 2043 2044 2440 2746 2747 2748 6 2439 2044 2045 2046 2441 2748 6 2440 2046 2442 2748 2749 2750 6 2441 2046 2047 2443 2750 2445 6 2442 2047 2048 2049 2444 2445 6 2443 2049 2445 2446 2447 2448 6 2443 2444 2446 2750 2442 3060 6 2445 2444 2447 3060 3061 3062 6 2446 2444 2448 3062 3063 3064 6 2447 2444 2049 2050 2449 3064 6 2448 2050 2051 2450 3064 3065 6 2449 2051 2052 2451 3065 3066 6 2450 2052 2053 2452 3066 3067 6 2451 2053 2453 3067 3068 2454 6 2452 2053 2054 2055 2056 2454 6 2453 2056 2455 3068 2452 3074 6 2454 2056 2057 2456 3074 3075 6 2455 2057 2058 2059 2457 3075 6 2456 2059 2060 2458 3075 3076 6 2457 2060 2061 2459 3076 3077 6 2458 2061 2062 2460 3077 3078 6 2459 2062 2063 2461 3078 3079 6 2460 2063 2462 3079 3080 3081 6 2461 2063 2064 2463 3081 3082 6 2462 2064 2065 2464 3082 3083 6 2463 2065 2465 2467 2482 3083 6 2464 2065 2066 2067 2466 2467 6 2465 2067 2069 2467 2468 2469 6 2465 2466 2468 2464 2482 2483 6 2467 2466 2469 2471 2477 2483 6 2468 2466 2069 2071 2470 2471 6 2469 2071 2471 2472 2473 2073 6 2469 2470 2472 2468 2477 2478 6 2471 2470 2473 2489 2478 2091 6 2472 2470 2073 2091 2088 2086 6 1516 1521 914 915 576 1515 6 1578 1587 2476 1574 6361 1573 6 2475 1587 1589 6353 6359 6361 6 2468 2471 2478 2483 2484 2485 6 2477 2471 2485 2488 2489 2472 6 1642 1643 1644 2480 1641 2490 6 2479 1644 2481 2490 2494 2869 6 2480 1644 1645 1650 2494 2495 6 2464 2467 2483 3085 3083 3926 6 2482 2467 2468 2477 2484 3926 6 2483 2477 2485 2486 3926 3150 6 2484 2477 2478 2486 2487 2488 6 2484 2485 2487 3148 3149 3150 6 2486 2485 2488 3148 3967 3161 6 2487 2485 2478 2489 5948 3967 6 2488 2478 2472 2091 2092 5948 6 1641 2479 2480 2867 2868 2869 6 70 71 2492 3436 3437 3441 6 2491 71 72 409 2493 3436 6 2492 409 1606 3515 3436 3516 6 2480 2481 2495 2869 2870 2871 6 2494 2481 1650 1651 2496 2871 6 2495 1651 2497 2871 2872 2882 6 2496 1651 1652 2498 2882 2883 6 2497 1652 2499 2883 4092 4093 6 2498 1652 1653 2500 2809 4093 6 2499 1653 1654 2501 2809 2810 6 2500 1654 1656 2810 2811 2812 6 2184 2182 2503 2193 2504 2505 6 2502 2182 30 2505 29 2180 6 2193 2502 2505 2506 2507 2508 6 2504 2502 2508 31 30 2503 6 2193 2504 2507 2509 2510 2192 6 2506 2504 2508 2509 3330 3880 6 2507 2504 2505 31 3330 32 6 2506 2507 2510 2511 3880 3881 6 2506 2509 2511 2512 2191 2192 6 2510 2509 2512 6499 6498 3881 6 2510 2511 2191 6498 6500 9710 6 2398 2399 2514 2709 2710 2711 6 2513 2399 2400 2515 2711 2712 6 2514 2400 2401 2516 2712 2713 6 2515 2401 2402 2517 2713 2714 6 2516 2402 2403 2518 2714 2715 6 2517 2403 2404 2519 2715 2716 6 2518 2404 2405 2520 2716 2717 6 2519 2405 2406 2521 2717 2718 6 2520 2406 2407 2522 2718 2719 6 2521 2407 2408 2523 2719 2720 6 2522 2408 2409 2524 2720 2721 6 2523 2409 2410 2525 2721 2722 6 2524 2410 2411 2526 2722 2723 6 2525 2411 2412 2527 2723 2724 6 2526 2412 2413 2528 2724 2725 6 2527 2413 2414 2529 2725 2726 6 2528 2414 2415 2530 2726 2727 6 2529 2415 2416 2531 2727 2728 6 2530 2416 2417 2532 2728 2729 6 2531 2417 2418 2533 2729 2730 6 2532 2418 2419 2534 2730 2731 6 2533 2419 2420 2535 2731 2732 6 2534 2420 2421 2536 2732 2733 6 2535 2421 2422 2537 2733 2734 6 2536 2422 2423 2538 2734 2735 6 2537 2423 2424 2539 2735 2736 6 2538 2424 2425 2540 2736 2737 6 2539 2425 2426 2541 2552 2737 6 2540 2426 2427 2542 2552 2553 6 2541 2427 2428 2543 2553 2554 6 2542 2428 2429 2544 2554 2555 6 2543 2429 2430 2432 2555 2556 6 408 2218 2546 2547 2841 2842 6 2545 2218 2547 2548 2549 2219 6 2545 2546 2548 2842 2845 2846 6 2547 2546 2549 2550 2857 2846 6 2548 2546 2219 2220 2550 2551 6 2548 2549 2551 6691 2856 2857 7 2550 2549 2220 2221 6702 6690 6691 6 2540 2541 2553 2737 2738 2739 6 2552 2541 2542 2554 2739 2740 6 2553 2542 2543 2555 2570 2740 6 2554 2543 2544 2556 2570 2557 5 2555 2544 2432 2433 2557 7 2556 2433 2434 2558 2570 2555 2742 5 2557 2434 2435 2559 2742 7 2558 2435 2437 2742 2743 2744 2745 6 2240 1714 2561 2562 2563 2564 6 2240 2560 2562 3435 2239 3446 6 2561 2560 2563 3446 3447 3448 6 2562 2560 2564 3448 3449 2567 6 2563 2560 1714 1715 2565 2567 6 2564 1715 1716 1717 2566 2567 6 2565 1717 2567 2568 2569 1718 6 2565 2566 2568 3449 2563 2564 6 2567 2566 2569 3458 3455 3449 6 2568 2566 1718 3463 3458 1719 6 2554 2555 2557 2740 2741 2742 6 2262 2263 2572 2769 2770 2771 6 2571 2263 2264 2573 2771 2772 6 2572 2264 2265 2574 2772 2773 6 2573 2265 2266 2575 2773 2774 6 2574 2266 2267 2576 2774 2775 6 2575 2267 2268 2577 2775 2776 6 2576 2268 2269 2578 2776 2777 6 2577 2269 2270 2579 2777 2778 6 2578 2270 2271 2580 2778 2779 6 2579 2271 2272 2581 2779 2780 6 2580 2272 2273 2582 2780 2781 6 2581 2273 2274 2583 2781 2782 6 2582 2274 2275 2584 2782 2783 6 2583 2275 2276 2585 2783 2784 6 2584 2276 2277 2586 2784 2785 6 2585 2277 2278 2587 2785 2786 6 2586 2278 2279 2588 2786 2787 6 2587 2279 2280 2589 2787 2788 6 2588 2280 2281 2590 2788 2789 6 2589 2281 2282 2591 2789 2790 6 2590 2282 2283 2592 2790 2791 6 2591 2283 2284 2593 2791 2792 6 2592 2284 2285 2594 2792 2793 6 2593 2285 2286 2595 2793 2794 6 2594 2286 2287 2596 2794 2795 6 2595 2287 2288 2597 2795 2796 6 2596 2288 2289 2598 2796 2797 6 2597 2289 2290 2599 2797 2798 6 2598 2290 2291 2600 2798 2799 6 2599 2291 2292 2601 2799 2800 6 2600 2292 2293 2602 2800 2801 6 2601 2293 2294 2603 2801 2802 6 2602 2294 2295 2296 2604 2802 6 2603 2296 2605 2802 2803 2606 5 2604 2296 2297 2298 2606 7 2605 2298 2299 2607 2803 2604 2826 5 2606 2299 2300 2608 2826 7 2607 2300 2301 2609 2826 2827 2828 6 2608 2301 2302 2610 2828 2829 6 2609 2302 2303 2611 2829 2830 6 2610 2303 2304 2612 2830 2831 6 2611 2304 2305 2613 2831 2832 6 2612 2305 2306 2614 2832 2833 6 2613 2306 2307 2615 2833 2834 6 2614 2307 2308 2616 2617 2834 6 2615 2308 2617 2618 2619 2309 6 2615 2616 2618 2834 2835 2836 6 2617 2616 2619 2836 2837 2838 6 2618 2616 2309 2310 2620 2838 6 2619 2310 2311 2621 2840 2838 6 2620 2311 2312 2622 2959 2840 6 2621 2312 2313 2623 2959 2960 6 2622 2313 2314 2624 2960 2961 6 2623 2314 2315 2625 2961 2962 6 2624 2315 2316 2626 2962 2963 6 2625 2316 2317 2627 2966 2963 6 2626 2317 2318 2628 2966 2967 6 2627 2318 2319 2629 2967 2968 6 2628 2319 2320 2630 2968 2969 6 2629 2320 2321 2631 2969 2970 6 2630 2321 2322 2632 2970 2971 6 2631 2322 2323 2633 2971 2972 6 2632 2323 2324 2634 2972 2973 6 2633 2324 2325 2635 2973 2974 6 2634 2325 2326 2636 2974 2975 6 2635 2326 2327 2328 2637 2975 6 2636 2328 2638 2639 2975 2976 6 2637 2328 2639 2640 2641 2329 6 2637 2638 2640 2976 2977 2978 6 2639 2638 2641 2642 2978 2979 6 2640 2638 2642 2331 2330 2329 6 2640 2641 2331 2643 2979 2980 6 2642 2331 2332 2644 2980 2981 6 2643 2332 2333 2645 2981 2982 6 2644 2333 2334 2646 2982 2983 6 2645 2334 2335 2647 2983 2984 6 2646 2335 2336 2648 2984 2985 6 2647 2336 2337 2649 2985 2986 6 2648 2337 2338 2650 2986 2987 6 2649 2338 2339 2651 2987 2988 6 2650 2339 2340 2652 2988 2989 6 2651 2340 2341 2653 2989 2990 6 2652 2341 2342 2654 2990 2991 6 2653 2342 2655 2991 2992 2656 6 2654 2342 2343 2344 2345 2656 6 2655 2345 2657 2992 2654 2993 6 2656 2345 2346 2658 2993 2994 6 2657 2346 2347 2659 2994 2995 6 2658 2347 2660 2995 2996 2997 6 2659 2347 2348 2661 2997 2998 6 2660 2348 2349 2350 2662 2998 6 2661 2350 2351 2663 2998 2999 6 2662 2351 2352 2664 2999 3000 6 2663 2352 2353 2665 3000 3001 6 2664 2353 2354 2666 3001 3002 6 2665 2354 2355 2667 3002 3565 6 2666 2355 2356 2668 3565 3566 6 2667 2356 2357 2669 3566 3567 6 2668 2357 2358 2670 3567 3568 6 2669 2358 2359 2671 3568 3569 6 2670 2359 2360 2672 3569 3570 6 2671 2360 2361 2362 2673 3570 6 2672 2362 2674 3570 3571 3572 6 2673 2362 2363 2675 3572 3573 6 2674 2363 2364 2676 3391 3573 6 2675 2364 2365 2677 3391 3392 6 2676 2365 2366 2678 3392 3393 6 2677 2366 2367 2679 3393 3394 6 2678 2367 2368 2680 3394 3579 6 2679 2368 2369 2681 3579 3580 6 2680 2369 2370 2682 3580 3581 6 2681 2370 2371 2683 3581 3582 6 2682 2371 2372 2684 3582 3583 6 2683 2372 2373 2685 3583 3584 6 2684 2373 2374 2686 3584 3585 6 2685 2374 2375 2687 3585 3586 6 2686 2375 2376 2688 3586 3587 6 2687 2376 2377 2689 3587 3588 6 2688 2377 2378 2690 3278 3588 6 2689 2378 2379 2691 3278 3279 6 2690 2379 2380 2692 3279 3280 6 2691 2380 2381 2693 3280 3281 6 2692 2381 2382 2694 3281 3282 6 2693 2382 2383 2695 3282 3283 6 2694 2383 2384 2696 3283 3284 6 2695 2384 2385 2697 3284 3285 6 2696 2385 2386 2698 3285 3286 6 2697 2386 2387 2699 3286 3287 6 2698 2387 2388 2700 3287 3288 6 2699 2388 2389 2701 3288 3289 6 2700 2389 2390 2702 3289 3290 6 2701 2390 2391 2703 3003 3290 6 2702 2391 2392 2704 3003 3004 6 2703 2392 2393 2705 3004 3005 6 2704 2393 2394 2706 3005 3006 6 2705 2394 2395 2707 3006 3007 6 2706 2395 2396 2708 3007 3008 6 2707 2396 2397 2709 3008 3009 6 2708 2397 2398 2513 2710 3009 6 2709 2513 2711 3009 3010 3011 6 2710 2513 2514 2712 3011 3012 6 2711 2514 2515 2713 3012 3013 6 2712 2515 2516 2714 3013 3014 6 2713 2516 2517 2715 3014 3015 6 2714 2517 2518 2716 3015 3016 6 2715 2518 2519 2717 3016 3017 6 2716 2519 2520 2718 3017 3018 6 2717 2520 2521 2719 3018 3019 6 2718 2521 2522 2720 3019 3020 6 2719 2522 2523 2721 3020 3021 6 2720 2523 2524 2722 3021 3022 6 2721 2524 2525 2723 3022 3023 6 2722 2525 2526 2724 3023 3024 6 2723 2526 2527 2725 3024 3025 6 2724 2527 2528 2726 3025 3026 6 2725 2528 2529 2727 3026 3027 6 2726 2529 2530 2728 3027 3028 6 2727 2530 2531 2729 3028 3029 6 2728 2531 2532 2730 3029 3030 6 2729 2532 2533 2731 3030 3031 6 2730 2533 2534 2732 3031 3032 6 2731 2534 2535 2733 3032 3033 6 2732 2535 2536 2734 3033 3034 6 2733 2536 2537 2735 3034 3035 6 2734 2537 2538 2736 3035 3036 6 2735 2538 2539 2737 3036 3037 6 2736 2539 2540 2552 2738 3037 6 2737 2552 2739 3037 3038 3039 6 2738 2552 2553 2740 3039 3040 6 2739 2553 2554 2570 2741 3040 6 2740 2570 2742 3040 3041 2743 6 2741 2570 2557 2558 2559 2743 6 2742 2559 2744 3041 2741 3049 5 2743 2559 2745 3049 3050 6 2744 2559 2437 2438 2746 3050 6 2745 2438 2439 2747 3050 3051 6 2746 2439 2748 3051 3052 2749 5 2747 2439 2440 2441 2749 6 2748 2441 2750 3052 2747 3058 7 2749 2441 2442 2445 3058 3059 3060 6 1746 1747 1748 2752 2893 2894 6 2751 1748 2233 2242 2753 2894 6 2752 2242 2754 2894 2895 2896 6 2753 2242 2243 2755 2896 2897 6 2754 2243 2756 2897 2898 2899 6 2755 2243 2244 2757 2899 2900 6 2756 2244 2245 2758 2900 2901 6 2757 2245 2759 2901 2902 2903 6 2758 2245 2246 2760 2903 2904 6 2759 2246 2247 2253 2761 2904 6 2760 2253 2254 2762 2904 2905 6 2761 2254 2255 2763 2905 2906 6 2762 2255 2256 2257 2764 2906 6 2763 2257 2765 2906 2907 2908 6 2764 2257 2258 2766 2908 2909 6 2765 2258 2259 2767 2909 2910 6 2766 2259 2260 2768 2910 2911 6 2767 2260 2261 2769 2911 2912 6 2768 2261 2262 2571 2770 2912 6 2769 2571 2771 2912 2913 2914 6 2770 2571 2572 2772 2914 2915 6 2771 2572 2573 2773 2915 2916 6 2772 2573 2574 2774 2916 2917 6 2773 2574 2575 2775 2917 2918 6 2774 2575 2576 2776 2918 2919 6 2775 2576 2577 2777 2919 2920 6 2776 2577 2578 2778 2920 2921 6 2777 2578 2579 2779 2921 2922 6 2778 2579 2580 2780 2922 2923 6 2779 2580 2581 2781 2923 2924 6 2780 2581 2582 2782 2924 2925 6 2781 2582 2583 2783 2925 2926 6 2782 2583 2584 2784 2926 2927 6 2783 2584 2585 2785 2927 2928 6 2784 2585 2586 2786 2928 2929 6 2785 2586 2587 2787 2929 2930 6 2786 2587 2588 2788 2930 2931 6 2787 2588 2589 2789 2931 2932 6 2788 2589 2590 2790 2932 2933 6 2789 2590 2591 2791 2933 2934 6 2790 2591 2592 2792 2934 2935 6 2791 2592 2593 2793 2935 2936 6 2792 2593 2594 2794 2936 2937 6 2793 2594 2595 2795 2937 2938 6 2794 2595 2596 2796 2938 2939 6 2795 2596 2597 2797 2939 2940 6 2796 2597 2598 2798 2940 2941 6 2797 2598 2599 2799 2941 2942 6 2798 2599 2600 2800 2942 2943 6 2799 2600 2601 2801 2943 2944 6 2800 2601 2602 2802 2944 2824 6 2801 2602 2603 2604 2803 2824 6 2802 2604 2606 2824 2825 2826 6 2173 2174 2175 2177 2805 3395 6 2804 2177 2806 3395 3396 3400 6 2805 2177 2178 2807 3400 3401 6 2806 2178 2808 3401 3402 3403 6 2807 2178 1731 3403 3404 1732 6 2499 2500 2810 4095 4093 4388 6 2809 2500 2501 2811 4388 2813 6 2810 2501 2812 1664 1666 2813 6 2811 2501 1656 1658 1661 1664 6 2811 1666 2814 3139 4388 2810 6 2813 1666 1667 2815 2817 3139 6 2814 1667 2816 2817 2818 2819 6 2815 1667 1668 2819 2820 2821 6 2814 2815 2818 3139 3140 3141 6 2817 2815 2819 3141 3142 3143 6 2818 2815 2816 2820 3143 3144 6 2819 2816 2821 3144 3145 3146 6 2820 2816 1668 2822 2823 3146 6 2821 1668 2823 1672 1671 1669 6 2821 2822 1672 3146 3147 1673 6 2802 2803 2825 2944 2801 2945 6 2824 2803 2826 2945 2946 2827 6 2825 2803 2606 2607 2608 2827 6 2826 2608 2828 2946 2825 2947 5 2827 2608 2609 2829 2947 6 2828 2609 2610 2830 2947 2948 6 2829 2610 2611 2831 2948 2949 6 2830 2611 2612 2832 2949 2950 6 2831 2612 2613 2833 2950 2951 6 2832 2613 2614 2834 2951 2952 7 2833 2614 2615 2617 2835 2952 2953 5 2834 2617 2836 2953 2954 6 2835 2617 2618 2837 2954 2955 6 2836 2618 2838 2839 2955 2956 6 2837 2618 2839 2840 2620 2619 6 2837 2838 2840 2956 2957 2958 6 2839 2838 2620 2958 2959 2621 6 408 2545 2842 2843 9690 429 6 2841 2545 2843 2844 2547 2845 6 2841 2842 2844 3168 9688 9690 6 2843 2842 3168 3165 3162 2845 6 2842 2547 2846 2847 3162 2844 6 2845 2547 2847 2848 2548 2857 6 2845 2846 2848 2849 3162 3163 6 2847 2846 2849 2850 2851 2857 6 2847 2848 2850 2852 2858 3163 6 2849 2848 2851 2852 2853 2854 6 2850 2848 2854 2855 2856 2857 6 2849 2850 2853 2858 2859 2860 5 2852 2850 2854 2860 6676 7 2853 2850 2851 2855 6676 6677 6678 7 2854 2851 2856 6689 6686 6680 6678 6 2855 2851 2857 6691 6689 2550 6 2856 2851 2848 2550 2548 2846 6 2849 2852 2859 3180 3163 6661 7 2858 2852 2860 6661 6674 6666 6662 6 2859 2852 2853 6675 6674 6676 5 1631 1633 1628 1629 1630 6 1628 1633 1636 2863 1627 7215 7 2862 1636 1637 2864 7216 7215 7217 5 2863 1637 1638 2865 7217 7 2864 1638 1639 2866 7217 7218 7219 7 2865 1639 1640 2867 3189 3214 7219 6 2866 1640 1641 2490 2868 3189 6 2867 2490 2869 3189 3190 3181 6 2868 2490 2480 2494 2870 3181 6 2869 2494 2871 2873 2884 3181 6 2870 2494 2495 2496 2872 2873 6 2871 2496 2873 2874 2881 2882 6 2871 2872 2874 2875 2870 2884 6 2873 2872 2875 2876 2880 2881 6 2873 2874 2876 2877 2884 2885 6 2875 2874 2877 2878 2879 2880 6 2875 2876 2878 2885 2886 2887 6 2877 2876 2879 2887 2888 2889 6 2878 2876 2880 2892 2889 7600 6 2879 2876 2874 2881 4086 7600 6 2880 2874 2872 2882 4086 4087 6 2881 2872 2496 2497 2883 4087 6 2882 2497 2498 4087 4088 4092 6 2870 2873 2875 2885 3181 3182 6 2884 2875 2877 2886 3182 3183 6 2885 2877 2887 3183 3184 3185 6 2886 2877 2878 2888 3188 3185 6 2887 2878 2889 2890 3959 3188 6 2888 2878 2890 2891 2892 2879 6 2888 2889 2891 3961 3959 7592 6 2890 2889 2892 7592 7593 7594 6 2891 2889 2879 7600 7597 7594 6 1745 1746 2751 2894 3199 3198 6 2893 2751 2752 2753 2895 3198 6 2894 2753 2896 3198 3200 3201 6 2895 2753 2754 2897 3201 3202 6 2896 2754 2755 2898 3202 3203 6 2897 2755 2899 3203 3204 3205 6 2898 2755 2756 2900 3205 3206 6 2899 2756 2757 2901 3206 3207 6 2900 2757 2758 2902 3207 3208 6 2901 2758 2903 3208 3209 3210 6 2902 2758 2759 2904 3213 3210 6 2903 2759 2760 2761 2905 3213 6 2904 2761 2762 2906 3483 3213 6 2905 2762 2763 2764 2907 3483 6 2906 2764 2908 3482 3212 3483 7 2907 2764 2765 2909 3500 3482 3697 6 2908 2765 2766 2910 3697 3698 6 2909 2766 2767 2911 3698 3699 6 2910 2767 2768 2912 3699 3700 6 2911 2768 2769 2770 2913 3700 6 2912 2770 2914 3700 3701 3702 6 2913 2770 2771 2915 3702 3703 6 2914 2771 2772 2916 3703 3704 6 2915 2772 2773 2917 3704 3705 6 2916 2773 2774 2918 3705 3706 6 2917 2774 2775 2919 3706 3707 6 2918 2775 2776 2920 3707 3708 6 2919 2776 2777 2921 3708 3709 6 2920 2777 2778 2922 3709 3710 6 2921 2778 2779 2923 3710 3711 6 2922 2779 2780 2924 3711 3712 6 2923 2780 2781 2925 3712 3713 6 2924 2781 2782 2926 3713 3714 6 2925 2782 2783 2927 3714 3715 6 2926 2783 2784 2928 3715 3716 6 2927 2784 2785 2929 3716 3717 6 2928 2785 2786 2930 3717 3718 6 2929 2786 2787 2931 3718 3719 6 2930 2787 2788 2932 3719 3720 6 2931 2788 2789 2933 3720 3721 6 2932 2789 2790 2934 3721 3722 6 2933 2790 2791 2935 3722 3723 6 2934 2791 2792 2936 3723 3724 6 2935 2792 2793 2937 3724 3725 6 2936 2793 2794 2938 3725 3726 6 2937 2794 2795 2939 3726 3727 6 2938 2795 2796 2940 3727 3728 6 2939 2796 2797 2941 3728 3729 6 2940 2797 2798 2942 3729 3730 6 2941 2798 2799 2943 3730 3731 6 2942 2799 2800 2944 3731 3732 6 2943 2800 2801 2824 2945 3732 6 2944 2824 2825 2946 3732 3733 6 2945 2825 2827 2947 3733 3734 6 2946 2827 2828 2829 2948 3734 7 2947 2829 2830 2949 3734 3735 3736 6 2948 2830 2831 2950 3242 3736 6 2949 2831 2832 2951 3242 3243 6 2950 2832 2833 2952 3243 3244 6 2951 2833 2834 2953 3244 3245 5 2952 2834 2835 2954 3245 7 2953 2835 2836 2955 3245 3246 3247 6 2954 2836 2837 2956 3247 3248 6 2955 2837 2839 2957 3248 3249 6 2956 2839 2958 3249 3250 3251 6 2957 2839 2840 2959 3251 3252 6 2958 2840 2621 2622 2960 3252 6 2959 2622 2623 2961 3254 3252 6 2960 2623 2624 2962 3254 3255 6 2961 2624 2625 2963 2964 3255 6 2962 2625 2964 2965 2966 2626 6 2962 2963 2965 3255 3256 3257 6 2964 2963 2966 3257 3258 3259 6 2965 2963 2626 2627 2967 3259 6 2966 2627 2628 2968 3259 3260 6 2967 2628 2629 2969 3260 3261 6 2968 2629 2630 2970 3261 3262 6 2969 2630 2631 2971 3262 3263 6 2970 2631 2632 2972 3263 3264 6 2971 2632 2633 2973 3264 3265 6 2972 2633 2634 2974 3265 3266 6 2973 2634 2635 2975 3266 3267 6 2974 2635 2636 2637 2976 3267 6 2975 2637 2639 2977 3267 3268 6 2976 2639 2978 3268 3269 3270 6 2977 2639 2640 2979 3270 3271 6 2978 2640 2642 2980 3271 3272 6 2979 2642 2643 2981 3272 3273 6 2980 2643 2644 2982 3273 3274 6 2981 2644 2645 2983 3274 3275 6 2982 2645 2646 2984 3275 3276 6 2983 2646 2647 2985 3276 3277 6 2984 2647 2648 2986 3277 3824 6 2985 2648 2649 2987 3545 3824 6 2986 2649 2650 2988 3545 3546 6 2987 2650 2651 2989 3546 3547 6 2988 2651 2652 2990 3547 3548 6 2989 2652 2653 2991 3548 3549 6 2990 2653 2654 2992 3549 3550 6 2991 2654 2656 2993 3550 3551 6 2992 2656 2657 2994 3551 3552 6 2993 2657 2658 2995 3552 3553 6 2994 2658 2659 2996 3553 3554 6 2995 2659 2997 3554 3555 3556 6 2996 2659 2660 2998 3556 3557 6 2997 2660 2661 2662 2999 3557 6 2998 2662 2663 3000 3557 3558 6 2999 2663 2664 3001 3558 3559 6 3000 2664 2665 3002 3559 3560 6 3001 2665 2666 3560 3561 3565 6 2702 2703 3004 3290 3291 3292 6 3003 2703 2704 3005 3292 3293 6 3004 2704 2705 3006 3293 3294 6 3005 2705 2706 3007 3294 3295 6 3006 2706 2707 3008 3295 3296 6 3007 2707 2708 3009 3296 3297 6 3008 2708 2709 2710 3010 3297 6 3009 2710 3011 3297 3298 3299 6 3010 2710 2711 3012 3299 3300 6 3011 2711 2712 3013 3300 3301 6 3012 2712 2713 3014 3301 3302 6 3013 2713 2714 3015 3302 3303 6 3014 2714 2715 3016 3303 3304 6 3015 2715 2716 3017 3304 3305 6 3016 2716 2717 3018 3305 3306 6 3017 2717 2718 3019 3306 3307 6 3018 2718 2719 3020 3307 3308 6 3019 2719 2720 3021 3308 3309 6 3020 2720 2721 3022 3309 3310 6 3021 2721 2722 3023 3310 3311 6 3022 2722 2723 3024 3311 3312 6 3023 2723 2724 3025 3312 3313 6 3024 2724 2725 3026 3313 3314 6 3025 2725 2726 3027 3314 3315 6 3026 2726 2727 3028 3315 3316 6 3027 2727 2728 3029 3316 3317 6 3028 2728 2729 3030 3317 3318 6 3029 2729 2730 3031 3318 3319 6 3030 2730 2731 3032 3319 3320 6 3031 2731 2732 3033 3320 3321 6 3032 2732 2733 3034 3321 3322 6 3033 2733 2734 3035 3042 3322 6 3034 2734 2735 3036 3042 3043 6 3035 2735 2736 3037 3043 3044 6 3036 2736 2737 2738 3038 3044 6 3037 2738 3039 3044 3045 3046 6 3038 2738 2739 3040 3046 3047 6 3039 2739 2740 2741 3041 3047 6 3040 2741 2743 3047 3048 3049 6 3034 3035 3043 3322 3323 3324 6 3042 3035 3036 3044 3324 3325 6 3043 3036 3037 3038 3045 3325 6 3044 3038 3046 3325 3326 3327 6 3045 3038 3039 3047 3053 3327 6 3046 3039 3040 3041 3048 3053 6 3047 3041 3049 3053 3054 3055 6 3048 3041 2743 2744 3050 3055 6 3049 2744 2745 2746 3051 3055 6 3050 2746 2747 3052 3055 3056 6 3051 2747 2749 3056 3057 3058 6 3046 3047 3048 3054 3327 3328 6 3053 3048 3055 3328 3329 3056 6 3054 3048 3049 3050 3051 3056 7 3055 3051 3052 3057 3329 3054 3641 5 3056 3052 3058 3641 3642 7 3057 3052 2749 2750 3059 3642 3643 6 3058 2750 3060 3643 3644 3061 5 3059 2750 2445 2446 3061 6 3060 2446 3062 3644 3059 3910 6 3061 2446 2447 3063 3910 3911 6 3062 2447 3064 3069 3911 3912 6 3063 2447 2448 2449 3065 3069 6 3064 2449 2450 3066 3069 3070 6 3065 2450 2451 3067 3070 3071 6 3066 2451 2452 3068 3071 3072 6 3067 2452 2454 3072 3073 3074 6 3063 3064 3065 3070 3912 3913 6 3069 3065 3066 3071 3913 3914 6 3070 3066 3067 3072 3914 3915 6 3071 3067 3068 3073 3915 3916 6 3072 3068 3074 3916 3917 3918 6 3073 3068 2454 2455 3075 3918 6 3074 2455 2456 2457 3076 3918 6 3075 2457 2458 3077 3349 3918 6 3076 2458 2459 3078 3349 3350 6 3077 2459 2460 3079 3107 3350 6 3078 2460 2461 3080 3107 3108 6 3079 2461 3081 3091 3108 3109 6 3080 2461 2462 3082 3091 3092 6 3081 2462 2463 3083 3084 3092 6 3082 2463 3084 3085 2482 2464 6 3082 3083 3085 3092 3112 3359 6 3084 3083 2482 3926 3152 3359 6 16 17 3087 3088 3089 3090 6 3086 17 18 3095 3126 3090 6 16 3086 3089 3098 417 15 6 3088 3086 3090 3098 3103 3104 6 3089 3086 3104 3105 3087 3126 6 3080 3081 3092 3109 3110 3111 6 3091 3081 3082 3084 3111 3112 5 1615 1616 3094 4099 3544 6 3093 1616 1617 4367 4099 1624 6 3087 18 19 3096 3125 3126 6 3095 19 20 3125 3128 414 6 2241 1657 1655 1647 1182 1184 6 3088 3089 417 3099 3102 3103 6 417 3098 418 3100 3101 3102 6 418 3099 3101 3228 3229 3684 6 3100 3099 3102 3226 3228 3498 7 3101 3099 3098 3103 3113 3498 3497 6 3102 3098 3089 3104 3113 3114 6 3103 3089 3090 3105 3106 3114 6 3104 3090 3106 3126 3124 3118 6 3104 3105 3116 3114 3117 3118 6 3078 3079 3108 3350 3351 3352 6 3107 3079 3080 3109 3352 3353 6 3108 3080 3091 3110 3353 3354 6 3109 3091 3111 3354 3355 3356 6 3110 3091 3092 3112 3356 3357 6 3111 3092 3084 3357 3358 3359 5 3102 3103 3114 3115 3497 6 3113 3103 3115 3116 3106 3104 7 3113 3114 3116 3497 3504 3501 3495 6 3115 3114 3106 3117 6712 3504 6 3116 3106 3118 3119 6712 6711 6 3117 3106 3119 3120 3124 3105 6 3117 3118 3120 3121 6711 6713 6 3119 3118 3121 3122 3123 3124 6 3119 3120 3122 3884 3887 6713 6 3121 3120 3123 3127 3883 3884 6 3122 3120 3124 3125 3127 3128 6 3123 3120 3118 3125 3126 3105 6 3123 3124 3126 3128 3095 3096 6 3125 3124 3105 3095 3087 3090 6 3122 3123 3128 3882 3339 3883 6 3127 3123 3125 414 3882 3096 6 2201 2203 3130 3851 3852 9781 6 3129 2203 2205 1525 1526 9781 6 2094 2095 3132 3133 9776 3138 6 2094 3131 3133 3134 3135 2093 6 3132 3131 3134 3136 3137 3138 6 3132 3133 3135 3136 5946 5945 6 3132 3134 5945 5943 5947 2093 6 3134 3133 3137 6090 6091 5946 6 3136 3133 3138 6090 6089 6092 6 3137 3133 6092 6093 9776 3131 6 2813 2814 2817 3140 4388 4386 6 3139 2817 3141 4385 4384 4386 6 3140 2817 2818 3142 4390 4385 6 3141 2818 3143 7767 4390 7768 6 3142 2818 2819 3144 7774 7768 6 3143 2819 2820 3145 7774 7775 6 3144 2820 3146 4231 7775 9791 6 3145 2820 2821 2823 3147 4231 6 3146 2823 1673 1674 3412 4231 6 2486 2487 3149 3156 3157 3161 6 2486 3148 3150 3151 3155 3156 6 2486 3149 3151 3152 3926 2484 6 3150 3149 3152 3153 3154 3155 6 3150 3151 3153 3926 3085 3359 6 3152 3151 3154 3358 3359 3360 6 3153 3151 3155 3360 3361 3362 6 3154 3151 3149 3156 3677 3362 6 3155 3149 3148 3157 3158 3677 6 3156 3148 3158 3159 3160 3161 6 3156 3157 3159 3676 3677 3945 6 3158 3157 3160 3945 3946 3962 6 3159 3157 3161 3962 3963 3964 6 3160 3157 3148 3967 3964 2487 6 2845 2847 3163 3164 3165 2844 6 3162 2847 3164 3180 2858 2849 6 3162 3163 3165 3166 3177 3180 6 3162 3164 3166 3167 3168 2844 6 3165 3164 3167 3177 3174 3171 6 3165 3166 3168 3169 3170 3171 6 3165 3167 3169 2843 2844 9688 6 3168 3167 3170 9687 9686 9688 5 3169 3167 3171 3172 9687 6 3170 3167 3172 3173 3174 3166 6 3170 3171 3173 9691 9687 6653 7 3172 3171 3174 3175 6654 6652 6653 6 3173 3171 3175 3176 3177 3166 5 3173 3174 3176 3450 6654 6 3175 3174 3177 3178 3179 3450 6 3176 3174 3178 3166 3164 3180 6 3176 3177 3179 3180 6660 6661 6 3176 3178 3450 6657 6659 6660 6 3177 3164 3178 3163 2858 6661 6 2869 2870 2884 3182 3190 2868 6 3181 2884 2885 3183 3216 3190 6 3182 2885 2886 3184 3193 3216 6 3183 2886 3185 3186 3192 3193 6 3184 2886 3186 3187 3188 2887 6 3184 3185 3187 3192 3196 7584 6 3186 3185 3188 3958 7586 7584 6 3187 3185 2887 3958 3959 2888 6 2867 2868 3190 2866 3214 3215 6 3189 2868 3181 3215 3216 3182 6 1741 1742 1744 3197 3198 3199 6 3184 3186 3193 3194 3195 3196 6 3184 3192 3194 7222 3216 3183 7 3193 3192 3195 7222 7221 7204 7203 6 3194 3192 3196 7196 7197 7203 6 3195 3192 3186 7583 7196 7584 6 1740 1741 3191 3198 3411 3200 7 3197 3191 3199 2893 2894 2895 3200 5 3198 3191 1744 1745 2893 6 3198 2895 3201 3411 3197 9751 6 3200 2895 2896 3202 3470 9751 6 3201 2896 2897 3203 3470 3471 6 3202 2897 2898 3204 3471 3472 6 3203 2898 3205 3472 3473 3474 6 3204 2898 2899 3206 3474 3475 6 3205 2899 2900 3207 3475 3476 6 3206 2900 2901 3208 3476 3477 6 3207 2901 2902 3209 3477 3478 6 3208 2902 3210 3211 3478 3479 6 3209 2902 3211 3212 3213 2903 6 3209 3210 3212 3479 3480 3481 7 3211 3210 3213 3481 3482 2907 3483 6 3212 3210 2903 3483 2905 2904 6 2866 3189 3215 7220 7219 7221 6 3214 3189 3190 3216 7221 7222 6 3215 3190 3182 7222 3193 3183 6 635 636 3218 4040 3763 3762 6 3217 636 638 3219 3484 4040 6 3218 638 3220 3221 3222 3484 6 3219 638 639 3221 3240 3241 6 3219 3220 3222 3223 3224 3241 6 3219 3221 3223 3484 3485 3486 6 3222 3221 3224 3225 3486 3487 6 3223 3221 3225 3226 3227 3241 6 3223 3224 3226 3493 3487 3494 7 3225 3224 3227 3228 3101 3494 3498 6 3226 3224 3228 3229 3230 3241 5 3226 3227 3101 3100 3229 6 3100 3228 3227 3230 3231 3684 6 3229 3227 3231 3232 3241 3240 6 3229 3230 3232 3233 3234 3684 6 3231 3230 3233 3240 3239 3236 7 3231 3232 3234 11 10 3235 3236 5 3231 3233 11 3684 12 6 10 3233 3236 3237 3238 9 6 3235 3233 3237 643 3239 3232 6 3235 3236 3238 647 644 643 5 3235 3237 9 8 647 6 643 3236 640 639 3240 3232 6 639 3239 3220 3241 3230 3232 6 3220 3240 3221 3224 3227 3230 6 2949 2950 3243 3736 3737 3738 6 3242 2950 2951 3244 3738 3739 6 3243 2951 2952 3245 3739 3740 7 3244 2952 2953 2954 3246 3740 3741 5 3245 2954 3247 3741 3742 6 3246 2954 2955 3248 3742 3743 6 3247 2955 2956 3249 3743 3744 6 3248 2956 2957 3250 3744 3745 6 3249 2957 3251 3745 3746 3747 6 3250 2957 2958 3252 3253 3747 6 3251 2958 3253 3254 2960 2959 6 3251 3252 3254 3747 3748 3749 6 3253 3252 2960 2961 3255 3749 6 3254 2961 2962 2964 3256 3749 6 3255 2964 3257 3749 3750 3751 6 3256 2964 2965 3258 3751 3752 6 3257 2965 3259 3752 3753 3754 6 3258 2965 2966 2967 3260 3754 6 3259 2967 2968 3261 3754 3755 6 3260 2968 2969 3262 3755 3756 6 3261 2969 2970 3263 3756 3757 6 3262 2970 2971 3264 3757 3758 6 3263 2971 2972 3265 3758 3759 7 3264 2972 2973 3266 3759 4054 4051 5 3265 2973 2974 3267 4054 6 3266 2974 2975 2976 3268 4054 7 3267 2976 2977 3269 4054 4053 4055 5 3268 2977 3270 4055 4056 6 3269 2977 2978 3271 4056 4057 6 3270 2978 2979 3272 4057 4058 6 3271 2979 2980 3273 4058 4059 6 3272 2980 2981 3274 4059 4060 6 3273 2981 2982 3275 4060 4061 6 3274 2982 2983 3276 4064 4061 6 3275 2983 2984 3277 4064 4065 6 3276 2984 2985 3826 4065 3824 6 2689 2690 3279 3588 3589 3590 6 3278 2690 2691 3280 3590 3591 6 3279 2691 2692 3281 3591 3592 6 3280 2692 2693 3282 3592 3593 6 3281 2693 2694 3283 3593 3594 6 3282 2694 2695 3284 3594 3595 6 3283 2695 2696 3285 3595 3596 6 3284 2696 2697 3286 3596 3597 6 3285 2697 2698 3287 3597 3598 6 3286 2698 2699 3288 3598 3599 6 3287 2699 2700 3289 3599 3600 6 3288 2700 2701 3290 3600 3601 6 3289 2701 2702 3003 3291 3601 6 3290 3003 3292 3601 3602 3603 6 3291 3003 3004 3293 3603 3604 6 3292 3004 3005 3294 3604 3605 6 3293 3005 3006 3295 3605 3606 6 3294 3006 3007 3296 3606 3607 6 3295 3007 3008 3297 3607 3608 6 3296 3008 3009 3010 3298 3608 6 3297 3010 3299 3608 3609 3610 6 3298 3010 3011 3300 3610 3611 6 3299 3011 3012 3301 3611 3612 6 3300 3012 3013 3302 3612 3613 6 3301 3013 3014 3303 3613 3614 6 3302 3014 3015 3304 3614 3615 6 3303 3015 3016 3305 3615 3616 6 3304 3016 3017 3306 3616 3617 6 3305 3017 3018 3307 3617 3618 6 3306 3018 3019 3308 3618 3619 6 3307 3019 3020 3309 3619 3620 6 3308 3020 3021 3310 3620 3621 6 3309 3021 3022 3311 3621 3622 6 3310 3022 3023 3312 3622 3623 6 3311 3023 3024 3313 3623 3624 6 3312 3024 3025 3314 3624 3625 6 3313 3025 3026 3315 3625 3626 6 3314 3026 3027 3316 3626 3627 6 3315 3027 3028 3317 3627 3628 6 3316 3028 3029 3318 3628 3629 6 3317 3029 3030 3319 3629 3630 6 3318 3030 3031 3320 3630 3631 6 3319 3031 3032 3321 3631 3632 6 3320 3032 3033 3322 3632 3633 6 3321 3033 3034 3042 3323 3633 6 3322 3042 3324 3633 3634 3635 6 3323 3042 3043 3325 3635 3636 6 3324 3043 3044 3045 3326 3636 6 3325 3045 3327 3636 3637 3638 6 3326 3045 3046 3053 3328 3638 6 3327 3053 3054 3329 3638 3639 6 3328 3054 3056 3639 3640 3641 6 2507 2508 32 33 3331 3880 6 3330 33 34 2248 3332 3880 6 3331 2248 3333 3334 3880 3881 6 3332 2248 3334 3335 3336 2249 6 3332 3333 3335 9707 6499 3881 6 3334 3333 3336 9706 6492 9707 6 3335 3333 2249 2250 2251 9706 6 1171 1172 1524 3338 3339 3882 6 3337 1524 3339 3340 3341 4250 6 3337 3338 3340 3882 3127 3883 6 3339 3338 3341 3342 3885 3883 6 3340 3338 3342 3343 2206 4250 6 3340 3341 3343 3861 6717 3885 6 3342 3341 2206 2207 3344 3861 6 3343 2207 2209 3345 3346 3861 6 3344 2209 3346 3347 3348 2211 6 3344 3345 3347 3861 3862 3863 6 3346 3345 3348 6532 3863 6524 6 3347 3345 2211 2213 6523 6524 6 3076 3077 3350 3918 3917 3919 6 3349 3077 3078 3107 3351 3919 6 3350 3107 3352 3919 3920 3921 6 3351 3107 3108 3353 3921 3922 6 3352 3108 3109 3354 3922 3923 6 3353 3109 3110 3355 3923 3924 6 3354 3110 3356 3924 3925 3374 6 3355 3110 3111 3357 3368 3374 6 3356 3111 3112 3358 3367 3368 6 3357 3112 3359 3153 3360 3367 6 3358 3112 3153 3085 3152 3084 6 3358 3153 3154 3361 3363 3367 6 3360 3154 3362 3363 3364 3678 6 3361 3154 3155 3677 3675 3678 6 3360 3361 3364 3365 3366 3367 6 3363 3361 3365 3678 3667 3668 6 3363 3364 3366 3373 3370 3668 6 3363 3365 3367 3368 3369 3370 6 3363 3366 3368 3360 3358 3357 6 3367 3366 3369 3357 3356 3374 6 3368 3366 3370 3371 3374 3375 6 3369 3366 3371 3372 3373 3365 6 3369 3370 3372 3375 3376 3377 6 3371 3370 3373 3377 3378 3379 6 3372 3370 3365 3379 3380 3668 6 3356 3368 3369 3375 3925 3355 7 3374 3369 3371 3376 3943 3925 4342 5 3375 3371 3377 4342 4343 6 3376 3371 3372 3378 4343 4344 6 3377 3372 3379 3645 4347 4344 6 3378 3372 3373 3380 3381 3645 6 3379 3373 3381 3382 3668 3656 6 3379 3380 3382 3383 3384 3645 6 3381 3380 3383 3390 3387 3656 6 3381 3382 3384 3385 3386 3387 6 3381 3383 3385 3645 3646 3647 6 3384 3383 3386 3647 3648 3649 6 3385 3383 3387 3388 3649 3650 6 3386 3383 3388 3389 3390 3382 6 3386 3387 3389 3650 3651 3652 6 3388 3387 3390 3652 3653 3654 6 3389 3387 3382 3654 3655 3656 6 2675 2676 3392 3573 3574 3575 6 3391 2676 2677 3393 3575 3576 6 3392 2677 2678 3394 3576 3577 6 3393 2678 2679 3577 3578 3579 6 2173 2804 2805 3396 3397 4747 6 3395 2805 3397 3398 3399 3400 6 3395 3396 3398 3892 4747 4746 6 3397 3396 3399 3892 3893 3894 6 3398 3396 3400 3894 3895 3896 6 3399 3396 2805 2806 3401 3896 6 3400 2806 2807 3402 3896 3897 6 3401 2807 3403 3897 3898 3899 6 3402 2807 2808 3404 3899 3900 6 3403 2808 1732 3405 3679 3900 6 3404 1732 1733 1734 3406 3679 6 3405 1734 1735 3407 3679 3680 6 3406 1735 1736 3408 3680 3681 6 3407 1736 1737 3409 3683 3681 6 3408 1737 1738 3410 3470 3683 6 3409 1738 1739 3411 9751 3470 6 3410 1739 1740 3197 3200 9751 6 3147 1674 1675 1676 3413 4231 6 3412 1676 1677 3414 9791 4231 6 3413 1677 3415 7778 7776 9791 6 3414 1677 1678 7778 7779 5382 6 1695 1696 3417 3786 1694 3787 6 3416 1696 1697 3418 3787 3789 6 3417 1697 1698 2223 3419 3789 6 3418 2223 3420 3789 3790 3791 6 3419 2223 2224 3421 3791 3792 6 3420 2224 2225 3422 3423 3792 6 3421 2225 3423 3424 3425 3426 6 3421 3422 3424 3794 3792 3795 6 3423 3422 3425 3795 3796 3797 6 3424 3422 3426 3797 3798 3799 6 3425 3422 2225 2226 3427 3799 6 3426 2226 2227 3428 3799 3800 6 3427 2227 2228 3429 3800 3801 6 3428 2228 3430 3801 3802 3432 6 3429 2228 2229 2238 3431 3432 6 3430 2238 3432 3433 3434 3435 6 3430 3431 3433 3442 3802 3429 6 3432 3431 3434 3442 3443 3444 6 3433 3431 3435 3444 3445 3446 6 3434 3431 2238 2239 2561 3446 6 2491 2492 3437 3438 3515 2493 6 2491 3436 3438 3439 3440 3441 6 3437 3436 3439 3513 3514 3515 6 3437 3438 3440 3508 3509 3513 6 3437 3439 3441 3451 3453 3508 6 3437 3440 2491 70 3451 69 6 3432 3433 3443 3802 3803 3804 6 3442 3433 3444 3804 3805 3806 6 3443 3433 3434 3445 3806 3807 6 3444 3434 3446 3807 3808 3447 6 3445 3434 3435 2561 2562 3447 6 3446 2562 3448 3808 3445 4107 6 3447 2562 2563 3449 3454 4107 6 3448 2563 2567 3454 3455 2568 7 3175 3176 3179 6655 6654 6656 6657 6 3441 3440 69 68 3452 3453 6 68 3451 3453 67 3505 3506 6 3452 3451 3440 3506 3507 3508 6 3448 3449 3455 3456 4107 4108 6 3454 3449 3456 3457 3458 2568 6 3454 3455 3457 3464 4110 4108 6 3456 3455 3458 3459 3460 3464 6 3457 3455 3459 3463 2569 2568 6 3457 3458 3460 3461 3462 3463 6 3457 3459 3461 3464 3465 3466 6 3460 3459 3462 3466 3467 3469 6 3461 3459 3463 1721 3469 1720 6 3462 3459 3458 2569 1720 1719 6 3456 3457 3460 3465 4394 4110 6 3464 3460 3466 4404 4394 4745 6 3465 3460 3461 3467 3468 4745 6 3466 3461 3468 2172 1724 3469 6 3466 3467 2172 4745 4746 4747 6 1724 3467 1722 1721 3462 3461 7 3201 3202 3471 9751 3410 3409 3683 6 3470 3202 3203 3472 3681 3683 6 3471 3203 3204 3473 3682 3681 6 3472 3204 3474 3685 3902 3682 6 3473 3204 3205 3475 3685 3686 6 3474 3205 3206 3476 3686 3687 6 3475 3206 3207 3477 3687 3688 6 3476 3207 3208 3478 3688 3689 6 3477 3208 3209 3479 3689 3690 6 3478 3209 3211 3480 3690 3691 6 3479 3211 3481 3499 3694 3691 6 3480 3211 3212 3482 3499 3500 5 3481 3212 2907 3500 2908 5 2907 3212 3213 2905 2906 6 3218 3219 3222 3485 4039 4040 6 3484 3222 3486 3489 3968 4039 6 3485 3222 3223 3487 3488 3489 6 3486 3223 3488 3492 3493 3225 6 3486 3487 3489 3490 3491 3492 6 3486 3488 3490 3485 3968 3969 6 3489 3488 3491 3969 3970 3971 6 3490 3488 3492 3971 9747 6555 6 3491 3488 3487 3493 3496 9747 6 3492 3487 3225 3494 3495 3496 6 3493 3225 3226 3495 3497 3498 6 3493 3494 3496 3497 3501 3115 6 3493 3495 3492 3501 3502 9747 6 3495 3494 3498 3102 3113 3115 5 3497 3494 3226 3101 3102 6 3480 3481 3500 3694 3695 3696 6 3499 3481 3482 2908 3696 3697 6 3496 3495 3502 3503 3504 3115 6 3496 3501 3503 9747 6706 9748 6 3502 3501 3504 6712 6710 9748 5 3503 3501 3115 6712 3116 6 67 3452 3506 6697 6703 66 6 3505 3452 3453 3507 6697 6704 6 3506 3453 3508 3510 4522 6704 6 3507 3453 3440 3439 3509 3510 6 3508 3439 3510 3511 3512 3513 6 3508 3509 3511 3770 3507 4522 6 3510 3509 3512 3770 3771 3772 6 3511 3509 3513 3772 3773 3520 6 3512 3509 3439 3438 3514 3520 6 3513 3438 3515 3520 3521 3517 6 3514 3438 3436 2493 3516 3517 6 3515 2493 3517 3518 1607 1606 6 3515 3516 3518 3521 3514 3522 6 3517 3516 1607 1613 3522 3523 5 1613 1607 1605 1608 1610 6 3513 3514 3521 3773 3512 4531 6 3520 3514 3517 3522 4116 4531 6 3521 3517 3518 3523 3525 4116 6 3522 3518 1613 1614 3524 3525 6 3523 1614 3525 3526 3527 3528 6 3523 3524 3526 3522 4116 4117 6 3525 3524 3527 3529 4117 4118 6 3526 3524 3528 3529 3530 3543 6 3527 3524 1614 3543 3544 1615 6 3526 3527 3530 3531 4118 9786 6 3529 3527 3531 3532 3542 3543 6 3529 3530 3532 3533 9786 9787 6 3531 3530 3533 3534 3541 3542 6 3531 3532 3534 3535 9787 9788 6 3533 3532 3535 3536 3540 3541 6 3533 3534 3536 3537 9788 7178 6 3535 3534 3537 3538 3539 3540 6 3535 3536 3538 7182 7179 7178 6 3537 3536 3539 7182 7183 7184 6 3538 3536 3540 7184 7185 7212 6 3539 3536 3534 3541 7212 4372 6 3540 3534 3532 3542 4372 4097 6 3541 3532 3530 3543 4096 4097 6 3542 3530 3527 3528 3544 4096 6 3543 3528 1615 4099 4096 3093 6 2986 2987 3546 3824 3825 3829 6 3545 2987 2988 3547 3829 3830 6 3546 2988 2989 3548 3830 3831 6 3547 2989 2990 3549 3831 3832 6 3548 2990 2991 3550 3832 3833 6 3549 2991 2992 3551 3809 3833 6 3550 2992 2993 3552 3809 3810 6 3551 2993 2994 3553 3810 3811 6 3552 2994 2995 3554 3811 3812 6 3553 2995 2996 3555 3812 3813 6 3554 2996 3556 3813 3814 3815 6 3555 2996 2997 3557 3815 3816 6 3556 2997 2998 2999 3558 3816 6 3557 2999 3000 3559 3816 3817 6 3558 3000 3001 3560 3817 3818 6 3559 3001 3002 3561 3562 3818 6 3560 3002 3562 3563 3564 3565 6 3560 3561 3563 3818 3819 3820 6 3562 3561 3564 3820 3821 3822 6 3563 3561 3565 3822 3823 3566 6 3564 3561 3002 2666 2667 3566 6 3565 2667 2668 3567 3823 3564 6 3566 2668 2669 3568 3850 3823 6 3567 2669 2670 3569 3879 3850 6 3568 2670 2671 3570 3891 3879 6 3569 2671 2672 2673 3571 3891 6 3570 2673 3572 4237 3891 4257 6 3571 2673 2674 3573 4257 4258 6 3572 2674 2675 3391 3574 4258 6 3573 3391 3575 4258 4259 4263 6 3574 3391 3392 3576 4263 4264 6 3575 3392 3393 3577 4264 4265 6 3576 3393 3394 3578 4265 4266 6 3577 3394 3579 4266 4267 4268 6 3578 3394 2679 2680 3580 4268 6 3579 2680 2681 3581 4141 4268 6 3580 2681 2682 3582 4141 4142 6 3581 2682 2683 3583 4142 4143 6 3582 2683 2684 3584 4143 4144 6 3583 2684 2685 3585 4144 4145 6 3584 2685 2686 3586 4145 4146 6 3585 2686 2687 3587 4146 4147 6 3586 2687 2688 3588 4147 4148 6 3587 2688 2689 3278 3589 4148 6 3588 3278 3590 4148 4149 4150 6 3589 3278 3279 3591 4150 4151 6 3590 3279 3280 3592 4151 4152 6 3591 3280 3281 3593 4152 4153 6 3592 3281 3282 3594 4153 4154 6 3593 3282 3283 3595 4154 4155 6 3594 3283 3284 3596 4155 4156 6 3595 3284 3285 3597 4156 4157 6 3596 3285 3286 3598 4157 4158 6 3597 3286 3287 3599 4158 4159 6 3598 3287 3288 3600 4159 4160 6 3599 3288 3289 3601 4160 4161 6 3600 3289 3290 3291 3602 4161 6 3601 3291 3603 4161 4162 4163 6 3602 3291 3292 3604 4163 4164 6 3603 3292 3293 3605 4164 4165 6 3604 3293 3294 3606 4165 4166 6 3605 3294 3295 3607 4166 4167 6 3606 3295 3296 3608 4167 4168 6 3607 3296 3297 3298 3609 4168 6 3608 3298 3610 4168 4169 4170 6 3609 3298 3299 3611 4170 4171 6 3610 3299 3300 3612 4171 4172 6 3611 3300 3301 3613 4172 4173 6 3612 3301 3302 3614 4173 4174 6 3613 3302 3303 3615 4174 4175 6 3614 3303 3304 3616 4175 4176 6 3615 3304 3305 3617 4176 4177 6 3616 3305 3306 3618 4177 4178 6 3617 3306 3307 3619 4178 4179 6 3618 3307 3308 3620 4179 4180 6 3619 3308 3309 3621 4180 4181 6 3620 3309 3310 3622 4181 4182 6 3621 3310 3311 3623 4182 4183 6 3622 3311 3312 3624 4183 4184 6 3623 3312 3313 3625 4184 4185 6 3624 3313 3314 3626 4185 4186 6 3625 3314 3315 3627 4186 4187 6 3626 3315 3316 3628 4187 4188 6 3627 3316 3317 3629 4188 4189 6 3628 3317 3318 3630 4189 4190 6 3629 3318 3319 3631 4190 4191 6 3630 3319 3320 3632 4191 4192 6 3631 3320 3321 3633 4192 4193 6 3632 3321 3322 3323 3634 4193 6 3633 3323 3635 3903 4193 4194 6 3634 3323 3324 3636 3903 3904 6 3635 3324 3325 3326 3637 3904 6 3636 3326 3638 3904 3905 3906 6 3637 3326 3327 3328 3639 3906 6 3638 3328 3329 3640 3906 3907 6 3639 3329 3641 3907 3908 3642 5 3640 3329 3056 3057 3642 7 3641 3057 3058 3643 3908 3640 3927 6 3642 3058 3059 3644 3909 3927 5 3643 3059 3061 3909 3910 6 3381 3384 3646 3379 3378 4347 6 3645 3384 3647 4347 4348 4349 6 3646 3384 3385 3648 4352 4349 6 3647 3385 3649 3657 4352 4353 6 3648 3385 3386 3650 3657 3658 6 3649 3386 3388 3651 3658 3659 6 3650 3388 3652 3659 3660 3661 6 3651 3388 3389 3653 3661 3662 6 3652 3389 3654 3662 3663 3664 6 3653 3389 3390 3655 3664 3665 6 3654 3390 3656 3665 3666 3667 6 3655 3390 3382 3667 3668 3380 6 3648 3649 3658 4353 4354 4358 6 3657 3649 3650 3659 4371 4358 6 3658 3650 3651 3660 9793 4371 6 3659 3651 3661 4906 4908 9793 6 3660 3651 3652 3662 3669 4906 6 3661 3652 3653 3663 3669 3670 6 3662 3653 3664 3670 3671 3672 6 3663 3653 3654 3665 3672 3673 6 3664 3654 3655 3666 3673 3674 6 3665 3655 3667 3674 3675 3678 6 3666 3655 3656 3668 3364 3678 6 3667 3656 3380 3364 3365 3373 6 3661 3662 3670 4903 4905 4906 6 3669 3662 3663 3671 4902 4903 6 3670 3663 3672 5918 4902 3951 6 3671 3663 3664 3673 3950 3951 6 3672 3664 3665 3674 3944 3950 6 3673 3665 3666 3675 3676 3944 6 3674 3666 3676 3677 3362 3678 6 3674 3675 3677 3158 3944 3945 6 3676 3675 3158 3156 3155 3362 6 3362 3675 3361 3364 3667 3666 6 3404 3405 3406 3680 3900 3901 6 3679 3406 3407 3681 3682 3901 7 3680 3407 3682 3472 3471 3683 3408 6 3680 3681 3472 3901 3902 3473 5 3471 3681 3408 3409 3470 7 418 3100 3229 3231 3234 12 13 7 3473 3474 3686 3902 4665 4664 4688 5 3685 3474 3475 3687 4688 7 3686 3475 3476 3688 4688 4689 4690 6 3687 3476 3477 3689 4690 4691 6 3688 3477 3478 3690 4691 4692 6 3689 3478 3479 3691 3692 4692 6 3690 3479 3692 3693 3694 3480 6 3690 3691 3693 4692 4693 4694 6 3692 3691 3694 4694 4695 4696 6 3693 3691 3480 3499 3695 4696 6 3694 3499 3696 4696 4697 4698 6 3695 3499 3500 3697 4698 4699 6 3696 3500 2908 2909 3698 4699 6 3697 2909 2910 3699 3972 4699 6 3698 2910 2911 3700 3972 3973 6 3699 2911 2912 2913 3701 3973 6 3700 2913 3702 3973 3974 3975 6 3701 2913 2914 3703 3975 3976 6 3702 2914 2915 3704 3976 3977 6 3703 2915 2916 3705 3977 3978 6 3704 2916 2917 3706 3978 3979 6 3705 2917 2918 3707 3979 3980 6 3706 2918 2919 3708 3980 3981 6 3707 2919 2920 3709 3981 3982 6 3708 2920 2921 3710 3982 3983 6 3709 2921 2922 3711 3983 3984 6 3710 2922 2923 3712 3984 3985 6 3711 2923 2924 3713 3985 3986 6 3712 2924 2925 3714 3986 3987 6 3713 2925 2926 3715 3987 3988 6 3714 2926 2927 3716 3988 3989 6 3715 2927 2928 3717 3989 3990 6 3716 2928 2929 3718 3990 3991 6 3717 2929 2930 3719 3991 3992 6 3718 2930 2931 3720 3992 3993 6 3719 2931 2932 3721 3993 3994 6 3720 2932 2933 3722 3994 3995 6 3721 2933 2934 3723 3995 3996 6 3722 2934 2935 3724 3996 3997 6 3723 2935 2936 3725 3997 3998 6 3724 2936 2937 3726 3998 3999 6 3725 2937 2938 3727 3999 4000 6 3726 2938 2939 3728 4000 4001 6 3727 2939 2940 3729 4001 4002 6 3728 2940 2941 3730 4002 4003 6 3729 2941 2942 3731 4003 4004 6 3730 2942 2943 3732 4004 4005 6 3731 2943 2944 2945 3733 4005 6 3732 2945 2946 3734 4005 4006 6 3733 2946 2947 2948 3735 4006 6 3734 2948 3736 4006 4007 3737 5 3735 2948 2949 3242 3737 6 3736 3242 3738 4007 3735 4012 6 3737 3242 3243 3739 4012 4013 6 3738 3243 3244 3740 4013 4014 6 3739 3244 3245 3741 4014 4015 6 3740 3245 3246 3742 4015 4016 6 3741 3246 3247 3743 4016 4017 6 3742 3247 3248 3744 4017 4018 6 3743 3248 3249 3745 4018 4019 6 3744 3249 3250 3746 4019 4020 6 3745 3250 3747 4020 4021 4022 6 3746 3250 3251 3253 3748 4022 6 3747 3253 3749 4022 4023 4024 7 3748 3253 3254 3255 3256 3750 4024 5 3749 3256 3751 4024 4025 6 3750 3256 3257 3752 4025 4026 6 3751 3257 3258 3753 4029 4026 7 3752 3258 3754 4037 4029 4046 3755 5 3753 3258 3259 3260 3755 6 3754 3260 3261 3756 4046 3753 6 3755 3261 3262 3757 4046 4047 6 3756 3262 3263 3758 4047 4048 6 3757 3263 3264 3759 4048 4049 6 3758 3264 3265 4049 4050 4051 6 615 617 3761 3764 3765 3763 6 3760 617 625 627 3762 3763 6 3761 627 3763 3217 635 629 6 3761 3762 3765 3760 4040 3217 6 615 3760 3765 4038 6557 612 6 3764 3760 3763 4038 4039 4040 5 2085 1567 3767 3768 6093 6 3766 1567 3768 3769 1571 1568 6 3766 3767 3769 6092 6093 6094 7 3768 3767 1571 6094 6088 6317 6318 6 3510 3511 3771 4522 4523 4524 6 3770 3511 3772 4524 4525 4528 6 3771 3511 3512 3773 4528 4529 6 3772 3512 3520 4529 4530 4531 6 1682 1683 3775 5391 5385 5383 6 3774 1683 3776 5620 5391 3778 6 3775 1683 1684 1686 3777 3778 6 3776 1686 3778 3779 3780 3781 6 3776 3777 3779 7791 5620 3775 6 3778 3777 3780 7798 7792 7791 6 3779 3777 3781 7798 3783 3782 6 3780 3777 1686 1687 1688 3782 6 3781 1688 1689 1691 3783 3780 6 3782 1691 3784 7798 3780 7799 6 3783 1691 1692 3785 7799 7800 6 3784 1692 3786 3787 3788 7800 6 3785 1692 1693 1694 3416 3787 6 3786 3416 3417 3785 3788 3789 6 3785 3787 3789 7800 7801 3790 6 3788 3787 3417 3418 3419 3790 6 3789 3419 3791 7801 3788 7802 6 3790 3419 3420 3792 3793 7802 6 3791 3420 3793 3794 3423 3421 6 3791 3792 3794 7802 7803 7804 6 3793 3792 3423 3795 7804 7805 6 3794 3423 3424 3796 7809 7805 6 3795 3424 3797 3952 7809 7810 6 3796 3424 3425 3798 3952 3953 6 3797 3425 3799 3953 3954 3955 6 3798 3425 3426 3427 3800 3955 6 3799 3427 3428 3801 3955 3956 6 3800 3428 3429 3802 3956 3957 6 3801 3429 3432 3442 3803 3957 6 3802 3442 3804 3957 4100 4239 6 3803 3442 3443 3805 4100 4101 6 3804 3443 3806 4101 4102 4103 6 3805 3443 3444 3807 4103 4104 6 3806 3444 3445 3808 4104 4105 6 3807 3445 3447 4105 4106 4107 6 3550 3551 3810 3833 3834 3835 6 3809 3551 3552 3811 3835 3836 6 3810 3552 3553 3812 3836 3837 6 3811 3553 3554 3813 3837 3838 6 3812 3554 3555 3814 3838 3839 6 3813 3555 3815 3839 3840 3841 6 3814 3555 3556 3816 3841 3842 6 3815 3556 3557 3558 3817 3842 6 3816 3558 3559 3818 3842 3843 6 3817 3559 3560 3562 3819 3843 6 3818 3562 3820 3843 3844 3845 6 3819 3562 3563 3821 3845 3846 6 3820 3563 3822 3846 3847 3848 6 3821 3563 3564 3823 3848 3849 6 3822 3564 3566 3849 3850 3567 6 2986 3545 3825 3826 3277 2985 6 3824 3545 3826 3827 3828 3829 6 3824 3825 3827 4069 4065 3277 6 3826 3825 3828 4756 4069 4763 6 3827 3825 3829 4763 4764 4765 6 3828 3825 3545 3546 3830 4765 6 3829 3546 3547 3831 4765 4766 6 3830 3547 3548 3832 4766 4767 6 3831 3548 3549 3833 4770 4767 6 3832 3549 3550 3809 3834 4770 6 3833 3809 3835 5016 4770 5024 6 3834 3809 3810 3836 5024 5025 6 3835 3810 3811 3837 5025 5026 6 3836 3811 3812 3838 4405 5026 6 3837 3812 3813 3839 3864 4405 6 3838 3813 3814 3840 3864 3865 6 3839 3814 3841 3865 3866 3867 6 3840 3814 3815 3842 3853 3867 6 3841 3815 3816 3817 3843 3853 6 3842 3817 3818 3819 3844 3853 6 3843 3819 3845 3853 3854 3855 6 3844 3819 3820 3846 3855 3856 6 3845 3820 3821 3847 3856 3857 6 3846 3821 3848 3860 3857 3876 6 3847 3821 3822 3849 3876 3877 6 3848 3822 3823 3850 3877 3878 6 3849 3823 3567 3878 3879 3568 6 2181 2199 2179 3852 2201 3129 6 2179 3851 27 26 3129 9781 6 3841 3842 3843 3844 3854 3867 6 3853 3844 3855 3867 3868 3869 6 3854 3844 3845 3856 3869 3870 6 3855 3845 3846 3857 3858 3870 6 3856 3846 3858 3859 3860 3847 6 3856 3857 3859 3870 3871 3872 6 3858 3857 3860 3872 3873 3874 6 3859 3857 3847 3874 3875 3876 6 3343 3344 3346 3862 6717 3342 6 3861 3346 3863 6716 6715 6717 7 3862 3346 6532 6531 3347 6533 6716 6 3838 3839 3865 4405 4406 4407 6 3864 3839 3840 3866 4407 4408 6 3865 3840 3867 4408 4409 3868 6 3866 3840 3841 3853 3854 3868 6 3867 3854 3869 4409 3866 4420 6 3868 3854 3855 3870 4420 4421 6 3869 3855 3856 3858 3871 4421 6 3870 3858 3872 4421 4422 4423 6 3871 3858 3859 3873 4423 4424 6 3872 3859 3874 4424 4425 4426 6 3873 3859 3860 3875 4426 4427 6 3874 3860 3876 4427 4428 3888 6 3875 3860 3847 3848 3877 3888 6 3876 3848 3849 3878 3888 3889 6 3877 3849 3850 3879 3889 3890 6 3878 3850 3568 3890 3891 3569 6 2507 3330 2509 3881 3331 3332 6 2509 3880 3334 6499 2511 3332 6 3337 3339 3127 1171 414 3128 6 3127 3339 3122 3884 3885 3340 6 3122 3883 3885 3886 3887 3121 6 3884 3883 3886 3342 6717 3340 6 3884 3885 3887 6538 6715 6717 6 3884 3886 3121 6713 6714 6538 6 3876 3877 3889 4428 3875 4251 6 3888 3877 3878 3890 4236 4251 6 3889 3878 3879 3891 4236 4237 6 3890 3879 3569 4237 3571 3570 6 3397 3398 3893 4746 4744 4743 6 3892 3398 3894 4743 4748 4749 6 3893 3398 3399 3895 4752 4749 6 3894 3399 3896 4661 4758 4752 6 3895 3399 3400 3401 3897 4661 6 3896 3401 3402 3898 4661 4662 6 3897 3402 3899 4662 4663 4664 6 3898 3402 3403 3900 4664 4665 6 3899 3403 3404 3679 3901 4665 6 3900 3679 3680 3682 3902 4665 5 3901 3682 3473 4665 3685 6 3634 3635 3904 4194 4195 4196 6 3903 3635 3636 3637 3905 4196 6 3904 3637 3906 4196 4197 4198 6 3905 3637 3638 3639 3907 4198 6 3906 3639 3640 3908 4198 4199 6 3907 3640 3642 3927 4199 4200 5 3643 3644 3910 3927 3928 7 3909 3644 3061 3062 3911 3928 3929 7 3910 3062 3063 3912 3929 3930 3931 6 3911 3063 3069 3913 3931 3932 6 3912 3069 3070 3914 3932 3933 6 3913 3070 3071 3915 3933 3934 6 3914 3071 3072 3916 3934 3935 6 3915 3072 3073 3917 3935 3936 6 3916 3073 3918 3349 3919 3936 6 3917 3073 3074 3075 3076 3349 6 3917 3349 3350 3351 3920 3936 6 3919 3351 3921 3936 3937 3938 6 3920 3351 3352 3922 3938 3939 6 3921 3352 3353 3923 3939 3940 6 3922 3353 3354 3924 3940 3941 6 3923 3354 3355 3925 3941 3942 6 3924 3355 3374 3942 3943 3375 6 3085 2482 2483 2484 3150 3152 6 3908 3642 3643 3909 3928 4200 6 3927 3909 3910 3929 4200 4201 6 3928 3910 3911 3930 4201 4202 6 3929 3911 3931 4202 4203 4204 5 3930 3911 3912 3932 4204 6 3931 3912 3913 3933 4204 4205 6 3932 3913 3914 3934 4205 4206 6 3933 3914 3915 3935 4206 4207 6 3934 3915 3916 3936 4207 3937 6 3935 3916 3917 3919 3920 3937 6 3936 3920 3938 4207 3935 4335 6 3937 3920 3921 3939 4335 4336 6 3938 3921 3922 3940 4336 4337 6 3939 3922 3923 3941 4337 4338 6 3940 3923 3924 3942 4338 4339 6 3941 3924 3925 3943 4339 4340 6 3942 3925 3375 4340 4341 4342 6 3673 3674 3676 3945 3950 3947 6 3944 3676 3158 3159 3946 3947 6 3945 3159 3947 3948 5922 3962 6 3945 3946 3948 3949 3950 3944 6 3947 3946 3949 5920 5921 5922 6 3947 3948 3950 3951 5919 5920 6 3947 3949 3951 3672 3673 3944 6 3950 3949 3672 5918 3671 5919 6 3796 3797 3953 7810 7811 7812 6 3952 3797 3798 3954 7812 7813 6 3953 3798 3955 7813 7814 7815 6 3954 3798 3799 3800 3956 7815 6 3955 3800 3801 3957 4238 7815 6 3956 3801 3802 3803 4238 4239 6 3187 3188 3959 3960 7588 7586 6 3958 3188 3960 3961 2890 2888 6 3958 3959 3961 7588 7589 7590 6 3960 3959 2890 7590 7591 7592 6 3159 3160 3963 5922 3946 5923 6 3962 3160 3964 3965 5923 5924 6 3963 3160 3965 3966 3967 3161 6 3963 3964 3966 5924 5942 5943 6 3965 3964 3967 5943 5948 5947 6 3966 3964 3161 5948 2488 2487 6 3485 3489 3969 6556 4038 4039 6 3968 3489 3490 3970 1597 6556 6 3969 3490 3971 6358 1595 1597 6 3970 3490 3491 6555 6357 6358 6 3698 3699 3973 4699 4700 4701 6 3972 3699 3700 3701 3974 4701 6 3973 3701 3975 4701 4702 4703 6 3974 3701 3702 3976 4703 4704 6 3975 3702 3703 3977 4704 4705 6 3976 3703 3704 3978 4705 4706 6 3977 3704 3705 3979 4706 4707 6 3978 3705 3706 3980 4707 4708 6 3979 3706 3707 3981 4708 4709 6 3980 3707 3708 3982 4709 4710 6 3981 3708 3709 3983 4710 4711 6 3982 3709 3710 3984 4711 4712 6 3983 3710 3711 3985 4712 4713 6 3984 3711 3712 3986 4713 4714 6 3985 3712 3713 3987 4714 4715 6 3986 3713 3714 3988 4715 4716 6 3987 3714 3715 3989 4716 4717 6 3988 3715 3716 3990 4717 4718 6 3989 3716 3717 3991 4718 4719 6 3990 3717 3718 3992 4719 4720 6 3991 3718 3719 3993 4720 4721 6 3992 3719 3720 3994 4439 4721 6 3993 3720 3721 3995 4439 4440 6 3994 3721 3722 3996 4440 4441 6 3995 3722 3723 3997 4441 4442 6 3996 3723 3724 3998 4442 4443 6 3997 3724 3725 3999 4443 4444 6 3998 3725 3726 4000 4444 4445 6 3999 3726 3727 4001 4445 4446 6 4000 3727 3728 4002 4070 4446 6 4001 3728 3729 4003 4008 4070 6 4002 3729 3730 4004 4008 4009 6 4003 3730 3731 4005 4009 4010 6 4004 3731 3732 3733 4006 4010 6 4005 3733 3734 3735 4007 4010 6 4006 3735 3737 4010 4011 4012 6 4002 4003 4009 4070 4071 4072 6 4008 4003 4004 4010 4072 4011 6 4009 4004 4005 4006 4007 4011 6 4010 4007 4012 4072 4009 4073 6 4011 4007 3737 3738 4013 4073 6 4012 3738 3739 4014 4073 4074 7 4013 3739 3740 4015 4074 4075 4076 6 4014 3740 3741 4016 4076 4077 6 4015 3741 3742 4017 4077 4078 6 4016 3742 3743 4018 4078 4079 6 4017 3743 3744 4019 4079 4080 6 4018 3744 3745 4020 4080 4081 6 4019 3745 3746 4021 4081 4082 6 4020 3746 4022 4030 4082 4083 6 4021 3746 3747 3748 4023 4030 6 4022 3748 4024 4030 4031 4032 6 4023 3748 3749 3750 4025 4032 6 4024 3750 3751 4026 4027 4032 6 4025 3751 4027 4028 4029 3752 6 4025 4026 4028 4032 4033 4034 6 4027 4026 4029 4034 4035 4036 6 4028 4026 3752 4036 4037 3753 6 4021 4022 4023 4031 4083 4084 6 4030 4023 4032 4084 4085 4033 6 4031 4023 4024 4025 4027 4033 6 4032 4027 4034 4085 4031 4462 6 4033 4027 4028 4035 4041 4462 6 4034 4028 4036 4041 4042 4043 6 4035 4028 4029 4037 4043 4044 6 4036 4029 3753 4044 4045 4046 6 3764 3765 4039 6556 6557 3968 6 4038 3765 4040 3968 3485 3484 6 4039 3765 3763 3217 3484 3218 6 4034 4035 4042 4462 4463 4464 6 4041 4035 4043 4464 4465 4466 6 4042 4035 4036 4044 4466 4467 6 4043 4036 4037 4045 4467 4468 6 4044 4037 4046 4468 4469 4047 6 4045 4037 3753 3755 3756 4047 6 4046 3756 3757 4048 4469 4045 6 4047 3757 3758 4049 4469 4470 6 4048 3758 3759 4050 4470 4209 6 4049 3759 4051 4052 4208 4209 6 4050 3759 4052 4053 4054 3265 6 4050 4051 4053 4208 4221 4222 6 4052 4051 4054 3268 4055 4222 6 4053 4051 3265 3266 3267 3268 5 4053 3268 3269 4056 4222 7 4055 3269 3270 4057 4222 4223 4224 7 4056 3270 3271 4058 4224 4225 4226 6 4057 3271 3272 4059 4226 4227 6 4058 3272 3273 4060 4227 4228 6 4059 3273 3274 4061 4062 4228 6 4060 3274 4062 4063 4064 3275 6 4060 4061 4063 4230 4228 4502 6 4062 4061 4064 4066 4067 4502 6 4063 4061 3275 3276 4065 4066 6 4064 3276 4066 4069 3826 3277 6 4064 4065 4063 4067 4068 4069 6 4063 4066 4068 4513 4502 4754 6 4067 4066 4069 4754 4755 4756 6 4068 4066 4065 3826 4756 3827 6 4001 4002 4008 4071 4446 4447 6 4070 4008 4072 4447 4448 4449 6 4071 4008 4009 4011 4073 4449 6 4072 4011 4012 4013 4074 4449 6 4073 4013 4014 4075 4449 4450 6 4074 4014 4076 4450 4451 4452 5 4075 4014 4015 4077 4452 6 4076 4015 4016 4078 4452 4453 6 4077 4016 4017 4079 4453 4454 6 4078 4017 4018 4080 4454 4455 6 4079 4018 4019 4081 4455 4456 6 4080 4019 4020 4082 4456 4457 6 4081 4020 4021 4083 4457 4458 6 4082 4021 4030 4084 4458 4459 6 4083 4030 4031 4085 4459 4460 6 4084 4031 4033 4460 4461 4462 6 2880 2881 4087 4089 7599 7600 6 4086 2881 2882 2883 4088 4089 6 4087 2883 4089 4090 4091 4092 7 4087 4088 4090 7598 7599 4086 7751 6 4089 4088 4091 7751 7753 4379 6 4090 4088 4092 4094 4378 4379 6 4091 4088 2883 2498 4093 4094 6 4092 2498 4094 4095 2809 2499 6 4092 4093 4095 4091 4378 4387 6 4094 4093 2809 4387 4386 4388 6 3542 3543 4097 4098 4099 3544 6 3542 4096 4098 4365 4372 3541 6 4097 4096 4099 4365 4366 4367 6 4098 4096 3544 4367 3094 3093 6 3803 3804 4101 4239 4240 4241 6 4100 3804 3805 4102 4241 4242 6 4101 3805 4103 4242 4243 4244 6 4102 3805 3806 4104 4111 4244 6 4103 3806 3807 4105 4111 4112 6 4104 3807 3808 4106 4112 4113 6 4105 3808 4107 4108 4109 4113 6 4106 3808 3447 3448 3454 4108 6 4107 3454 4106 4109 4110 3456 6 4106 4108 4110 4113 4114 4115 6 4109 4108 3456 4115 4394 3464 6 4103 4104 4112 4244 4245 4246 6 4111 4104 4105 4113 4249 4246 6 4112 4105 4106 4109 4114 4249 6 4113 4109 4115 4249 4391 4392 6 4114 4109 4110 4392 4393 4394 7 3522 3525 4117 4530 4531 3521 4119 5 4116 3525 3526 4118 4119 6 4117 3526 4119 4120 3529 9786 7 4117 4118 4120 4121 9784 4530 4116 6 4119 4118 4121 4122 9786 9789 6 4119 4120 4122 4123 4395 9784 6 4121 4120 4123 4124 9789 7172 6 4121 4122 4124 4125 4126 4395 6 4123 4122 4125 7171 4140 7172 6 4123 4124 4126 4127 4128 4140 6 4123 4125 4127 4395 4396 4397 6 4126 4125 4128 4129 4130 4397 6 4127 4125 4129 4136 4139 4140 6 4127 4128 4130 4131 4135 4136 6 4127 4129 4131 4132 4397 4398 6 4130 4129 4132 4133 4134 4135 6 4130 4131 4133 4401 4398 4410 6 4132 4131 4134 4410 4411 4412 6 4133 4131 4135 4412 4413 7164 6 4134 4131 4129 4136 4137 7164 6 4135 4129 4128 4137 4138 4139 6 4135 4136 4138 7163 7161 7164 6 4137 4136 4139 7168 7163 7169 6 4138 4136 4128 4140 7169 7170 6 4139 4128 4125 7170 7171 4124 6 3580 3581 4142 4268 4269 4270 6 4141 3581 3582 4143 4270 4271 6 4142 3582 3583 4144 4271 4272 6 4143 3583 3584 4145 4272 4273 6 4144 3584 3585 4146 4273 4274 6 4145 3585 3586 4147 4274 4275 6 4146 3586 3587 4148 4275 4276 6 4147 3587 3588 3589 4149 4276 6 4148 3589 4150 4276 4277 4278 6 4149 3589 3590 4151 4278 4279 6 4150 3590 3591 4152 4279 4280 6 4151 3591 3592 4153 4280 4281 6 4152 3592 3593 4154 4281 4282 6 4153 3593 3594 4155 4282 4283 6 4154 3594 3595 4156 4283 4284 6 4155 3595 3596 4157 4284 4285 6 4156 3596 3597 4158 4285 4286 6 4157 3597 3598 4159 4286 4287 6 4158 3598 3599 4160 4287 4288 6 4159 3599 3600 4161 4288 4289 6 4160 3600 3601 3602 4162 4289 6 4161 3602 4163 4289 4290 4291 6 4162 3602 3603 4164 4291 4292 6 4163 3603 3604 4165 4292 4293 6 4164 3604 3605 4166 4293 4294 6 4165 3605 3606 4167 4294 4295 6 4166 3606 3607 4168 4295 4296 6 4167 3607 3608 3609 4169 4296 6 4168 3609 4170 4296 4297 4298 6 4169 3609 3610 4171 4298 4299 6 4170 3610 3611 4172 4299 4300 6 4171 3611 3612 4173 4300 4301 6 4172 3612 3613 4174 4301 4302 6 4173 3613 3614 4175 4302 4303 6 4174 3614 3615 4176 4303 4304 6 4175 3615 3616 4177 4304 4305 6 4176 3616 3617 4178 4305 4306 6 4177 3617 3618 4179 4306 4307 6 4178 3618 3619 4180 4307 4308 6 4179 3619 3620 4181 4308 4309 6 4180 3620 3621 4182 4309 4310 6 4181 3621 3622 4183 4310 4311 6 4182 3622 3623 4184 4311 4312 6 4183 3623 3624 4185 4312 4313 6 4184 3624 3625 4186 4313 4314 6 4185 3625 3626 4187 4314 4315 6 4186 3626 3627 4188 4315 4316 6 4187 3627 3628 4189 4316 4317 6 4188 3628 3629 4190 4317 4318 6 4189 3629 3630 4191 4318 4319 6 4190 3630 3631 4192 4319 4320 6 4191 3631 3632 4193 4320 4321 6 4192 3632 3633 3634 4194 4321 6 4193 3634 3903 4195 4321 4322 6 4194 3903 4196 4322 4323 4324 6 4195 3903 3904 3905 4197 4324 6 4196 3905 4198 4324 4325 4326 6 4197 3905 3906 3907 4199 4326 6 4198 3907 3908 4200 4326 4327 6 4199 3908 3927 3928 4201 4327 6 4200 3928 3929 4202 4327 4328 6 4201 3929 3930 4203 4328 4329 6 4202 3930 4204 4329 4330 4331 6 4203 3930 3931 3932 4205 4331 6 4204 3932 3933 4206 4331 4332 6 4205 3933 3934 4207 4332 4333 7 4206 3934 3935 3937 4333 4334 4335 6 4050 4052 4209 4210 4211 4221 6 4050 4208 4210 4470 4049 4477 6 4209 4208 4211 4212 4477 4478 6 4210 4208 4212 4213 4220 4221 6 4210 4211 4213 4214 4478 4479 6 4212 4211 4214 4215 4216 4220 6 4212 4213 4215 4479 4480 4481 6 4214 4213 4216 4217 4481 4482 6 4215 4213 4217 4218 4219 4220 6 4215 4216 4218 4232 4482 4483 6 4217 4216 4219 4232 4233 4234 6 4218 4216 4220 4224 4234 4223 6 4219 4216 4213 4211 4221 4223 6 4220 4211 4208 4052 4222 4223 6 4221 4052 4053 4055 4056 4223 6 4222 4056 4224 4221 4220 4219 6 4223 4056 4057 4225 4234 4219 6 4224 4057 4226 4235 4234 4488 5 4225 4057 4058 4227 4488 7 4226 4058 4059 4228 4229 4487 4488 6 4227 4059 4229 4230 4062 4060 6 4227 4228 4230 4489 4487 4500 6 4229 4228 4062 4500 4501 4502 6 3147 3412 3146 3145 9791 3413 6 4217 4218 4233 4483 4484 4485 6 4232 4218 4234 4235 4485 4486 6 4233 4218 4235 4225 4224 4219 6 4233 4234 4225 4486 4487 4488 6 3889 3890 4237 4251 4252 4256 6 4236 3890 3891 3571 4256 4257 6 3956 3957 4239 7815 7816 4503 6 4238 3957 3803 4100 4240 4503 6 4239 4100 4241 4503 4504 4505 6 4240 4100 4101 4242 4505 4506 6 4241 4101 4102 4243 4416 4506 6 4242 4102 4244 4416 4417 4418 6 4243 4102 4103 4111 4245 4418 6 4244 4111 4246 4247 4418 4419 6 4245 4111 4247 4248 4249 4112 6 4245 4246 4248 4419 7829 7830 6 4247 4246 4249 4391 4739 7830 6 4248 4246 4112 4113 4114 4391 6 3341 3338 1524 1525 2205 2206 6 3889 4236 4252 4253 4428 3888 6 4251 4236 4253 4254 4255 4256 6 4251 4252 4254 4647 4428 6892 6 4253 4252 4255 4729 4730 6892 6 4254 4252 4256 4729 4261 4260 6 4255 4252 4236 4237 4257 4260 6 4256 4237 3571 3572 4258 4260 6 4257 3572 3573 3574 4259 4260 6 4258 3574 4260 4261 4262 4263 6 4258 4259 4261 4256 4257 4255 6 4260 4259 4262 4732 4729 4255 6 4261 4259 4263 6901 4732 6902 6 4262 4259 3574 3575 4264 6902 6 4263 3575 3576 4265 5231 6902 6 4264 3576 3577 4266 5231 5232 6 4265 3577 3578 4267 5232 5233 6 4266 3578 4268 5233 5234 4269 6 4267 3578 3579 3580 4141 4269 6 4268 4141 4270 5234 4267 5451 6 4269 4141 4142 4271 5451 5452 6 4270 4142 4143 4272 5452 5453 6 4271 4143 4144 4273 5453 5454 6 4272 4144 4145 4274 5457 5454 6 4273 4145 4146 4275 5469 5457 6 4274 4146 4147 4276 5469 5470 6 4275 4147 4148 4149 4277 5470 6 4276 4149 4278 5470 5471 5472 6 4277 4149 4150 4279 5472 5473 6 4278 4150 4151 4280 5473 5474 6 4279 4151 4152 4281 5046 5474 6 4280 4152 4153 4282 5046 5047 6 4281 4153 4154 4283 5047 5048 6 4282 4154 4155 4284 5048 5049 6 4283 4155 4156 4285 5049 5050 6 4284 4156 4157 4286 5050 5051 6 4285 4157 4158 4287 5051 5052 6 4286 4158 4159 4288 4923 5052 6 4287 4159 4160 4289 4923 4924 6 4288 4160 4161 4162 4290 4924 6 4289 4162 4291 4924 4925 4926 6 4290 4162 4163 4292 4926 4927 6 4291 4163 4164 4293 4927 4928 6 4292 4164 4165 4294 4928 4929 6 4293 4165 4166 4295 4929 4930 6 4294 4166 4167 4296 4930 4931 6 4295 4167 4168 4169 4297 4931 6 4296 4169 4298 4771 4931 4932 6 4297 4169 4170 4299 4771 4772 6 4298 4170 4171 4300 4772 4773 6 4299 4171 4172 4301 4773 4774 6 4300 4172 4173 4302 4774 4775 6 4301 4173 4174 4303 4775 4776 6 4302 4174 4175 4304 4776 4777 6 4303 4175 4176 4305 4777 4778 6 4304 4176 4177 4306 4778 4779 6 4305 4177 4178 4307 4779 4780 6 4306 4178 4179 4308 4780 4781 6 4307 4179 4180 4309 4781 4782 6 4308 4180 4181 4310 4566 4782 6 4309 4181 4182 4311 4566 4567 6 4310 4182 4183 4312 4567 4568 6 4311 4183 4184 4313 4568 4569 6 4312 4184 4185 4314 4569 4570 6 4313 4185 4186 4315 4570 4571 6 4314 4186 4187 4316 4571 4572 6 4315 4187 4188 4317 4572 4573 6 4316 4188 4189 4318 4573 4574 6 4317 4189 4190 4319 4574 4575 6 4318 4190 4191 4320 4575 4576 6 4319 4191 4192 4321 4576 4577 6 4320 4192 4193 4194 4322 4577 6 4321 4194 4195 4323 4577 4578 6 4322 4195 4324 4578 4579 4580 6 4323 4195 4196 4197 4325 4580 6 4324 4197 4326 4580 4581 4582 6 4325 4197 4198 4199 4327 4582 6 4326 4199 4200 4201 4328 4582 6 4327 4201 4202 4329 4582 4583 6 4328 4202 4203 4330 4583 4584 6 4329 4203 4331 4584 4585 4589 7 4330 4203 4204 4205 4332 4589 4590 6 4331 4205 4206 4333 4590 4591 6 4332 4206 4207 4334 4591 4592 6 4333 4207 4335 4336 4429 4592 5 4334 4207 3937 3938 4336 6 4335 3938 3939 4337 4334 4429 6 4336 3939 3940 4338 4429 4430 6 4337 3940 3941 4339 4430 4431 6 4338 3941 3942 4340 4431 4432 6 4339 3942 3943 4341 4432 4433 6 4340 3943 4342 4433 4434 4435 6 4341 3943 3375 3376 4343 4435 6 4342 3376 3377 4344 4345 4435 6 4343 3377 4345 4346 4347 3378 6 4343 4344 4346 4435 4436 4437 6 4345 4344 4347 4437 4438 4348 6 4346 4344 3378 3645 3646 4348 6 4347 3646 4349 4350 4438 4346 6 4348 3646 4350 4351 4352 3647 6 4348 4349 4351 4601 4438 4602 6 4350 4349 4352 4602 4603 4604 6 4351 4349 3647 3648 4353 4604 6 4352 3648 3657 4354 4355 4604 6 4353 3657 4355 4356 4357 4358 6 4353 4354 4356 4604 4605 4606 6 4355 4354 4357 4361 4362 4606 6 4356 4354 4358 4359 4360 4361 6 4357 4354 4359 4371 3658 3657 6 4357 4358 4360 4368 4369 4371 6 4357 4359 4361 4364 4368 4614 6 4357 4360 4356 4362 4363 4364 6 4356 4361 4363 4606 4607 4608 6 4362 4361 4364 4611 4608 4612 6 4363 4361 4360 4612 4613 4614 6 4097 4098 4366 4372 4373 4374 6 4365 4098 4367 4374 4375 4376 7 4366 4098 4099 3094 4376 1626 1624 6 4360 4359 4369 4370 4614 4615 6 4368 4359 4370 4371 9794 9793 6 4368 4369 9794 4642 4637 4615 6 4369 4359 4358 3658 9793 3659 6 4097 4365 4373 7212 3540 3541 6 4372 4365 4374 7212 7210 7209 6 4373 4365 4366 4375 7209 7213 6 4374 4366 4376 4377 7213 7214 6 4375 4366 4367 4377 1627 1626 5 4375 4376 1627 7214 7215 6 4091 4094 4379 4380 4381 4387 7 4091 4378 4380 7753 4090 7752 7754 6 4379 4378 4381 4382 7754 7755 6 4380 4378 4382 4383 4384 4387 6 4380 4381 4383 7755 7756 7764 6 4382 4381 4384 4385 4389 7764 6 4383 4381 4385 3140 4386 4387 6 4383 4384 3140 4389 4390 3141 6 3140 4384 4387 4095 4388 3139 6 4386 4384 4381 4378 4094 4095 6 4386 4095 2809 2810 2813 3139 6 4383 4385 4390 7764 7765 7766 6 4389 4385 3141 7766 7767 3142 6 4249 4114 4392 4248 4739 4740 6 4391 4114 4115 4393 4402 4740 6 4392 4115 4394 4402 4403 4404 6 4393 4115 4110 3464 4404 3465 5 4121 4123 4126 4396 9784 7 4395 4126 4397 4399 4528 4529 9784 6 4396 4126 4127 4130 4398 4399 6 4397 4130 4399 4400 4401 4132 6 4397 4398 4400 4525 4528 4396 5 4399 4398 4401 4527 4525 7 4400 4398 4132 4410 4534 4527 4535 6 4392 4393 4403 4740 4741 4742 6 4402 4393 4404 4742 4743 4744 6 4403 4393 4394 3465 4744 4745 6 3837 3838 3864 4406 5026 5027 6 4405 3864 4407 5027 5028 5029 6 4406 3864 3865 4408 5029 5030 6 4407 3865 3866 4409 5030 5031 6 4408 3866 3868 4420 5031 5032 6 4401 4132 4133 4411 4535 4536 6 4410 4133 4412 4545 4539 4536 6 4411 4133 4134 4413 4414 4545 6 4412 4134 4414 4415 7164 7165 6 4412 4413 4415 4545 4544 4648 6 4414 4413 4649 4648 7165 7166 6 4242 4243 4417 4506 4507 4508 6 4416 4243 4418 4508 4509 4510 6 4417 4243 4244 4245 4419 4510 6 4418 4245 4247 7828 4510 7829 6 4409 3868 3869 4421 5032 5033 6 4420 3869 3870 3871 4422 5033 6 4421 3871 4423 5033 5034 5035 6 4422 3871 3872 4424 5035 5036 6 4423 3872 3873 4425 4643 5036 6 4424 3873 4426 4643 4644 4645 6 4425 3873 3874 4427 4645 4646 6 4426 3874 3875 4428 4646 4647 6 4427 3875 3888 4647 4253 4251 6 4334 4336 4337 4430 4592 4593 6 4429 4337 4338 4431 4593 4594 6 4430 4338 4339 4432 4594 4595 6 4431 4339 4340 4433 4595 4596 6 4432 4340 4341 4434 4596 4597 6 4433 4341 4435 4597 4598 4436 6 4434 4341 4342 4343 4345 4436 6 4435 4345 4437 4598 4434 4599 6 4436 4345 4346 4438 4599 4600 6 4437 4346 4348 4600 4601 4350 6 3993 3994 4440 4721 4722 4723 6 4439 3994 3995 4441 4723 4724 6 4440 3995 3996 4442 4724 4725 6 4441 3996 3997 4443 4725 4726 6 4442 3997 3998 4444 4726 4727 6 4443 3998 3999 4445 4727 4728 6 4444 3999 4000 4446 4728 4658 6 4445 4000 4001 4070 4447 4658 6 4446 4070 4071 4448 4658 4659 6 4447 4071 4449 4659 4660 4450 6 4448 4071 4072 4073 4074 4450 6 4449 4074 4075 4451 4660 4448 6 4450 4075 4452 4669 4738 4660 6 4451 4075 4076 4077 4453 4669 6 4452 4077 4078 4454 4669 4670 6 4453 4078 4079 4455 4670 4671 6 4454 4079 4080 4456 4671 4672 6 4455 4080 4081 4457 4672 4673 6 4456 4081 4082 4458 4673 4674 6 4457 4082 4083 4459 4674 4675 6 4458 4083 4084 4460 4675 4676 6 4459 4084 4085 4461 4676 4677 6 4460 4085 4462 4677 4678 4679 7 4461 4085 4033 4034 4041 4463 4679 5 4462 4041 4464 4679 4680 6 4463 4041 4042 4465 4471 4680 6 4464 4042 4466 4471 4472 4473 6 4465 4042 4043 4467 4473 4474 6 4466 4043 4044 4468 4474 4475 6 4467 4044 4045 4469 4475 4476 6 4468 4045 4047 4048 4470 4476 6 4469 4048 4049 4209 4476 4477 6 4464 4465 4472 4680 4681 4682 6 4471 4465 4473 4682 4683 4684 6 4472 4465 4466 4474 4684 4685 6 4473 4466 4467 4475 4685 4686 6 4474 4467 4468 4476 4686 4687 6 4475 4468 4469 4470 4477 4687 6 4476 4470 4209 4210 4478 4687 6 4477 4210 4212 4479 4687 5213 6 4478 4212 4214 4480 5213 5214 6 4479 4214 4481 5214 5215 5216 6 4480 4214 4215 4482 4490 5216 6 4481 4215 4217 4483 4490 4491 6 4482 4217 4232 4484 4491 4492 6 4483 4232 4485 4492 4493 4494 6 4484 4232 4233 4486 4494 4495 6 4485 4233 4235 4487 4489 4495 6 4486 4235 4488 4227 4489 4229 5 4487 4235 4227 4226 4225 6 4486 4487 4229 4495 4496 4500 6 4481 4482 4491 4981 4989 5216 6 4490 4482 4483 4492 4981 4982 6 4491 4483 4484 4493 4982 4983 6 4492 4484 4494 4983 4984 4985 6 4493 4484 4485 4495 4985 4497 6 4494 4485 4486 4489 4496 4497 6 4495 4489 4497 4498 4499 4500 6 4495 4496 4498 4985 4494 4986 6 4497 4496 4499 4986 4987 4988 5 4498 4496 4500 4988 4511 7 4499 4496 4489 4229 4230 4501 4511 6 4500 4230 4502 4511 4512 4513 6 4501 4230 4062 4513 4067 4063 6 4239 4240 4504 7816 4238 7817 6 4503 4240 4505 7817 7818 7819 6 4504 4240 4241 4506 7819 7820 6 4505 4241 4242 4416 4507 7820 6 4506 4416 4508 7820 7821 7822 6 4507 4416 4417 4509 7822 7823 6 4508 4417 4510 7823 7824 7825 6 4509 4417 4418 7825 7828 4419 7 4500 4501 4512 4988 4499 5002 4999 6 4511 4501 4513 4754 4759 5002 5 4512 4501 4502 4067 4754 6 426 411 4515 4516 5611 5612 6 4514 411 4516 4517 4521 410 6 4514 4515 4517 4518 5611 5615 6 4516 4515 4518 4519 4520 4521 6 4516 4517 4519 9734 7508 5615 6 4518 4517 4520 5235 9734 9678 6 4519 4517 4521 5235 5236 5237 6 4520 4517 4515 410 5237 421 7 3507 3510 3770 4523 6693 6695 6704 6 4522 3770 4524 6694 6693 4532 6 4523 3770 3771 4525 4526 4532 7 4524 3771 4526 4527 4400 4399 4528 6 4524 4525 4527 4532 4533 4534 5 4526 4525 4400 4534 4401 6 4399 4525 3771 3772 4529 4396 6 4528 3772 3773 4530 4396 9784 6 4529 3773 4531 4116 4119 9784 5 4530 3773 4116 3521 3520 6 4524 4526 4533 5156 4523 6694 6 4532 4526 4534 5156 5157 4666 6 4533 4526 4527 4401 4535 4666 6 4534 4401 4410 4536 4537 4666 6 4535 4410 4537 4538 4539 4411 6 4535 4536 4538 4666 4667 4668 6 4537 4536 4539 4540 4546 4668 6 4538 4536 4540 4541 4545 4411 6 4538 4539 4541 4542 4546 4547 6 4540 4539 4542 4543 4544 4545 6 4540 4541 4543 4550 4547 4551 6 4542 4541 4544 4551 4552 4553 6 4543 4541 4545 4414 4648 4553 6 4544 4541 4539 4411 4412 4414 6 4538 4540 4547 4548 9762 4668 6 4546 4540 4548 4549 4550 4542 6 4546 4547 4549 4557 4560 9762 6 4548 4547 4550 4557 4558 4559 6 4549 4547 4542 4551 6763 4559 6 4550 4542 4543 4552 7144 6763 6 4551 4543 4553 4554 7145 7144 6 4552 4543 4554 4555 4544 4648 6 4552 4553 4555 4556 7145 7146 6 4554 4553 4556 4648 4649 7153 6 4554 4555 7146 7148 7149 7153 6 4548 4549 4558 4560 4561 4562 6 4557 4549 4559 4565 4562 6764 6 4558 4549 6763 6762 6764 4550 7 4548 4557 4561 9762 9761 6675 9792 6 4560 4557 4562 4563 6674 6675 6 4561 4557 4563 4564 4565 4558 6 4561 4562 4564 6665 6666 6674 6 4563 4562 4565 6673 6665 6790 6 4564 4562 4558 6764 6765 6790 6 4309 4310 4567 4782 4783 4784 6 4566 4310 4311 4568 4784 4785 6 4567 4311 4312 4569 4785 4786 6 4568 4312 4313 4570 4786 4787 6 4569 4313 4314 4571 4787 4788 6 4570 4314 4315 4572 4788 4789 6 4571 4315 4316 4573 4789 4790 6 4572 4316 4317 4574 4790 4791 6 4573 4317 4318 4575 4791 4792 6 4574 4318 4319 4576 4792 4793 6 4575 4319 4320 4577 4793 4794 6 4576 4320 4321 4322 4578 4794 6 4577 4322 4323 4579 4794 4795 6 4578 4323 4580 4795 4796 4797 6 4579 4323 4324 4325 4581 4797 6 4580 4325 4582 4797 4798 4583 6 4581 4325 4326 4327 4328 4583 6 4582 4328 4329 4584 4798 4581 7 4583 4329 4330 4585 4586 4804 4798 6 4584 4330 4586 4587 4588 4589 5 4584 4585 4587 4804 4805 6 4586 4585 4588 4805 4806 4807 6 4587 4585 4589 4807 4808 4809 6 4588 4585 4330 4331 4590 4809 5 4589 4331 4332 4591 4809 6 4590 4332 4333 4592 4809 4810 6 4591 4333 4334 4429 4593 4810 6 4592 4429 4430 4594 4810 4811 6 4593 4430 4431 4595 4811 4812 6 4594 4431 4432 4596 4812 4813 6 4595 4432 4433 4597 4813 4814 6 4596 4433 4434 4598 4814 4815 6 4597 4434 4436 4599 4815 4816 6 4598 4436 4437 4600 4816 4817 6 4599 4437 4438 4601 4817 4818 6 4600 4438 4350 4602 4821 4818 6 4601 4350 4351 4603 4821 4822 6 4602 4351 4604 4825 4822 4826 7 4603 4351 4352 4353 4355 4605 4826 5 4604 4355 4606 4826 4827 6 4605 4355 4356 4362 4607 4827 5 4606 4362 4608 4609 4827 6 4607 4362 4609 4610 4611 4363 7 4607 4608 4610 4827 4828 4829 4830 6 4609 4608 4611 4830 4831 4832 6 4610 4608 4363 4612 4832 4834 6 4611 4363 4364 4613 4837 4834 6 4612 4364 4614 4616 4617 4837 6 4613 4364 4360 4368 4615 4616 7 4614 4368 4616 4637 4634 4619 4370 6 4614 4615 4613 4617 4618 4619 6 4613 4616 4618 4837 4622 4838 6 4617 4616 4619 4620 4621 4622 6 4618 4616 4620 4633 4634 4615 6 4618 4619 4621 4628 4629 4633 6 4618 4620 4622 4623 4624 4628 6 4618 4621 4623 4840 4838 4617 6 4622 4621 4624 4625 4840 4841 6 4623 4621 4625 4626 4627 4628 6 4623 4624 4626 4841 4860 4853 6 4625 4624 4627 4860 4861 4862 6 4626 4624 4628 4862 4863 4630 6 4627 4624 4621 4620 4629 4630 6 4628 4620 4630 4631 4632 4633 6 4628 4629 4631 4863 4627 4864 6 4630 4629 4632 4638 4868 4864 6 4631 4629 4633 4638 4639 4635 6 4632 4629 4620 4619 4634 4635 6 4633 4619 4635 4636 4637 4615 6 4633 4634 4636 4639 4632 4640 6 4635 4634 4637 4640 4641 4642 5 4636 4634 4615 4642 4370 6 4631 4632 4639 4868 4912 9760 6 4638 4632 4635 4640 4912 4913 6 4639 4635 4636 4641 4916 4913 6 4640 4636 4642 4910 4916 4909 7 4641 4636 4637 4908 4909 9794 4370 6 4424 4425 4644 5036 5037 5044 6 4643 4425 4645 5045 5044 6889 6 4644 4425 4426 4646 6890 6889 6 4645 4426 4427 4647 6890 6891 6 4646 4427 4428 4253 6891 6892 6 4544 4414 4553 4555 4649 4415 6 4555 4648 4415 7166 7154 7153 6 422 52 53 4651 4652 9684 6 4650 53 4652 4653 4657 54 6 4650 4651 4653 4654 9683 9684 6 4652 4651 4654 4655 4656 4657 6 4652 4653 4655 9682 9680 9683 6 4654 4653 4656 9682 9685 9686 7 4655 4653 4657 5380 9688 9686 9689 6 4656 4653 4651 54 5380 55 6 4446 4447 4659 4728 4445 4736 6 4658 4447 4448 4660 4736 4737 6 4659 4448 4450 4737 4738 4451 6 3895 3896 3897 4662 7841 4758 6 4661 3897 3898 4663 7841 7842 6 4662 3898 4664 7842 4689 4688 6 4663 3898 3899 4665 3685 4688 6 4664 3899 3900 3901 3902 3685 6 4534 4535 4537 4667 5157 4533 6 4666 4537 4668 9750 5157 9761 6 4667 4537 4538 9761 9762 4546 7 4451 4452 4453 4670 4980 4738 5194 6 4669 4453 4454 4671 5194 5195 6 4670 4454 4455 4672 5195 5196 6 4671 4455 4456 4673 5196 5197 6 4672 4456 4457 4674 5197 5198 6 4673 4457 4458 4675 5198 5199 6 4674 4458 4459 4676 5199 5200 6 4675 4459 4460 4677 5200 5201 6 4676 4460 4461 4678 5201 5202 6 4677 4461 4679 5202 5203 5204 6 4678 4461 4462 4463 4680 5204 7 4679 4463 4464 4471 4681 5204 5205 5 4680 4471 4682 5205 5206 7 4681 4471 4472 4683 5206 5207 5208 5 4682 4472 4684 5208 5209 7 4683 4472 4473 4685 5209 5210 5211 6 4684 4473 4474 4686 5211 5212 6 4685 4474 4475 4687 5212 5213 6 4686 4475 4476 4477 4478 5213 6 4664 3685 3686 3687 4689 4663 6 4688 3687 4690 7842 4663 7843 6 4689 3687 3688 4691 7843 7844 6 4690 3688 3689 4692 5158 7844 6 4691 3689 3690 3692 4693 5158 6 4692 3692 4694 5158 5159 5160 6 4693 3692 3693 4695 5160 5161 6 4694 3693 4696 5161 5162 5163 6 4695 3693 3694 3695 4697 5163 6 4696 3695 4698 5163 5164 5165 6 4697 3695 3696 4699 5165 4700 6 4698 3696 3697 3698 3972 4700 6 4699 3972 4701 5165 4698 7854 6 4700 3972 3973 3974 4702 7854 6 4701 3974 4703 7308 7854 7855 6 4702 3974 3975 4704 7308 7309 6 4703 3975 3976 4705 7309 7310 6 4704 3976 3977 4706 7310 7311 6 4705 3977 3978 4707 7311 7312 6 4706 3978 3979 4708 5170 7312 6 4707 3979 3980 4709 5170 5171 6 4708 3980 3981 4710 5171 5172 6 4709 3981 3982 4711 5172 5173 6 4710 3982 3983 4712 5173 5174 6 4711 3983 3984 4713 5174 5175 6 4712 3984 3985 4714 5175 5176 6 4713 3985 3986 4715 5176 5177 6 4714 3986 3987 4716 4965 5177 6 4715 3987 3988 4717 4965 4966 6 4716 3988 3989 4718 4966 4967 6 4717 3989 3990 4719 4967 4968 6 4718 3990 3991 4720 4968 4969 6 4719 3991 3992 4721 4969 4970 6 4720 3992 3993 4439 4722 4970 6 4721 4439 4723 4970 4971 4972 6 4722 4439 4440 4724 4972 4973 6 4723 4440 4441 4725 4973 4974 6 4724 4441 4442 4726 4733 4974 6 4725 4442 4443 4727 4733 4734 6 4726 4443 4444 4728 4734 4735 6 4727 4444 4445 4658 4735 4736 6 4254 4255 4730 4731 4732 4261 6 4254 4729 4731 6892 6893 6894 6 4730 4729 4732 6894 6895 6896 6 4731 4729 4261 6896 6901 4262 6 4725 4726 4734 4974 4975 4976 6 4733 4726 4727 4735 4976 4977 6 4734 4727 4728 4736 4977 4978 6 4735 4728 4658 4659 4737 4978 6 4736 4659 4660 4738 4978 4979 6 4737 4660 4451 4979 4980 4669 6 4248 4391 4740 5003 7830 7831 6 4739 4391 4392 4402 4741 5003 6 4740 4402 4742 4753 5003 5004 6 4741 4402 4403 4743 4753 4748 6 4742 4403 4744 3892 3893 4748 6 4743 4403 4404 4745 4746 3892 6 4744 4404 3465 3466 3468 4746 6 4745 3468 4747 3397 3892 4744 6 4746 3468 2172 2173 3395 3397 6 4743 3893 4749 4750 4753 4742 6 4748 3893 4750 4751 4752 3894 6 4748 4749 4751 5005 4753 7837 6 4750 4749 4752 4757 7837 7838 6 4751 4749 3894 4757 4758 3895 6 4741 4742 4748 5004 5005 4750 7 4513 4067 4068 4755 4512 4759 4760 5 4754 4068 4756 4760 4761 7 4755 4068 4069 3827 4761 4762 4763 6 4751 4752 4758 7838 7839 7840 6 4757 4752 3895 7840 7841 4661 6 4512 4754 4760 5006 5002 5001 5 4759 4754 4755 4761 5006 7 4760 4755 4756 4762 5006 5007 5008 6 4761 4756 4763 5008 5009 5010 6 4762 4756 3827 3828 4764 5010 6 4763 3828 4765 5010 5011 5012 6 4764 3828 3829 3830 4766 5012 6 4765 3830 3831 4767 4768 5012 6 4766 3831 4768 4769 4770 3832 7 4766 4767 4769 5012 5011 5013 5014 6 4768 4767 4770 5014 5015 5016 6 4769 4767 3832 5016 3834 3833 6 4297 4298 4772 4932 4933 4934 6 4771 4298 4299 4773 4934 4935 6 4772 4299 4300 4774 4935 4936 6 4773 4300 4301 4775 4936 4937 6 4774 4301 4302 4776 4937 4938 6 4775 4302 4303 4777 4938 4939 6 4776 4303 4304 4778 4939 4940 6 4777 4304 4305 4779 4940 4941 6 4778 4305 4306 4780 4941 4942 6 4779 4306 4307 4781 4942 4943 6 4780 4307 4308 4782 4943 4944 6 4781 4308 4309 4566 4783 4944 6 4782 4566 4784 4944 4945 4946 6 4783 4566 4567 4785 4946 4947 6 4784 4567 4568 4786 4947 4948 6 4785 4568 4569 4787 4948 4949 6 4786 4569 4570 4788 4949 4950 6 4787 4570 4571 4789 4950 4951 6 4788 4571 4572 4790 4951 4952 6 4789 4572 4573 4791 4952 4953 6 4790 4573 4574 4792 4953 4954 6 4791 4574 4575 4793 4799 4954 6 4792 4575 4576 4794 4799 4800 6 4793 4576 4577 4578 4795 4800 6 4794 4578 4579 4796 4800 4801 6 4795 4579 4797 4801 4802 4803 6 4796 4579 4580 4581 4798 4803 6 4797 4581 4583 4803 4804 4584 6 4792 4793 4800 4954 4955 4956 6 4799 4793 4794 4795 4801 4956 6 4800 4795 4796 4802 4956 4957 6 4801 4796 4803 4957 4958 4959 6 4802 4796 4797 4798 4804 4959 6 4803 4798 4584 4586 4805 4959 6 4804 4586 4587 4806 4918 4959 6 4805 4587 4807 4918 4919 4920 6 4806 4587 4588 4808 4920 4921 6 4807 4588 4809 4921 4922 4810 6 4808 4588 4589 4590 4591 4810 7 4809 4591 4592 4593 4811 4922 4808 5 4810 4593 4594 4812 4922 6 4811 4594 4595 4813 4964 4922 6 4812 4595 4596 4814 5093 4964 6 4813 4596 4597 4815 5093 5094 6 4814 4597 4598 4816 5094 5095 6 4815 4598 4599 4817 5095 5096 6 4816 4599 4600 4818 4819 5096 6 4817 4600 4819 4820 4821 4601 6 4817 4818 4820 5096 5097 5098 6 4819 4818 4821 5098 5099 4823 6 4820 4818 4601 4602 4822 4823 6 4821 4602 4823 4824 4825 4603 6 4821 4822 4824 5099 4820 5100 6 4823 4822 4825 5100 5101 5102 6 4824 4822 4603 4826 5102 5103 6 4825 4603 4604 4605 4827 5103 7 4826 4605 4606 4607 4609 4828 5103 6 4827 4609 4829 5103 5102 5104 6 4828 4609 4830 5104 5105 5106 6 4829 4609 4610 4831 5106 5107 6 4830 4610 4832 4833 5113 5107 5 4831 4610 4611 4833 4834 6 4831 4832 4834 4835 5113 5114 7 4833 4832 4611 4835 4836 4837 4612 6 4833 4834 4836 5114 4845 4844 6 4835 4834 4837 4838 4839 4844 6 4836 4834 4612 4613 4617 4838 6 4836 4837 4839 4840 4622 4617 6 4836 4838 4840 4842 4843 4844 6 4839 4838 4622 4623 4841 4842 6 4840 4623 4842 4625 4852 4853 6 4840 4841 4839 4843 4852 4850 6 4839 4842 4844 4845 4846 4850 5 4839 4843 4845 4835 4836 7 4844 4843 4846 4847 5114 4835 5115 6 4845 4843 4847 4848 4849 4850 6 4845 4846 4848 5117 5115 5118 6 4847 4846 4849 5118 5119 5120 6 4848 4846 4850 4851 5120 5121 6 4849 4846 4851 4852 4842 4843 6 4849 4850 4852 4854 4855 5121 6 4851 4850 4842 4841 4853 4854 6 4852 4841 4854 4857 4860 4625 6 4851 4852 4853 4855 4856 4857 6 4851 4854 4856 5121 5122 5123 6 4855 4854 4857 4858 5123 5124 6 4856 4854 4853 4858 4859 4860 6 4856 4857 4859 5124 5125 5129 6 4858 4857 4860 5129 5130 4861 6 4859 4857 4853 4625 4626 4861 6 4860 4626 4862 5130 4859 5131 6 4861 4626 4627 4863 4865 5131 6 4862 4627 4630 4864 4865 4866 6 4863 4630 4866 4867 4868 4631 6 4862 4863 4866 5131 5132 5136 6 4865 4863 4864 4867 5136 5137 6 4866 4864 4868 4869 4870 5137 6 4867 4864 4631 4638 4869 9760 6 4867 4868 4870 4871 4872 9760 6 4867 4869 4871 5137 5138 5139 6 4870 4869 4872 4873 5150 5139 6 4871 4869 4873 4874 4875 9760 6 4871 4872 4874 5149 5147 5150 6 4873 4872 4875 4876 4877 5149 6 4874 4872 4876 9760 4912 4914 6 4874 4875 4877 4878 4879 4914 6 4874 4876 4878 5155 5149 4882 6 4877 4876 4879 4880 4881 4882 6 4878 4876 4880 4914 4915 9753 7 4878 4879 4881 9753 9754 9756 9757 6 4878 4880 4882 4883 4884 9757 6 4878 4881 4883 5155 4877 5369 6 4882 4881 4884 4885 5369 5370 6 4883 4881 4885 4886 9757 4895 6 4883 4884 4886 4887 4888 5370 6 4885 4884 4887 4894 4891 4895 6 4885 4886 4888 4889 4890 4891 6 4885 4887 4889 5372 5370 5899 6 4888 4887 4890 5898 5896 5899 6 4889 4887 4891 4892 5898 5901 6 4890 4887 4892 4893 4894 4886 6 4890 4891 4893 5901 5902 5903 6 4892 4891 4894 5912 5903 5913 6 4893 4891 4886 4895 4896 5913 7 4894 4886 4896 4897 9757 9756 4884 6 4894 4895 4897 4898 4899 5913 5 4896 4895 4898 9756 9759 6 4896 4897 4899 4900 4901 9759 6 4896 4898 4900 5913 5914 5917 6 4899 4898 4901 4902 5917 5918 6 4900 4898 4902 4903 4904 9759 6 4900 4901 4903 5918 3671 3670 6 4902 4901 4904 4905 3669 3670 6 4903 4901 4905 9754 4911 9759 6 4903 4904 3669 4906 4907 4911 6 3669 4905 4907 4908 3661 3660 6 4906 4905 4908 4909 4910 4911 7 4906 4907 4909 4642 3660 9793 9794 5 4908 4907 4910 4642 4641 6 4909 4907 4911 4917 4916 4641 6 4910 4907 4905 9754 4917 4904 6 4638 4639 4913 4914 9760 4875 6 4912 4639 4914 4915 4916 4640 6 4912 4913 4915 4875 4876 4879 6 4914 4913 4916 4917 9753 4879 6 4915 4913 4917 4910 4641 4640 6 4915 4916 4910 9753 9754 4911 6 4805 4806 4919 4959 4958 4960 6 4918 4806 4920 4960 4961 4962 6 4919 4806 4807 4921 4962 4963 6 4920 4807 4808 4922 4963 4964 6 4921 4808 4810 4964 4812 4811 6 4287 4288 4924 5052 5053 5054 6 4923 4288 4289 4290 4925 5054 6 4924 4290 4926 5054 5055 5056 6 4925 4290 4291 4927 5056 5057 6 4926 4291 4292 4928 5057 5058 6 4927 4292 4293 4929 5058 5059 6 4928 4293 4294 4930 5059 5060 6 4929 4294 4295 4931 5060 5061 6 4930 4295 4296 4297 4932 5061 6 4931 4297 4771 4933 5061 5062 6 4932 4771 4934 5062 5063 5064 6 4933 4771 4772 4935 5064 5065 6 4934 4772 4773 4936 5065 5066 6 4935 4773 4774 4937 5066 5067 6 4936 4774 4775 4938 5067 5068 6 4937 4775 4776 4939 5068 5069 6 4938 4776 4777 4940 5069 5070 6 4939 4777 4778 4941 5070 5071 6 4940 4778 4779 4942 5071 5072 6 4941 4779 4780 4943 5072 5073 6 4942 4780 4781 4944 5073 5074 6 4943 4781 4782 4783 4945 5074 6 4944 4783 4946 5074 5075 5076 6 4945 4783 4784 4947 5076 5077 6 4946 4784 4785 4948 5077 5078 6 4947 4785 4786 4949 5078 5079 6 4948 4786 4787 4950 5079 5080 6 4949 4787 4788 4951 5080 5081 6 4950 4788 4789 4952 5081 5082 6 4951 4789 4790 4953 5082 5083 6 4952 4790 4791 4954 5083 5084 6 4953 4791 4792 4799 4955 5084 6 4954 4799 4956 5084 5085 5086 6 4955 4799 4800 4801 4957 5086 6 4956 4801 4802 4958 5088 5086 6 4957 4802 4959 4918 4960 5088 6 4958 4802 4803 4804 4805 4918 6 4958 4918 4919 4961 5088 5089 6 4960 4919 4962 5089 5090 5091 6 4961 4919 4920 4963 5091 5092 6 4962 4920 4921 4964 5092 5093 6 4963 4921 4922 4812 5093 4813 6 4715 4716 4966 5177 5178 5179 6 4965 4716 4717 4967 5179 5180 6 4966 4717 4718 4968 5180 5181 6 4967 4718 4719 4969 5181 5182 6 4968 4719 4720 4970 5182 5183 6 4969 4720 4721 4722 4971 5183 6 4970 4722 4972 5183 5184 5185 6 4971 4722 4723 4973 5185 5186 6 4972 4723 4724 4974 5186 5187 6 4973 4724 4725 4733 4975 5187 6 4974 4733 4976 5187 5188 5189 6 4975 4733 4734 4977 5189 5190 6 4976 4734 4735 4978 5190 5191 6 4977 4735 4736 4737 4979 5191 6 4978 4737 4738 4980 5191 5192 6 4979 4738 4669 5192 5193 5194 6 4490 4491 4982 4989 4990 4991 6 4981 4491 4492 4983 4991 4992 6 4982 4492 4493 4984 4992 4993 6 4983 4493 4985 4993 4994 4995 6 4984 4493 4494 4497 4986 4995 6 4985 4497 4498 4987 4995 4996 6 4986 4498 4988 4996 4997 4998 6 4987 4498 4499 4511 4998 4999 6 4490 4981 4990 5216 5217 5218 6 4989 4981 4991 5218 5219 5220 6 4990 4981 4982 4992 5220 5221 6 4991 4982 4983 4993 5221 5222 6 4992 4983 4984 4994 5222 5223 6 4993 4984 4995 5223 5224 5225 6 4994 4984 4985 4986 4996 5225 6 4995 4986 4987 4997 5225 5226 6 4996 4987 4998 5226 5227 5228 6 4997 4987 4988 4999 5000 5228 6 4998 4988 5000 5001 5002 4511 6 4998 4999 5001 5228 5229 5230 7 5000 4999 5002 4759 5006 5166 5230 5 5001 4999 4511 4512 4759 6 4739 4740 4741 5004 7831 7834 6 5003 4741 4753 5005 7834 7835 6 5004 4753 4750 7835 7836 7837 7 4759 4760 4761 5007 5021 5001 5166 6 5006 4761 5008 5021 5022 5023 6 5007 4761 4762 5009 5023 5018 6 5008 4762 5010 5011 5017 5018 5 5009 4762 4763 4764 5011 7 5010 4764 5012 4768 5013 5009 5017 5 5011 4764 4765 4766 4768 6 5011 4768 5014 5020 5017 5241 6 5013 4768 4769 5015 5241 5242 6 5014 4769 5016 5242 5243 5024 5 5015 4769 4770 3834 5024 6 5009 5011 5018 5019 5020 5013 7 5009 5017 5019 5023 5008 5238 6833 6 5018 5017 5020 5238 5239 5240 5 5019 5017 5013 5240 5241 5 5006 5007 5022 5166 5167 6 5021 5007 5023 5167 5168 5169 6 5022 5007 5008 5018 5169 6833 7 5016 3834 3835 5025 5243 5015 5244 6 5024 3835 3836 5026 5244 5245 6 5025 3836 3837 4405 5027 5245 6 5026 4405 4406 5028 5245 5246 6 5027 4406 5029 5249 5246 6844 6 5028 4406 4407 5030 6844 6845 6 5029 4407 4408 5031 6845 6846 6 5030 4408 4409 5032 6849 6846 6 5031 4409 4420 5033 6849 6850 6 5032 4420 4421 4422 5034 6850 6 5033 4422 5035 6850 6851 6852 6 5034 4422 4423 5036 6852 5038 6 5035 4423 4424 4643 5037 5038 6 5036 4643 5038 5039 5040 5044 6 5036 5037 5039 6852 5035 6853 6 5038 5037 5040 5041 6856 6853 6 5039 5037 5041 5042 5043 5044 6 5039 5040 5042 6858 6856 6863 6 5041 5040 5043 6878 6879 6863 6 5042 5040 5044 5045 6880 6878 6 5043 5040 5045 4644 4643 5037 6 5043 5044 4644 6880 6881 6889 6 4280 4281 5047 5474 5475 5476 6 5046 4281 4282 5048 5476 5477 6 5047 4282 4283 5049 5477 5478 6 5048 4283 4284 5050 5478 5479 6 5049 4284 4285 5051 5479 5480 6 5050 4285 4286 5052 5480 5481 6 5051 4286 4287 4923 5053 5481 6 5052 4923 5054 5481 5482 5483 6 5053 4923 4924 4925 5055 5483 6 5054 4925 5056 5483 5484 5485 6 5055 4925 4926 5057 5485 5486 6 5056 4926 4927 5058 5486 5487 6 5057 4927 4928 5059 5487 5488 6 5058 4928 4929 5060 5488 5489 6 5059 4929 4930 5061 5489 5490 6 5060 4930 4931 4932 5062 5490 6 5061 4932 4933 5063 5490 5491 6 5062 4933 5064 5250 5491 5492 6 5063 4933 4934 5065 5250 5251 6 5064 4934 4935 5066 5251 5252 6 5065 4935 4936 5067 5252 5253 6 5066 4936 4937 5068 5253 5254 6 5067 4937 4938 5069 5254 5255 6 5068 4938 4939 5070 5255 5256 6 5069 4939 4940 5071 5256 5257 6 5070 4940 4941 5072 5257 5258 6 5071 4941 4942 5073 5258 5259 6 5072 4942 4943 5074 5259 5260 6 5073 4943 4944 4945 5075 5260 6 5074 4945 5076 5260 5261 5262 6 5075 4945 4946 5077 5262 5263 6 5076 4946 4947 5078 5263 5264 6 5077 4947 4948 5079 5264 5265 6 5078 4948 4949 5080 5265 5266 6 5079 4949 4950 5081 5266 5267 6 5080 4950 4951 5082 5267 5268 6 5081 4951 4952 5083 5268 5269 6 5082 4952 4953 5084 5269 5270 6 5083 4953 4954 4955 5085 5270 6 5084 4955 5086 5087 5270 5271 6 5085 4955 4956 5087 5088 4957 6 5085 5086 5088 5271 5272 5089 6 5087 5086 4957 4958 4960 5089 6 5088 4960 4961 5090 5272 5087 6 5089 4961 5091 5272 5273 5274 6 5090 4961 4962 5092 5274 5275 6 5091 4962 4963 5093 5275 5276 7 5092 4963 4964 4813 4814 5094 5276 6 5093 4814 4815 5095 5276 5277 6 5094 4815 4816 5096 5277 5278 6 5095 4816 4817 4819 5097 5278 6 5096 4819 5098 5278 5279 5280 6 5097 4819 4820 5099 5280 5281 6 5098 4820 4823 5100 5281 5282 6 5099 4823 4824 5101 5282 5152 6 5100 4824 5102 5104 5151 5152 6 5101 4824 4825 5103 4828 5104 5 5102 4825 4826 4827 4828 6 5102 4828 4829 5105 5101 5151 7 5104 4829 5106 5154 5151 5287 5288 6 5105 4829 4830 5107 5108 5288 6 5106 4830 5108 5109 5113 4831 6 5106 5107 5109 5110 5288 5289 6 5108 5107 5110 5111 5112 5113 6 5108 5109 5111 5289 5290 5294 6 5110 5109 5112 5294 5295 5116 6 5111 5109 5113 5114 5115 5116 6 5112 5109 5107 4831 4833 5114 6 5113 4833 4835 4845 5115 5112 6 5114 4845 5112 5116 5117 4847 6 5112 5115 5117 5295 5111 5296 6 5116 5115 4847 5118 5299 5296 6 5117 4847 4848 5119 5299 5300 6 5118 4848 5120 5300 5301 5302 5 5119 4848 4849 5121 5302 6 5120 4849 4851 4855 5122 5302 6 5121 4855 5123 5318 5302 5319 6 5122 4855 4856 5124 5321 5319 6 5123 4856 4858 5125 5126 5321 6 5124 4858 5126 5127 5128 5129 6 5124 5125 5127 5322 5321 5323 6 5126 5125 5128 5323 5324 5328 6 5127 5125 5129 5336 5328 5337 6 5128 5125 4858 4859 5130 5337 6 5129 4859 4861 5131 5337 5338 7 5130 4861 4862 4865 5132 5133 5338 6 5131 4865 5133 5134 5135 5136 5 5131 5132 5134 5338 5339 6 5133 5132 5135 5339 5340 5341 6 5134 5132 5136 5346 5344 5341 6 5135 5132 4865 4866 5137 5346 6 5136 4866 4867 4870 5138 5346 6 5137 4870 5139 5140 5344 5346 6 5138 4870 5140 5141 4871 5150 6 5138 5139 5141 5142 5345 5344 6 5140 5139 5142 5143 5144 5150 6 5140 5141 5143 5345 5360 5359 7 5142 5141 5144 5145 5360 5357 5361 6 5143 5141 5145 5146 5147 5150 6 5143 5144 5146 5361 5362 5366 5 5145 5144 5147 5148 5366 6 5146 5144 5148 5149 4873 5150 7 5146 5147 5149 5155 5366 5367 5368 6 5148 5147 4873 5155 4877 4874 6 4873 5147 4871 5139 5141 5144 6 5101 5104 5152 5153 5154 5105 6 5101 5151 5153 5282 5100 5283 6 5152 5151 5154 5283 5284 5285 6 5153 5151 5105 5285 5286 5287 6 5148 5149 4877 4882 5368 5369 7 4532 4533 5157 6682 6683 6684 6694 6 5156 4533 4666 6682 9750 4667 5 4691 4692 4693 5159 7844 7 5158 4693 5160 7844 7845 7846 7847 6 5159 4693 4694 5161 7847 7848 6 5160 4694 4695 5162 7848 7849 6 5161 4695 5163 7849 7850 7851 6 5162 4695 4696 4697 5164 7851 6 5163 4697 5165 7851 7852 7853 6 5164 4697 4698 4700 7853 7854 5 5001 5006 5021 5167 5230 8 5166 5021 5022 5168 5229 5230 6826 6824 6 5167 5022 5169 6826 6827 6830 7 5168 5022 5023 6830 6831 6832 6833 6 4707 4708 5171 7312 7313 7314 6 5170 4708 4709 5172 7314 7315 6 5171 4709 4710 5173 7315 7316 6 5172 4710 4711 5174 7316 7317 6 5173 4711 4712 5175 7317 7318 6 5174 4712 4713 5176 7318 7319 6 5175 4713 4714 5177 7319 7320 6 5176 4714 4715 4965 5178 7320 6 5177 4965 5179 7320 7321 7322 6 5178 4965 4966 5180 7322 7323 6 5179 4966 4967 5181 5411 7323 6 5180 4967 4968 5182 5411 5412 6 5181 4968 4969 5183 5412 5413 6 5182 4969 4970 4971 5184 5413 6 5183 4971 5185 5413 5414 5415 6 5184 4971 4972 5186 5403 5415 6 5185 4972 4973 5187 5403 5404 6 5186 4973 4974 4975 5188 5404 6 5187 4975 5189 5404 5405 5406 6 5188 4975 4976 5190 5406 5407 6 5189 4976 4977 5191 5407 5408 6 5190 4977 4978 4979 5192 5408 6 5191 4979 4980 5193 5408 5409 6 5192 4980 5194 5409 5410 5195 5 5193 4980 4669 4670 5195 6 5194 4670 4671 5196 5410 5193 7 5195 4671 4672 5197 5423 5410 5431 5 5196 4672 4673 5198 5431 7 5197 4673 4674 5199 5431 5432 5433 6 5198 4674 4675 5200 5433 5434 6 5199 4675 4676 5201 5434 5435 6 5200 4676 4677 5202 5435 5436 6 5201 4677 4678 5203 5436 5437 6 5202 4678 5204 5437 5438 5439 6 5203 4678 4679 4680 5205 5439 5 5204 4680 4681 5206 5439 7 5205 4681 4682 5207 5439 5440 5441 6 5206 4682 5208 5441 5442 5443 6 5207 4682 4683 5209 5424 5443 7 5208 4683 4684 5210 5424 5425 5426 5 5209 4684 5211 5426 5427 7 5210 4684 4685 5212 5427 5215 5214 5 5211 4685 4686 5213 5214 6 5212 4686 4687 4478 4479 5214 6 5213 4479 4480 5215 5211 5212 6 5214 4480 5216 5427 5211 5217 6 5215 4480 4481 4490 4989 5217 7 5216 4989 5218 5447 5427 5215 6810 6 5217 4989 4990 5219 6810 6811 6 5218 4990 5220 6811 6812 6813 6 5219 4990 4991 5221 6813 6814 5 5220 4991 4992 5222 6814 7 5221 4992 4993 5223 6814 6815 6816 5 5222 4993 4994 5224 6816 7 5223 4994 5225 6816 6817 6818 6819 6 5224 4994 4995 4996 5226 6819 6 5225 4996 4997 5227 6819 6820 6 5226 4997 5228 6820 6821 6822 6 5227 4997 4998 5000 5229 6822 7 5228 5000 5230 5167 6822 6823 6824 5 5229 5000 5167 5166 5001 6 4264 4265 5232 6902 6903 5458 6 5231 4265 4266 5233 5448 5458 6 5232 4266 4267 5234 5448 5449 6 5233 4267 4269 5449 5450 5451 6 4519 4520 5236 9677 9678 9679 6 5235 4520 5237 9679 9683 9684 6 5236 4520 4521 422 9684 421 6 5018 5019 5239 6832 6833 6834 6 5238 5019 5240 5648 6834 6835 6 5239 5019 5020 5241 5648 5649 7 5240 5020 5013 5014 5242 5649 5650 5 5241 5014 5015 5243 5650 7 5242 5015 5024 5244 5652 5650 5653 6 5243 5024 5025 5245 5653 5247 6 5244 5025 5026 5027 5246 5247 6 5245 5027 5247 5248 5249 5028 6 5245 5246 5248 5653 5244 6840 6 5247 5246 5249 6841 6840 6842 6 5248 5246 5028 6842 6843 6844 6 5063 5064 5251 5492 5493 5494 6 5250 5064 5065 5252 5494 5495 6 5251 5065 5066 5253 5495 5496 6 5252 5066 5067 5254 5496 5497 6 5253 5067 5068 5255 5497 5498 6 5254 5068 5069 5256 5498 5499 6 5255 5069 5070 5257 5499 5500 6 5256 5070 5071 5258 5500 5501 6 5257 5071 5072 5259 5501 5502 6 5258 5072 5073 5260 5502 5503 6 5259 5073 5074 5075 5261 5503 6 5260 5075 5262 5503 5504 5505 6 5261 5075 5076 5263 5505 5506 6 5262 5076 5077 5264 5506 5507 6 5263 5077 5078 5265 5507 5508 6 5264 5078 5079 5266 5508 5509 6 5265 5079 5080 5267 5509 5510 6 5266 5080 5081 5268 5510 5511 6 5267 5081 5082 5269 5511 5512 6 5268 5082 5083 5270 5512 5513 6 5269 5083 5084 5085 5271 5513 6 5270 5085 5087 5272 5513 5514 6 5271 5087 5089 5090 5273 5514 6 5272 5090 5274 5514 5515 5516 6 5273 5090 5091 5275 5519 5516 6 5274 5091 5092 5276 5519 5277 5 5275 5092 5093 5094 5277 6 5276 5094 5095 5278 5519 5275 6 5277 5095 5096 5097 5279 5519 6 5278 5097 5280 5519 5518 5520 6 5279 5097 5098 5281 5520 5377 6 5280 5098 5099 5282 5376 5377 6 5281 5099 5100 5152 5283 5376 6 5282 5152 5153 5284 5379 5376 6 5283 5153 5285 5524 5379 5525 6 5284 5153 5154 5286 5525 5526 6 5285 5154 5287 5526 5527 5291 6 5286 5154 5105 5288 5291 5289 5 5287 5105 5106 5108 5289 6 5288 5108 5110 5290 5291 5287 6 5289 5110 5291 5292 5293 5294 7 5289 5290 5292 5527 5286 5287 5528 6 5291 5290 5293 5528 5529 5533 5 5292 5290 5294 5533 5534 6 5293 5290 5110 5111 5295 5534 6 5294 5111 5116 5296 5297 5534 6 5295 5116 5297 5298 5299 5117 6 5295 5296 5298 5534 5535 5542 6 5297 5296 5299 5542 5543 5544 6 5298 5296 5117 5118 5300 5544 6 5299 5118 5119 5301 5304 5544 6 5300 5119 5302 5303 5304 5305 7 5301 5119 5303 5318 5122 5120 5121 6 5301 5302 5308 5305 5309 5318 6 5300 5301 5305 5306 5543 5544 6 5304 5301 5306 5307 5308 5303 6 5304 5305 5307 5543 5545 5546 6 5306 5305 5308 5311 5312 5546 6 5307 5305 5303 5309 5310 5311 6 5308 5303 5310 5316 5317 5318 6 5308 5309 5311 5314 5315 5316 6 5308 5310 5307 5312 5313 5314 6 5307 5311 5313 5546 5547 5548 6 5312 5311 5314 5548 5549 5550 6 5313 5311 5310 5315 5553 5550 6 5314 5310 5316 5555 5553 5558 6 5315 5310 5309 5317 5558 5559 6 5316 5309 5318 5319 5320 5559 6 5317 5309 5303 5302 5122 5319 6 5318 5122 5317 5320 5321 5123 6 5317 5319 5321 5322 5559 5560 6 5320 5319 5322 5126 5124 5123 6 5320 5321 5126 5323 5560 5561 6 5322 5126 5127 5324 5325 5561 6 5323 5127 5325 5326 5327 5328 6 5323 5324 5326 5561 5562 5563 6 5325 5324 5327 5572 5563 5573 6 5326 5324 5328 5329 5330 5573 6 5327 5324 5329 5336 5128 5127 6 5327 5328 5330 5331 5332 5336 6 5327 5329 5331 5573 5574 5575 6 5330 5329 5332 5333 5575 5576 6 5331 5329 5333 5334 5335 5336 6 5331 5332 5334 5576 5577 5578 6 5333 5332 5335 5578 5340 5339 6 5334 5332 5336 5337 5338 5339 6 5335 5332 5329 5328 5128 5337 6 5336 5128 5129 5130 5335 5338 6 5335 5337 5130 5131 5133 5339 6 5338 5133 5134 5340 5334 5335 6 5339 5134 5341 5342 5578 5334 6 5340 5134 5342 5343 5344 5135 6 5340 5341 5343 5348 5349 5578 6 5342 5341 5344 5345 5347 5348 7 5343 5341 5345 5140 5138 5346 5135 6 5343 5344 5140 5142 5347 5359 5 5138 5344 5135 5136 5137 6 5343 5345 5348 5351 5352 5359 6 5343 5347 5342 5349 5350 5351 6 5342 5348 5350 5578 5577 5579 6 5349 5348 5351 5579 5580 5584 6 5350 5348 5347 5352 5353 5584 6 5351 5347 5353 5354 5355 5359 6 5351 5352 5354 5608 5584 5609 6 5353 5352 5355 5356 5807 5609 6 5354 5352 5356 5357 5359 5360 6 5354 5355 5357 5358 5807 5808 6 5356 5355 5358 5360 5143 5361 7 5356 5357 5808 5809 5810 5363 5361 6 5355 5352 5347 5360 5142 5345 5 5355 5359 5142 5143 5357 6 5357 5143 5145 5362 5363 5358 6 5361 5145 5363 5364 5365 5366 5 5361 5362 5364 5810 5358 6 5363 5362 5365 5810 5811 5402 7 5364 5362 5366 5402 5401 5367 5375 6 5365 5362 5145 5146 5148 5367 6 5366 5148 5368 5374 5365 5375 6 5367 5148 5155 5369 5371 5374 6 5368 5155 4882 4883 5370 5371 6 5369 4883 5371 5372 4888 4885 6 5369 5370 5372 5373 5374 5368 6 5371 5370 5373 4888 5393 5899 6 5371 5372 5374 5375 5392 5393 5 5371 5373 5375 5368 5367 6 5374 5373 5392 5365 5367 5401 6 5281 5282 5377 5378 5379 5283 6 5281 5376 5378 5520 5280 5521 6 5377 5376 5379 5521 5522 5523 6 5378 5376 5283 5523 5524 5284 6 4656 4657 55 9689 430 56 6 1679 1680 1678 5382 5383 1682 6 1678 5381 5383 5384 7779 3415 6 5382 5381 5384 5385 3774 1682 6 5382 5383 5385 5386 7779 7780 6 5384 5383 5386 5387 5391 3774 6 5384 5385 5387 5388 7780 7781 6 5386 5385 5388 5389 5390 5391 6 5386 5387 5389 5616 7781 7782 6 5388 5387 5390 5616 5617 5618 6 5389 5387 5391 5618 5619 5620 6 5390 5387 5385 3774 5620 3775 6 5375 5373 5393 5394 5401 5398 6 5392 5373 5394 5372 5395 5899 6 5392 5393 5395 5396 5397 5398 5 5394 5393 5396 5899 5894 6 5394 5395 5397 5893 5890 5894 6 5394 5396 5398 5399 5889 5890 6 5394 5397 5399 5400 5401 5392 6 5398 5397 5400 5880 5888 5889 7 5398 5399 5401 5402 5887 5881 5880 6 5398 5400 5402 5365 5375 5392 6 5401 5400 5887 5811 5364 5365 6 5185 5186 5404 5415 5416 5417 6 5403 5186 5187 5188 5405 5417 6 5404 5188 5406 5417 5418 5419 6 5405 5188 5189 5407 5419 5420 6 5406 5189 5190 5408 5420 5421 6 5407 5190 5191 5192 5409 5421 6 5408 5192 5193 5410 5421 5422 6 5409 5193 5195 5422 5423 5196 6 5180 5181 5412 7323 7324 7325 6 5411 5181 5182 5413 7325 7326 6 5412 5182 5183 5184 5414 7326 6 5413 5184 5415 7326 7327 7328 6 5414 5184 5185 5403 5416 7328 6 5415 5403 5417 7328 7329 7330 6 5416 5403 5404 5405 5418 7330 6 5417 5405 5419 6791 7330 7331 6 5418 5405 5406 5420 6791 6792 6 5419 5406 5407 5421 5428 6792 6 5420 5407 5408 5409 5422 5428 6 5421 5409 5410 5423 5428 5429 6 5422 5410 5196 5429 5430 5431 6 5208 5209 5425 5443 5444 5445 6 5424 5209 5426 5445 5446 5447 5 5425 5209 5210 5427 5447 6 5426 5210 5211 5215 5447 5217 6 5420 5421 5422 5429 6792 6793 6 5428 5422 5423 5430 6793 6794 6 5429 5423 5431 6794 6795 5432 6 5430 5423 5196 5197 5198 5432 5 5431 5198 5433 6795 5430 6 5432 5198 5199 5434 6795 6796 6 5433 5199 5200 5435 6796 6797 6 5434 5200 5201 5436 6797 6798 6 5435 5201 5202 5437 6798 6799 6 5436 5202 5203 5438 6799 6800 6 5437 5203 5439 6800 6801 6802 7 5438 5203 5204 5205 5206 5440 6802 5 5439 5206 5441 6802 6803 6 5440 5206 5207 5442 6803 6804 6 5441 5207 5443 6804 6805 5444 5 5442 5207 5208 5424 5444 6 5443 5424 5445 6805 5442 6806 6 5444 5424 5425 5446 6806 6807 6 5445 5425 5447 6807 6808 6809 7 5446 5425 5426 5427 5217 6809 6810 6 5232 5233 5449 5458 5459 5460 6 5448 5233 5234 5450 5460 5461 6 5449 5234 5451 5461 5462 5463 6 5450 5234 4269 4270 5452 5463 6 5451 4270 4271 5453 5463 5464 6 5452 4271 4272 5454 5455 5464 6 5453 4272 5455 5456 5457 4273 6 5453 5454 5456 5464 5465 5466 6 5455 5454 5457 5466 5467 5468 6 5456 5454 4273 5468 5469 4274 6 5232 5448 5459 6903 5231 6904 6 5458 5448 5460 6904 6905 6906 6 5459 5448 5449 5461 6906 6907 6 5460 5449 5450 5462 6907 6908 6 5461 5450 5463 6908 6909 6910 6 5462 5450 5451 5452 5464 6910 6 5463 5452 5453 5455 5465 6910 6 5464 5455 5466 6910 6911 6912 6 5465 5455 5456 5467 6912 6913 6 5466 5456 5468 6913 6914 6915 6 5467 5456 5457 5469 6915 6916 6 5468 5457 4274 4275 5470 6916 6 5469 4275 4276 4277 5471 6916 6 5470 4277 5472 6916 6917 6918 6 5471 4277 4278 5473 6918 6919 6 5472 4278 4279 5474 6919 6920 6 5473 4279 4280 5046 5475 6920 6 5474 5046 5476 6920 6921 6922 6 5475 5046 5047 5477 6922 6923 6 5476 5047 5048 5478 6923 6924 6 5477 5048 5049 5479 6924 6925 6 5478 5049 5050 5480 6925 6926 6 5479 5050 5051 5481 5654 6926 6 5480 5051 5052 5053 5482 5654 6 5481 5053 5483 5654 5655 5656 6 5482 5053 5054 5055 5484 5656 6 5483 5055 5485 5656 5657 5658 6 5484 5055 5056 5486 5658 5659 6 5485 5056 5057 5487 5659 5660 6 5486 5057 5058 5488 5660 5661 6 5487 5058 5059 5489 5621 5661 6 5488 5059 5060 5490 5621 5622 6 5489 5060 5061 5062 5491 5622 6 5490 5062 5063 5492 5622 5623 6 5491 5063 5250 5493 5623 5624 6 5492 5250 5494 5624 5625 5626 6 5493 5250 5251 5495 5626 5627 6 5494 5251 5252 5496 5627 5628 6 5495 5252 5253 5497 5628 5629 6 5496 5253 5254 5498 5629 5630 6 5497 5254 5255 5499 5630 5631 6 5498 5255 5256 5500 5631 5632 6 5499 5256 5257 5501 5632 5633 6 5500 5257 5258 5502 5633 5634 6 5501 5258 5259 5503 5634 5635 6 5502 5259 5260 5261 5504 5635 6 5503 5261 5505 5635 5636 5637 6 5504 5261 5262 5506 5637 5638 6 5505 5262 5263 5507 5638 5639 6 5506 5263 5264 5508 5639 5640 6 5507 5264 5265 5509 5640 5641 6 5508 5265 5266 5510 5641 5642 6 5509 5266 5267 5511 5642 5643 6 5510 5267 5268 5512 5643 5644 6 5511 5268 5269 5513 5644 5645 6 5512 5269 5270 5271 5514 5645 6 5513 5271 5272 5273 5515 5645 6 5514 5273 5516 5517 5645 5646 6 5515 5273 5517 5518 5519 5274 6 5515 5516 5518 5646 5647 5520 5 5517 5516 5519 5279 5520 7 5518 5516 5274 5275 5277 5278 5279 7 5518 5279 5280 5377 5521 5647 5517 5 5520 5377 5378 5522 5647 7 5521 5378 5523 5685 5647 5684 5686 6 5522 5378 5379 5524 5687 5686 6 5523 5379 5284 5525 5687 5688 6 5524 5284 5285 5526 5688 5689 6 5525 5285 5286 5527 5689 5690 6 5526 5286 5291 5528 5690 5691 6 5527 5291 5292 5529 5530 5691 6 5528 5292 5530 5531 5532 5533 5 5528 5529 5531 5691 5692 6 5530 5529 5532 5692 5693 5694 7 5531 5529 5533 5694 5695 5538 5536 6 5532 5529 5292 5293 5534 5536 7 5533 5293 5294 5295 5297 5535 5536 6 5534 5297 5536 5537 5541 5542 6 5534 5535 5537 5538 5532 5533 6 5536 5535 5538 5539 5540 5541 6 5536 5537 5539 5695 5532 5696 6 5538 5537 5540 5696 5697 5698 7 5539 5537 5541 5698 5699 5700 9795 5 5540 5537 5535 5542 9795 6 5541 5535 5297 5298 5543 9795 7 5542 5298 5544 5304 5306 5545 9795 5 5543 5298 5304 5300 5299 6 5543 5306 5546 5701 5700 9795 6 5545 5306 5307 5312 5547 5701 6 5546 5312 5548 5701 5702 5703 6 5547 5312 5313 5549 5703 5704 6 5548 5313 5550 5551 5704 5705 6 5549 5313 5551 5552 5553 5314 6 5549 5550 5552 5705 5706 5707 6 5551 5550 5553 5554 5707 5708 6 5552 5550 5314 5554 5555 5315 6 5552 5553 5555 5556 5708 5709 6 5554 5553 5315 5556 5557 5558 6 5554 5555 5557 5709 5710 5711 6 5556 5555 5558 5714 5711 5715 6 5557 5555 5315 5316 5559 5715 6 5558 5316 5317 5320 5560 5715 6 5559 5320 5322 5561 5716 5715 6 5560 5322 5323 5325 5562 5716 6 5561 5325 5563 5564 5717 5716 6 5562 5325 5564 5565 5572 5326 6 5562 5563 5565 5566 5717 5713 6 5564 5563 5566 5567 5571 5572 6 5564 5565 5567 5568 5753 5713 6 5566 5565 5568 5569 5570 5571 6 5566 5567 5569 5752 5753 5754 6 5568 5567 5570 5754 5755 5770 6 5569 5567 5571 5769 5767 5770 6 5570 5567 5565 5572 5769 5771 6 5571 5565 5563 5326 5573 5771 6 5572 5326 5327 5330 5574 5771 6 5573 5330 5575 5771 5772 5773 6 5574 5330 5331 5576 5773 5594 7 5575 5331 5333 5577 5594 5589 5774 6 5576 5333 5578 5349 5579 5774 6 5577 5333 5334 5340 5342 5349 6 5577 5349 5350 5580 5581 5774 6 5579 5350 5581 5582 5583 5584 6 5579 5580 5582 5585 5586 5774 6 5581 5580 5583 5585 5605 5606 6 5582 5580 5584 5606 5607 5608 6 5583 5580 5350 5351 5608 5353 6 5581 5582 5586 5587 5605 5597 6 5581 5585 5587 5588 5589 5774 6 5586 5585 5588 5595 5596 5597 6 5586 5587 5589 5590 5591 5595 6 5586 5588 5590 5594 5576 5774 6 5589 5588 5591 5592 5594 5773 6 5590 5588 5592 5593 5595 5778 6 5590 5591 5593 5773 5772 5775 6 5592 5591 5775 5776 5777 5778 5 5589 5590 5773 5575 5576 6 5591 5588 5587 5596 5778 5779 6 5595 5587 5597 5598 5599 5779 6 5596 5587 5598 5602 5605 5585 6 5596 5597 5599 5600 5601 5602 6 5596 5598 5600 5779 5780 5781 6 5599 5598 5601 5781 5789 5790 6 5600 5598 5602 5603 5790 5791 6 5601 5598 5603 5604 5597 5605 6 5601 5602 5604 5794 5791 5795 6 5603 5602 5795 5796 5606 5605 6 5602 5597 5585 5582 5606 5604 6 5605 5582 5583 5607 5796 5604 6 5606 5583 5608 5610 5798 5796 6 5607 5583 5584 5353 5609 5610 7 5608 5353 5610 5800 5806 5807 5354 5 5608 5609 5607 5800 5798 6 4514 4516 5612 5613 5614 5615 6 4514 5611 5613 427 426 7500 6 5612 5611 5614 7500 7501 7505 6 5613 5611 5615 7505 7506 7507 6 5614 5611 4516 7507 7508 4518 6 5388 5389 5617 7782 7783 7784 6 5616 5389 5618 7784 7785 7786 6 5617 5389 5390 5619 7786 7789 6 5618 5390 5620 7789 7790 7791 6 5619 5390 5391 3775 3778 7791 6 5488 5489 5622 5661 5662 5663 6 5621 5489 5490 5491 5623 5663 6 5622 5491 5492 5624 5663 5664 6 5623 5492 5493 5625 5664 5665 6 5624 5493 5626 5665 5666 5667 6 5625 5493 5494 5627 5667 5668 6 5626 5494 5495 5628 5668 5669 6 5627 5495 5496 5629 5669 5670 6 5628 5496 5497 5630 5670 5671 6 5629 5497 5498 5631 5671 5672 6 5630 5498 5499 5632 5672 5673 6 5631 5499 5500 5633 5673 5674 6 5632 5500 5501 5634 5674 5675 6 5633 5501 5502 5635 5675 5676 6 5634 5502 5503 5504 5636 5676 6 5635 5504 5637 5676 5677 5678 6 5636 5504 5505 5638 5678 5679 6 5637 5505 5506 5639 5679 5680 6 5638 5506 5507 5640 5680 5681 6 5639 5507 5508 5641 5681 5682 6 5640 5508 5509 5642 5682 5683 6 5641 5509 5510 5643 5683 5684 6 5642 5510 5511 5644 5684 5685 6 5643 5511 5512 5645 5685 5646 6 5644 5512 5513 5514 5515 5646 6 5645 5515 5517 5647 5685 5644 6 5646 5517 5520 5685 5522 5521 6 5239 5240 5649 6835 6836 6837 6 5648 5240 5241 5650 5651 6837 6 5649 5241 5651 5652 5243 5242 6 5649 5650 5652 6837 6838 6839 6 5651 5650 5243 5653 6839 6840 5 5652 5243 5244 5247 6840 6 5480 5481 5482 5655 6926 6927 6 5654 5482 5656 6927 6928 6929 6 5655 5482 5483 5484 5657 6929 6 5656 5484 5658 6929 6930 6931 6 5657 5484 5485 5659 5831 6931 6 5658 5485 5486 5660 5831 5832 6 5659 5486 5487 5661 5832 5833 6 5660 5487 5488 5621 5662 5833 6 5661 5621 5663 5833 5834 5835 6 5662 5621 5622 5623 5664 5835 6 5663 5623 5624 5665 5835 5813 6 5664 5624 5625 5666 5812 5813 6 5665 5625 5667 5812 5816 5817 6 5666 5625 5626 5668 5859 5817 6 5667 5626 5627 5669 5859 5860 6 5668 5627 5628 5670 5860 5861 6 5669 5628 5629 5671 5861 5862 6 5670 5629 5630 5672 5862 5863 6 5671 5630 5631 5673 5863 5864 6 5672 5631 5632 5674 5864 5865 6 5673 5632 5633 5675 5865 5866 6 5674 5633 5634 5676 5866 5867 6 5675 5634 5635 5636 5677 5867 6 5676 5636 5678 5867 5868 5693 6 5677 5636 5637 5679 5693 5869 6 5678 5637 5638 5680 5869 5870 6 5679 5638 5639 5681 5870 5871 6 5680 5639 5640 5682 5871 5688 6 5681 5640 5641 5683 5688 5687 6 5682 5641 5642 5684 5686 5687 6 5683 5642 5643 5685 5522 5686 6 5684 5643 5644 5646 5647 5522 5 5684 5522 5683 5687 5523 6 5683 5686 5523 5524 5688 5682 7 5687 5524 5525 5689 5871 5681 5682 5 5688 5525 5526 5690 5871 7 5689 5526 5527 5691 5871 5870 5692 5 5690 5527 5528 5530 5692 7 5691 5530 5531 5693 5870 5690 5869 7 5692 5531 5694 5868 5677 5678 5869 6 5693 5531 5532 5695 9698 5868 6 5694 5532 5538 5696 9699 9698 6 5695 5538 5539 5697 5718 9699 6 5696 5539 5698 5718 5719 5720 6 5697 5539 5540 5699 5720 5721 6 5698 5540 5700 5701 5721 5722 5 5699 5540 5701 5545 9795 7 5699 5700 5545 5546 5547 5702 5722 6 5701 5547 5703 5722 5723 5727 6 5702 5547 5548 5704 5727 5728 6 5703 5548 5549 5705 5728 5729 6 5704 5549 5551 5706 5732 5729 6 5705 5551 5707 5732 5733 5734 6 5706 5551 5552 5708 5737 5734 6 5707 5552 5554 5709 5737 5738 6 5708 5554 5556 5710 5747 5738 6 5709 5556 5711 5712 5747 5748 6 5710 5556 5712 5713 5714 5557 6 5710 5711 5713 5748 5749 5753 7 5712 5711 5714 5717 5564 5753 5566 6 5713 5711 5557 5715 5716 5717 6 5714 5557 5716 5560 5559 5558 6 5714 5715 5717 5562 5561 5560 5 5714 5716 5562 5564 5713 7 5696 5697 5719 9696 5865 9697 9699 6 5718 5697 5720 9696 9695 9700 6 5719 5697 5698 5721 9700 9701 7 5720 5698 5699 5722 5723 5724 9701 5 5721 5699 5701 5702 5723 7 5722 5702 5721 5724 5725 5726 5727 6 5721 5723 5725 6095 9701 9702 6 5724 5723 5726 6095 6096 6097 6 5725 5723 5727 6097 5730 5728 5 5726 5723 5702 5703 5728 6 5727 5703 5704 5729 5730 5726 6 5728 5704 5730 5731 5732 5705 7 5728 5729 5731 6097 5726 6098 6099 6 5730 5729 5732 6099 6100 6101 6 5731 5729 5705 5706 5733 6101 6 5732 5706 5734 5735 6101 6102 6 5733 5706 5735 5736 5737 5707 6 5733 5734 5736 6105 6102 6106 6 5735 5734 5737 6106 6107 5739 6 5736 5734 5707 5708 5738 5739 6 5737 5708 5739 5740 5747 5709 6 5737 5738 5740 5741 6107 5736 6 5739 5738 5741 5742 5746 5747 6 5739 5740 5742 5743 6107 6108 6 5741 5740 5743 5744 5745 5746 6 5741 5742 5744 6111 6108 6112 6 5743 5742 5745 6112 6113 6114 6 5744 5742 5746 5750 6121 6114 6 5745 5742 5740 5747 5748 5750 6 5746 5740 5738 5709 5710 5748 6 5747 5710 5712 5749 5746 5750 6 5748 5712 5750 5751 5752 5753 6 5746 5748 5745 5749 5751 6121 5 5750 5749 5752 6121 5949 6 5751 5749 5753 5568 5754 5949 6 5752 5749 5712 5713 5568 5566 6 5752 5568 5569 5755 5756 5949 6 5754 5569 5756 5757 5758 5770 6 5754 5755 5757 5949 5950 5951 6 5756 5755 5758 5759 5951 5952 6 5757 5755 5759 5760 5761 5770 6 5757 5758 5760 5952 5953 5957 6 5759 5758 5761 5762 5763 5957 6 5760 5758 5762 5766 5767 5770 6 5760 5761 5763 5764 5765 5766 6 5760 5762 5764 5957 5958 5988 6 5763 5762 5765 5989 5988 5990 6 5764 5762 5766 5990 5991 5776 6 5765 5762 5761 5767 5768 5776 6 5766 5761 5768 5769 5570 5770 6 5766 5767 5769 5772 5775 5776 6 5768 5767 5570 5571 5771 5772 6 5570 5767 5569 5761 5755 5758 6 5769 5571 5572 5573 5574 5772 7 5771 5574 5773 5592 5775 5769 5768 6 5772 5574 5575 5594 5590 5592 6 5589 5576 5586 5581 5579 5577 5 5772 5592 5593 5776 5768 7 5775 5593 5777 5991 5765 5768 5766 6 5776 5593 5778 5992 5991 5782 6 5777 5593 5591 5595 5779 5782 6 5778 5595 5596 5599 5780 5782 6 5779 5599 5781 5782 5783 5784 6 5780 5599 5600 5784 5785 5789 6 5779 5780 5783 5992 5777 5778 6 5782 5780 5784 5993 5992 5996 7 5783 5780 5781 5785 5786 5996 5997 6 5784 5781 5786 5787 5788 5789 6 5784 5785 5787 5997 5998 5999 6 5786 5785 5788 6002 5999 6003 6 5787 5785 5789 6009 6003 6199 6 5788 5785 5781 5600 5790 6199 6 5789 5600 5601 5791 5792 6199 6 5790 5601 5792 5793 5794 5603 6 5790 5791 5793 6198 6199 6197 6 5792 5791 5794 6197 6200 6221 6 5793 5791 5603 5795 6221 6219 6 5794 5603 5604 5796 5797 6219 6 5795 5604 5797 5798 5607 5606 6 5795 5796 5798 5799 6218 6219 6 5797 5796 5607 5799 5800 5610 6 5797 5798 5800 5801 5802 6218 7 5799 5798 5610 5609 5801 5805 5806 6 5799 5800 5802 5803 5804 5805 6 5799 5801 5803 6217 6209 6218 6 5802 5801 5804 5823 5824 6217 6 5803 5801 5805 5823 5830 5839 6 5804 5801 5800 5806 5808 5839 5 5805 5800 5609 5807 5808 5 5806 5609 5354 5356 5808 7 5807 5356 5358 5809 5839 5805 5806 6 5808 5358 5810 5838 5839 5886 7 5809 5358 5363 5364 5811 5885 5886 6 5810 5364 5884 5885 5887 5402 6 5665 5666 5813 5814 5815 5816 6 5665 5812 5814 5835 5664 5842 6 5813 5812 5815 5842 5843 5844 6 5814 5812 5816 5819 5820 5844 6 5815 5812 5666 5817 5818 5819 6 5816 5666 5818 5859 5857 5667 6 5816 5817 5819 5822 5857 5854 6 5816 5818 5815 5820 5821 5822 6 5815 5819 5821 5844 5845 5846 6 5820 5819 5822 5852 5849 5846 6 5821 5819 5818 5852 5853 5854 6 5803 5804 5824 5825 5826 5830 5 5803 5823 5825 6216 6217 7 5824 5823 5826 5827 6216 6215 6021 6 5825 5823 5827 5828 5829 5830 6 5825 5826 5828 6019 6020 6021 6 5827 5826 5829 5836 5872 6019 6 5828 5826 5830 5836 5837 5838 6 5829 5826 5823 5804 5838 5839 6 5658 5659 5832 6931 6932 6933 6 5831 5659 5660 5833 5840 6933 6 5832 5660 5661 5662 5834 5840 6 5833 5662 5835 5840 5841 5842 6 5834 5662 5663 5664 5813 5842 6 5828 5829 5837 5872 5873 5883 6 5836 5829 5838 5885 5883 5886 6 5837 5829 5830 5839 5809 5886 6 5838 5830 5809 5808 5805 5804 6 5832 5833 5834 5841 6933 6934 6 5840 5834 5842 6934 6935 5843 6 5841 5834 5835 5813 5814 5843 6 5842 5814 5844 6018 6935 5841 6 5843 5814 5815 5820 5845 6018 6 5844 5820 5846 5847 6018 6940 6 5845 5820 5847 5848 5849 5821 6 5845 5846 5848 6940 6941 6942 6 5847 5846 5849 5850 6945 6942 6 5848 5846 5850 5851 5852 5821 5 5848 5849 5851 6945 6385 6 5850 5849 5852 6103 6104 6385 6 5851 5849 5821 5822 5853 6103 6 5852 5822 5854 5855 6100 6103 6 5853 5822 5855 5856 5857 5818 6 5853 5854 5856 6098 6099 6100 6 5855 5854 5857 5858 6384 6098 6 5856 5854 5858 5859 5817 5818 6 5856 5857 5859 5860 6383 6384 6 5858 5857 5817 5667 5668 5860 6 5859 5668 5669 5861 6383 5858 6 5860 5669 5670 5862 9703 6383 6 5861 5670 5671 5863 9694 9703 6 5862 5671 5672 5864 9694 9695 6 5863 5672 5673 5865 9695 9696 7 5864 5673 5674 5866 9696 5718 9697 5 5865 5674 5675 5867 9697 7 5866 5675 5676 5677 5868 9697 9698 5 5867 5677 5693 5694 9698 5 5693 5678 5679 5870 5692 6 5869 5679 5680 5871 5690 5692 6 5870 5680 5681 5688 5689 5690 6 5828 5836 5873 5874 9736 6019 6 5872 5836 5874 5875 5882 5883 6 5872 5873 5875 5876 9736 6041 6 5874 5873 5876 5877 5878 5882 6 5874 5875 5877 6048 6041 6042 6 5876 5875 5878 5879 6049 6048 6 5877 5875 5879 5880 5881 5882 6 5877 5878 5880 6049 6050 5888 6 5879 5878 5881 5400 5399 5888 6 5880 5878 5882 5884 5887 5400 6 5881 5878 5875 5873 5883 5884 6 5882 5873 5836 5884 5885 5837 6 5882 5883 5885 5811 5881 5887 6 5884 5883 5837 5811 5810 5886 5 5810 5885 5837 5838 5809 5 5881 5884 5811 5402 5400 6 5880 5399 5889 6053 6050 5879 6 5888 5399 5397 5890 5891 6053 6 5889 5397 5891 5892 5893 5396 6 5889 5890 5892 6056 6053 6057 6 5891 5890 5893 6057 6058 6059 6 5892 5890 5396 5894 5895 6059 6 5893 5396 5895 5896 5899 5395 6 5893 5894 5896 5897 6059 6061 6 5895 5894 5897 5898 4889 5899 6 5895 5896 5898 5900 6061 6062 6 5897 5896 4889 4890 5900 5901 7 4889 5896 5894 5395 5393 5372 4888 6 5897 5898 5901 6065 6062 6066 6 5900 5898 4890 4892 5902 6066 6 5901 4892 5903 5904 5905 6066 6 5902 4892 5904 5911 5912 4893 6 5902 5903 5905 5906 5907 5911 6 5902 5904 5906 6066 6070 6067 7 5905 5904 5907 5908 6075 6072 6070 6 5906 5904 5908 5909 5910 5911 5 5906 5907 5909 5934 6075 7 5908 5907 5910 5932 5929 5933 5934 6 5909 5907 5911 5932 9752 5915 6 5910 5907 5904 5903 5912 5915 6 5911 5903 4893 5913 5914 5915 6 5912 4893 4894 4896 4899 5914 6 5913 4899 5912 5915 5916 5917 6 5912 5914 5916 5911 9752 5910 6 5915 5914 5917 9752 9755 9758 6 5916 5914 4899 4900 5918 9758 7 5917 4900 4902 3671 3951 5919 9758 6 5918 3951 3949 5920 9755 9758 5 5919 3949 3948 5921 9755 6 5920 3948 5922 5930 5931 9755 6 5921 3948 3946 3962 5923 5930 6 5922 3962 3963 5924 5925 5930 6 5923 3963 3965 5925 5926 5942 6 5923 5924 5926 5927 5929 5930 6 5925 5924 5927 5928 5941 5942 5 5925 5926 5928 5929 5933 7 5927 5926 5935 5933 5936 5940 5941 7 5925 5927 5930 5931 5932 5909 5933 6 5925 5929 5931 5923 5922 5921 6 5930 5929 5921 5932 9752 9755 5 5931 5929 5909 5910 9752 6 5909 5929 5934 5935 5928 5927 6 5909 5933 5935 6074 6075 5908 6 5934 5933 5928 5936 5937 6074 6 5935 5928 5937 5938 5939 5940 5 5935 5936 5938 6074 6076 6 5937 5936 5939 6076 6077 6086 6 5938 5936 5940 6087 6086 6091 7 5939 5936 5928 5941 5944 6091 5946 5 5940 5928 5926 5942 5944 6 5941 5926 5924 3965 5943 5944 7 5942 3965 3966 5944 5945 3135 5947 6 5942 5943 5941 5940 5945 5946 5 5944 5943 5946 3134 3135 6 5944 5945 3134 6091 5940 3136 6 3135 5943 2093 2092 5948 3966 6 2092 5947 3966 3967 2488 2489 6 5754 5756 5950 5752 5751 6121 6 5949 5756 5951 6166 6120 6121 6 5950 5756 5757 5952 6166 6164 6 5951 5757 5759 5953 5954 6164 6 5952 5759 5954 5955 5956 5957 6 5952 5953 5955 6162 6161 6164 6 5954 5953 5956 5960 5967 6162 6 5955 5953 5957 5958 5959 5960 6 5956 5953 5759 5760 5763 5958 6 5957 5763 5956 5959 5963 5988 6 5956 5958 5960 5961 5962 5963 6 5956 5959 5961 5964 5967 5955 6 5960 5959 5962 5964 5965 5982 6 5961 5959 5963 5983 5982 5984 6 5962 5959 5958 5987 5984 5988 6 5960 5961 5965 5966 5967 5968 6 5964 5961 5966 5982 5980 5971 6 5964 5965 5968 5969 5970 5971 6 5960 5964 5955 5968 6163 6162 7 5967 5964 5966 5969 6156 6157 6163 6 5968 5966 5970 6447 6445 6156 6 5969 5966 5971 5972 6447 6448 6 5970 5966 5972 5973 5965 5980 6 5970 5971 5973 5974 5975 6448 6 5972 5971 5974 5978 5979 5980 6 5972 5973 5975 5976 5977 5978 6 5972 5974 5976 6448 6449 6450 6 5975 5974 5977 6450 6608 6609 6 5976 5974 5978 6609 6612 6613 6 5977 5974 5973 5979 6613 6614 6 5978 5973 5980 5981 6640 6614 6 5979 5973 5981 5982 5965 5971 6 5979 5980 5982 5983 6640 6641 6 5981 5980 5983 5962 5961 5965 6 5981 5982 5962 5984 5985 6641 6 5983 5962 5985 5986 5987 5963 6 5983 5984 5986 6643 6641 6168 6 5985 5984 5987 5994 6167 6168 6 5986 5984 5963 5988 5989 5994 6 5987 5963 5958 5989 5764 5763 6 5987 5988 5764 5990 5993 5994 6 5989 5764 5765 5991 5992 5993 5 5990 5765 5992 5777 5776 6 5990 5991 5777 5993 5783 5782 7 5990 5992 5783 5989 5994 5995 5996 6 5989 5993 5995 5986 5987 6167 6 5994 5993 5996 5997 5998 6167 5 5995 5993 5783 5784 5997 5 5995 5996 5998 5784 5786 7 5995 5997 5786 5999 6000 6169 6167 6 5998 5786 6000 6001 6002 5787 5 5998 5999 6001 6169 6170 6 6000 5999 6002 6170 6171 6005 6 6001 5999 5787 6003 6004 6005 6 6002 5787 6004 6008 6009 5788 6 6002 6003 6005 6006 6007 6008 6 6002 6004 6006 6171 6001 6172 6 6005 6004 6007 6010 6172 6173 6 6006 6004 6008 6010 6011 6015 6 6007 6004 6003 6009 6017 6015 6 6008 6003 5788 6198 6017 6199 6 6006 6007 6011 6012 6179 6173 6 6010 6007 6012 6013 6014 6015 6 6010 6011 6013 6180 6179 6186 6 6012 6011 6014 6190 6187 6186 6 6013 6011 6015 6016 6190 6191 6 6014 6011 6016 6017 6008 6007 6 6014 6015 6017 6191 6194 6195 6 6016 6015 6008 6198 6195 6009 6 5843 5844 5845 6937 6935 6940 6 5827 5828 6020 9736 6038 5872 6 5827 6019 6021 6022 6023 6038 6 5827 6020 6022 6215 5825 6222 6 6021 6020 6023 6024 6025 6222 6 6022 6020 6024 6037 6028 6038 6 6022 6023 6025 6026 6027 6028 6 6022 6024 6026 6222 6225 6223 6 6025 6024 6027 6225 6226 6032 6 6026 6024 6028 6029 6031 6032 6 6027 6024 6029 6030 6037 6023 6 6027 6028 6030 6031 6033 6034 6 6029 6028 6034 6035 6036 6037 6 6027 6029 6032 6033 6247 6239 6 6027 6031 6226 6026 6227 6239 6 6031 6029 6034 6247 6246 6248 6 6033 6029 6030 6035 6248 6249 6 6034 6030 6036 6249 6263 6264 6 6035 6030 6037 6039 6040 6264 6 6036 6030 6028 6023 6038 6039 6 6037 6023 6039 9736 6019 6020 6 6037 6038 6036 6040 6041 9736 7 6036 6039 6041 6042 6043 6265 6264 6 6040 6039 6042 9736 5874 5876 6 6040 6041 6043 6044 6048 5876 5 6040 6042 6044 6045 6265 6 6043 6042 6045 6046 6047 6048 7 6043 6044 6046 6262 6265 6261 6266 6 6045 6044 6047 6269 6266 6280 6 6046 6044 6048 6049 6051 6280 6 6047 6044 6042 6049 5877 5876 6 6047 6048 5877 5879 6050 6051 6 6049 5879 6051 6052 6053 5888 6 6049 6050 6052 6054 6280 6047 6 6051 6050 6053 6054 6055 6056 6 6052 6050 5888 5889 6056 5891 7 6051 6052 6055 6279 6280 6278 6281 6 6054 6052 6056 6283 6281 6284 6 6055 6052 6053 5891 6057 6284 6 6056 5891 5892 6058 6060 6284 6 6057 5892 6059 6060 6287 6288 6 6058 5892 5893 5895 6061 6288 6 6057 6058 6284 6285 6286 6287 6 6059 5895 5897 6062 6063 6288 6 6061 5897 6063 6064 6065 5900 7 6061 6062 6064 6288 6291 6289 6292 5 6063 6062 6065 6292 6068 6 6064 6062 5900 6066 6067 6068 6 6065 5900 5901 5902 5905 6067 6 6065 6066 6068 6069 6070 5905 7 6065 6067 6069 6292 6064 6293 6294 5 6068 6067 6070 6071 6294 6 6069 6067 5905 6071 6072 5906 7 6069 6070 6072 6073 6296 6294 6297 6 6071 6070 6073 6074 6075 5906 6 6071 6072 6074 6297 6078 6076 7 6073 6072 6075 5934 5935 5937 6076 5 6074 6072 5934 5908 5906 6 6074 5937 5938 6077 6078 6073 6 6076 5938 6078 6079 6086 6083 6 6076 6077 6079 6080 6297 6073 6 6078 6077 6080 6081 6082 6083 6 6078 6079 6081 6297 6298 6301 6 6080 6079 6082 6301 6302 6314 6 6081 6079 6083 6084 6313 6314 6 6082 6079 6084 6085 6086 6077 7 6082 6083 6085 6088 6313 6315 6318 6 6084 6083 6086 6087 6088 6089 6 6085 6083 6087 5939 5938 6077 6 6085 6086 5939 6089 6090 6091 6 6084 6085 6089 6094 3769 6318 7 6088 6085 6087 6090 3137 6092 6094 5 6089 6087 6091 3136 3137 6 6090 6087 5939 5940 5946 3136 6 6089 3137 3138 6093 3768 6094 7 6092 3138 3768 3766 2085 2084 9776 5 6092 3768 3769 6088 6089 6 5724 5725 6096 6383 9702 9703 6 6095 5725 6097 6098 6383 6384 5 6096 5725 5726 5730 6098 7 6096 6097 5730 6099 6384 5856 5855 5 6098 5730 5731 6100 5855 7 6099 5731 6101 6102 6103 5855 5853 5 6100 5731 5732 5733 6102 7 6101 5733 6100 6103 6104 6105 5735 6 6100 6102 6104 5853 5852 5851 6 6103 6102 6105 5851 6385 6386 5 6104 6102 5735 6106 6386 7 6105 5735 5736 6107 6386 6387 6109 6 6106 5736 5739 5741 6108 6109 6 6107 5741 6109 6110 6111 5743 6 6107 6108 6110 6387 6106 6388 6 6109 6108 6111 6388 6389 6390 6 6110 6108 5743 6112 6393 6390 6 6111 5743 5744 6113 6115 6393 6 6112 5744 6114 6115 6116 6117 6 6113 5744 6120 6117 6121 5745 6 6112 6113 6116 6393 9737 9738 6 6115 6113 6117 6118 6122 9738 6 6116 6113 6118 6119 6120 6114 6 6116 6117 6119 6122 6123 6165 5 6118 6117 6120 6166 6165 6 6119 6117 6114 6121 6166 5950 7 6120 6114 5745 5750 5751 5949 5950 6 6116 6118 6123 6124 6131 9738 6 6122 6118 6124 6125 6165 6160 6 6122 6123 6125 6126 6127 6131 6 6124 6123 6126 6152 6160 6158 6 6124 6125 6127 6128 6151 6152 6 6124 6126 6128 6129 6130 6131 6 6127 6126 6129 6150 6149 6151 6 6127 6128 6130 6150 6137 6134 6 6127 6129 6131 6132 6133 6134 6 6127 6130 6132 9738 6122 6124 6 6131 6130 6133 6398 9737 9738 6 6132 6130 6134 6135 6397 6398 6 6133 6130 6135 6136 6137 6129 6 6133 6134 6136 6397 6399 6400 6 6135 6134 6137 6138 6400 6401 6 6136 6134 6138 6139 6150 6129 6 6136 6137 6139 6140 6401 6402 6 6138 6137 6140 6141 6148 6150 6 6138 6139 6141 6142 6402 6403 6 6140 6139 6142 6143 6144 6148 6 6140 6141 6143 6403 6404 6405 6 6142 6141 6144 6145 6405 6436 6 6143 6141 6145 6146 6147 6148 6 6143 6144 6146 6437 6436 6438 6 6145 6144 6147 6438 6439 6440 6 6146 6144 6148 6149 6440 6441 6 6147 6144 6141 6139 6149 6150 6 6147 6148 6150 6128 6151 6441 6 6149 6148 6139 6137 6129 6128 6 6149 6128 6126 6152 6153 6441 6 6151 6126 6125 6153 6154 6158 6 6151 6152 6154 6155 6441 6442 6 6153 6152 6155 6156 6157 6158 6 6153 6154 6156 6444 6442 6445 6 6155 6154 6157 5969 6445 5968 6 6156 6154 6158 6159 5968 6163 6 6157 6154 6152 6159 6160 6125 6 6157 6158 6160 6161 6162 6163 6 6159 6158 6125 6161 6123 6165 6 6159 6160 6162 5954 6164 6165 6 6159 6161 6163 5967 5955 5954 5 6159 6162 5967 6157 5968 6 5954 6161 6165 6166 5951 5952 7 6164 6161 6166 6119 6118 6123 6160 6 6164 6165 6119 6120 5950 5951 6 5994 5995 5986 6168 6169 5998 6 5986 6167 6169 6643 5985 9783 6 6168 6167 5998 6000 6170 9783 7 6169 6000 6001 6171 6789 9783 9782 7 6170 6001 6005 6172 6788 6786 6789 6 6171 6005 6006 6173 6174 6788 6 6172 6006 6174 6175 6010 6179 6 6172 6173 6175 6176 6784 6788 6 6174 6173 6176 6177 6178 6179 6 6174 6175 6177 6782 6781 6784 6 6176 6175 6178 9796 6782 9797 6 6177 6175 6179 6180 6181 9796 6 6178 6175 6180 6012 6010 6173 6 6178 6179 6181 6182 6186 6012 6 6178 6180 6182 6183 9796 9799 6 6181 6180 6183 6184 6185 6186 6 6181 6182 6184 6362 6645 9799 6 6183 6182 6185 6362 6363 6367 6 6184 6182 6186 6187 6188 6367 6 6185 6182 6180 6187 6012 6013 6 6185 6186 6188 6189 6190 6013 6 6185 6187 6189 6367 6368 6369 6 6188 6187 6190 6369 6372 6192 6 6189 6187 6013 6014 6191 6192 6 6190 6014 6016 6192 6193 6194 6 6190 6191 6193 6372 6189 6373 6 6192 6191 6194 6382 6373 6203 6 6193 6191 6016 6195 6196 6203 6 6194 6016 6196 6197 6198 6017 6 6194 6195 6197 6200 6201 6203 6 6196 6195 6198 5792 5793 6200 6 6197 6195 6017 6009 6199 5792 6 6198 6009 5792 5790 5789 5788 6 6197 5793 6196 6201 6202 6221 6 6196 6200 6202 6203 6204 6205 6 6201 6200 6205 6206 6220 6221 6 6196 6201 6204 6382 6193 6194 6 6203 6201 6205 6382 6459 6381 6 6204 6201 6202 6206 6207 6459 6 6205 6202 6207 6208 6209 6220 6 6205 6206 6208 6210 6211 6459 6 6207 6206 6209 6210 6214 6217 6 6208 6206 5802 6217 6218 6220 6 6207 6208 6211 6212 6213 6214 6 6207 6210 6212 6456 6458 6459 7 6211 6210 6213 6223 6224 6454 6456 5 6212 6210 6214 6215 6223 6 6213 6210 6208 6215 6216 6217 7 6213 6214 6216 5825 6021 6222 6223 5 6215 6214 6217 5824 5825 7 6216 6214 5824 5803 5802 6209 6208 6 5802 6209 5799 5797 6219 6220 6 5797 6218 6220 6221 5794 5795 6 6219 6218 6209 6206 6202 6221 6 6219 6220 6202 6200 5793 5794 5 6215 6021 6022 6025 6223 7 6215 6222 6213 6212 6224 6225 6025 7 6212 6223 6225 6454 6231 6226 6228 5 6224 6223 6025 6026 6226 6 6225 6026 6032 6227 6228 6224 6 6226 6032 6228 6229 6238 6239 6 6226 6227 6229 6230 6231 6224 6 6228 6227 6230 6237 6234 6238 6 6228 6229 6231 6232 6233 6234 6 6228 6230 6232 6454 6224 6455 6 6231 6230 6233 6455 6460 6461 6 6232 6230 6234 6235 6461 6462 6 6233 6230 6235 6236 6237 6229 6 6233 6234 6236 6462 6463 6471 6 6235 6234 6237 6473 6471 6476 6 6236 6234 6229 6238 6476 6241 6 6237 6229 6227 6239 6240 6241 6 6238 6227 6240 6247 6031 6032 6 6238 6239 6241 6242 6243 6247 6 6238 6240 6242 6476 6237 6477 6 6241 6240 6243 6244 6477 6479 6 6242 6240 6244 6245 6246 6247 6 6242 6243 6245 6481 6479 6482 6 6244 6243 6246 6482 6253 6251 6 6245 6243 6247 6033 6248 6251 6 6246 6243 6240 6239 6031 6033 6 6246 6033 6034 6249 6250 6251 6 6248 6034 6035 6250 6263 6255 6 6248 6249 6251 6252 6254 6255 6 6248 6250 6252 6253 6245 6246 6 6251 6250 6253 6254 6484 6485 6 6251 6252 6482 6245 6483 6484 6 6252 6250 6255 6256 6257 6485 6 6254 6250 6256 6263 6260 6249 6 6254 6255 6257 6258 6259 6260 6 6254 6256 6258 6485 6493 6494 6 6257 6256 6259 6494 6495 6496 7 6258 6256 6260 6261 6496 6273 6267 6 6259 6256 6261 6262 6263 6255 6 6259 6260 6262 6045 6266 6267 6 6261 6260 6263 6264 6265 6045 6 6262 6260 6264 6255 6249 6035 6 6262 6263 6265 6035 6040 6036 5 6262 6264 6045 6043 6040 6 6045 6261 6267 6268 6269 6046 6 6261 6266 6268 6272 6273 6259 6 6267 6266 6269 6270 6271 6272 6 6268 6266 6046 6270 6279 6280 6 6268 6269 6271 6277 6278 6279 6 6268 6270 6272 6275 6276 6277 6 6268 6271 6267 6273 6274 6275 6 6267 6272 6274 6496 6259 6497 6 6273 6272 6275 6500 6497 6501 6 6274 6272 6271 6276 6501 6502 6 6275 6271 6277 6502 6503 6504 6 6276 6271 6270 6278 6504 6505 7 6277 6270 6279 6054 6281 6282 6505 5 6278 6270 6269 6280 6054 6 6279 6269 6046 6054 6051 6047 5 6278 6054 6282 6283 6055 6 6278 6281 6283 6506 6505 6507 6 6282 6281 6055 6284 6507 6285 6 6283 6055 6056 6057 6060 6285 6 6284 6060 6286 6507 6283 6508 7 6285 6060 6287 6508 6328 6511 6290 6 6286 6060 6058 6288 6289 6290 6 6287 6058 6059 6061 6063 6289 5 6287 6288 6290 6291 6063 5 6287 6289 6291 6328 6286 7 6290 6289 6063 6292 6326 6327 6328 6 6291 6063 6064 6068 6293 6326 6 6292 6068 6294 6295 6325 6326 6 6293 6068 6069 6295 6296 6071 6 6293 6294 6296 6299 6324 6325 6 6295 6294 6071 6297 6298 6299 6 6296 6071 6073 6078 6080 6298 6 6297 6080 6296 6299 6300 6301 5 6296 6298 6300 6324 6295 6 6299 6298 6301 6303 6323 6324 6 6300 6298 6080 6081 6302 6303 6 6301 6081 6303 6304 6308 6314 6 6301 6302 6304 6305 6323 6300 6 6303 6302 6305 6306 6307 6308 6 6303 6304 6306 6323 6337 6338 6 6305 6304 6307 6338 6341 6342 6 6306 6304 6308 6309 6342 6343 6 6307 6304 6302 6309 6310 6314 6 6307 6308 6310 6311 6343 6346 6 6309 6308 6311 6312 6313 6314 6 6309 6310 6312 6321 6322 6346 6 6311 6310 6313 6315 6316 6321 6 6312 6310 6314 6082 6084 6315 6 6313 6310 6082 6081 6302 6308 6 6313 6084 6312 6316 6317 6318 6 6312 6315 6317 6319 6320 6321 6 6316 6315 6318 3769 1571 6319 5 6317 6315 3769 6084 6088 5 6317 1571 1572 6320 6316 7 6319 1572 1573 6316 6321 6322 6360 5 6316 6320 6322 6312 6311 7 6321 6320 6311 6347 6346 6348 6360 6 6303 6305 6300 6324 6335 6337 7 6300 6323 6299 6295 6325 6336 6335 6 6295 6324 6293 6326 6336 6331 6 6293 6325 6292 6291 6327 6331 6 6291 6326 6328 6329 6330 6331 6 6291 6327 6329 6511 6286 6290 6 6328 6327 6330 6510 6511 6519 7 6329 6327 6331 6332 6333 6519 6518 6 6330 6327 6332 6336 6325 6326 6 6330 6331 6333 6334 6335 6336 5 6330 6332 6334 6518 6520 6 6333 6332 6335 6520 6528 6529 7 6334 6332 6336 6324 6323 6337 6529 5 6335 6332 6331 6325 6324 6 6335 6323 6305 6338 6339 6529 6 6337 6305 6306 6339 6340 6341 6 6337 6338 6340 6530 6527 6529 5 6339 6338 6341 6545 6530 6 6340 6338 6306 6342 6546 6545 6 6341 6306 6307 6343 6344 6546 6 6342 6307 6344 6345 6346 6309 6 6342 6343 6345 6546 6543 6547 6 6344 6343 6346 6347 6549 6547 6 6345 6343 6347 6322 6311 6309 6 6345 6346 6322 6348 6349 6549 6 6347 6322 6349 6350 6359 6360 6 6347 6348 6350 6351 6550 6549 6 6349 6348 6351 6352 6353 6359 6 6349 6350 6352 6552 6550 6553 6 6351 6350 6353 6354 6355 6553 6 6352 6350 6354 1589 2476 6359 7 6352 6353 6355 6356 1594 1590 1589 6 6352 6354 6356 6357 6553 6554 5 6355 6354 6357 6358 1594 6 6355 6356 6358 6554 6555 3971 6 6357 6356 1594 3971 3970 1595 6 2476 6353 6350 6348 6360 6361 6 6359 6348 6361 1573 6320 6322 5 6359 6360 1573 2475 2476 6 6183 6184 6363 6364 6644 6645 6 6362 6184 6364 6365 6366 6367 6 6362 6363 6365 6644 6648 6649 6 6364 6363 6366 9727 9673 6649 6 6365 6363 6367 9727 9728 6368 6 6366 6363 6184 6185 6188 6368 6 6367 6188 6369 6370 9728 6366 6 6368 6188 6189 6370 6371 6372 6 6368 6369 6371 9728 9729 9730 6 6370 6369 6372 6374 6375 9730 6 6371 6369 6189 6192 6373 6374 6 6372 6192 6374 6382 6380 6193 6 6372 6373 6371 6375 6376 6380 6 6371 6374 6376 6377 6467 9730 6 6375 6374 6377 6378 6379 6380 5 6375 6376 6378 9693 6467 7 6377 6376 6379 6457 6455 6460 9693 6 6378 6376 6380 6381 6457 6458 6 6379 6376 6381 6382 6373 6374 6 6379 6380 6382 6459 6458 6204 6 6381 6380 6373 6193 6203 6204 7 6095 6096 6384 9703 5861 5860 5858 5 6383 6096 6098 5856 5858 6 5851 6104 6386 6945 5850 6946 7 6385 6104 6105 6106 6387 6946 6947 5 6386 6106 6109 6388 6947 6 6387 6109 6110 6389 6947 6948 6 6388 6110 6390 6391 6948 6949 6 6389 6110 6391 6392 6393 6111 6 6389 6390 6392 6394 6395 6949 6 6391 6390 6393 6394 9737 6398 6 6392 6390 6111 6112 6115 9737 6 6391 6392 6395 6396 6397 6398 6 6391 6394 6396 6949 6950 6951 6 6395 6394 6397 6951 6952 6399 6 6396 6394 6398 6133 6135 6399 6 6397 6394 6133 6132 9737 6392 6 6397 6135 6400 6952 6396 6953 6 6399 6135 6136 6401 6953 6954 6 6400 6136 6138 6402 6954 6960 6 6401 6138 6140 6403 6960 6410 6 6402 6140 6142 6404 6408 6410 6 6403 6142 6405 6406 6407 6408 6 6404 6142 6143 6406 6436 6434 6 6404 6405 6407 6431 6429 6434 6 6404 6406 6408 6409 6428 6429 6 6404 6407 6409 6403 6410 6411 6 6408 6407 6411 6412 6413 6428 6 6403 6408 6411 6959 6960 6402 6 6410 6408 6409 6412 6959 6961 6 6411 6409 6413 6414 6963 6961 6 6412 6409 6414 6415 6427 6428 6 6412 6413 6415 6416 6963 6964 6 6414 6413 6416 6417 6418 6427 6 6414 6415 6417 6558 6559 6964 6 6416 6415 6418 6419 6558 6565 6 6417 6415 6419 6420 6427 6424 6 6417 6418 6420 6421 6573 6565 6 6419 6418 6421 6422 6423 6424 6 6419 6420 6422 6573 6572 6574 6 6421 6420 6423 6580 6577 6574 6 6422 6420 6424 6425 6580 6581 6 6423 6420 6425 6426 6427 6418 6 6423 6424 6426 6584 6581 6430 6 6425 6424 6427 6428 6429 6430 6 6426 6424 6418 6415 6413 6428 6 6427 6413 6409 6407 6426 6429 6 6426 6428 6407 6430 6431 6406 6 6426 6429 6431 6432 6584 6425 6 6430 6429 6406 6432 6433 6434 6 6430 6431 6433 6584 6585 6586 6 6432 6431 6434 6435 6589 6586 6 6433 6431 6435 6436 6405 6406 6 6433 6434 6436 6437 6589 6590 6 6435 6434 6405 6437 6145 6143 6 6435 6436 6145 6438 6590 6591 6 6437 6145 6146 6439 6591 6592 6 6438 6146 6440 6595 6592 6443 6 6439 6146 6147 6441 6442 6443 6 6440 6147 6149 6151 6153 6442 6 6441 6153 6440 6443 6444 6155 6 6440 6442 6444 6595 6439 6453 6 6443 6442 6155 6445 6446 6453 6 6444 6155 6446 6447 5969 6156 6 6444 6445 6447 6449 6452 6453 6 6446 6445 5969 5970 6448 6449 5 6447 5970 5972 5975 6449 7 6448 5975 6447 6450 6451 6452 6446 7 6449 5975 5976 6451 6607 6598 6608 6 6449 6450 6452 6596 6597 6598 5 6449 6451 6446 6453 6596 6 6446 6452 6595 6443 6444 6596 5 6212 6224 6231 6455 6456 7 6454 6231 6456 6457 6378 6232 6460 6 6454 6455 6457 6458 6211 6212 5 6456 6455 6378 6379 6458 6 6457 6379 6456 6211 6459 6381 6 6211 6458 6207 6381 6204 6205 5 6455 6232 6461 9693 6378 6 6460 6232 6233 6462 6465 9693 6 6461 6233 6235 6463 6464 6465 6 6462 6235 6464 6469 6470 6471 6 6462 6463 6465 6466 6468 6469 6 6462 6464 6461 6466 6467 9693 6 6465 6464 6467 6468 9731 9732 7 6465 6466 9693 6377 6375 9730 9731 6 6466 6464 6469 7509 7510 9732 7 6468 6464 6463 6470 7507 7509 7506 6 6469 6463 6471 6472 7506 7505 6 6470 6463 6235 6472 6473 6236 6 6470 6471 6473 6474 7504 7505 6 6472 6471 6236 6474 6475 6476 7 6472 6473 6475 7503 7504 9692 9780 6 6474 6473 6476 6477 6478 9692 6 6475 6473 6236 6237 6241 6477 6 6476 6241 6242 6475 6478 6479 7 6475 6477 6479 6480 9692 9778 9779 6 6478 6477 6242 6480 6481 6244 6 6478 6479 6481 6487 9705 9778 6 6480 6479 6244 6482 6486 6487 6 6481 6244 6245 6253 6483 6486 5 6482 6253 6484 6486 6489 7 6483 6253 6252 6485 6489 6490 6491 7 6484 6252 6254 6257 6491 6492 6493 6 6482 6483 6481 6487 6488 6489 5 6481 6486 6488 9705 6480 7 6487 6486 6489 9704 2194 2195 9705 6 6488 6486 6483 6484 6490 9704 6 6489 6484 6491 2251 2252 9704 6 6490 6484 6485 6492 2251 9706 6 6491 6485 6493 9706 3335 9707 5 6492 6485 6257 6494 9707 6 6493 6257 6258 6495 9707 6499 6 6494 6258 6496 6497 6498 6499 5 6495 6258 6259 6273 6497 6 6496 6273 6495 6498 6500 6274 6 6495 6497 6499 2511 2512 6500 7 6495 6498 2511 3334 9707 3881 6494 6 2512 6498 6497 6274 6501 9710 6 6500 6274 6275 6502 9709 9710 6 6501 6275 6276 6503 9708 9709 6 6502 6276 6504 6512 9708 9711 6 6503 6276 6277 6505 6506 6512 5 6504 6277 6506 6282 6278 7 6504 6505 6282 6507 6512 6513 6509 6 6506 6282 6283 6285 6508 6509 6 6507 6285 6286 6509 6510 6511 6 6507 6508 6510 6513 6506 6514 7 6509 6508 6511 6329 6514 6515 6519 5 6510 6508 6329 6328 6286 6 6503 6504 6506 6513 9711 9717 5 6512 6506 6509 6514 9717 7 6513 6509 6510 6515 6516 9717 9718 6 6514 6510 6516 6517 6518 6519 6 6514 6515 6517 9718 9719 6522 6 6516 6515 6518 6520 6521 6522 6 6517 6515 6519 6330 6333 6520 5 6518 6515 6510 6329 6330 7 6518 6333 6334 6517 6521 6525 6528 6 6517 6520 6522 6523 6524 6525 7 6517 6521 6523 2214 9719 6516 2213 5 6522 6521 6524 2213 3348 7 6523 6521 6525 6526 3348 3347 6532 6 6524 6521 6520 6526 6527 6528 6 6524 6525 6527 6530 6531 6532 6 6526 6525 6528 6530 6339 6529 5 6527 6525 6520 6334 6529 6 6528 6334 6335 6339 6527 6337 7 6526 6527 6531 6340 6545 6339 6534 6 6526 6530 6532 3863 6533 6534 5 6526 6531 3863 3347 6524 6 3863 6531 6534 6535 6536 6716 6 6533 6531 6535 6544 6545 6530 6 6533 6534 6536 6537 6544 6541 6 6533 6535 6537 6538 6715 6716 6 6536 6535 6538 6539 6540 6541 7 6536 6537 6539 6714 3887 3886 6715 6 6538 6537 6540 6714 6718 6719 6 6539 6537 6541 6542 6719 6708 6 6540 6537 6542 6543 6544 6535 6 6540 6541 6543 6547 6548 6708 6 6542 6541 6544 6546 6344 6547 6 6543 6541 6535 6534 6545 6546 6 6544 6534 6546 6341 6340 6530 6 6544 6545 6543 6341 6342 6344 6 6543 6344 6542 6548 6549 6345 6 6542 6547 6549 6550 6551 6708 6 6548 6547 6345 6347 6550 6349 6 6548 6549 6551 6552 6351 6349 6 6548 6550 6552 6705 6707 6708 6 6551 6550 6351 6553 6554 6705 5 6552 6351 6352 6355 6554 6 6553 6355 6357 6555 6552 6705 7 6554 6357 3971 6705 6706 9747 3491 6 3969 1597 1598 6557 4038 3968 6 6556 1598 4038 3764 612 611 6 6416 6417 6559 6560 6564 6565 6 6416 6558 6560 6561 6964 6965 6 6559 6558 6561 6562 6563 6564 6 6559 6560 6562 6965 6966 6967 6 6561 6560 6563 6985 6983 6967 6 6562 6560 6564 6985 6986 6567 6 6563 6560 6558 6565 6566 6567 6 6564 6558 6417 6566 6573 6419 6 6564 6565 6567 6568 6569 6573 6 6564 6566 6568 6986 6563 6987 6 6567 6566 6569 6570 6990 6987 6 6568 6566 6570 6571 6572 6573 6 6568 6569 6571 6997 6990 6998 6 6570 6569 6572 6575 7001 6998 6 6571 6569 6573 6421 6574 6575 6 6572 6569 6566 6565 6419 6421 6 6572 6421 6575 6576 6577 6422 6 6572 6574 6576 7003 7001 6571 6 6575 6574 6577 6578 7003 7004 6 6576 6574 6578 6579 6580 6422 6 6576 6577 6579 7004 7005 7006 6 6578 6577 6580 7006 7007 6582 6 6579 6577 6422 6423 6581 6582 6 6580 6423 6582 6583 6584 6425 6 6580 6581 6583 7007 6579 7008 6 6582 6581 6584 6720 7008 6585 6 6583 6581 6425 6430 6432 6585 6 6584 6432 6586 6587 6720 6583 6 6585 6432 6587 6588 6589 6433 6 6585 6586 6588 6720 6721 6728 6 6587 6586 6589 6728 6729 6730 6 6588 6586 6433 6435 6590 6730 6 6589 6435 6437 6591 6730 6731 6 6590 6437 6438 6592 6593 6731 6 6591 6438 6593 6594 6595 6439 6 6591 6592 6594 6731 6732 6733 7 6593 6592 6595 6600 6733 6597 6596 6 6594 6592 6439 6443 6453 6596 6 6595 6453 6452 6451 6597 6594 6 6596 6451 6598 6599 6600 6594 6 6597 6451 6599 6606 6607 6450 6 6597 6598 6600 6601 6602 6606 5 6597 6599 6601 6733 6594 6 6600 6599 6602 6603 6734 6733 6 6601 6599 6603 6604 6605 6606 7 6601 6602 6604 6734 6735 6736 6737 5 6603 6602 6605 6737 6738 7 6604 6602 6606 6738 6739 6748 6745 6 6605 6602 6599 6598 6607 6748 6 6606 6598 6450 6608 6747 6748 6 6607 6450 5976 6609 6610 6747 6 6608 5976 5977 6610 6611 6612 6 6608 6609 6611 6747 6746 6749 6 6610 6609 6612 6619 6620 6749 6 6611 6609 5977 6613 6616 6619 6 6612 5977 5978 6614 6615 6616 6 6613 5978 6615 6639 6640 5979 6 6613 6614 6616 6617 6638 6639 6 6613 6615 6617 6618 6619 6612 6 6616 6615 6618 6636 6637 6638 6 6616 6617 6619 6621 6622 6636 6 6616 6618 6612 6611 6620 6621 6 6611 6619 6621 6750 6749 6626 6 6620 6619 6618 6622 6623 6626 6 6621 6618 6623 6624 6635 6636 6 6621 6622 6624 6625 6626 6627 6 6623 6622 6625 6633 6634 6635 6 6623 6624 6627 6628 6632 6633 6 6621 6623 6627 6750 6620 6751 6 6626 6623 6625 6628 6629 6751 6 6627 6625 6629 6630 6631 6632 6 6627 6628 6630 6756 6753 6751 6 6629 6628 6631 6756 6757 6758 6 6630 6628 6632 6758 6766 6767 6 6631 6628 6625 6633 6767 6768 6 6632 6625 6624 6634 6768 6769 6 6633 6624 6635 6769 6770 6771 6 6634 6624 6622 6636 9785 6771 6 6635 6622 6618 6617 6637 9785 6 6636 6617 6638 6785 6783 9785 6 6637 6617 6615 6639 9777 6785 6 6638 6615 6614 6640 9777 6642 6 6639 6614 5979 5981 6641 6642 6 6640 5981 5983 6642 6643 5985 7 6640 6641 6643 9777 6639 6787 9782 6 6642 6641 5985 6168 9782 9783 6 6362 6364 6645 6646 6647 6648 6 6362 6644 6183 6646 9724 9799 6 6645 6644 6647 9723 9724 6655 6 6646 6644 6648 6652 6654 6655 6 6647 6644 6364 6649 6650 6652 6 6648 6364 6650 6651 9673 6365 6 6648 6649 6651 6652 6653 9670 6 6650 6649 9670 9671 9672 9673 6 6648 6650 6653 6647 6654 3173 6 6652 6650 9670 9691 3172 3173 6 6647 6652 3173 6655 3450 3175 6 6647 6654 3450 6656 9723 6646 6 6655 3450 6657 6658 9721 9723 6 6656 3450 6658 3179 6659 6667 6 6656 6657 6667 6668 6669 9721 6 6657 3179 6660 6663 6664 6667 6 6659 3179 3178 6661 6662 6663 6 6660 3178 3180 2858 2859 6662 5 6660 6661 6663 6666 2859 6 6660 6662 6659 6664 6665 6666 6 6659 6663 6665 6667 6668 6672 7 6664 6663 6666 6672 6673 4564 4563 6 6665 6663 6662 4563 6674 2859 5 6659 6664 6668 6658 6657 7 6667 6664 6658 6669 6670 6671 6672 6 6658 6668 6670 6774 6775 9721 6 6669 6668 6671 6773 6772 6774 6 6670 6668 6672 6673 6790 6773 5 6671 6668 6664 6665 6673 5 6672 6665 4564 6671 6790 6 4563 6666 4561 6675 2860 2859 6 4561 6674 2860 6676 4560 9792 6 6675 2860 2853 2854 6677 9792 6 6676 2854 6678 6679 6681 9792 5 6677 2854 6679 6680 2855 6 6677 6678 6680 6681 6682 6683 6 6679 6678 6685 6683 6686 2855 6 6677 6679 6682 9750 9761 9792 6 6681 6679 6683 5156 5157 9750 6 6682 6679 5156 6684 6685 6680 6 5156 6683 6685 6692 6693 6694 6 6684 6683 6680 6686 6687 6692 6 6685 6680 6687 6688 6689 2855 6 6685 6686 6688 6692 6696 6699 6 6687 6686 6689 6690 6699 6700 6 6688 6686 6690 6691 2856 2855 6 6688 6689 6691 6700 6702 2551 5 6690 6689 2856 2550 2551 6 6685 6687 6684 6693 6695 6696 6 6684 6692 6694 4523 4522 6695 5 6684 6693 4523 4532 5156 6 4522 6693 6692 6696 6697 6704 6 6695 6692 6687 6697 6698 6699 7 6695 6696 6698 6703 3505 3506 6704 6 6697 6696 6699 6700 6701 6703 5 6698 6696 6687 6688 6700 7 6699 6688 6690 6698 6701 2222 6702 6 6698 6700 2222 64 65 6703 5 2222 6700 6690 2551 2221 6 6698 6701 65 66 6697 3505 5 6697 3506 3507 4522 6695 7 6552 6554 6555 6706 6551 6707 9749 6 6705 6555 9747 3502 9748 9749 6 6551 6705 6708 6709 6710 9749 7 6551 6707 6709 6719 6540 6548 6542 6 6708 6707 6710 6711 6718 6719 7 6709 6707 6711 6712 3503 9748 9749 7 6709 6710 6712 3117 3119 6713 6718 6 6711 6710 3503 3504 3116 3117 6 6711 3119 3121 3887 6714 6718 5 6713 3887 6538 6539 6718 6 6538 3886 6536 6716 3862 6717 5 6536 6715 6533 3863 3862 6 3862 6715 3861 3342 3885 3886 6 6714 6539 6713 6711 6709 6719 5 6718 6539 6540 6709 6708 6 6585 6587 6721 6722 7008 6583 6 6720 6587 6722 6723 6727 6728 6 6720 6721 6723 6724 7009 7008 6 6722 6721 6724 6725 6726 6727 6 6722 6723 6725 7009 7010 7011 6 6724 6723 6726 7022 7011 7023 6 6725 6723 6727 7023 7026 7027 6 6726 6723 6721 6728 7027 7030 6 6727 6721 6587 6588 6729 7030 6 6728 6588 6730 7030 7031 7032 6 6729 6588 6589 6590 6731 7032 6 6730 6590 6591 6593 6732 7032 6 6731 6593 6733 6734 7032 7033 6 6732 6593 6734 6601 6600 6594 6 6732 6733 6601 6603 6735 7033 6 6734 6603 6736 7033 7034 7035 6 6735 6603 6737 6740 7035 7036 5 6736 6603 6604 6738 6740 7 6737 6604 6605 6739 6740 6741 6742 6 6738 6605 6742 6743 6744 6745 6 6736 6737 6738 6741 7036 7037 6 6740 6738 6742 7037 7038 7039 6 6741 6738 6739 6743 7039 7040 7 6742 6739 6744 7040 7041 6754 7042 5 6743 6739 6745 6746 7042 6 6744 6739 6746 6747 6748 6605 7 6744 6745 6747 6610 6749 6750 7042 6 6746 6745 6748 6607 6608 6610 5 6747 6745 6607 6605 6606 5 6746 6610 6750 6620 6611 7 6746 6749 6620 6626 6751 6752 7042 6 6750 6626 6752 6753 6629 6627 5 6750 6751 6753 6754 7042 6 6752 6751 6754 6755 6756 6629 7 6752 6753 6755 7041 6743 7042 7141 5 6754 6753 6756 7141 6759 6 6755 6753 6629 6630 6757 6759 6 6756 6630 6758 6759 6760 6761 6 6757 6630 6631 6761 6762 6766 6 6756 6757 6760 7141 6755 7142 6 6759 6757 6761 7142 7143 7144 6 6760 6757 6758 6762 6763 7144 6 6761 6758 6763 4559 6764 6766 6 6761 6762 4559 4551 7144 4550 6 4559 6762 4558 4565 6765 6766 5 4565 6764 6766 6790 6767 6 6765 6764 6762 6758 6631 6767 6 6766 6631 6632 6768 6790 6765 6 6767 6632 6633 6769 6773 6790 6 6768 6633 6634 6770 6772 6773 6 6769 6634 6771 6772 6777 6778 6 6770 6634 6778 6779 6635 9785 6 6769 6770 6773 6670 6774 6777 6 6769 6772 6670 6671 6790 6768 6 6670 6772 6669 6775 6776 6777 6 6669 6774 6776 9721 9722 9798 7 6775 6774 6777 6778 6780 9797 9798 5 6776 6774 6772 6770 6778 6 6777 6770 6771 6779 6780 6776 6 6778 6771 6780 6781 6783 9785 6 6778 6779 6781 6782 6776 9797 6 6780 6779 6782 6176 6783 6784 5 6780 6781 6176 6177 9797 6 6781 6779 6784 6785 6637 9785 7 6781 6783 6176 6174 6785 6786 6788 7 6784 6783 6786 6787 9777 6638 6637 6 6784 6785 6787 6788 6171 6789 6 6786 6785 9777 6642 9782 6789 5 6784 6786 6171 6172 6174 5 6171 6786 6170 6787 9782 8 6671 6673 6773 4564 4565 6765 6768 6767 6 5418 5419 6792 7331 7332 7333 6 6791 5419 5420 5428 6793 7333 6 6792 5428 5429 6794 7333 7334 6 6793 5429 5430 6795 7334 7335 6 6794 5430 5432 5433 6796 7335 6 6795 5433 5434 6797 7335 7336 6 6796 5434 5435 6798 7336 7337 6 6797 5435 5436 6799 7337 7338 6 6798 5436 5437 6800 7338 7339 6 6799 5437 5438 6801 7339 7340 6 6800 5438 6802 7340 7341 7342 6 6801 5438 5439 5440 6803 7342 6 6802 5440 5441 6804 7342 7343 6 6803 5441 5442 6805 7343 7344 6 6804 5442 5444 6806 7344 7345 6 6805 5444 5445 6807 7345 7346 6 6806 5445 5446 6808 7346 7347 6 6807 5446 6809 7347 7348 7349 6 6808 5446 5447 6810 7349 6811 5 6809 5447 5217 5218 6811 6 6810 5218 5219 6812 7349 6809 5 6811 5219 6813 7349 7350 6 6812 5219 5220 6814 7350 7351 7 6813 5220 5221 5222 6815 7351 7352 5 6814 5222 6816 7352 7353 7 6815 5222 5223 5224 6817 7353 7354 5 6816 5224 6818 7354 7355 6 6817 5224 6819 7355 7356 7357 6 6818 5224 5225 5226 6820 7357 5 6819 5226 5227 6821 7357 6 6820 5227 6822 7357 7358 7359 7 6821 5227 5228 5229 6823 7359 7360 5 6822 5229 6824 6825 7360 5 6823 5229 6825 6826 5167 7 6823 6824 6826 6827 6828 7362 7360 5 6825 6824 5167 5168 6827 6 6826 5168 6825 6828 6829 6830 6 6825 6827 6829 7362 7363 7364 6 6828 6827 6830 7364 7365 7366 6 6829 6827 5168 5169 6831 7366 7 6830 5169 6832 7366 7367 7368 6834 5 6831 5169 6833 5238 6834 5 6832 5169 5238 5018 5023 6 6832 5238 5239 6835 7368 6831 6 6834 5239 5648 6836 7375 7368 7 6835 5648 6837 7375 7374 7376 7377 6 6836 5648 5649 5651 6838 7377 6 6837 5651 6839 7377 7378 7379 6 6838 5651 5652 6840 6841 7379 6 6839 5652 5653 5247 6841 5248 6 6839 6840 5248 6842 7379 7380 6 6841 5248 5249 6843 7380 7381 6 6842 5249 6844 7381 7382 7383 6 6843 5249 5028 5029 6845 7383 6 6844 5029 5030 6846 6847 7383 6 6845 5030 6847 6848 6849 5031 6 6845 6846 6848 7384 7383 7385 6 6847 6846 6849 7385 7386 7387 6 6848 6846 5031 5032 6850 7387 6 6849 5032 5033 5034 6851 7387 6 6850 5034 6852 7387 7388 6854 6 6851 5034 5035 5038 6853 6854 6 6852 5038 6854 6855 6856 5039 6 6852 6853 6855 7388 6851 7389 6 6854 6853 6856 6857 6859 7389 6 6855 6853 5039 6857 6858 5041 6 6855 6856 6858 6859 6860 6861 6 6857 6856 5041 6861 6862 6863 6 6855 6857 6860 7389 7390 7397 6 6859 6857 6861 7397 7398 7399 6 6860 6857 6858 6862 7399 7400 6 6861 6858 6863 6864 6865 7400 6 6862 6858 6864 5042 6879 5041 6 6862 6863 6865 6866 6879 6873 6 6862 6864 6866 6867 7400 7401 6 6865 6864 6867 6868 6872 6873 6 6865 6866 6868 6869 7401 7402 6 6867 6866 6869 6870 6871 6872 6 6867 6868 6870 7405 7402 7406 6 6869 6868 6871 7412 7406 7413 6 6870 6868 6872 7419 7416 7413 6 6871 6868 6866 6873 6874 7419 6 6872 6866 6874 6875 6864 6879 6 6872 6873 6875 6876 7419 7418 6 6874 6873 6876 6877 6878 6879 6 6874 6875 6877 6883 6884 7418 6 6876 6875 6878 6880 6882 6883 6 6877 6875 6879 6880 5043 5042 6 6878 6875 5042 6863 6864 6873 6 6877 6878 5043 5045 6881 6882 6 6880 5045 6882 6887 6888 6889 6 6880 6881 6877 6883 6886 6887 6 6877 6882 6876 6884 6885 6886 6 6876 6883 6885 7418 7420 7426 6 6884 6883 6886 7426 7427 7428 6 6885 6883 6882 6887 7428 7429 6 6886 6882 6881 6888 7429 7430 6 6887 6881 6889 6890 7430 7433 6 6888 6881 5045 6890 4645 4644 6 6888 6889 4645 4646 6891 7433 6 6890 4646 4647 6892 7433 6893 6 6891 4647 4253 4254 4730 6893 6 6892 4730 6894 7433 6891 7432 6 6893 4730 4731 6895 6897 7432 6 6894 4731 6896 6897 6898 6899 6 6895 4731 4732 6899 6900 6901 6 6894 6895 6898 7432 7431 7434 6 6897 6895 6899 7434 7435 7436 6 6898 6895 6896 6900 7436 7437 6 6899 6896 6901 7437 6904 6903 6 6900 6896 4732 4262 6902 6903 6 6901 4262 4263 4264 5231 6903 6 6902 5231 5458 6904 6900 6901 6 6903 5458 5459 6905 7437 6900 6 6904 5459 6906 7437 7438 7439 6 6905 5459 5460 6907 7439 7440 6 6906 5460 5461 6908 7262 7440 6 6907 5461 5462 6909 7262 7263 6 6908 5462 6910 7263 7264 6911 6 6909 5462 5463 5464 5465 6911 6 6910 5465 6912 7264 6909 7265 6 6911 5465 5466 6913 7265 7266 6 6912 5466 5467 6914 7266 7267 6 6913 5467 6915 7267 7268 7269 6 6914 5467 5468 6916 6917 7269 6 6915 5468 5469 5470 5471 6917 6 6915 6916 5471 6918 7269 7270 6 6917 5471 5472 6919 7270 7271 6 6918 5472 5473 6920 7271 7272 6 6919 5473 5474 5475 6921 7272 6 6920 5475 6922 7274 7272 7275 6 6921 5475 5476 6923 7275 7276 6 6922 5476 5477 6924 7276 7277 6 6923 5477 5478 6925 7277 7278 6 6924 5478 5479 6926 7278 7279 6 6925 5479 5480 5654 6927 7279 6 6926 5654 5655 6928 7281 7279 6 6927 5655 6929 7281 7282 7283 6 6928 5655 5656 5657 6930 7283 6 6929 5657 6931 7283 7284 7285 6 6930 5657 5658 5831 6932 7285 6 6931 5831 6933 7285 7286 7287 6 6932 5831 5832 5840 6934 7287 6 6933 5840 5841 6935 6936 7287 6 6934 5841 5843 6936 6937 6018 6 6934 6935 6937 6938 7287 7288 6 6936 6935 6018 6938 6939 6940 6 6936 6937 6939 7288 7289 7290 6 6938 6937 6940 7290 7291 6941 6 6939 6937 6018 5845 5847 6941 6 6940 5847 6942 6943 7291 6939 6 6941 5847 6943 6944 6945 5848 6 6941 6942 6944 7291 7292 7293 6 6943 6942 6945 7293 7294 7295 7 6944 6942 5848 5850 6385 6946 7295 6 6945 6385 6386 6947 7295 7296 6 6946 6386 6387 6388 6948 7296 6 6947 6388 6389 6949 7296 7297 7 6948 6389 6391 6395 6950 7297 7298 6 6949 6395 6951 7298 7300 7301 6 6950 6395 6396 6952 7043 7301 6 6951 6396 6399 6953 7043 7044 6 6952 6399 6400 6954 6955 7044 6 6953 6400 6401 6955 6956 6960 6 6953 6954 6956 6957 7044 7045 6 6955 6954 6957 6958 6959 6960 6 6955 6956 6958 7045 7048 7049 6 6957 6956 6959 6961 6962 7049 6 6958 6956 6960 6410 6411 6961 6 6959 6956 6954 6401 6402 6410 6 6959 6411 6958 6962 6963 6412 6 6958 6961 6963 7051 7049 7052 6 6962 6961 6412 6414 6964 7052 6 6963 6414 6416 6559 6965 7052 6 6964 6559 6561 6966 7052 6971 6 6965 6561 6967 6968 6970 6971 6 6966 6561 6968 6969 6562 6983 6 6966 6967 6969 6970 6974 6975 6 6968 6967 6981 6975 6982 6983 6 6966 6968 6971 6972 6973 6974 6 6966 6970 6972 7052 6965 7051 6 6971 6970 6973 7051 7050 7053 6 6972 6970 6974 7062 7053 7063 6 6973 6970 6968 6975 6976 7063 6 6974 6968 6976 6977 6981 6969 6 6974 6975 6977 6978 7063 7064 6 6976 6975 6978 6979 6980 6981 6 6976 6977 6979 7064 7065 7066 6 6978 6977 6980 7066 7067 7071 6 6979 6977 6981 7071 7072 7073 6 6980 6977 6975 6969 6982 7073 6 6981 6969 6983 6984 7073 7074 6 6982 6969 6984 6985 6562 6967 6 6982 6983 6985 7074 7075 7076 6 6984 6983 6562 6563 6986 7076 6 6985 6563 6567 6987 6988 7076 6 6986 6567 6988 6989 6990 6568 6 6986 6987 6989 6991 7076 7077 6 6988 6987 6990 6991 6992 6996 6 6989 6987 6996 6997 6570 6568 6 6988 6989 6992 6993 7077 7078 6 6991 6989 6993 6994 6995 6996 6 6991 6992 6994 7078 7081 7082 6 6993 6992 6995 7082 7085 7086 6 6994 6992 6996 7086 7087 7088 6 6995 6992 6989 6990 6997 7088 6 6996 6990 6570 6998 6999 7088 6 6997 6570 6999 7000 7001 6571 6 6997 6998 7000 7088 7089 7092 6 6999 6998 7001 7002 7092 7093 6 7000 6998 7002 7003 6575 6571 6 7000 7001 7003 7093 7094 7095 6 7002 7001 6575 6576 7004 7095 6 7003 6576 6578 7005 7095 7096 6 7004 6578 7006 7096 7097 7098 6 7005 6578 6579 7007 7012 7098 6 7006 6579 6582 7008 7009 7012 6 7007 6582 7009 6722 6720 6583 6 7007 7008 6722 6724 7010 7012 6 7009 6724 7011 7012 7013 7014 6 7010 6724 7022 7020 7014 6725 6 7009 7010 7007 7006 7013 7098 6 7012 7010 7014 7015 7098 7099 6 7013 7010 7015 7016 7020 7011 6 7013 7014 7016 7017 7099 7100 6 7015 7014 7017 7018 7019 7020 6 7015 7016 7018 7107 7100 7113 6 7017 7016 7019 7114 7113 7115 6 7018 7016 7020 7021 7115 7116 6 7019 7016 7014 7021 7022 7011 6 7019 7020 7022 7024 7116 7117 6 7021 7020 7011 6725 7023 7024 6 7022 6725 6726 7024 7025 7026 6 7021 7022 7023 7025 7117 7118 6 7024 7023 7026 7118 7119 7120 6 7025 7023 6726 7027 7028 7120 6 7026 6726 6727 7028 7029 7030 6 7026 7027 7029 7122 7120 7123 6 7028 7027 7030 7123 7034 7031 6 7029 7027 6727 6728 6729 7031 6 7030 6729 7032 7034 7029 7033 6 7031 6729 6730 6731 6732 7033 6 7032 6732 6734 6735 7034 7031 6 7033 6735 7035 7123 7029 7031 5 7034 6735 6736 7036 7123 6 7035 6736 6740 7037 7123 7122 7 7036 6740 6741 7038 7122 7124 7125 6 7037 6741 7039 7135 7125 7136 6 7038 6741 6742 7040 7136 7137 6 7039 6742 6743 7041 7137 7138 5 7040 6743 6754 7141 7138 6 6754 6743 6744 6746 6750 6752 6 6951 6952 7044 7301 7302 7046 6 7043 6952 6953 6955 7045 7046 6 7044 6955 6957 7046 7047 7048 6 7044 7045 7047 7302 7043 7303 6 7046 7045 7048 7303 7056 7054 6 7047 7045 6957 7049 7050 7054 6 7048 6957 7050 7051 6962 6958 6 7048 7049 7051 6972 7053 7054 6 7050 7049 6962 7052 6971 6972 6 7051 6962 6963 6964 6965 6971 6 7050 6972 7054 7055 7062 6973 6 7050 7053 7055 7056 7047 7048 6 7054 7053 7056 7057 7058 7062 6 7054 7055 7057 7303 7047 7304 6 7056 7055 7058 7059 7307 7304 6 7057 7055 7059 7060 7061 7062 6 7057 7058 7060 7307 7476 7477 6 7059 7058 7061 7477 7478 7479 6 7060 7058 7062 7063 7064 7479 6 7061 7058 7055 7053 6973 7063 6 7062 6973 6974 6976 7061 7064 6 7061 7063 6976 6978 7065 7479 6 7064 6978 7066 7479 7480 7481 6 7065 6978 6979 7067 7068 7481 6 7066 6979 7068 7069 7070 7071 6 7066 7067 7069 7483 7481 7462 6 7068 7067 7070 7462 7484 7485 6 7069 7067 7071 7485 7486 7487 6 7070 7067 6979 6980 7072 7487 6 7071 6980 7073 7487 7488 7492 6 7072 6980 6981 6982 7074 7492 6 7073 6982 6984 7075 7493 7492 6 7074 6984 7076 7493 7079 7077 6 7075 6984 6985 6986 6988 7077 6 7076 6988 6991 7078 7079 7075 6 7077 6991 6993 7079 7080 7081 6 7077 7078 7080 7691 7493 7075 6 7079 7078 7081 7223 7224 7691 6 7080 7078 6993 7082 7083 7223 6 7081 6993 6994 7083 7084 7085 6 7081 7082 7084 7226 7223 7227 6 7083 7082 7085 7227 7228 7229 6 7084 7082 6994 7086 7232 7229 6 7085 6994 6995 7087 7232 7233 6 7086 6995 7088 7089 7090 7233 6 7087 6995 6996 6997 6999 7089 6 7088 6999 7087 7090 7091 7092 6 7087 7089 7091 7233 7234 7235 6 7090 7089 7092 7235 7236 7237 6 7091 7089 6999 7000 7093 7237 6 7092 7000 7002 7094 7237 7238 6 7093 7002 7095 7238 7239 7103 6 7094 7002 7003 7004 7096 7103 6 7095 7004 7005 7097 7102 7103 6 7096 7005 7098 7099 7101 7102 6 7097 7005 7006 7012 7013 7099 6 7098 7013 7015 7100 7101 7097 6 7099 7015 7101 7106 7107 7017 6 7099 7100 7097 7102 7105 7106 6 7097 7101 7096 7103 7104 7105 6 7096 7102 7104 7239 7094 7095 6 7103 7102 7105 7241 7239 7242 6 7104 7102 7101 7106 7242 7243 6 7105 7101 7100 7107 7108 7243 6 7106 7100 7017 7108 7109 7113 6 7106 7107 7109 7110 7243 7244 6 7108 7107 7110 7111 7112 7113 6 7108 7109 7111 7247 7244 7248 6 7110 7109 7112 7248 7249 7250 6 7111 7109 7113 7114 7250 7251 6 7112 7109 7114 7018 7017 7107 6 7112 7113 7018 7115 7251 7254 6 7114 7018 7019 7116 7254 7255 6 7115 7019 7021 7117 7258 7255 6 7116 7021 7024 7118 7258 7259 6 7117 7024 7025 7119 7259 7128 6 7118 7025 7120 7121 7127 7128 6 7119 7025 7121 7122 7028 7026 6 7119 7120 7122 7124 7126 7127 7 7121 7120 7028 7123 7036 7037 7124 6 7122 7028 7029 7034 7035 7036 5 7122 7037 7125 7126 7121 5 7124 7037 7126 7135 7038 7 7124 7125 7121 7127 7130 7131 7135 6 7121 7126 7119 7128 7129 7130 6 7119 7127 7129 7261 7259 7118 6 7128 7127 7130 7261 7532 7530 6 7129 7127 7126 7131 7132 7532 6 7130 7126 7132 7133 7134 7135 6 7130 7131 7133 7532 7531 7533 6 7132 7131 7134 7533 7534 7535 6 7133 7131 7135 7535 7536 7136 6 7134 7131 7126 7125 7038 7136 6 7135 7038 7039 7137 7536 7134 6 7136 7039 7040 7138 7139 7536 6 7137 7040 7139 7140 7141 7041 6 7137 7138 7140 7148 7150 7536 6 7139 7138 7141 7142 7147 7148 7 7140 7138 7041 6754 6755 6759 7142 6 7140 7141 6759 6760 7143 7147 6 7142 6760 7144 7145 7146 7147 7 7143 6760 7145 4552 4551 6763 6761 5 7143 7144 4552 4554 7146 6 7145 4554 4556 7143 7147 7148 5 7143 7146 7148 7140 7142 7 7147 7146 4556 7140 7139 7149 7150 6 7148 4556 7150 7151 7152 7153 6 7148 7149 7139 7151 7536 7535 6 7150 7149 7152 7535 7534 7537 6 7151 7149 7153 7154 7155 7537 6 7152 7149 7154 4649 4555 4556 6 7152 7153 7155 7156 7166 4649 6 7152 7154 7156 7157 7537 7538 6 7155 7154 7157 7158 7159 7166 6 7155 7156 7158 7538 7539 7554 6 7157 7156 7159 7160 7554 7555 6 7158 7156 7160 7161 7162 7166 6 7158 7159 7161 7163 7167 7555 6 7160 7159 7162 7163 4137 7164 5 7161 7159 7164 7165 7166 6 7160 7161 4137 7167 7168 4138 7 4137 7161 7162 7165 4413 4134 4135 5 7164 7162 4413 4415 7166 7 4415 7165 7162 7159 7156 7154 4649 6 7160 7163 7168 7555 7556 7560 7 7167 7163 4138 7169 7560 7561 7562 5 7168 4138 4139 7170 7562 7 7169 4139 4140 7171 7562 7563 7564 6 7170 4140 4124 7172 7173 7564 6 7171 4124 7173 7174 4122 9789 6 7171 7172 7174 7175 7176 7564 6 7173 7172 7175 9788 9787 9789 6 7173 7174 7176 7177 7178 9788 7 7173 7175 7177 7564 7563 7568 7569 6 7176 7175 7178 7179 7180 7569 6 7177 7175 7179 9788 3535 3537 6 7177 7178 7180 7181 7182 3537 6 7177 7179 7181 7570 7569 7571 6 7180 7179 7182 7571 7572 7573 6 7181 7179 3537 3538 7183 7573 6 7182 3538 7184 7575 7573 7187 6 7183 3538 3539 7185 7186 7187 6 7184 3539 7186 7211 7210 7212 6 7184 7185 7187 7188 7211 7192 6 7184 7186 7188 7189 7575 7183 6 7187 7186 7189 7190 7191 7192 6 7187 7188 7190 7575 7576 7579 6 7189 7188 7191 7193 7579 7580 6 7190 7188 7192 7193 7194 7198 6 7191 7188 7198 7199 7211 7186 6 7190 7191 7194 7195 7580 7581 6 7193 7191 7195 7196 7197 7198 6 7193 7194 7196 7581 7582 7583 6 7195 7194 7197 7583 3196 3195 6 7196 7194 7198 3195 7200 7203 6 7197 7194 7191 7192 7199 7200 6 7198 7192 7200 7201 7211 7208 6 7198 7199 7201 7202 7203 7197 6 7200 7199 7202 7206 7207 7208 6 7200 7201 7203 7204 7205 7206 6 7200 7202 7204 3194 3195 7197 6 7203 7202 7205 7220 7221 3194 6 7204 7202 7206 9745 7218 7220 6 7205 7202 7201 7207 9745 9746 6 7206 7201 7208 7209 9746 7213 6 7207 7201 7209 7210 7211 7199 6 7207 7208 7210 4373 4374 7213 6 7209 7208 7211 7185 7212 4373 6 7210 7208 7199 7192 7186 7185 6 7210 7185 3539 3540 4372 4373 6 7209 4374 4375 7214 9746 7207 6 7213 4375 4377 7215 7216 9746 6 7214 4377 7216 2863 1627 2862 6 7214 7215 2863 7217 9745 9746 6 7216 2863 2864 2865 7218 9745 6 7217 2865 7219 7220 7205 9745 5 7218 2865 7220 3214 2866 6 7218 7219 3214 7221 7205 7204 6 7220 3214 3215 7222 3194 7204 5 7221 3215 3216 3193 3194 6 7080 7081 7224 7225 7226 7083 6 7080 7223 7225 7691 7690 7692 6 7224 7223 7226 7692 7693 7674 6 7225 7223 7083 7227 7674 7694 6 7226 7083 7084 7228 7694 7695 6 7227 7084 7229 7230 7695 7696 6 7228 7084 7230 7231 7232 7085 6 7228 7229 7231 7696 7697 7701 6 7230 7229 7232 7701 7702 7703 6 7231 7229 7085 7086 7233 7703 6 7232 7086 7087 7090 7234 7703 6 7233 7090 7235 7718 7704 7703 6 7234 7090 7091 7236 7718 7717 6 7235 7091 7237 7717 7719 7720 6 7236 7091 7092 7093 7238 7720 6 7237 7093 7094 7239 7240 7720 6 7238 7094 7103 7240 7241 7104 6 7238 7239 7241 7720 7721 7722 6 7240 7239 7104 7242 7722 7725 6 7241 7104 7105 7243 7245 7725 6 7242 7105 7106 7108 7244 7245 6 7243 7108 7245 7246 7247 7110 6 7243 7244 7246 7728 7725 7242 6 7245 7244 7247 7964 7728 7965 6 7246 7244 7110 7248 7965 7966 6 7247 7110 7111 7249 7966 7967 6 7248 7111 7250 7511 7967 7968 6 7249 7111 7112 7251 7252 7511 6 7250 7112 7114 7252 7253 7254 6 7250 7251 7253 7511 7512 7516 6 7252 7251 7254 7256 9775 7516 6 7253 7251 7114 7115 7255 7256 6 7254 7115 7256 7257 7258 7116 6 7254 7255 7257 7523 7253 9775 6 7256 7255 7258 7260 7524 7523 6 7257 7255 7116 7117 7259 7260 6 7258 7117 7118 7260 7261 7128 6 7258 7259 7261 7529 7524 7257 6 7260 7259 7128 7129 7530 7529 6 6907 6908 7263 7440 7442 7443 6 7262 6908 6909 7264 7443 7444 6 7263 6909 6911 7265 7444 7445 6 7264 6911 6912 7266 7445 7446 6 7265 6912 6913 7267 7449 7446 6 7266 6913 6914 7268 7449 7450 6 7267 6914 7269 7450 7451 7452 6 7268 6914 6915 6917 7270 7452 6 7269 6917 6918 7271 7452 7453 6 7270 6918 6919 7272 7273 7453 6 7271 6919 7273 7274 6921 6920 6 7271 7272 7274 7453 7454 7455 6 7273 7272 6921 7275 7455 7456 6 7274 6921 6922 7276 7456 7457 6 7275 6922 6923 7277 7457 7458 6 7276 6923 6924 7278 7458 7459 6 7277 6924 6925 7279 7280 7459 6 7278 6925 7280 7281 6927 6926 6 7278 7279 7281 7459 7460 7464 6 7280 7279 6927 6928 7282 7464 6 7281 6928 7283 7464 7465 7466 6 7282 6928 6929 6930 7284 7466 6 7283 6930 7285 7466 7467 7468 6 7284 6930 6931 6932 7286 7468 6 7285 6932 7287 7468 7469 7288 6 7286 6932 6933 6934 6936 7288 6 7287 6936 6938 7289 7469 7286 6 7288 6938 7290 7469 7470 7471 6 7289 6938 6939 7291 7471 7472 6 7290 6939 6941 6943 7292 7472 6 7291 6943 7293 7472 7473 7474 6 7292 6943 6944 7294 7474 7299 6 7293 6944 7295 7297 7298 7299 6 7294 6944 6945 6946 7296 7297 5 7295 6946 6947 6948 7297 6 7296 6948 6949 7295 7294 7298 6 7294 7297 6949 6950 7299 7300 5 7294 7298 7300 7474 7293 7 7299 7298 6950 7301 7474 7305 7302 5 7300 6950 6951 7043 7302 6 7301 7043 7046 7303 7305 7300 6 7302 7046 7047 7056 7304 7305 6 7303 7056 7305 7306 7307 7057 6 7303 7304 7306 7474 7300 7302 6 7305 7304 7307 7474 7473 7475 6 7306 7304 7057 7059 7475 7476 5 4702 4703 7309 7855 7856 6 7308 4703 4704 7310 7856 7857 6 7309 4704 4705 7311 7857 7858 6 7310 4705 4706 7312 7858 7859 6 7311 4706 4707 5170 7313 7859 6 7312 5170 7314 7859 7860 7861 6 7313 5170 5171 7315 7861 7862 6 7314 5171 5172 7316 7862 7863 6 7315 5172 5173 7317 7863 7864 6 7316 5173 5174 7318 7864 7865 6 7317 5174 5175 7319 7865 7866 6 7318 5175 5176 7320 7866 7867 6 7319 5176 5177 5178 7321 7867 6 7320 5178 7322 7867 7868 7869 6 7321 5178 5179 7323 7869 7870 6 7322 5179 5180 5411 7324 7870 6 7323 5411 7325 7870 7871 7872 6 7324 5411 5412 7326 7872 7873 6 7325 5412 5413 5414 7327 7873 6 7326 5414 7328 7873 7874 7875 6 7327 5414 5415 5416 7329 7875 6 7328 5416 7330 7875 7876 7877 6 7329 5416 5417 5418 7331 7877 6 7330 5418 6791 7332 7877 7878 6 7331 6791 7333 7878 7879 7880 6 7332 6791 6792 6793 7334 7880 6 7333 6793 6794 7335 7880 7881 6 7334 6794 6795 6796 7336 7881 6 7335 6796 6797 7337 7881 7882 6 7336 6797 6798 7338 7882 7883 6 7337 6798 6799 7339 7883 7884 6 7338 6799 6800 7340 7884 7885 6 7339 6800 6801 7341 7885 7886 6 7340 6801 7342 7886 7887 7888 6 7341 6801 6802 6803 7343 7888 6 7342 6803 6804 7344 7888 7889 6 7343 6804 6805 7345 7889 7890 6 7344 6805 6806 7346 7890 7891 6 7345 6806 6807 7347 7891 7892 6 7346 6807 6808 7348 7892 7893 6 7347 6808 7349 7893 7894 7895 7 7348 6808 6809 6811 6812 7350 7895 6 7349 6812 6813 7351 7895 7896 6 7350 6813 6814 7352 7896 7897 5 7351 6814 6815 7353 7897 7 7352 6815 6816 7354 7897 7898 7899 5 7353 6816 6817 7355 7899 7 7354 6817 6818 7356 7899 7900 7901 6 7355 6818 7357 7901 7902 7903 7 7356 6818 6819 6820 6821 7358 7903 6 7357 6821 7359 7903 7904 7905 6 7358 6821 6822 7360 7361 7905 6 7359 6822 6823 7361 7362 6825 6 7359 7360 7362 7905 7906 7907 6 7361 7360 6825 6828 7363 7907 6 7362 6828 7364 7907 7908 7909 5 7363 6828 6829 7365 7909 7 7364 6829 7366 7369 7371 7909 7910 6 7365 6829 6830 6831 7367 7369 6 7366 6831 7368 7369 7370 7375 5 7367 6831 7375 6835 6834 6 7366 7367 7370 7365 7371 7372 6 7369 7367 7372 7373 7374 7375 6 7365 7369 7372 7910 7911 7912 6 7371 7369 7370 7373 7912 7913 6 7372 7370 7374 7913 7914 7915 6 7373 7370 7375 6836 7376 7915 6 7374 7370 7367 7368 6835 6836 6 7374 6836 7377 7915 7916 7917 6 7376 6836 6837 6838 7378 7917 5 7377 6838 7379 7601 7917 6 7378 6838 6839 6841 7380 7601 6 7379 6841 6842 7381 7601 7602 6 7380 6842 6843 7382 7605 7602 6 7381 6843 7383 7384 7605 7606 6 7382 6843 7384 6847 6845 6844 6 7382 7383 6847 7385 7606 7607 6 7384 6847 6848 7386 7607 7392 6 7385 6848 7387 7388 7391 7392 6 7386 6848 6849 6850 6851 7388 6 7387 6851 6854 7389 7391 7386 6 7388 6854 6855 6859 7390 7391 6 7389 6859 7391 7396 7393 7397 6 7389 7390 7388 7386 7392 7393 6 7386 7391 7393 7394 7607 7385 6 7392 7391 7394 7395 7396 7390 6 7392 7393 7395 7607 7608 7611 6 7394 7393 7396 7611 7612 7622 6 7395 7393 7390 7397 7622 7623 6 7396 7390 6859 6860 7398 7623 5 7397 6860 7399 7623 7624 6 7398 6860 6861 7400 7624 7625 7 7399 6861 6862 6865 7401 7625 7626 6 7400 6865 6867 7402 7403 7626 6 7401 6867 7403 7404 7405 6869 6 7401 7402 7404 7626 7627 7628 6 7403 7402 7405 7408 7628 7629 6 7404 7402 6869 7406 7407 7408 6 7405 6869 7407 7411 7412 6870 6 7405 7406 7408 7409 7410 7411 6 7405 7407 7404 7409 7632 7629 6 7408 7407 7410 7632 7633 7634 6 7409 7407 7411 7634 7635 7642 6 7410 7407 7406 7412 7642 7643 6 7411 7406 6870 7413 7414 7643 6 7412 6870 7414 7415 7416 6871 6 7412 7413 7415 7643 7644 7645 6 7414 7413 7416 7417 7645 7646 6 7415 7413 7417 7418 7419 6871 6 7415 7416 7418 7420 7421 7646 7 7417 7416 7419 6874 6876 6884 7420 5 7418 7416 6871 6872 6874 6 7418 6884 7417 7421 7422 7426 6 7417 7420 7422 7423 7646 7647 6 7421 7420 7423 7424 7425 7426 6 7421 7422 7424 7647 7648 7649 6 7423 7422 7425 7649 7650 7651 6 7424 7422 7426 7651 7652 7427 6 7425 7422 7420 6884 6885 7427 6 7426 6885 7428 7652 7425 7653 6 7427 6885 6886 7429 7653 7654 6 7428 6886 6887 7430 7431 7654 6 7429 6887 6888 7431 7432 7433 6 7429 7430 7432 6897 7434 7654 6 7431 7430 7433 6893 6894 6897 6 7432 7430 6888 6890 6891 6893 6 7431 6897 6898 7435 7655 7654 6 7434 6898 7436 7655 7656 7660 6 7435 6898 6899 7437 7660 7438 6 7436 6899 6900 6904 6905 7438 6 7437 6905 7439 7660 7436 7661 6 7438 6905 6906 7440 7441 7661 6 7439 6906 6907 7262 7441 7442 6 7439 7440 7442 7661 7662 7663 6 7441 7440 7262 7443 7663 7664 6 7442 7262 7263 7444 7664 7665 6 7443 7263 7264 7445 7665 7666 6 7444 7264 7265 7446 7447 7666 6 7445 7265 7447 7448 7449 7266 6 7445 7446 7448 7668 7666 7671 6 7447 7446 7449 7671 7676 7673 6 7448 7446 7266 7267 7450 7676 6 7449 7267 7268 7451 7676 7677 6 7450 7268 7452 7677 7678 7682 6 7451 7268 7269 7270 7453 7682 6 7452 7270 7271 7273 7454 7682 6 7453 7273 7455 7682 7681 7683 6 7454 7273 7274 7456 7686 7683 6 7455 7274 7275 7457 7686 7687 6 7456 7275 7276 7458 7687 7688 6 7457 7276 7277 7459 7688 7461 6 7458 7277 7278 7280 7460 7461 6 7459 7280 7461 7462 7463 7464 6 7459 7460 7462 7688 7458 7484 7 7461 7460 7463 7483 7068 7069 7484 6 7462 7460 7464 7483 7482 7465 6 7463 7460 7280 7281 7282 7465 6 7464 7282 7466 7482 7463 7494 6 7465 7282 7283 7284 7467 7494 6 7466 7284 7468 7494 7495 7496 6 7467 7284 7285 7286 7469 7496 6 7468 7286 7288 7289 7470 7496 6 7469 7289 7471 7496 7497 7498 6 7470 7289 7290 7472 7498 7475 6 7471 7290 7291 7292 7473 7475 5 7472 7292 7474 7306 7475 7 7473 7292 7293 7299 7300 7305 7306 7 7473 7306 7307 7476 7498 7471 7472 5 7475 7307 7059 7477 7498 6 7476 7059 7060 7478 7497 7498 7 7477 7060 7479 7480 7497 7495 7499 6 7478 7060 7061 7064 7065 7480 6 7478 7479 7065 7481 7482 7499 6 7480 7065 7482 7483 7068 7066 7 7480 7481 7483 7463 7465 7494 7499 5 7482 7481 7068 7462 7463 5 7462 7069 7485 7688 7461 6 7484 7069 7070 7486 7687 7688 6 7485 7070 7487 7686 7687 7685 7 7486 7070 7071 7072 7488 7489 7685 6 7487 7072 7489 7490 7491 7492 5 7487 7488 7490 7685 7684 6 7489 7488 7491 7684 7689 7690 6 7490 7488 7492 7493 7690 7691 6 7491 7488 7493 7074 7073 7072 6 7491 7492 7074 7075 7691 7079 6 7482 7465 7466 7467 7495 7499 6 7494 7467 7496 7497 7478 7499 6 7495 7467 7468 7469 7470 7497 6 7496 7470 7498 7477 7478 7495 6 7497 7470 7471 7477 7476 7475 5 7495 7478 7480 7482 7494 6 427 5612 5613 7501 7502 9768 6 7500 5613 7502 7503 7504 7505 6 7500 7501 7503 9768 9769 9770 6 7502 7501 7504 6474 9770 9780 5 7503 7501 6474 6472 7505 7 6472 7504 7501 5613 5614 7506 6470 5 7505 5614 7507 6469 6470 6 7506 5614 5615 7508 7509 6469 6 7507 5615 7509 7510 9734 4518 5 7507 7508 7510 6469 6468 6 7509 7508 6468 9732 9733 9734 6 7249 7250 7252 7512 7513 7968 6 7511 7252 7513 7514 7515 7516 6 7511 7512 7514 7968 7969 7970 6 7513 7512 7515 7970 7971 7972 6 7514 7512 7516 7517 7518 7972 6 7515 7512 7252 7517 9775 7253 6 7515 7516 7518 7519 7520 9775 6 7515 7517 7519 7972 7973 7977 6 7518 7517 7520 7521 7977 7978 6 7519 7517 7521 7522 7523 9775 6 7519 7520 7522 7989 7978 7526 6 7521 7520 7523 7524 7525 7526 6 7522 7520 7524 7256 7257 9775 6 7522 7523 7525 7260 7529 7257 6 7522 7524 7526 7527 7528 7529 6 7522 7525 7527 7989 7521 7990 6 7526 7525 7528 7990 7546 7545 6 7527 7525 7529 7530 7531 7545 6 7528 7525 7530 7261 7260 7524 6 7528 7529 7261 7531 7532 7129 7 7528 7530 7532 7132 7533 7543 7545 5 7531 7530 7129 7130 7132 6 7531 7132 7133 7534 7544 7543 6 7533 7133 7535 7151 7537 7544 6 7534 7133 7134 7536 7150 7151 6 7535 7134 7136 7137 7139 7150 6 7534 7151 7152 7155 7538 7544 6 7537 7155 7157 7539 7540 7544 6 7538 7157 7540 7541 7553 7554 6 7538 7539 7541 7542 7543 7544 6 7540 7539 7542 7547 7553 7550 6 7540 7541 7543 7545 7546 7547 6 7540 7542 7544 7533 7531 7545 6 7540 7543 7533 7534 7537 7538 6 7531 7543 7542 7546 7527 7528 6 7545 7542 7547 7548 7990 7527 6 7546 7542 7541 7548 7549 7550 6 7546 7547 7549 7990 7989 7991 6 7548 7547 7550 7551 7991 7992 6 7549 7547 7551 7552 7553 7541 6 7549 7550 7552 7992 7994 7995 7 7551 7550 7553 7557 7556 7558 7995 6 7552 7550 7541 7539 7554 7557 6 7553 7539 7157 7158 7555 7557 6 7554 7158 7160 7167 7556 7557 7 7555 7167 7557 7552 7558 7559 7560 5 7555 7556 7554 7553 7552 5 7552 7556 7559 7995 7996 7 7558 7556 7560 7996 7999 7566 7561 5 7559 7556 7167 7168 7561 6 7560 7168 7562 7565 7566 7559 6 7561 7168 7169 7170 7563 7565 6 7562 7170 7564 7176 7565 7568 5 7563 7170 7171 7173 7176 6 7562 7563 7561 7566 7567 7568 6 7561 7565 7567 7999 7559 8000 6 7566 7565 7568 7569 7570 8000 5 7567 7565 7563 7176 7569 6 7568 7176 7567 7570 7180 7177 6 7567 7569 7180 7571 8000 8001 6 7570 7180 7181 7572 8001 8002 6 7571 7181 7573 7574 8002 8003 6 7572 7181 7574 7575 7183 7182 6 7572 7573 7575 7576 7577 8003 6 7574 7573 7183 7187 7189 7576 6 7575 7189 7574 7577 7578 7579 6 7574 7576 7578 8003 8004 8005 6 7577 7576 7579 8005 8006 8007 6 7578 7576 7189 7190 7580 8007 6 7579 7190 7193 7581 8007 8008 6 7580 7193 7195 7582 8008 8009 6 7581 7195 7583 7585 8012 8009 6 7582 7195 7196 3196 7584 7585 6 7583 3196 3186 7585 7586 3187 6 7583 7584 7586 7587 7582 8012 6 7585 7584 7587 7588 3958 3187 6 7585 7586 7588 7729 8013 8012 6 7587 7586 3958 3960 7589 7729 6 7588 3960 7590 7729 7730 7731 6 7589 3960 3961 7591 7731 7732 6 7590 3961 7592 7738 7732 7739 6 7591 3961 2890 2891 7593 7739 6 7592 2891 7594 7595 7739 7740 6 7593 2891 7595 7596 7597 2892 6 7593 7594 7596 7740 7741 7745 6 7595 7594 7597 7598 7745 7746 6 7596 7594 7598 7599 7600 2892 6 7596 7597 7599 4089 7746 7751 5 7598 7597 7600 4089 4086 6 7599 7597 4086 2880 2879 2892 7 7378 7379 7380 7602 7603 7917 7918 6 7601 7380 7603 7604 7605 7381 6 7601 7602 7604 7926 7920 7918 5 7603 7602 7605 7926 7927 7 7604 7602 7381 7382 7606 7609 7927 6 7605 7382 7384 7607 7608 7609 6 7606 7384 7385 7392 7394 7608 6 7607 7394 7606 7609 7610 7611 6 7606 7608 7610 7929 7927 7605 6 7609 7608 7611 7613 7616 7929 6 7610 7608 7394 7395 7612 7613 6 7611 7395 7613 7614 7621 7622 6 7611 7612 7614 7615 7616 7610 6 7613 7612 7615 7619 7620 7621 6 7613 7614 7616 7617 7618 7619 6 7613 7615 7617 8157 7929 7610 6 7616 7615 7618 8155 8157 8156 6 7617 7615 7619 8156 8158 8159 6 7618 7615 7614 7620 8159 8160 6 7619 7614 7621 8160 8161 8162 6 7620 7614 7612 7622 8162 8163 6 7621 7612 7395 7396 7623 8163 6 7622 7396 7397 7398 7624 8163 6 7623 7398 7399 7625 8163 8164 6 7624 7399 7400 7626 8164 7627 5 7625 7400 7401 7403 7627 6 7626 7403 7628 8164 7625 8165 6 7627 7403 7404 7629 7630 8165 6 7628 7404 7630 7631 7632 7408 6 7628 7629 7631 8165 8166 8167 6 7630 7629 7632 8170 8167 8171 6 7631 7629 7408 7409 7633 8171 6 7632 7409 7634 8173 8171 8174 6 7633 7409 7410 7635 7636 8174 6 7634 7410 7636 7637 7641 7642 6 7634 7635 7637 7638 8174 8175 6 7636 7635 7638 7639 7640 7641 6 7636 7637 7639 8175 8176 8177 6 7638 7637 7640 8177 8178 8179 6 7639 7637 7641 8179 8180 8181 6 7640 7637 7635 7642 8181 8182 6 7641 7635 7410 7411 7643 8182 6 7642 7411 7412 7414 7644 8182 6 7643 7414 7645 8183 8182 8184 6 7644 7414 7415 7646 8184 8185 6 7645 7415 7417 7421 7647 8185 6 7646 7421 7423 7648 8185 8186 6 7647 7423 7649 8186 8187 8188 6 7648 7423 7424 7650 8188 8189 6 7649 7424 7651 8189 8190 8191 6 7650 7424 7425 7652 8191 8192 6 7651 7425 7427 7653 8192 7657 6 7652 7427 7428 7654 7655 7657 6 7653 7428 7429 7655 7434 7431 6 7653 7654 7434 7435 7656 7657 6 7655 7435 7657 7658 7659 7660 6 7655 7656 7658 8192 7652 7653 6 7657 7656 7659 8192 8193 8194 6 7658 7656 7660 8194 7662 7661 6 7659 7656 7435 7436 7438 7661 6 7660 7438 7439 7441 7662 7659 6 7661 7441 7663 8194 7659 8195 6 7662 7441 7442 7664 8208 8195 6 7663 7442 7443 7665 8208 8207 6 7664 7443 7444 7666 7667 8207 6 7665 7444 7667 7668 7447 7445 6 7665 7666 7668 7669 8206 8207 6 7667 7666 7447 7669 7670 7671 6 7667 7668 7670 7698 8206 9790 6 7669 7668 7671 7672 7695 9790 6 7670 7668 7447 7448 7672 7673 6 7670 7671 7673 7674 7695 7694 6 7672 7671 7674 7675 7676 7448 7 7672 7673 7675 7693 7225 7226 7694 6 7674 7673 7676 7677 7679 7693 6 7675 7673 7448 7449 7450 7677 6 7676 7450 7451 7678 7679 7675 6 7677 7451 7679 7680 7681 7682 7 7677 7678 7680 7675 7693 7692 7689 5 7679 7678 7681 7689 7684 6 7680 7678 7682 7454 7683 7684 6 7681 7678 7451 7452 7453 7454 6 7681 7454 7684 7685 7686 7455 7 7681 7683 7685 7489 7490 7689 7680 6 7684 7683 7686 7486 7487 7489 6 7685 7683 7455 7456 7687 7486 6 7686 7456 7457 7486 7485 7688 6 7485 7687 7457 7458 7461 7484 6 7684 7490 7690 7692 7679 7680 6 7689 7490 7491 7691 7224 7692 6 7690 7491 7493 7079 7080 7224 6 7690 7224 7225 7693 7679 7689 5 7692 7225 7674 7675 7679 5 7674 7226 7227 7695 7672 7 7694 7227 7228 7696 7670 7672 9790 6 7695 7228 7230 7697 7698 9790 6 7696 7230 7698 7699 7700 7701 6 7696 7697 7699 8206 7669 9790 6 7698 7697 7700 8205 8203 8206 6 7699 7697 7701 8318 8205 7707 6 7700 7697 7230 7231 7702 7707 6 7701 7231 7703 7704 7705 7707 6 7702 7231 7704 7234 7233 7232 6 7702 7703 7705 7706 7718 7234 6 7702 7704 7706 7707 7708 7709 6 7705 7704 7709 7710 7711 7718 6 7702 7705 7708 8318 7700 7701 6 7707 7705 7709 8318 8481 8317 6 7708 7705 7706 7710 8481 8482 6 7709 7706 7711 7712 7713 8482 6 7710 7706 7712 7716 7717 7718 6 7710 7711 7713 7714 7715 7716 6 7710 7712 7714 8482 8483 8484 6 7713 7712 7715 8484 9765 8486 6 7714 7712 7716 9765 7723 9767 6 7715 7712 7711 7717 9767 7719 6 7716 7711 7718 7235 7236 7719 6 7717 7711 7706 7704 7234 7235 6 7717 7236 7720 9767 7716 7721 6 7719 7236 7237 7238 7240 7721 6 7720 7240 7722 7723 9767 7719 6 7721 7240 7241 7723 7724 7725 7 7721 7722 7724 7726 9765 7715 9767 6 7723 7722 7725 7726 7727 7728 6 7724 7722 7728 7245 7242 7241 6 7723 7724 7727 7962 9765 9764 6 7726 7724 7728 7962 7963 7964 6 7727 7724 7725 7245 7964 7246 6 7587 7588 7589 7730 8013 8014 6 7729 7589 7731 8014 8015 7734 6 7730 7589 7590 7732 7733 7734 6 7731 7590 7733 7737 7738 7591 6 7731 7732 7734 7735 7736 7737 6 7731 7733 7735 8015 7730 8016 6 7734 7733 7736 8016 8017 8018 6 7735 7733 7737 8018 8019 8020 6 7736 7733 7732 7738 8020 8021 6 7737 7732 7591 7739 9766 8021 6 7738 7591 7592 7593 7740 9766 6 7739 7593 7595 7741 7742 9766 6 7740 7595 7742 7743 7744 7745 6 7740 7741 7743 8025 8023 9766 6 7742 7741 7744 8025 8026 8027 6 7743 7741 7745 7747 7748 8027 6 7744 7741 7595 7596 7746 7747 6 7745 7596 7598 7747 7750 7751 6 7745 7746 7744 7748 7749 7750 6 7744 7747 7749 8027 8031 8032 6 7748 7747 7750 8032 8036 7759 6 7749 7747 7746 7751 7752 7759 7 7750 7746 7598 4089 4090 7752 7753 7 7750 7751 7753 4379 7754 7758 7759 4 7752 7751 4090 4379 5 7752 4379 4380 7755 7758 6 7754 4380 4382 7756 7757 7758 6 7755 4382 7757 7762 7763 7764 6 7755 7756 7758 7760 7761 7762 6 7755 7757 7754 7752 7759 7760 6 7752 7758 7760 8036 7749 7750 5 7759 7758 7757 7761 8036 7 7760 7757 7762 8036 8640 8635 8035 7 7761 7757 7756 7763 8852 8639 8640 6 7762 7756 7764 7765 8852 8853 6 7763 7756 4382 4383 4389 7765 6 7763 7764 4389 7766 8319 8853 6 7765 4389 4390 7767 8319 8320 6 7766 4390 3142 7768 7769 8320 6 7767 3142 7769 7770 7774 3143 6 7767 7768 7770 7771 8322 8320 6 7769 7768 7771 7772 7773 7774 6 7769 7770 7772 8322 8323 8324 6 7771 7770 7773 8324 8325 7777 6 7772 7770 7774 7775 7776 7777 6 7773 7770 7768 3143 3144 7775 6 7774 3144 7773 7776 3145 9791 6 7773 7775 7777 7778 3414 9791 6 7773 7776 7778 8325 7772 8326 6 7777 7776 3414 3415 7779 8326 6 7778 3415 5382 5384 7780 8326 6 7779 5384 5386 7781 8326 8327 6 7780 5386 5388 7782 8329 8327 6 7781 5388 5616 7783 8329 8330 6 7782 5616 7784 8330 8331 8332 6 7783 5616 5617 7785 8037 8332 6 7784 5617 7786 7787 8037 8038 6 7785 5617 5618 7787 7788 7789 6 7785 7786 7788 8038 8039 8040 6 7787 7786 7789 8045 8040 7794 6 7788 7786 5618 5619 7790 7794 6 7789 5619 7791 7792 7793 7794 6 7790 5619 7792 3779 3778 5620 6 7790 7791 7793 7797 7798 3779 6 7790 7792 7794 7795 7796 7797 6 7790 7793 7795 8045 7788 7789 6 7794 7793 7796 8045 8046 8047 6 7795 7793 7797 8048 8047 8049 6 7796 7793 7792 7798 8049 7799 6 7797 7792 3779 3780 3783 7799 6 7798 3783 3784 7800 8049 7797 6 7799 3784 3785 3788 7801 8049 6 7800 3788 3790 7802 8048 8049 6 7801 3790 3791 3793 7803 8048 6 7802 3793 7804 7806 8047 8048 6 7803 3793 3794 7805 7806 7807 6 7804 3794 7807 7808 7809 3795 6 7803 7804 7807 8046 8047 8343 6 7806 7804 7805 7808 8344 8343 6 7807 7805 7809 8344 8345 7930 6 7808 7805 3795 3796 7810 7930 6 7809 3796 3952 7811 7930 7931 6 7810 3952 7812 7931 7932 7936 6 7811 3952 3953 7813 7936 7937 6 7812 3953 3954 7814 7937 7938 6 7813 3954 7815 7938 7939 7816 6 7814 3954 3955 3956 4238 7816 6 7815 4238 4503 7817 7939 7814 6 7816 4503 4504 7818 7939 7940 6 7817 4504 7819 7940 7941 7942 6 7818 4504 4505 7820 7942 7943 6 7819 4505 4506 4507 7821 7943 6 7820 4507 7822 7943 7944 7945 6 7821 4507 4508 7823 7945 7946 6 7822 4508 4509 7824 7946 7947 6 7823 4509 7825 7826 7947 7948 6 7824 4509 4510 7826 7827 7828 6 7824 7825 7827 7948 7949 7950 6 7826 7825 7828 7950 7951 7952 6 7827 7825 4510 4419 7829 7952 6 7828 4419 4247 7830 7952 7832 6 7829 4247 4248 4739 7831 7832 6 7830 4739 5003 7832 7833 7834 6 7830 7831 7833 7952 7829 7953 6 7832 7831 7834 7953 7954 7955 6 7833 7831 5003 5004 7835 7955 6 7834 5004 5005 7836 7955 7956 6 7835 5005 7837 7956 7957 7958 6 7836 5005 4750 4751 7838 7958 6 7837 4751 4757 7839 7958 7959 6 7838 4757 7840 7959 7960 7846 6 7839 4757 4758 7841 7846 7961 6 7840 4758 4661 4662 7842 7961 6 7841 4662 4663 4689 7843 7961 6 7842 4689 4690 7844 7961 7845 6 7843 4690 4691 5158 5159 7845 5 7844 5159 7846 7961 7843 7 7845 5159 7847 7960 7839 7840 7961 6 7846 5159 5160 7848 8082 7960 6 7847 5160 5161 7849 8082 8083 6 7848 5161 5162 7850 8083 8084 6 7849 5162 7851 8084 8085 8086 6 7850 5162 5163 5164 7852 8086 6 7851 5164 7853 8086 8087 8088 6 7852 5164 5165 7854 8088 8089 7 7853 5165 4700 4701 4702 7855 8089 5 7854 4702 7308 7856 8089 7 7855 7308 7309 7857 8089 8090 8091 7 7856 7309 7310 7858 8091 8092 8093 6 7857 7310 7311 7859 8093 8094 6 7858 7311 7312 7313 7860 8094 6 7859 7313 7861 8094 8095 8096 6 7860 7313 7314 7862 8096 8097 6 7861 7314 7315 7863 8097 8098 6 7862 7315 7316 7864 8098 8099 6 7863 7316 7317 7865 8099 8100 6 7864 7317 7318 7866 8100 8101 6 7865 7318 7319 7867 8101 8102 6 7866 7319 7320 7321 7868 8102 6 7867 7321 7869 8102 8103 8104 6 7868 7321 7322 7870 8104 8105 6 7869 7322 7323 7324 7871 8105 6 7870 7324 7872 8105 8106 8107 6 7871 7324 7325 7873 8107 8108 6 7872 7325 7326 7327 7874 8108 6 7873 7327 7875 8108 8109 8110 6 7874 7327 7328 7329 7876 8110 6 7875 7329 7877 8110 8111 8112 6 7876 7329 7330 7331 7878 8112 6 7877 7331 7332 7879 8112 8113 6 7878 7332 7880 8113 8114 8115 6 7879 7332 7333 7334 7881 8115 6 7880 7334 7335 7336 7882 8115 6 7881 7336 7337 7883 8115 8116 7 7882 7337 7338 7884 8116 8117 8118 6 7883 7338 7339 7885 8118 8119 6 7884 7339 7340 7886 8119 8120 6 7885 7340 7341 7887 8120 8121 6 7886 7341 7888 8121 8122 8123 6 7887 7341 7342 7343 7889 8123 6 7888 7343 7344 7890 8123 8124 6 7889 7344 7345 7891 8124 8125 6 7890 7345 7346 7892 8125 8126 6 7891 7346 7347 7893 8126 8127 6 7892 7347 7348 7894 8127 8128 6 7893 7348 7895 8128 8129 8130 6 7894 7348 7349 7350 7896 8130 6 7895 7350 7351 7897 8130 8131 7 7896 7351 7352 7353 7898 8131 8132 5 7897 7353 7899 8132 8133 7 7898 7353 7354 7355 7900 8133 8134 6 7899 7355 7901 8134 8135 8136 5 7900 7355 7356 7902 8136 7 7901 7356 7903 8136 8137 8138 7904 5 7902 7356 7357 7358 7904 6 7903 7358 7905 8138 7902 8139 6 7904 7358 7359 7361 7906 8139 6 7905 7361 7907 8139 8140 8141 6 7906 7361 7362 7363 7908 8141 6 7907 7363 7909 8141 8142 8143 6 7908 7363 7364 7365 7910 8143 6 7909 7365 7371 7911 8143 8144 6 7910 7371 7912 8144 8145 8146 5 7911 7371 7372 7913 8146 7 7912 7372 7373 7914 8146 8147 8148 6 7913 7373 7915 8148 8149 8150 6 7914 7373 7374 7376 7916 8150 6 7915 7376 7917 7918 7919 8150 6 7916 7376 7377 7378 7601 7918 6 7917 7601 7916 7919 7920 7603 6 7916 7918 7920 7921 7922 8150 6 7919 7918 7921 7925 7926 7603 6 7919 7920 7922 7923 7924 7925 6 7919 7921 7923 8150 8151 8149 6 7922 7921 7924 8151 8152 8153 6 7923 7921 7925 8153 8154 8155 6 7924 7921 7920 7926 8155 7928 6 7925 7920 7603 7604 7927 7928 6 7926 7604 7928 7929 7609 7605 6 7926 7927 7929 8155 7925 8157 6 7928 7927 7609 8157 7616 7610 6 7809 7810 7931 8050 8345 7808 6 7930 7810 7811 7932 7933 8050 6 7931 7811 7933 7934 7935 7936 6 7931 7932 7934 8050 8051 8052 6 7933 7932 7935 8052 8053 8057 6 7934 7932 7936 8059 8057 8060 6 7935 7932 7811 7812 7937 8060 6 7936 7812 7813 7938 8060 8061 6 7937 7813 7814 7939 8061 8062 6 7938 7814 7816 7817 7940 8062 6 7939 7817 7818 7941 8062 8063 6 7940 7818 7942 8063 8064 8065 6 7941 7818 7819 7943 8065 8066 6 7942 7819 7820 7821 7944 8066 6 7943 7821 7945 8066 8067 8068 6 7944 7821 7822 7946 8068 8069 6 7945 7822 7823 7947 8069 8070 6 7946 7823 7824 7948 8070 8071 6 7947 7824 7826 7949 8071 8072 6 7948 7826 7950 8072 8073 8074 6 7949 7826 7827 7951 8074 8075 6 7950 7827 7952 8075 8076 7953 6 7951 7827 7828 7829 7832 7953 6 7952 7832 7833 7954 8076 7951 6 7953 7833 7955 8076 8077 8078 6 7954 7833 7834 7835 7956 8078 6 7955 7835 7836 7957 8078 8079 6 7956 7836 7958 8079 8080 8081 6 7957 7836 7837 7838 7959 8081 6 7958 7838 7839 7960 8081 8082 5 7959 7839 7846 8082 7847 6 7846 7840 7841 7842 7843 7845 6 7726 7727 7963 8466 8468 9764 6 7962 7727 7964 8466 8487 8488 6 7963 7727 7728 7246 7965 8488 6 7964 7246 7247 7966 8488 8489 6 7965 7247 7248 7967 8489 8490 6 7966 7248 7249 7968 8490 8491 6 7967 7249 7511 7513 7969 8491 6 7968 7513 7970 8493 8491 8494 6 7969 7513 7514 7971 8494 8495 6 7970 7514 7972 8495 8496 7974 6 7971 7514 7515 7518 7973 7974 6 7972 7518 7974 7975 7976 7977 6 7972 7973 7975 8496 7971 8497 6 7974 7973 7976 8500 8497 7981 6 7975 7973 7977 7979 7980 7981 6 7976 7973 7518 7519 7978 7979 6 7977 7519 7979 7988 7989 7521 6 7977 7978 7976 7980 7987 7988 6 7976 7979 7981 7982 7986 7987 6 7976 7980 7982 7983 8500 7975 6 7981 7980 7983 7984 7985 7986 6 7981 7982 7984 8500 8501 8502 6 7983 7982 7985 8502 8503 8504 6 7984 7982 7986 8504 8505 8506 6 7985 7982 7980 7987 8506 7993 7 7986 7980 7979 7988 7991 7992 7993 5 7987 7979 7978 7989 7991 7 7988 7978 7521 7526 7990 7548 7991 5 7989 7526 7527 7546 7548 6 7989 7548 7549 7992 7987 7988 6 7991 7549 7551 7987 7993 7994 6 7987 7992 7994 8506 7986 8507 6 7993 7992 7551 8507 7997 7995 6 7551 7552 7558 7996 7997 7994 6 7995 7558 7559 7997 7998 7999 6 7995 7996 7998 8507 7994 8508 6 7997 7996 7999 8508 8509 8510 6 7998 7996 7559 7566 8000 8510 6 7999 7566 7567 7570 8001 8510 7 8000 7570 7571 8002 8510 8522 8511 6 8001 7571 7572 8003 8522 8523 7 8002 7572 7574 7577 8004 8520 8523 7 8003 7577 8005 8519 8517 8520 8541 5 8004 7577 7578 8006 8541 6 8005 7578 8007 8610 8540 8541 6 8006 7578 7579 7580 8008 8610 6 8007 7580 7581 8009 8010 8610 6 8008 7581 8010 8011 8012 7582 8 8008 8009 8011 8609 8537 8538 8540 8610 5 8010 8009 8012 8013 8609 6 8011 8009 8013 7587 7582 7585 7 8011 8012 7587 7729 8014 8608 8609 6 8013 7729 7730 8015 8607 8608 6 8014 7730 7734 8016 8611 8607 6 8015 7734 7735 8017 8611 8612 6 8016 7735 8018 8612 8613 8614 6 8017 7735 7736 8019 8614 8615 6 8018 7736 8020 8615 8618 8619 6 8019 7736 7737 8021 8022 8619 6 8020 7737 8022 8023 9766 7738 6 8020 8021 8023 8024 8619 8620 6 8022 8021 8024 8025 7742 9766 6 8022 8023 8025 8620 8621 8028 6 8024 8023 7742 7743 8026 8028 6 8025 7743 8027 8028 8029 8030 6 8026 7743 7744 7748 8030 8031 6 8025 8026 8029 8621 8024 8622 6 8028 8026 8030 8628 8622 8629 6 8029 8026 8027 8031 8033 8629 6 8030 8027 7748 8032 8033 8034 6 8031 7748 7749 8034 8035 8036 6 8030 8031 8034 8629 8630 8631 6 8033 8031 8032 8035 8631 8632 6 8034 8032 8036 7761 8635 8632 6 8035 8032 7749 7759 7760 7761 6 7784 7785 8038 8332 8333 8334 6 8037 7785 7787 8039 8041 8334 6 8038 7787 8040 8041 8042 8043 6 8039 7787 8043 8044 8045 7788 6 8038 8039 8042 8334 8335 8336 6 8041 8039 8043 8336 8337 8341 6 8042 8039 8040 8044 8341 8342 6 8043 8040 8045 8342 8343 8046 6 8044 8040 7788 7794 7795 8046 6 8045 7795 8047 7806 8343 8044 6 8046 7795 7806 7803 8048 7796 6 7803 8047 7796 7802 7801 8049 6 7801 8048 7796 7797 7799 7800 6 7930 7931 7933 8051 8345 8346 6 8050 7933 8052 8346 8347 8348 6 8051 7933 7934 8053 8054 8348 6 8052 7934 8054 8055 8056 8057 6 8052 8053 8055 8348 8349 8350 6 8054 8053 8056 8350 8351 8352 6 8055 8053 8057 8058 8352 8353 6 8056 8053 8058 8059 7935 7934 6 8056 8057 8059 8353 8354 8355 6 8058 8057 7935 8060 8355 8356 6 8059 7935 7936 7937 8061 8356 6 8060 7937 7938 8062 8356 8358 6 8061 7938 7939 7940 8063 8358 6 8062 7940 7941 8064 8359 8358 6 8063 7941 8065 8359 8360 8361 6 8064 7941 7942 8066 8361 8362 6 8065 7942 7943 7944 8067 8362 6 8066 7944 8068 8362 8363 8364 6 8067 7944 7945 8069 8364 8365 6 8068 7945 7946 8070 8365 8366 6 8069 7946 7947 8071 8366 8367 6 8070 7947 7948 8072 8367 8368 6 8071 7948 7949 8073 8368 8369 6 8072 7949 8074 8369 8370 8371 6 8073 7949 7950 8075 8371 8372 6 8074 7950 7951 8076 8372 8373 6 8075 7951 7953 7954 8077 8373 6 8076 7954 8078 8375 8373 8376 6 8077 7954 7955 7956 8079 8376 6 8078 7956 7957 8080 8376 8377 6 8079 7957 8081 8209 8377 8378 6 8080 7957 7958 7959 8082 8209 7 8081 7959 7960 7847 7848 8083 8209 6 8082 7848 7849 8084 8209 8210 6 8083 7849 7850 8085 8210 8211 6 8084 7850 8086 8211 8212 8213 6 8085 7850 7851 7852 8087 8213 6 8086 7852 8088 8213 8214 8215 6 8087 7852 7853 8089 8215 8090 6 8088 7853 7854 7855 7856 8090 5 8089 7856 8091 8215 8088 7 8090 7856 7857 8092 8215 8216 8217 5 8091 7857 8093 8217 8218 6 8092 7857 7858 8094 8218 8219 6 8093 7858 7859 7860 8095 8219 6 8094 7860 8096 8219 8220 8221 6 8095 7860 7861 8097 8221 8222 6 8096 7861 7862 8098 8222 8223 6 8097 7862 7863 8099 8223 8224 6 8098 7863 7864 8100 8224 8225 6 8099 7864 7865 8101 8225 8226 6 8100 7865 7866 8102 8226 8227 6 8101 7866 7867 7868 8103 8227 6 8102 7868 8104 8227 8228 8229 6 8103 7868 7869 8105 8229 8230 6 8104 7869 7870 7871 8106 8230 6 8105 7871 8107 8230 8231 8232 6 8106 7871 7872 8108 8232 8233 6 8107 7872 7873 7874 8109 8233 6 8108 7874 8110 8233 8234 8235 6 8109 7874 7875 7876 8111 8235 6 8110 7876 8112 8235 8236 8237 6 8111 7876 7877 7878 8113 8237 6 8112 7878 7879 8114 8237 8238 6 8113 7879 8115 8238 8239 8116 6 8114 7879 7880 7881 7882 8116 6 8115 7882 7883 8117 8239 8114 6 8116 7883 8118 8239 8240 8241 5 8117 7883 7884 8119 8241 6 8118 7884 7885 8120 8241 8242 6 8119 7885 7886 8121 8242 8243 6 8120 7886 7887 8122 8243 8244 6 8121 7887 8123 8244 8245 8246 6 8122 7887 7888 7889 8124 8246 6 8123 7889 7890 8125 8246 8247 6 8124 7890 7891 8126 8247 8248 6 8125 7891 7892 8127 8248 8249 6 8126 7892 7893 8128 8249 8250 6 8127 7893 7894 8129 8250 8251 6 8128 7894 8130 8251 8252 8253 6 8129 7894 7895 7896 8131 8253 6 8130 7896 7897 8132 8253 8254 5 8131 7897 7898 8133 8254 7 8132 7898 7899 8134 8254 8255 8256 5 8133 7899 7900 8135 8256 7 8134 7900 8136 8256 8257 8258 8259 6 8135 7900 7901 7902 8137 8259 6 8136 7902 8138 8259 8260 8261 6 8137 7902 7904 8139 8261 8262 6 8138 7904 7905 7906 8140 8262 6 8139 7906 8141 8262 8263 8264 6 8140 7906 7907 7908 8142 8264 6 8141 7908 8143 8264 8265 8266 6 8142 7908 7909 7910 8144 8266 6 8143 7910 7911 8145 8266 8267 6 8144 7911 8146 8267 8268 8269 6 8145 7911 7912 7913 8147 8269 6 8146 7913 8148 8269 8270 8271 6 8147 7913 7914 8149 8151 8271 5 8148 7914 8150 8151 7922 6 8149 7914 7915 7916 7919 7922 7 8148 8149 7922 7923 8152 8271 8272 5 8151 7923 8153 8272 8273 7 8152 7923 7924 8154 8273 8274 8275 6 8153 7924 8155 8156 8275 8276 7 8154 7924 8156 7925 7928 8157 7617 6 8154 8155 7617 7618 8158 8276 5 8155 7928 7929 7616 7617 6 8156 7618 8159 8276 8277 8278 6 8158 7618 7619 8160 8278 8279 7 8159 7619 7620 8161 8279 8280 8281 5 8160 7620 8162 8281 8282 7 8161 7620 7621 8163 8282 8283 8164 6 8162 7621 7622 7623 7624 8164 7 8163 7624 7625 7627 8165 8283 8162 6 8164 7627 7628 7630 8166 8283 6 8165 7630 8167 8168 8283 8282 6 8166 7630 8168 8169 8170 7631 6 8166 8167 8169 8282 8284 8285 6 8168 8167 8170 8285 8286 8287 6 8169 8167 7631 8171 8172 8287 6 8170 7631 8172 8173 7633 7632 6 8170 8171 8173 8287 8288 8289 6 8172 8171 7633 8174 8289 8290 6 8173 7633 7634 7636 8175 8290 6 8174 7636 7638 8176 8290 8291 6 8175 7638 8177 8291 8292 8293 6 8176 7638 7639 8178 8293 8294 6 8177 7639 8179 8294 8295 8296 6 8178 7639 7640 8180 8296 8297 6 8179 7640 8181 8307 8297 8308 6 8180 7640 7641 8182 8183 8308 6 8181 7641 8183 7644 7643 7642 6 8181 8182 7644 8184 8308 8309 6 8183 7644 7645 8185 8309 8310 7 8184 7645 7646 7647 8186 8310 8311 6 8185 7647 7648 8187 8311 8312 6 8186 7648 8188 8312 8313 8314 6 8187 7648 7649 8189 8314 8315 6 8188 7649 7650 8190 8315 8200 6 8189 7650 8191 8197 8199 8200 6 8190 7650 7651 8192 8197 8193 6 8191 7651 7652 7657 7658 8193 6 8192 7658 8194 8196 8197 8191 6 8193 7658 7659 7662 8195 8196 6 8194 7662 8196 8208 8204 7663 6 8194 8195 8193 8197 8198 8204 6 8193 8196 8198 8199 8190 8191 6 8197 8196 8199 8202 8203 8204 6 8197 8198 8190 8200 8201 8202 6 8190 8199 8201 8315 8189 8316 6 8200 8199 8202 8316 8317 8318 6 8201 8199 8198 8203 8205 8318 6 8202 8198 8204 8205 7699 8206 7 8203 8198 8206 8207 8208 8195 8196 5 8202 8203 7699 8318 7700 7 7699 8203 8204 7698 7669 7667 8207 6 7667 8206 8204 8208 7664 7665 5 8207 8204 8195 7663 7664 6 8080 8081 8082 8083 8210 8378 5 8209 8083 8084 8211 8378 6 8210 8084 8085 8212 8378 8379 6 8211 8085 8213 8379 8380 8381 6 8212 8085 8086 8087 8214 8381 6 8213 8087 8215 8381 8382 8216 6 8214 8087 8088 8090 8091 8216 6 8215 8091 8217 8382 8214 8383 6 8216 8091 8092 8218 8383 8384 6 8217 8092 8093 8219 8384 8385 6 8218 8093 8094 8095 8220 8385 5 8219 8095 8221 8385 8386 6 8220 8095 8096 8222 8386 8387 6 8221 8096 8097 8223 8387 8388 6 8222 8097 8098 8224 8388 8389 6 8223 8098 8099 8225 8389 8390 6 8224 8099 8100 8226 8390 8391 6 8225 8100 8101 8227 8391 8392 6 8226 8101 8102 8103 8228 8392 6 8227 8103 8229 8392 8393 8394 6 8228 8103 8104 8230 8394 8395 6 8229 8104 8105 8106 8231 8395 6 8230 8106 8232 8395 8396 8397 6 8231 8106 8107 8233 8397 8398 6 8232 8107 8108 8109 8234 8398 6 8233 8109 8235 8398 8399 8400 6 8234 8109 8110 8111 8236 8400 6 8235 8111 8237 8400 8401 8402 6 8236 8111 8112 8113 8238 8402 6 8237 8113 8114 8239 8402 8403 6 8238 8114 8116 8117 8240 8403 6 8239 8117 8241 8403 8404 8405 6 8240 8117 8118 8119 8242 8405 6 8241 8119 8120 8243 8405 8406 6 8242 8120 8121 8244 8406 8407 6 8243 8121 8122 8245 8407 8408 6 8244 8122 8246 8408 8409 8410 6 8245 8122 8123 8124 8247 8410 6 8246 8124 8125 8248 8410 8411 6 8247 8125 8126 8249 8411 8412 6 8248 8126 8127 8250 8412 8413 6 8249 8127 8128 8251 8413 8414 6 8250 8128 8129 8252 8414 8415 6 8251 8129 8253 8415 8416 8417 6 8252 8129 8130 8131 8254 8417 7 8253 8131 8132 8133 8255 8417 8418 5 8254 8133 8256 8418 8419 7 8255 8133 8134 8135 8257 8419 8420 5 8256 8135 8258 8420 8421 6 8257 8135 8259 8421 8422 8260 5 8258 8135 8136 8137 8260 6 8259 8137 8261 8422 8258 8423 6 8260 8137 8138 8262 8423 8424 6 8261 8138 8139 8140 8263 8424 6 8262 8140 8264 8424 8425 8426 6 8263 8140 8141 8142 8265 8426 6 8264 8142 8266 8426 8427 8428 7 8265 8142 8143 8144 8267 8428 8429 6 8266 8144 8145 8268 8429 8430 6 8267 8145 8269 8430 8431 8432 6 8268 8145 8146 8147 8270 8432 6 8269 8147 8271 8432 8433 8434 6 8270 8147 8148 8151 8272 8434 5 8271 8151 8152 8273 8434 7 8272 8152 8153 8274 8434 8435 8436 6 8273 8153 8275 8436 8437 8438 6 8274 8153 8154 8276 8438 8277 5 8275 8154 8156 8158 8277 6 8276 8158 8278 8438 8275 8439 6 8277 8158 8159 8279 8439 8440 7 8278 8159 8160 8280 8440 8441 8445 6 8279 8160 8281 8445 8446 8284 5 8280 8160 8161 8282 8284 7 8281 8161 8162 8283 8166 8168 8284 5 8282 8162 8164 8165 8166 6 8282 8168 8285 8446 8280 8281 6 8284 8168 8169 8286 8446 8447 6 8285 8169 8287 8447 8449 8450 6 8286 8169 8170 8172 8288 8450 6 8287 8172 8289 8450 8451 8452 6 8288 8172 8173 8290 8452 8453 6 8289 8173 8174 8175 8291 8453 6 8290 8175 8176 8292 8453 8454 6 8291 8176 8293 8454 8455 8456 6 8292 8176 8177 8294 8456 8457 6 8293 8177 8178 8295 8457 8458 6 8294 8178 8296 8461 8458 8299 6 8295 8178 8179 8297 8298 8299 6 8296 8179 8298 8307 8305 8180 6 8296 8297 8299 8300 8301 8305 6 8296 8298 8300 8461 8295 8462 6 8299 8298 8301 8302 8462 8463 6 8300 8298 8302 8303 8304 8305 6 8300 8301 8303 8463 8464 8465 6 8302 8301 8304 8465 8466 8467 6 8303 8301 8305 8306 8470 8467 6 8304 8301 8298 8306 8307 8297 6 8304 8305 8307 8470 8471 8472 6 8306 8305 8297 8180 8308 8472 6 8307 8180 8181 8183 8309 8472 6 8308 8183 8184 8310 8472 8473 6 8309 8184 8185 8311 8473 8474 5 8310 8185 8186 8312 8474 6 8311 8186 8187 8313 8474 8475 6 8312 8187 8314 8478 8475 8479 6 8313 8187 8188 8315 8479 8480 6 8314 8188 8189 8200 8316 8480 5 8315 8200 8201 8317 8480 6 8316 8201 8318 8480 8481 7708 7 8317 8201 8202 8205 7700 7707 7708 6 7765 7766 8320 8321 8853 8854 6 8319 7766 7767 8321 8322 7769 7 8319 8320 8322 8854 8855 8856 8323 5 8321 8320 7769 7771 8323 6 8322 7771 8324 8856 8321 8857 6 8323 7771 7772 8325 8857 8328 6 8324 7772 7777 8326 8327 8328 6 8325 7777 7778 7779 7780 8327 6 8326 7780 8325 8328 8329 7781 6 8325 8327 8329 8857 8324 8858 6 8328 8327 7781 7782 8330 8858 6 8329 7782 7783 8331 8858 8859 6 8330 7783 8332 8865 8862 8859 6 8331 7783 7784 8037 8333 8865 6 8332 8037 8334 8866 8865 8867 6 8333 8037 8038 8041 8335 8867 6 8334 8041 8336 8867 8868 8869 6 8335 8041 8042 8337 8338 8869 6 8336 8042 8338 8339 8340 8341 6 8336 8337 8339 8869 8870 8874 6 8338 8337 8340 8874 8875 8347 6 8339 8337 8341 8347 8346 8876 6 8340 8337 8042 8043 8342 8876 6 8341 8043 8044 8343 8344 8876 6 8342 8044 8344 7807 7806 8046 6 8342 8343 7807 7808 8345 8876 6 8344 7808 7930 8050 8346 8876 6 8345 8050 8051 8347 8340 8876 6 8346 8051 8348 8875 8339 8340 6 8347 8051 8052 8054 8349 8875 6 8348 8054 8350 8902 8875 8901 6 8349 8054 8055 8351 8901 8903 6 8350 8055 8352 8903 8904 8905 6 8351 8055 8056 8353 8905 8906 6 8352 8056 8058 8354 8906 8907 6 8353 8058 8355 8907 8908 8909 6 8354 8058 8059 8356 8357 8909 6 8355 8059 8060 8061 8357 8358 6 8355 8356 8358 8359 8909 8910 6 8357 8356 8061 8062 8359 8063 6 8357 8358 8063 8064 8360 8910 6 8359 8064 8361 8912 8910 8913 6 8360 8064 8065 8362 8913 8914 6 8361 8065 8066 8067 8363 8914 6 8362 8067 8364 8916 8914 8917 6 8363 8067 8068 8365 8917 8918 6 8364 8068 8069 8366 8918 8919 6 8365 8069 8070 8367 8919 8920 6 8366 8070 8071 8368 8920 8921 6 8367 8071 8072 8369 8921 8922 6 8368 8072 8073 8370 8922 8923 6 8369 8073 8371 8923 8924 8925 6 8370 8073 8074 8372 8925 8926 6 8371 8074 8075 8373 8374 8926 6 8372 8075 8076 8374 8375 8077 6 8372 8373 8375 8926 8927 8928 6 8374 8373 8077 8376 8928 8929 6 8375 8077 8078 8079 8377 8929 6 8376 8079 8080 8378 8929 8379 6 8377 8080 8209 8210 8211 8379 7 8378 8211 8212 8380 8929 8377 8930 5 8379 8212 8381 8930 8931 7 8380 8212 8213 8214 8382 8743 8931 6 8381 8214 8216 8383 8641 8743 6 8382 8216 8217 8384 8641 8642 6 8383 8217 8218 8385 8642 8643 6 8384 8218 8219 8220 8386 8643 7 8385 8220 8221 8387 8643 8644 8645 6 8386 8221 8222 8388 8645 8646 6 8387 8222 8223 8389 8646 8647 6 8388 8223 8224 8390 8647 8648 7 8389 8224 8225 8391 8648 8649 8650 6 8390 8225 8226 8392 8650 8651 6 8391 8226 8227 8228 8393 8651 6 8392 8228 8394 8651 8652 8653 6 8393 8228 8229 8395 8653 8654 6 8394 8229 8230 8231 8396 8654 5 8395 8231 8397 8654 8655 6 8396 8231 8232 8398 8655 8656 7 8397 8232 8233 8234 8399 8656 8657 5 8398 8234 8400 8657 8658 7 8399 8234 8235 8236 8401 8658 8659 5 8400 8236 8402 8659 8660 6 8401 8236 8237 8238 8403 8660 6 8402 8238 8239 8240 8404 8660 6 8403 8240 8405 8660 8661 8662 6 8404 8240 8241 8242 8406 8662 6 8405 8242 8243 8407 8662 8663 7 8406 8243 8244 8408 8663 8664 8665 6 8407 8244 8245 8409 8665 8666 6 8408 8245 8410 8666 8667 8668 6 8409 8245 8246 8247 8411 8668 6 8410 8247 8248 8412 8668 8669 6 8411 8248 8249 8413 8669 8670 6 8412 8249 8250 8414 8670 8671 6 8413 8250 8251 8415 8671 8672 6 8414 8251 8252 8416 8672 8673 6 8415 8252 8417 8673 8674 8675 6 8416 8252 8253 8254 8418 8675 6 8417 8254 8255 8419 8675 8676 6 8418 8255 8256 8420 8676 8677 6 8419 8256 8257 8421 8677 8678 6 8420 8257 8258 8422 8678 8679 6 8421 8258 8260 8423 8679 8680 7 8422 8260 8261 8424 8680 8681 8682 6 8423 8261 8262 8263 8425 8682 6 8424 8263 8426 8682 8683 8687 6 8425 8263 8264 8265 8427 8687 6 8426 8265 8428 8687 8688 8689 6 8427 8265 8266 8429 8689 8690 5 8428 8266 8267 8430 8690 6 8429 8267 8268 8431 8542 8690 6 8430 8268 8432 8542 8543 8544 6 8431 8268 8269 8270 8433 8544 6 8432 8270 8434 8544 8545 8546 7 8433 8270 8271 8272 8273 8435 8546 6 8434 8273 8436 8546 8547 8548 6 8435 8273 8274 8437 8548 8549 6 8436 8274 8438 8549 8550 8439 5 8437 8274 8275 8277 8439 7 8438 8277 8278 8440 8550 8437 8551 6 8439 8278 8279 8441 8442 8551 6 8440 8279 8442 8443 8444 8445 6 8440 8441 8443 8551 8552 8553 6 8442 8441 8444 8553 8554 8555 7 8443 8441 8445 8446 8447 8448 8555 5 8444 8441 8279 8280 8446 6 8445 8280 8284 8285 8447 8444 6 8446 8285 8286 8444 8448 8449 5 8444 8447 8449 8555 8556 6 8448 8447 8286 8450 8556 8557 7 8449 8286 8287 8288 8451 8557 8558 6 8450 8288 8452 8558 8559 8560 6 8451 8288 8289 8453 8560 8561 6 8452 8289 8290 8291 8454 8561 6 8453 8291 8292 8455 8561 8562 6 8454 8292 8456 8562 8563 8564 6 8455 8292 8293 8457 8564 8565 6 8456 8293 8294 8458 8459 8565 6 8457 8294 8459 8460 8461 8295 6 8457 8458 8460 8565 8566 8567 6 8459 8458 8461 8567 8568 8569 6 8460 8458 8295 8299 8462 8569 6 8461 8299 8300 8463 8569 8570 6 8462 8300 8302 8464 8570 8571 6 8463 8302 8465 8571 8572 8573 6 8464 8302 8303 8466 8573 8487 7 8465 8303 8467 8468 7962 7963 8487 6 8466 8303 8468 8469 8470 8304 6 8466 8467 8469 7962 9763 9764 7 8468 8467 8470 9094 8485 9763 8486 6 8469 8467 8304 8306 8471 9094 6 8470 8306 8472 8476 9094 8473 6 8471 8306 8307 8308 8309 8473 6 8472 8309 8310 8474 8476 8471 6 8473 8310 8311 8312 8475 8476 6 8474 8312 8476 8477 8478 8313 7 8474 8475 8477 8485 9094 8471 8473 6 8476 8475 8478 8483 8484 8485 6 8477 8475 8313 8479 8483 8482 6 8478 8313 8314 8480 8482 8481 6 8479 8314 8315 8316 8317 8481 6 8480 8317 7708 7709 8482 8479 7 8481 7709 7710 7713 8483 8478 8479 5 8482 7713 8484 8477 8478 6 8483 7713 7714 8477 8485 8486 6 8477 8484 8486 8469 9094 8476 6 8485 8484 9765 9763 8469 7714 5 8466 7963 8488 8573 8465 7 8487 7963 7964 7965 8489 8573 8574 5 8488 7965 7966 8490 8574 7 8489 7966 7967 8491 8492 8574 8575 6 8490 7967 8492 8493 7969 7968 5 8490 8491 8493 8575 8576 6 8492 8491 7969 8494 8576 8577 6 8493 7969 7970 8495 8577 8578 6 8494 7970 7971 8496 8578 8579 6 8495 7971 7974 8497 8498 8579 6 8496 7974 8498 8499 8500 7975 6 8496 8497 8499 8579 8580 8581 6 8498 8497 8500 8581 8582 8501 6 8499 8497 7975 7981 7983 8501 6 8500 7983 8502 8582 8499 8583 6 8501 7983 7984 8503 8586 8583 6 8502 7984 8504 8527 8586 8526 6 8503 7984 7985 8505 8526 8588 6 8504 7985 8506 8588 8513 8589 6 8505 7985 7986 7993 8507 8589 6 8506 7993 7994 7997 8508 8589 6 8507 7997 7998 8509 8513 8589 6 8508 7998 8510 8511 8512 8513 6 8509 7998 7999 8000 8001 8511 6 8509 8510 8512 8521 8522 8001 6 8509 8511 8513 8514 8515 8521 7 8509 8512 8514 8588 8505 8589 8508 6 8513 8512 8515 8516 8526 8588 6 8514 8512 8516 8517 8520 8521 6 8514 8515 8517 8518 8524 8526 6 8516 8515 8518 8519 8004 8520 6 8516 8517 8519 8524 8525 8531 6 8518 8517 8004 8541 8539 8531 6 8004 8517 8003 8515 8521 8523 6 8520 8515 8512 8511 8522 8523 5 8521 8511 8001 8002 8523 5 8522 8002 8521 8520 8003 6 8516 8518 8525 8526 8527 8528 6 8524 8518 8528 8529 8530 8531 7 8516 8524 8527 8503 8504 8588 8514 5 8526 8524 8528 8586 8503 6 8527 8524 8525 8529 8587 8586 6 8528 8525 8530 8602 8587 8603 6 8529 8525 8531 8532 8533 8603 6 8530 8525 8532 8519 8539 8518 6 8530 8531 8533 8534 8538 8539 6 8530 8532 8534 8535 8603 8604 6 8533 8532 8535 8536 8537 8538 6 8533 8534 8536 8604 8605 8606 6 8535 8534 8537 8606 8607 8608 6 8536 8534 8538 8608 8609 8010 6 8537 8534 8532 8539 8540 8010 6 8538 8532 8540 8541 8519 8531 6 8538 8539 8541 8010 8610 8006 6 8540 8539 8519 8006 8005 8004 6 8430 8431 8543 8690 8691 8692 6 8542 8431 8544 8692 8693 8694 6 8543 8431 8432 8433 8545 8694 6 8544 8433 8546 8694 8695 8547 5 8545 8433 8434 8435 8547 6 8546 8435 8548 8695 8545 8696 6 8547 8435 8436 8549 8696 8697 6 8548 8436 8437 8550 8697 8698 6 8549 8437 8439 8551 8698 8552 5 8550 8439 8440 8442 8552 7 8551 8442 8553 8698 8550 8699 8700 6 8552 8442 8443 8554 8700 8701 6 8553 8443 8555 8701 8702 8703 6 8554 8443 8444 8448 8556 8703 6 8555 8448 8449 8557 8703 8704 6 8556 8449 8450 8558 8704 8705 6 8557 8450 8451 8559 8705 8706 6 8558 8451 8560 8706 8707 8708 5 8559 8451 8452 8561 8708 6 8560 8452 8453 8454 8562 8708 6 8561 8454 8455 8563 8708 8709 6 8562 8455 8564 8709 8710 8711 6 8563 8455 8456 8565 8711 8712 7 8564 8456 8457 8459 8566 8712 8713 5 8565 8459 8567 8713 8714 6 8566 8459 8460 8568 8714 8715 6 8567 8460 8569 8715 8716 8717 6 8568 8460 8461 8462 8570 8717 7 8569 8462 8463 8571 8590 8592 8717 5 8570 8463 8464 8572 8590 7 8571 8464 8573 8574 8575 8576 8590 6 8572 8464 8465 8487 8488 8574 6 8573 8488 8489 8490 8575 8572 5 8574 8490 8492 8576 8572 7 8575 8492 8493 8577 8572 8590 8591 6 8576 8493 8494 8578 8594 8591 6 8577 8494 8495 8579 8594 8595 6 8578 8495 8496 8498 8580 8595 6 8579 8498 8581 8595 8596 8597 6 8580 8498 8499 8582 8597 8598 6 8581 8499 8501 8583 8584 8598 6 8582 8501 8584 8585 8586 8502 6 8582 8583 8585 8598 8599 8600 6 8584 8583 8586 8587 8600 8601 7 8585 8583 8587 8528 8527 8503 8502 6 8585 8586 8528 8601 8602 8529 5 8526 8504 8505 8513 8514 5 8513 8505 8506 8508 8507 6 8572 8576 8591 8571 8570 8592 6 8590 8576 8592 8593 8594 8577 5 8570 8590 8591 8593 8717 7 8592 8591 8594 8717 8716 8718 8719 6 8593 8591 8577 8578 8595 8719 7 8594 8578 8579 8580 8596 8719 8720 6 8595 8580 8597 8720 8721 8722 6 8596 8580 8581 8598 8722 8723 6 8597 8581 8582 8584 8599 8723 6 8598 8584 8600 8723 8724 8725 6 8599 8584 8585 8601 8725 8726 6 8600 8585 8587 8602 8726 8727 5 8601 8587 8529 8603 8727 6 8602 8529 8530 8533 8604 8727 6 8603 8533 8535 8605 8727 8728 6 8604 8535 8606 8728 8731 8732 6 8605 8535 8536 8607 8611 8732 6 8606 8536 8608 8611 8015 8014 6 8607 8536 8537 8609 8014 8013 5 8608 8537 8010 8013 8011 5 8010 8540 8008 8007 8006 6 8606 8607 8015 8016 8612 8732 6 8611 8016 8017 8613 8732 8733 6 8612 8017 8614 8733 8734 8735 6 8613 8017 8018 8615 8616 8735 6 8614 8018 8019 8616 8617 8618 6 8614 8615 8617 8735 8736 8737 6 8616 8615 8618 8737 8738 8739 6 8617 8615 8019 8619 8739 8742 6 8618 8019 8020 8022 8620 8742 6 8619 8022 8024 8621 8624 8742 6 8620 8024 8028 8622 8623 8624 6 8621 8028 8623 8627 8628 8029 6 8621 8622 8624 8625 8626 8627 6 8621 8623 8625 8741 8742 8620 6 8624 8623 8626 8837 8741 8838 6 8625 8623 8627 8838 8839 8840 6 8626 8623 8622 8628 8840 8841 6 8627 8622 8029 8629 8841 8842 6 8628 8029 8030 8033 8630 8842 6 8629 8033 8631 8842 8843 8844 6 8630 8033 8034 8632 8633 8844 6 8631 8034 8633 8634 8635 8035 6 8631 8632 8634 8844 8845 8846 6 8633 8632 8635 8636 8637 8846 6 8634 8632 8636 8640 7761 8035 6 8634 8635 8637 8638 8639 8640 6 8634 8636 8638 8846 8848 8849 6 8637 8636 8639 8849 8850 8851 6 8638 8636 8640 8851 8852 7762 5 8639 8636 8635 7761 7762 6 8382 8383 8642 8743 8744 8745 6 8641 8383 8384 8643 8745 8746 6 8642 8384 8385 8386 8644 8746 6 8643 8386 8645 8746 8747 8748 6 8644 8386 8387 8646 8748 8749 6 8645 8387 8388 8647 8749 8750 6 8646 8388 8389 8648 8750 8751 6 8647 8389 8390 8649 8751 8752 6 8648 8390 8650 8752 8753 8754 5 8649 8390 8391 8651 8754 6 8650 8391 8392 8393 8652 8754 6 8651 8393 8653 8754 8755 8756 6 8652 8393 8394 8654 8756 8757 6 8653 8394 8395 8396 8655 8757 6 8654 8396 8397 8656 8757 8758 7 8655 8397 8398 8657 8758 8759 8760 5 8656 8398 8399 8658 8760 7 8657 8399 8400 8659 8760 8761 8762 5 8658 8400 8401 8660 8762 8 8659 8401 8402 8403 8404 8661 8762 8763 5 8660 8404 8662 8763 8764 6 8661 8404 8405 8406 8663 8764 6 8662 8406 8407 8664 8764 8765 6 8663 8407 8665 8765 8766 8767 5 8664 8407 8408 8666 8767 6 8665 8408 8409 8667 8767 8768 6 8666 8409 8668 8768 8769 8770 6 8667 8409 8410 8411 8669 8770 6 8668 8411 8412 8670 8770 8771 6 8669 8412 8413 8671 8771 8772 6 8670 8413 8414 8672 8772 8773 6 8671 8414 8415 8673 8773 8774 6 8672 8415 8416 8674 8774 8775 6 8673 8416 8675 8775 8776 8777 6 8674 8416 8417 8418 8676 8777 6 8675 8418 8419 8677 8777 8778 6 8676 8419 8420 8678 8778 8779 6 8677 8420 8421 8679 8779 8780 6 8678 8421 8422 8680 8780 8781 6 8679 8422 8423 8681 8781 8782 6 8680 8423 8682 8782 8783 8684 6 8681 8423 8424 8425 8683 8684 6 8682 8425 8684 8685 8686 8687 5 8682 8683 8685 8783 8681 6 8684 8683 8686 8783 8784 8785 6 8685 8683 8687 8785 8786 8787 7 8686 8683 8425 8426 8427 8688 8787 5 8687 8427 8689 8787 8788 6 8688 8427 8428 8690 8788 8789 7 8689 8428 8429 8430 8542 8691 8789 6 8690 8542 8692 8789 8790 8791 5 8691 8542 8543 8693 8791 7 8692 8543 8694 8791 8792 8793 8794 6 8693 8543 8544 8545 8695 8794 6 8694 8545 8547 8696 8794 8795 7 8695 8547 8548 8697 8795 8796 8797 6 8696 8548 8549 8698 8797 8798 6 8697 8549 8550 8552 8699 8798 6 8698 8552 8700 8798 8799 8800 6 8699 8552 8553 8701 8800 8803 6 8700 8553 8554 8702 8803 8804 6 8701 8554 8703 8804 8805 8806 6 8702 8554 8555 8556 8704 8806 6 8703 8556 8557 8705 8806 8807 6 8704 8557 8558 8706 8807 8808 6 8705 8558 8559 8707 8808 8809 6 8706 8559 8708 8809 8810 8811 7 8707 8559 8560 8561 8562 8709 8811 5 8708 8562 8563 8710 8811 7 8709 8563 8711 8811 8812 8813 8814 6 8710 8563 8564 8712 8814 8815 6 8711 8564 8565 8713 8815 8816 5 8712 8565 8566 8714 8816 7 8713 8566 8567 8715 8816 8817 8818 6 8714 8567 8568 8716 8818 8819 6 8715 8568 8717 8593 8718 8819 6 8716 8568 8569 8570 8592 8593 6 8716 8593 8719 8819 8820 8720 5 8718 8593 8594 8595 8720 6 8719 8595 8596 8721 8820 8718 6 8720 8596 8722 8820 8821 8822 5 8721 8596 8597 8723 8822 6 8722 8597 8598 8599 8724 8822 6 8723 8599 8725 8822 8823 8824 6 8724 8599 8600 8726 8824 8825 6 8725 8600 8601 8727 8825 8729 7 8726 8601 8602 8603 8604 8728 8729 6 8727 8604 8605 8729 8730 8731 5 8727 8728 8730 8825 8726 6 8729 8728 8731 8825 8827 8828 6 8730 8728 8605 8732 8828 8829 7 8731 8605 8606 8611 8612 8733 8829 6 8732 8612 8613 8734 8830 8829 6 8733 8613 8735 8830 8831 8736 5 8734 8613 8614 8616 8736 6 8735 8616 8737 8831 8734 8832 6 8736 8616 8617 8738 8832 8833 6 8737 8617 8739 8740 8833 8834 6 8738 8617 8618 8740 8741 8742 6 8738 8739 8741 8834 8835 8836 7 8740 8739 8742 8624 8836 8837 8625 6 8741 8739 8624 8620 8619 8618 6 8381 8382 8641 8744 8931 8932 5 8743 8641 8745 8932 8933 6 8744 8641 8642 8746 8933 8934 6 8745 8642 8643 8644 8747 8934 6 8746 8644 8748 8934 8935 8936 6 8747 8644 8645 8749 8936 8937 6 8748 8645 8646 8750 8937 8938 6 8749 8646 8647 8751 8938 8939 6 8750 8647 8648 8752 8939 8940 6 8751 8648 8649 8753 8940 8941 6 8752 8649 8754 8941 8942 8943 7 8753 8649 8650 8651 8652 8755 8943 5 8754 8652 8756 8943 8944 6 8755 8652 8653 8757 8944 8945 6 8756 8653 8654 8655 8758 8945 7 8757 8655 8656 8759 8945 8946 8947 5 8758 8656 8760 8947 8948 6 8759 8656 8657 8658 8761 8948 6 8760 8658 8762 8948 8949 8950 6 8761 8658 8659 8660 8763 8950 5 8762 8660 8661 8764 8950 7 8763 8661 8662 8663 8765 8950 8951 6 8764 8663 8664 8766 8951 8952 6 8765 8664 8767 8952 8953 8954 6 8766 8664 8665 8666 8768 8954 6 8767 8666 8667 8769 8954 8955 6 8768 8667 8770 8955 8956 8957 6 8769 8667 8668 8669 8771 8957 6 8770 8669 8670 8772 8957 8958 6 8771 8670 8671 8773 8958 8959 6 8772 8671 8672 8774 8959 8960 6 8773 8672 8673 8775 8960 8961 6 8774 8673 8674 8776 8961 8962 6 8775 8674 8777 8962 8963 8964 6 8776 8674 8675 8676 8778 8964 6 8777 8676 8677 8779 8964 8965 6 8778 8677 8678 8780 8965 8966 6 8779 8678 8679 8781 8966 8967 6 8780 8679 8680 8782 8967 8968 6 8781 8680 8681 8783 8968 8969 6 8782 8681 8684 8685 8784 8969 6 8783 8685 8785 8969 8970 8971 6 8784 8685 8686 8786 8971 8972 6 8785 8686 8787 8972 8973 8974 6 8786 8686 8687 8688 8788 8974 6 8787 8688 8689 8789 8974 8975 6 8788 8689 8690 8691 8790 8975 6 8789 8691 8791 8975 8976 8977 6 8790 8691 8692 8693 8792 8977 6 8791 8693 8793 8977 8978 8979 6 8792 8693 8794 8979 8980 8795 5 8793 8693 8694 8695 8795 6 8794 8695 8696 8796 8980 8793 6 8795 8696 8797 8980 8981 8982 6 8796 8696 8697 8798 8982 8799 5 8797 8697 8698 8699 8799 6 8798 8699 8800 8801 8982 8797 6 8799 8699 8700 8801 8802 8803 6 8799 8800 8802 8982 8983 8984 6 8801 8800 8803 8984 8985 8986 6 8802 8800 8700 8701 8804 8986 6 8803 8701 8702 8805 8986 8987 6 8804 8702 8806 8987 8988 8989 6 8805 8702 8703 8704 8807 8989 6 8806 8704 8705 8808 8989 8990 7 8807 8705 8706 8809 8992 8990 8993 5 8808 8706 8707 8810 8993 6 8809 8707 8811 8993 8994 8812 6 8810 8707 8708 8709 8710 8812 6 8811 8710 8813 8994 8810 8995 6 8812 8710 8814 8995 8996 8997 6 8813 8710 8711 8815 8997 8998 5 8814 8711 8712 8816 8998 7 8815 8712 8713 8714 8817 8998 8999 6 8816 8714 8818 8999 9000 9001 6 8817 8714 8715 8819 9001 9002 6 8818 8715 8716 8718 8820 9002 6 8819 8718 8720 8721 8821 9002 6 8820 8721 8822 9002 9003 8823 6 8821 8721 8722 8723 8724 8823 6 8822 8724 8824 9003 8821 9004 6 8823 8724 8725 8825 8826 9004 7 8824 8725 8726 8729 8730 8826 8827 6 8824 8825 8827 9004 9005 9006 6 8826 8825 8730 8828 9012 9006 6 8827 8730 8731 8829 8830 9012 5 8828 8731 8830 8733 8732 7 8828 8829 8733 8734 8831 9011 9012 6 8830 8734 8736 8832 9013 9011 7 8831 8736 8737 8833 9013 9014 9015 6 8832 8737 8738 8834 9015 9016 6 8833 8738 8740 8835 9016 9017 6 8834 8740 8836 9017 9018 9019 6 8835 8740 8741 8837 9019 9020 5 8836 8741 8625 8838 9020 6 8837 8625 8626 8839 9020 9021 6 8838 8626 8840 9021 9022 9023 6 8839 8626 8627 8841 9023 9024 6 8840 8627 8628 8842 9024 9025 6 8841 8628 8629 8630 8843 9025 6 8842 8630 8844 9025 9026 9030 6 8843 8630 8631 8633 8845 9030 6 8844 8633 8846 8847 9031 9030 6 8845 8633 8634 8637 8847 8848 6 8845 8846 8848 9031 9032 9033 6 8847 8846 8637 8849 9042 9033 6 8848 8637 8638 8850 9043 9042 6 8849 8638 8851 9043 9044 9045 6 8850 8638 8639 8852 9045 9048 6 8851 8639 7762 7763 8853 9048 6 8852 7763 7765 8319 8854 9048 6 8853 8319 8321 8855 9047 9048 6 8854 8321 8856 9047 9049 9050 5 8855 8321 8323 8857 9050 7 8856 8323 8324 8328 8858 9050 8860 6 8857 8328 8329 8330 8859 8860 6 8858 8330 8860 8861 8862 8331 6 8858 8859 8861 9050 8857 9051 6 8860 8859 8862 8863 9051 9052 6 8861 8859 8863 8864 8865 8331 6 8861 8862 8864 8877 9058 9052 6 8863 8862 8865 8866 8877 8878 6 8864 8862 8866 8333 8332 8331 6 8864 8865 8333 8867 8878 8879 6 8866 8333 8334 8335 8868 8879 6 8867 8335 8869 8879 8880 8871 6 8868 8335 8336 8338 8870 8871 6 8869 8338 8871 8872 8873 8874 6 8869 8870 8872 8894 8880 8868 6 8871 8870 8873 8896 8894 8897 6 8872 8870 8874 8897 8898 8902 6 8873 8870 8338 8339 8875 8902 6 8874 8339 8347 8902 8349 8348 6 8346 8340 8341 8342 8344 8345 5 8863 8864 8878 9058 8882 6 8877 8864 8866 8879 8881 8882 6 8878 8866 8867 8868 8880 8881 6 8879 8868 8881 8893 8894 8871 6 8879 8880 8878 8882 8883 8893 6 8878 8881 8883 8884 9058 8877 6 8882 8881 8884 8885 8892 8893 6 8882 8883 8885 8886 8887 9058 6 8884 8883 8886 8890 8891 8892 6 8884 8885 8887 8888 8889 8890 6 8884 8886 8888 9058 9057 9059 6 8887 8886 8889 9059 9060 9061 6 8888 8886 8890 9061 9062 9063 6 8889 8886 8885 8891 9063 9064 6 8890 8885 8892 9064 9065 9066 6 8891 8885 8883 8893 9066 8895 6 8892 8883 8881 8880 8894 8895 6 8893 8880 8895 8896 8872 8871 6 8893 8894 8896 9066 8892 9067 6 8895 8894 8872 8897 9067 9068 6 8896 8872 8873 8898 8899 9068 6 8897 8873 8899 8900 8901 8902 6 8897 8898 8900 9068 9069 9070 6 8899 8898 8901 9070 9071 8903 6 8900 8898 8902 8349 8350 8903 6 8901 8898 8873 8874 8875 8349 6 8901 8350 8351 8904 9071 8900 6 8903 8351 8905 9071 9072 9073 6 8904 8351 8352 8906 9073 9074 6 8905 8352 8353 8907 9074 9075 6 8906 8353 8354 8908 9075 9076 6 8907 8354 8909 9076 9077 8911 6 8908 8354 8355 8357 8910 8911 6 8909 8357 8911 8912 8360 8359 6 8909 8910 8912 9077 8908 9078 6 8911 8910 8360 8913 9078 9079 6 8912 8360 8361 8914 8915 9079 6 8913 8361 8362 8915 8916 8363 6 8913 8914 8916 9079 9080 9081 6 8915 8914 8363 8917 9081 9082 6 8916 8363 8364 8918 9082 9083 6 8917 8364 8365 8919 9083 9084 6 8918 8365 8366 8920 9093 9084 6 8919 8366 8367 8921 9093 9100 6 8920 8367 8368 8922 9100 9101 6 8921 8368 8369 8923 9101 9102 6 8922 8369 8370 8924 9102 9103 6 8923 8370 8925 9103 9104 9105 6 8924 8370 8371 8926 9105 9106 6 8925 8371 8372 8374 8927 9106 6 8926 8374 8928 9106 9107 8931 6 8927 8374 8375 8929 8931 8930 6 8928 8375 8376 8377 8379 8930 5 8929 8379 8380 8931 8928 8 8930 8380 8381 8743 8932 9107 8927 8928 5 8931 8743 8744 8933 9107 8 8932 8744 8745 8934 9107 9106 9105 9108 6 8933 8745 8746 8747 8935 9108 6 8934 8747 8936 9108 9109 9110 6 8935 8747 8748 8937 9110 9111 6 8936 8748 8749 8938 9111 9112 6 8937 8749 8750 8939 9112 9113 6 8938 8750 8751 8940 9113 9114 6 8939 8751 8752 8941 9114 9115 6 8940 8752 8753 8942 9115 9116 6 8941 8753 8943 9116 9117 8944 5 8942 8753 8754 8755 8944 7 8943 8755 8756 8945 9117 8942 9118 7 8944 8756 8757 8758 8946 9118 9119 5 8945 8758 8947 9119 9120 6 8946 8758 8759 8948 9120 9121 7 8947 8759 8760 8761 8949 9121 9122 6 8948 8761 8950 9122 9123 8951 6 8949 8761 8762 8763 8764 8951 6 8950 8764 8765 8952 9123 8949 6 8951 8765 8766 8953 9123 9124 6 8952 8766 8954 9124 9125 9126 6 8953 8766 8767 8768 8955 9126 6 8954 8768 8769 8956 9126 9127 6 8955 8769 8957 9127 9128 9129 6 8956 8769 8770 8771 8958 9129 6 8957 8771 8772 8959 9129 9130 6 8958 8772 8773 8960 9130 9131 6 8959 8773 8774 8961 9131 9132 6 8960 8774 8775 8962 9132 9133 6 8961 8775 8776 8963 9133 9134 6 8962 8776 8964 9134 9135 9136 6 8963 8776 8777 8778 8965 9136 6 8964 8778 8779 8966 9136 9137 6 8965 8779 8780 8967 9137 9138 6 8966 8780 8781 8968 9138 9139 6 8967 8781 8782 8969 9139 9140 7 8968 8782 8783 8784 8970 9140 9141 5 8969 8784 8971 9141 9142 7 8970 8784 8785 8972 9142 9143 9144 6 8971 8785 8786 8973 9144 9145 6 8972 8786 8974 9145 9146 9147 6 8973 8786 8787 8788 8975 9147 6 8974 8788 8789 8790 8976 9147 6 8975 8790 8977 9147 9148 9149 6 8976 8790 8791 8792 8978 9149 6 8977 8792 8979 9149 9150 9151 6 8978 8792 8793 8980 9151 9152 6 8979 8793 8795 8796 8981 9152 6 8980 8796 8982 9152 9153 8983 6 8981 8796 8797 8799 8801 8983 6 8982 8801 8984 9153 8981 9154 6 8983 8801 8802 8985 9154 9155 6 8984 8802 8986 9155 9156 9157 7 8985 8802 8803 8804 8987 9157 9158 5 8986 8804 8805 8988 9158 7 8987 8805 8989 8990 8991 9158 9159 5 8988 8805 8806 8807 8990 6 8989 8807 8988 8991 8992 8808 6 8988 8990 8992 9159 9160 9161 6 8991 8990 8808 8993 9164 9161 6 8992 8808 8809 8810 8994 9164 6 8993 8810 8812 8995 9164 9165 7 8994 8812 8813 8996 9165 9167 9168 5 8995 8813 8997 9168 9169 6 8996 8813 8814 8998 9169 9170 7 8997 8814 8815 8816 8999 9170 9171 5 8998 8816 8817 9000 9171 6 8999 8817 9001 9171 9172 9173 6 9000 8817 8818 9002 9173 9003 6 9001 8818 8819 8820 8821 9003 6 9002 8821 8823 9004 9173 9001 6 9003 8823 8824 8826 9005 9173 6 9004 8826 9006 9007 9008 9173 6 9005 8826 9007 9011 9012 8827 6 9005 9006 9008 9009 9010 9011 6 9005 9007 9009 9173 9172 9174 5 9008 9007 9010 9174 9177 6 9009 9007 9011 9013 9177 9014 7 9010 9007 9006 9012 9013 8831 8830 5 9011 9006 8830 8828 8827 5 9010 9011 8831 8832 9014 6 9013 8832 9015 9177 9010 9178 6 9014 8832 8833 9016 9181 9178 5 9015 8833 8834 9017 9181 7 9016 8834 8835 9018 9181 9182 9188 6 9017 8835 9019 9188 9189 9190 6 9018 8835 8836 9020 9190 9191 6 9019 8836 8837 8838 9021 9191 6 9020 8838 8839 9022 9191 9192 6 9021 8839 9023 9192 9195 9196 6 9022 8839 8840 9024 9196 9197 6 9023 8840 8841 9025 9197 9027 6 9024 8841 8842 8843 9026 9027 6 9025 8843 9027 9028 9029 9030 6 9025 9026 9028 9197 9024 9198 6 9027 9026 9029 9198 9199 9203 5 9028 9026 9030 9031 9203 6 9029 9026 8843 9031 8845 8844 7 9029 9030 8845 8847 9032 9203 9204 6 9031 8847 9033 9034 9204 9205 6 9032 8847 9034 9035 9042 8848 6 9032 9033 9035 9036 9037 9205 6 9034 9033 9036 9040 9041 9042 6 9034 9035 9037 9038 9039 9040 6 9034 9036 9038 9205 9206 9207 6 9037 9036 9039 9207 9208 9209 6 9038 9036 9040 9209 9062 9061 6 9039 9036 9035 9041 9061 9060 6 9040 9035 9042 9043 9060 9210 6 9041 9035 9033 8848 9043 8849 6 9041 9042 8849 8850 9044 9210 7 9043 8850 9045 9046 9055 9056 9210 6 9044 8850 8851 9046 9047 9048 6 9044 9045 9047 9053 9055 9049 6 9046 9045 9048 8854 8855 9049 6 9047 9045 8851 8854 8853 8852 6 9047 8855 9050 9051 9053 9046 6 9049 8855 8856 8857 8860 9051 6 9050 8860 8861 9052 9053 9049 6 9051 8861 9053 9054 9058 8863 6 9051 9052 9054 9055 9046 9049 6 9053 9052 9055 9056 9057 9058 5 9053 9054 9046 9044 9056 6 9044 9055 9054 9057 9059 9210 5 9056 9054 9058 8887 9059 8 9057 9054 9052 8863 8877 8882 8884 8887 6 9057 8887 8888 9060 9210 9056 6 9059 8888 9061 9040 9041 9210 6 9060 8888 8889 9062 9039 9040 6 9061 8889 9063 9209 9039 9211 6 9062 8889 8890 9064 9211 9212 6 9063 8890 8891 9065 9212 9213 6 9064 8891 9066 9213 9214 9215 6 9065 8891 8892 8895 9067 9215 6 9066 8895 8896 9068 9215 9216 6 9067 8896 8897 8899 9069 9216 6 9068 8899 9070 9216 9217 9218 6 9069 8899 8900 9071 9218 9219 7 9070 8900 8903 8904 9072 9219 9220 5 9071 8904 9073 9220 9221 7 9072 8904 8905 9074 9221 9222 9223 6 9073 8905 8906 9075 9223 9225 6 9074 8906 8907 9076 9225 9226 5 9075 8907 8908 9077 9226 7 9076 8908 8911 9078 9226 9227 9228 5 9077 8911 8912 9079 9228 6 9078 8912 8913 8915 9080 9228 6 9079 8915 9081 9228 9229 9230 6 9080 8915 8916 9082 9230 9231 6 9081 8916 8917 9083 9231 9232 6 9082 8917 8918 9084 9085 9232 6 9083 8918 9085 9086 9093 8919 6 9083 9084 9086 9087 9232 9233 6 9085 9084 9087 9088 9092 9093 6 9085 9086 9088 9089 9233 9234 6 9087 9086 9089 9090 9091 9092 6 9087 9088 9090 9095 9234 9235 6 9089 9088 9091 9095 9096 9097 6 9090 9088 9092 9097 9098 9099 6 9091 9088 9086 9093 9099 9100 6 9092 9086 9084 8919 8920 9100 5 8469 8470 8485 8476 8471 6 9089 9090 9096 9235 9236 9237 6 9095 9090 9097 9237 9238 9239 6 9096 9090 9091 9098 9239 9240 6 9097 9091 9099 9240 9241 9242 6 9098 9091 9092 9100 9242 9101 6 9099 9092 9093 8920 8921 9101 6 9100 8921 8922 9102 9242 9099 6 9101 8922 8923 9103 9242 9243 6 9102 8923 8924 9104 9243 9244 6 9103 8924 9105 9109 9244 9108 6 9104 8924 8925 9106 8933 9108 6 9105 8925 8926 8927 9107 8933 5 9106 8927 8931 8932 8933 6 9105 8933 8934 8935 9109 9104 5 9108 8935 9110 9244 9104 7 9109 8935 8936 9111 9245 9244 9348 6 9110 8936 8937 9112 9350 9348 5 9111 8937 8938 9113 9350 6 9112 8938 8939 9114 9350 9351 6 9113 8939 8940 9115 9351 9352 6 9114 8940 8941 9116 9352 9353 6 9115 8941 8942 9117 9246 9353 6 9116 8942 8944 9118 9246 9247 6 9117 8944 8945 9119 9247 9248 5 9118 8945 8946 9120 9248 7 9119 8946 8947 9121 9248 9249 9250 6 9120 8947 8948 9122 9250 9251 5 9121 8948 8949 9123 9251 6 9122 8949 8951 8952 9124 9251 6 9123 8952 8953 9125 9251 9252 6 9124 8953 9126 9252 9253 9254 6 9125 8953 8954 8955 9127 9254 6 9126 8955 8956 9128 9254 9255 6 9127 8956 9129 9255 9256 9257 6 9128 8956 8957 8958 9130 9257 6 9129 8958 8959 9131 9257 9258 6 9130 8959 8960 9132 9258 9259 6 9131 8960 8961 9133 9259 9260 6 9132 8961 8962 9134 9260 9261 6 9133 8962 8963 9135 9261 9262 6 9134 8963 9136 9262 9263 9264 6 9135 8963 8964 8965 9137 9264 6 9136 8965 8966 9138 9264 9265 6 9137 8966 8967 9139 9265 9266 6 9138 8967 8968 9140 9266 9267 6 9139 8968 8969 9141 9267 9268 5 9140 8969 8970 9142 9268 7 9141 8970 8971 9143 9268 9269 9270 6 9142 8971 9144 9270 9271 9272 5 9143 8971 8972 9145 9272 6 9144 8972 8973 9146 9272 9273 6 9145 8973 9147 9273 9274 9148 6 9146 8973 8974 8975 8976 9148 6 9147 8976 9149 9274 9146 9275 6 9148 8976 8977 8978 9150 9275 6 9149 8978 9151 9275 9276 9277 6 9150 8978 8979 9152 9277 9278 7 9151 8979 8980 8981 9153 9278 9279 6 9152 8981 8983 9154 9279 9280 6 9153 8983 8984 9155 9280 9281 6 9154 8984 8985 9156 9281 9282 6 9155 8985 9157 9282 9283 9284 6 9156 8985 8986 9158 9284 9285 6 9157 8986 8987 8988 9159 9285 6 9158 8988 8991 9160 9285 9286 6 9159 8991 9161 9162 9286 9287 6 9160 8991 9162 9163 9164 8992 6 9160 9161 9163 9287 9288 9289 6 9162 9161 9164 9165 9166 9289 6 9163 9161 8992 8993 8994 9165 6 9164 8994 8995 9163 9166 9167 6 9163 9165 9167 9289 9290 9186 6 9166 9165 8995 9168 9186 9185 6 9167 8995 8996 9169 9185 9184 7 9168 8996 8997 9170 9184 9179 9176 6 9169 8997 8998 9171 9176 9175 6 9170 8998 8999 9000 9172 9175 6 9171 9000 9173 9008 9174 9175 7 9172 9000 9001 9003 9004 9005 9008 6 9172 9008 9009 9175 9176 9177 5 9172 9174 9176 9170 9171 6 9175 9174 9177 9179 9169 9170 7 9176 9174 9009 9010 9014 9178 9179 6 9177 9014 9179 9180 9181 9015 6 9177 9178 9180 9184 9169 9176 6 9179 9178 9181 9182 9183 9184 6 9180 9178 9015 9016 9017 9182 6 9181 9017 9180 9183 9187 9188 6 9180 9182 9184 9185 9186 9187 6 9180 9183 9185 9168 9169 9179 5 9184 9183 9186 9167 9168 6 9185 9183 9187 9290 9166 9167 6 9186 9183 9182 9188 9290 9291 6 9187 9182 9017 9018 9189 9291 5 9188 9018 9190 9291 9292 6 9189 9018 9019 9191 9292 9193 6 9190 9019 9020 9021 9192 9193 6 9191 9021 9022 9193 9194 9195 6 9191 9192 9194 9292 9190 9293 6 9193 9192 9195 9293 9294 9295 6 9194 9192 9022 9196 9295 9296 6 9195 9022 9023 9197 9302 9296 7 9196 9023 9024 9027 9198 9302 9303 6 9197 9027 9028 9199 9200 9303 6 9198 9028 9200 9201 9202 9203 6 9198 9199 9201 9303 9301 9304 6 9200 9199 9202 9304 9305 9306 6 9201 9199 9203 9306 9307 9204 6 9202 9199 9028 9029 9031 9204 7 9203 9031 9032 9205 9307 9202 9206 5 9204 9032 9034 9037 9206 6 9205 9037 9207 9307 9204 9308 6 9206 9037 9038 9208 9308 9309 6 9207 9038 9209 9309 9310 9314 6 9208 9038 9039 9062 9211 9314 6 9060 9041 9043 9059 9056 9044 6 9209 9062 9063 9212 9314 9315 6 9211 9063 9064 9213 9315 9316 6 9212 9064 9065 9214 9319 9316 6 9213 9065 9215 9319 9320 9321 6 9214 9065 9066 9067 9216 9321 6 9215 9067 9068 9069 9217 9321 7 9216 9069 9218 9321 9320 9322 9323 5 9217 9069 9070 9219 9323 7 9218 9070 9071 9220 9323 9324 9325 5 9219 9071 9072 9221 9325 7 9220 9072 9073 9222 9325 9326 9327 6 9221 9073 9223 9224 9327 9328 5 9222 9073 9074 9224 9225 6 9222 9223 9225 9328 9329 9330 6 9224 9223 9074 9075 9226 9330 7 9225 9075 9076 9077 9227 9330 9331 6 9226 9077 9228 9331 9332 9229 6 9227 9077 9078 9079 9080 9229 7 9228 9080 9230 9332 9227 9333 9334 6 9229 9080 9081 9231 9334 9335 6 9230 9081 9082 9232 9335 9336 7 9231 9082 9083 9085 9233 9336 9337 5 9232 9085 9087 9234 9337 7 9233 9087 9089 9235 9337 9338 9339 5 9234 9089 9095 9236 9339 7 9235 9095 9237 9339 9340 9341 9342 6 9236 9095 9096 9238 9342 9343 6 9237 9096 9239 9343 9344 9345 6 9238 9096 9097 9240 9345 9346 6 9239 9097 9098 9241 9346 9347 6 9240 9098 9242 9347 9245 9243 6 9241 9098 9099 9101 9102 9243 6 9242 9102 9103 9244 9245 9241 6 9243 9103 9245 9110 9109 9104 6 9243 9244 9110 9347 9241 9348 6 9116 9117 9247 9353 9354 9355 6 9246 9117 9118 9248 9355 9356 6 9247 9118 9119 9120 9249 9356 6 9248 9120 9250 9356 9357 9358 6 9249 9120 9121 9251 9358 9252 6 9250 9121 9122 9123 9124 9252 7 9251 9124 9125 9253 9358 9250 9359 5 9252 9125 9254 9359 9360 7 9253 9125 9126 9127 9255 9360 9361 6 9254 9127 9128 9256 9361 9362 6 9255 9128 9257 9362 9363 9364 6 9256 9128 9129 9130 9258 9364 7 9257 9130 9131 9259 9364 9365 9366 6 9258 9131 9132 9260 9366 9367 6 9259 9132 9133 9261 9367 9368 6 9260 9133 9134 9262 9368 9369 6 9261 9134 9135 9263 9369 9370 6 9262 9135 9264 9370 9371 9372 6 9263 9135 9136 9137 9265 9372 6 9264 9137 9138 9266 9372 9373 6 9265 9138 9139 9267 9373 9374 6 9266 9139 9140 9268 9374 9375 7 9267 9140 9141 9142 9269 9375 9376 5 9268 9142 9270 9376 9377 6 9269 9142 9143 9271 9377 9381 6 9270 9143 9272 9381 9382 9383 6 9271 9143 9144 9145 9273 9383 6 9272 9145 9146 9274 9383 9384 6 9273 9146 9148 9275 9384 9385 7 9274 9148 9149 9150 9276 9385 9386 5 9275 9150 9277 9386 9388 6 9276 9150 9151 9278 9388 9389 6 9277 9151 9152 9279 9389 9390 6 9278 9152 9153 9280 9390 9391 5 9279 9153 9154 9281 9391 6 9280 9154 9155 9282 9393 9391 6 9281 9155 9156 9283 9393 9394 6 9282 9156 9284 9394 9395 9396 6 9283 9156 9157 9285 9396 9397 6 9284 9157 9158 9159 9286 9397 6 9285 9159 9160 9287 9397 9398 5 9286 9160 9162 9288 9398 7 9287 9162 9289 9398 9399 9400 9401 6 9288 9162 9163 9166 9290 9401 7 9289 9166 9186 9187 9291 9402 9401 6 9290 9187 9188 9189 9292 9402 7 9291 9189 9190 9193 9293 9402 9400 6 9292 9193 9194 9294 9400 9403 6 9293 9194 9295 9403 9404 9405 6 9294 9194 9195 9296 9297 9405 6 9295 9195 9297 9298 9302 9196 6 9295 9296 9298 9299 9405 9406 6 9297 9296 9299 9300 9301 9302 6 9297 9298 9300 9409 9406 9410 6 9299 9298 9301 9410 9411 9412 7 9300 9298 9302 9303 9200 9304 9412 6 9301 9298 9296 9196 9197 9303 5 9302 9197 9198 9200 9301 5 9301 9200 9201 9305 9412 7 9304 9201 9306 9412 9413 9414 9418 5 9305 9201 9202 9307 9418 6 9306 9202 9204 9206 9308 9418 6 9307 9206 9207 9309 9417 9418 6 9308 9207 9208 9310 9311 9417 6 9309 9208 9311 9312 9313 9314 6 9309 9310 9312 9416 9417 9419 6 9311 9310 9313 9419 9420 9424 7 9312 9310 9314 9424 9425 9317 9315 6 9313 9310 9208 9209 9211 9315 6 9314 9211 9212 9316 9317 9313 6 9315 9212 9317 9318 9319 9213 6 9315 9316 9318 9425 9313 9426 6 9317 9316 9319 9426 9427 9428 6 9318 9316 9213 9214 9320 9428 6 9319 9214 9321 9217 9322 9428 5 9320 9214 9215 9216 9217 6 9320 9217 9323 9428 9429 9430 6 9322 9217 9218 9219 9324 9430 6 9323 9219 9325 9430 9431 9432 6 9324 9219 9220 9221 9326 9432 6 9325 9221 9327 9432 9433 9434 6 9326 9221 9222 9328 9434 9435 5 9327 9222 9224 9329 9435 7 9328 9224 9330 9435 9436 9437 9438 6 9329 9224 9225 9226 9331 9438 6 9330 9226 9227 9332 9438 9439 6 9331 9227 9229 9333 9442 9439 6 9332 9229 9334 9442 9443 9446 5 9333 9229 9230 9335 9446 6 9334 9230 9231 9336 9446 9447 6 9335 9231 9232 9337 9447 9448 6 9336 9232 9233 9234 9338 9448 6 9337 9234 9339 9448 9449 9450 6 9338 9234 9235 9236 9340 9450 6 9339 9236 9341 9450 9451 9452 6 9340 9236 9342 9452 9453 9454 6 9341 9236 9237 9343 9454 9455 5 9342 9237 9238 9344 9455 7 9343 9238 9345 9455 9456 9457 9458 6 9344 9238 9239 9346 9458 9349 5 9345 9239 9240 9347 9349 6 9346 9240 9241 9245 9348 9349 6 9347 9245 9349 9350 9111 9110 7 9347 9348 9350 9458 9345 9346 9351 6 9349 9348 9111 9112 9113 9351 7 9350 9113 9114 9352 9458 9349 9459 6 9351 9114 9115 9353 9459 9460 6 9352 9115 9116 9246 9354 9460 6 9353 9246 9355 9460 9461 9462 6 9354 9246 9247 9356 9462 9463 6 9355 9247 9248 9249 9357 9463 6 9356 9249 9358 9463 9464 9465 6 9357 9249 9250 9252 9359 9465 5 9358 9252 9253 9360 9465 7 9359 9253 9254 9361 9465 9466 9467 5 9360 9254 9255 9362 9467 6 9361 9255 9256 9363 9467 9468 6 9362 9256 9364 9468 9469 9470 6 9363 9256 9257 9258 9365 9470 6 9364 9258 9366 9470 9471 9472 5 9365 9258 9259 9367 9472 6 9366 9259 9260 9368 9472 9473 6 9367 9260 9261 9369 9473 9474 6 9368 9261 9262 9370 9474 9475 6 9369 9262 9263 9371 9475 9476 6 9370 9263 9372 9476 9477 9478 6 9371 9263 9264 9265 9373 9478 6 9372 9265 9266 9374 9478 9479 6 9373 9266 9267 9375 9479 9480 6 9374 9267 9268 9376 9480 9481 6 9375 9268 9269 9377 9378 9481 7 9376 9269 9270 9378 9379 9380 9381 5 9376 9377 9379 9481 9482 6 9378 9377 9380 9482 9483 9484 6 9379 9377 9381 9484 9485 9382 5 9380 9377 9270 9271 9382 6 9381 9271 9383 9485 9380 9486 7 9382 9271 9272 9273 9384 9486 9487 6 9383 9273 9274 9385 9487 9488 6 9384 9274 9275 9386 9387 9488 5 9385 9275 9276 9387 9388 6 9385 9386 9388 9488 9489 9490 7 9387 9386 9276 9277 9389 9490 9491 6 9388 9277 9278 9390 9491 9492 6 9389 9278 9279 9391 9392 9492 6 9390 9279 9392 9393 9281 9280 6 9390 9391 9393 9492 9493 9494 6 9392 9391 9281 9282 9394 9494 6 9393 9282 9283 9395 9494 9495 6 9394 9283 9396 9495 9496 9497 6 9395 9283 9284 9397 9498 9497 6 9396 9284 9285 9286 9398 9498 6 9397 9286 9287 9288 9399 9498 6 9398 9288 9400 9498 9404 9403 7 9399 9288 9401 9402 9292 9293 9403 5 9400 9288 9402 9290 9289 5 9400 9401 9290 9291 9292 5 9400 9293 9294 9404 9399 6 9403 9294 9405 9498 9399 9407 6 9404 9294 9295 9297 9406 9407 6 9405 9297 9407 9408 9409 9299 6 9405 9406 9408 9497 9498 9404 6 9407 9406 9409 9496 9497 9499 6 9408 9406 9299 9410 9499 9500 6 9409 9299 9300 9411 9500 9501 6 9410 9300 9412 9501 9502 9413 6 9411 9300 9301 9304 9305 9413 6 9412 9305 9414 9415 9502 9411 6 9413 9305 9415 9416 9417 9418 6 9413 9414 9416 9502 9503 9504 6 9415 9414 9417 9311 9419 9504 6 9416 9414 9418 9308 9309 9311 6 9417 9414 9308 9307 9306 9305 6 9416 9311 9312 9420 9421 9504 6 9419 9312 9421 9422 9423 9424 6 9419 9420 9422 9504 9505 9506 6 9421 9420 9423 9506 9507 9508 6 9422 9420 9424 9511 9508 9512 6 9423 9420 9312 9313 9425 9512 5 9424 9313 9317 9426 9512 6 9425 9317 9318 9427 9512 9513 6 9426 9318 9428 9513 9514 9429 6 9427 9318 9319 9320 9322 9429 6 9428 9322 9430 9517 9514 9427 6 9429 9322 9323 9324 9431 9517 6 9430 9324 9432 9524 9517 9525 6 9431 9324 9325 9326 9433 9525 6 9432 9326 9434 9525 9526 9527 6 9433 9326 9327 9435 9527 9528 6 9434 9327 9328 9329 9436 9528 6 9435 9329 9437 9528 9530 9531 6 9436 9329 9438 9531 9532 9440 6 9437 9329 9330 9331 9439 9440 6 9438 9331 9440 9441 9442 9332 5 9438 9439 9441 9532 9437 7 9440 9439 9442 9443 9444 9532 9533 5 9441 9439 9332 9333 9443 6 9442 9333 9441 9444 9445 9446 5 9441 9443 9445 9533 9534 6 9444 9443 9446 9534 9535 9536 7 9445 9443 9333 9334 9335 9447 9536 6 9446 9335 9336 9448 9536 9537 6 9447 9336 9337 9338 9449 9537 6 9448 9338 9450 9537 9538 9451 5 9449 9338 9339 9340 9451 7 9450 9340 9452 9538 9449 9539 9540 6 9451 9340 9341 9453 9540 9541 6 9452 9341 9454 9541 9542 9543 6 9453 9341 9342 9455 9543 9544 6 9454 9342 9343 9344 9456 9544 6 9455 9344 9457 9544 9545 9461 6 9456 9344 9458 9461 9460 9459 6 9457 9344 9345 9349 9351 9459 5 9458 9351 9352 9460 9457 6 9459 9352 9353 9354 9461 9457 6 9460 9354 9462 9545 9456 9457 5 9461 9354 9355 9463 9545 7 9462 9355 9356 9357 9464 9545 9546 6 9463 9357 9465 9546 9547 9548 7 9464 9357 9358 9359 9360 9466 9548 6 9465 9360 9467 9548 9549 9550 6 9466 9360 9361 9362 9468 9550 6 9467 9362 9363 9469 9550 9551 6 9468 9363 9470 9551 9552 9553 6 9469 9363 9364 9365 9471 9553 6 9470 9365 9472 9553 9554 9555 6 9471 9365 9366 9367 9473 9555 6 9472 9367 9368 9474 9555 9556 6 9473 9368 9369 9475 9556 9557 6 9474 9369 9370 9476 9557 9558 6 9475 9370 9371 9477 9558 9559 6 9476 9371 9478 9559 9560 9561 6 9477 9371 9372 9373 9479 9561 6 9478 9373 9374 9480 9561 9562 6 9479 9374 9375 9481 9562 9563 6 9480 9375 9376 9378 9482 9563 6 9481 9378 9379 9483 9563 9564 6 9482 9379 9484 9564 9565 9566 6 9483 9379 9380 9485 9566 9567 6 9484 9380 9382 9486 9567 9568 6 9485 9382 9383 9487 9568 9569 6 9486 9383 9384 9488 9569 9570 6 9487 9384 9385 9387 9489 9570 6 9488 9387 9490 9570 9571 9572 6 9489 9387 9388 9491 9572 9573 6 9490 9388 9389 9492 9573 9574 6 9491 9389 9390 9392 9493 9574 6 9492 9392 9494 9574 9575 9576 6 9493 9392 9393 9394 9495 9576 6 9494 9394 9395 9496 9576 9577 6 9495 9395 9497 9408 9499 9577 6 9496 9395 9408 9407 9498 9396 7 9407 9497 9396 9397 9398 9399 9404 5 9496 9408 9409 9500 9577 7 9499 9409 9410 9501 9577 9578 9579 6 9500 9410 9411 9502 9579 9580 6 9501 9411 9413 9415 9503 9580 6 9502 9415 9504 9580 9581 9582 7 9503 9415 9416 9419 9421 9505 9582 5 9504 9421 9506 9582 9583 6 9505 9421 9422 9507 9583 9584 6 9506 9422 9508 9509 9584 9585 6 9507 9422 9509 9510 9511 9423 6 9507 9508 9510 9585 9586 9587 6 9509 9508 9511 9518 9587 9521 6 9510 9508 9423 9512 9518 9519 7 9511 9423 9424 9425 9426 9513 9519 6 9512 9426 9427 9514 9515 9519 6 9513 9427 9515 9516 9517 9429 6 9513 9514 9516 9519 9518 9520 6 9515 9514 9517 9523 9520 9524 6 9516 9514 9429 9430 9524 9431 6 9510 9511 9519 9515 9520 9521 5 9518 9511 9512 9513 9515 6 9518 9515 9521 9522 9523 9516 6 9518 9520 9522 9587 9510 9588 6 9521 9520 9523 9588 9589 9590 6 9522 9520 9516 9524 9590 9591 6 9523 9516 9517 9431 9525 9591 7 9524 9431 9432 9433 9526 9591 9592 5 9525 9433 9527 9592 9593 6 9526 9433 9434 9528 9529 9593 6 9527 9434 9435 9436 9529 9530 6 9527 9528 9530 9593 9594 9595 6 9529 9528 9436 9531 9595 9596 6 9530 9436 9437 9532 9596 9597 7 9531 9437 9440 9441 9533 9597 9598 5 9532 9441 9444 9534 9598 7 9533 9444 9445 9535 9598 9599 9600 6 9534 9445 9536 9600 9601 9602 7 9535 9445 9446 9447 9537 9602 9603 6 9536 9447 9448 9449 9538 9603 6 9537 9449 9451 9539 9603 9604 6 9538 9451 9540 9604 9605 9606 6 9539 9451 9452 9541 9606 9607 5 9540 9452 9453 9542 9607 7 9541 9453 9543 9607 9608 9609 9610 5 9542 9453 9454 9544 9610 7 9543 9454 9455 9456 9545 9610 9546 6 9544 9456 9461 9462 9463 9546 6 9545 9463 9464 9547 9610 9544 6 9546 9464 9548 9610 9609 9549 5 9547 9464 9465 9466 9549 6 9548 9466 9550 9609 9547 9611 6 9549 9466 9467 9468 9551 9611 6 9550 9468 9469 9552 9611 9612 6 9551 9469 9553 9612 9613 9614 6 9552 9469 9470 9471 9554 9614 6 9553 9471 9555 9614 9615 9616 6 9554 9471 9472 9473 9556 9616 6 9555 9473 9474 9557 9616 9617 6 9556 9474 9475 9558 9617 9618 6 9557 9475 9476 9559 9618 9619 6 9558 9476 9477 9560 9619 9620 6 9559 9477 9561 9620 9621 9622 6 9560 9477 9478 9479 9562 9622 6 9561 9479 9480 9563 9622 9623 6 9562 9480 9481 9482 9564 9623 6 9563 9482 9483 9565 9623 9624 6 9564 9483 9566 9624 9625 9626 6 9565 9483 9484 9567 9626 9627 6 9566 9484 9485 9568 9627 9628 7 9567 9485 9486 9569 9628 9629 9630 6 9568 9486 9487 9570 9630 9631 6 9569 9487 9488 9489 9571 9631 6 9570 9489 9572 9631 9632 9633 6 9571 9489 9490 9573 9633 9634 6 9572 9490 9491 9574 9634 9635 6 9573 9491 9492 9493 9575 9635 6 9574 9493 9576 9635 9636 9578 6 9575 9493 9494 9495 9577 9578 6 9576 9495 9496 9499 9500 9578 6 9577 9500 9579 9636 9575 9576 6 9578 9500 9501 9580 9636 9581 5 9579 9501 9502 9503 9581 6 9580 9503 9582 9636 9579 9637 6 9581 9503 9504 9505 9583 9637 6 9582 9505 9506 9584 9637 9638 6 9583 9506 9507 9585 9638 9633 6 9584 9507 9509 9586 9633 9632 6 9585 9509 9587 9632 9639 9629 6 9586 9509 9510 9521 9588 9629 6 9587 9521 9522 9589 9629 9628 6 9588 9522 9590 9628 9627 9640 6 9589 9522 9523 9591 9640 9641 6 9590 9523 9524 9525 9592 9641 6 9591 9525 9526 9593 9641 9642 7 9592 9526 9527 9529 9594 9642 9643 5 9593 9529 9595 9643 9644 6 9594 9529 9530 9596 9644 9645 6 9595 9530 9531 9597 9645 9646 6 9596 9531 9532 9598 9646 9647 6 9597 9532 9533 9534 9599 9647 5 9598 9534 9600 9647 9648 7 9599 9534 9535 9601 9648 9649 9650 5 9600 9535 9602 9650 9651 6 9601 9535 9536 9603 9651 9604 5 9602 9536 9537 9538 9604 6 9603 9538 9539 9605 9651 9602 6 9604 9539 9606 9651 9652 9653 6 9605 9539 9540 9607 9653 9613 6 9606 9540 9541 9542 9608 9613 6 9607 9542 9609 9613 9612 9611 6 9608 9542 9610 9547 9549 9611 6 9609 9542 9543 9544 9546 9547 6 9609 9549 9550 9551 9612 9608 5 9611 9551 9552 9613 9608 7 9612 9552 9614 9653 9606 9607 9608 6 9613 9552 9553 9554 9615 9653 6 9614 9554 9616 9653 9652 9654 6 9615 9554 9555 9556 9617 9654 6 9616 9556 9557 9618 9654 9655 6 9617 9557 9558 9619 9655 9656 6 9618 9558 9559 9620 9656 9657 6 9619 9559 9560 9621 9657 9658 6 9620 9560 9622 9658 9659 9660 6 9621 9560 9561 9562 9623 9660 6 9622 9562 9563 9564 9624 9660 7 9623 9564 9565 9625 9660 9661 9662 5 9624 9565 9626 9662 9663 7 9625 9565 9566 9627 9663 9664 9640 6 9626 9566 9567 9628 9589 9640 6 9627 9567 9568 9629 9588 9589 7 9628 9568 9630 9639 9586 9587 9588 5 9629 9568 9569 9631 9639 6 9630 9569 9570 9571 9632 9639 6 9631 9571 9633 9585 9586 9639 7 9632 9571 9572 9634 9638 9584 9585 6 9633 9572 9573 9635 9637 9638 6 9634 9573 9574 9575 9636 9637 6 9635 9575 9578 9579 9581 9637 7 9636 9581 9582 9583 9638 9635 9634 5 9637 9583 9584 9633 9634 5 9632 9586 9629 9630 9631 6 9627 9589 9590 9641 9664 9626 6 9640 9590 9591 9592 9642 9664 6 9641 9592 9593 9643 9664 9663 6 9642 9593 9594 9644 9663 9662 7 9643 9594 9595 9645 9662 9661 9665 7 9644 9595 9596 9646 9665 9659 9666 6 9645 9596 9597 9647 9666 9667 6 9646 9597 9598 9599 9648 9667 6 9647 9599 9600 9649 9667 9668 6 9648 9600 9650 9668 9656 9655 6 9649 9600 9601 9651 9655 9669 7 9650 9601 9602 9604 9605 9652 9669 6 9651 9605 9653 9615 9654 9669 6 9652 9605 9606 9613 9614 9615 6 9652 9615 9616 9617 9655 9669 7 9654 9617 9618 9656 9649 9650 9669 6 9655 9618 9619 9657 9668 9649 5 9656 9619 9620 9658 9668 6 9657 9620 9621 9659 9668 9666 6 9658 9621 9660 9665 9645 9666 7 9659 9621 9622 9623 9624 9661 9665 5 9660 9624 9662 9644 9665 6 9661 9624 9625 9663 9643 9644 6 9662 9625 9626 9664 9642 9643 5 9663 9626 9640 9641 9642 5 9661 9644 9645 9659 9660 6 9659 9645 9646 9667 9668 9658 5 9666 9646 9647 9648 9668 7 9667 9648 9649 9656 9657 9658 9666 5 9655 9650 9651 9652 9654 6 6653 6650 6651 9671 9691 9681 6 9670 6651 9672 9676 9680 9681 6 9671 6651 9673 9674 9675 9676 6 9672 6651 9674 6649 9727 6365 6 9672 9673 9675 9725 9726 9727 6 9672 9674 9676 9677 9678 9725 6 9672 9675 9677 9679 9680 9671 5 9676 9675 9678 5235 9679 7 9677 9675 5235 9734 4519 9725 9733 6 9677 5235 5236 9676 9680 9683 7 9676 9679 9671 9681 9682 4654 9683 6 9671 9680 9682 9691 9670 9685 5 9681 9680 4654 4655 9685 6 4654 9680 9679 5236 4652 9684 6 4652 9683 4650 422 5237 5236 6 9682 4655 9686 9687 9691 9681 6 9685 4655 9687 3169 9688 4656 6 9685 9686 3169 3170 9691 3172 7 3169 9686 4656 9689 3168 2843 9690 5 9688 4656 5380 430 9690 6 2843 9688 9689 430 2841 429 6 9685 9687 3172 6653 9670 9681 6 6475 6478 6474 9779 9774 9780 6 6460 6461 6465 6467 6377 6378 6 5862 5863 9695 9702 9703 9700 6 9694 5863 5864 9696 5719 9700 5 9695 5864 5865 5718 5719 6 5718 5865 5866 5867 9698 9699 6 9697 5867 9699 5695 5694 5868 5 9697 9698 5695 5696 5718 6 9695 5719 5720 9701 9702 9694 5 9700 5720 5721 5724 9702 6 9701 5724 6095 9703 9694 9700 6 9702 6095 6383 9694 5862 5861 6 6490 2252 415 2194 6488 6489 7 6488 2195 6487 6480 2196 9773 9778 5 2251 6491 3336 6492 3335 6 3335 6492 3334 6499 6493 6494 6 6502 6503 9709 2189 9711 9712 6 6502 9708 2189 6501 9710 2190 6 6501 9709 6500 2190 2191 2512 7 9708 6503 6512 9712 9715 9716 9717 5 9708 9711 2189 9713 9715 6 2189 9712 2187 2197 9714 9715 6 2197 9713 9715 2215 2216 9720 6 9714 9713 9712 9711 9716 2215 7 9715 9711 9717 9718 9719 2214 2215 6 9716 9711 6512 6513 6514 9718 5 9717 6514 6516 9719 9716 5 9718 6516 9716 2214 6522 6 9714 2216 2217 2200 2198 2197 6 6669 6775 9722 9723 6656 6658 5 9721 6775 9723 9724 9798 6 9721 9722 9724 6646 6656 6655 6 9723 9722 6646 6645 9799 9798 6 9675 9674 9726 9678 9733 9735 6 9725 9674 9727 9729 9735 9728 6 9726 9674 9673 6365 6366 9728 6 9727 6366 6368 6370 9729 9726 6 9728 6370 9730 9731 9735 9726 6 9729 6370 6371 6375 6467 9731 6 9730 6467 6466 9732 9735 9729 6 9731 6466 6468 7510 9733 9735 6 9732 7510 9734 9735 9678 9725 6 9733 7510 7508 4518 4519 9678 6 9732 9733 9731 9729 9726 9725 6 6041 6039 6038 6019 5872 5874 6 6132 6398 6392 6393 6115 9738 6 9737 6115 6116 6132 6131 6122 6 569 571 9740 9744 568 9743 6 9739 571 573 9741 9742 9743 6 9740 573 916 917 9742 918 6 9740 9741 918 9743 921 919 6 9740 9742 921 563 9744 9739 6 9743 563 564 567 568 9739 6 7205 7206 9746 7218 7217 7216 6 9745 7206 7207 7213 7216 7214 6 3491 3492 3496 3502 6706 6555 5 6706 3502 9749 3503 6710 5 6706 9748 6710 6707 6705 5 6682 5157 4667 6681 9761 5 3201 3470 3410 3200 3411 6 5932 5910 5915 5916 9755 5931 5 4915 4917 9754 4880 4879 7 9753 4917 4911 4880 9756 4904 9759 7 9752 5916 5931 5921 5920 5919 9758 6 4880 9754 9757 4895 4897 9759 5 4880 9756 4895 4884 4881 5 5919 9755 5918 5916 5917 6 9754 4904 4901 4898 4897 9756 6 4638 4912 4875 4872 4869 4868 7 6681 9750 4667 4668 9762 4560 9792 5 9761 4668 4546 4548 4560 5 8468 8469 9764 9765 8486 5 8468 9763 9765 7726 7962 7 9764 9763 8486 7714 7715 7723 7726 6 8023 8021 7738 7739 7740 7742 5 7723 7715 7716 7719 7721 6 427 7500 7502 9769 46 45 6 9768 7502 9770 9772 44 45 7 9769 7502 7503 9771 9772 9774 9780 7 2196 43 1 9772 9770 9773 9774 5 9771 1 9770 9769 44 6 2196 9771 9774 9705 9778 9779 6 9773 9771 9770 9779 9692 9780 6 7253 7256 7523 7520 7517 7516 6 2095 2083 2084 6093 3138 3131 5 6638 6639 6642 6787 6785 5 9705 9773 9779 6478 6480 5 9778 9773 9774 9692 6478 5 9692 9774 6474 9770 7503 6 3852 3129 26 25 1526 3130 6 6787 6642 6643 9783 6789 6170 5 9782 6643 6168 6169 6170 6 4396 4529 4395 4121 4119 4530 6 6637 6783 6779 6636 6635 6771 6 4118 3529 3531 9787 9789 4120 6 9786 3531 3533 9788 7174 9789 6 9787 3533 3535 7178 7175 7174 6 9787 7174 9786 4120 4122 7172 5 7670 7695 7696 7698 7669 6 7775 3145 4231 3413 3414 7776 6 4560 6675 6676 6677 6681 9761 6 3659 3660 4908 9794 4369 4371 5 9793 4908 4642 4370 4369 6 5543 5545 5700 5540 5541 5542 6 6177 6178 9797 9798 6181 9799 6 6782 6177 9796 9798 6776 6780 7 9797 9796 6776 9799 9724 9722 6775 6 9796 6181 6183 6645 9724 9798 scotch-6.0.4.dfsg/src/check/data/m4x4.grf0000644002563400244210000000023712374677274023167 0ustar trophimeutilisateurs du domaine0 16 48 0 000 2 1 4 3 0 2 5 3 1 3 6 2 2 7 3 0 5 8 4 1 4 6 9 4 2 5 7 10 3 3 6 11 3 4 9 12 4 5 8 10 13 4 6 9 11 14 3 7 10 15 2 8 13 3 9 12 14 3 10 13 15 2 11 14 scotch-6.0.4.dfsg/src/check/data/bump_b1.grf0000644002563400244210000112145312370115422023677 0ustar trophimeutilisateurs du domaine0 9800 57978 1 000 3 414 408 7 4 9772 44 9773 45 4 77 1475 1476 78 3 1243 148 149 3 694 207 208 3 522 349 350 4 8 413 414 1 4 7 413 9 648 4 10 3239 648 8 4 3236 3239 9 11 4 12 3234 3236 10 4 3235 3234 11 13 4 3685 3235 12 14 4 15 419 3685 13 4 16 418 419 14 4 15 418 17 3089 4 18 3087 3089 16 4 17 3087 3088 19 4 3088 18 3096 20 4 3096 19 3097 21 4 22 415 3097 20 4 21 415 1172 23 4 1172 22 1173 24 4 1173 23 1174 25 4 1174 24 1527 26 4 1527 25 27 9782 4 28 3853 9782 26 4 29 2180 3853 27 4 28 2180 2181 30 4 2181 29 31 2504 4 32 2506 2504 30 4 2509 2506 31 33 4 3331 2509 34 32 4 3331 33 3332 35 4 36 2249 3332 34 4 35 2249 2250 37 4 2250 36 2251 38 4 39 417 2251 37 4 40 416 417 38 4 39 416 2195 41 4 2195 40 2196 42 4 2196 41 2197 43 3 2197 42 44 4 43 2197 9772 2 4 9770 9773 2 46 4 47 9769 9770 45 4 48 428 9769 46 4 49 427 428 47 4 48 427 50 412 4 51 411 412 49 4 50 411 52 422 4 51 422 423 53 4 423 52 4651 54 4 4651 53 4652 55 4 4658 4652 54 56 4 5381 4658 55 57 4 58 431 5381 56 4 57 431 430 59 4 60 409 430 58 4 59 409 2219 61 4 2219 60 2220 62 4 2220 61 2221 63 4 2221 62 2222 64 4 2222 63 2223 65 4 6702 2223 64 66 4 6702 65 6704 67 4 6704 66 3506 68 4 69 3453 3506 67 4 70 3452 3453 68 4 3442 3452 69 71 4 72 2492 3442 70 4 71 2492 2493 73 4 74 410 2493 72 4 73 410 75 429 4 74 429 76 1604 4 75 1604 1605 77 4 3 1475 1605 76 4 1476 3 1477 79 4 1477 78 1478 80 4 1478 79 1479 81 4 1479 80 1480 82 4 1480 81 1481 83 4 1481 82 1482 84 4 1482 83 1483 85 4 1483 84 1484 86 4 87 1161 1484 85 4 86 1161 1162 88 4 1162 87 1163 89 4 1163 88 1164 90 4 1164 89 1187 91 4 1187 90 1186 92 4 1186 91 1188 93 4 1188 92 1189 94 4 1189 93 1190 95 4 1190 94 1191 96 4 1191 95 1192 97 4 1192 96 1193 98 4 1193 97 1194 99 4 1194 98 1195 100 4 1195 99 1196 101 4 1196 100 1197 102 4 1197 101 1198 103 4 1198 102 1199 104 4 1199 103 1200 105 4 1200 104 1201 106 4 1201 105 1202 107 4 1202 106 1203 108 4 1203 107 1204 109 4 1204 108 1205 110 4 1205 109 1206 111 4 1206 110 1207 112 4 1207 111 1208 113 4 1208 112 1209 114 4 1209 113 1210 115 4 1210 114 1211 116 4 1211 115 1212 117 4 1212 116 1213 118 4 1213 117 1214 119 4 1214 118 1215 120 4 1215 119 1216 121 4 1216 120 1217 122 4 1217 121 1218 123 4 1218 122 1219 124 4 1219 123 1220 125 4 1220 124 1221 126 4 1221 125 1222 127 4 1222 126 1223 128 4 1223 127 1224 129 4 1224 128 1225 130 4 1225 129 1226 131 4 1226 130 1227 132 4 1227 131 1228 133 4 1228 132 1229 134 4 1229 133 1230 135 4 1230 134 1231 136 4 1231 135 1232 137 4 1232 136 1233 138 4 1233 137 1234 139 4 1234 138 1235 140 4 1235 139 1236 141 4 1236 140 1237 142 4 1237 141 1238 143 4 1238 142 1239 144 4 1239 143 1240 145 4 1240 144 1241 146 4 1241 145 1242 147 4 1242 146 1243 148 3 1243 147 4 4 1243 4 1244 150 4 1244 149 1245 151 4 1245 150 1246 152 4 1246 151 1247 153 4 1247 152 1248 154 4 1248 153 1249 155 4 156 924 1249 154 4 155 924 925 157 4 925 156 926 158 4 926 157 927 159 4 927 158 928 160 4 928 159 929 161 4 929 160 930 162 4 930 161 931 163 4 931 162 932 164 4 165 652 932 163 4 164 652 653 166 4 653 165 654 167 4 654 166 655 168 4 655 167 656 169 4 656 168 657 170 4 657 169 658 171 4 658 170 659 172 4 659 171 660 173 4 660 172 661 174 4 661 173 662 175 4 662 174 663 176 4 663 175 664 177 4 664 176 665 178 4 665 177 666 179 4 666 178 667 180 4 667 179 668 181 4 668 180 669 182 4 669 181 670 183 4 670 182 671 184 4 671 183 672 185 4 672 184 673 186 4 673 185 674 187 4 674 186 675 188 4 675 187 676 189 4 676 188 677 190 4 677 189 678 191 4 678 190 679 192 4 679 191 680 193 4 680 192 681 194 4 681 193 682 195 4 682 194 683 196 4 683 195 684 197 4 684 196 685 198 4 685 197 686 199 4 686 198 687 200 4 687 199 688 201 4 688 200 689 202 4 689 201 690 203 4 690 202 691 204 4 691 203 692 205 4 692 204 693 206 3 693 205 207 4 693 206 694 5 3 694 5 209 4 694 208 695 210 4 695 209 696 211 4 696 210 697 212 4 697 211 698 213 4 698 212 699 214 4 699 213 700 215 4 700 214 701 216 4 701 215 702 217 4 702 216 703 218 4 703 217 704 219 4 704 218 705 220 4 705 219 706 221 4 706 220 707 222 4 707 221 708 223 4 708 222 709 224 4 709 223 710 225 4 710 224 711 226 4 711 225 712 227 4 712 226 713 228 4 713 227 714 229 4 714 228 715 230 4 715 229 716 231 4 716 230 717 232 4 717 231 718 233 4 718 232 719 234 4 719 233 720 235 4 720 234 721 236 4 721 235 722 237 4 722 236 723 238 4 723 237 724 239 4 724 238 725 240 4 725 239 726 241 4 726 240 727 242 4 727 241 728 243 4 728 242 729 244 4 729 243 730 245 4 730 244 731 246 4 731 245 732 247 4 732 246 733 248 4 733 247 734 249 4 734 248 735 250 4 735 249 736 251 4 736 250 737 252 4 737 251 738 253 4 738 252 739 254 4 739 253 740 255 4 740 254 741 256 4 741 255 742 257 4 742 256 743 258 4 259 432 743 257 4 258 432 433 260 4 433 259 434 261 4 434 260 435 262 4 435 261 436 263 4 436 262 437 264 4 437 263 438 265 4 438 264 439 266 4 439 265 440 267 4 440 266 441 268 4 441 267 442 269 4 442 268 443 270 4 443 269 444 271 4 444 270 445 272 4 445 271 446 273 4 446 272 447 274 4 447 273 448 275 4 448 274 449 276 4 449 275 450 277 4 450 276 451 278 4 451 277 452 279 4 452 278 453 280 4 453 279 454 281 4 454 280 455 282 4 455 281 456 283 4 456 282 457 284 4 457 283 458 285 4 458 284 459 286 4 459 285 460 287 4 460 286 461 288 4 461 287 462 289 4 462 288 463 290 4 463 289 464 291 4 464 290 465 292 4 465 291 466 293 4 466 292 467 294 4 467 293 468 295 4 468 294 469 296 4 469 295 470 297 4 470 296 471 298 4 471 297 472 299 4 472 298 473 300 4 473 299 474 301 4 474 300 475 302 4 475 301 476 303 4 476 302 477 304 4 477 303 478 305 4 478 304 479 306 4 479 305 480 307 4 480 306 481 308 4 481 307 482 309 4 482 308 483 310 4 483 309 484 311 4 484 310 485 312 4 485 311 486 313 4 486 312 487 314 4 487 313 488 315 4 488 314 489 316 4 489 315 490 317 4 490 316 491 318 4 491 317 492 319 4 492 318 493 320 4 493 319 494 321 4 494 320 495 322 4 495 321 496 323 4 496 322 497 324 4 497 323 498 325 4 498 324 499 326 4 499 325 500 327 4 500 326 501 328 4 501 327 502 329 4 502 328 503 330 4 503 329 504 331 4 504 330 505 332 4 505 331 506 333 4 506 332 507 334 4 507 333 508 335 4 508 334 509 336 4 509 335 510 337 4 510 336 511 338 4 511 337 512 339 4 512 338 513 340 4 513 339 514 341 4 514 340 515 342 4 515 341 516 343 4 516 342 517 344 4 517 343 518 345 4 518 344 519 346 4 519 345 520 347 4 520 346 521 348 4 521 347 522 349 3 522 348 6 4 522 6 523 351 4 523 350 524 352 4 524 351 525 353 4 525 352 526 354 4 526 353 527 355 4 527 354 528 356 4 528 355 529 357 4 529 356 530 358 4 530 357 531 359 4 531 358 532 360 4 532 359 533 361 4 533 360 534 362 4 534 361 535 363 4 535 362 536 364 4 536 363 537 365 4 537 364 538 366 4 538 365 539 367 4 539 366 540 368 4 540 367 541 369 4 541 368 542 370 4 542 369 543 371 4 543 370 544 372 4 544 371 545 373 4 545 372 546 374 4 546 373 547 375 4 547 374 548 376 4 551 548 375 377 4 551 376 552 378 4 552 377 553 379 4 553 378 554 380 4 557 554 379 381 4 567 557 380 382 4 567 381 568 383 4 568 382 569 384 4 569 383 570 385 4 570 384 571 386 4 426 571 387 385 4 388 424 426 386 4 387 424 425 389 4 580 425 390 388 4 585 580 389 391 4 585 390 586 392 4 586 391 587 393 4 587 392 421 394 4 395 420 421 393 4 394 420 595 396 4 397 597 595 395 4 623 597 396 398 4 623 397 624 399 4 624 398 625 400 4 399 625 627 401 4 627 400 629 402 4 631 629 403 401 4 631 402 632 404 4 403 632 2098 405 4 406 650 2098 404 4 649 650 405 407 4 649 406 414 408 3 414 407 1 6 59 60 430 2219 2546 2842 6 73 74 2493 2494 1607 429 6 50 51 412 4522 4516 422 6 50 411 49 427 4515 4516 6 7 8 414 648 647 649 6 7 413 649 407 408 1 6 21 22 1172 3883 3129 3097 6 39 40 417 2195 2253 9705 6 39 416 38 2251 2252 2253 6 15 16 419 3089 3099 3100 6 15 418 14 3100 3101 3685 6 394 395 421 594 589 595 6 394 420 587 393 588 589 6 51 52 423 5238 4522 411 6 422 52 53 4651 9685 5238 6 387 388 425 426 578 576 6 424 388 578 579 580 389 6 387 424 573 571 386 576 6 48 49 428 412 4515 5613 6 48 427 47 5613 7501 9769 6 74 75 1604 1606 1607 410 6 59 409 431 58 2842 9691 6 57 58 430 9690 5381 9691 6 258 259 433 743 744 745 6 432 259 260 434 745 746 6 433 260 261 435 746 747 6 434 261 262 436 747 748 6 435 262 263 437 748 749 6 436 263 264 438 749 750 6 437 264 265 439 750 751 6 438 265 266 440 751 752 6 439 266 267 441 752 753 6 440 267 268 442 753 754 6 441 268 269 443 754 755 6 442 269 270 444 755 756 6 443 270 271 445 756 757 6 444 271 272 446 757 758 6 445 272 273 447 758 759 6 446 273 274 448 759 760 6 447 274 275 449 760 761 6 448 275 276 450 761 762 6 449 276 277 451 762 763 6 450 277 278 452 763 764 6 451 278 279 453 764 765 6 452 279 280 454 765 766 6 453 280 281 455 766 767 6 454 281 282 456 767 768 6 455 282 283 457 768 769 6 456 283 284 458 769 770 6 457 284 285 459 770 771 6 458 285 286 460 771 772 6 459 286 287 461 772 773 6 460 287 288 462 773 774 6 461 288 289 463 774 775 6 462 289 290 464 775 776 6 463 290 291 465 776 777 6 464 291 292 466 777 778 6 465 292 293 467 778 779 6 466 293 294 468 779 780 6 467 294 295 469 780 781 6 468 295 296 470 781 782 6 469 296 297 471 782 783 6 470 297 298 472 783 784 6 471 298 299 473 784 785 6 472 299 300 474 785 786 6 473 300 301 475 786 787 6 474 301 302 476 787 788 6 475 302 303 477 788 789 6 476 303 304 478 789 790 6 477 304 305 479 790 791 6 478 305 306 480 791 792 6 479 306 307 481 792 793 6 480 307 308 482 793 794 6 481 308 309 483 794 795 6 482 309 310 484 795 796 6 483 310 311 485 796 797 6 484 311 312 486 797 798 6 485 312 313 487 798 799 6 486 313 314 488 799 800 6 487 314 315 489 800 801 6 488 315 316 490 801 802 6 489 316 317 491 802 803 6 490 317 318 492 803 804 6 491 318 319 493 804 805 6 492 319 320 494 805 806 6 493 320 321 495 806 807 6 494 321 322 496 807 808 6 495 322 323 497 808 809 6 496 323 324 498 809 810 6 497 324 325 499 810 811 6 498 325 326 500 811 812 6 499 326 327 501 812 813 6 500 327 328 502 813 814 6 501 328 329 503 814 815 6 502 329 330 504 815 816 6 503 330 331 505 816 817 6 504 331 332 506 817 818 6 505 332 333 507 818 819 6 506 333 334 508 819 820 6 507 334 335 509 820 821 6 508 335 336 510 821 822 6 509 336 337 511 822 823 6 510 337 338 512 823 824 6 511 338 339 513 824 825 6 512 339 340 514 825 826 6 513 340 341 515 826 827 6 514 341 342 516 827 828 6 515 342 343 517 828 829 6 516 343 344 518 829 830 6 517 344 345 519 830 831 6 518 345 346 520 831 832 6 519 346 347 521 832 833 6 520 347 348 522 833 834 7 521 348 349 6 350 523 834 6 522 350 351 524 834 835 5 523 351 352 525 835 6 524 352 353 526 835 836 6 525 353 354 527 836 837 6 526 354 355 528 837 838 6 527 355 356 529 838 839 6 528 356 357 530 839 840 6 529 357 358 531 840 841 6 530 358 359 532 841 842 6 531 359 360 533 842 843 6 532 360 361 534 843 844 6 533 361 362 535 844 845 6 534 362 363 536 845 846 6 535 363 364 537 846 847 6 536 364 365 538 847 848 6 537 365 366 539 848 849 6 538 366 367 540 849 850 6 539 367 368 541 850 851 6 540 368 369 542 854 851 6 541 369 370 543 856 854 6 542 370 371 544 856 857 6 543 371 372 545 857 858 6 544 372 373 546 858 859 6 545 373 374 547 859 860 6 546 374 375 548 549 860 6 547 375 549 550 551 376 6 547 548 550 860 861 862 6 549 548 551 862 863 864 6 550 548 376 377 552 864 6 551 377 378 553 864 865 6 552 378 379 554 555 865 6 553 379 555 556 557 380 6 553 554 556 558 865 866 6 555 554 557 558 559 566 6 556 554 380 566 567 381 6 555 556 559 560 866 867 6 558 556 560 561 562 566 6 558 559 561 867 868 869 6 560 559 562 563 923 869 6 561 559 563 564 565 566 6 561 562 564 922 921 923 6 563 562 565 9744 922 9745 6 564 562 566 567 9745 568 6 565 562 559 556 557 567 6 566 557 381 382 568 565 6 567 382 383 569 9745 565 6 568 383 384 570 9745 9740 6 569 384 385 571 572 9740 6 570 385 572 573 426 386 6 570 571 573 574 9740 9741 6 572 571 426 574 575 576 6 572 573 575 9741 9742 917 6 574 573 576 577 917 916 6 575 573 426 577 578 424 6 575 576 578 916 2475 1516 6 577 576 424 425 579 1516 6 578 425 580 581 582 1516 6 579 425 389 581 585 390 6 579 580 582 583 584 585 6 579 581 583 1516 1517 1518 6 582 581 584 1518 1509 1507 6 583 581 585 586 590 1507 6 584 581 580 390 391 586 6 585 391 392 587 590 584 6 586 392 393 421 588 590 6 587 421 589 590 591 592 6 588 421 592 593 594 420 6 587 588 591 586 584 1507 6 590 588 592 1507 1508 1515 6 591 588 589 593 600 1515 6 592 589 594 598 599 600 6 593 589 420 595 596 598 6 594 420 395 596 597 396 6 594 595 597 598 622 607 6 596 595 622 623 397 396 6 594 596 593 599 606 607 6 593 598 600 601 605 606 6 593 599 601 602 1515 592 6 600 599 602 603 604 605 6 600 601 603 1514 1515 1540 6 602 601 604 1540 1541 1584 6 603 601 605 1603 1584 609 6 604 601 599 606 608 609 6 605 599 598 607 608 615 6 606 598 622 621 596 615 6 605 606 609 610 611 615 6 605 608 610 1603 604 1601 6 609 608 611 612 1600 1601 6 610 608 612 613 614 615 6 610 611 613 6558 1599 1600 6 612 611 614 616 3765 6558 6 613 611 615 616 617 621 6 614 611 621 607 606 608 6 613 614 617 618 3761 3765 6 616 614 618 619 620 621 6 616 617 619 3761 3762 626 6 618 617 620 624 625 626 6 619 617 621 622 624 623 6 620 617 614 615 622 607 6 620 621 607 596 597 623 6 622 597 397 398 624 620 6 623 398 399 625 619 620 6 624 399 619 626 627 400 6 619 625 627 628 3762 618 6 626 625 628 629 400 401 6 626 627 629 630 3762 3763 6 628 627 630 631 402 401 6 628 629 631 636 3763 633 6 630 629 402 403 632 633 6 631 403 633 634 404 2098 6 631 632 634 635 636 630 6 633 632 635 2098 651 642 6 633 634 636 637 638 642 6 633 635 637 3218 3763 630 6 636 635 638 639 3218 3219 6 637 635 639 640 641 642 6 637 638 640 3219 3220 3221 6 639 638 641 3221 3240 3241 6 640 638 642 643 644 3240 6 641 638 643 634 651 635 6 641 642 644 645 646 651 6 641 643 645 3238 3237 3240 6 644 643 646 647 648 3238 6 645 643 647 649 650 651 5 645 646 648 413 649 7 645 647 413 9 3239 3238 8 7 413 647 646 650 406 407 414 6 649 646 651 406 405 2098 6 650 646 634 2098 642 643 6 164 165 653 932 933 934 6 652 165 166 654 934 935 6 653 166 167 655 935 936 6 654 167 168 656 936 937 6 655 168 169 657 937 938 6 656 169 170 658 938 939 6 657 170 171 659 939 940 6 658 171 172 660 940 941 6 659 172 173 661 941 942 6 660 173 174 662 942 943 6 661 174 175 663 943 944 6 662 175 176 664 944 945 6 663 176 177 665 945 946 6 664 177 178 666 946 947 6 665 178 179 667 947 948 6 666 179 180 668 948 949 6 667 180 181 669 949 950 6 668 181 182 670 950 951 6 669 182 183 671 951 952 6 670 183 184 672 952 953 6 671 184 185 673 953 954 6 672 185 186 674 954 955 6 673 186 187 675 955 956 6 674 187 188 676 956 957 6 675 188 189 677 957 958 6 676 189 190 678 958 959 6 677 190 191 679 959 960 6 678 191 192 680 960 961 6 679 192 193 681 961 962 6 680 193 194 682 962 963 6 681 194 195 683 963 964 6 682 195 196 684 964 965 6 683 196 197 685 965 966 6 684 197 198 686 966 967 6 685 198 199 687 967 968 6 686 199 200 688 968 969 6 687 200 201 689 969 970 6 688 201 202 690 970 971 6 689 202 203 691 971 972 6 690 203 204 692 972 973 6 691 204 205 693 973 974 7 692 205 206 207 694 974 695 6 693 207 5 208 209 695 7 694 209 210 696 974 693 975 6 695 210 211 697 975 976 6 696 211 212 698 976 977 6 697 212 213 699 977 978 6 698 213 214 700 978 979 6 699 214 215 701 979 980 6 700 215 216 702 980 981 6 701 216 217 703 981 982 6 702 217 218 704 982 983 6 703 218 219 705 983 984 6 704 219 220 706 984 985 6 705 220 221 707 985 986 6 706 221 222 708 986 987 6 707 222 223 709 987 988 6 708 223 224 710 988 989 6 709 224 225 711 989 990 6 710 225 226 712 990 991 6 711 226 227 713 991 992 6 712 227 228 714 992 993 6 713 228 229 715 993 994 6 714 229 230 716 994 995 6 715 230 231 717 995 996 6 716 231 232 718 996 997 6 717 232 233 719 997 998 6 718 233 234 720 998 999 6 719 234 235 721 999 1000 6 720 235 236 722 1000 1001 6 721 236 237 723 1001 1002 6 722 237 238 724 1002 1003 6 723 238 239 725 1003 1004 6 724 239 240 726 1004 1005 6 725 240 241 727 1005 1006 6 726 241 242 728 1006 1007 6 727 242 243 729 1007 1008 6 728 243 244 730 1008 1009 6 729 244 245 731 1009 1010 6 730 245 246 732 1010 1011 6 731 246 247 733 1011 1012 6 732 247 248 734 1012 1013 6 733 248 249 735 1013 1014 6 734 249 250 736 1017 1014 6 735 250 251 737 1017 1018 6 736 251 252 738 1018 1019 6 737 252 253 739 1019 1020 6 738 253 254 740 1020 1021 6 739 254 255 741 1021 1022 6 740 255 256 742 1022 1023 6 741 256 257 743 1023 1024 6 742 257 258 432 744 1024 6 743 432 745 1024 1025 1026 6 744 432 433 746 1026 1027 6 745 433 434 747 1027 1028 6 746 434 435 748 1028 1029 6 747 435 436 749 1029 1030 6 748 436 437 750 1030 1031 6 749 437 438 751 1031 1032 6 750 438 439 752 1032 1033 6 751 439 440 753 1033 1034 6 752 440 441 754 1034 1035 6 753 441 442 755 1035 1036 6 754 442 443 756 1036 1037 6 755 443 444 757 1037 1038 6 756 444 445 758 1038 1039 6 757 445 446 759 1039 1040 6 758 446 447 760 1040 1041 6 759 447 448 761 1041 1042 6 760 448 449 762 1042 1043 6 761 449 450 763 1043 1044 6 762 450 451 764 1044 1045 6 763 451 452 765 1045 1046 6 764 452 453 766 1046 1047 6 765 453 454 767 1047 1048 6 766 454 455 768 1048 1049 6 767 455 456 769 1049 1050 6 768 456 457 770 1050 1051 6 769 457 458 771 1051 1052 6 770 458 459 772 1052 1053 6 771 459 460 773 1053 1054 6 772 460 461 774 1054 1055 6 773 461 462 775 1055 1056 6 774 462 463 776 1056 1057 6 775 463 464 777 1057 1058 6 776 464 465 778 1058 1059 6 777 465 466 779 1059 1060 6 778 466 467 780 1060 1061 6 779 467 468 781 1061 1062 6 780 468 469 782 1062 1063 6 781 469 470 783 1063 1064 6 782 470 471 784 1064 1065 6 783 471 472 785 1065 1066 6 784 472 473 786 1066 1067 6 785 473 474 787 1067 1068 6 786 474 475 788 1068 1069 6 787 475 476 789 1069 1070 6 788 476 477 790 1070 1071 6 789 477 478 791 1071 1072 6 790 478 479 792 1072 1073 6 791 479 480 793 1073 1074 6 792 480 481 794 1074 1075 6 793 481 482 795 1075 1076 6 794 482 483 796 1076 1077 6 795 483 484 797 1077 1078 6 796 484 485 798 1078 1079 6 797 485 486 799 1079 1080 6 798 486 487 800 1080 1081 6 799 487 488 801 1081 1082 6 800 488 489 802 1082 1083 6 801 489 490 803 1083 1084 6 802 490 491 804 1084 1085 6 803 491 492 805 1085 1086 6 804 492 493 806 1086 1087 6 805 493 494 807 1087 1088 6 806 494 495 808 1088 1089 6 807 495 496 809 1089 1090 6 808 496 497 810 1090 1091 6 809 497 498 811 1091 1092 6 810 498 499 812 1092 1093 6 811 499 500 813 1093 1094 6 812 500 501 814 1094 1095 6 813 501 502 815 1095 1096 6 814 502 503 816 1096 1097 6 815 503 504 817 1097 1098 6 816 504 505 818 1098 1099 6 817 505 506 819 1099 1100 6 818 506 507 820 1100 1101 6 819 507 508 821 1101 1102 6 820 508 509 822 1102 1103 6 821 509 510 823 1103 1104 6 822 510 511 824 1104 1105 6 823 511 512 825 1105 1106 6 824 512 513 826 1106 1107 6 825 513 514 827 1107 1108 6 826 514 515 828 1108 1109 6 827 515 516 829 1109 1110 6 828 516 517 830 1110 1111 6 829 517 518 831 1111 1112 6 830 518 519 832 1112 1113 6 831 519 520 833 1113 1114 6 832 520 521 834 1114 1115 6 833 521 522 523 835 1115 6 834 523 524 525 836 1115 7 835 525 526 837 1115 1116 1117 6 836 526 527 838 1117 1118 6 837 527 528 839 1118 1119 6 838 528 529 840 1119 1120 6 839 529 530 841 1120 1121 6 840 530 531 842 1121 1122 6 841 531 532 843 1122 1123 6 842 532 533 844 1123 1124 6 843 533 534 845 1124 1125 6 844 534 535 846 1125 1126 6 845 535 536 847 1126 1127 6 846 536 537 848 1127 1128 6 847 537 538 849 1128 1129 6 848 538 539 850 1129 1130 6 849 539 540 851 852 1130 6 850 540 852 853 854 541 6 850 851 853 1130 1131 1132 6 852 851 854 855 1132 1133 6 853 851 855 856 542 541 6 853 854 856 1133 1134 1135 6 855 854 542 543 857 1135 6 856 543 544 858 1135 1136 6 857 544 545 859 1136 1137 6 858 545 546 860 1137 1138 6 859 546 547 549 861 1138 6 860 549 862 1138 1139 1140 6 861 549 550 863 1140 1141 6 862 550 864 1141 1142 1143 6 863 550 551 552 865 1143 6 864 552 553 555 866 1143 6 865 555 558 867 1143 1144 6 866 558 560 868 1144 1145 6 867 560 869 870 1145 1146 6 868 560 870 871 923 561 6 868 869 871 872 1146 1147 6 870 869 872 873 874 923 6 870 871 873 1147 1148 1149 6 872 871 874 875 1152 1149 6 873 871 875 876 923 921 6 873 874 876 877 1171 1152 6 875 874 877 878 920 921 6 875 876 878 879 880 1171 6 877 876 879 919 883 920 6 877 878 880 881 882 883 6 877 879 881 885 887 1171 6 880 879 882 885 886 892 6 881 879 883 884 892 893 6 882 879 884 918 919 878 6 882 883 913 893 914 918 6 880 881 886 887 888 889 6 885 881 889 890 891 892 6 880 885 888 1965 1170 1171 6 887 885 889 1966 1965 2076 6 888 885 886 890 2076 2077 6 889 886 891 2077 2078 2082 6 890 886 892 894 895 2082 6 891 886 881 882 893 894 6 892 882 894 897 913 884 6 892 893 891 895 896 897 6 891 894 896 898 899 2082 6 895 894 897 898 910 911 6 896 894 893 911 912 913 6 895 896 899 900 901 910 6 895 898 900 902 2082 2081 6 899 898 901 902 903 907 6 900 898 907 908 909 910 6 899 900 903 904 2081 2083 6 902 900 904 905 906 907 6 902 903 905 2083 2084 2085 6 904 903 906 2085 2086 1566 6 905 903 907 1564 1565 1566 6 906 903 900 901 908 1564 6 907 901 909 1544 1564 1537 6 908 901 910 1523 1524 1537 6 909 901 898 896 911 1523 6 910 896 897 912 1521 1523 6 911 897 913 1522 1521 915 6 912 897 893 884 914 915 6 913 884 915 916 917 918 6 913 914 916 2475 1522 912 6 915 914 917 575 577 2475 6 916 914 918 9742 574 575 6 917 914 884 883 919 9742 6 918 883 878 920 9743 9742 6 919 878 876 921 922 9743 6 920 876 922 563 923 874 6 920 921 563 9744 9743 564 6 563 921 874 871 869 561 6 155 156 925 1249 1250 1251 6 924 156 157 926 1251 1252 6 925 157 158 927 1252 1253 6 926 158 159 928 1253 1254 6 927 159 160 929 1254 1255 6 928 160 161 930 1255 1256 6 929 161 162 931 1256 1257 6 930 162 163 932 1257 1258 6 931 163 164 652 933 1258 6 932 652 934 1258 1259 1260 6 933 652 653 935 1260 1261 6 934 653 654 936 1261 1262 6 935 654 655 937 1262 1263 6 936 655 656 938 1263 1264 6 937 656 657 939 1264 1265 6 938 657 658 940 1265 1266 6 939 658 659 941 1266 1267 6 940 659 660 942 1267 1268 6 941 660 661 943 1268 1269 6 942 661 662 944 1269 1270 6 943 662 663 945 1270 1271 6 944 663 664 946 1271 1272 6 945 664 665 947 1272 1273 6 946 665 666 948 1273 1274 6 947 666 667 949 1274 1275 6 948 667 668 950 1275 1276 6 949 668 669 951 1276 1277 6 950 669 670 952 1277 1278 6 951 670 671 953 1278 1279 6 952 671 672 954 1279 1280 6 953 672 673 955 1280 1281 6 954 673 674 956 1281 1282 6 955 674 675 957 1282 1283 6 956 675 676 958 1283 1284 6 957 676 677 959 1284 1285 6 958 677 678 960 1285 1286 6 959 678 679 961 1286 1287 6 960 679 680 962 1287 1288 6 961 680 681 963 1288 1289 6 962 681 682 964 1289 1290 6 963 682 683 965 1290 1291 6 964 683 684 966 1291 1292 6 965 684 685 967 1292 1293 6 966 685 686 968 1293 1294 6 967 686 687 969 1294 1295 6 968 687 688 970 1295 1296 6 969 688 689 971 1296 1297 6 970 689 690 972 1297 1298 6 971 690 691 973 1298 1299 6 972 691 692 974 1299 1300 6 973 692 693 695 975 1300 5 974 695 696 976 1300 6 975 696 697 977 1300 1301 6 976 697 698 978 1301 1302 6 977 698 699 979 1302 1303 6 978 699 700 980 1303 1304 6 979 700 701 981 1304 1305 6 980 701 702 982 1305 1306 6 981 702 703 983 1306 1307 6 982 703 704 984 1307 1308 6 983 704 705 985 1308 1309 6 984 705 706 986 1309 1310 6 985 706 707 987 1310 1311 6 986 707 708 988 1311 1312 6 987 708 709 989 1312 1313 6 988 709 710 990 1313 1314 6 989 710 711 991 1314 1315 6 990 711 712 992 1315 1316 6 991 712 713 993 1316 1317 6 992 713 714 994 1317 1318 6 993 714 715 995 1318 1319 6 994 715 716 996 1319 1320 6 995 716 717 997 1320 1321 6 996 717 718 998 1321 1322 6 997 718 719 999 1322 1323 6 998 719 720 1000 1323 1324 6 999 720 721 1001 1324 1325 6 1000 721 722 1002 1325 1326 6 1001 722 723 1003 1326 1327 6 1002 723 724 1004 1327 1328 6 1003 724 725 1005 1328 1329 6 1004 725 726 1006 1329 1330 6 1005 726 727 1007 1330 1331 6 1006 727 728 1008 1331 1332 6 1007 728 729 1009 1332 1333 6 1008 729 730 1010 1333 1334 6 1009 730 731 1011 1334 1335 6 1010 731 732 1012 1335 1336 6 1011 732 733 1013 1336 1337 6 1012 733 734 1014 1015 1337 6 1013 734 1015 1016 1017 735 6 1013 1014 1016 1337 1338 1339 6 1015 1014 1017 1339 1340 1341 6 1016 1014 735 736 1018 1341 6 1017 736 737 1019 1341 1342 6 1018 737 738 1020 1342 1343 6 1019 738 739 1021 1343 1344 6 1020 739 740 1022 1344 1345 6 1021 740 741 1023 1345 1346 6 1022 741 742 1024 1346 1347 6 1023 742 743 744 1025 1347 6 1024 744 1026 1347 1348 1349 6 1025 744 745 1027 1349 1350 6 1026 745 746 1028 1350 1351 6 1027 746 747 1029 1351 1352 6 1028 747 748 1030 1352 1353 6 1029 748 749 1031 1353 1354 6 1030 749 750 1032 1354 1355 6 1031 750 751 1033 1355 1356 6 1032 751 752 1034 1356 1357 6 1033 752 753 1035 1357 1358 6 1034 753 754 1036 1358 1359 6 1035 754 755 1037 1359 1360 6 1036 755 756 1038 1360 1361 6 1037 756 757 1039 1361 1362 6 1038 757 758 1040 1362 1363 6 1039 758 759 1041 1363 1364 6 1040 759 760 1042 1364 1365 6 1041 760 761 1043 1365 1366 6 1042 761 762 1044 1366 1367 6 1043 762 763 1045 1367 1368 6 1044 763 764 1046 1368 1369 6 1045 764 765 1047 1369 1370 6 1046 765 766 1048 1370 1371 6 1047 766 767 1049 1371 1372 6 1048 767 768 1050 1372 1373 6 1049 768 769 1051 1373 1374 6 1050 769 770 1052 1374 1375 6 1051 770 771 1053 1375 1376 6 1052 771 772 1054 1376 1377 6 1053 772 773 1055 1377 1378 6 1054 773 774 1056 1378 1379 6 1055 774 775 1057 1379 1380 6 1056 775 776 1058 1380 1381 6 1057 776 777 1059 1381 1382 6 1058 777 778 1060 1382 1383 6 1059 778 779 1061 1383 1384 6 1060 779 780 1062 1384 1385 6 1061 780 781 1063 1385 1386 6 1062 781 782 1064 1386 1387 6 1063 782 783 1065 1387 1388 6 1064 783 784 1066 1388 1389 6 1065 784 785 1067 1389 1390 6 1066 785 786 1068 1390 1391 6 1067 786 787 1069 1391 1392 6 1068 787 788 1070 1392 1393 6 1069 788 789 1071 1393 1394 6 1070 789 790 1072 1394 1395 6 1071 790 791 1073 1395 1396 6 1072 791 792 1074 1396 1397 6 1073 792 793 1075 1397 1398 6 1074 793 794 1076 1398 1399 6 1075 794 795 1077 1399 1400 6 1076 795 796 1078 1400 1401 6 1077 796 797 1079 1401 1402 6 1078 797 798 1080 1402 1403 6 1079 798 799 1081 1403 1404 6 1080 799 800 1082 1404 1405 6 1081 800 801 1083 1405 1406 6 1082 801 802 1084 1406 1407 6 1083 802 803 1085 1407 1408 6 1084 803 804 1086 1408 1409 6 1085 804 805 1087 1409 1410 6 1086 805 806 1088 1410 1411 6 1087 806 807 1089 1411 1412 6 1088 807 808 1090 1412 1413 6 1089 808 809 1091 1413 1414 6 1090 809 810 1092 1414 1415 6 1091 810 811 1093 1415 1416 6 1092 811 812 1094 1416 1417 6 1093 812 813 1095 1417 1418 6 1094 813 814 1096 1418 1419 6 1095 814 815 1097 1419 1420 6 1096 815 816 1098 1420 1421 6 1097 816 817 1099 1421 1422 6 1098 817 818 1100 1422 1423 6 1099 818 819 1101 1423 1424 6 1100 819 820 1102 1424 1425 6 1101 820 821 1103 1425 1426 6 1102 821 822 1104 1426 1427 6 1103 822 823 1105 1427 1428 6 1104 823 824 1106 1428 1429 6 1105 824 825 1107 1429 1430 6 1106 825 826 1108 1430 1431 6 1107 826 827 1109 1431 1432 6 1108 827 828 1110 1432 1433 6 1109 828 829 1111 1433 1434 6 1110 829 830 1112 1434 1435 6 1111 830 831 1113 1435 1436 6 1112 831 832 1114 1436 1437 6 1113 832 833 1115 1437 1116 6 1114 833 834 835 836 1116 6 1115 836 1117 1437 1114 1438 5 1116 836 837 1118 1438 6 1117 837 838 1119 1438 1439 6 1118 838 839 1120 1439 1440 6 1119 839 840 1121 1440 1441 6 1120 840 841 1122 1441 1442 6 1121 841 842 1123 1442 1443 6 1122 842 843 1124 1443 1444 6 1123 843 844 1125 1444 1445 6 1124 844 845 1126 1445 1446 6 1125 845 846 1127 1446 1447 6 1126 846 847 1128 1447 1448 6 1127 847 848 1129 1448 1449 6 1128 848 849 1130 1449 1450 6 1129 849 850 852 1131 1450 6 1130 852 1132 1450 1451 1452 6 1131 852 853 1133 1452 1453 6 1132 853 855 1134 1453 1454 6 1133 855 1135 1457 1454 1153 6 1134 855 856 857 1136 1153 6 1135 857 858 1137 1153 1154 6 1136 858 859 1138 1154 1155 6 1137 859 860 861 1139 1155 6 1138 861 1140 1155 1156 1157 6 1139 861 862 1141 1157 1158 6 1140 862 863 1142 1158 1159 6 1141 863 1143 1159 1160 1144 6 1142 863 864 865 866 1144 6 1143 866 867 1145 1160 1142 6 1144 867 868 1146 1499 1160 6 1145 868 870 1147 1499 1500 6 1146 870 872 1148 1165 1500 6 1147 872 1149 1150 1165 1166 6 1148 872 1150 1151 1152 873 6 1148 1149 1151 1166 1167 1168 6 1150 1149 1152 1168 1169 1170 6 1151 1149 873 1170 1171 875 6 1135 1136 1154 1474 1457 1134 6 1153 1136 1137 1155 1474 1491 6 1154 1137 1138 1139 1156 1491 6 1155 1139 1157 1491 1492 1493 6 1156 1139 1140 1158 1493 1494 6 1157 1140 1141 1159 1494 1495 6 1158 1141 1142 1160 1498 1495 6 1159 1142 1144 1145 1499 1498 6 86 87 1162 1484 1485 1489 6 1161 87 88 1163 1175 1489 6 1162 88 89 1164 1175 1176 6 1163 89 90 1176 1178 1187 6 1147 1148 1166 1500 1528 1529 6 1165 1148 1150 1167 1529 1534 6 1166 1150 1168 1536 1534 1542 6 1167 1150 1151 1169 1542 1963 6 1168 1151 1170 1963 1964 1965 6 1169 1151 1152 1171 887 1965 6 1170 1152 875 887 880 877 6 415 22 23 1173 3338 3883 6 1172 23 24 1174 1525 3338 6 1173 24 25 1525 1526 1527 6 1162 1163 1176 1177 1489 1490 6 1175 1163 1177 1164 1178 1179 6 1175 1176 1490 1643 1644 1179 6 1176 1164 1179 1180 1187 1184 6 1176 1178 1180 1181 1644 1177 6 1179 1178 1181 1182 1183 1184 6 1179 1180 1182 1644 1645 1646 6 1181 1180 1183 1646 1647 1648 6 1182 1180 1184 1185 3098 1648 6 1183 1180 1185 1186 1187 1178 6 1183 1184 1186 3098 2242 1188 6 1185 1184 1187 91 92 1188 6 1186 1184 1178 1164 90 91 6 1186 92 93 1189 2242 1185 6 1188 93 94 1190 2242 1660 6 1189 94 95 1191 1661 1660 6 1190 95 96 1192 1663 1661 6 1191 96 97 1193 1671 1663 6 1192 97 98 1194 1671 1672 6 1193 98 99 1195 1672 1673 6 1194 99 100 1196 1673 1674 6 1195 100 101 1197 1674 1675 6 1196 101 102 1198 1675 1676 6 1197 102 103 1199 1501 1676 6 1198 103 104 1200 1458 1501 6 1199 104 105 1201 1458 1459 6 1200 105 106 1202 1459 1460 6 1201 106 107 1203 1460 1461 6 1202 107 108 1204 1461 1686 6 1203 108 109 1205 1688 1686 6 1204 109 110 1206 1688 1689 6 1205 110 111 1207 1689 1690 6 1206 111 112 1208 1690 1691 6 1207 112 113 1209 1694 1691 6 1208 113 114 1210 1694 1695 6 1209 114 115 1211 1695 1696 6 1210 115 116 1212 1557 1696 6 1211 116 117 1213 1547 1557 6 1212 117 118 1214 1547 1548 6 1213 118 119 1215 1548 1549 6 1214 119 120 1216 1549 1550 6 1215 120 121 1217 1550 1551 6 1216 121 122 1218 1554 1551 6 1217 122 123 1219 1556 1554 6 1218 123 124 1220 1717 1556 6 1219 124 125 1221 1717 1718 6 1220 125 126 1222 1718 1719 6 1221 126 127 1223 1719 1720 6 1222 127 128 1224 1720 1721 6 1223 128 129 1225 1721 1722 6 1224 129 130 1226 1722 1723 6 1225 130 131 1227 1723 1724 6 1226 131 132 1228 1727 1724 6 1227 132 133 1229 1727 1728 6 1228 133 134 1230 1728 1729 6 1229 134 135 1231 1729 1730 6 1230 135 136 1232 1730 1731 6 1231 136 137 1233 1734 1731 6 1232 137 138 1234 1734 1735 6 1233 138 139 1235 1735 1736 6 1234 139 140 1236 1736 1737 6 1235 140 141 1237 1737 1738 6 1236 141 142 1238 1738 1739 6 1237 142 143 1239 1739 1740 6 1238 143 144 1240 1740 1741 6 1239 144 145 1241 1741 1742 6 1240 145 146 1242 1742 1743 6 1241 146 147 1243 1743 1744 7 1242 147 148 4 149 1244 1744 5 1243 149 150 1245 1744 6 1244 150 151 1246 1744 1745 6 1245 151 152 1247 1745 1746 6 1246 152 153 1248 1746 1747 6 1247 153 154 1249 1747 1748 6 1248 154 155 924 1250 1748 6 1249 924 1251 1748 1749 1750 6 1250 924 925 1252 1750 1751 6 1251 925 926 1253 1751 1752 6 1252 926 927 1254 1752 1753 6 1253 927 928 1255 1753 1754 6 1254 928 929 1256 1754 1755 6 1255 929 930 1257 1755 1756 6 1256 930 931 1258 1756 1757 6 1257 931 932 933 1259 1757 6 1258 933 1260 1757 1758 1759 6 1259 933 934 1261 1759 1760 6 1260 934 935 1262 1760 1761 6 1261 935 936 1263 1761 1762 6 1262 936 937 1264 1762 1763 6 1263 937 938 1265 1763 1764 6 1264 938 939 1266 1764 1765 6 1265 939 940 1267 1765 1766 6 1266 940 941 1268 1766 1767 6 1267 941 942 1269 1767 1768 6 1268 942 943 1270 1768 1769 6 1269 943 944 1271 1769 1770 6 1270 944 945 1272 1770 1771 6 1271 945 946 1273 1771 1772 6 1272 946 947 1274 1772 1773 6 1273 947 948 1275 1773 1774 6 1274 948 949 1276 1774 1775 6 1275 949 950 1277 1775 1776 6 1276 950 951 1278 1776 1777 6 1277 951 952 1279 1777 1778 6 1278 952 953 1280 1778 1779 6 1279 953 954 1281 1779 1780 6 1280 954 955 1282 1780 1781 6 1281 955 956 1283 1781 1782 6 1282 956 957 1284 1782 1783 6 1283 957 958 1285 1783 1784 6 1284 958 959 1286 1784 1785 6 1285 959 960 1287 1785 1786 6 1286 960 961 1288 1786 1787 6 1287 961 962 1289 1787 1788 6 1288 962 963 1290 1788 1789 6 1289 963 964 1291 1789 1790 6 1290 964 965 1292 1790 1791 6 1291 965 966 1293 1791 1792 6 1292 966 967 1294 1792 1793 6 1293 967 968 1295 1793 1794 6 1294 968 969 1296 1794 1795 6 1295 969 970 1297 1795 1796 6 1296 970 971 1298 1796 1797 6 1297 971 972 1299 1797 1798 6 1298 972 973 1300 1798 1301 6 1299 973 974 975 976 1301 7 1300 976 977 1302 1798 1299 2101 6 1301 977 978 1303 2101 2102 6 1302 978 979 1304 2102 2103 6 1303 979 980 1305 2103 2104 6 1304 980 981 1306 2104 2105 6 1305 981 982 1307 2105 2106 6 1306 982 983 1308 2106 2107 6 1307 983 984 1309 1799 2107 6 1308 984 985 1310 1799 1800 6 1309 985 986 1311 1800 1801 6 1310 986 987 1312 1801 1802 6 1311 987 988 1313 1802 1803 6 1312 988 989 1314 1803 1804 6 1313 989 990 1315 1804 1805 6 1314 990 991 1316 1805 1806 6 1315 991 992 1317 1806 1807 6 1316 992 993 1318 1807 1808 6 1317 993 994 1319 1808 1809 6 1318 994 995 1320 1809 1810 6 1319 995 996 1321 1810 1811 6 1320 996 997 1322 1811 1812 6 1321 997 998 1323 1812 1813 6 1322 998 999 1324 1813 1814 6 1323 999 1000 1325 1814 1815 6 1324 1000 1001 1326 1815 1816 6 1325 1001 1002 1327 1816 1817 6 1326 1002 1003 1328 1817 1818 6 1327 1003 1004 1329 1818 1819 6 1328 1004 1005 1330 1819 1820 6 1329 1005 1006 1331 1820 1821 6 1330 1006 1007 1332 1821 1822 6 1331 1007 1008 1333 1822 1823 6 1332 1008 1009 1334 1823 1824 6 1333 1009 1010 1335 1824 1825 6 1334 1010 1011 1336 1825 1826 6 1335 1011 1012 1337 1826 1827 6 1336 1012 1013 1015 1338 1827 6 1337 1015 1339 1827 1828 1829 6 1338 1015 1016 1340 1829 1830 6 1339 1016 1341 1830 1831 1832 6 1340 1016 1017 1018 1342 1832 6 1341 1018 1019 1343 1832 1833 6 1342 1019 1020 1344 1833 1834 6 1343 1020 1021 1345 1834 1835 6 1344 1021 1022 1346 1835 1836 6 1345 1022 1023 1347 1836 1837 6 1346 1023 1024 1025 1348 1837 6 1347 1025 1349 1837 1838 1839 6 1348 1025 1026 1350 1839 1840 6 1349 1026 1027 1351 1840 1841 6 1350 1027 1028 1352 1841 1842 6 1351 1028 1029 1353 1842 1843 6 1352 1029 1030 1354 1843 1844 6 1353 1030 1031 1355 1844 1845 6 1354 1031 1032 1356 1845 1846 6 1355 1032 1033 1357 1846 1847 6 1356 1033 1034 1358 1847 1848 6 1357 1034 1035 1359 1848 1849 6 1358 1035 1036 1360 1849 1850 6 1359 1036 1037 1361 1850 1851 6 1360 1037 1038 1362 1851 1852 6 1361 1038 1039 1363 1852 1853 6 1362 1039 1040 1364 1853 1854 6 1363 1040 1041 1365 1854 1855 6 1364 1041 1042 1366 1855 1856 6 1365 1042 1043 1367 1856 1857 6 1366 1043 1044 1368 1857 1858 6 1367 1044 1045 1369 1858 1859 6 1368 1045 1046 1370 1859 1860 6 1369 1046 1047 1371 1860 1861 6 1370 1047 1048 1372 1861 1862 6 1371 1048 1049 1373 1862 1863 6 1372 1049 1050 1374 1863 1864 6 1373 1050 1051 1375 1864 1865 6 1374 1051 1052 1376 1865 1866 6 1375 1052 1053 1377 1866 1867 6 1376 1053 1054 1378 1867 1868 6 1377 1054 1055 1379 1868 1869 6 1378 1055 1056 1380 1869 1870 6 1379 1056 1057 1381 1870 1871 6 1380 1057 1058 1382 1871 1872 6 1381 1058 1059 1383 1872 1873 6 1382 1059 1060 1384 1873 1874 6 1383 1060 1061 1385 1874 1875 6 1384 1061 1062 1386 1875 1876 6 1385 1062 1063 1387 1876 1877 6 1386 1063 1064 1388 1877 1878 6 1387 1064 1065 1389 1878 1879 6 1388 1065 1066 1390 1879 1880 6 1389 1066 1067 1391 1880 1881 6 1390 1067 1068 1392 1881 1882 6 1391 1068 1069 1393 1882 1883 6 1392 1069 1070 1394 1883 1884 6 1393 1070 1071 1395 1884 1885 6 1394 1071 1072 1396 1885 1886 6 1395 1072 1073 1397 1886 1887 6 1396 1073 1074 1398 1887 1888 6 1397 1074 1075 1399 1888 1889 6 1398 1075 1076 1400 1889 1890 6 1399 1076 1077 1401 1890 1891 6 1400 1077 1078 1402 1891 1892 6 1401 1078 1079 1403 1892 1893 6 1402 1079 1080 1404 1893 1894 6 1403 1080 1081 1405 1894 1895 6 1404 1081 1082 1406 1895 1896 6 1405 1082 1083 1407 1896 1897 6 1406 1083 1084 1408 1897 1898 6 1407 1084 1085 1409 1898 1899 6 1408 1085 1086 1410 1899 1900 6 1409 1086 1087 1411 1900 1901 6 1410 1087 1088 1412 1901 1902 6 1411 1088 1089 1413 1902 1903 6 1412 1089 1090 1414 1903 1904 6 1413 1090 1091 1415 1904 1905 6 1414 1091 1092 1416 1905 1906 6 1415 1092 1093 1417 1906 1907 6 1416 1093 1094 1418 1907 1908 6 1417 1094 1095 1419 1908 1909 6 1418 1095 1096 1420 1909 1910 6 1419 1096 1097 1421 1910 1911 6 1420 1097 1098 1422 1911 1912 6 1421 1098 1099 1423 1912 1913 6 1422 1099 1100 1424 1913 1914 6 1423 1100 1101 1425 1914 1915 6 1424 1101 1102 1426 1915 1916 6 1425 1102 1103 1427 1916 1917 6 1426 1103 1104 1428 1917 1918 6 1427 1104 1105 1429 1918 1919 6 1428 1105 1106 1430 1919 1920 6 1429 1106 1107 1431 1920 1921 6 1430 1107 1108 1432 1921 1922 6 1431 1108 1109 1433 1922 1923 6 1432 1109 1110 1434 1923 1924 6 1433 1110 1111 1435 1924 1925 6 1434 1111 1112 1436 1925 1926 6 1435 1112 1113 1437 1926 1927 6 1436 1113 1114 1116 1438 1927 6 1437 1116 1117 1118 1439 1927 6 1438 1118 1119 1440 1927 1928 6 1439 1119 1120 1441 1928 1929 6 1440 1120 1121 1442 1929 1930 6 1441 1121 1122 1443 1930 1931 6 1442 1122 1123 1444 1931 1932 6 1443 1123 1124 1445 1932 1933 6 1444 1124 1125 1446 1462 1933 6 1445 1125 1126 1447 1462 1463 6 1446 1126 1127 1448 1463 1464 6 1447 1127 1128 1449 1464 1465 6 1448 1128 1129 1450 1465 1466 6 1449 1129 1130 1131 1451 1466 6 1450 1131 1452 1466 1467 1468 6 1451 1131 1132 1453 1468 1469 6 1452 1132 1133 1454 1455 1469 6 1453 1133 1455 1456 1457 1134 6 1453 1454 1456 1469 1470 1471 6 1455 1454 1457 1471 1472 1473 6 1456 1454 1134 1473 1474 1153 6 1199 1200 1459 1501 1502 1680 6 1458 1200 1201 1460 1680 1681 6 1459 1201 1202 1461 1681 1682 6 1460 1202 1203 1682 1685 1686 6 1445 1446 1463 1933 1934 1935 6 1462 1446 1447 1464 1935 1936 6 1463 1447 1448 1465 1936 1937 6 1464 1448 1449 1466 1937 1938 6 1465 1449 1450 1451 1467 1938 6 1466 1451 1468 1938 1939 1940 6 1467 1451 1452 1469 1940 1941 6 1468 1452 1453 1455 1470 1941 6 1469 1455 1471 1941 1942 1943 6 1470 1455 1456 1472 1943 1944 6 1471 1456 1473 1944 1945 1946 6 1472 1456 1457 1474 1946 1947 6 1473 1457 1153 1154 1491 1947 7 77 3 1476 1609 1605 1610 1619 6 1475 3 78 1477 1621 1619 6 1476 78 79 1478 1621 1622 6 1477 79 80 1479 1622 1623 6 1478 80 81 1480 1631 1623 6 1479 81 82 1481 1631 1632 6 1480 82 83 1482 1632 1633 6 1481 83 84 1483 1636 1633 6 1482 84 85 1484 1486 1636 6 1483 85 86 1161 1485 1486 6 1484 1161 1486 1487 1488 1489 6 1484 1485 1487 1503 1636 1483 6 1486 1485 1488 1503 1504 1505 6 1487 1485 1489 1505 1506 1490 6 1488 1485 1161 1162 1175 1490 6 1489 1175 1177 1506 1488 1643 6 1474 1154 1155 1156 1492 1947 6 1491 1156 1493 1947 1948 1949 6 1492 1156 1157 1494 1949 1950 6 1493 1157 1158 1495 1496 1950 6 1494 1158 1496 1497 1498 1159 6 1494 1495 1497 1952 1950 1953 6 1496 1495 1498 1953 1531 1530 6 1497 1495 1159 1160 1499 1530 6 1145 1146 1500 1160 1498 1530 6 1499 1146 1147 1165 1528 1530 6 1198 1199 1458 1502 1676 1677 6 1501 1458 1677 1678 1679 1680 6 1486 1487 1504 1638 1635 1636 6 1503 1487 1505 1638 1639 1640 6 1504 1487 1488 1506 1640 1641 6 1505 1488 1490 1641 1642 1643 6 584 590 591 1508 1509 583 6 1507 591 1509 1510 1514 1515 6 1507 1508 1510 1511 1518 583 6 1509 1508 1511 1512 1513 1514 6 1509 1510 1512 1518 1519 1520 6 1511 1510 1513 1524 1520 1538 6 1512 1510 1514 1538 1539 1540 6 1513 1510 1508 1515 602 1540 6 1514 1508 602 600 592 591 6 578 579 582 1517 2475 577 6 1516 582 1518 1519 1522 2475 6 1517 582 583 1509 1511 1519 6 1518 1511 1520 1521 1522 1517 6 1519 1511 1521 1523 1524 1512 6 1519 1520 1522 912 911 1523 6 1519 1521 912 1517 2475 915 6 911 1521 1520 1524 909 910 6 1523 1520 1512 909 1537 1538 6 1173 1174 1526 3338 3339 4251 6 1525 1174 1527 3131 2206 4251 6 1526 1174 25 26 3131 9782 6 1500 1165 1529 1530 1531 1532 6 1528 1165 1166 1532 1533 1534 6 1498 1499 1500 1528 1531 1497 6 1530 1528 1532 1953 1497 1954 6 1531 1528 1529 1533 1954 1955 6 1532 1529 1534 1535 1955 1956 6 1533 1529 1535 1536 1167 1166 6 1533 1534 1536 1956 1957 1958 6 1535 1534 1167 1542 1961 1958 6 909 1524 1538 1543 1544 908 6 1537 1524 1512 1513 1539 1543 6 1538 1513 1540 1541 1546 1543 6 1539 1513 1514 602 603 1541 6 1540 603 1539 1583 1546 1584 6 1536 1167 1168 1961 1962 1963 6 1537 1538 1544 1545 1546 1539 6 1537 1543 1545 1563 1564 908 6 1544 1543 1546 1563 1581 1578 6 1545 1543 1539 1583 1581 1541 6 1212 1213 1548 1557 1558 1559 6 1547 1213 1214 1549 1562 1559 6 1548 1214 1215 1550 1711 1562 6 1549 1215 1216 1551 1552 1711 6 1550 1216 1552 1553 1554 1217 6 1550 1551 1553 1711 1712 1713 6 1552 1551 1554 1555 1713 1714 6 1553 1551 1555 1556 1218 1217 6 1553 1554 1556 1714 1715 1716 6 1555 1554 1218 1716 1717 1219 6 1211 1212 1547 1558 1696 1697 6 1557 1547 1559 1560 1697 1698 6 1558 1547 1560 1561 1562 1548 6 1558 1559 1561 1698 1699 1700 6 1560 1559 1562 1700 1701 1710 6 1561 1559 1548 1710 1711 1549 6 1544 1545 1564 1565 1577 1578 6 1544 1563 1565 906 908 907 6 1564 1563 906 1566 1567 1577 6 906 1565 1567 1568 2086 905 6 1566 1565 1568 1569 1570 1577 6 1566 1567 1569 2086 3767 3768 6 1568 1567 1570 1571 1572 3768 6 1569 1567 1571 1575 1576 1577 6 1569 1570 1572 1573 1574 1575 7 1569 1571 1573 3770 3768 6318 6320 5 1572 1571 1574 6320 6321 7 1573 1571 1575 6321 6362 6361 2476 6 1574 1571 1570 1576 1579 2476 6 1575 1570 1577 1578 1579 1580 6 1576 1570 1567 1565 1563 1578 6 1577 1563 1576 1580 1581 1545 6 1575 1576 1580 1587 1588 2476 6 1579 1576 1578 1581 1582 1587 6 1580 1578 1545 1582 1583 1546 6 1580 1581 1583 1585 1586 1587 6 1582 1581 1546 1541 1584 1585 6 1583 1541 1585 1603 604 603 6 1583 1584 1582 1586 1602 1603 6 1582 1585 1587 1592 1589 1602 6 1582 1586 1580 1579 1588 1589 6 1579 1587 1589 1590 2476 2477 6 1588 1587 1590 1591 1592 1586 6 1588 1589 1591 6355 6354 2477 6 1590 1589 1592 1593 1595 6355 6 1591 1589 1586 1593 1594 1602 6 1591 1592 1594 1595 1596 1597 6 1593 1592 1600 1597 1601 1602 6 1591 1593 1596 6359 6357 6355 6 1595 1593 1597 1598 3971 6359 6 1596 1593 1598 1599 1600 1594 6 1596 1597 1599 3971 3970 6557 6 1598 1597 1600 6557 6558 612 6 1599 1597 1594 1601 612 610 6 1600 1594 1602 1603 609 610 6 1601 1594 1592 1586 1585 1603 6 1601 1602 1585 1584 604 609 6 75 76 1605 429 1606 1609 5 1604 76 77 1609 1475 6 429 1604 1607 1608 1609 3520 6 429 1606 1608 2494 410 3517 6 1607 1606 3519 3517 1614 3520 7 1606 1604 1605 1475 1610 1611 3520 5 1609 1475 1611 1612 1619 6 1609 1610 1612 1613 1614 3520 6 1611 1610 1613 1617 1618 1619 6 1611 1612 1614 1615 1616 1617 7 1611 1613 1615 3519 1608 3520 3524 6 1614 1613 1616 3524 3525 3529 6 1615 1613 1617 3094 3545 3529 6 1616 1613 1612 1618 3094 3095 6 1617 1612 1619 1620 3095 1625 7 1618 1612 1620 1621 1476 1610 1475 6 1618 1619 1621 1622 1624 1625 5 1620 1619 1476 1477 1622 6 1621 1477 1478 1623 1624 1620 6 1622 1478 1624 1630 1631 1479 6 1622 1623 1620 1625 1626 1630 7 1620 1624 1626 1627 1618 3095 4368 6 1625 1624 1627 1628 1629 1630 5 1625 1626 1628 4377 4368 7 1627 1626 1629 4378 4377 2863 7216 6 1628 1626 1630 2862 1634 2863 6 1629 1626 1624 1623 1631 2862 6 1630 1623 1479 1480 1632 2862 6 1631 1480 1481 1633 1634 2862 6 1632 1481 1634 1635 1636 1482 7 1632 1633 1635 1637 2862 1629 2863 6 1634 1633 1636 1637 1638 1503 6 1635 1633 1482 1503 1486 1483 5 1634 1635 1638 2863 2864 7 1637 1635 1503 1504 1639 2864 2865 5 1638 1504 1640 2865 2866 6 1639 1504 1505 1641 2866 2867 6 1640 1505 1506 1642 2867 2868 6 1641 1506 1643 2480 2491 2868 6 1642 1506 1490 1177 1644 2480 6 1643 1177 1179 1181 1645 2480 6 1644 1181 1646 2480 2481 2482 6 1645 1181 1182 1647 2482 1651 6 1646 1182 1648 1649 1650 1651 6 1647 1182 1649 1656 3098 1183 6 1647 1648 1650 1654 1655 1656 6 1647 1649 1651 1652 1653 1654 6 1647 1650 1652 2482 1646 2496 6 1651 1650 1653 2496 2497 2498 6 1652 1650 1654 2498 2499 2500 6 1653 1650 1649 1655 2500 2501 6 1654 1649 1656 1657 2501 2502 6 1655 1649 1648 1657 1658 3098 6 1655 1656 1658 1659 2502 2813 6 1657 1656 1659 1660 2242 3098 6 1657 1658 1660 1661 1662 2813 6 1659 1658 1661 1190 1189 2242 6 1659 1660 1662 1663 1191 1190 6 1659 1661 1663 1664 1665 2813 6 1662 1661 1664 1671 1192 1191 6 1662 1663 1665 1666 1670 1671 6 1662 1664 1666 1667 2813 2812 6 1665 1664 1667 1668 1669 1670 6 1665 1666 1668 2812 2814 2815 6 1667 1666 1669 2815 2816 2817 6 1668 1666 1670 2817 2822 2823 6 1669 1666 1664 1671 1672 2823 6 1670 1664 1663 1192 1193 1672 6 1671 1193 1194 1673 2823 1670 6 1672 1194 1195 1674 2824 2823 6 1673 1195 1196 1675 3148 2824 6 1674 1196 1197 1676 3148 3413 6 1675 1197 1198 1501 1677 3413 6 1676 1501 1502 1678 3413 3414 6 1677 1502 1679 3414 3415 3416 6 1678 1502 1680 3416 5382 5383 6 1679 1502 1458 1459 1681 5382 6 1680 1459 1460 1682 1683 5382 6 1681 1460 1461 1683 1684 1685 6 1681 1682 1684 3775 5384 5382 6 1683 1682 1685 3775 3776 3777 6 1684 1682 1461 1686 1687 3777 6 1685 1461 1687 1688 1204 1203 6 1685 1686 1688 3777 3778 3782 6 1687 1686 1204 1205 1689 3782 6 1688 1205 1206 1690 3782 3783 6 1689 1206 1207 1691 1692 3783 6 1690 1207 1692 1693 1694 1208 6 1690 1691 1693 3783 3784 3785 6 1692 1691 1694 3785 3786 3787 6 1693 1691 1208 1209 1695 3787 6 1694 1209 1210 1696 3787 3417 6 1695 1210 1211 1557 1697 3417 6 1696 1557 1558 1698 3417 3418 6 1697 1558 1560 1699 3418 3419 6 1698 1560 1700 1704 2224 3419 6 1699 1560 1561 1701 1702 1704 6 1700 1561 1702 1703 1709 1710 6 1700 1701 1703 1704 1705 1706 6 1702 1701 1706 1707 1708 1709 6 1700 1702 1705 1699 2224 2225 6 1704 1702 1706 2225 2226 2227 6 1705 1702 1703 1707 2227 2228 6 1706 1703 1708 2228 2229 2230 6 1707 1703 1709 2230 2231 2232 6 1708 1703 1701 1710 1712 2232 6 1709 1701 1561 1562 1711 1712 6 1710 1562 1549 1550 1552 1712 6 1711 1552 1713 2232 1709 1710 6 1712 1552 1553 1714 2233 2232 6 1713 1553 1555 1715 2241 2233 6 1714 1555 1716 2241 2561 2565 6 1715 1555 1556 1717 2565 2566 6 1716 1556 1219 1220 1718 2566 6 1717 1220 1221 1719 2566 2567 6 1718 1221 1222 1720 2570 2567 6 1719 1222 1223 1721 3464 2570 6 1720 1223 1224 1722 3463 3464 6 1721 1224 1225 1723 3470 3463 6 1722 1225 1226 1724 1725 3470 6 1723 1226 1725 1726 1727 1227 6 1723 1724 1726 2173 3468 3470 6 1725 1724 1727 2173 2174 2175 6 1726 1724 1227 1228 1728 2175 6 1727 1228 1229 1729 2175 2176 6 1728 1229 1230 1730 2176 2177 6 1729 1230 1231 1731 1732 2177 6 1730 1231 1732 1733 1734 1232 6 1730 1731 1733 2179 2177 2809 6 1732 1731 1734 3405 2809 3406 6 1733 1731 1232 1233 1735 3406 6 1734 1233 1234 1736 3406 3407 6 1735 1234 1235 1737 3407 3408 6 1736 1235 1236 1738 3408 3409 6 1737 1236 1237 1739 3409 3410 6 1738 1237 1238 1740 3410 3411 6 1739 1238 1239 1741 3411 3412 6 1740 1239 1240 1742 3198 3412 6 1741 1240 1241 1743 3192 3198 6 1742 1241 1242 1744 3192 1745 6 1743 1242 1243 1244 1245 1745 7 1744 1245 1246 1746 3192 1743 3200 6 1745 1246 1247 1747 2894 3200 6 1746 1247 1248 1748 2752 2894 6 1747 1248 1249 1250 1749 2752 6 1748 1250 1750 2234 2752 2753 6 1749 1250 1251 1751 2234 2235 6 1750 1251 1252 1752 2238 2235 6 1751 1252 1253 1753 2248 2238 6 1752 1253 1254 1754 2248 2254 6 1753 1254 1255 1755 2254 2255 6 1754 1255 1256 1756 2255 2256 6 1755 1256 1257 1757 2256 2257 6 1756 1257 1258 1259 1758 2257 6 1757 1259 1759 2257 2258 2259 6 1758 1259 1260 1760 2259 2260 6 1759 1260 1261 1761 2260 2261 6 1760 1261 1262 1762 2261 2262 6 1761 1262 1263 1763 2262 2263 6 1762 1263 1264 1764 2263 2264 6 1763 1264 1265 1765 2264 2265 6 1764 1265 1266 1766 2265 2266 6 1765 1266 1267 1767 2266 2267 6 1766 1267 1268 1768 2267 2268 6 1767 1268 1269 1769 2268 2269 6 1768 1269 1270 1770 2269 2270 6 1769 1270 1271 1771 2270 2271 6 1770 1271 1272 1772 2271 2272 6 1771 1272 1273 1773 2272 2273 6 1772 1273 1274 1774 2273 2274 6 1773 1274 1275 1775 2274 2275 6 1774 1275 1276 1776 2275 2276 6 1775 1276 1277 1777 2276 2277 6 1776 1277 1278 1778 2277 2278 6 1777 1278 1279 1779 2278 2279 6 1778 1279 1280 1780 2279 2280 6 1779 1280 1281 1781 2280 2281 6 1780 1281 1282 1782 2281 2282 6 1781 1282 1283 1783 2282 2283 6 1782 1283 1284 1784 2283 2284 6 1783 1284 1285 1785 2284 2285 6 1784 1285 1286 1786 2285 2286 6 1785 1286 1287 1787 2286 2287 6 1786 1287 1288 1788 2287 2288 6 1787 1288 1289 1789 2288 2289 6 1788 1289 1290 1790 2289 2290 6 1789 1290 1291 1791 2290 2291 6 1790 1291 1292 1792 2291 2292 6 1791 1292 1293 1793 2292 2293 6 1792 1293 1294 1794 2293 2294 6 1793 1294 1295 1795 2294 2295 6 1794 1295 1296 1796 2295 2296 6 1795 1296 1297 1797 2099 2296 6 1796 1297 1298 1798 2099 2100 6 1797 1298 1299 1301 2100 2101 6 1308 1309 1800 2107 2108 2109 6 1799 1309 1310 1801 2109 2110 6 1800 1310 1311 1802 2110 2111 6 1801 1311 1312 1803 2111 2112 6 1802 1312 1313 1804 2112 2113 6 1803 1313 1314 1805 2113 2114 6 1804 1314 1315 1806 2114 2115 6 1805 1315 1316 1807 2115 2116 6 1806 1316 1317 1808 2116 2117 6 1807 1317 1318 1809 2117 2118 6 1808 1318 1319 1810 2118 2119 6 1809 1319 1320 1811 2119 2120 6 1810 1320 1321 1812 2120 2121 6 1811 1321 1322 1813 2121 2122 6 1812 1322 1323 1814 2122 2123 6 1813 1323 1324 1815 2123 2124 6 1814 1324 1325 1816 2124 2125 6 1815 1325 1326 1817 2125 2126 6 1816 1326 1327 1818 2126 2127 6 1817 1327 1328 1819 2127 2128 6 1818 1328 1329 1820 2128 2129 6 1819 1329 1330 1821 2129 2130 6 1820 1330 1331 1822 2130 2131 6 1821 1331 1332 1823 2131 2132 6 1822 1332 1333 1824 2132 2133 6 1823 1333 1334 1825 2133 2134 6 1824 1334 1335 1826 2134 2135 6 1825 1335 1336 1827 2135 2136 6 1826 1336 1337 1338 1828 2136 6 1827 1338 1829 2136 2137 2138 6 1828 1338 1339 1830 2138 2139 6 1829 1339 1340 1831 2139 2140 6 1830 1340 1832 2140 2141 2142 6 1831 1340 1341 1342 1833 2142 6 1832 1342 1343 1834 2142 2143 6 1833 1343 1344 1835 2143 2144 6 1834 1344 1345 1836 2144 2145 6 1835 1345 1346 1837 2145 2146 6 1836 1346 1347 1348 1838 2146 6 1837 1348 1839 2151 2146 2166 6 1838 1348 1349 1840 2166 2167 6 1839 1349 1350 1841 2167 2168 6 1840 1350 1351 1842 2168 2169 6 1841 1351 1352 1843 2172 2169 6 1842 1352 1353 1844 2350 2172 6 1843 1353 1354 1845 2350 2351 6 1844 1354 1355 1846 2351 2352 6 1845 1355 1356 1847 2352 2353 6 1846 1356 1357 1848 2353 2354 6 1847 1357 1358 1849 2354 2355 6 1848 1358 1359 1850 2355 2356 6 1849 1359 1360 1851 2356 2357 6 1850 1360 1361 1852 2357 2358 6 1851 1361 1362 1853 2358 2359 6 1852 1362 1363 1854 2359 2360 6 1853 1363 1364 1855 2360 2361 6 1854 1364 1365 1856 2361 2362 6 1855 1365 1366 1857 1967 2362 6 1856 1366 1367 1858 1967 1968 6 1857 1367 1368 1859 1968 1969 6 1858 1368 1369 1860 1969 1970 6 1859 1369 1370 1861 1970 1971 6 1860 1370 1371 1862 1971 1972 6 1861 1371 1372 1863 1972 1973 6 1862 1372 1373 1864 1973 1974 6 1863 1373 1374 1865 1974 1975 6 1864 1374 1375 1866 1975 1976 6 1865 1375 1376 1867 1976 1977 6 1866 1376 1377 1868 1977 1978 6 1867 1377 1378 1869 1978 1979 6 1868 1378 1379 1870 1979 1980 6 1869 1379 1380 1871 1980 1981 6 1870 1380 1381 1872 1981 1982 6 1871 1381 1382 1873 1982 1983 6 1872 1382 1383 1874 1983 1984 6 1873 1383 1384 1875 1984 1985 6 1874 1384 1385 1876 1985 1986 6 1875 1385 1386 1877 1986 1987 6 1876 1386 1387 1878 1987 1988 6 1877 1387 1388 1879 1988 1989 6 1878 1388 1389 1880 1989 1990 6 1879 1389 1390 1881 1990 1991 6 1880 1390 1391 1882 1991 1992 6 1881 1391 1392 1883 1992 1993 6 1882 1392 1393 1884 1993 1994 6 1883 1393 1394 1885 1994 1995 6 1884 1394 1395 1886 1995 1996 6 1885 1395 1396 1887 1996 1997 6 1886 1396 1397 1888 1997 1998 6 1887 1397 1398 1889 1998 1999 6 1888 1398 1399 1890 1999 2000 6 1889 1399 1400 1891 2000 2001 6 1890 1400 1401 1892 2001 2002 6 1891 1401 1402 1893 2002 2003 6 1892 1402 1403 1894 2003 2004 6 1893 1403 1404 1895 2004 2005 6 1894 1404 1405 1896 2005 2006 6 1895 1405 1406 1897 2006 2007 6 1896 1406 1407 1898 2007 2008 6 1897 1407 1408 1899 2008 2009 6 1898 1408 1409 1900 2009 2010 6 1899 1409 1410 1901 2010 2011 6 1900 1410 1411 1902 2011 2012 6 1901 1411 1412 1903 2012 2013 6 1902 1412 1413 1904 2013 2014 6 1903 1413 1414 1905 2014 2015 6 1904 1414 1415 1906 2015 2016 6 1905 1415 1416 1907 2016 2017 6 1906 1416 1417 1908 2017 2018 6 1907 1417 1418 1909 2018 2019 6 1908 1418 1419 1910 2019 2020 6 1909 1419 1420 1911 2020 2021 6 1910 1420 1421 1912 2021 2022 6 1911 1421 1422 1913 2022 2023 6 1912 1422 1423 1914 2023 2024 6 1913 1423 1424 1915 2024 2025 6 1914 1424 1425 1916 2025 2026 6 1915 1425 1426 1917 2026 2027 6 1916 1426 1427 1918 2027 2028 6 1917 1427 1428 1919 2028 2029 6 1918 1428 1429 1920 2029 2030 6 1919 1429 1430 1921 2030 2031 6 1920 1430 1431 1922 2031 2032 6 1921 1431 1432 1923 2032 2033 6 1922 1432 1433 1924 2033 2034 6 1923 1433 1434 1925 2034 2035 6 1924 1434 1435 1926 2035 2036 6 1925 1435 1436 1927 2036 1928 6 1926 1436 1437 1438 1439 1928 7 1927 1439 1440 1929 2036 1926 2037 6 1928 1440 1441 1930 2037 2038 6 1929 1441 1442 1931 2038 2039 6 1930 1442 1443 1932 2039 2040 6 1931 1443 1444 1933 2040 2041 7 1932 1444 1445 1462 1934 2041 2042 5 1933 1462 1935 2042 2043 6 1934 1462 1463 1936 2043 2044 6 1935 1463 1464 1937 2044 2045 6 1936 1464 1465 1938 2045 2046 6 1937 1465 1466 1467 1939 2046 6 1938 1467 1940 2046 2047 2048 6 1939 1467 1468 1941 2048 2049 6 1940 1468 1469 1470 1942 2049 6 1941 1470 1943 2049 2050 2051 6 1942 1470 1471 1944 2051 2052 6 1943 1471 1472 1945 2052 2053 6 1944 1472 1946 2053 2054 2055 6 1945 1472 1473 1947 2055 1948 6 1946 1473 1474 1491 1492 1948 6 1947 1492 1949 2055 1946 2056 6 1948 1492 1493 1950 1951 2056 6 1949 1493 1951 1952 1496 1494 6 1949 1950 1952 2056 2057 2058 6 1951 1950 1496 1953 2058 2059 6 1952 1496 1497 1531 1954 2059 6 1953 1531 1532 1955 2059 2060 6 1954 1532 1533 1956 2060 2061 6 1955 1533 1535 1957 2061 2062 6 1956 1535 1958 1959 2062 2063 6 1957 1535 1959 1960 1961 1536 6 1957 1958 1960 2063 2064 2065 6 1959 1958 1961 2065 2066 2067 6 1960 1958 1536 1542 1962 2067 6 1961 1542 1963 2067 2068 2069 6 1962 1542 1168 1169 1964 2069 6 1963 1169 1965 1966 2071 2069 6 1964 1169 1966 888 887 1170 6 1964 1965 888 2073 2071 2076 6 1856 1857 1968 2362 2363 2364 6 1967 1857 1858 1969 2364 2365 6 1968 1858 1859 1970 2365 2366 6 1969 1859 1860 1971 2366 2367 6 1970 1860 1861 1972 2367 2368 6 1971 1861 1862 1973 2368 2369 6 1972 1862 1863 1974 2369 2370 6 1973 1863 1864 1975 2370 2371 6 1974 1864 1865 1976 2371 2372 6 1975 1865 1866 1977 2372 2373 6 1976 1866 1867 1978 2373 2374 6 1977 1867 1868 1979 2374 2375 6 1978 1868 1869 1980 2375 2376 6 1979 1869 1870 1981 2376 2377 6 1980 1870 1871 1982 2377 2378 6 1981 1871 1872 1983 2378 2379 6 1982 1872 1873 1984 2379 2380 6 1983 1873 1874 1985 2380 2381 6 1984 1874 1875 1986 2381 2382 6 1985 1875 1876 1987 2382 2383 6 1986 1876 1877 1988 2383 2384 6 1987 1877 1878 1989 2384 2385 6 1988 1878 1879 1990 2385 2386 6 1989 1879 1880 1991 2386 2387 6 1990 1880 1881 1992 2387 2388 6 1991 1881 1882 1993 2388 2389 6 1992 1882 1883 1994 2389 2390 6 1993 1883 1884 1995 2390 2391 6 1994 1884 1885 1996 2391 2392 6 1995 1885 1886 1997 2392 2393 6 1996 1886 1887 1998 2393 2394 6 1997 1887 1888 1999 2394 2395 6 1998 1888 1889 2000 2395 2396 6 1999 1889 1890 2001 2396 2397 6 2000 1890 1891 2002 2397 2398 6 2001 1891 1892 2003 2398 2399 6 2002 1892 1893 2004 2399 2400 6 2003 1893 1894 2005 2400 2401 6 2004 1894 1895 2006 2401 2402 6 2005 1895 1896 2007 2402 2403 6 2006 1896 1897 2008 2403 2404 6 2007 1897 1898 2009 2404 2405 6 2008 1898 1899 2010 2405 2406 6 2009 1899 1900 2011 2406 2407 6 2010 1900 1901 2012 2407 2408 6 2011 1901 1902 2013 2408 2409 6 2012 1902 1903 2014 2409 2410 6 2013 1903 1904 2015 2410 2411 6 2014 1904 1905 2016 2411 2412 6 2015 1905 1906 2017 2412 2413 6 2016 1906 1907 2018 2413 2414 6 2017 1907 1908 2019 2414 2415 6 2018 1908 1909 2020 2415 2416 6 2019 1909 1910 2021 2416 2417 6 2020 1910 1911 2022 2417 2418 6 2021 1911 1912 2023 2418 2419 6 2022 1912 1913 2024 2419 2420 6 2023 1913 1914 2025 2420 2421 6 2024 1914 1915 2026 2421 2422 6 2025 1915 1916 2027 2422 2423 6 2026 1916 1917 2028 2423 2424 6 2027 1917 1918 2029 2424 2425 6 2028 1918 1919 2030 2425 2426 6 2029 1919 1920 2031 2426 2427 6 2030 1920 1921 2032 2427 2428 6 2031 1921 1922 2033 2428 2429 6 2032 1922 1923 2034 2429 2430 6 2033 1923 1924 2035 2430 2431 6 2034 1924 1925 2036 2431 2432 6 2035 1925 1926 1928 2037 2432 5 2036 1928 1929 2038 2432 6 2037 1929 1930 2039 2432 2433 6 2038 1930 1931 2040 2433 2434 6 2039 1931 1932 2041 2434 2435 7 2040 1932 1933 2042 2435 2436 2437 5 2041 1933 1934 2043 2437 7 2042 1934 1935 2044 2437 2438 2439 6 2043 1935 1936 2045 2439 2440 6 2044 1936 1937 2046 2440 2441 6 2045 1937 1938 1939 2047 2441 6 2046 1939 2048 2441 2442 2443 6 2047 1939 1940 2049 2443 2444 6 2048 1940 1941 1942 2050 2444 6 2049 1942 2051 2444 2445 2449 6 2050 1942 1943 2052 2449 2450 6 2051 1943 1944 2053 2450 2451 6 2052 1944 1945 2054 2451 2452 6 2053 1945 2055 2452 2453 2454 6 2054 1945 1946 1948 2056 2454 6 2055 1948 1949 1951 2057 2454 6 2056 1951 2058 2454 2455 2456 6 2057 1951 1952 2059 2456 2457 6 2058 1952 1953 1954 2060 2457 6 2059 1954 1955 2061 2457 2458 6 2060 1955 1956 2062 2458 2459 6 2061 1956 1957 2063 2459 2460 6 2062 1957 1959 2064 2460 2461 6 2063 1959 2065 2461 2462 2463 6 2064 1959 1960 2066 2463 2464 6 2065 1960 2067 2464 2465 2466 6 2066 1960 1961 1962 2068 2466 6 2067 1962 2069 2070 2466 2467 6 2068 1962 1963 2070 2071 1964 6 2068 2069 2071 2072 2467 2470 6 2070 2069 1964 2072 2073 1966 6 2070 2071 2073 2074 2470 2471 6 2072 2071 1966 2074 2075 2076 6 2072 2073 2075 2474 2471 2087 6 2074 2073 2076 2077 2079 2087 6 2075 2073 1966 888 889 2077 6 2076 889 890 2078 2079 2075 6 2077 890 2079 2080 2081 2082 6 2077 2078 2080 2075 2087 2088 6 2079 2078 2081 2097 2088 2083 6 2080 2078 2082 899 902 2083 6 2081 2078 890 891 895 899 6 2081 902 904 2084 2097 2080 6 2083 904 2085 2097 2096 9777 6 2084 904 905 2086 6094 9777 6 2085 905 1566 1568 3767 6094 6 2075 2079 2088 2089 2474 2074 6 2087 2079 2089 2090 2097 2080 6 2087 2088 2090 2091 2092 2474 6 2089 2088 2091 2095 2096 2097 6 2089 2090 2092 2093 2094 2095 6 2089 2091 2093 2490 2473 2474 6 2092 2091 2094 2490 5948 5949 6 2093 2091 2095 3136 5948 3133 6 2094 2091 2090 2096 3132 3133 6 2095 2090 2097 3132 2084 9777 6 2096 2090 2088 2080 2083 2084 6 632 404 634 651 650 405 6 1796 1797 2100 2296 2297 2298 6 2099 1797 1798 2101 2298 2102 5 2100 1798 1301 1302 2102 6 2101 1302 1303 2103 2298 2100 6 2102 1303 1304 2104 2298 2299 6 2103 1304 1305 2105 2299 2300 6 2104 1305 1306 2106 2300 2301 6 2105 1306 1307 2107 2301 2302 7 2106 1307 1308 1799 2108 2302 2303 5 2107 1799 2109 2303 2304 6 2108 1799 1800 2110 2304 2305 6 2109 1800 1801 2111 2305 2306 6 2110 1801 1802 2112 2306 2307 6 2111 1802 1803 2113 2307 2308 6 2112 1803 1804 2114 2308 2309 6 2113 1804 1805 2115 2309 2310 6 2114 1805 1806 2116 2310 2311 6 2115 1806 1807 2117 2311 2312 6 2116 1807 1808 2118 2312 2313 6 2117 1808 1809 2119 2313 2314 6 2118 1809 1810 2120 2314 2315 6 2119 1810 1811 2121 2315 2316 6 2120 1811 1812 2122 2316 2317 6 2121 1812 1813 2123 2317 2318 6 2122 1813 1814 2124 2318 2319 6 2123 1814 1815 2125 2319 2320 6 2124 1815 1816 2126 2320 2321 6 2125 1816 1817 2127 2321 2322 6 2126 1817 1818 2128 2322 2323 6 2127 1818 1819 2129 2323 2324 6 2128 1819 1820 2130 2324 2325 6 2129 1820 1821 2131 2325 2326 6 2130 1821 1822 2132 2326 2327 6 2131 1822 1823 2133 2327 2328 6 2132 1823 1824 2134 2152 2328 6 2133 1824 1825 2135 2152 2153 6 2134 1825 1826 2136 2153 2154 6 2135 1826 1827 1828 2137 2154 6 2136 1828 2138 2154 2155 2156 6 2137 1828 1829 2139 2156 2157 6 2138 1829 1830 2140 2157 2158 6 2139 1830 1831 2141 2158 2159 6 2140 1831 2142 2147 2159 2160 6 2141 1831 1832 1833 2143 2147 6 2142 1833 1834 2144 2147 2148 6 2143 1834 1835 2145 2148 2149 6 2144 1835 1836 2146 2149 2150 6 2145 1836 1837 2150 2151 1838 6 2141 2142 2143 2148 2160 2161 6 2147 2143 2144 2149 2161 2162 6 2148 2144 2145 2150 2162 2163 6 2149 2145 2146 2151 2163 2164 6 2150 2146 1838 2164 2165 2166 6 2133 2134 2153 2328 2329 2330 6 2152 2134 2135 2154 2330 2331 6 2153 2135 2136 2137 2155 2331 6 2154 2137 2156 2331 2332 2333 6 2155 2137 2138 2157 2333 2334 6 2156 2138 2139 2158 2334 2335 6 2157 2139 2140 2159 2335 2336 6 2158 2140 2141 2160 2336 2337 6 2159 2141 2147 2161 2337 2338 6 2160 2147 2148 2162 2338 2339 6 2161 2148 2149 2163 2339 2340 6 2162 2149 2150 2164 2340 2341 6 2163 2150 2151 2165 2341 2342 6 2164 2151 2166 2342 2343 2344 6 2165 2151 1838 1839 2167 2344 6 2166 1839 1840 2168 2344 2345 6 2167 1840 1841 2169 2170 2345 6 2168 1841 2170 2171 2172 1842 6 2168 2169 2171 2345 2346 2347 6 2170 2169 2172 2347 2348 2349 6 2171 2169 1842 2349 2350 1843 6 1725 1726 2174 3469 3468 4748 6 2173 1726 2175 2805 3396 4748 6 2174 1726 1727 1728 2176 2805 6 2175 1728 1729 2177 2178 2805 6 2176 1729 2178 2179 1732 1730 6 2176 2177 2179 2805 2806 2807 6 2178 2177 1732 2807 2808 2809 6 28 29 2181 2182 3852 3853 6 2180 29 30 2182 2183 2504 6 2180 2181 2183 2184 2200 3852 6 2182 2181 2184 2185 2503 2504 6 2182 2183 2185 2186 2199 2200 6 2184 2183 2186 2187 2194 2503 6 2184 2185 2187 2188 2198 2199 6 2186 2185 2188 2189 2193 2194 6 2186 2187 2189 2190 2198 9714 6 2188 2187 2190 2191 2192 2193 7 2188 2189 2191 9710 9709 9713 9714 5 2190 2189 2192 9711 9710 6 2191 2189 2193 2511 2513 9711 6 2192 2189 2187 2194 2511 2507 6 2193 2187 2185 2503 2505 2507 6 416 40 41 2196 9705 6489 6 2195 41 42 2197 6489 9706 7 2196 42 43 9706 44 9772 9774 6 2186 2188 2199 9714 9715 9721 6 2186 2198 2184 2200 2201 9721 6 2184 2199 2201 2202 2182 3852 6 2200 2199 2202 2203 9721 2218 6 2200 2201 2203 2204 3130 3852 6 2202 2201 2204 2205 2218 2209 6 2202 2203 2205 2206 3130 3131 6 2204 2203 2206 2207 2208 2209 6 2204 2205 2207 3131 1526 4251 6 2206 2205 2208 3344 3342 4251 6 2207 2205 2209 2210 3344 3345 6 2208 2205 2210 2211 2218 2203 6 2208 2209 2211 2212 3345 3346 6 2210 2209 2212 2213 2217 2218 6 2210 2211 2213 2214 3349 3346 6 2212 2211 2214 2215 2216 2217 6 2212 2213 2215 6523 6524 3349 6 2214 2213 2216 9717 9720 6523 6 2215 2213 2217 9717 9716 9715 6 2216 2213 2211 2218 9715 9721 6 2217 2211 2209 2203 9721 2201 6 409 60 61 2220 2546 2547 6 2219 61 62 2221 2550 2547 6 2220 62 63 2222 2550 2552 6 2221 63 64 2223 2552 6703 6 2222 64 6702 6701 6703 65 6 1699 1704 2225 3419 3420 3421 6 2224 1704 1705 2226 3421 3422 6 2225 1705 2227 3422 3423 3427 6 2226 1705 1706 2228 3427 3428 6 2227 1706 1707 2229 3428 3429 6 2228 1707 2230 3429 3430 3431 6 2229 1707 1708 2231 2239 3431 6 2230 1708 2232 2233 2239 2240 6 2231 1708 2233 1713 1712 1709 6 2231 2232 1713 2240 2241 1714 6 1749 1750 2235 2236 2243 2753 6 2234 1750 2236 2237 2238 1751 6 2234 2235 2237 2243 2244 2245 6 2236 2235 2238 2245 2246 2247 6 2237 2235 1751 2247 2248 1752 6 2230 2231 2240 3431 3432 3436 6 2239 2231 2233 2241 3436 2562 6 2240 2233 1714 1715 2561 2562 6 1188 1189 1660 1658 3098 1185 6 2234 2236 2244 2753 2754 2755 6 2243 2236 2245 2755 2756 2757 6 2244 2236 2237 2246 2757 2758 6 2245 2237 2247 2758 2759 2760 6 2246 2237 2238 2248 2760 2761 6 2247 2238 1752 1753 2254 2761 6 35 36 2250 3332 3333 3334 6 2249 36 37 2251 3337 3334 6 2250 37 38 417 2252 3337 7 2251 417 2253 6491 6492 9707 3337 5 2252 417 416 6491 9705 6 2248 1753 1754 2255 2761 2762 6 2254 1754 1755 2256 2762 2763 6 2255 1755 1756 2257 2763 2764 6 2256 1756 1757 1758 2258 2764 6 2257 1758 2259 2764 2765 2766 6 2258 1758 1759 2260 2766 2767 6 2259 1759 1760 2261 2767 2768 6 2260 1760 1761 2262 2768 2769 6 2261 1761 1762 2263 2769 2770 6 2262 1762 1763 2264 2572 2770 6 2263 1763 1764 2265 2572 2573 6 2264 1764 1765 2266 2573 2574 6 2265 1765 1766 2267 2574 2575 6 2266 1766 1767 2268 2575 2576 6 2267 1767 1768 2269 2576 2577 6 2268 1768 1769 2270 2577 2578 6 2269 1769 1770 2271 2578 2579 6 2270 1770 1771 2272 2579 2580 6 2271 1771 1772 2273 2580 2581 6 2272 1772 1773 2274 2581 2582 6 2273 1773 1774 2275 2582 2583 6 2274 1774 1775 2276 2583 2584 6 2275 1775 1776 2277 2584 2585 6 2276 1776 1777 2278 2585 2586 6 2277 1777 1778 2279 2586 2587 6 2278 1778 1779 2280 2587 2588 6 2279 1779 1780 2281 2588 2589 6 2280 1780 1781 2282 2589 2590 6 2281 1781 1782 2283 2590 2591 6 2282 1782 1783 2284 2591 2592 6 2283 1783 1784 2285 2592 2593 6 2284 1784 1785 2286 2593 2594 6 2285 1785 1786 2287 2594 2595 6 2286 1786 1787 2288 2595 2596 6 2287 1787 1788 2289 2596 2597 6 2288 1788 1789 2290 2597 2598 6 2289 1789 1790 2291 2598 2599 6 2290 1790 1791 2292 2599 2600 6 2291 1791 1792 2293 2600 2601 6 2292 1792 1793 2294 2601 2602 6 2293 1793 1794 2295 2602 2603 6 2294 1794 1795 2296 2603 2604 6 2295 1795 1796 2099 2297 2604 6 2296 2099 2298 2604 2605 2606 7 2297 2099 2100 2102 2103 2299 2606 6 2298 2103 2104 2300 2606 2607 6 2299 2104 2105 2301 2607 2608 6 2300 2105 2106 2302 2608 2609 6 2301 2106 2107 2303 2609 2610 6 2302 2107 2108 2304 2610 2611 6 2303 2108 2109 2305 2611 2612 6 2304 2109 2110 2306 2612 2613 6 2305 2110 2111 2307 2613 2614 6 2306 2111 2112 2308 2614 2615 6 2307 2112 2113 2309 2615 2616 6 2308 2113 2114 2310 2616 2617 6 2309 2114 2115 2311 2620 2617 6 2310 2115 2116 2312 2620 2621 6 2311 2116 2117 2313 2621 2622 6 2312 2117 2118 2314 2622 2623 6 2313 2118 2119 2315 2623 2624 6 2314 2119 2120 2316 2624 2625 6 2315 2120 2121 2317 2625 2626 6 2316 2121 2122 2318 2626 2627 6 2317 2122 2123 2319 2627 2628 6 2318 2123 2124 2320 2628 2629 6 2319 2124 2125 2321 2629 2630 6 2320 2125 2126 2322 2630 2631 6 2321 2126 2127 2323 2631 2632 6 2322 2127 2128 2324 2632 2633 6 2323 2128 2129 2325 2633 2634 6 2324 2129 2130 2326 2634 2635 6 2325 2130 2131 2327 2635 2636 6 2326 2131 2132 2328 2636 2637 6 2327 2132 2133 2152 2329 2637 6 2328 2152 2330 2637 2638 2639 6 2329 2152 2153 2331 2642 2639 6 2330 2153 2154 2155 2332 2642 6 2331 2155 2333 2643 2642 2644 6 2332 2155 2156 2334 2644 2645 6 2333 2156 2157 2335 2645 2646 6 2334 2157 2158 2336 2646 2647 6 2335 2158 2159 2337 2647 2648 6 2336 2159 2160 2338 2648 2649 6 2337 2160 2161 2339 2649 2650 6 2338 2161 2162 2340 2650 2651 6 2339 2162 2163 2341 2651 2652 6 2340 2163 2164 2342 2652 2653 6 2341 2164 2165 2343 2653 2654 6 2342 2165 2344 2654 2655 2656 6 2343 2165 2166 2167 2345 2656 6 2344 2167 2168 2170 2346 2656 6 2345 2170 2347 2656 2657 2658 6 2346 2170 2171 2348 2658 2659 6 2347 2171 2349 2659 2660 2661 6 2348 2171 2172 2350 2661 2662 6 2349 2172 1843 1844 2351 2662 6 2350 1844 1845 2352 2662 2663 6 2351 1845 1846 2353 2663 2664 6 2352 1846 1847 2354 2664 2665 6 2353 1847 1848 2355 2665 2666 6 2354 1848 1849 2356 2666 2667 6 2355 1849 1850 2357 2667 2668 6 2356 1850 1851 2358 2668 2669 6 2357 1851 1852 2359 2669 2670 6 2358 1852 1853 2360 2670 2671 6 2359 1853 1854 2361 2671 2672 6 2360 1854 1855 2362 2672 2673 6 2361 1855 1856 1967 2363 2673 6 2362 1967 2364 2673 2674 2675 6 2363 1967 1968 2365 2675 2676 6 2364 1968 1969 2366 2676 2677 6 2365 1969 1970 2367 2677 2678 6 2366 1970 1971 2368 2678 2679 6 2367 1971 1972 2369 2679 2680 6 2368 1972 1973 2370 2680 2681 6 2369 1973 1974 2371 2681 2682 6 2370 1974 1975 2372 2682 2683 6 2371 1975 1976 2373 2683 2684 6 2372 1976 1977 2374 2684 2685 6 2373 1977 1978 2375 2685 2686 6 2374 1978 1979 2376 2686 2687 6 2375 1979 1980 2377 2687 2688 6 2376 1980 1981 2378 2688 2689 6 2377 1981 1982 2379 2689 2690 6 2378 1982 1983 2380 2690 2691 6 2379 1983 1984 2381 2691 2692 6 2380 1984 1985 2382 2692 2693 6 2381 1985 1986 2383 2693 2694 6 2382 1986 1987 2384 2694 2695 6 2383 1987 1988 2385 2695 2696 6 2384 1988 1989 2386 2696 2697 6 2385 1989 1990 2387 2697 2698 6 2386 1990 1991 2388 2698 2699 6 2387 1991 1992 2389 2699 2700 6 2388 1992 1993 2390 2700 2701 6 2389 1993 1994 2391 2701 2702 6 2390 1994 1995 2392 2702 2703 6 2391 1995 1996 2393 2703 2704 6 2392 1996 1997 2394 2704 2705 6 2393 1997 1998 2395 2705 2706 6 2394 1998 1999 2396 2706 2707 6 2395 1999 2000 2397 2707 2708 6 2396 2000 2001 2398 2708 2709 6 2397 2001 2002 2399 2709 2710 6 2398 2002 2003 2400 2514 2710 6 2399 2003 2004 2401 2514 2515 6 2400 2004 2005 2402 2515 2516 6 2401 2005 2006 2403 2516 2517 6 2402 2006 2007 2404 2517 2518 6 2403 2007 2008 2405 2518 2519 6 2404 2008 2009 2406 2519 2520 6 2405 2009 2010 2407 2520 2521 6 2406 2010 2011 2408 2521 2522 6 2407 2011 2012 2409 2522 2523 6 2408 2012 2013 2410 2523 2524 6 2409 2013 2014 2411 2524 2525 6 2410 2014 2015 2412 2525 2526 6 2411 2015 2016 2413 2526 2527 6 2412 2016 2017 2414 2527 2528 6 2413 2017 2018 2415 2528 2529 6 2414 2018 2019 2416 2529 2530 6 2415 2019 2020 2417 2530 2531 6 2416 2020 2021 2418 2531 2532 6 2417 2021 2022 2419 2532 2533 6 2418 2022 2023 2420 2533 2534 6 2419 2023 2024 2421 2534 2535 6 2420 2024 2025 2422 2535 2536 6 2421 2025 2026 2423 2536 2537 6 2422 2026 2027 2424 2537 2538 6 2423 2027 2028 2425 2538 2539 6 2424 2028 2029 2426 2539 2540 6 2425 2029 2030 2427 2540 2541 6 2426 2030 2031 2428 2541 2542 6 2427 2031 2032 2429 2542 2543 6 2428 2032 2033 2430 2543 2544 6 2429 2033 2034 2431 2544 2545 6 2430 2034 2035 2432 2545 2433 6 2431 2035 2036 2037 2038 2433 7 2432 2038 2039 2434 2545 2431 2557 6 2433 2039 2040 2435 2557 2558 6 2434 2040 2041 2436 2558 2559 6 2435 2041 2437 2559 2560 2438 5 2436 2041 2042 2043 2438 6 2437 2043 2439 2560 2436 2746 6 2438 2043 2044 2440 2746 2747 7 2439 2044 2045 2441 2747 2748 2749 6 2440 2045 2046 2047 2442 2749 6 2441 2047 2443 2749 2750 2751 6 2442 2047 2048 2444 2751 2446 6 2443 2048 2049 2050 2445 2446 6 2444 2050 2446 2447 2448 2449 6 2444 2445 2447 2751 2443 3061 6 2446 2445 2448 3061 3062 3063 6 2447 2445 2449 3063 3064 3065 6 2448 2445 2050 2051 2450 3065 6 2449 2051 2052 2451 3065 3066 6 2450 2052 2053 2452 3066 3067 6 2451 2053 2054 2453 3067 3068 6 2452 2054 2454 3068 3069 2455 6 2453 2054 2055 2056 2057 2455 6 2454 2057 2456 3069 2453 3075 6 2455 2057 2058 2457 3075 3076 6 2456 2058 2059 2060 2458 3076 6 2457 2060 2061 2459 3076 3077 6 2458 2061 2062 2460 3077 3078 6 2459 2062 2063 2461 3078 3079 6 2460 2063 2064 2462 3079 3080 6 2461 2064 2463 3080 3081 3082 6 2462 2064 2065 2464 3082 3083 6 2463 2065 2066 2465 3083 3084 6 2464 2066 2466 2468 2483 3084 6 2465 2066 2067 2068 2467 2468 6 2466 2068 2070 2468 2469 2470 6 2466 2467 2469 2465 2483 2484 6 2468 2467 2470 2472 2478 2484 6 2469 2467 2070 2072 2471 2472 6 2470 2072 2472 2473 2474 2074 6 2470 2471 2473 2469 2478 2479 6 2472 2471 2474 2490 2479 2092 6 2473 2471 2074 2092 2089 2087 6 1517 1522 915 916 577 1516 6 1579 1588 2477 1575 6362 1574 6 2476 1588 1590 6354 6360 6362 6 2469 2472 2479 2484 2485 2486 6 2478 2472 2486 2489 2490 2473 6 1643 1644 1645 2481 1642 2491 6 2480 1645 2482 2491 2495 2870 6 2481 1645 1646 1651 2495 2496 6 2465 2468 2484 3086 3084 3927 6 2483 2468 2469 2478 2485 3927 6 2484 2478 2486 2487 3927 3151 6 2485 2478 2479 2487 2488 2489 6 2485 2486 2488 3149 3150 3151 6 2487 2486 2489 3149 3968 3162 6 2488 2486 2479 2490 5949 3968 6 2489 2479 2473 2092 2093 5949 6 1642 2480 2481 2868 2869 2870 6 71 72 2493 3437 3438 3442 6 2492 72 73 410 2494 3437 6 2493 410 1607 3516 3437 3517 6 2481 2482 2496 2870 2871 2872 6 2495 2482 1651 1652 2497 2872 6 2496 1652 2498 2872 2873 2883 6 2497 1652 1653 2499 2883 2884 6 2498 1653 2500 2884 4093 4094 6 2499 1653 1654 2501 2810 4094 6 2500 1654 1655 2502 2810 2811 6 2501 1655 1657 2811 2812 2813 6 2185 2183 2504 2194 2505 2506 6 2503 2183 31 2506 30 2181 6 2194 2503 2506 2507 2508 2509 6 2505 2503 2509 32 31 2504 6 2194 2505 2508 2510 2511 2193 6 2507 2505 2509 2510 3331 3881 6 2508 2505 2506 32 3331 33 6 2507 2508 2511 2512 3881 3882 6 2507 2510 2512 2513 2192 2193 6 2511 2510 2513 6500 6499 3882 6 2511 2512 2192 6499 6501 9711 6 2399 2400 2515 2710 2711 2712 6 2514 2400 2401 2516 2712 2713 6 2515 2401 2402 2517 2713 2714 6 2516 2402 2403 2518 2714 2715 6 2517 2403 2404 2519 2715 2716 6 2518 2404 2405 2520 2716 2717 6 2519 2405 2406 2521 2717 2718 6 2520 2406 2407 2522 2718 2719 6 2521 2407 2408 2523 2719 2720 6 2522 2408 2409 2524 2720 2721 6 2523 2409 2410 2525 2721 2722 6 2524 2410 2411 2526 2722 2723 6 2525 2411 2412 2527 2723 2724 6 2526 2412 2413 2528 2724 2725 6 2527 2413 2414 2529 2725 2726 6 2528 2414 2415 2530 2726 2727 6 2529 2415 2416 2531 2727 2728 6 2530 2416 2417 2532 2728 2729 6 2531 2417 2418 2533 2729 2730 6 2532 2418 2419 2534 2730 2731 6 2533 2419 2420 2535 2731 2732 6 2534 2420 2421 2536 2732 2733 6 2535 2421 2422 2537 2733 2734 6 2536 2422 2423 2538 2734 2735 6 2537 2423 2424 2539 2735 2736 6 2538 2424 2425 2540 2736 2737 6 2539 2425 2426 2541 2737 2738 6 2540 2426 2427 2542 2553 2738 6 2541 2427 2428 2543 2553 2554 6 2542 2428 2429 2544 2554 2555 6 2543 2429 2430 2545 2555 2556 6 2544 2430 2431 2433 2556 2557 6 409 2219 2547 2548 2842 2843 6 2546 2219 2548 2549 2550 2220 6 2546 2547 2549 2843 2846 2847 6 2548 2547 2550 2551 2858 2847 6 2549 2547 2220 2221 2551 2552 6 2549 2550 2552 6692 2857 2858 7 2551 2550 2221 2222 6703 6691 6692 6 2541 2542 2554 2738 2739 2740 6 2553 2542 2543 2555 2740 2741 6 2554 2543 2544 2556 2571 2741 6 2555 2544 2545 2557 2571 2558 5 2556 2545 2433 2434 2558 7 2557 2434 2435 2559 2571 2556 2743 5 2558 2435 2436 2560 2743 7 2559 2436 2438 2743 2744 2745 2746 6 2241 1715 2562 2563 2564 2565 6 2241 2561 2563 3436 2240 3447 6 2562 2561 2564 3447 3448 3449 6 2563 2561 2565 3449 3450 2568 6 2564 2561 1715 1716 2566 2568 6 2565 1716 1717 1718 2567 2568 6 2566 1718 2568 2569 2570 1719 6 2566 2567 2569 3450 2564 2565 6 2568 2567 2570 3459 3456 3450 6 2569 2567 1719 3464 3459 1720 6 2555 2556 2558 2741 2742 2743 6 2263 2264 2573 2770 2771 2772 6 2572 2264 2265 2574 2772 2773 6 2573 2265 2266 2575 2773 2774 6 2574 2266 2267 2576 2774 2775 6 2575 2267 2268 2577 2775 2776 6 2576 2268 2269 2578 2776 2777 6 2577 2269 2270 2579 2777 2778 6 2578 2270 2271 2580 2778 2779 6 2579 2271 2272 2581 2779 2780 6 2580 2272 2273 2582 2780 2781 6 2581 2273 2274 2583 2781 2782 6 2582 2274 2275 2584 2782 2783 6 2583 2275 2276 2585 2783 2784 6 2584 2276 2277 2586 2784 2785 6 2585 2277 2278 2587 2785 2786 6 2586 2278 2279 2588 2786 2787 6 2587 2279 2280 2589 2787 2788 6 2588 2280 2281 2590 2788 2789 6 2589 2281 2282 2591 2789 2790 6 2590 2282 2283 2592 2790 2791 6 2591 2283 2284 2593 2791 2792 6 2592 2284 2285 2594 2792 2793 6 2593 2285 2286 2595 2793 2794 6 2594 2286 2287 2596 2794 2795 6 2595 2287 2288 2597 2795 2796 6 2596 2288 2289 2598 2796 2797 6 2597 2289 2290 2599 2797 2798 6 2598 2290 2291 2600 2798 2799 6 2599 2291 2292 2601 2799 2800 6 2600 2292 2293 2602 2800 2801 6 2601 2293 2294 2603 2801 2802 6 2602 2294 2295 2604 2802 2803 6 2603 2295 2296 2297 2605 2803 6 2604 2297 2606 2803 2804 2607 5 2605 2297 2298 2299 2607 7 2606 2299 2300 2608 2804 2605 2827 5 2607 2300 2301 2609 2827 7 2608 2301 2302 2610 2827 2828 2829 6 2609 2302 2303 2611 2829 2830 6 2610 2303 2304 2612 2830 2831 6 2611 2304 2305 2613 2831 2832 6 2612 2305 2306 2614 2832 2833 6 2613 2306 2307 2615 2833 2834 6 2614 2307 2308 2616 2834 2835 6 2615 2308 2309 2617 2618 2835 6 2616 2309 2618 2619 2620 2310 6 2616 2617 2619 2835 2836 2837 6 2618 2617 2620 2837 2838 2839 6 2619 2617 2310 2311 2621 2839 6 2620 2311 2312 2622 2841 2839 6 2621 2312 2313 2623 2960 2841 6 2622 2313 2314 2624 2960 2961 6 2623 2314 2315 2625 2961 2962 6 2624 2315 2316 2626 2962 2963 6 2625 2316 2317 2627 2963 2964 6 2626 2317 2318 2628 2967 2964 6 2627 2318 2319 2629 2967 2968 6 2628 2319 2320 2630 2968 2969 6 2629 2320 2321 2631 2969 2970 6 2630 2321 2322 2632 2970 2971 6 2631 2322 2323 2633 2971 2972 6 2632 2323 2324 2634 2972 2973 6 2633 2324 2325 2635 2973 2974 6 2634 2325 2326 2636 2974 2975 6 2635 2326 2327 2637 2975 2976 6 2636 2327 2328 2329 2638 2976 6 2637 2329 2639 2640 2976 2977 6 2638 2329 2640 2641 2642 2330 6 2638 2639 2641 2977 2978 2979 6 2640 2639 2642 2643 2979 2980 6 2641 2639 2643 2332 2331 2330 6 2641 2642 2332 2644 2980 2981 6 2643 2332 2333 2645 2981 2982 6 2644 2333 2334 2646 2982 2983 6 2645 2334 2335 2647 2983 2984 6 2646 2335 2336 2648 2984 2985 6 2647 2336 2337 2649 2985 2986 6 2648 2337 2338 2650 2986 2987 6 2649 2338 2339 2651 2987 2988 6 2650 2339 2340 2652 2988 2989 6 2651 2340 2341 2653 2989 2990 6 2652 2341 2342 2654 2990 2991 6 2653 2342 2343 2655 2991 2992 6 2654 2343 2656 2992 2993 2657 6 2655 2343 2344 2345 2346 2657 6 2656 2346 2658 2993 2655 2994 6 2657 2346 2347 2659 2994 2995 6 2658 2347 2348 2660 2995 2996 6 2659 2348 2661 2996 2997 2998 6 2660 2348 2349 2662 2998 2999 6 2661 2349 2350 2351 2663 2999 6 2662 2351 2352 2664 2999 3000 6 2663 2352 2353 2665 3000 3001 6 2664 2353 2354 2666 3001 3002 6 2665 2354 2355 2667 3002 3003 6 2666 2355 2356 2668 3003 3566 6 2667 2356 2357 2669 3566 3567 6 2668 2357 2358 2670 3567 3568 6 2669 2358 2359 2671 3568 3569 6 2670 2359 2360 2672 3569 3570 6 2671 2360 2361 2673 3570 3571 6 2672 2361 2362 2363 2674 3571 6 2673 2363 2675 3571 3572 3573 6 2674 2363 2364 2676 3573 3574 6 2675 2364 2365 2677 3392 3574 6 2676 2365 2366 2678 3392 3393 6 2677 2366 2367 2679 3393 3394 6 2678 2367 2368 2680 3394 3395 6 2679 2368 2369 2681 3395 3580 6 2680 2369 2370 2682 3580 3581 6 2681 2370 2371 2683 3581 3582 6 2682 2371 2372 2684 3582 3583 6 2683 2372 2373 2685 3583 3584 6 2684 2373 2374 2686 3584 3585 6 2685 2374 2375 2687 3585 3586 6 2686 2375 2376 2688 3586 3587 6 2687 2376 2377 2689 3587 3588 6 2688 2377 2378 2690 3588 3589 6 2689 2378 2379 2691 3279 3589 6 2690 2379 2380 2692 3279 3280 6 2691 2380 2381 2693 3280 3281 6 2692 2381 2382 2694 3281 3282 6 2693 2382 2383 2695 3282 3283 6 2694 2383 2384 2696 3283 3284 6 2695 2384 2385 2697 3284 3285 6 2696 2385 2386 2698 3285 3286 6 2697 2386 2387 2699 3286 3287 6 2698 2387 2388 2700 3287 3288 6 2699 2388 2389 2701 3288 3289 6 2700 2389 2390 2702 3289 3290 6 2701 2390 2391 2703 3290 3291 6 2702 2391 2392 2704 3004 3291 6 2703 2392 2393 2705 3004 3005 6 2704 2393 2394 2706 3005 3006 6 2705 2394 2395 2707 3006 3007 6 2706 2395 2396 2708 3007 3008 6 2707 2396 2397 2709 3008 3009 6 2708 2397 2398 2710 3009 3010 6 2709 2398 2399 2514 2711 3010 6 2710 2514 2712 3010 3011 3012 6 2711 2514 2515 2713 3012 3013 6 2712 2515 2516 2714 3013 3014 6 2713 2516 2517 2715 3014 3015 6 2714 2517 2518 2716 3015 3016 6 2715 2518 2519 2717 3016 3017 6 2716 2519 2520 2718 3017 3018 6 2717 2520 2521 2719 3018 3019 6 2718 2521 2522 2720 3019 3020 6 2719 2522 2523 2721 3020 3021 6 2720 2523 2524 2722 3021 3022 6 2721 2524 2525 2723 3022 3023 6 2722 2525 2526 2724 3023 3024 6 2723 2526 2527 2725 3024 3025 6 2724 2527 2528 2726 3025 3026 6 2725 2528 2529 2727 3026 3027 6 2726 2529 2530 2728 3027 3028 6 2727 2530 2531 2729 3028 3029 6 2728 2531 2532 2730 3029 3030 6 2729 2532 2533 2731 3030 3031 6 2730 2533 2534 2732 3031 3032 6 2731 2534 2535 2733 3032 3033 6 2732 2535 2536 2734 3033 3034 6 2733 2536 2537 2735 3034 3035 6 2734 2537 2538 2736 3035 3036 6 2735 2538 2539 2737 3036 3037 6 2736 2539 2540 2738 3037 3038 6 2737 2540 2541 2553 2739 3038 6 2738 2553 2740 3038 3039 3040 6 2739 2553 2554 2741 3040 3041 6 2740 2554 2555 2571 2742 3041 6 2741 2571 2743 3041 3042 2744 6 2742 2571 2558 2559 2560 2744 6 2743 2560 2745 3042 2742 3050 5 2744 2560 2746 3050 3051 6 2745 2560 2438 2439 2747 3051 6 2746 2439 2440 2748 3051 3052 6 2747 2440 2749 3052 3053 2750 5 2748 2440 2441 2442 2750 6 2749 2442 2751 3053 2748 3059 7 2750 2442 2443 2446 3059 3060 3061 6 1747 1748 1749 2753 2894 2895 6 2752 1749 2234 2243 2754 2895 6 2753 2243 2755 2895 2896 2897 6 2754 2243 2244 2756 2897 2898 6 2755 2244 2757 2898 2899 2900 6 2756 2244 2245 2758 2900 2901 6 2757 2245 2246 2759 2901 2902 6 2758 2246 2760 2902 2903 2904 6 2759 2246 2247 2761 2904 2905 6 2760 2247 2248 2254 2762 2905 6 2761 2254 2255 2763 2905 2906 6 2762 2255 2256 2764 2906 2907 6 2763 2256 2257 2258 2765 2907 6 2764 2258 2766 2907 2908 2909 6 2765 2258 2259 2767 2909 2910 6 2766 2259 2260 2768 2910 2911 6 2767 2260 2261 2769 2911 2912 6 2768 2261 2262 2770 2912 2913 6 2769 2262 2263 2572 2771 2913 6 2770 2572 2772 2913 2914 2915 6 2771 2572 2573 2773 2915 2916 6 2772 2573 2574 2774 2916 2917 6 2773 2574 2575 2775 2917 2918 6 2774 2575 2576 2776 2918 2919 6 2775 2576 2577 2777 2919 2920 6 2776 2577 2578 2778 2920 2921 6 2777 2578 2579 2779 2921 2922 6 2778 2579 2580 2780 2922 2923 6 2779 2580 2581 2781 2923 2924 6 2780 2581 2582 2782 2924 2925 6 2781 2582 2583 2783 2925 2926 6 2782 2583 2584 2784 2926 2927 6 2783 2584 2585 2785 2927 2928 6 2784 2585 2586 2786 2928 2929 6 2785 2586 2587 2787 2929 2930 6 2786 2587 2588 2788 2930 2931 6 2787 2588 2589 2789 2931 2932 6 2788 2589 2590 2790 2932 2933 6 2789 2590 2591 2791 2933 2934 6 2790 2591 2592 2792 2934 2935 6 2791 2592 2593 2793 2935 2936 6 2792 2593 2594 2794 2936 2937 6 2793 2594 2595 2795 2937 2938 6 2794 2595 2596 2796 2938 2939 6 2795 2596 2597 2797 2939 2940 6 2796 2597 2598 2798 2940 2941 6 2797 2598 2599 2799 2941 2942 6 2798 2599 2600 2800 2942 2943 6 2799 2600 2601 2801 2943 2944 6 2800 2601 2602 2802 2944 2945 6 2801 2602 2603 2803 2945 2825 6 2802 2603 2604 2605 2804 2825 6 2803 2605 2607 2825 2826 2827 6 2174 2175 2176 2178 2806 3396 6 2805 2178 2807 3396 3397 3401 6 2806 2178 2179 2808 3401 3402 6 2807 2179 2809 3402 3403 3404 6 2808 2179 1732 3404 3405 1733 6 2500 2501 2811 4096 4094 4389 6 2810 2501 2502 2812 4389 2814 6 2811 2502 2813 1665 1667 2814 6 2812 2502 1657 1659 1662 1665 6 2812 1667 2815 3140 4389 2811 6 2814 1667 1668 2816 2818 3140 6 2815 1668 2817 2818 2819 2820 6 2816 1668 1669 2820 2821 2822 6 2815 2816 2819 3140 3141 3142 6 2818 2816 2820 3142 3143 3144 6 2819 2816 2817 2821 3144 3145 6 2820 2817 2822 3145 3146 3147 6 2821 2817 1669 2823 2824 3147 6 2822 1669 2824 1673 1672 1670 6 2822 2823 1673 3147 3148 1674 6 2803 2804 2826 2945 2802 2946 6 2825 2804 2827 2946 2947 2828 6 2826 2804 2607 2608 2609 2828 6 2827 2609 2829 2947 2826 2948 5 2828 2609 2610 2830 2948 6 2829 2610 2611 2831 2948 2949 6 2830 2611 2612 2832 2949 2950 6 2831 2612 2613 2833 2950 2951 6 2832 2613 2614 2834 2951 2952 6 2833 2614 2615 2835 2952 2953 7 2834 2615 2616 2618 2836 2953 2954 5 2835 2618 2837 2954 2955 6 2836 2618 2619 2838 2955 2956 6 2837 2619 2839 2840 2956 2957 6 2838 2619 2840 2841 2621 2620 6 2838 2839 2841 2957 2958 2959 6 2840 2839 2621 2959 2960 2622 6 409 2546 2843 2844 9691 430 6 2842 2546 2844 2845 2548 2846 6 2842 2843 2845 3169 9689 9691 6 2844 2843 3169 3166 3163 2846 6 2843 2548 2847 2848 3163 2845 6 2846 2548 2848 2849 2549 2858 6 2846 2847 2849 2850 3163 3164 6 2848 2847 2850 2851 2852 2858 6 2848 2849 2851 2853 2859 3164 6 2850 2849 2852 2853 2854 2855 6 2851 2849 2855 2856 2857 2858 6 2850 2851 2854 2859 2860 2861 5 2853 2851 2855 2861 6677 7 2854 2851 2852 2856 6677 6678 6679 7 2855 2852 2857 6690 6687 6681 6679 6 2856 2852 2858 6692 6690 2551 6 2857 2852 2849 2551 2549 2847 6 2850 2853 2860 3181 3164 6662 7 2859 2853 2861 6662 6675 6667 6663 6 2860 2853 2854 6676 6675 6677 5 1632 1634 1629 1630 1631 6 1629 1634 1637 2864 1628 7216 7 2863 1637 1638 2865 7217 7216 7218 5 2864 1638 1639 2866 7218 7 2865 1639 1640 2867 7218 7219 7220 7 2866 1640 1641 2868 3190 3215 7220 6 2867 1641 1642 2491 2869 3190 6 2868 2491 2870 3190 3191 3182 6 2869 2491 2481 2495 2871 3182 6 2870 2495 2872 2874 2885 3182 6 2871 2495 2496 2497 2873 2874 6 2872 2497 2874 2875 2882 2883 6 2872 2873 2875 2876 2871 2885 6 2874 2873 2876 2877 2881 2882 6 2874 2875 2877 2878 2885 2886 6 2876 2875 2878 2879 2880 2881 6 2876 2877 2879 2886 2887 2888 6 2878 2877 2880 2888 2889 2890 6 2879 2877 2881 2893 2890 7601 6 2880 2877 2875 2882 4087 7601 6 2881 2875 2873 2883 4087 4088 6 2882 2873 2497 2498 2884 4088 6 2883 2498 2499 4088 4089 4093 6 2871 2874 2876 2886 3182 3183 6 2885 2876 2878 2887 3183 3184 6 2886 2878 2888 3184 3185 3186 6 2887 2878 2879 2889 3189 3186 6 2888 2879 2890 2891 3960 3189 6 2889 2879 2891 2892 2893 2880 6 2889 2890 2892 3962 3960 7593 6 2891 2890 2893 7593 7594 7595 6 2892 2890 2880 7601 7598 7595 6 1746 1747 2752 2895 3200 3199 6 2894 2752 2753 2754 2896 3199 6 2895 2754 2897 3199 3201 3202 6 2896 2754 2755 2898 3202 3203 6 2897 2755 2756 2899 3203 3204 6 2898 2756 2900 3204 3205 3206 6 2899 2756 2757 2901 3206 3207 6 2900 2757 2758 2902 3207 3208 6 2901 2758 2759 2903 3208 3209 6 2902 2759 2904 3209 3210 3211 6 2903 2759 2760 2905 3214 3211 6 2904 2760 2761 2762 2906 3214 6 2905 2762 2763 2907 3484 3214 6 2906 2763 2764 2765 2908 3484 6 2907 2765 2909 3483 3213 3484 7 2908 2765 2766 2910 3501 3483 3698 6 2909 2766 2767 2911 3698 3699 6 2910 2767 2768 2912 3699 3700 6 2911 2768 2769 2913 3700 3701 6 2912 2769 2770 2771 2914 3701 6 2913 2771 2915 3701 3702 3703 6 2914 2771 2772 2916 3703 3704 6 2915 2772 2773 2917 3704 3705 6 2916 2773 2774 2918 3705 3706 6 2917 2774 2775 2919 3706 3707 6 2918 2775 2776 2920 3707 3708 6 2919 2776 2777 2921 3708 3709 6 2920 2777 2778 2922 3709 3710 6 2921 2778 2779 2923 3710 3711 6 2922 2779 2780 2924 3711 3712 6 2923 2780 2781 2925 3712 3713 6 2924 2781 2782 2926 3713 3714 6 2925 2782 2783 2927 3714 3715 6 2926 2783 2784 2928 3715 3716 6 2927 2784 2785 2929 3716 3717 6 2928 2785 2786 2930 3717 3718 6 2929 2786 2787 2931 3718 3719 6 2930 2787 2788 2932 3719 3720 6 2931 2788 2789 2933 3720 3721 6 2932 2789 2790 2934 3721 3722 6 2933 2790 2791 2935 3722 3723 6 2934 2791 2792 2936 3723 3724 6 2935 2792 2793 2937 3724 3725 6 2936 2793 2794 2938 3725 3726 6 2937 2794 2795 2939 3726 3727 6 2938 2795 2796 2940 3727 3728 6 2939 2796 2797 2941 3728 3729 6 2940 2797 2798 2942 3729 3730 6 2941 2798 2799 2943 3730 3731 6 2942 2799 2800 2944 3731 3732 6 2943 2800 2801 2945 3732 3733 6 2944 2801 2802 2825 2946 3733 6 2945 2825 2826 2947 3733 3734 6 2946 2826 2828 2948 3734 3735 6 2947 2828 2829 2830 2949 3735 7 2948 2830 2831 2950 3735 3736 3737 6 2949 2831 2832 2951 3243 3737 6 2950 2832 2833 2952 3243 3244 6 2951 2833 2834 2953 3244 3245 6 2952 2834 2835 2954 3245 3246 5 2953 2835 2836 2955 3246 7 2954 2836 2837 2956 3246 3247 3248 6 2955 2837 2838 2957 3248 3249 6 2956 2838 2840 2958 3249 3250 6 2957 2840 2959 3250 3251 3252 6 2958 2840 2841 2960 3252 3253 6 2959 2841 2622 2623 2961 3253 6 2960 2623 2624 2962 3255 3253 6 2961 2624 2625 2963 3255 3256 6 2962 2625 2626 2964 2965 3256 6 2963 2626 2965 2966 2967 2627 6 2963 2964 2966 3256 3257 3258 6 2965 2964 2967 3258 3259 3260 6 2966 2964 2627 2628 2968 3260 6 2967 2628 2629 2969 3260 3261 6 2968 2629 2630 2970 3261 3262 6 2969 2630 2631 2971 3262 3263 6 2970 2631 2632 2972 3263 3264 6 2971 2632 2633 2973 3264 3265 6 2972 2633 2634 2974 3265 3266 6 2973 2634 2635 2975 3266 3267 6 2974 2635 2636 2976 3267 3268 6 2975 2636 2637 2638 2977 3268 6 2976 2638 2640 2978 3268 3269 6 2977 2640 2979 3269 3270 3271 6 2978 2640 2641 2980 3271 3272 6 2979 2641 2643 2981 3272 3273 6 2980 2643 2644 2982 3273 3274 6 2981 2644 2645 2983 3274 3275 6 2982 2645 2646 2984 3275 3276 6 2983 2646 2647 2985 3276 3277 6 2984 2647 2648 2986 3277 3278 6 2985 2648 2649 2987 3278 3825 6 2986 2649 2650 2988 3546 3825 6 2987 2650 2651 2989 3546 3547 6 2988 2651 2652 2990 3547 3548 6 2989 2652 2653 2991 3548 3549 6 2990 2653 2654 2992 3549 3550 6 2991 2654 2655 2993 3550 3551 6 2992 2655 2657 2994 3551 3552 6 2993 2657 2658 2995 3552 3553 6 2994 2658 2659 2996 3553 3554 6 2995 2659 2660 2997 3554 3555 6 2996 2660 2998 3555 3556 3557 6 2997 2660 2661 2999 3557 3558 6 2998 2661 2662 2663 3000 3558 6 2999 2663 2664 3001 3558 3559 6 3000 2664 2665 3002 3559 3560 6 3001 2665 2666 3003 3560 3561 6 3002 2666 2667 3561 3562 3566 6 2703 2704 3005 3291 3292 3293 6 3004 2704 2705 3006 3293 3294 6 3005 2705 2706 3007 3294 3295 6 3006 2706 2707 3008 3295 3296 6 3007 2707 2708 3009 3296 3297 6 3008 2708 2709 3010 3297 3298 6 3009 2709 2710 2711 3011 3298 6 3010 2711 3012 3298 3299 3300 6 3011 2711 2712 3013 3300 3301 6 3012 2712 2713 3014 3301 3302 6 3013 2713 2714 3015 3302 3303 6 3014 2714 2715 3016 3303 3304 6 3015 2715 2716 3017 3304 3305 6 3016 2716 2717 3018 3305 3306 6 3017 2717 2718 3019 3306 3307 6 3018 2718 2719 3020 3307 3308 6 3019 2719 2720 3021 3308 3309 6 3020 2720 2721 3022 3309 3310 6 3021 2721 2722 3023 3310 3311 6 3022 2722 2723 3024 3311 3312 6 3023 2723 2724 3025 3312 3313 6 3024 2724 2725 3026 3313 3314 6 3025 2725 2726 3027 3314 3315 6 3026 2726 2727 3028 3315 3316 6 3027 2727 2728 3029 3316 3317 6 3028 2728 2729 3030 3317 3318 6 3029 2729 2730 3031 3318 3319 6 3030 2730 2731 3032 3319 3320 6 3031 2731 2732 3033 3320 3321 6 3032 2732 2733 3034 3321 3322 6 3033 2733 2734 3035 3322 3323 6 3034 2734 2735 3036 3043 3323 6 3035 2735 2736 3037 3043 3044 6 3036 2736 2737 3038 3044 3045 6 3037 2737 2738 2739 3039 3045 6 3038 2739 3040 3045 3046 3047 6 3039 2739 2740 3041 3047 3048 6 3040 2740 2741 2742 3042 3048 6 3041 2742 2744 3048 3049 3050 6 3035 3036 3044 3323 3324 3325 6 3043 3036 3037 3045 3325 3326 6 3044 3037 3038 3039 3046 3326 6 3045 3039 3047 3326 3327 3328 6 3046 3039 3040 3048 3054 3328 6 3047 3040 3041 3042 3049 3054 6 3048 3042 3050 3054 3055 3056 6 3049 3042 2744 2745 3051 3056 6 3050 2745 2746 2747 3052 3056 6 3051 2747 2748 3053 3056 3057 6 3052 2748 2750 3057 3058 3059 6 3047 3048 3049 3055 3328 3329 6 3054 3049 3056 3329 3330 3057 6 3055 3049 3050 3051 3052 3057 7 3056 3052 3053 3058 3330 3055 3642 5 3057 3053 3059 3642 3643 7 3058 3053 2750 2751 3060 3643 3644 6 3059 2751 3061 3644 3645 3062 5 3060 2751 2446 2447 3062 6 3061 2447 3063 3645 3060 3911 6 3062 2447 2448 3064 3911 3912 6 3063 2448 3065 3070 3912 3913 6 3064 2448 2449 2450 3066 3070 6 3065 2450 2451 3067 3070 3071 6 3066 2451 2452 3068 3071 3072 6 3067 2452 2453 3069 3072 3073 6 3068 2453 2455 3073 3074 3075 6 3064 3065 3066 3071 3913 3914 6 3070 3066 3067 3072 3914 3915 6 3071 3067 3068 3073 3915 3916 6 3072 3068 3069 3074 3916 3917 6 3073 3069 3075 3917 3918 3919 6 3074 3069 2455 2456 3076 3919 6 3075 2456 2457 2458 3077 3919 6 3076 2458 2459 3078 3350 3919 6 3077 2459 2460 3079 3350 3351 6 3078 2460 2461 3080 3108 3351 6 3079 2461 2462 3081 3108 3109 6 3080 2462 3082 3092 3109 3110 6 3081 2462 2463 3083 3092 3093 6 3082 2463 2464 3084 3085 3093 6 3083 2464 3085 3086 2483 2465 6 3083 3084 3086 3093 3113 3360 6 3085 3084 2483 3927 3153 3360 6 17 18 3088 3089 3090 3091 6 3087 18 19 3096 3127 3091 6 17 3087 3090 3099 418 16 6 3089 3087 3091 3099 3104 3105 6 3090 3087 3105 3106 3088 3127 6 3081 3082 3093 3110 3111 3112 6 3092 3082 3083 3085 3112 3113 5 1616 1617 3095 4100 3545 6 3094 1617 1618 4368 4100 1625 6 3088 19 20 3097 3126 3127 6 3096 20 21 3126 3129 415 6 2242 1658 1656 1648 1183 1185 6 3089 3090 418 3100 3103 3104 6 418 3099 419 3101 3102 3103 6 419 3100 3102 3229 3230 3685 6 3101 3100 3103 3227 3229 3499 7 3102 3100 3099 3104 3114 3499 3498 6 3103 3099 3090 3105 3114 3115 6 3104 3090 3091 3106 3107 3115 6 3105 3091 3107 3127 3125 3119 6 3105 3106 3117 3115 3118 3119 6 3079 3080 3109 3351 3352 3353 6 3108 3080 3081 3110 3353 3354 6 3109 3081 3092 3111 3354 3355 6 3110 3092 3112 3355 3356 3357 6 3111 3092 3093 3113 3357 3358 6 3112 3093 3085 3358 3359 3360 5 3103 3104 3115 3116 3498 6 3114 3104 3116 3117 3107 3105 7 3114 3115 3117 3498 3505 3502 3496 6 3116 3115 3107 3118 6713 3505 6 3117 3107 3119 3120 6713 6712 6 3118 3107 3120 3121 3125 3106 6 3118 3119 3121 3122 6712 6714 6 3120 3119 3122 3123 3124 3125 6 3120 3121 3123 3885 3888 6714 6 3122 3121 3124 3128 3884 3885 6 3123 3121 3125 3126 3128 3129 6 3124 3121 3119 3126 3127 3106 6 3124 3125 3127 3129 3096 3097 6 3126 3125 3106 3096 3088 3091 6 3123 3124 3129 3883 3340 3884 6 3128 3124 3126 415 3883 3097 6 2202 2204 3131 3852 3853 9782 6 3130 2204 2206 1526 1527 9782 6 2095 2096 3133 3134 9777 3139 6 2095 3132 3134 3135 3136 2094 6 3133 3132 3135 3137 3138 3139 6 3133 3134 3136 3137 5947 5946 6 3133 3135 5946 5944 5948 2094 6 3135 3134 3138 6091 6092 5947 6 3137 3134 3139 6091 6090 6093 6 3138 3134 6093 6094 9777 3132 6 2814 2815 2818 3141 4389 4387 6 3140 2818 3142 4386 4385 4387 6 3141 2818 2819 3143 4391 4386 6 3142 2819 3144 7768 4391 7769 6 3143 2819 2820 3145 7775 7769 6 3144 2820 2821 3146 7775 7776 6 3145 2821 3147 4232 7776 9792 6 3146 2821 2822 2824 3148 4232 6 3147 2824 1674 1675 3413 4232 6 2487 2488 3150 3157 3158 3162 6 2487 3149 3151 3152 3156 3157 6 2487 3150 3152 3153 3927 2485 6 3151 3150 3153 3154 3155 3156 6 3151 3152 3154 3927 3086 3360 6 3153 3152 3155 3359 3360 3361 6 3154 3152 3156 3361 3362 3363 6 3155 3152 3150 3157 3678 3363 6 3156 3150 3149 3158 3159 3678 6 3157 3149 3159 3160 3161 3162 6 3157 3158 3160 3677 3678 3946 6 3159 3158 3161 3946 3947 3963 6 3160 3158 3162 3963 3964 3965 6 3161 3158 3149 3968 3965 2488 6 2846 2848 3164 3165 3166 2845 6 3163 2848 3165 3181 2859 2850 6 3163 3164 3166 3167 3178 3181 6 3163 3165 3167 3168 3169 2845 6 3166 3165 3168 3178 3175 3172 6 3166 3167 3169 3170 3171 3172 6 3166 3168 3170 2844 2845 9689 6 3169 3168 3171 9688 9687 9689 5 3170 3168 3172 3173 9688 6 3171 3168 3173 3174 3175 3167 6 3171 3172 3174 9692 9688 6654 7 3173 3172 3175 3176 6655 6653 6654 6 3174 3172 3176 3177 3178 3167 5 3174 3175 3177 3451 6655 6 3176 3175 3178 3179 3180 3451 6 3177 3175 3179 3167 3165 3181 6 3177 3178 3180 3181 6661 6662 6 3177 3179 3451 6658 6660 6661 6 3178 3165 3179 3164 2859 6662 6 2870 2871 2885 3183 3191 2869 6 3182 2885 2886 3184 3217 3191 6 3183 2886 2887 3185 3194 3217 6 3184 2887 3186 3187 3193 3194 6 3185 2887 3187 3188 3189 2888 6 3185 3186 3188 3193 3197 7585 6 3187 3186 3189 3959 7587 7585 6 3188 3186 2888 3959 3960 2889 6 2868 2869 3191 2867 3215 3216 6 3190 2869 3182 3216 3217 3183 6 1742 1743 1745 3198 3199 3200 6 3185 3187 3194 3195 3196 3197 6 3185 3193 3195 7223 3217 3184 7 3194 3193 3196 7223 7222 7205 7204 6 3195 3193 3197 7197 7198 7204 6 3196 3193 3187 7584 7197 7585 6 1741 1742 3192 3199 3412 3201 7 3198 3192 3200 2894 2895 2896 3201 5 3199 3192 1745 1746 2894 6 3199 2896 3202 3412 3198 9752 6 3201 2896 2897 3203 3471 9752 6 3202 2897 2898 3204 3471 3472 6 3203 2898 2899 3205 3472 3473 6 3204 2899 3206 3473 3474 3475 6 3205 2899 2900 3207 3475 3476 6 3206 2900 2901 3208 3476 3477 6 3207 2901 2902 3209 3477 3478 6 3208 2902 2903 3210 3478 3479 6 3209 2903 3211 3212 3479 3480 6 3210 2903 3212 3213 3214 2904 6 3210 3211 3213 3480 3481 3482 7 3212 3211 3214 3482 3483 2908 3484 6 3213 3211 2904 3484 2906 2905 6 2867 3190 3216 7221 7220 7222 6 3215 3190 3191 3217 7222 7223 6 3216 3191 3183 7223 3194 3184 6 636 637 3219 4041 3764 3763 6 3218 637 639 3220 3485 4041 6 3219 639 3221 3222 3223 3485 6 3220 639 640 3222 3241 3242 6 3220 3221 3223 3224 3225 3242 6 3220 3222 3224 3485 3486 3487 6 3223 3222 3225 3226 3487 3488 6 3224 3222 3226 3227 3228 3242 6 3224 3225 3227 3494 3488 3495 7 3226 3225 3228 3229 3102 3495 3499 6 3227 3225 3229 3230 3231 3242 5 3227 3228 3102 3101 3230 6 3101 3229 3228 3231 3232 3685 6 3230 3228 3232 3233 3242 3241 6 3230 3231 3233 3234 3235 3685 6 3232 3231 3234 3241 3240 3237 7 3232 3233 3235 12 11 3236 3237 5 3232 3234 12 3685 13 6 11 3234 3237 3238 3239 10 6 3236 3234 3238 644 3240 3233 6 3236 3237 3239 648 645 644 5 3236 3238 10 9 648 6 644 3237 641 640 3241 3233 6 640 3240 3221 3242 3231 3233 6 3221 3241 3222 3225 3228 3231 6 2950 2951 3244 3737 3738 3739 6 3243 2951 2952 3245 3739 3740 6 3244 2952 2953 3246 3740 3741 7 3245 2953 2954 2955 3247 3741 3742 5 3246 2955 3248 3742 3743 6 3247 2955 2956 3249 3743 3744 6 3248 2956 2957 3250 3744 3745 6 3249 2957 2958 3251 3745 3746 6 3250 2958 3252 3746 3747 3748 6 3251 2958 2959 3253 3254 3748 6 3252 2959 3254 3255 2961 2960 6 3252 3253 3255 3748 3749 3750 6 3254 3253 2961 2962 3256 3750 6 3255 2962 2963 2965 3257 3750 6 3256 2965 3258 3750 3751 3752 6 3257 2965 2966 3259 3752 3753 6 3258 2966 3260 3753 3754 3755 6 3259 2966 2967 2968 3261 3755 6 3260 2968 2969 3262 3755 3756 6 3261 2969 2970 3263 3756 3757 6 3262 2970 2971 3264 3757 3758 6 3263 2971 2972 3265 3758 3759 6 3264 2972 2973 3266 3759 3760 7 3265 2973 2974 3267 3760 4055 4052 5 3266 2974 2975 3268 4055 6 3267 2975 2976 2977 3269 4055 7 3268 2977 2978 3270 4055 4054 4056 5 3269 2978 3271 4056 4057 6 3270 2978 2979 3272 4057 4058 6 3271 2979 2980 3273 4058 4059 6 3272 2980 2981 3274 4059 4060 6 3273 2981 2982 3275 4060 4061 6 3274 2982 2983 3276 4061 4062 6 3275 2983 2984 3277 4065 4062 6 3276 2984 2985 3278 4065 4066 6 3277 2985 2986 3827 4066 3825 6 2690 2691 3280 3589 3590 3591 6 3279 2691 2692 3281 3591 3592 6 3280 2692 2693 3282 3592 3593 6 3281 2693 2694 3283 3593 3594 6 3282 2694 2695 3284 3594 3595 6 3283 2695 2696 3285 3595 3596 6 3284 2696 2697 3286 3596 3597 6 3285 2697 2698 3287 3597 3598 6 3286 2698 2699 3288 3598 3599 6 3287 2699 2700 3289 3599 3600 6 3288 2700 2701 3290 3600 3601 6 3289 2701 2702 3291 3601 3602 6 3290 2702 2703 3004 3292 3602 6 3291 3004 3293 3602 3603 3604 6 3292 3004 3005 3294 3604 3605 6 3293 3005 3006 3295 3605 3606 6 3294 3006 3007 3296 3606 3607 6 3295 3007 3008 3297 3607 3608 6 3296 3008 3009 3298 3608 3609 6 3297 3009 3010 3011 3299 3609 6 3298 3011 3300 3609 3610 3611 6 3299 3011 3012 3301 3611 3612 6 3300 3012 3013 3302 3612 3613 6 3301 3013 3014 3303 3613 3614 6 3302 3014 3015 3304 3614 3615 6 3303 3015 3016 3305 3615 3616 6 3304 3016 3017 3306 3616 3617 6 3305 3017 3018 3307 3617 3618 6 3306 3018 3019 3308 3618 3619 6 3307 3019 3020 3309 3619 3620 6 3308 3020 3021 3310 3620 3621 6 3309 3021 3022 3311 3621 3622 6 3310 3022 3023 3312 3622 3623 6 3311 3023 3024 3313 3623 3624 6 3312 3024 3025 3314 3624 3625 6 3313 3025 3026 3315 3625 3626 6 3314 3026 3027 3316 3626 3627 6 3315 3027 3028 3317 3627 3628 6 3316 3028 3029 3318 3628 3629 6 3317 3029 3030 3319 3629 3630 6 3318 3030 3031 3320 3630 3631 6 3319 3031 3032 3321 3631 3632 6 3320 3032 3033 3322 3632 3633 6 3321 3033 3034 3323 3633 3634 6 3322 3034 3035 3043 3324 3634 6 3323 3043 3325 3634 3635 3636 6 3324 3043 3044 3326 3636 3637 6 3325 3044 3045 3046 3327 3637 6 3326 3046 3328 3637 3638 3639 6 3327 3046 3047 3054 3329 3639 6 3328 3054 3055 3330 3639 3640 6 3329 3055 3057 3640 3641 3642 6 2508 2509 33 34 3332 3881 6 3331 34 35 2249 3333 3881 6 3332 2249 3334 3335 3881 3882 6 3333 2249 3335 3336 3337 2250 6 3333 3334 3336 9708 6500 3882 6 3335 3334 3337 9707 6493 9708 6 3336 3334 2250 2251 2252 9707 6 1172 1173 1525 3339 3340 3883 6 3338 1525 3340 3341 3342 4251 6 3338 3339 3341 3883 3128 3884 6 3340 3339 3342 3343 3886 3884 6 3341 3339 3343 3344 2207 4251 6 3341 3342 3344 3862 6718 3886 6 3343 3342 2207 2208 3345 3862 6 3344 2208 2210 3346 3347 3862 6 3345 2210 3347 3348 3349 2212 6 3345 3346 3348 3862 3863 3864 6 3347 3346 3349 6533 3864 6525 6 3348 3346 2212 2214 6524 6525 6 3077 3078 3351 3919 3918 3920 6 3350 3078 3079 3108 3352 3920 6 3351 3108 3353 3920 3921 3922 6 3352 3108 3109 3354 3922 3923 6 3353 3109 3110 3355 3923 3924 6 3354 3110 3111 3356 3924 3925 6 3355 3111 3357 3925 3926 3375 6 3356 3111 3112 3358 3369 3375 6 3357 3112 3113 3359 3368 3369 6 3358 3113 3360 3154 3361 3368 6 3359 3113 3154 3086 3153 3085 6 3359 3154 3155 3362 3364 3368 6 3361 3155 3363 3364 3365 3679 6 3362 3155 3156 3678 3676 3679 6 3361 3362 3365 3366 3367 3368 6 3364 3362 3366 3679 3668 3669 6 3364 3365 3367 3374 3371 3669 6 3364 3366 3368 3369 3370 3371 6 3364 3367 3369 3361 3359 3358 6 3368 3367 3370 3358 3357 3375 6 3369 3367 3371 3372 3375 3376 6 3370 3367 3372 3373 3374 3366 6 3370 3371 3373 3376 3377 3378 6 3372 3371 3374 3378 3379 3380 6 3373 3371 3366 3380 3381 3669 6 3357 3369 3370 3376 3926 3356 7 3375 3370 3372 3377 3944 3926 4343 5 3376 3372 3378 4343 4344 6 3377 3372 3373 3379 4344 4345 6 3378 3373 3380 3646 4348 4345 6 3379 3373 3374 3381 3382 3646 6 3380 3374 3382 3383 3669 3657 6 3380 3381 3383 3384 3385 3646 6 3382 3381 3384 3391 3388 3657 6 3382 3383 3385 3386 3387 3388 6 3382 3384 3386 3646 3647 3648 6 3385 3384 3387 3648 3649 3650 6 3386 3384 3388 3389 3650 3651 6 3387 3384 3389 3390 3391 3383 6 3387 3388 3390 3651 3652 3653 6 3389 3388 3391 3653 3654 3655 6 3390 3388 3383 3655 3656 3657 6 2676 2677 3393 3574 3575 3576 6 3392 2677 2678 3394 3576 3577 6 3393 2678 2679 3395 3577 3578 6 3394 2679 2680 3578 3579 3580 6 2174 2805 2806 3397 3398 4748 6 3396 2806 3398 3399 3400 3401 6 3396 3397 3399 3893 4748 4747 6 3398 3397 3400 3893 3894 3895 6 3399 3397 3401 3895 3896 3897 6 3400 3397 2806 2807 3402 3897 6 3401 2807 2808 3403 3897 3898 6 3402 2808 3404 3898 3899 3900 6 3403 2808 2809 3405 3900 3901 6 3404 2809 1733 3406 3680 3901 6 3405 1733 1734 1735 3407 3680 6 3406 1735 1736 3408 3680 3681 6 3407 1736 1737 3409 3681 3682 6 3408 1737 1738 3410 3684 3682 6 3409 1738 1739 3411 3471 3684 6 3410 1739 1740 3412 9752 3471 6 3411 1740 1741 3198 3201 9752 6 3148 1675 1676 1677 3414 4232 6 3413 1677 1678 3415 9792 4232 6 3414 1678 3416 7779 7777 9792 6 3415 1678 1679 7779 7780 5383 6 1696 1697 3418 3787 1695 3788 6 3417 1697 1698 3419 3788 3790 6 3418 1698 1699 2224 3420 3790 6 3419 2224 3421 3790 3791 3792 6 3420 2224 2225 3422 3792 3793 6 3421 2225 2226 3423 3424 3793 6 3422 2226 3424 3425 3426 3427 6 3422 3423 3425 3795 3793 3796 6 3424 3423 3426 3796 3797 3798 6 3425 3423 3427 3798 3799 3800 6 3426 3423 2226 2227 3428 3800 6 3427 2227 2228 3429 3800 3801 6 3428 2228 2229 3430 3801 3802 6 3429 2229 3431 3802 3803 3433 6 3430 2229 2230 2239 3432 3433 6 3431 2239 3433 3434 3435 3436 6 3431 3432 3434 3443 3803 3430 6 3433 3432 3435 3443 3444 3445 6 3434 3432 3436 3445 3446 3447 6 3435 3432 2239 2240 2562 3447 6 2492 2493 3438 3439 3516 2494 6 2492 3437 3439 3440 3441 3442 6 3438 3437 3440 3514 3515 3516 6 3438 3439 3441 3509 3510 3514 6 3438 3440 3442 3452 3454 3509 6 3438 3441 2492 71 3452 70 6 3433 3434 3444 3803 3804 3805 6 3443 3434 3445 3805 3806 3807 6 3444 3434 3435 3446 3807 3808 6 3445 3435 3447 3808 3809 3448 6 3446 3435 3436 2562 2563 3448 6 3447 2563 3449 3809 3446 4108 6 3448 2563 2564 3450 3455 4108 6 3449 2564 2568 3455 3456 2569 7 3176 3177 3180 6656 6655 6657 6658 6 3442 3441 70 69 3453 3454 6 69 3452 3454 68 3506 3507 6 3453 3452 3441 3507 3508 3509 6 3449 3450 3456 3457 4108 4109 6 3455 3450 3457 3458 3459 2569 6 3455 3456 3458 3465 4111 4109 6 3457 3456 3459 3460 3461 3465 6 3458 3456 3460 3464 2570 2569 6 3458 3459 3461 3462 3463 3464 6 3458 3460 3462 3465 3466 3467 6 3461 3460 3463 3467 3468 3470 6 3462 3460 3464 1722 3470 1721 6 3463 3460 3459 2570 1721 1720 6 3457 3458 3461 3466 4395 4111 6 3465 3461 3467 4405 4395 4746 6 3466 3461 3462 3468 3469 4746 6 3467 3462 3469 2173 1725 3470 6 3467 3468 2173 4746 4747 4748 6 1725 3468 1723 1722 3463 3462 7 3202 3203 3472 9752 3411 3410 3684 6 3471 3203 3204 3473 3682 3684 6 3472 3204 3205 3474 3683 3682 6 3473 3205 3475 3686 3903 3683 6 3474 3205 3206 3476 3686 3687 6 3475 3206 3207 3477 3687 3688 6 3476 3207 3208 3478 3688 3689 6 3477 3208 3209 3479 3689 3690 6 3478 3209 3210 3480 3690 3691 6 3479 3210 3212 3481 3691 3692 6 3480 3212 3482 3500 3695 3692 6 3481 3212 3213 3483 3500 3501 5 3482 3213 2908 3501 2909 5 2908 3213 3214 2906 2907 6 3219 3220 3223 3486 4040 4041 6 3485 3223 3487 3490 3969 4040 6 3486 3223 3224 3488 3489 3490 6 3487 3224 3489 3493 3494 3226 6 3487 3488 3490 3491 3492 3493 6 3487 3489 3491 3486 3969 3970 6 3490 3489 3492 3970 3971 3972 6 3491 3489 3493 3972 9748 6556 6 3492 3489 3488 3494 3497 9748 6 3493 3488 3226 3495 3496 3497 6 3494 3226 3227 3496 3498 3499 6 3494 3495 3497 3498 3502 3116 6 3494 3496 3493 3502 3503 9748 6 3496 3495 3499 3103 3114 3116 5 3498 3495 3227 3102 3103 6 3481 3482 3501 3695 3696 3697 6 3500 3482 3483 2909 3697 3698 6 3497 3496 3503 3504 3505 3116 6 3497 3502 3504 9748 6707 9749 6 3503 3502 3505 6713 6711 9749 5 3504 3502 3116 6713 3117 6 68 3453 3507 6698 6704 67 6 3506 3453 3454 3508 6698 6705 6 3507 3454 3509 3511 4523 6705 6 3508 3454 3441 3440 3510 3511 6 3509 3440 3511 3512 3513 3514 6 3509 3510 3512 3771 3508 4523 6 3511 3510 3513 3771 3772 3773 6 3512 3510 3514 3773 3774 3521 6 3513 3510 3440 3439 3515 3521 6 3514 3439 3516 3521 3522 3518 6 3515 3439 3437 2494 3517 3518 6 3516 2494 3518 3519 1608 1607 6 3516 3517 3519 3522 3515 3523 6 3518 3517 1608 1614 3523 3524 5 1614 1608 1606 1609 1611 6 3514 3515 3522 3774 3513 4532 6 3521 3515 3518 3523 4117 4532 6 3522 3518 3519 3524 3526 4117 6 3523 3519 1614 1615 3525 3526 6 3524 1615 3526 3527 3528 3529 6 3524 3525 3527 3523 4117 4118 6 3526 3525 3528 3530 4118 4119 6 3527 3525 3529 3530 3531 3544 6 3528 3525 1615 3544 3545 1616 6 3527 3528 3531 3532 4119 9787 6 3530 3528 3532 3533 3543 3544 6 3530 3531 3533 3534 9787 9788 6 3532 3531 3534 3535 3542 3543 6 3532 3533 3535 3536 9788 9789 6 3534 3533 3536 3537 3541 3542 6 3534 3535 3537 3538 9789 7179 6 3536 3535 3538 3539 3540 3541 6 3536 3537 3539 7183 7180 7179 6 3538 3537 3540 7183 7184 7185 6 3539 3537 3541 7185 7186 7213 6 3540 3537 3535 3542 7213 4373 6 3541 3535 3533 3543 4373 4098 6 3542 3533 3531 3544 4097 4098 6 3543 3531 3528 3529 3545 4097 6 3544 3529 1616 4100 4097 3094 6 2987 2988 3547 3825 3826 3830 6 3546 2988 2989 3548 3830 3831 6 3547 2989 2990 3549 3831 3832 6 3548 2990 2991 3550 3832 3833 6 3549 2991 2992 3551 3833 3834 6 3550 2992 2993 3552 3810 3834 6 3551 2993 2994 3553 3810 3811 6 3552 2994 2995 3554 3811 3812 6 3553 2995 2996 3555 3812 3813 6 3554 2996 2997 3556 3813 3814 6 3555 2997 3557 3814 3815 3816 6 3556 2997 2998 3558 3816 3817 6 3557 2998 2999 3000 3559 3817 6 3558 3000 3001 3560 3817 3818 6 3559 3001 3002 3561 3818 3819 6 3560 3002 3003 3562 3563 3819 6 3561 3003 3563 3564 3565 3566 6 3561 3562 3564 3819 3820 3821 6 3563 3562 3565 3821 3822 3823 6 3564 3562 3566 3823 3824 3567 6 3565 3562 3003 2667 2668 3567 6 3566 2668 2669 3568 3824 3565 6 3567 2669 2670 3569 3851 3824 6 3568 2670 2671 3570 3880 3851 6 3569 2671 2672 3571 3892 3880 6 3570 2672 2673 2674 3572 3892 6 3571 2674 3573 4238 3892 4258 6 3572 2674 2675 3574 4258 4259 6 3573 2675 2676 3392 3575 4259 6 3574 3392 3576 4259 4260 4264 6 3575 3392 3393 3577 4264 4265 6 3576 3393 3394 3578 4265 4266 6 3577 3394 3395 3579 4266 4267 6 3578 3395 3580 4267 4268 4269 6 3579 3395 2680 2681 3581 4269 6 3580 2681 2682 3582 4142 4269 6 3581 2682 2683 3583 4142 4143 6 3582 2683 2684 3584 4143 4144 6 3583 2684 2685 3585 4144 4145 6 3584 2685 2686 3586 4145 4146 6 3585 2686 2687 3587 4146 4147 6 3586 2687 2688 3588 4147 4148 6 3587 2688 2689 3589 4148 4149 6 3588 2689 2690 3279 3590 4149 6 3589 3279 3591 4149 4150 4151 6 3590 3279 3280 3592 4151 4152 6 3591 3280 3281 3593 4152 4153 6 3592 3281 3282 3594 4153 4154 6 3593 3282 3283 3595 4154 4155 6 3594 3283 3284 3596 4155 4156 6 3595 3284 3285 3597 4156 4157 6 3596 3285 3286 3598 4157 4158 6 3597 3286 3287 3599 4158 4159 6 3598 3287 3288 3600 4159 4160 6 3599 3288 3289 3601 4160 4161 6 3600 3289 3290 3602 4161 4162 6 3601 3290 3291 3292 3603 4162 6 3602 3292 3604 4162 4163 4164 6 3603 3292 3293 3605 4164 4165 6 3604 3293 3294 3606 4165 4166 6 3605 3294 3295 3607 4166 4167 6 3606 3295 3296 3608 4167 4168 6 3607 3296 3297 3609 4168 4169 6 3608 3297 3298 3299 3610 4169 6 3609 3299 3611 4169 4170 4171 6 3610 3299 3300 3612 4171 4172 6 3611 3300 3301 3613 4172 4173 6 3612 3301 3302 3614 4173 4174 6 3613 3302 3303 3615 4174 4175 6 3614 3303 3304 3616 4175 4176 6 3615 3304 3305 3617 4176 4177 6 3616 3305 3306 3618 4177 4178 6 3617 3306 3307 3619 4178 4179 6 3618 3307 3308 3620 4179 4180 6 3619 3308 3309 3621 4180 4181 6 3620 3309 3310 3622 4181 4182 6 3621 3310 3311 3623 4182 4183 6 3622 3311 3312 3624 4183 4184 6 3623 3312 3313 3625 4184 4185 6 3624 3313 3314 3626 4185 4186 6 3625 3314 3315 3627 4186 4187 6 3626 3315 3316 3628 4187 4188 6 3627 3316 3317 3629 4188 4189 6 3628 3317 3318 3630 4189 4190 6 3629 3318 3319 3631 4190 4191 6 3630 3319 3320 3632 4191 4192 6 3631 3320 3321 3633 4192 4193 6 3632 3321 3322 3634 4193 4194 6 3633 3322 3323 3324 3635 4194 6 3634 3324 3636 3904 4194 4195 6 3635 3324 3325 3637 3904 3905 6 3636 3325 3326 3327 3638 3905 6 3637 3327 3639 3905 3906 3907 6 3638 3327 3328 3329 3640 3907 6 3639 3329 3330 3641 3907 3908 6 3640 3330 3642 3908 3909 3643 5 3641 3330 3057 3058 3643 7 3642 3058 3059 3644 3909 3641 3928 6 3643 3059 3060 3645 3910 3928 5 3644 3060 3062 3910 3911 6 3382 3385 3647 3380 3379 4348 6 3646 3385 3648 4348 4349 4350 6 3647 3385 3386 3649 4353 4350 6 3648 3386 3650 3658 4353 4354 6 3649 3386 3387 3651 3658 3659 6 3650 3387 3389 3652 3659 3660 6 3651 3389 3653 3660 3661 3662 6 3652 3389 3390 3654 3662 3663 6 3653 3390 3655 3663 3664 3665 6 3654 3390 3391 3656 3665 3666 6 3655 3391 3657 3666 3667 3668 6 3656 3391 3383 3668 3669 3381 6 3649 3650 3659 4354 4355 4359 6 3658 3650 3651 3660 4372 4359 6 3659 3651 3652 3661 9794 4372 6 3660 3652 3662 4907 4909 9794 6 3661 3652 3653 3663 3670 4907 6 3662 3653 3654 3664 3670 3671 6 3663 3654 3665 3671 3672 3673 6 3664 3654 3655 3666 3673 3674 6 3665 3655 3656 3667 3674 3675 6 3666 3656 3668 3675 3676 3679 6 3667 3656 3657 3669 3365 3679 6 3668 3657 3381 3365 3366 3374 6 3662 3663 3671 4904 4906 4907 6 3670 3663 3664 3672 4903 4904 6 3671 3664 3673 5919 4903 3952 6 3672 3664 3665 3674 3951 3952 6 3673 3665 3666 3675 3945 3951 6 3674 3666 3667 3676 3677 3945 6 3675 3667 3677 3678 3363 3679 6 3675 3676 3678 3159 3945 3946 6 3677 3676 3159 3157 3156 3363 6 3363 3676 3362 3365 3668 3667 6 3405 3406 3407 3681 3901 3902 6 3680 3407 3408 3682 3683 3902 7 3681 3408 3683 3473 3472 3684 3409 6 3681 3682 3473 3902 3903 3474 5 3472 3682 3409 3410 3471 7 419 3101 3230 3232 3235 13 14 7 3474 3475 3687 3903 4666 4665 4689 5 3686 3475 3476 3688 4689 7 3687 3476 3477 3689 4689 4690 4691 6 3688 3477 3478 3690 4691 4692 6 3689 3478 3479 3691 4692 4693 6 3690 3479 3480 3692 3693 4693 6 3691 3480 3693 3694 3695 3481 6 3691 3692 3694 4693 4694 4695 6 3693 3692 3695 4695 4696 4697 6 3694 3692 3481 3500 3696 4697 6 3695 3500 3697 4697 4698 4699 6 3696 3500 3501 3698 4699 4700 6 3697 3501 2909 2910 3699 4700 6 3698 2910 2911 3700 3973 4700 6 3699 2911 2912 3701 3973 3974 6 3700 2912 2913 2914 3702 3974 6 3701 2914 3703 3974 3975 3976 6 3702 2914 2915 3704 3976 3977 6 3703 2915 2916 3705 3977 3978 6 3704 2916 2917 3706 3978 3979 6 3705 2917 2918 3707 3979 3980 6 3706 2918 2919 3708 3980 3981 6 3707 2919 2920 3709 3981 3982 6 3708 2920 2921 3710 3982 3983 6 3709 2921 2922 3711 3983 3984 6 3710 2922 2923 3712 3984 3985 6 3711 2923 2924 3713 3985 3986 6 3712 2924 2925 3714 3986 3987 6 3713 2925 2926 3715 3987 3988 6 3714 2926 2927 3716 3988 3989 6 3715 2927 2928 3717 3989 3990 6 3716 2928 2929 3718 3990 3991 6 3717 2929 2930 3719 3991 3992 6 3718 2930 2931 3720 3992 3993 6 3719 2931 2932 3721 3993 3994 6 3720 2932 2933 3722 3994 3995 6 3721 2933 2934 3723 3995 3996 6 3722 2934 2935 3724 3996 3997 6 3723 2935 2936 3725 3997 3998 6 3724 2936 2937 3726 3998 3999 6 3725 2937 2938 3727 3999 4000 6 3726 2938 2939 3728 4000 4001 6 3727 2939 2940 3729 4001 4002 6 3728 2940 2941 3730 4002 4003 6 3729 2941 2942 3731 4003 4004 6 3730 2942 2943 3732 4004 4005 6 3731 2943 2944 3733 4005 4006 6 3732 2944 2945 2946 3734 4006 6 3733 2946 2947 3735 4006 4007 6 3734 2947 2948 2949 3736 4007 6 3735 2949 3737 4007 4008 3738 5 3736 2949 2950 3243 3738 6 3737 3243 3739 4008 3736 4013 6 3738 3243 3244 3740 4013 4014 6 3739 3244 3245 3741 4014 4015 6 3740 3245 3246 3742 4015 4016 6 3741 3246 3247 3743 4016 4017 6 3742 3247 3248 3744 4017 4018 6 3743 3248 3249 3745 4018 4019 6 3744 3249 3250 3746 4019 4020 6 3745 3250 3251 3747 4020 4021 6 3746 3251 3748 4021 4022 4023 6 3747 3251 3252 3254 3749 4023 6 3748 3254 3750 4023 4024 4025 7 3749 3254 3255 3256 3257 3751 4025 5 3750 3257 3752 4025 4026 6 3751 3257 3258 3753 4026 4027 6 3752 3258 3259 3754 4030 4027 7 3753 3259 3755 4038 4030 4047 3756 5 3754 3259 3260 3261 3756 6 3755 3261 3262 3757 4047 3754 6 3756 3262 3263 3758 4047 4048 6 3757 3263 3264 3759 4048 4049 6 3758 3264 3265 3760 4049 4050 6 3759 3265 3266 4050 4051 4052 6 616 618 3762 3765 3766 3764 6 3761 618 626 628 3763 3764 6 3762 628 3764 3218 636 630 6 3762 3763 3766 3761 4041 3218 6 616 3761 3766 4039 6558 613 6 3765 3761 3764 4039 4040 4041 5 2086 1568 3768 3769 6094 6 3767 1568 3769 3770 1572 1569 6 3767 3768 3770 6093 6094 6095 7 3769 3768 1572 6095 6089 6318 6319 6 3511 3512 3772 4523 4524 4525 6 3771 3512 3773 4525 4526 4529 6 3772 3512 3513 3774 4529 4530 6 3773 3513 3521 4530 4531 4532 6 1683 1684 3776 5392 5386 5384 6 3775 1684 3777 5621 5392 3779 6 3776 1684 1685 1687 3778 3779 6 3777 1687 3779 3780 3781 3782 6 3777 3778 3780 7792 5621 3776 6 3779 3778 3781 7799 7793 7792 6 3780 3778 3782 7799 3784 3783 6 3781 3778 1687 1688 1689 3783 6 3782 1689 1690 1692 3784 3781 6 3783 1692 3785 7799 3781 7800 6 3784 1692 1693 3786 7800 7801 6 3785 1693 3787 3788 3789 7801 6 3786 1693 1694 1695 3417 3788 6 3787 3417 3418 3786 3789 3790 6 3786 3788 3790 7801 7802 3791 6 3789 3788 3418 3419 3420 3791 6 3790 3420 3792 7802 3789 7803 6 3791 3420 3421 3793 3794 7803 6 3792 3421 3794 3795 3424 3422 6 3792 3793 3795 7803 7804 7805 6 3794 3793 3424 3796 7805 7806 6 3795 3424 3425 3797 7810 7806 6 3796 3425 3798 3953 7810 7811 6 3797 3425 3426 3799 3953 3954 6 3798 3426 3800 3954 3955 3956 6 3799 3426 3427 3428 3801 3956 6 3800 3428 3429 3802 3956 3957 6 3801 3429 3430 3803 3957 3958 6 3802 3430 3433 3443 3804 3958 6 3803 3443 3805 3958 4101 4240 6 3804 3443 3444 3806 4101 4102 6 3805 3444 3807 4102 4103 4104 6 3806 3444 3445 3808 4104 4105 6 3807 3445 3446 3809 4105 4106 6 3808 3446 3448 4106 4107 4108 6 3551 3552 3811 3834 3835 3836 6 3810 3552 3553 3812 3836 3837 6 3811 3553 3554 3813 3837 3838 6 3812 3554 3555 3814 3838 3839 6 3813 3555 3556 3815 3839 3840 6 3814 3556 3816 3840 3841 3842 6 3815 3556 3557 3817 3842 3843 6 3816 3557 3558 3559 3818 3843 6 3817 3559 3560 3819 3843 3844 6 3818 3560 3561 3563 3820 3844 6 3819 3563 3821 3844 3845 3846 6 3820 3563 3564 3822 3846 3847 6 3821 3564 3823 3847 3848 3849 6 3822 3564 3565 3824 3849 3850 6 3823 3565 3567 3850 3851 3568 6 2987 3546 3826 3827 3278 2986 6 3825 3546 3827 3828 3829 3830 6 3825 3826 3828 4070 4066 3278 6 3827 3826 3829 4757 4070 4764 6 3828 3826 3830 4764 4765 4766 6 3829 3826 3546 3547 3831 4766 6 3830 3547 3548 3832 4766 4767 6 3831 3548 3549 3833 4767 4768 6 3832 3549 3550 3834 4771 4768 6 3833 3550 3551 3810 3835 4771 6 3834 3810 3836 5017 4771 5025 6 3835 3810 3811 3837 5025 5026 6 3836 3811 3812 3838 5026 5027 6 3837 3812 3813 3839 4406 5027 6 3838 3813 3814 3840 3865 4406 6 3839 3814 3815 3841 3865 3866 6 3840 3815 3842 3866 3867 3868 6 3841 3815 3816 3843 3854 3868 6 3842 3816 3817 3818 3844 3854 6 3843 3818 3819 3820 3845 3854 6 3844 3820 3846 3854 3855 3856 6 3845 3820 3821 3847 3856 3857 6 3846 3821 3822 3848 3857 3858 6 3847 3822 3849 3861 3858 3877 6 3848 3822 3823 3850 3877 3878 6 3849 3823 3824 3851 3878 3879 6 3850 3824 3568 3879 3880 3569 6 2182 2200 2180 3853 2202 3130 6 2180 3852 28 27 3130 9782 6 3842 3843 3844 3845 3855 3868 6 3854 3845 3856 3868 3869 3870 6 3855 3845 3846 3857 3870 3871 6 3856 3846 3847 3858 3859 3871 6 3857 3847 3859 3860 3861 3848 6 3857 3858 3860 3871 3872 3873 6 3859 3858 3861 3873 3874 3875 6 3860 3858 3848 3875 3876 3877 6 3344 3345 3347 3863 6718 3343 6 3862 3347 3864 6717 6716 6718 7 3863 3347 6533 6532 3348 6534 6717 6 3839 3840 3866 4406 4407 4408 6 3865 3840 3841 3867 4408 4409 6 3866 3841 3868 4409 4410 3869 6 3867 3841 3842 3854 3855 3869 6 3868 3855 3870 4410 3867 4421 6 3869 3855 3856 3871 4421 4422 6 3870 3856 3857 3859 3872 4422 6 3871 3859 3873 4422 4423 4424 6 3872 3859 3860 3874 4424 4425 6 3873 3860 3875 4425 4426 4427 6 3874 3860 3861 3876 4427 4428 6 3875 3861 3877 4428 4429 3889 6 3876 3861 3848 3849 3878 3889 6 3877 3849 3850 3879 3889 3890 6 3878 3850 3851 3880 3890 3891 6 3879 3851 3569 3891 3892 3570 6 2508 3331 2510 3882 3332 3333 6 2510 3881 3335 6500 2512 3333 6 3338 3340 3128 1172 415 3129 6 3128 3340 3123 3885 3886 3341 6 3123 3884 3886 3887 3888 3122 6 3885 3884 3887 3343 6718 3341 6 3885 3886 3888 6539 6716 6718 6 3885 3887 3122 6714 6715 6539 6 3877 3878 3890 4429 3876 4252 6 3889 3878 3879 3891 4237 4252 6 3890 3879 3880 3892 4237 4238 6 3891 3880 3570 4238 3572 3571 6 3398 3399 3894 4747 4745 4744 6 3893 3399 3895 4744 4749 4750 6 3894 3399 3400 3896 4753 4750 6 3895 3400 3897 4662 4759 4753 6 3896 3400 3401 3402 3898 4662 6 3897 3402 3403 3899 4662 4663 6 3898 3403 3900 4663 4664 4665 6 3899 3403 3404 3901 4665 4666 6 3900 3404 3405 3680 3902 4666 6 3901 3680 3681 3683 3903 4666 5 3902 3683 3474 4666 3686 6 3635 3636 3905 4195 4196 4197 6 3904 3636 3637 3638 3906 4197 6 3905 3638 3907 4197 4198 4199 6 3906 3638 3639 3640 3908 4199 6 3907 3640 3641 3909 4199 4200 6 3908 3641 3643 3928 4200 4201 5 3644 3645 3911 3928 3929 7 3910 3645 3062 3063 3912 3929 3930 7 3911 3063 3064 3913 3930 3931 3932 6 3912 3064 3070 3914 3932 3933 6 3913 3070 3071 3915 3933 3934 6 3914 3071 3072 3916 3934 3935 6 3915 3072 3073 3917 3935 3936 6 3916 3073 3074 3918 3936 3937 6 3917 3074 3919 3350 3920 3937 6 3918 3074 3075 3076 3077 3350 6 3918 3350 3351 3352 3921 3937 6 3920 3352 3922 3937 3938 3939 6 3921 3352 3353 3923 3939 3940 6 3922 3353 3354 3924 3940 3941 6 3923 3354 3355 3925 3941 3942 6 3924 3355 3356 3926 3942 3943 6 3925 3356 3375 3943 3944 3376 6 3086 2483 2484 2485 3151 3153 6 3909 3643 3644 3910 3929 4201 6 3928 3910 3911 3930 4201 4202 6 3929 3911 3912 3931 4202 4203 6 3930 3912 3932 4203 4204 4205 5 3931 3912 3913 3933 4205 6 3932 3913 3914 3934 4205 4206 6 3933 3914 3915 3935 4206 4207 6 3934 3915 3916 3936 4207 4208 6 3935 3916 3917 3937 4208 3938 6 3936 3917 3918 3920 3921 3938 6 3937 3921 3939 4208 3936 4336 6 3938 3921 3922 3940 4336 4337 6 3939 3922 3923 3941 4337 4338 6 3940 3923 3924 3942 4338 4339 6 3941 3924 3925 3943 4339 4340 6 3942 3925 3926 3944 4340 4341 6 3943 3926 3376 4341 4342 4343 6 3674 3675 3677 3946 3951 3948 6 3945 3677 3159 3160 3947 3948 6 3946 3160 3948 3949 5923 3963 6 3946 3947 3949 3950 3951 3945 6 3948 3947 3950 5921 5922 5923 6 3948 3949 3951 3952 5920 5921 6 3948 3950 3952 3673 3674 3945 6 3951 3950 3673 5919 3672 5920 6 3797 3798 3954 7811 7812 7813 6 3953 3798 3799 3955 7813 7814 6 3954 3799 3956 7814 7815 7816 6 3955 3799 3800 3801 3957 7816 6 3956 3801 3802 3958 4239 7816 6 3957 3802 3803 3804 4239 4240 6 3188 3189 3960 3961 7589 7587 6 3959 3189 3961 3962 2891 2889 6 3959 3960 3962 7589 7590 7591 6 3961 3960 2891 7591 7592 7593 6 3160 3161 3964 5923 3947 5924 6 3963 3161 3965 3966 5924 5925 6 3964 3161 3966 3967 3968 3162 6 3964 3965 3967 5925 5943 5944 6 3966 3965 3968 5944 5949 5948 6 3967 3965 3162 5949 2489 2488 6 3486 3490 3970 6557 4039 4040 6 3969 3490 3491 3971 1598 6557 6 3970 3491 3972 6359 1596 1598 6 3971 3491 3492 6556 6358 6359 6 3699 3700 3974 4700 4701 4702 6 3973 3700 3701 3702 3975 4702 6 3974 3702 3976 4702 4703 4704 6 3975 3702 3703 3977 4704 4705 6 3976 3703 3704 3978 4705 4706 6 3977 3704 3705 3979 4706 4707 6 3978 3705 3706 3980 4707 4708 6 3979 3706 3707 3981 4708 4709 6 3980 3707 3708 3982 4709 4710 6 3981 3708 3709 3983 4710 4711 6 3982 3709 3710 3984 4711 4712 6 3983 3710 3711 3985 4712 4713 6 3984 3711 3712 3986 4713 4714 6 3985 3712 3713 3987 4714 4715 6 3986 3713 3714 3988 4715 4716 6 3987 3714 3715 3989 4716 4717 6 3988 3715 3716 3990 4717 4718 6 3989 3716 3717 3991 4718 4719 6 3990 3717 3718 3992 4719 4720 6 3991 3718 3719 3993 4720 4721 6 3992 3719 3720 3994 4721 4722 6 3993 3720 3721 3995 4440 4722 6 3994 3721 3722 3996 4440 4441 6 3995 3722 3723 3997 4441 4442 6 3996 3723 3724 3998 4442 4443 6 3997 3724 3725 3999 4443 4444 6 3998 3725 3726 4000 4444 4445 6 3999 3726 3727 4001 4445 4446 6 4000 3727 3728 4002 4446 4447 6 4001 3728 3729 4003 4071 4447 6 4002 3729 3730 4004 4009 4071 6 4003 3730 3731 4005 4009 4010 6 4004 3731 3732 4006 4010 4011 6 4005 3732 3733 3734 4007 4011 6 4006 3734 3735 3736 4008 4011 6 4007 3736 3738 4011 4012 4013 6 4003 4004 4010 4071 4072 4073 6 4009 4004 4005 4011 4073 4012 6 4010 4005 4006 4007 4008 4012 6 4011 4008 4013 4073 4010 4074 6 4012 4008 3738 3739 4014 4074 6 4013 3739 3740 4015 4074 4075 7 4014 3740 3741 4016 4075 4076 4077 6 4015 3741 3742 4017 4077 4078 6 4016 3742 3743 4018 4078 4079 6 4017 3743 3744 4019 4079 4080 6 4018 3744 3745 4020 4080 4081 6 4019 3745 3746 4021 4081 4082 6 4020 3746 3747 4022 4082 4083 6 4021 3747 4023 4031 4083 4084 6 4022 3747 3748 3749 4024 4031 6 4023 3749 4025 4031 4032 4033 6 4024 3749 3750 3751 4026 4033 6 4025 3751 3752 4027 4028 4033 6 4026 3752 4028 4029 4030 3753 6 4026 4027 4029 4033 4034 4035 6 4028 4027 4030 4035 4036 4037 6 4029 4027 3753 4037 4038 3754 6 4022 4023 4024 4032 4084 4085 6 4031 4024 4033 4085 4086 4034 6 4032 4024 4025 4026 4028 4034 6 4033 4028 4035 4086 4032 4463 6 4034 4028 4029 4036 4042 4463 6 4035 4029 4037 4042 4043 4044 6 4036 4029 4030 4038 4044 4045 6 4037 4030 3754 4045 4046 4047 6 3765 3766 4040 6557 6558 3969 6 4039 3766 4041 3969 3486 3485 6 4040 3766 3764 3218 3485 3219 6 4035 4036 4043 4463 4464 4465 6 4042 4036 4044 4465 4466 4467 6 4043 4036 4037 4045 4467 4468 6 4044 4037 4038 4046 4468 4469 6 4045 4038 4047 4469 4470 4048 6 4046 4038 3754 3756 3757 4048 6 4047 3757 3758 4049 4470 4046 6 4048 3758 3759 4050 4470 4471 6 4049 3759 3760 4051 4471 4210 6 4050 3760 4052 4053 4209 4210 6 4051 3760 4053 4054 4055 3266 6 4051 4052 4054 4209 4222 4223 6 4053 4052 4055 3269 4056 4223 6 4054 4052 3266 3267 3268 3269 5 4054 3269 3270 4057 4223 7 4056 3270 3271 4058 4223 4224 4225 7 4057 3271 3272 4059 4225 4226 4227 6 4058 3272 3273 4060 4227 4228 6 4059 3273 3274 4061 4228 4229 6 4060 3274 3275 4062 4063 4229 6 4061 3275 4063 4064 4065 3276 6 4061 4062 4064 4231 4229 4503 6 4063 4062 4065 4067 4068 4503 6 4064 4062 3276 3277 4066 4067 6 4065 3277 4067 4070 3827 3278 6 4065 4066 4064 4068 4069 4070 6 4064 4067 4069 4514 4503 4755 6 4068 4067 4070 4755 4756 4757 6 4069 4067 4066 3827 4757 3828 6 4002 4003 4009 4072 4447 4448 6 4071 4009 4073 4448 4449 4450 6 4072 4009 4010 4012 4074 4450 6 4073 4012 4013 4014 4075 4450 6 4074 4014 4015 4076 4450 4451 6 4075 4015 4077 4451 4452 4453 5 4076 4015 4016 4078 4453 6 4077 4016 4017 4079 4453 4454 6 4078 4017 4018 4080 4454 4455 6 4079 4018 4019 4081 4455 4456 6 4080 4019 4020 4082 4456 4457 6 4081 4020 4021 4083 4457 4458 6 4082 4021 4022 4084 4458 4459 6 4083 4022 4031 4085 4459 4460 6 4084 4031 4032 4086 4460 4461 6 4085 4032 4034 4461 4462 4463 6 2881 2882 4088 4090 7600 7601 6 4087 2882 2883 2884 4089 4090 6 4088 2884 4090 4091 4092 4093 7 4088 4089 4091 7599 7600 4087 7752 6 4090 4089 4092 7752 7754 4380 6 4091 4089 4093 4095 4379 4380 6 4092 4089 2884 2499 4094 4095 6 4093 2499 4095 4096 2810 2500 6 4093 4094 4096 4092 4379 4388 6 4095 4094 2810 4388 4387 4389 6 3543 3544 4098 4099 4100 3545 6 3543 4097 4099 4366 4373 3542 6 4098 4097 4100 4366 4367 4368 6 4099 4097 3545 4368 3095 3094 6 3804 3805 4102 4240 4241 4242 6 4101 3805 3806 4103 4242 4243 6 4102 3806 4104 4243 4244 4245 6 4103 3806 3807 4105 4112 4245 6 4104 3807 3808 4106 4112 4113 6 4105 3808 3809 4107 4113 4114 6 4106 3809 4108 4109 4110 4114 6 4107 3809 3448 3449 3455 4109 6 4108 3455 4107 4110 4111 3457 6 4107 4109 4111 4114 4115 4116 6 4110 4109 3457 4116 4395 3465 6 4104 4105 4113 4245 4246 4247 6 4112 4105 4106 4114 4250 4247 6 4113 4106 4107 4110 4115 4250 6 4114 4110 4116 4250 4392 4393 6 4115 4110 4111 4393 4394 4395 7 3523 3526 4118 4531 4532 3522 4120 5 4117 3526 3527 4119 4120 6 4118 3527 4120 4121 3530 9787 7 4118 4119 4121 4122 9785 4531 4117 6 4120 4119 4122 4123 9787 9790 6 4120 4121 4123 4124 4396 9785 6 4122 4121 4124 4125 9790 7173 6 4122 4123 4125 4126 4127 4396 6 4124 4123 4126 7172 4141 7173 6 4124 4125 4127 4128 4129 4141 6 4124 4126 4128 4396 4397 4398 6 4127 4126 4129 4130 4131 4398 6 4128 4126 4130 4137 4140 4141 6 4128 4129 4131 4132 4136 4137 6 4128 4130 4132 4133 4398 4399 6 4131 4130 4133 4134 4135 4136 6 4131 4132 4134 4402 4399 4411 6 4133 4132 4135 4411 4412 4413 6 4134 4132 4136 4413 4414 7165 6 4135 4132 4130 4137 4138 7165 6 4136 4130 4129 4138 4139 4140 6 4136 4137 4139 7164 7162 7165 6 4138 4137 4140 7169 7164 7170 6 4139 4137 4129 4141 7170 7171 6 4140 4129 4126 7171 7172 4125 6 3581 3582 4143 4269 4270 4271 6 4142 3582 3583 4144 4271 4272 6 4143 3583 3584 4145 4272 4273 6 4144 3584 3585 4146 4273 4274 6 4145 3585 3586 4147 4274 4275 6 4146 3586 3587 4148 4275 4276 6 4147 3587 3588 4149 4276 4277 6 4148 3588 3589 3590 4150 4277 6 4149 3590 4151 4277 4278 4279 6 4150 3590 3591 4152 4279 4280 6 4151 3591 3592 4153 4280 4281 6 4152 3592 3593 4154 4281 4282 6 4153 3593 3594 4155 4282 4283 6 4154 3594 3595 4156 4283 4284 6 4155 3595 3596 4157 4284 4285 6 4156 3596 3597 4158 4285 4286 6 4157 3597 3598 4159 4286 4287 6 4158 3598 3599 4160 4287 4288 6 4159 3599 3600 4161 4288 4289 6 4160 3600 3601 4162 4289 4290 6 4161 3601 3602 3603 4163 4290 6 4162 3603 4164 4290 4291 4292 6 4163 3603 3604 4165 4292 4293 6 4164 3604 3605 4166 4293 4294 6 4165 3605 3606 4167 4294 4295 6 4166 3606 3607 4168 4295 4296 6 4167 3607 3608 4169 4296 4297 6 4168 3608 3609 3610 4170 4297 6 4169 3610 4171 4297 4298 4299 6 4170 3610 3611 4172 4299 4300 6 4171 3611 3612 4173 4300 4301 6 4172 3612 3613 4174 4301 4302 6 4173 3613 3614 4175 4302 4303 6 4174 3614 3615 4176 4303 4304 6 4175 3615 3616 4177 4304 4305 6 4176 3616 3617 4178 4305 4306 6 4177 3617 3618 4179 4306 4307 6 4178 3618 3619 4180 4307 4308 6 4179 3619 3620 4181 4308 4309 6 4180 3620 3621 4182 4309 4310 6 4181 3621 3622 4183 4310 4311 6 4182 3622 3623 4184 4311 4312 6 4183 3623 3624 4185 4312 4313 6 4184 3624 3625 4186 4313 4314 6 4185 3625 3626 4187 4314 4315 6 4186 3626 3627 4188 4315 4316 6 4187 3627 3628 4189 4316 4317 6 4188 3628 3629 4190 4317 4318 6 4189 3629 3630 4191 4318 4319 6 4190 3630 3631 4192 4319 4320 6 4191 3631 3632 4193 4320 4321 6 4192 3632 3633 4194 4321 4322 6 4193 3633 3634 3635 4195 4322 6 4194 3635 3904 4196 4322 4323 6 4195 3904 4197 4323 4324 4325 6 4196 3904 3905 3906 4198 4325 6 4197 3906 4199 4325 4326 4327 6 4198 3906 3907 3908 4200 4327 6 4199 3908 3909 4201 4327 4328 6 4200 3909 3928 3929 4202 4328 6 4201 3929 3930 4203 4328 4329 6 4202 3930 3931 4204 4329 4330 6 4203 3931 4205 4330 4331 4332 6 4204 3931 3932 3933 4206 4332 6 4205 3933 3934 4207 4332 4333 6 4206 3934 3935 4208 4333 4334 7 4207 3935 3936 3938 4334 4335 4336 6 4051 4053 4210 4211 4212 4222 6 4051 4209 4211 4471 4050 4478 6 4210 4209 4212 4213 4478 4479 6 4211 4209 4213 4214 4221 4222 6 4211 4212 4214 4215 4479 4480 6 4213 4212 4215 4216 4217 4221 6 4213 4214 4216 4480 4481 4482 6 4215 4214 4217 4218 4482 4483 6 4216 4214 4218 4219 4220 4221 6 4216 4217 4219 4233 4483 4484 6 4218 4217 4220 4233 4234 4235 6 4219 4217 4221 4225 4235 4224 6 4220 4217 4214 4212 4222 4224 6 4221 4212 4209 4053 4223 4224 6 4222 4053 4054 4056 4057 4224 6 4223 4057 4225 4222 4221 4220 6 4224 4057 4058 4226 4235 4220 6 4225 4058 4227 4236 4235 4489 5 4226 4058 4059 4228 4489 7 4227 4059 4060 4229 4230 4488 4489 6 4228 4060 4230 4231 4063 4061 6 4228 4229 4231 4490 4488 4501 6 4230 4229 4063 4501 4502 4503 6 3148 3413 3147 3146 9792 3414 6 4218 4219 4234 4484 4485 4486 6 4233 4219 4235 4236 4486 4487 6 4234 4219 4236 4226 4225 4220 6 4234 4235 4226 4487 4488 4489 6 3890 3891 4238 4252 4253 4257 6 4237 3891 3892 3572 4257 4258 6 3957 3958 4240 7816 7817 4504 6 4239 3958 3804 4101 4241 4504 6 4240 4101 4242 4504 4505 4506 6 4241 4101 4102 4243 4506 4507 6 4242 4102 4103 4244 4417 4507 6 4243 4103 4245 4417 4418 4419 6 4244 4103 4104 4112 4246 4419 6 4245 4112 4247 4248 4419 4420 6 4246 4112 4248 4249 4250 4113 6 4246 4247 4249 4420 7830 7831 6 4248 4247 4250 4392 4740 7831 6 4249 4247 4113 4114 4115 4392 6 3342 3339 1525 1526 2206 2207 6 3890 4237 4253 4254 4429 3889 6 4252 4237 4254 4255 4256 4257 6 4252 4253 4255 4648 4429 6893 6 4254 4253 4256 4730 4731 6893 6 4255 4253 4257 4730 4262 4261 6 4256 4253 4237 4238 4258 4261 6 4257 4238 3572 3573 4259 4261 6 4258 3573 3574 3575 4260 4261 6 4259 3575 4261 4262 4263 4264 6 4259 4260 4262 4257 4258 4256 6 4261 4260 4263 4733 4730 4256 6 4262 4260 4264 6902 4733 6903 6 4263 4260 3575 3576 4265 6903 6 4264 3576 3577 4266 5232 6903 6 4265 3577 3578 4267 5232 5233 6 4266 3578 3579 4268 5233 5234 6 4267 3579 4269 5234 5235 4270 6 4268 3579 3580 3581 4142 4270 6 4269 4142 4271 5235 4268 5452 6 4270 4142 4143 4272 5452 5453 6 4271 4143 4144 4273 5453 5454 6 4272 4144 4145 4274 5454 5455 6 4273 4145 4146 4275 5458 5455 6 4274 4146 4147 4276 5470 5458 6 4275 4147 4148 4277 5470 5471 6 4276 4148 4149 4150 4278 5471 6 4277 4150 4279 5471 5472 5473 6 4278 4150 4151 4280 5473 5474 6 4279 4151 4152 4281 5474 5475 6 4280 4152 4153 4282 5047 5475 6 4281 4153 4154 4283 5047 5048 6 4282 4154 4155 4284 5048 5049 6 4283 4155 4156 4285 5049 5050 6 4284 4156 4157 4286 5050 5051 6 4285 4157 4158 4287 5051 5052 6 4286 4158 4159 4288 5052 5053 6 4287 4159 4160 4289 4924 5053 6 4288 4160 4161 4290 4924 4925 6 4289 4161 4162 4163 4291 4925 6 4290 4163 4292 4925 4926 4927 6 4291 4163 4164 4293 4927 4928 6 4292 4164 4165 4294 4928 4929 6 4293 4165 4166 4295 4929 4930 6 4294 4166 4167 4296 4930 4931 6 4295 4167 4168 4297 4931 4932 6 4296 4168 4169 4170 4298 4932 6 4297 4170 4299 4772 4932 4933 6 4298 4170 4171 4300 4772 4773 6 4299 4171 4172 4301 4773 4774 6 4300 4172 4173 4302 4774 4775 6 4301 4173 4174 4303 4775 4776 6 4302 4174 4175 4304 4776 4777 6 4303 4175 4176 4305 4777 4778 6 4304 4176 4177 4306 4778 4779 6 4305 4177 4178 4307 4779 4780 6 4306 4178 4179 4308 4780 4781 6 4307 4179 4180 4309 4781 4782 6 4308 4180 4181 4310 4782 4783 6 4309 4181 4182 4311 4567 4783 6 4310 4182 4183 4312 4567 4568 6 4311 4183 4184 4313 4568 4569 6 4312 4184 4185 4314 4569 4570 6 4313 4185 4186 4315 4570 4571 6 4314 4186 4187 4316 4571 4572 6 4315 4187 4188 4317 4572 4573 6 4316 4188 4189 4318 4573 4574 6 4317 4189 4190 4319 4574 4575 6 4318 4190 4191 4320 4575 4576 6 4319 4191 4192 4321 4576 4577 6 4320 4192 4193 4322 4577 4578 6 4321 4193 4194 4195 4323 4578 6 4322 4195 4196 4324 4578 4579 6 4323 4196 4325 4579 4580 4581 6 4324 4196 4197 4198 4326 4581 6 4325 4198 4327 4581 4582 4583 6 4326 4198 4199 4200 4328 4583 6 4327 4200 4201 4202 4329 4583 6 4328 4202 4203 4330 4583 4584 6 4329 4203 4204 4331 4584 4585 6 4330 4204 4332 4585 4586 4590 7 4331 4204 4205 4206 4333 4590 4591 6 4332 4206 4207 4334 4591 4592 6 4333 4207 4208 4335 4592 4593 6 4334 4208 4336 4337 4430 4593 5 4335 4208 3938 3939 4337 6 4336 3939 3940 4338 4335 4430 6 4337 3940 3941 4339 4430 4431 6 4338 3941 3942 4340 4431 4432 6 4339 3942 3943 4341 4432 4433 6 4340 3943 3944 4342 4433 4434 6 4341 3944 4343 4434 4435 4436 6 4342 3944 3376 3377 4344 4436 6 4343 3377 3378 4345 4346 4436 6 4344 3378 4346 4347 4348 3379 6 4344 4345 4347 4436 4437 4438 6 4346 4345 4348 4438 4439 4349 6 4347 4345 3379 3646 3647 4349 6 4348 3647 4350 4351 4439 4347 6 4349 3647 4351 4352 4353 3648 6 4349 4350 4352 4602 4439 4603 6 4351 4350 4353 4603 4604 4605 6 4352 4350 3648 3649 4354 4605 6 4353 3649 3658 4355 4356 4605 6 4354 3658 4356 4357 4358 4359 6 4354 4355 4357 4605 4606 4607 6 4356 4355 4358 4362 4363 4607 6 4357 4355 4359 4360 4361 4362 6 4358 4355 4360 4372 3659 3658 6 4358 4359 4361 4369 4370 4372 6 4358 4360 4362 4365 4369 4615 6 4358 4361 4357 4363 4364 4365 6 4357 4362 4364 4607 4608 4609 6 4363 4362 4365 4612 4609 4613 6 4364 4362 4361 4613 4614 4615 6 4098 4099 4367 4373 4374 4375 6 4366 4099 4368 4375 4376 4377 7 4367 4099 4100 3095 4377 1627 1625 6 4361 4360 4370 4371 4615 4616 6 4369 4360 4371 4372 9795 9794 6 4369 4370 9795 4643 4638 4616 6 4370 4360 4359 3659 9794 3660 6 4098 4366 4374 7213 3541 3542 6 4373 4366 4375 7213 7211 7210 6 4374 4366 4367 4376 7210 7214 6 4375 4367 4377 4378 7214 7215 6 4376 4367 4368 4378 1628 1627 5 4376 4377 1628 7215 7216 6 4092 4095 4380 4381 4382 4388 7 4092 4379 4381 7754 4091 7753 7755 6 4380 4379 4382 4383 7755 7756 6 4381 4379 4383 4384 4385 4388 6 4381 4382 4384 7756 7757 7765 6 4383 4382 4385 4386 4390 7765 6 4384 4382 4386 3141 4387 4388 6 4384 4385 3141 4390 4391 3142 6 3141 4385 4388 4096 4389 3140 6 4387 4385 4382 4379 4095 4096 6 4387 4096 2810 2811 2814 3140 6 4384 4386 4391 7765 7766 7767 6 4390 4386 3142 7767 7768 3143 6 4250 4115 4393 4249 4740 4741 6 4392 4115 4116 4394 4403 4741 6 4393 4116 4395 4403 4404 4405 6 4394 4116 4111 3465 4405 3466 5 4122 4124 4127 4397 9785 7 4396 4127 4398 4400 4529 4530 9785 6 4397 4127 4128 4131 4399 4400 6 4398 4131 4400 4401 4402 4133 6 4398 4399 4401 4526 4529 4397 5 4400 4399 4402 4528 4526 7 4401 4399 4133 4411 4535 4528 4536 6 4393 4394 4404 4741 4742 4743 6 4403 4394 4405 4743 4744 4745 6 4404 4394 4395 3466 4745 4746 6 3838 3839 3865 4407 5027 5028 6 4406 3865 4408 5028 5029 5030 6 4407 3865 3866 4409 5030 5031 6 4408 3866 3867 4410 5031 5032 6 4409 3867 3869 4421 5032 5033 6 4402 4133 4134 4412 4536 4537 6 4411 4134 4413 4546 4540 4537 6 4412 4134 4135 4414 4415 4546 6 4413 4135 4415 4416 7165 7166 6 4413 4414 4416 4546 4545 4649 6 4415 4414 4650 4649 7166 7167 6 4243 4244 4418 4507 4508 4509 6 4417 4244 4419 4509 4510 4511 6 4418 4244 4245 4246 4420 4511 6 4419 4246 4248 7829 4511 7830 6 4410 3869 3870 4422 5033 5034 6 4421 3870 3871 3872 4423 5034 6 4422 3872 4424 5034 5035 5036 6 4423 3872 3873 4425 5036 5037 6 4424 3873 3874 4426 4644 5037 6 4425 3874 4427 4644 4645 4646 6 4426 3874 3875 4428 4646 4647 6 4427 3875 3876 4429 4647 4648 6 4428 3876 3889 4648 4254 4252 6 4335 4337 4338 4431 4593 4594 6 4430 4338 4339 4432 4594 4595 6 4431 4339 4340 4433 4595 4596 6 4432 4340 4341 4434 4596 4597 6 4433 4341 4342 4435 4597 4598 6 4434 4342 4436 4598 4599 4437 6 4435 4342 4343 4344 4346 4437 6 4436 4346 4438 4599 4435 4600 6 4437 4346 4347 4439 4600 4601 6 4438 4347 4349 4601 4602 4351 6 3994 3995 4441 4722 4723 4724 6 4440 3995 3996 4442 4724 4725 6 4441 3996 3997 4443 4725 4726 6 4442 3997 3998 4444 4726 4727 6 4443 3998 3999 4445 4727 4728 6 4444 3999 4000 4446 4728 4729 6 4445 4000 4001 4447 4729 4659 6 4446 4001 4002 4071 4448 4659 6 4447 4071 4072 4449 4659 4660 6 4448 4072 4450 4660 4661 4451 6 4449 4072 4073 4074 4075 4451 6 4450 4075 4076 4452 4661 4449 6 4451 4076 4453 4670 4739 4661 6 4452 4076 4077 4078 4454 4670 6 4453 4078 4079 4455 4670 4671 6 4454 4079 4080 4456 4671 4672 6 4455 4080 4081 4457 4672 4673 6 4456 4081 4082 4458 4673 4674 6 4457 4082 4083 4459 4674 4675 6 4458 4083 4084 4460 4675 4676 6 4459 4084 4085 4461 4676 4677 6 4460 4085 4086 4462 4677 4678 6 4461 4086 4463 4678 4679 4680 7 4462 4086 4034 4035 4042 4464 4680 5 4463 4042 4465 4680 4681 6 4464 4042 4043 4466 4472 4681 6 4465 4043 4467 4472 4473 4474 6 4466 4043 4044 4468 4474 4475 6 4467 4044 4045 4469 4475 4476 6 4468 4045 4046 4470 4476 4477 6 4469 4046 4048 4049 4471 4477 6 4470 4049 4050 4210 4477 4478 6 4465 4466 4473 4681 4682 4683 6 4472 4466 4474 4683 4684 4685 6 4473 4466 4467 4475 4685 4686 6 4474 4467 4468 4476 4686 4687 6 4475 4468 4469 4477 4687 4688 6 4476 4469 4470 4471 4478 4688 6 4477 4471 4210 4211 4479 4688 6 4478 4211 4213 4480 4688 5214 6 4479 4213 4215 4481 5214 5215 6 4480 4215 4482 5215 5216 5217 6 4481 4215 4216 4483 4491 5217 6 4482 4216 4218 4484 4491 4492 6 4483 4218 4233 4485 4492 4493 6 4484 4233 4486 4493 4494 4495 6 4485 4233 4234 4487 4495 4496 6 4486 4234 4236 4488 4490 4496 6 4487 4236 4489 4228 4490 4230 5 4488 4236 4228 4227 4226 6 4487 4488 4230 4496 4497 4501 6 4482 4483 4492 4982 4990 5217 6 4491 4483 4484 4493 4982 4983 6 4492 4484 4485 4494 4983 4984 6 4493 4485 4495 4984 4985 4986 6 4494 4485 4486 4496 4986 4498 6 4495 4486 4487 4490 4497 4498 6 4496 4490 4498 4499 4500 4501 6 4496 4497 4499 4986 4495 4987 6 4498 4497 4500 4987 4988 4989 5 4499 4497 4501 4989 4512 7 4500 4497 4490 4230 4231 4502 4512 6 4501 4231 4503 4512 4513 4514 6 4502 4231 4063 4514 4068 4064 6 4240 4241 4505 7817 4239 7818 6 4504 4241 4506 7818 7819 7820 6 4505 4241 4242 4507 7820 7821 6 4506 4242 4243 4417 4508 7821 6 4507 4417 4509 7821 7822 7823 6 4508 4417 4418 4510 7823 7824 6 4509 4418 4511 7824 7825 7826 6 4510 4418 4419 7826 7829 4420 7 4501 4502 4513 4989 4500 5003 5000 6 4512 4502 4514 4755 4760 5003 5 4513 4502 4503 4068 4755 6 427 412 4516 4517 5612 5613 6 4515 412 4517 4518 4522 411 6 4515 4516 4518 4519 5612 5616 6 4517 4516 4519 4520 4521 4522 6 4517 4518 4520 9735 7509 5616 6 4519 4518 4521 5236 9735 9679 6 4520 4518 4522 5236 5237 5238 6 4521 4518 4516 411 5238 422 7 3508 3511 3771 4524 6694 6696 6705 6 4523 3771 4525 6695 6694 4533 6 4524 3771 3772 4526 4527 4533 7 4525 3772 4527 4528 4401 4400 4529 6 4525 4526 4528 4533 4534 4535 5 4527 4526 4401 4535 4402 6 4400 4526 3772 3773 4530 4397 6 4529 3773 3774 4531 4397 9785 6 4530 3774 4532 4117 4120 9785 5 4531 3774 4117 3522 3521 6 4525 4527 4534 5157 4524 6695 6 4533 4527 4535 5157 5158 4667 6 4534 4527 4528 4402 4536 4667 6 4535 4402 4411 4537 4538 4667 6 4536 4411 4538 4539 4540 4412 6 4536 4537 4539 4667 4668 4669 6 4538 4537 4540 4541 4547 4669 6 4539 4537 4541 4542 4546 4412 6 4539 4540 4542 4543 4547 4548 6 4541 4540 4543 4544 4545 4546 6 4541 4542 4544 4551 4548 4552 6 4543 4542 4545 4552 4553 4554 6 4544 4542 4546 4415 4649 4554 6 4545 4542 4540 4412 4413 4415 6 4539 4541 4548 4549 9763 4669 6 4547 4541 4549 4550 4551 4543 6 4547 4548 4550 4558 4561 9763 6 4549 4548 4551 4558 4559 4560 6 4550 4548 4543 4552 6764 4560 6 4551 4543 4544 4553 7145 6764 6 4552 4544 4554 4555 7146 7145 6 4553 4544 4555 4556 4545 4649 6 4553 4554 4556 4557 7146 7147 6 4555 4554 4557 4649 4650 7154 6 4555 4556 7147 7149 7150 7154 6 4549 4550 4559 4561 4562 4563 6 4558 4550 4560 4566 4563 6765 6 4559 4550 6764 6763 6765 4551 7 4549 4558 4562 9763 9762 6676 9793 6 4561 4558 4563 4564 6675 6676 6 4562 4558 4564 4565 4566 4559 6 4562 4563 4565 6666 6667 6675 6 4564 4563 4566 6674 6666 6791 6 4565 4563 4559 6765 6766 6791 6 4310 4311 4568 4783 4784 4785 6 4567 4311 4312 4569 4785 4786 6 4568 4312 4313 4570 4786 4787 6 4569 4313 4314 4571 4787 4788 6 4570 4314 4315 4572 4788 4789 6 4571 4315 4316 4573 4789 4790 6 4572 4316 4317 4574 4790 4791 6 4573 4317 4318 4575 4791 4792 6 4574 4318 4319 4576 4792 4793 6 4575 4319 4320 4577 4793 4794 6 4576 4320 4321 4578 4794 4795 6 4577 4321 4322 4323 4579 4795 6 4578 4323 4324 4580 4795 4796 6 4579 4324 4581 4796 4797 4798 6 4580 4324 4325 4326 4582 4798 6 4581 4326 4583 4798 4799 4584 6 4582 4326 4327 4328 4329 4584 6 4583 4329 4330 4585 4799 4582 7 4584 4330 4331 4586 4587 4805 4799 6 4585 4331 4587 4588 4589 4590 5 4585 4586 4588 4805 4806 6 4587 4586 4589 4806 4807 4808 6 4588 4586 4590 4808 4809 4810 6 4589 4586 4331 4332 4591 4810 5 4590 4332 4333 4592 4810 6 4591 4333 4334 4593 4810 4811 6 4592 4334 4335 4430 4594 4811 6 4593 4430 4431 4595 4811 4812 6 4594 4431 4432 4596 4812 4813 6 4595 4432 4433 4597 4813 4814 6 4596 4433 4434 4598 4814 4815 6 4597 4434 4435 4599 4815 4816 6 4598 4435 4437 4600 4816 4817 6 4599 4437 4438 4601 4817 4818 6 4600 4438 4439 4602 4818 4819 6 4601 4439 4351 4603 4822 4819 6 4602 4351 4352 4604 4822 4823 6 4603 4352 4605 4826 4823 4827 7 4604 4352 4353 4354 4356 4606 4827 5 4605 4356 4607 4827 4828 6 4606 4356 4357 4363 4608 4828 5 4607 4363 4609 4610 4828 6 4608 4363 4610 4611 4612 4364 7 4608 4609 4611 4828 4829 4830 4831 6 4610 4609 4612 4831 4832 4833 6 4611 4609 4364 4613 4833 4835 6 4612 4364 4365 4614 4838 4835 6 4613 4365 4615 4617 4618 4838 6 4614 4365 4361 4369 4616 4617 7 4615 4369 4617 4638 4635 4620 4371 6 4615 4616 4614 4618 4619 4620 6 4614 4617 4619 4838 4623 4839 6 4618 4617 4620 4621 4622 4623 6 4619 4617 4621 4634 4635 4616 6 4619 4620 4622 4629 4630 4634 6 4619 4621 4623 4624 4625 4629 6 4619 4622 4624 4841 4839 4618 6 4623 4622 4625 4626 4841 4842 6 4624 4622 4626 4627 4628 4629 6 4624 4625 4627 4842 4861 4854 6 4626 4625 4628 4861 4862 4863 6 4627 4625 4629 4863 4864 4631 6 4628 4625 4622 4621 4630 4631 6 4629 4621 4631 4632 4633 4634 6 4629 4630 4632 4864 4628 4865 6 4631 4630 4633 4639 4869 4865 6 4632 4630 4634 4639 4640 4636 6 4633 4630 4621 4620 4635 4636 6 4634 4620 4636 4637 4638 4616 6 4634 4635 4637 4640 4633 4641 6 4636 4635 4638 4641 4642 4643 5 4637 4635 4616 4643 4371 6 4632 4633 4640 4869 4913 9761 6 4639 4633 4636 4641 4913 4914 6 4640 4636 4637 4642 4917 4914 6 4641 4637 4643 4911 4917 4910 7 4642 4637 4638 4909 4910 9795 4371 6 4425 4426 4645 5037 5038 5045 6 4644 4426 4646 5046 5045 6890 6 4645 4426 4427 4647 6891 6890 6 4646 4427 4428 4648 6891 6892 6 4647 4428 4429 4254 6892 6893 6 4545 4415 4554 4556 4650 4416 6 4556 4649 4416 7167 7155 7154 6 423 53 54 4652 4653 9685 6 4651 54 4653 4654 4658 55 6 4651 4652 4654 4655 9684 9685 6 4653 4652 4655 4656 4657 4658 6 4653 4654 4656 9683 9681 9684 6 4655 4654 4657 9683 9686 9687 7 4656 4654 4658 5381 9689 9687 9690 6 4657 4654 4652 55 5381 56 6 4447 4448 4660 4729 4446 4737 6 4659 4448 4449 4661 4737 4738 6 4660 4449 4451 4738 4739 4452 6 3896 3897 3898 4663 7842 4759 6 4662 3898 3899 4664 7842 7843 6 4663 3899 4665 7843 4690 4689 6 4664 3899 3900 4666 3686 4689 6 4665 3900 3901 3902 3903 3686 6 4535 4536 4538 4668 5158 4534 6 4667 4538 4669 9751 5158 9762 6 4668 4538 4539 9762 9763 4547 7 4452 4453 4454 4671 4981 4739 5195 6 4670 4454 4455 4672 5195 5196 6 4671 4455 4456 4673 5196 5197 6 4672 4456 4457 4674 5197 5198 6 4673 4457 4458 4675 5198 5199 6 4674 4458 4459 4676 5199 5200 6 4675 4459 4460 4677 5200 5201 6 4676 4460 4461 4678 5201 5202 6 4677 4461 4462 4679 5202 5203 6 4678 4462 4680 5203 5204 5205 6 4679 4462 4463 4464 4681 5205 7 4680 4464 4465 4472 4682 5205 5206 5 4681 4472 4683 5206 5207 7 4682 4472 4473 4684 5207 5208 5209 5 4683 4473 4685 5209 5210 7 4684 4473 4474 4686 5210 5211 5212 6 4685 4474 4475 4687 5212 5213 6 4686 4475 4476 4688 5213 5214 6 4687 4476 4477 4478 4479 5214 6 4665 3686 3687 3688 4690 4664 6 4689 3688 4691 7843 4664 7844 6 4690 3688 3689 4692 7844 7845 6 4691 3689 3690 4693 5159 7845 6 4692 3690 3691 3693 4694 5159 6 4693 3693 4695 5159 5160 5161 6 4694 3693 3694 4696 5161 5162 6 4695 3694 4697 5162 5163 5164 6 4696 3694 3695 3696 4698 5164 6 4697 3696 4699 5164 5165 5166 6 4698 3696 3697 4700 5166 4701 6 4699 3697 3698 3699 3973 4701 6 4700 3973 4702 5166 4699 7855 6 4701 3973 3974 3975 4703 7855 6 4702 3975 4704 7309 7855 7856 6 4703 3975 3976 4705 7309 7310 6 4704 3976 3977 4706 7310 7311 6 4705 3977 3978 4707 7311 7312 6 4706 3978 3979 4708 7312 7313 6 4707 3979 3980 4709 5171 7313 6 4708 3980 3981 4710 5171 5172 6 4709 3981 3982 4711 5172 5173 6 4710 3982 3983 4712 5173 5174 6 4711 3983 3984 4713 5174 5175 6 4712 3984 3985 4714 5175 5176 6 4713 3985 3986 4715 5176 5177 6 4714 3986 3987 4716 5177 5178 6 4715 3987 3988 4717 4966 5178 6 4716 3988 3989 4718 4966 4967 6 4717 3989 3990 4719 4967 4968 6 4718 3990 3991 4720 4968 4969 6 4719 3991 3992 4721 4969 4970 6 4720 3992 3993 4722 4970 4971 6 4721 3993 3994 4440 4723 4971 6 4722 4440 4724 4971 4972 4973 6 4723 4440 4441 4725 4973 4974 6 4724 4441 4442 4726 4974 4975 6 4725 4442 4443 4727 4734 4975 6 4726 4443 4444 4728 4734 4735 6 4727 4444 4445 4729 4735 4736 6 4728 4445 4446 4659 4736 4737 6 4255 4256 4731 4732 4733 4262 6 4255 4730 4732 6893 6894 6895 6 4731 4730 4733 6895 6896 6897 6 4732 4730 4262 6897 6902 4263 6 4726 4727 4735 4975 4976 4977 6 4734 4727 4728 4736 4977 4978 6 4735 4728 4729 4737 4978 4979 6 4736 4729 4659 4660 4738 4979 6 4737 4660 4661 4739 4979 4980 6 4738 4661 4452 4980 4981 4670 6 4249 4392 4741 5004 7831 7832 6 4740 4392 4393 4403 4742 5004 6 4741 4403 4743 4754 5004 5005 6 4742 4403 4404 4744 4754 4749 6 4743 4404 4745 3893 3894 4749 6 4744 4404 4405 4746 4747 3893 6 4745 4405 3466 3467 3469 4747 6 4746 3469 4748 3398 3893 4745 6 4747 3469 2173 2174 3396 3398 6 4744 3894 4750 4751 4754 4743 6 4749 3894 4751 4752 4753 3895 6 4749 4750 4752 5006 4754 7838 6 4751 4750 4753 4758 7838 7839 6 4752 4750 3895 4758 4759 3896 6 4742 4743 4749 5005 5006 4751 7 4514 4068 4069 4756 4513 4760 4761 5 4755 4069 4757 4761 4762 7 4756 4069 4070 3828 4762 4763 4764 6 4752 4753 4759 7839 7840 7841 6 4758 4753 3896 7841 7842 4662 6 4513 4755 4761 5007 5003 5002 5 4760 4755 4756 4762 5007 7 4761 4756 4757 4763 5007 5008 5009 6 4762 4757 4764 5009 5010 5011 6 4763 4757 3828 3829 4765 5011 6 4764 3829 4766 5011 5012 5013 6 4765 3829 3830 3831 4767 5013 6 4766 3831 3832 4768 4769 5013 6 4767 3832 4769 4770 4771 3833 7 4767 4768 4770 5013 5012 5014 5015 6 4769 4768 4771 5015 5016 5017 6 4770 4768 3833 5017 3835 3834 6 4298 4299 4773 4933 4934 4935 6 4772 4299 4300 4774 4935 4936 6 4773 4300 4301 4775 4936 4937 6 4774 4301 4302 4776 4937 4938 6 4775 4302 4303 4777 4938 4939 6 4776 4303 4304 4778 4939 4940 6 4777 4304 4305 4779 4940 4941 6 4778 4305 4306 4780 4941 4942 6 4779 4306 4307 4781 4942 4943 6 4780 4307 4308 4782 4943 4944 6 4781 4308 4309 4783 4944 4945 6 4782 4309 4310 4567 4784 4945 6 4783 4567 4785 4945 4946 4947 6 4784 4567 4568 4786 4947 4948 6 4785 4568 4569 4787 4948 4949 6 4786 4569 4570 4788 4949 4950 6 4787 4570 4571 4789 4950 4951 6 4788 4571 4572 4790 4951 4952 6 4789 4572 4573 4791 4952 4953 6 4790 4573 4574 4792 4953 4954 6 4791 4574 4575 4793 4954 4955 6 4792 4575 4576 4794 4800 4955 6 4793 4576 4577 4795 4800 4801 6 4794 4577 4578 4579 4796 4801 6 4795 4579 4580 4797 4801 4802 6 4796 4580 4798 4802 4803 4804 6 4797 4580 4581 4582 4799 4804 6 4798 4582 4584 4804 4805 4585 6 4793 4794 4801 4955 4956 4957 6 4800 4794 4795 4796 4802 4957 6 4801 4796 4797 4803 4957 4958 6 4802 4797 4804 4958 4959 4960 6 4803 4797 4798 4799 4805 4960 6 4804 4799 4585 4587 4806 4960 6 4805 4587 4588 4807 4919 4960 6 4806 4588 4808 4919 4920 4921 6 4807 4588 4589 4809 4921 4922 6 4808 4589 4810 4922 4923 4811 6 4809 4589 4590 4591 4592 4811 7 4810 4592 4593 4594 4812 4923 4809 5 4811 4594 4595 4813 4923 6 4812 4595 4596 4814 4965 4923 6 4813 4596 4597 4815 5094 4965 6 4814 4597 4598 4816 5094 5095 6 4815 4598 4599 4817 5095 5096 6 4816 4599 4600 4818 5096 5097 6 4817 4600 4601 4819 4820 5097 6 4818 4601 4820 4821 4822 4602 6 4818 4819 4821 5097 5098 5099 6 4820 4819 4822 5099 5100 4824 6 4821 4819 4602 4603 4823 4824 6 4822 4603 4824 4825 4826 4604 6 4822 4823 4825 5100 4821 5101 6 4824 4823 4826 5101 5102 5103 6 4825 4823 4604 4827 5103 5104 6 4826 4604 4605 4606 4828 5104 7 4827 4606 4607 4608 4610 4829 5104 6 4828 4610 4830 5104 5103 5105 6 4829 4610 4831 5105 5106 5107 6 4830 4610 4611 4832 5107 5108 6 4831 4611 4833 4834 5114 5108 5 4832 4611 4612 4834 4835 6 4832 4833 4835 4836 5114 5115 7 4834 4833 4612 4836 4837 4838 4613 6 4834 4835 4837 5115 4846 4845 6 4836 4835 4838 4839 4840 4845 6 4837 4835 4613 4614 4618 4839 6 4837 4838 4840 4841 4623 4618 6 4837 4839 4841 4843 4844 4845 6 4840 4839 4623 4624 4842 4843 6 4841 4624 4843 4626 4853 4854 6 4841 4842 4840 4844 4853 4851 6 4840 4843 4845 4846 4847 4851 5 4840 4844 4846 4836 4837 7 4845 4844 4847 4848 5115 4836 5116 6 4846 4844 4848 4849 4850 4851 6 4846 4847 4849 5118 5116 5119 6 4848 4847 4850 5119 5120 5121 6 4849 4847 4851 4852 5121 5122 6 4850 4847 4852 4853 4843 4844 6 4850 4851 4853 4855 4856 5122 6 4852 4851 4843 4842 4854 4855 6 4853 4842 4855 4858 4861 4626 6 4852 4853 4854 4856 4857 4858 6 4852 4855 4857 5122 5123 5124 6 4856 4855 4858 4859 5124 5125 6 4857 4855 4854 4859 4860 4861 6 4857 4858 4860 5125 5126 5130 6 4859 4858 4861 5130 5131 4862 6 4860 4858 4854 4626 4627 4862 6 4861 4627 4863 5131 4860 5132 6 4862 4627 4628 4864 4866 5132 6 4863 4628 4631 4865 4866 4867 6 4864 4631 4867 4868 4869 4632 6 4863 4864 4867 5132 5133 5137 6 4866 4864 4865 4868 5137 5138 6 4867 4865 4869 4870 4871 5138 6 4868 4865 4632 4639 4870 9761 6 4868 4869 4871 4872 4873 9761 6 4868 4870 4872 5138 5139 5140 6 4871 4870 4873 4874 5151 5140 6 4872 4870 4874 4875 4876 9761 6 4872 4873 4875 5150 5148 5151 6 4874 4873 4876 4877 4878 5150 6 4875 4873 4877 9761 4913 4915 6 4875 4876 4878 4879 4880 4915 6 4875 4877 4879 5156 5150 4883 6 4878 4877 4880 4881 4882 4883 6 4879 4877 4881 4915 4916 9754 7 4879 4880 4882 9754 9755 9757 9758 6 4879 4881 4883 4884 4885 9758 6 4879 4882 4884 5156 4878 5370 6 4883 4882 4885 4886 5370 5371 6 4884 4882 4886 4887 9758 4896 6 4884 4885 4887 4888 4889 5371 6 4886 4885 4888 4895 4892 4896 6 4886 4887 4889 4890 4891 4892 6 4886 4888 4890 5373 5371 5900 6 4889 4888 4891 5899 5897 5900 6 4890 4888 4892 4893 5899 5902 6 4891 4888 4893 4894 4895 4887 6 4891 4892 4894 5902 5903 5904 6 4893 4892 4895 5913 5904 5914 6 4894 4892 4887 4896 4897 5914 7 4895 4887 4897 4898 9758 9757 4885 6 4895 4896 4898 4899 4900 5914 5 4897 4896 4899 9757 9760 6 4897 4898 4900 4901 4902 9760 6 4897 4899 4901 5914 5915 5918 6 4900 4899 4902 4903 5918 5919 6 4901 4899 4903 4904 4905 9760 6 4901 4902 4904 5919 3672 3671 6 4903 4902 4905 4906 3670 3671 6 4904 4902 4906 9755 4912 9760 6 4904 4905 3670 4907 4908 4912 6 3670 4906 4908 4909 3662 3661 6 4907 4906 4909 4910 4911 4912 7 4907 4908 4910 4643 3661 9794 9795 5 4909 4908 4911 4643 4642 6 4910 4908 4912 4918 4917 4642 6 4911 4908 4906 9755 4918 4905 6 4639 4640 4914 4915 9761 4876 6 4913 4640 4915 4916 4917 4641 6 4913 4914 4916 4876 4877 4880 6 4915 4914 4917 4918 9754 4880 6 4916 4914 4918 4911 4642 4641 6 4916 4917 4911 9754 9755 4912 6 4806 4807 4920 4960 4959 4961 6 4919 4807 4921 4961 4962 4963 6 4920 4807 4808 4922 4963 4964 6 4921 4808 4809 4923 4964 4965 6 4922 4809 4811 4965 4813 4812 6 4288 4289 4925 5053 5054 5055 6 4924 4289 4290 4291 4926 5055 6 4925 4291 4927 5055 5056 5057 6 4926 4291 4292 4928 5057 5058 6 4927 4292 4293 4929 5058 5059 6 4928 4293 4294 4930 5059 5060 6 4929 4294 4295 4931 5060 5061 6 4930 4295 4296 4932 5061 5062 6 4931 4296 4297 4298 4933 5062 6 4932 4298 4772 4934 5062 5063 6 4933 4772 4935 5063 5064 5065 6 4934 4772 4773 4936 5065 5066 6 4935 4773 4774 4937 5066 5067 6 4936 4774 4775 4938 5067 5068 6 4937 4775 4776 4939 5068 5069 6 4938 4776 4777 4940 5069 5070 6 4939 4777 4778 4941 5070 5071 6 4940 4778 4779 4942 5071 5072 6 4941 4779 4780 4943 5072 5073 6 4942 4780 4781 4944 5073 5074 6 4943 4781 4782 4945 5074 5075 6 4944 4782 4783 4784 4946 5075 6 4945 4784 4947 5075 5076 5077 6 4946 4784 4785 4948 5077 5078 6 4947 4785 4786 4949 5078 5079 6 4948 4786 4787 4950 5079 5080 6 4949 4787 4788 4951 5080 5081 6 4950 4788 4789 4952 5081 5082 6 4951 4789 4790 4953 5082 5083 6 4952 4790 4791 4954 5083 5084 6 4953 4791 4792 4955 5084 5085 6 4954 4792 4793 4800 4956 5085 6 4955 4800 4957 5085 5086 5087 6 4956 4800 4801 4802 4958 5087 6 4957 4802 4803 4959 5089 5087 6 4958 4803 4960 4919 4961 5089 6 4959 4803 4804 4805 4806 4919 6 4959 4919 4920 4962 5089 5090 6 4961 4920 4963 5090 5091 5092 6 4962 4920 4921 4964 5092 5093 6 4963 4921 4922 4965 5093 5094 6 4964 4922 4923 4813 5094 4814 6 4716 4717 4967 5178 5179 5180 6 4966 4717 4718 4968 5180 5181 6 4967 4718 4719 4969 5181 5182 6 4968 4719 4720 4970 5182 5183 6 4969 4720 4721 4971 5183 5184 6 4970 4721 4722 4723 4972 5184 6 4971 4723 4973 5184 5185 5186 6 4972 4723 4724 4974 5186 5187 6 4973 4724 4725 4975 5187 5188 6 4974 4725 4726 4734 4976 5188 6 4975 4734 4977 5188 5189 5190 6 4976 4734 4735 4978 5190 5191 6 4977 4735 4736 4979 5191 5192 6 4978 4736 4737 4738 4980 5192 6 4979 4738 4739 4981 5192 5193 6 4980 4739 4670 5193 5194 5195 6 4491 4492 4983 4990 4991 4992 6 4982 4492 4493 4984 4992 4993 6 4983 4493 4494 4985 4993 4994 6 4984 4494 4986 4994 4995 4996 6 4985 4494 4495 4498 4987 4996 6 4986 4498 4499 4988 4996 4997 6 4987 4499 4989 4997 4998 4999 6 4988 4499 4500 4512 4999 5000 6 4491 4982 4991 5217 5218 5219 6 4990 4982 4992 5219 5220 5221 6 4991 4982 4983 4993 5221 5222 6 4992 4983 4984 4994 5222 5223 6 4993 4984 4985 4995 5223 5224 6 4994 4985 4996 5224 5225 5226 6 4995 4985 4986 4987 4997 5226 6 4996 4987 4988 4998 5226 5227 6 4997 4988 4999 5227 5228 5229 6 4998 4988 4989 5000 5001 5229 6 4999 4989 5001 5002 5003 4512 6 4999 5000 5002 5229 5230 5231 7 5001 5000 5003 4760 5007 5167 5231 5 5002 5000 4512 4513 4760 6 4740 4741 4742 5005 7832 7835 6 5004 4742 4754 5006 7835 7836 6 5005 4754 4751 7836 7837 7838 7 4760 4761 4762 5008 5022 5002 5167 6 5007 4762 5009 5022 5023 5024 6 5008 4762 4763 5010 5024 5019 6 5009 4763 5011 5012 5018 5019 5 5010 4763 4764 4765 5012 7 5011 4765 5013 4769 5014 5010 5018 5 5012 4765 4766 4767 4769 6 5012 4769 5015 5021 5018 5242 6 5014 4769 4770 5016 5242 5243 6 5015 4770 5017 5243 5244 5025 5 5016 4770 4771 3835 5025 6 5010 5012 5019 5020 5021 5014 7 5010 5018 5020 5024 5009 5239 6834 6 5019 5018 5021 5239 5240 5241 5 5020 5018 5014 5241 5242 5 5007 5008 5023 5167 5168 6 5022 5008 5024 5168 5169 5170 6 5023 5008 5009 5019 5170 6834 7 5017 3835 3836 5026 5244 5016 5245 6 5025 3836 3837 5027 5245 5246 6 5026 3837 3838 4406 5028 5246 6 5027 4406 4407 5029 5246 5247 6 5028 4407 5030 5250 5247 6845 6 5029 4407 4408 5031 6845 6846 6 5030 4408 4409 5032 6846 6847 6 5031 4409 4410 5033 6850 6847 6 5032 4410 4421 5034 6850 6851 6 5033 4421 4422 4423 5035 6851 6 5034 4423 5036 6851 6852 6853 6 5035 4423 4424 5037 6853 5039 6 5036 4424 4425 4644 5038 5039 6 5037 4644 5039 5040 5041 5045 6 5037 5038 5040 6853 5036 6854 6 5039 5038 5041 5042 6857 6854 6 5040 5038 5042 5043 5044 5045 6 5040 5041 5043 6859 6857 6864 6 5042 5041 5044 6879 6880 6864 6 5043 5041 5045 5046 6881 6879 6 5044 5041 5046 4645 4644 5038 6 5044 5045 4645 6881 6882 6890 6 4281 4282 5048 5475 5476 5477 6 5047 4282 4283 5049 5477 5478 6 5048 4283 4284 5050 5478 5479 6 5049 4284 4285 5051 5479 5480 6 5050 4285 4286 5052 5480 5481 6 5051 4286 4287 5053 5481 5482 6 5052 4287 4288 4924 5054 5482 6 5053 4924 5055 5482 5483 5484 6 5054 4924 4925 4926 5056 5484 6 5055 4926 5057 5484 5485 5486 6 5056 4926 4927 5058 5486 5487 6 5057 4927 4928 5059 5487 5488 6 5058 4928 4929 5060 5488 5489 6 5059 4929 4930 5061 5489 5490 6 5060 4930 4931 5062 5490 5491 6 5061 4931 4932 4933 5063 5491 6 5062 4933 4934 5064 5491 5492 6 5063 4934 5065 5251 5492 5493 6 5064 4934 4935 5066 5251 5252 6 5065 4935 4936 5067 5252 5253 6 5066 4936 4937 5068 5253 5254 6 5067 4937 4938 5069 5254 5255 6 5068 4938 4939 5070 5255 5256 6 5069 4939 4940 5071 5256 5257 6 5070 4940 4941 5072 5257 5258 6 5071 4941 4942 5073 5258 5259 6 5072 4942 4943 5074 5259 5260 6 5073 4943 4944 5075 5260 5261 6 5074 4944 4945 4946 5076 5261 6 5075 4946 5077 5261 5262 5263 6 5076 4946 4947 5078 5263 5264 6 5077 4947 4948 5079 5264 5265 6 5078 4948 4949 5080 5265 5266 6 5079 4949 4950 5081 5266 5267 6 5080 4950 4951 5082 5267 5268 6 5081 4951 4952 5083 5268 5269 6 5082 4952 4953 5084 5269 5270 6 5083 4953 4954 5085 5270 5271 6 5084 4954 4955 4956 5086 5271 6 5085 4956 5087 5088 5271 5272 6 5086 4956 4957 5088 5089 4958 6 5086 5087 5089 5272 5273 5090 6 5088 5087 4958 4959 4961 5090 6 5089 4961 4962 5091 5273 5088 6 5090 4962 5092 5273 5274 5275 6 5091 4962 4963 5093 5275 5276 6 5092 4963 4964 5094 5276 5277 7 5093 4964 4965 4814 4815 5095 5277 6 5094 4815 4816 5096 5277 5278 6 5095 4816 4817 5097 5278 5279 6 5096 4817 4818 4820 5098 5279 6 5097 4820 5099 5279 5280 5281 6 5098 4820 4821 5100 5281 5282 6 5099 4821 4824 5101 5282 5283 6 5100 4824 4825 5102 5283 5153 6 5101 4825 5103 5105 5152 5153 6 5102 4825 4826 5104 4829 5105 5 5103 4826 4827 4828 4829 6 5103 4829 4830 5106 5102 5152 7 5105 4830 5107 5155 5152 5288 5289 6 5106 4830 4831 5108 5109 5289 6 5107 4831 5109 5110 5114 4832 6 5107 5108 5110 5111 5289 5290 6 5109 5108 5111 5112 5113 5114 6 5109 5110 5112 5290 5291 5295 6 5111 5110 5113 5295 5296 5117 6 5112 5110 5114 5115 5116 5117 6 5113 5110 5108 4832 4834 5115 6 5114 4834 4836 4846 5116 5113 6 5115 4846 5113 5117 5118 4848 6 5113 5116 5118 5296 5112 5297 6 5117 5116 4848 5119 5300 5297 6 5118 4848 4849 5120 5300 5301 6 5119 4849 5121 5301 5302 5303 5 5120 4849 4850 5122 5303 6 5121 4850 4852 4856 5123 5303 6 5122 4856 5124 5319 5303 5320 6 5123 4856 4857 5125 5322 5320 6 5124 4857 4859 5126 5127 5322 6 5125 4859 5127 5128 5129 5130 6 5125 5126 5128 5323 5322 5324 6 5127 5126 5129 5324 5325 5329 6 5128 5126 5130 5337 5329 5338 6 5129 5126 4859 4860 5131 5338 6 5130 4860 4862 5132 5338 5339 7 5131 4862 4863 4866 5133 5134 5339 6 5132 4866 5134 5135 5136 5137 5 5132 5133 5135 5339 5340 6 5134 5133 5136 5340 5341 5342 6 5135 5133 5137 5347 5345 5342 6 5136 5133 4866 4867 5138 5347 6 5137 4867 4868 4871 5139 5347 6 5138 4871 5140 5141 5345 5347 6 5139 4871 5141 5142 4872 5151 6 5139 5140 5142 5143 5346 5345 6 5141 5140 5143 5144 5145 5151 6 5141 5142 5144 5346 5361 5360 7 5143 5142 5145 5146 5361 5358 5362 6 5144 5142 5146 5147 5148 5151 6 5144 5145 5147 5362 5363 5367 5 5146 5145 5148 5149 5367 6 5147 5145 5149 5150 4874 5151 7 5147 5148 5150 5156 5367 5368 5369 6 5149 5148 4874 5156 4878 4875 6 4874 5148 4872 5140 5142 5145 6 5102 5105 5153 5154 5155 5106 6 5102 5152 5154 5283 5101 5284 6 5153 5152 5155 5284 5285 5286 6 5154 5152 5106 5286 5287 5288 6 5149 5150 4878 4883 5369 5370 7 4533 4534 5158 6683 6684 6685 6695 6 5157 4534 4667 6683 9751 4668 5 4692 4693 4694 5160 7845 7 5159 4694 5161 7845 7846 7847 7848 6 5160 4694 4695 5162 7848 7849 6 5161 4695 4696 5163 7849 7850 6 5162 4696 5164 7850 7851 7852 6 5163 4696 4697 4698 5165 7852 6 5164 4698 5166 7852 7853 7854 6 5165 4698 4699 4701 7854 7855 5 5002 5007 5022 5168 5231 8 5167 5022 5023 5169 5230 5231 6827 6825 6 5168 5023 5170 6827 6828 6831 7 5169 5023 5024 6831 6832 6833 6834 6 4708 4709 5172 7313 7314 7315 6 5171 4709 4710 5173 7315 7316 6 5172 4710 4711 5174 7316 7317 6 5173 4711 4712 5175 7317 7318 6 5174 4712 4713 5176 7318 7319 6 5175 4713 4714 5177 7319 7320 6 5176 4714 4715 5178 7320 7321 6 5177 4715 4716 4966 5179 7321 6 5178 4966 5180 7321 7322 7323 6 5179 4966 4967 5181 7323 7324 6 5180 4967 4968 5182 5412 7324 6 5181 4968 4969 5183 5412 5413 6 5182 4969 4970 5184 5413 5414 6 5183 4970 4971 4972 5185 5414 6 5184 4972 5186 5414 5415 5416 6 5185 4972 4973 5187 5404 5416 6 5186 4973 4974 5188 5404 5405 6 5187 4974 4975 4976 5189 5405 6 5188 4976 5190 5405 5406 5407 6 5189 4976 4977 5191 5407 5408 6 5190 4977 4978 5192 5408 5409 6 5191 4978 4979 4980 5193 5409 6 5192 4980 4981 5194 5409 5410 6 5193 4981 5195 5410 5411 5196 5 5194 4981 4670 4671 5196 6 5195 4671 4672 5197 5411 5194 7 5196 4672 4673 5198 5424 5411 5432 5 5197 4673 4674 5199 5432 7 5198 4674 4675 5200 5432 5433 5434 6 5199 4675 4676 5201 5434 5435 6 5200 4676 4677 5202 5435 5436 6 5201 4677 4678 5203 5436 5437 6 5202 4678 4679 5204 5437 5438 6 5203 4679 5205 5438 5439 5440 6 5204 4679 4680 4681 5206 5440 5 5205 4681 4682 5207 5440 7 5206 4682 4683 5208 5440 5441 5442 6 5207 4683 5209 5442 5443 5444 6 5208 4683 4684 5210 5425 5444 7 5209 4684 4685 5211 5425 5426 5427 5 5210 4685 5212 5427 5428 7 5211 4685 4686 5213 5428 5216 5215 5 5212 4686 4687 5214 5215 6 5213 4687 4688 4479 4480 5215 6 5214 4480 4481 5216 5212 5213 6 5215 4481 5217 5428 5212 5218 6 5216 4481 4482 4491 4990 5218 7 5217 4990 5219 5448 5428 5216 6811 6 5218 4990 4991 5220 6811 6812 6 5219 4991 5221 6812 6813 6814 6 5220 4991 4992 5222 6814 6815 5 5221 4992 4993 5223 6815 7 5222 4993 4994 5224 6815 6816 6817 5 5223 4994 4995 5225 6817 7 5224 4995 5226 6817 6818 6819 6820 6 5225 4995 4996 4997 5227 6820 6 5226 4997 4998 5228 6820 6821 6 5227 4998 5229 6821 6822 6823 6 5228 4998 4999 5001 5230 6823 7 5229 5001 5231 5168 6823 6824 6825 5 5230 5001 5168 5167 5002 6 4265 4266 5233 6903 6904 5459 6 5232 4266 4267 5234 5449 5459 6 5233 4267 4268 5235 5449 5450 6 5234 4268 4270 5450 5451 5452 6 4520 4521 5237 9678 9679 9680 6 5236 4521 5238 9680 9684 9685 6 5237 4521 4522 423 9685 422 6 5019 5020 5240 6833 6834 6835 6 5239 5020 5241 5649 6835 6836 6 5240 5020 5021 5242 5649 5650 7 5241 5021 5014 5015 5243 5650 5651 5 5242 5015 5016 5244 5651 7 5243 5016 5025 5245 5653 5651 5654 6 5244 5025 5026 5246 5654 5248 6 5245 5026 5027 5028 5247 5248 6 5246 5028 5248 5249 5250 5029 6 5246 5247 5249 5654 5245 6841 6 5248 5247 5250 6842 6841 6843 6 5249 5247 5029 6843 6844 6845 6 5064 5065 5252 5493 5494 5495 6 5251 5065 5066 5253 5495 5496 6 5252 5066 5067 5254 5496 5497 6 5253 5067 5068 5255 5497 5498 6 5254 5068 5069 5256 5498 5499 6 5255 5069 5070 5257 5499 5500 6 5256 5070 5071 5258 5500 5501 6 5257 5071 5072 5259 5501 5502 6 5258 5072 5073 5260 5502 5503 6 5259 5073 5074 5261 5503 5504 6 5260 5074 5075 5076 5262 5504 6 5261 5076 5263 5504 5505 5506 6 5262 5076 5077 5264 5506 5507 6 5263 5077 5078 5265 5507 5508 6 5264 5078 5079 5266 5508 5509 6 5265 5079 5080 5267 5509 5510 6 5266 5080 5081 5268 5510 5511 6 5267 5081 5082 5269 5511 5512 6 5268 5082 5083 5270 5512 5513 6 5269 5083 5084 5271 5513 5514 6 5270 5084 5085 5086 5272 5514 6 5271 5086 5088 5273 5514 5515 6 5272 5088 5090 5091 5274 5515 6 5273 5091 5275 5515 5516 5517 6 5274 5091 5092 5276 5520 5517 6 5275 5092 5093 5277 5520 5278 5 5276 5093 5094 5095 5278 6 5277 5095 5096 5279 5520 5276 6 5278 5096 5097 5098 5280 5520 6 5279 5098 5281 5520 5519 5521 6 5280 5098 5099 5282 5521 5378 6 5281 5099 5100 5283 5377 5378 6 5282 5100 5101 5153 5284 5377 6 5283 5153 5154 5285 5380 5377 6 5284 5154 5286 5525 5380 5526 6 5285 5154 5155 5287 5526 5527 6 5286 5155 5288 5527 5528 5292 6 5287 5155 5106 5289 5292 5290 5 5288 5106 5107 5109 5290 6 5289 5109 5111 5291 5292 5288 6 5290 5111 5292 5293 5294 5295 7 5290 5291 5293 5528 5287 5288 5529 6 5292 5291 5294 5529 5530 5534 5 5293 5291 5295 5534 5535 6 5294 5291 5111 5112 5296 5535 6 5295 5112 5117 5297 5298 5535 6 5296 5117 5298 5299 5300 5118 6 5296 5297 5299 5535 5536 5543 6 5298 5297 5300 5543 5544 5545 6 5299 5297 5118 5119 5301 5545 6 5300 5119 5120 5302 5305 5545 6 5301 5120 5303 5304 5305 5306 7 5302 5120 5304 5319 5123 5121 5122 6 5302 5303 5309 5306 5310 5319 6 5301 5302 5306 5307 5544 5545 6 5305 5302 5307 5308 5309 5304 6 5305 5306 5308 5544 5546 5547 6 5307 5306 5309 5312 5313 5547 6 5308 5306 5304 5310 5311 5312 6 5309 5304 5311 5317 5318 5319 6 5309 5310 5312 5315 5316 5317 6 5309 5311 5308 5313 5314 5315 6 5308 5312 5314 5547 5548 5549 6 5313 5312 5315 5549 5550 5551 6 5314 5312 5311 5316 5554 5551 6 5315 5311 5317 5556 5554 5559 6 5316 5311 5310 5318 5559 5560 6 5317 5310 5319 5320 5321 5560 6 5318 5310 5304 5303 5123 5320 6 5319 5123 5318 5321 5322 5124 6 5318 5320 5322 5323 5560 5561 6 5321 5320 5323 5127 5125 5124 6 5321 5322 5127 5324 5561 5562 6 5323 5127 5128 5325 5326 5562 6 5324 5128 5326 5327 5328 5329 6 5324 5325 5327 5562 5563 5564 6 5326 5325 5328 5573 5564 5574 6 5327 5325 5329 5330 5331 5574 6 5328 5325 5330 5337 5129 5128 6 5328 5329 5331 5332 5333 5337 6 5328 5330 5332 5574 5575 5576 6 5331 5330 5333 5334 5576 5577 6 5332 5330 5334 5335 5336 5337 6 5332 5333 5335 5577 5578 5579 6 5334 5333 5336 5579 5341 5340 6 5335 5333 5337 5338 5339 5340 6 5336 5333 5330 5329 5129 5338 6 5337 5129 5130 5131 5336 5339 6 5336 5338 5131 5132 5134 5340 6 5339 5134 5135 5341 5335 5336 6 5340 5135 5342 5343 5579 5335 6 5341 5135 5343 5344 5345 5136 6 5341 5342 5344 5349 5350 5579 6 5343 5342 5345 5346 5348 5349 7 5344 5342 5346 5141 5139 5347 5136 6 5344 5345 5141 5143 5348 5360 5 5139 5345 5136 5137 5138 6 5344 5346 5349 5352 5353 5360 6 5344 5348 5343 5350 5351 5352 6 5343 5349 5351 5579 5578 5580 6 5350 5349 5352 5580 5581 5585 6 5351 5349 5348 5353 5354 5585 6 5352 5348 5354 5355 5356 5360 6 5352 5353 5355 5609 5585 5610 6 5354 5353 5356 5357 5808 5610 6 5355 5353 5357 5358 5360 5361 6 5355 5356 5358 5359 5808 5809 6 5357 5356 5359 5361 5144 5362 7 5357 5358 5809 5810 5811 5364 5362 6 5356 5353 5348 5361 5143 5346 5 5356 5360 5143 5144 5358 6 5358 5144 5146 5363 5364 5359 6 5362 5146 5364 5365 5366 5367 5 5362 5363 5365 5811 5359 6 5364 5363 5366 5811 5812 5403 7 5365 5363 5367 5403 5402 5368 5376 6 5366 5363 5146 5147 5149 5368 6 5367 5149 5369 5375 5366 5376 6 5368 5149 5156 5370 5372 5375 6 5369 5156 4883 4884 5371 5372 6 5370 4884 5372 5373 4889 4886 6 5370 5371 5373 5374 5375 5369 6 5372 5371 5374 4889 5394 5900 6 5372 5373 5375 5376 5393 5394 5 5372 5374 5376 5369 5368 6 5375 5374 5393 5366 5368 5402 6 5282 5283 5378 5379 5380 5284 6 5282 5377 5379 5521 5281 5522 6 5378 5377 5380 5522 5523 5524 6 5379 5377 5284 5524 5525 5285 6 4657 4658 56 9690 431 57 6 1680 1681 1679 5383 5384 1683 6 1679 5382 5384 5385 7780 3416 6 5383 5382 5385 5386 3775 1683 6 5383 5384 5386 5387 7780 7781 6 5385 5384 5387 5388 5392 3775 6 5385 5386 5388 5389 7781 7782 6 5387 5386 5389 5390 5391 5392 6 5387 5388 5390 5617 7782 7783 6 5389 5388 5391 5617 5618 5619 6 5390 5388 5392 5619 5620 5621 6 5391 5388 5386 3775 5621 3776 6 5376 5374 5394 5395 5402 5399 6 5393 5374 5395 5373 5396 5900 6 5393 5394 5396 5397 5398 5399 5 5395 5394 5397 5900 5895 6 5395 5396 5398 5894 5891 5895 6 5395 5397 5399 5400 5890 5891 6 5395 5398 5400 5401 5402 5393 6 5399 5398 5401 5881 5889 5890 7 5399 5400 5402 5403 5888 5882 5881 6 5399 5401 5403 5366 5376 5393 6 5402 5401 5888 5812 5365 5366 6 5186 5187 5405 5416 5417 5418 6 5404 5187 5188 5189 5406 5418 6 5405 5189 5407 5418 5419 5420 6 5406 5189 5190 5408 5420 5421 6 5407 5190 5191 5409 5421 5422 6 5408 5191 5192 5193 5410 5422 6 5409 5193 5194 5411 5422 5423 6 5410 5194 5196 5423 5424 5197 6 5181 5182 5413 7324 7325 7326 6 5412 5182 5183 5414 7326 7327 6 5413 5183 5184 5185 5415 7327 6 5414 5185 5416 7327 7328 7329 6 5415 5185 5186 5404 5417 7329 6 5416 5404 5418 7329 7330 7331 6 5417 5404 5405 5406 5419 7331 6 5418 5406 5420 6792 7331 7332 6 5419 5406 5407 5421 6792 6793 6 5420 5407 5408 5422 5429 6793 6 5421 5408 5409 5410 5423 5429 6 5422 5410 5411 5424 5429 5430 6 5423 5411 5197 5430 5431 5432 6 5209 5210 5426 5444 5445 5446 6 5425 5210 5427 5446 5447 5448 5 5426 5210 5211 5428 5448 6 5427 5211 5212 5216 5448 5218 6 5421 5422 5423 5430 6793 6794 6 5429 5423 5424 5431 6794 6795 6 5430 5424 5432 6795 6796 5433 6 5431 5424 5197 5198 5199 5433 5 5432 5199 5434 6796 5431 6 5433 5199 5200 5435 6796 6797 6 5434 5200 5201 5436 6797 6798 6 5435 5201 5202 5437 6798 6799 6 5436 5202 5203 5438 6799 6800 6 5437 5203 5204 5439 6800 6801 6 5438 5204 5440 6801 6802 6803 7 5439 5204 5205 5206 5207 5441 6803 5 5440 5207 5442 6803 6804 6 5441 5207 5208 5443 6804 6805 6 5442 5208 5444 6805 6806 5445 5 5443 5208 5209 5425 5445 6 5444 5425 5446 6806 5443 6807 6 5445 5425 5426 5447 6807 6808 6 5446 5426 5448 6808 6809 6810 7 5447 5426 5427 5428 5218 6810 6811 6 5233 5234 5450 5459 5460 5461 6 5449 5234 5235 5451 5461 5462 6 5450 5235 5452 5462 5463 5464 6 5451 5235 4270 4271 5453 5464 6 5452 4271 4272 5454 5464 5465 6 5453 4272 4273 5455 5456 5465 6 5454 4273 5456 5457 5458 4274 6 5454 5455 5457 5465 5466 5467 6 5456 5455 5458 5467 5468 5469 6 5457 5455 4274 5469 5470 4275 6 5233 5449 5460 6904 5232 6905 6 5459 5449 5461 6905 6906 6907 6 5460 5449 5450 5462 6907 6908 6 5461 5450 5451 5463 6908 6909 6 5462 5451 5464 6909 6910 6911 6 5463 5451 5452 5453 5465 6911 6 5464 5453 5454 5456 5466 6911 6 5465 5456 5467 6911 6912 6913 6 5466 5456 5457 5468 6913 6914 6 5467 5457 5469 6914 6915 6916 6 5468 5457 5458 5470 6916 6917 6 5469 5458 4275 4276 5471 6917 6 5470 4276 4277 4278 5472 6917 6 5471 4278 5473 6917 6918 6919 6 5472 4278 4279 5474 6919 6920 6 5473 4279 4280 5475 6920 6921 6 5474 4280 4281 5047 5476 6921 6 5475 5047 5477 6921 6922 6923 6 5476 5047 5048 5478 6923 6924 6 5477 5048 5049 5479 6924 6925 6 5478 5049 5050 5480 6925 6926 6 5479 5050 5051 5481 6926 6927 6 5480 5051 5052 5482 5655 6927 6 5481 5052 5053 5054 5483 5655 6 5482 5054 5484 5655 5656 5657 6 5483 5054 5055 5056 5485 5657 6 5484 5056 5486 5657 5658 5659 6 5485 5056 5057 5487 5659 5660 6 5486 5057 5058 5488 5660 5661 6 5487 5058 5059 5489 5661 5662 6 5488 5059 5060 5490 5622 5662 6 5489 5060 5061 5491 5622 5623 6 5490 5061 5062 5063 5492 5623 6 5491 5063 5064 5493 5623 5624 6 5492 5064 5251 5494 5624 5625 6 5493 5251 5495 5625 5626 5627 6 5494 5251 5252 5496 5627 5628 6 5495 5252 5253 5497 5628 5629 6 5496 5253 5254 5498 5629 5630 6 5497 5254 5255 5499 5630 5631 6 5498 5255 5256 5500 5631 5632 6 5499 5256 5257 5501 5632 5633 6 5500 5257 5258 5502 5633 5634 6 5501 5258 5259 5503 5634 5635 6 5502 5259 5260 5504 5635 5636 6 5503 5260 5261 5262 5505 5636 6 5504 5262 5506 5636 5637 5638 6 5505 5262 5263 5507 5638 5639 6 5506 5263 5264 5508 5639 5640 6 5507 5264 5265 5509 5640 5641 6 5508 5265 5266 5510 5641 5642 6 5509 5266 5267 5511 5642 5643 6 5510 5267 5268 5512 5643 5644 6 5511 5268 5269 5513 5644 5645 6 5512 5269 5270 5514 5645 5646 6 5513 5270 5271 5272 5515 5646 6 5514 5272 5273 5274 5516 5646 6 5515 5274 5517 5518 5646 5647 6 5516 5274 5518 5519 5520 5275 6 5516 5517 5519 5647 5648 5521 5 5518 5517 5520 5280 5521 7 5519 5517 5275 5276 5278 5279 5280 7 5519 5280 5281 5378 5522 5648 5518 5 5521 5378 5379 5523 5648 7 5522 5379 5524 5686 5648 5685 5687 6 5523 5379 5380 5525 5688 5687 6 5524 5380 5285 5526 5688 5689 6 5525 5285 5286 5527 5689 5690 6 5526 5286 5287 5528 5690 5691 6 5527 5287 5292 5529 5691 5692 6 5528 5292 5293 5530 5531 5692 6 5529 5293 5531 5532 5533 5534 5 5529 5530 5532 5692 5693 6 5531 5530 5533 5693 5694 5695 7 5532 5530 5534 5695 5696 5539 5537 6 5533 5530 5293 5294 5535 5537 7 5534 5294 5295 5296 5298 5536 5537 6 5535 5298 5537 5538 5542 5543 6 5535 5536 5538 5539 5533 5534 6 5537 5536 5539 5540 5541 5542 6 5537 5538 5540 5696 5533 5697 6 5539 5538 5541 5697 5698 5699 7 5540 5538 5542 5699 5700 5701 9796 5 5541 5538 5536 5543 9796 6 5542 5536 5298 5299 5544 9796 7 5543 5299 5545 5305 5307 5546 9796 5 5544 5299 5305 5301 5300 6 5544 5307 5547 5702 5701 9796 6 5546 5307 5308 5313 5548 5702 6 5547 5313 5549 5702 5703 5704 6 5548 5313 5314 5550 5704 5705 6 5549 5314 5551 5552 5705 5706 6 5550 5314 5552 5553 5554 5315 6 5550 5551 5553 5706 5707 5708 6 5552 5551 5554 5555 5708 5709 6 5553 5551 5315 5555 5556 5316 6 5553 5554 5556 5557 5709 5710 6 5555 5554 5316 5557 5558 5559 6 5555 5556 5558 5710 5711 5712 6 5557 5556 5559 5715 5712 5716 6 5558 5556 5316 5317 5560 5716 6 5559 5317 5318 5321 5561 5716 6 5560 5321 5323 5562 5717 5716 6 5561 5323 5324 5326 5563 5717 6 5562 5326 5564 5565 5718 5717 6 5563 5326 5565 5566 5573 5327 6 5563 5564 5566 5567 5718 5714 6 5565 5564 5567 5568 5572 5573 6 5565 5566 5568 5569 5754 5714 6 5567 5566 5569 5570 5571 5572 6 5567 5568 5570 5753 5754 5755 6 5569 5568 5571 5755 5756 5771 6 5570 5568 5572 5770 5768 5771 6 5571 5568 5566 5573 5770 5772 6 5572 5566 5564 5327 5574 5772 6 5573 5327 5328 5331 5575 5772 6 5574 5331 5576 5772 5773 5774 6 5575 5331 5332 5577 5774 5595 7 5576 5332 5334 5578 5595 5590 5775 6 5577 5334 5579 5350 5580 5775 6 5578 5334 5335 5341 5343 5350 6 5578 5350 5351 5581 5582 5775 6 5580 5351 5582 5583 5584 5585 6 5580 5581 5583 5586 5587 5775 6 5582 5581 5584 5586 5606 5607 6 5583 5581 5585 5607 5608 5609 6 5584 5581 5351 5352 5609 5354 6 5582 5583 5587 5588 5606 5598 6 5582 5586 5588 5589 5590 5775 6 5587 5586 5589 5596 5597 5598 6 5587 5588 5590 5591 5592 5596 6 5587 5589 5591 5595 5577 5775 6 5590 5589 5592 5593 5595 5774 6 5591 5589 5593 5594 5596 5779 6 5591 5592 5594 5774 5773 5776 6 5593 5592 5776 5777 5778 5779 5 5590 5591 5774 5576 5577 6 5592 5589 5588 5597 5779 5780 6 5596 5588 5598 5599 5600 5780 6 5597 5588 5599 5603 5606 5586 6 5597 5598 5600 5601 5602 5603 6 5597 5599 5601 5780 5781 5782 6 5600 5599 5602 5782 5790 5791 6 5601 5599 5603 5604 5791 5792 6 5602 5599 5604 5605 5598 5606 6 5602 5603 5605 5795 5792 5796 6 5604 5603 5796 5797 5607 5606 6 5603 5598 5586 5583 5607 5605 6 5606 5583 5584 5608 5797 5605 6 5607 5584 5609 5611 5799 5797 6 5608 5584 5585 5354 5610 5611 7 5609 5354 5611 5801 5807 5808 5355 5 5609 5610 5608 5801 5799 6 4515 4517 5613 5614 5615 5616 6 4515 5612 5614 428 427 7501 6 5613 5612 5615 7501 7502 7506 6 5614 5612 5616 7506 7507 7508 6 5615 5612 4517 7508 7509 4519 6 5389 5390 5618 7783 7784 7785 6 5617 5390 5619 7785 7786 7787 6 5618 5390 5391 5620 7787 7790 6 5619 5391 5621 7790 7791 7792 6 5620 5391 5392 3776 3779 7792 6 5489 5490 5623 5662 5663 5664 6 5622 5490 5491 5492 5624 5664 6 5623 5492 5493 5625 5664 5665 6 5624 5493 5494 5626 5665 5666 6 5625 5494 5627 5666 5667 5668 6 5626 5494 5495 5628 5668 5669 6 5627 5495 5496 5629 5669 5670 6 5628 5496 5497 5630 5670 5671 6 5629 5497 5498 5631 5671 5672 6 5630 5498 5499 5632 5672 5673 6 5631 5499 5500 5633 5673 5674 6 5632 5500 5501 5634 5674 5675 6 5633 5501 5502 5635 5675 5676 6 5634 5502 5503 5636 5676 5677 6 5635 5503 5504 5505 5637 5677 6 5636 5505 5638 5677 5678 5679 6 5637 5505 5506 5639 5679 5680 6 5638 5506 5507 5640 5680 5681 6 5639 5507 5508 5641 5681 5682 6 5640 5508 5509 5642 5682 5683 6 5641 5509 5510 5643 5683 5684 6 5642 5510 5511 5644 5684 5685 6 5643 5511 5512 5645 5685 5686 6 5644 5512 5513 5646 5686 5647 6 5645 5513 5514 5515 5516 5647 6 5646 5516 5518 5648 5686 5645 6 5647 5518 5521 5686 5523 5522 6 5240 5241 5650 6836 6837 6838 6 5649 5241 5242 5651 5652 6838 6 5650 5242 5652 5653 5244 5243 6 5650 5651 5653 6838 6839 6840 6 5652 5651 5244 5654 6840 6841 5 5653 5244 5245 5248 6841 6 5481 5482 5483 5656 6927 6928 6 5655 5483 5657 6928 6929 6930 6 5656 5483 5484 5485 5658 6930 6 5657 5485 5659 6930 6931 6932 6 5658 5485 5486 5660 5832 6932 6 5659 5486 5487 5661 5832 5833 6 5660 5487 5488 5662 5833 5834 6 5661 5488 5489 5622 5663 5834 6 5662 5622 5664 5834 5835 5836 6 5663 5622 5623 5624 5665 5836 6 5664 5624 5625 5666 5836 5814 6 5665 5625 5626 5667 5813 5814 6 5666 5626 5668 5813 5817 5818 6 5667 5626 5627 5669 5860 5818 6 5668 5627 5628 5670 5860 5861 6 5669 5628 5629 5671 5861 5862 6 5670 5629 5630 5672 5862 5863 6 5671 5630 5631 5673 5863 5864 6 5672 5631 5632 5674 5864 5865 6 5673 5632 5633 5675 5865 5866 6 5674 5633 5634 5676 5866 5867 6 5675 5634 5635 5677 5867 5868 6 5676 5635 5636 5637 5678 5868 6 5677 5637 5679 5868 5869 5694 6 5678 5637 5638 5680 5694 5870 6 5679 5638 5639 5681 5870 5871 6 5680 5639 5640 5682 5871 5872 6 5681 5640 5641 5683 5872 5689 6 5682 5641 5642 5684 5689 5688 6 5683 5642 5643 5685 5687 5688 6 5684 5643 5644 5686 5523 5687 6 5685 5644 5645 5647 5648 5523 5 5685 5523 5684 5688 5524 6 5684 5687 5524 5525 5689 5683 7 5688 5525 5526 5690 5872 5682 5683 5 5689 5526 5527 5691 5872 7 5690 5527 5528 5692 5872 5871 5693 5 5691 5528 5529 5531 5693 7 5692 5531 5532 5694 5871 5691 5870 7 5693 5532 5695 5869 5678 5679 5870 6 5694 5532 5533 5696 9699 5869 6 5695 5533 5539 5697 9700 9699 6 5696 5539 5540 5698 5719 9700 6 5697 5540 5699 5719 5720 5721 6 5698 5540 5541 5700 5721 5722 6 5699 5541 5701 5702 5722 5723 5 5700 5541 5702 5546 9796 7 5700 5701 5546 5547 5548 5703 5723 6 5702 5548 5704 5723 5724 5728 6 5703 5548 5549 5705 5728 5729 6 5704 5549 5550 5706 5729 5730 6 5705 5550 5552 5707 5733 5730 6 5706 5552 5708 5733 5734 5735 6 5707 5552 5553 5709 5738 5735 6 5708 5553 5555 5710 5738 5739 6 5709 5555 5557 5711 5748 5739 6 5710 5557 5712 5713 5748 5749 6 5711 5557 5713 5714 5715 5558 6 5711 5712 5714 5749 5750 5754 7 5713 5712 5715 5718 5565 5754 5567 6 5714 5712 5558 5716 5717 5718 6 5715 5558 5717 5561 5560 5559 6 5715 5716 5718 5563 5562 5561 5 5715 5717 5563 5565 5714 7 5697 5698 5720 9697 5866 9698 9700 6 5719 5698 5721 9697 9696 9701 6 5720 5698 5699 5722 9701 9702 7 5721 5699 5700 5723 5724 5725 9702 5 5722 5700 5702 5703 5724 7 5723 5703 5722 5725 5726 5727 5728 6 5722 5724 5726 6096 9702 9703 6 5725 5724 5727 6096 6097 6098 6 5726 5724 5728 6098 5731 5729 5 5727 5724 5703 5704 5729 6 5728 5704 5705 5730 5731 5727 6 5729 5705 5731 5732 5733 5706 7 5729 5730 5732 6098 5727 6099 6100 6 5731 5730 5733 6100 6101 6102 6 5732 5730 5706 5707 5734 6102 6 5733 5707 5735 5736 6102 6103 6 5734 5707 5736 5737 5738 5708 6 5734 5735 5737 6106 6103 6107 6 5736 5735 5738 6107 6108 5740 6 5737 5735 5708 5709 5739 5740 6 5738 5709 5740 5741 5748 5710 6 5738 5739 5741 5742 6108 5737 6 5740 5739 5742 5743 5747 5748 6 5740 5741 5743 5744 6108 6109 6 5742 5741 5744 5745 5746 5747 6 5742 5743 5745 6112 6109 6113 6 5744 5743 5746 6113 6114 6115 6 5745 5743 5747 5751 6122 6115 6 5746 5743 5741 5748 5749 5751 6 5747 5741 5739 5710 5711 5749 6 5748 5711 5713 5750 5747 5751 6 5749 5713 5751 5752 5753 5754 6 5747 5749 5746 5750 5752 6122 5 5751 5750 5753 6122 5950 6 5752 5750 5754 5569 5755 5950 6 5753 5750 5713 5714 5569 5567 6 5753 5569 5570 5756 5757 5950 6 5755 5570 5757 5758 5759 5771 6 5755 5756 5758 5950 5951 5952 6 5757 5756 5759 5760 5952 5953 6 5758 5756 5760 5761 5762 5771 6 5758 5759 5761 5953 5954 5958 6 5760 5759 5762 5763 5764 5958 6 5761 5759 5763 5767 5768 5771 6 5761 5762 5764 5765 5766 5767 6 5761 5763 5765 5958 5959 5989 6 5764 5763 5766 5990 5989 5991 6 5765 5763 5767 5991 5992 5777 6 5766 5763 5762 5768 5769 5777 6 5767 5762 5769 5770 5571 5771 6 5767 5768 5770 5773 5776 5777 6 5769 5768 5571 5572 5772 5773 6 5571 5768 5570 5762 5756 5759 6 5770 5572 5573 5574 5575 5773 7 5772 5575 5774 5593 5776 5770 5769 6 5773 5575 5576 5595 5591 5593 6 5590 5577 5587 5582 5580 5578 5 5773 5593 5594 5777 5769 7 5776 5594 5778 5992 5766 5769 5767 6 5777 5594 5779 5993 5992 5783 6 5778 5594 5592 5596 5780 5783 6 5779 5596 5597 5600 5781 5783 6 5780 5600 5782 5783 5784 5785 6 5781 5600 5601 5785 5786 5790 6 5780 5781 5784 5993 5778 5779 6 5783 5781 5785 5994 5993 5997 7 5784 5781 5782 5786 5787 5997 5998 6 5785 5782 5787 5788 5789 5790 6 5785 5786 5788 5998 5999 6000 6 5787 5786 5789 6003 6000 6004 6 5788 5786 5790 6010 6004 6200 6 5789 5786 5782 5601 5791 6200 6 5790 5601 5602 5792 5793 6200 6 5791 5602 5793 5794 5795 5604 6 5791 5792 5794 6199 6200 6198 6 5793 5792 5795 6198 6201 6222 6 5794 5792 5604 5796 6222 6220 6 5795 5604 5605 5797 5798 6220 6 5796 5605 5798 5799 5608 5607 6 5796 5797 5799 5800 6219 6220 6 5798 5797 5608 5800 5801 5611 6 5798 5799 5801 5802 5803 6219 7 5800 5799 5611 5610 5802 5806 5807 6 5800 5801 5803 5804 5805 5806 6 5800 5802 5804 6218 6210 6219 6 5803 5802 5805 5824 5825 6218 6 5804 5802 5806 5824 5831 5840 6 5805 5802 5801 5807 5809 5840 5 5806 5801 5610 5808 5809 5 5807 5610 5355 5357 5809 7 5808 5357 5359 5810 5840 5806 5807 6 5809 5359 5811 5839 5840 5887 7 5810 5359 5364 5365 5812 5886 5887 6 5811 5365 5885 5886 5888 5403 6 5666 5667 5814 5815 5816 5817 6 5666 5813 5815 5836 5665 5843 6 5814 5813 5816 5843 5844 5845 6 5815 5813 5817 5820 5821 5845 6 5816 5813 5667 5818 5819 5820 6 5817 5667 5819 5860 5858 5668 6 5817 5818 5820 5823 5858 5855 6 5817 5819 5816 5821 5822 5823 6 5816 5820 5822 5845 5846 5847 6 5821 5820 5823 5853 5850 5847 6 5822 5820 5819 5853 5854 5855 6 5804 5805 5825 5826 5827 5831 5 5804 5824 5826 6217 6218 7 5825 5824 5827 5828 6217 6216 6022 6 5826 5824 5828 5829 5830 5831 6 5826 5827 5829 6020 6021 6022 6 5828 5827 5830 5837 5873 6020 6 5829 5827 5831 5837 5838 5839 6 5830 5827 5824 5805 5839 5840 6 5659 5660 5833 6932 6933 6934 6 5832 5660 5661 5834 5841 6934 6 5833 5661 5662 5663 5835 5841 6 5834 5663 5836 5841 5842 5843 6 5835 5663 5664 5665 5814 5843 6 5829 5830 5838 5873 5874 5884 6 5837 5830 5839 5886 5884 5887 6 5838 5830 5831 5840 5810 5887 6 5839 5831 5810 5809 5806 5805 6 5833 5834 5835 5842 6934 6935 6 5841 5835 5843 6935 6936 5844 6 5842 5835 5836 5814 5815 5844 6 5843 5815 5845 6019 6936 5842 6 5844 5815 5816 5821 5846 6019 6 5845 5821 5847 5848 6019 6941 6 5846 5821 5848 5849 5850 5822 6 5846 5847 5849 6941 6942 6943 6 5848 5847 5850 5851 6946 6943 6 5849 5847 5851 5852 5853 5822 5 5849 5850 5852 6946 6386 6 5851 5850 5853 6104 6105 6386 6 5852 5850 5822 5823 5854 6104 6 5853 5823 5855 5856 6101 6104 6 5854 5823 5856 5857 5858 5819 6 5854 5855 5857 6099 6100 6101 6 5856 5855 5858 5859 6385 6099 6 5857 5855 5859 5860 5818 5819 6 5857 5858 5860 5861 6384 6385 6 5859 5858 5818 5668 5669 5861 6 5860 5669 5670 5862 6384 5859 6 5861 5670 5671 5863 9704 6384 6 5862 5671 5672 5864 9695 9704 6 5863 5672 5673 5865 9695 9696 6 5864 5673 5674 5866 9696 9697 7 5865 5674 5675 5867 9697 5719 9698 5 5866 5675 5676 5868 9698 7 5867 5676 5677 5678 5869 9698 9699 5 5868 5678 5694 5695 9699 5 5694 5679 5680 5871 5693 6 5870 5680 5681 5872 5691 5693 6 5871 5681 5682 5689 5690 5691 6 5829 5837 5874 5875 9737 6020 6 5873 5837 5875 5876 5883 5884 6 5873 5874 5876 5877 9737 6042 6 5875 5874 5877 5878 5879 5883 6 5875 5876 5878 6049 6042 6043 6 5877 5876 5879 5880 6050 6049 6 5878 5876 5880 5881 5882 5883 6 5878 5879 5881 6050 6051 5889 6 5880 5879 5882 5401 5400 5889 6 5881 5879 5883 5885 5888 5401 6 5882 5879 5876 5874 5884 5885 6 5883 5874 5837 5885 5886 5838 6 5883 5884 5886 5812 5882 5888 6 5885 5884 5838 5812 5811 5887 5 5811 5886 5838 5839 5810 5 5882 5885 5812 5403 5401 6 5881 5400 5890 6054 6051 5880 6 5889 5400 5398 5891 5892 6054 6 5890 5398 5892 5893 5894 5397 6 5890 5891 5893 6057 6054 6058 6 5892 5891 5894 6058 6059 6060 6 5893 5891 5397 5895 5896 6060 6 5894 5397 5896 5897 5900 5396 6 5894 5895 5897 5898 6060 6062 6 5896 5895 5898 5899 4890 5900 6 5896 5897 5899 5901 6062 6063 6 5898 5897 4890 4891 5901 5902 7 4890 5897 5895 5396 5394 5373 4889 6 5898 5899 5902 6066 6063 6067 6 5901 5899 4891 4893 5903 6067 6 5902 4893 5904 5905 5906 6067 6 5903 4893 5905 5912 5913 4894 6 5903 5904 5906 5907 5908 5912 6 5903 5905 5907 6067 6071 6068 7 5906 5905 5908 5909 6076 6073 6071 6 5907 5905 5909 5910 5911 5912 5 5907 5908 5910 5935 6076 7 5909 5908 5911 5933 5930 5934 5935 6 5910 5908 5912 5933 9753 5916 6 5911 5908 5905 5904 5913 5916 6 5912 5904 4894 5914 5915 5916 6 5913 4894 4895 4897 4900 5915 6 5914 4900 5913 5916 5917 5918 6 5913 5915 5917 5912 9753 5911 6 5916 5915 5918 9753 9756 9759 6 5917 5915 4900 4901 5919 9759 7 5918 4901 4903 3672 3952 5920 9759 6 5919 3952 3950 5921 9756 9759 5 5920 3950 3949 5922 9756 6 5921 3949 5923 5931 5932 9756 6 5922 3949 3947 3963 5924 5931 6 5923 3963 3964 5925 5926 5931 6 5924 3964 3966 5926 5927 5943 6 5924 5925 5927 5928 5930 5931 6 5926 5925 5928 5929 5942 5943 5 5926 5927 5929 5930 5934 7 5928 5927 5936 5934 5937 5941 5942 7 5926 5928 5931 5932 5933 5910 5934 6 5926 5930 5932 5924 5923 5922 6 5931 5930 5922 5933 9753 9756 5 5932 5930 5910 5911 9753 6 5910 5930 5935 5936 5929 5928 6 5910 5934 5936 6075 6076 5909 6 5935 5934 5929 5937 5938 6075 6 5936 5929 5938 5939 5940 5941 5 5936 5937 5939 6075 6077 6 5938 5937 5940 6077 6078 6087 6 5939 5937 5941 6088 6087 6092 7 5940 5937 5929 5942 5945 6092 5947 5 5941 5929 5927 5943 5945 6 5942 5927 5925 3966 5944 5945 7 5943 3966 3967 5945 5946 3136 5948 6 5943 5944 5942 5941 5946 5947 5 5945 5944 5947 3135 3136 6 5945 5946 3135 6092 5941 3137 6 3136 5944 2094 2093 5949 3967 6 2093 5948 3967 3968 2489 2490 6 5755 5757 5951 5753 5752 6122 6 5950 5757 5952 6167 6121 6122 6 5951 5757 5758 5953 6167 6165 6 5952 5758 5760 5954 5955 6165 6 5953 5760 5955 5956 5957 5958 6 5953 5954 5956 6163 6162 6165 6 5955 5954 5957 5961 5968 6163 6 5956 5954 5958 5959 5960 5961 6 5957 5954 5760 5761 5764 5959 6 5958 5764 5957 5960 5964 5989 6 5957 5959 5961 5962 5963 5964 6 5957 5960 5962 5965 5968 5956 6 5961 5960 5963 5965 5966 5983 6 5962 5960 5964 5984 5983 5985 6 5963 5960 5959 5988 5985 5989 6 5961 5962 5966 5967 5968 5969 6 5965 5962 5967 5983 5981 5972 6 5965 5966 5969 5970 5971 5972 6 5961 5965 5956 5969 6164 6163 7 5968 5965 5967 5970 6157 6158 6164 6 5969 5967 5971 6448 6446 6157 6 5970 5967 5972 5973 6448 6449 6 5971 5967 5973 5974 5966 5981 6 5971 5972 5974 5975 5976 6449 6 5973 5972 5975 5979 5980 5981 6 5973 5974 5976 5977 5978 5979 6 5973 5975 5977 6449 6450 6451 6 5976 5975 5978 6451 6609 6610 6 5977 5975 5979 6610 6613 6614 6 5978 5975 5974 5980 6614 6615 6 5979 5974 5981 5982 6641 6615 6 5980 5974 5982 5983 5966 5972 6 5980 5981 5983 5984 6641 6642 6 5982 5981 5984 5963 5962 5966 6 5982 5983 5963 5985 5986 6642 6 5984 5963 5986 5987 5988 5964 6 5984 5985 5987 6644 6642 6169 6 5986 5985 5988 5995 6168 6169 6 5987 5985 5964 5989 5990 5995 6 5988 5964 5959 5990 5765 5764 6 5988 5989 5765 5991 5994 5995 6 5990 5765 5766 5992 5993 5994 5 5991 5766 5993 5778 5777 6 5991 5992 5778 5994 5784 5783 7 5991 5993 5784 5990 5995 5996 5997 6 5990 5994 5996 5987 5988 6168 6 5995 5994 5997 5998 5999 6168 5 5996 5994 5784 5785 5998 5 5996 5997 5999 5785 5787 7 5996 5998 5787 6000 6001 6170 6168 6 5999 5787 6001 6002 6003 5788 5 5999 6000 6002 6170 6171 6 6001 6000 6003 6171 6172 6006 6 6002 6000 5788 6004 6005 6006 6 6003 5788 6005 6009 6010 5789 6 6003 6004 6006 6007 6008 6009 6 6003 6005 6007 6172 6002 6173 6 6006 6005 6008 6011 6173 6174 6 6007 6005 6009 6011 6012 6016 6 6008 6005 6004 6010 6018 6016 6 6009 6004 5789 6199 6018 6200 6 6007 6008 6012 6013 6180 6174 6 6011 6008 6013 6014 6015 6016 6 6011 6012 6014 6181 6180 6187 6 6013 6012 6015 6191 6188 6187 6 6014 6012 6016 6017 6191 6192 6 6015 6012 6017 6018 6009 6008 6 6015 6016 6018 6192 6195 6196 6 6017 6016 6009 6199 6196 6010 6 5844 5845 5846 6938 6936 6941 6 5828 5829 6021 9737 6039 5873 6 5828 6020 6022 6023 6024 6039 6 5828 6021 6023 6216 5826 6223 6 6022 6021 6024 6025 6026 6223 6 6023 6021 6025 6038 6029 6039 6 6023 6024 6026 6027 6028 6029 6 6023 6025 6027 6223 6226 6224 6 6026 6025 6028 6226 6227 6033 6 6027 6025 6029 6030 6032 6033 6 6028 6025 6030 6031 6038 6024 6 6028 6029 6031 6032 6034 6035 6 6030 6029 6035 6036 6037 6038 6 6028 6030 6033 6034 6248 6240 6 6028 6032 6227 6027 6228 6240 6 6032 6030 6035 6248 6247 6249 6 6034 6030 6031 6036 6249 6250 6 6035 6031 6037 6250 6264 6265 6 6036 6031 6038 6040 6041 6265 6 6037 6031 6029 6024 6039 6040 6 6038 6024 6040 9737 6020 6021 6 6038 6039 6037 6041 6042 9737 7 6037 6040 6042 6043 6044 6266 6265 6 6041 6040 6043 9737 5875 5877 6 6041 6042 6044 6045 6049 5877 5 6041 6043 6045 6046 6266 6 6044 6043 6046 6047 6048 6049 7 6044 6045 6047 6263 6266 6262 6267 6 6046 6045 6048 6270 6267 6281 6 6047 6045 6049 6050 6052 6281 6 6048 6045 6043 6050 5878 5877 6 6048 6049 5878 5880 6051 6052 6 6050 5880 6052 6053 6054 5889 6 6050 6051 6053 6055 6281 6048 6 6052 6051 6054 6055 6056 6057 6 6053 6051 5889 5890 6057 5892 7 6052 6053 6056 6280 6281 6279 6282 6 6055 6053 6057 6284 6282 6285 6 6056 6053 6054 5892 6058 6285 6 6057 5892 5893 6059 6061 6285 6 6058 5893 6060 6061 6288 6289 6 6059 5893 5894 5896 6062 6289 6 6058 6059 6285 6286 6287 6288 6 6060 5896 5898 6063 6064 6289 6 6062 5898 6064 6065 6066 5901 7 6062 6063 6065 6289 6292 6290 6293 5 6064 6063 6066 6293 6069 6 6065 6063 5901 6067 6068 6069 6 6066 5901 5902 5903 5906 6068 6 6066 6067 6069 6070 6071 5906 7 6066 6068 6070 6293 6065 6294 6295 5 6069 6068 6071 6072 6295 6 6070 6068 5906 6072 6073 5907 7 6070 6071 6073 6074 6297 6295 6298 6 6072 6071 6074 6075 6076 5907 6 6072 6073 6075 6298 6079 6077 7 6074 6073 6076 5935 5936 5938 6077 5 6075 6073 5935 5909 5907 6 6075 5938 5939 6078 6079 6074 6 6077 5939 6079 6080 6087 6084 6 6077 6078 6080 6081 6298 6074 6 6079 6078 6081 6082 6083 6084 6 6079 6080 6082 6298 6299 6302 6 6081 6080 6083 6302 6303 6315 6 6082 6080 6084 6085 6314 6315 6 6083 6080 6085 6086 6087 6078 7 6083 6084 6086 6089 6314 6316 6319 6 6085 6084 6087 6088 6089 6090 6 6086 6084 6088 5940 5939 6078 6 6086 6087 5940 6090 6091 6092 6 6085 6086 6090 6095 3770 6319 7 6089 6086 6088 6091 3138 6093 6095 5 6090 6088 6092 3137 3138 6 6091 6088 5940 5941 5947 3137 6 6090 3138 3139 6094 3769 6095 7 6093 3139 3769 3767 2086 2085 9777 5 6093 3769 3770 6089 6090 6 5725 5726 6097 6384 9703 9704 6 6096 5726 6098 6099 6384 6385 5 6097 5726 5727 5731 6099 7 6097 6098 5731 6100 6385 5857 5856 5 6099 5731 5732 6101 5856 7 6100 5732 6102 6103 6104 5856 5854 5 6101 5732 5733 5734 6103 7 6102 5734 6101 6104 6105 6106 5736 6 6101 6103 6105 5854 5853 5852 6 6104 6103 6106 5852 6386 6387 5 6105 6103 5736 6107 6387 7 6106 5736 5737 6108 6387 6388 6110 6 6107 5737 5740 5742 6109 6110 6 6108 5742 6110 6111 6112 5744 6 6108 6109 6111 6388 6107 6389 6 6110 6109 6112 6389 6390 6391 6 6111 6109 5744 6113 6394 6391 6 6112 5744 5745 6114 6116 6394 6 6113 5745 6115 6116 6117 6118 6 6114 5745 6121 6118 6122 5746 6 6113 6114 6117 6394 9738 9739 6 6116 6114 6118 6119 6123 9739 6 6117 6114 6119 6120 6121 6115 6 6117 6118 6120 6123 6124 6166 5 6119 6118 6121 6167 6166 6 6120 6118 6115 6122 6167 5951 7 6121 6115 5746 5751 5752 5950 5951 6 6117 6119 6124 6125 6132 9739 6 6123 6119 6125 6126 6166 6161 6 6123 6124 6126 6127 6128 6132 6 6125 6124 6127 6153 6161 6159 6 6125 6126 6128 6129 6152 6153 6 6125 6127 6129 6130 6131 6132 6 6128 6127 6130 6151 6150 6152 6 6128 6129 6131 6151 6138 6135 6 6128 6130 6132 6133 6134 6135 6 6128 6131 6133 9739 6123 6125 6 6132 6131 6134 6399 9738 9739 6 6133 6131 6135 6136 6398 6399 6 6134 6131 6136 6137 6138 6130 6 6134 6135 6137 6398 6400 6401 6 6136 6135 6138 6139 6401 6402 6 6137 6135 6139 6140 6151 6130 6 6137 6138 6140 6141 6402 6403 6 6139 6138 6141 6142 6149 6151 6 6139 6140 6142 6143 6403 6404 6 6141 6140 6143 6144 6145 6149 6 6141 6142 6144 6404 6405 6406 6 6143 6142 6145 6146 6406 6437 6 6144 6142 6146 6147 6148 6149 6 6144 6145 6147 6438 6437 6439 6 6146 6145 6148 6439 6440 6441 6 6147 6145 6149 6150 6441 6442 6 6148 6145 6142 6140 6150 6151 6 6148 6149 6151 6129 6152 6442 6 6150 6149 6140 6138 6130 6129 6 6150 6129 6127 6153 6154 6442 6 6152 6127 6126 6154 6155 6159 6 6152 6153 6155 6156 6442 6443 6 6154 6153 6156 6157 6158 6159 6 6154 6155 6157 6445 6443 6446 6 6156 6155 6158 5970 6446 5969 6 6157 6155 6159 6160 5969 6164 6 6158 6155 6153 6160 6161 6126 6 6158 6159 6161 6162 6163 6164 6 6160 6159 6126 6162 6124 6166 6 6160 6161 6163 5955 6165 6166 6 6160 6162 6164 5968 5956 5955 5 6160 6163 5968 6158 5969 6 5955 6162 6166 6167 5952 5953 7 6165 6162 6167 6120 6119 6124 6161 6 6165 6166 6120 6121 5951 5952 6 5995 5996 5987 6169 6170 5999 6 5987 6168 6170 6644 5986 9784 6 6169 6168 5999 6001 6171 9784 7 6170 6001 6002 6172 6790 9784 9783 7 6171 6002 6006 6173 6789 6787 6790 6 6172 6006 6007 6174 6175 6789 6 6173 6007 6175 6176 6011 6180 6 6173 6174 6176 6177 6785 6789 6 6175 6174 6177 6178 6179 6180 6 6175 6176 6178 6783 6782 6785 6 6177 6176 6179 9797 6783 9798 6 6178 6176 6180 6181 6182 9797 6 6179 6176 6181 6013 6011 6174 6 6179 6180 6182 6183 6187 6013 6 6179 6181 6183 6184 9797 9800 6 6182 6181 6184 6185 6186 6187 6 6182 6183 6185 6363 6646 9800 6 6184 6183 6186 6363 6364 6368 6 6185 6183 6187 6188 6189 6368 6 6186 6183 6181 6188 6013 6014 6 6186 6187 6189 6190 6191 6014 6 6186 6188 6190 6368 6369 6370 6 6189 6188 6191 6370 6373 6193 6 6190 6188 6014 6015 6192 6193 6 6191 6015 6017 6193 6194 6195 6 6191 6192 6194 6373 6190 6374 6 6193 6192 6195 6383 6374 6204 6 6194 6192 6017 6196 6197 6204 6 6195 6017 6197 6198 6199 6018 6 6195 6196 6198 6201 6202 6204 6 6197 6196 6199 5793 5794 6201 6 6198 6196 6018 6010 6200 5793 6 6199 6010 5793 5791 5790 5789 6 6198 5794 6197 6202 6203 6222 6 6197 6201 6203 6204 6205 6206 6 6202 6201 6206 6207 6221 6222 6 6197 6202 6205 6383 6194 6195 6 6204 6202 6206 6383 6460 6382 6 6205 6202 6203 6207 6208 6460 6 6206 6203 6208 6209 6210 6221 6 6206 6207 6209 6211 6212 6460 6 6208 6207 6210 6211 6215 6218 6 6209 6207 5803 6218 6219 6221 6 6208 6209 6212 6213 6214 6215 6 6208 6211 6213 6457 6459 6460 7 6212 6211 6214 6224 6225 6455 6457 5 6213 6211 6215 6216 6224 6 6214 6211 6209 6216 6217 6218 7 6214 6215 6217 5826 6022 6223 6224 5 6216 6215 6218 5825 5826 7 6217 6215 5825 5804 5803 6210 6209 6 5803 6210 5800 5798 6220 6221 6 5798 6219 6221 6222 5795 5796 6 6220 6219 6210 6207 6203 6222 6 6220 6221 6203 6201 5794 5795 5 6216 6022 6023 6026 6224 7 6216 6223 6214 6213 6225 6226 6026 7 6213 6224 6226 6455 6232 6227 6229 5 6225 6224 6026 6027 6227 6 6226 6027 6033 6228 6229 6225 6 6227 6033 6229 6230 6239 6240 6 6227 6228 6230 6231 6232 6225 6 6229 6228 6231 6238 6235 6239 6 6229 6230 6232 6233 6234 6235 6 6229 6231 6233 6455 6225 6456 6 6232 6231 6234 6456 6461 6462 6 6233 6231 6235 6236 6462 6463 6 6234 6231 6236 6237 6238 6230 6 6234 6235 6237 6463 6464 6472 6 6236 6235 6238 6474 6472 6477 6 6237 6235 6230 6239 6477 6242 6 6238 6230 6228 6240 6241 6242 6 6239 6228 6241 6248 6032 6033 6 6239 6240 6242 6243 6244 6248 6 6239 6241 6243 6477 6238 6478 6 6242 6241 6244 6245 6478 6480 6 6243 6241 6245 6246 6247 6248 6 6243 6244 6246 6482 6480 6483 6 6245 6244 6247 6483 6254 6252 6 6246 6244 6248 6034 6249 6252 6 6247 6244 6241 6240 6032 6034 6 6247 6034 6035 6250 6251 6252 6 6249 6035 6036 6251 6264 6256 6 6249 6250 6252 6253 6255 6256 6 6249 6251 6253 6254 6246 6247 6 6252 6251 6254 6255 6485 6486 6 6252 6253 6483 6246 6484 6485 6 6253 6251 6256 6257 6258 6486 6 6255 6251 6257 6264 6261 6250 6 6255 6256 6258 6259 6260 6261 6 6255 6257 6259 6486 6494 6495 6 6258 6257 6260 6495 6496 6497 7 6259 6257 6261 6262 6497 6274 6268 6 6260 6257 6262 6263 6264 6256 6 6260 6261 6263 6046 6267 6268 6 6262 6261 6264 6265 6266 6046 6 6263 6261 6265 6256 6250 6036 6 6263 6264 6266 6036 6041 6037 5 6263 6265 6046 6044 6041 6 6046 6262 6268 6269 6270 6047 6 6262 6267 6269 6273 6274 6260 6 6268 6267 6270 6271 6272 6273 6 6269 6267 6047 6271 6280 6281 6 6269 6270 6272 6278 6279 6280 6 6269 6271 6273 6276 6277 6278 6 6269 6272 6268 6274 6275 6276 6 6268 6273 6275 6497 6260 6498 6 6274 6273 6276 6501 6498 6502 6 6275 6273 6272 6277 6502 6503 6 6276 6272 6278 6503 6504 6505 6 6277 6272 6271 6279 6505 6506 7 6278 6271 6280 6055 6282 6283 6506 5 6279 6271 6270 6281 6055 6 6280 6270 6047 6055 6052 6048 5 6279 6055 6283 6284 6056 6 6279 6282 6284 6507 6506 6508 6 6283 6282 6056 6285 6508 6286 6 6284 6056 6057 6058 6061 6286 6 6285 6061 6287 6508 6284 6509 7 6286 6061 6288 6509 6329 6512 6291 6 6287 6061 6059 6289 6290 6291 6 6288 6059 6060 6062 6064 6290 5 6288 6289 6291 6292 6064 5 6288 6290 6292 6329 6287 7 6291 6290 6064 6293 6327 6328 6329 6 6292 6064 6065 6069 6294 6327 6 6293 6069 6295 6296 6326 6327 6 6294 6069 6070 6296 6297 6072 6 6294 6295 6297 6300 6325 6326 6 6296 6295 6072 6298 6299 6300 6 6297 6072 6074 6079 6081 6299 6 6298 6081 6297 6300 6301 6302 5 6297 6299 6301 6325 6296 6 6300 6299 6302 6304 6324 6325 6 6301 6299 6081 6082 6303 6304 6 6302 6082 6304 6305 6309 6315 6 6302 6303 6305 6306 6324 6301 6 6304 6303 6306 6307 6308 6309 6 6304 6305 6307 6324 6338 6339 6 6306 6305 6308 6339 6342 6343 6 6307 6305 6309 6310 6343 6344 6 6308 6305 6303 6310 6311 6315 6 6308 6309 6311 6312 6344 6347 6 6310 6309 6312 6313 6314 6315 6 6310 6311 6313 6322 6323 6347 6 6312 6311 6314 6316 6317 6322 6 6313 6311 6315 6083 6085 6316 6 6314 6311 6083 6082 6303 6309 6 6314 6085 6313 6317 6318 6319 6 6313 6316 6318 6320 6321 6322 6 6317 6316 6319 3770 1572 6320 5 6318 6316 3770 6085 6089 5 6318 1572 1573 6321 6317 7 6320 1573 1574 6317 6322 6323 6361 5 6317 6321 6323 6313 6312 7 6322 6321 6312 6348 6347 6349 6361 6 6304 6306 6301 6325 6336 6338 7 6301 6324 6300 6296 6326 6337 6336 6 6296 6325 6294 6327 6337 6332 6 6294 6326 6293 6292 6328 6332 6 6292 6327 6329 6330 6331 6332 6 6292 6328 6330 6512 6287 6291 6 6329 6328 6331 6511 6512 6520 7 6330 6328 6332 6333 6334 6520 6519 6 6331 6328 6333 6337 6326 6327 6 6331 6332 6334 6335 6336 6337 5 6331 6333 6335 6519 6521 6 6334 6333 6336 6521 6529 6530 7 6335 6333 6337 6325 6324 6338 6530 5 6336 6333 6332 6326 6325 6 6336 6324 6306 6339 6340 6530 6 6338 6306 6307 6340 6341 6342 6 6338 6339 6341 6531 6528 6530 5 6340 6339 6342 6546 6531 6 6341 6339 6307 6343 6547 6546 6 6342 6307 6308 6344 6345 6547 6 6343 6308 6345 6346 6347 6310 6 6343 6344 6346 6547 6544 6548 6 6345 6344 6347 6348 6550 6548 6 6346 6344 6348 6323 6312 6310 6 6346 6347 6323 6349 6350 6550 6 6348 6323 6350 6351 6360 6361 6 6348 6349 6351 6352 6551 6550 6 6350 6349 6352 6353 6354 6360 6 6350 6351 6353 6553 6551 6554 6 6352 6351 6354 6355 6356 6554 6 6353 6351 6355 1590 2477 6360 7 6353 6354 6356 6357 1595 1591 1590 6 6353 6355 6357 6358 6554 6555 5 6356 6355 6358 6359 1595 6 6356 6357 6359 6555 6556 3972 6 6358 6357 1595 3972 3971 1596 6 2477 6354 6351 6349 6361 6362 6 6360 6349 6362 1574 6321 6323 5 6360 6361 1574 2476 2477 6 6184 6185 6364 6365 6645 6646 6 6363 6185 6365 6366 6367 6368 6 6363 6364 6366 6645 6649 6650 6 6365 6364 6367 9728 9674 6650 6 6366 6364 6368 9728 9729 6369 6 6367 6364 6185 6186 6189 6369 6 6368 6189 6370 6371 9729 6367 6 6369 6189 6190 6371 6372 6373 6 6369 6370 6372 9729 9730 9731 6 6371 6370 6373 6375 6376 9731 6 6372 6370 6190 6193 6374 6375 6 6373 6193 6375 6383 6381 6194 6 6373 6374 6372 6376 6377 6381 6 6372 6375 6377 6378 6468 9731 6 6376 6375 6378 6379 6380 6381 5 6376 6377 6379 9694 6468 7 6378 6377 6380 6458 6456 6461 9694 6 6379 6377 6381 6382 6458 6459 6 6380 6377 6382 6383 6374 6375 6 6380 6381 6383 6460 6459 6205 6 6382 6381 6374 6194 6204 6205 7 6096 6097 6385 9704 5862 5861 5859 5 6384 6097 6099 5857 5859 6 5852 6105 6387 6946 5851 6947 7 6386 6105 6106 6107 6388 6947 6948 5 6387 6107 6110 6389 6948 6 6388 6110 6111 6390 6948 6949 6 6389 6111 6391 6392 6949 6950 6 6390 6111 6392 6393 6394 6112 6 6390 6391 6393 6395 6396 6950 6 6392 6391 6394 6395 9738 6399 6 6393 6391 6112 6113 6116 9738 6 6392 6393 6396 6397 6398 6399 6 6392 6395 6397 6950 6951 6952 6 6396 6395 6398 6952 6953 6400 6 6397 6395 6399 6134 6136 6400 6 6398 6395 6134 6133 9738 6393 6 6398 6136 6401 6953 6397 6954 6 6400 6136 6137 6402 6954 6955 6 6401 6137 6139 6403 6955 6961 6 6402 6139 6141 6404 6961 6411 6 6403 6141 6143 6405 6409 6411 6 6404 6143 6406 6407 6408 6409 6 6405 6143 6144 6407 6437 6435 6 6405 6406 6408 6432 6430 6435 6 6405 6407 6409 6410 6429 6430 6 6405 6408 6410 6404 6411 6412 6 6409 6408 6412 6413 6414 6429 6 6404 6409 6412 6960 6961 6403 6 6411 6409 6410 6413 6960 6962 6 6412 6410 6414 6415 6964 6962 6 6413 6410 6415 6416 6428 6429 6 6413 6414 6416 6417 6964 6965 6 6415 6414 6417 6418 6419 6428 6 6415 6416 6418 6559 6560 6965 6 6417 6416 6419 6420 6559 6566 6 6418 6416 6420 6421 6428 6425 6 6418 6419 6421 6422 6574 6566 6 6420 6419 6422 6423 6424 6425 6 6420 6421 6423 6574 6573 6575 6 6422 6421 6424 6581 6578 6575 6 6423 6421 6425 6426 6581 6582 6 6424 6421 6426 6427 6428 6419 6 6424 6425 6427 6585 6582 6431 6 6426 6425 6428 6429 6430 6431 6 6427 6425 6419 6416 6414 6429 6 6428 6414 6410 6408 6427 6430 6 6427 6429 6408 6431 6432 6407 6 6427 6430 6432 6433 6585 6426 6 6431 6430 6407 6433 6434 6435 6 6431 6432 6434 6585 6586 6587 6 6433 6432 6435 6436 6590 6587 6 6434 6432 6436 6437 6406 6407 6 6434 6435 6437 6438 6590 6591 6 6436 6435 6406 6438 6146 6144 6 6436 6437 6146 6439 6591 6592 6 6438 6146 6147 6440 6592 6593 6 6439 6147 6441 6596 6593 6444 6 6440 6147 6148 6442 6443 6444 6 6441 6148 6150 6152 6154 6443 6 6442 6154 6441 6444 6445 6156 6 6441 6443 6445 6596 6440 6454 6 6444 6443 6156 6446 6447 6454 6 6445 6156 6447 6448 5970 6157 6 6445 6446 6448 6450 6453 6454 6 6447 6446 5970 5971 6449 6450 5 6448 5971 5973 5976 6450 7 6449 5976 6448 6451 6452 6453 6447 7 6450 5976 5977 6452 6608 6599 6609 6 6450 6451 6453 6597 6598 6599 5 6450 6452 6447 6454 6597 6 6447 6453 6596 6444 6445 6597 5 6213 6225 6232 6456 6457 7 6455 6232 6457 6458 6379 6233 6461 6 6455 6456 6458 6459 6212 6213 5 6457 6456 6379 6380 6459 6 6458 6380 6457 6212 6460 6382 6 6212 6459 6208 6382 6205 6206 5 6456 6233 6462 9694 6379 6 6461 6233 6234 6463 6466 9694 6 6462 6234 6236 6464 6465 6466 6 6463 6236 6465 6470 6471 6472 6 6463 6464 6466 6467 6469 6470 6 6463 6465 6462 6467 6468 9694 6 6466 6465 6468 6469 9732 9733 7 6466 6467 9694 6378 6376 9731 9732 6 6467 6465 6470 7510 7511 9733 7 6469 6465 6464 6471 7508 7510 7507 6 6470 6464 6472 6473 7507 7506 6 6471 6464 6236 6473 6474 6237 6 6471 6472 6474 6475 7505 7506 6 6473 6472 6237 6475 6476 6477 7 6473 6474 6476 7504 7505 9693 9781 6 6475 6474 6477 6478 6479 9693 6 6476 6474 6237 6238 6242 6478 6 6477 6242 6243 6476 6479 6480 7 6476 6478 6480 6481 9693 9779 9780 6 6479 6478 6243 6481 6482 6245 6 6479 6480 6482 6488 9706 9779 6 6481 6480 6245 6483 6487 6488 6 6482 6245 6246 6254 6484 6487 5 6483 6254 6485 6487 6490 7 6484 6254 6253 6486 6490 6491 6492 7 6485 6253 6255 6258 6492 6493 6494 6 6483 6484 6482 6488 6489 6490 5 6482 6487 6489 9706 6481 7 6488 6487 6490 9705 2195 2196 9706 6 6489 6487 6484 6485 6491 9705 6 6490 6485 6492 2252 2253 9705 6 6491 6485 6486 6493 2252 9707 6 6492 6486 6494 9707 3336 9708 5 6493 6486 6258 6495 9708 6 6494 6258 6259 6496 9708 6500 6 6495 6259 6497 6498 6499 6500 5 6496 6259 6260 6274 6498 6 6497 6274 6496 6499 6501 6275 6 6496 6498 6500 2512 2513 6501 7 6496 6499 2512 3335 9708 3882 6495 6 2513 6499 6498 6275 6502 9711 6 6501 6275 6276 6503 9710 9711 6 6502 6276 6277 6504 9709 9710 6 6503 6277 6505 6513 9709 9712 6 6504 6277 6278 6506 6507 6513 5 6505 6278 6507 6283 6279 7 6505 6506 6283 6508 6513 6514 6510 6 6507 6283 6284 6286 6509 6510 6 6508 6286 6287 6510 6511 6512 6 6508 6509 6511 6514 6507 6515 7 6510 6509 6512 6330 6515 6516 6520 5 6511 6509 6330 6329 6287 6 6504 6505 6507 6514 9712 9718 5 6513 6507 6510 6515 9718 7 6514 6510 6511 6516 6517 9718 9719 6 6515 6511 6517 6518 6519 6520 6 6515 6516 6518 9719 9720 6523 6 6517 6516 6519 6521 6522 6523 6 6518 6516 6520 6331 6334 6521 5 6519 6516 6511 6330 6331 7 6519 6334 6335 6518 6522 6526 6529 6 6518 6521 6523 6524 6525 6526 7 6518 6522 6524 2215 9720 6517 2214 5 6523 6522 6525 2214 3349 7 6524 6522 6526 6527 3349 3348 6533 6 6525 6522 6521 6527 6528 6529 6 6525 6526 6528 6531 6532 6533 6 6527 6526 6529 6531 6340 6530 5 6528 6526 6521 6335 6530 6 6529 6335 6336 6340 6528 6338 7 6527 6528 6532 6341 6546 6340 6535 6 6527 6531 6533 3864 6534 6535 5 6527 6532 3864 3348 6525 6 3864 6532 6535 6536 6537 6717 6 6534 6532 6536 6545 6546 6531 6 6534 6535 6537 6538 6545 6542 6 6534 6536 6538 6539 6716 6717 6 6537 6536 6539 6540 6541 6542 7 6537 6538 6540 6715 3888 3887 6716 6 6539 6538 6541 6715 6719 6720 6 6540 6538 6542 6543 6720 6709 6 6541 6538 6543 6544 6545 6536 6 6541 6542 6544 6548 6549 6709 6 6543 6542 6545 6547 6345 6548 6 6544 6542 6536 6535 6546 6547 6 6545 6535 6547 6342 6341 6531 6 6545 6546 6544 6342 6343 6345 6 6544 6345 6543 6549 6550 6346 6 6543 6548 6550 6551 6552 6709 6 6549 6548 6346 6348 6551 6350 6 6549 6550 6552 6553 6352 6350 6 6549 6551 6553 6706 6708 6709 6 6552 6551 6352 6554 6555 6706 5 6553 6352 6353 6356 6555 6 6554 6356 6358 6556 6553 6706 7 6555 6358 3972 6706 6707 9748 3492 6 3970 1598 1599 6558 4039 3969 6 6557 1599 4039 3765 613 612 6 6417 6418 6560 6561 6565 6566 6 6417 6559 6561 6562 6965 6966 6 6560 6559 6562 6563 6564 6565 6 6560 6561 6563 6966 6967 6968 6 6562 6561 6564 6986 6984 6968 6 6563 6561 6565 6986 6987 6568 6 6564 6561 6559 6566 6567 6568 6 6565 6559 6418 6567 6574 6420 6 6565 6566 6568 6569 6570 6574 6 6565 6567 6569 6987 6564 6988 6 6568 6567 6570 6571 6991 6988 6 6569 6567 6571 6572 6573 6574 6 6569 6570 6572 6998 6991 6999 6 6571 6570 6573 6576 7002 6999 6 6572 6570 6574 6422 6575 6576 6 6573 6570 6567 6566 6420 6422 6 6573 6422 6576 6577 6578 6423 6 6573 6575 6577 7004 7002 6572 6 6576 6575 6578 6579 7004 7005 6 6577 6575 6579 6580 6581 6423 6 6577 6578 6580 7005 7006 7007 6 6579 6578 6581 7007 7008 6583 6 6580 6578 6423 6424 6582 6583 6 6581 6424 6583 6584 6585 6426 6 6581 6582 6584 7008 6580 7009 6 6583 6582 6585 6721 7009 6586 6 6584 6582 6426 6431 6433 6586 6 6585 6433 6587 6588 6721 6584 6 6586 6433 6588 6589 6590 6434 6 6586 6587 6589 6721 6722 6729 6 6588 6587 6590 6729 6730 6731 6 6589 6587 6434 6436 6591 6731 6 6590 6436 6438 6592 6731 6732 6 6591 6438 6439 6593 6594 6732 6 6592 6439 6594 6595 6596 6440 6 6592 6593 6595 6732 6733 6734 7 6594 6593 6596 6601 6734 6598 6597 6 6595 6593 6440 6444 6454 6597 6 6596 6454 6453 6452 6598 6595 6 6597 6452 6599 6600 6601 6595 6 6598 6452 6600 6607 6608 6451 6 6598 6599 6601 6602 6603 6607 5 6598 6600 6602 6734 6595 6 6601 6600 6603 6604 6735 6734 6 6602 6600 6604 6605 6606 6607 7 6602 6603 6605 6735 6736 6737 6738 5 6604 6603 6606 6738 6739 7 6605 6603 6607 6739 6740 6749 6746 6 6606 6603 6600 6599 6608 6749 6 6607 6599 6451 6609 6748 6749 6 6608 6451 5977 6610 6611 6748 6 6609 5977 5978 6611 6612 6613 6 6609 6610 6612 6748 6747 6750 6 6611 6610 6613 6620 6621 6750 6 6612 6610 5978 6614 6617 6620 6 6613 5978 5979 6615 6616 6617 6 6614 5979 6616 6640 6641 5980 6 6614 6615 6617 6618 6639 6640 6 6614 6616 6618 6619 6620 6613 6 6617 6616 6619 6637 6638 6639 6 6617 6618 6620 6622 6623 6637 6 6617 6619 6613 6612 6621 6622 6 6612 6620 6622 6751 6750 6627 6 6621 6620 6619 6623 6624 6627 6 6622 6619 6624 6625 6636 6637 6 6622 6623 6625 6626 6627 6628 6 6624 6623 6626 6634 6635 6636 6 6624 6625 6628 6629 6633 6634 6 6622 6624 6628 6751 6621 6752 6 6627 6624 6626 6629 6630 6752 6 6628 6626 6630 6631 6632 6633 6 6628 6629 6631 6757 6754 6752 6 6630 6629 6632 6757 6758 6759 6 6631 6629 6633 6759 6767 6768 6 6632 6629 6626 6634 6768 6769 6 6633 6626 6625 6635 6769 6770 6 6634 6625 6636 6770 6771 6772 6 6635 6625 6623 6637 9786 6772 6 6636 6623 6619 6618 6638 9786 6 6637 6618 6639 6786 6784 9786 6 6638 6618 6616 6640 9778 6786 6 6639 6616 6615 6641 9778 6643 6 6640 6615 5980 5982 6642 6643 6 6641 5982 5984 6643 6644 5986 7 6641 6642 6644 9778 6640 6788 9783 6 6643 6642 5986 6169 9783 9784 6 6363 6365 6646 6647 6648 6649 6 6363 6645 6184 6647 9725 9800 6 6646 6645 6648 9724 9725 6656 6 6647 6645 6649 6653 6655 6656 6 6648 6645 6365 6650 6651 6653 6 6649 6365 6651 6652 9674 6366 6 6649 6650 6652 6653 6654 9671 6 6651 6650 9671 9672 9673 9674 6 6649 6651 6654 6648 6655 3174 6 6653 6651 9671 9692 3173 3174 6 6648 6653 3174 6656 3451 3176 6 6648 6655 3451 6657 9724 6647 6 6656 3451 6658 6659 9722 9724 6 6657 3451 6659 3180 6660 6668 6 6657 6658 6668 6669 6670 9722 6 6658 3180 6661 6664 6665 6668 6 6660 3180 3179 6662 6663 6664 6 6661 3179 3181 2859 2860 6663 5 6661 6662 6664 6667 2860 6 6661 6663 6660 6665 6666 6667 6 6660 6664 6666 6668 6669 6673 7 6665 6664 6667 6673 6674 4565 4564 6 6666 6664 6663 4564 6675 2860 5 6660 6665 6669 6659 6658 7 6668 6665 6659 6670 6671 6672 6673 6 6659 6669 6671 6775 6776 9722 6 6670 6669 6672 6774 6773 6775 6 6671 6669 6673 6674 6791 6774 5 6672 6669 6665 6666 6674 5 6673 6666 4565 6672 6791 6 4564 6667 4562 6676 2861 2860 6 4562 6675 2861 6677 4561 9793 6 6676 2861 2854 2855 6678 9793 6 6677 2855 6679 6680 6682 9793 5 6678 2855 6680 6681 2856 6 6678 6679 6681 6682 6683 6684 6 6680 6679 6686 6684 6687 2856 6 6678 6680 6683 9751 9762 9793 6 6682 6680 6684 5157 5158 9751 6 6683 6680 5157 6685 6686 6681 6 5157 6684 6686 6693 6694 6695 6 6685 6684 6681 6687 6688 6693 6 6686 6681 6688 6689 6690 2856 6 6686 6687 6689 6693 6697 6700 6 6688 6687 6690 6691 6700 6701 6 6689 6687 6691 6692 2857 2856 6 6689 6690 6692 6701 6703 2552 5 6691 6690 2857 2551 2552 6 6686 6688 6685 6694 6696 6697 6 6685 6693 6695 4524 4523 6696 5 6685 6694 4524 4533 5157 6 4523 6694 6693 6697 6698 6705 6 6696 6693 6688 6698 6699 6700 7 6696 6697 6699 6704 3506 3507 6705 6 6698 6697 6700 6701 6702 6704 5 6699 6697 6688 6689 6701 7 6700 6689 6691 6699 6702 2223 6703 6 6699 6701 2223 65 66 6704 5 2223 6701 6691 2552 2222 6 6699 6702 66 67 6698 3506 5 6698 3507 3508 4523 6696 7 6553 6555 6556 6707 6552 6708 9750 6 6706 6556 9748 3503 9749 9750 6 6552 6706 6709 6710 6711 9750 7 6552 6708 6710 6720 6541 6549 6543 6 6709 6708 6711 6712 6719 6720 7 6710 6708 6712 6713 3504 9749 9750 7 6710 6711 6713 3118 3120 6714 6719 6 6712 6711 3504 3505 3117 3118 6 6712 3120 3122 3888 6715 6719 5 6714 3888 6539 6540 6719 6 6539 3887 6537 6717 3863 6718 5 6537 6716 6534 3864 3863 6 3863 6716 3862 3343 3886 3887 6 6715 6540 6714 6712 6710 6720 5 6719 6540 6541 6710 6709 6 6586 6588 6722 6723 7009 6584 6 6721 6588 6723 6724 6728 6729 6 6721 6722 6724 6725 7010 7009 6 6723 6722 6725 6726 6727 6728 6 6723 6724 6726 7010 7011 7012 6 6725 6724 6727 7023 7012 7024 6 6726 6724 6728 7024 7027 7028 6 6727 6724 6722 6729 7028 7031 6 6728 6722 6588 6589 6730 7031 6 6729 6589 6731 7031 7032 7033 6 6730 6589 6590 6591 6732 7033 6 6731 6591 6592 6594 6733 7033 6 6732 6594 6734 6735 7033 7034 6 6733 6594 6735 6602 6601 6595 6 6733 6734 6602 6604 6736 7034 6 6735 6604 6737 7034 7035 7036 6 6736 6604 6738 6741 7036 7037 5 6737 6604 6605 6739 6741 7 6738 6605 6606 6740 6741 6742 6743 6 6739 6606 6743 6744 6745 6746 6 6737 6738 6739 6742 7037 7038 6 6741 6739 6743 7038 7039 7040 6 6742 6739 6740 6744 7040 7041 7 6743 6740 6745 7041 7042 6755 7043 5 6744 6740 6746 6747 7043 6 6745 6740 6747 6748 6749 6606 7 6745 6746 6748 6611 6750 6751 7043 6 6747 6746 6749 6608 6609 6611 5 6748 6746 6608 6606 6607 5 6747 6611 6751 6621 6612 7 6747 6750 6621 6627 6752 6753 7043 6 6751 6627 6753 6754 6630 6628 5 6751 6752 6754 6755 7043 6 6753 6752 6755 6756 6757 6630 7 6753 6754 6756 7042 6744 7043 7142 5 6755 6754 6757 7142 6760 6 6756 6754 6630 6631 6758 6760 6 6757 6631 6759 6760 6761 6762 6 6758 6631 6632 6762 6763 6767 6 6757 6758 6761 7142 6756 7143 6 6760 6758 6762 7143 7144 7145 6 6761 6758 6759 6763 6764 7145 6 6762 6759 6764 4560 6765 6767 6 6762 6763 4560 4552 7145 4551 6 4560 6763 4559 4566 6766 6767 5 4566 6765 6767 6791 6768 6 6766 6765 6763 6759 6632 6768 6 6767 6632 6633 6769 6791 6766 6 6768 6633 6634 6770 6774 6791 6 6769 6634 6635 6771 6773 6774 6 6770 6635 6772 6773 6778 6779 6 6771 6635 6779 6780 6636 9786 6 6770 6771 6774 6671 6775 6778 6 6770 6773 6671 6672 6791 6769 6 6671 6773 6670 6776 6777 6778 6 6670 6775 6777 9722 9723 9799 7 6776 6775 6778 6779 6781 9798 9799 5 6777 6775 6773 6771 6779 6 6778 6771 6772 6780 6781 6777 6 6779 6772 6781 6782 6784 9786 6 6779 6780 6782 6783 6777 9798 6 6781 6780 6783 6177 6784 6785 5 6781 6782 6177 6178 9798 6 6782 6780 6785 6786 6638 9786 7 6782 6784 6177 6175 6786 6787 6789 7 6785 6784 6787 6788 9778 6639 6638 6 6785 6786 6788 6789 6172 6790 6 6787 6786 9778 6643 9783 6790 5 6785 6787 6172 6173 6175 5 6172 6787 6171 6788 9783 8 6672 6674 6774 4565 4566 6766 6769 6768 6 5419 5420 6793 7332 7333 7334 6 6792 5420 5421 5429 6794 7334 6 6793 5429 5430 6795 7334 7335 6 6794 5430 5431 6796 7335 7336 6 6795 5431 5433 5434 6797 7336 6 6796 5434 5435 6798 7336 7337 6 6797 5435 5436 6799 7337 7338 6 6798 5436 5437 6800 7338 7339 6 6799 5437 5438 6801 7339 7340 6 6800 5438 5439 6802 7340 7341 6 6801 5439 6803 7341 7342 7343 6 6802 5439 5440 5441 6804 7343 6 6803 5441 5442 6805 7343 7344 6 6804 5442 5443 6806 7344 7345 6 6805 5443 5445 6807 7345 7346 6 6806 5445 5446 6808 7346 7347 6 6807 5446 5447 6809 7347 7348 6 6808 5447 6810 7348 7349 7350 6 6809 5447 5448 6811 7350 6812 5 6810 5448 5218 5219 6812 6 6811 5219 5220 6813 7350 6810 5 6812 5220 6814 7350 7351 6 6813 5220 5221 6815 7351 7352 7 6814 5221 5222 5223 6816 7352 7353 5 6815 5223 6817 7353 7354 7 6816 5223 5224 5225 6818 7354 7355 5 6817 5225 6819 7355 7356 6 6818 5225 6820 7356 7357 7358 6 6819 5225 5226 5227 6821 7358 5 6820 5227 5228 6822 7358 6 6821 5228 6823 7358 7359 7360 7 6822 5228 5229 5230 6824 7360 7361 5 6823 5230 6825 6826 7361 5 6824 5230 6826 6827 5168 7 6824 6825 6827 6828 6829 7363 7361 5 6826 6825 5168 5169 6828 6 6827 5169 6826 6829 6830 6831 6 6826 6828 6830 7363 7364 7365 6 6829 6828 6831 7365 7366 7367 6 6830 6828 5169 5170 6832 7367 7 6831 5170 6833 7367 7368 7369 6835 5 6832 5170 6834 5239 6835 5 6833 5170 5239 5019 5024 6 6833 5239 5240 6836 7369 6832 6 6835 5240 5649 6837 7376 7369 7 6836 5649 6838 7376 7375 7377 7378 6 6837 5649 5650 5652 6839 7378 6 6838 5652 6840 7378 7379 7380 6 6839 5652 5653 6841 6842 7380 6 6840 5653 5654 5248 6842 5249 6 6840 6841 5249 6843 7380 7381 6 6842 5249 5250 6844 7381 7382 6 6843 5250 6845 7382 7383 7384 6 6844 5250 5029 5030 6846 7384 6 6845 5030 5031 6847 6848 7384 6 6846 5031 6848 6849 6850 5032 6 6846 6847 6849 7385 7384 7386 6 6848 6847 6850 7386 7387 7388 6 6849 6847 5032 5033 6851 7388 6 6850 5033 5034 5035 6852 7388 6 6851 5035 6853 7388 7389 6855 6 6852 5035 5036 5039 6854 6855 6 6853 5039 6855 6856 6857 5040 6 6853 6854 6856 7389 6852 7390 6 6855 6854 6857 6858 6860 7390 6 6856 6854 5040 6858 6859 5042 6 6856 6857 6859 6860 6861 6862 6 6858 6857 5042 6862 6863 6864 6 6856 6858 6861 7390 7391 7398 6 6860 6858 6862 7398 7399 7400 6 6861 6858 6859 6863 7400 7401 6 6862 6859 6864 6865 6866 7401 6 6863 6859 6865 5043 6880 5042 6 6863 6864 6866 6867 6880 6874 6 6863 6865 6867 6868 7401 7402 6 6866 6865 6868 6869 6873 6874 6 6866 6867 6869 6870 7402 7403 6 6868 6867 6870 6871 6872 6873 6 6868 6869 6871 7406 7403 7407 6 6870 6869 6872 7413 7407 7414 6 6871 6869 6873 7420 7417 7414 6 6872 6869 6867 6874 6875 7420 6 6873 6867 6875 6876 6865 6880 6 6873 6874 6876 6877 7420 7419 6 6875 6874 6877 6878 6879 6880 6 6875 6876 6878 6884 6885 7419 6 6877 6876 6879 6881 6883 6884 6 6878 6876 6880 6881 5044 5043 6 6879 6876 5043 6864 6865 6874 6 6878 6879 5044 5046 6882 6883 6 6881 5046 6883 6888 6889 6890 6 6881 6882 6878 6884 6887 6888 6 6878 6883 6877 6885 6886 6887 6 6877 6884 6886 7419 7421 7427 6 6885 6884 6887 7427 7428 7429 6 6886 6884 6883 6888 7429 7430 6 6887 6883 6882 6889 7430 7431 6 6888 6882 6890 6891 7431 7434 6 6889 6882 5046 6891 4646 4645 6 6889 6890 4646 4647 6892 7434 6 6891 4647 4648 6893 7434 6894 6 6892 4648 4254 4255 4731 6894 6 6893 4731 6895 7434 6892 7433 6 6894 4731 4732 6896 6898 7433 6 6895 4732 6897 6898 6899 6900 6 6896 4732 4733 6900 6901 6902 6 6895 6896 6899 7433 7432 7435 6 6898 6896 6900 7435 7436 7437 6 6899 6896 6897 6901 7437 7438 6 6900 6897 6902 7438 6905 6904 6 6901 6897 4733 4263 6903 6904 6 6902 4263 4264 4265 5232 6904 6 6903 5232 5459 6905 6901 6902 6 6904 5459 5460 6906 7438 6901 6 6905 5460 6907 7438 7439 7440 6 6906 5460 5461 6908 7440 7441 6 6907 5461 5462 6909 7263 7441 6 6908 5462 5463 6910 7263 7264 6 6909 5463 6911 7264 7265 6912 6 6910 5463 5464 5465 5466 6912 6 6911 5466 6913 7265 6910 7266 6 6912 5466 5467 6914 7266 7267 6 6913 5467 5468 6915 7267 7268 6 6914 5468 6916 7268 7269 7270 6 6915 5468 5469 6917 6918 7270 6 6916 5469 5470 5471 5472 6918 6 6916 6917 5472 6919 7270 7271 6 6918 5472 5473 6920 7271 7272 6 6919 5473 5474 6921 7272 7273 6 6920 5474 5475 5476 6922 7273 6 6921 5476 6923 7275 7273 7276 6 6922 5476 5477 6924 7276 7277 6 6923 5477 5478 6925 7277 7278 6 6924 5478 5479 6926 7278 7279 6 6925 5479 5480 6927 7279 7280 6 6926 5480 5481 5655 6928 7280 6 6927 5655 5656 6929 7282 7280 6 6928 5656 6930 7282 7283 7284 6 6929 5656 5657 5658 6931 7284 6 6930 5658 6932 7284 7285 7286 6 6931 5658 5659 5832 6933 7286 6 6932 5832 6934 7286 7287 7288 6 6933 5832 5833 5841 6935 7288 6 6934 5841 5842 6936 6937 7288 6 6935 5842 5844 6937 6938 6019 6 6935 6936 6938 6939 7288 7289 6 6937 6936 6019 6939 6940 6941 6 6937 6938 6940 7289 7290 7291 6 6939 6938 6941 7291 7292 6942 6 6940 6938 6019 5846 5848 6942 6 6941 5848 6943 6944 7292 6940 6 6942 5848 6944 6945 6946 5849 6 6942 6943 6945 7292 7293 7294 6 6944 6943 6946 7294 7295 7296 7 6945 6943 5849 5851 6386 6947 7296 6 6946 6386 6387 6948 7296 7297 6 6947 6387 6388 6389 6949 7297 6 6948 6389 6390 6950 7297 7298 7 6949 6390 6392 6396 6951 7298 7299 6 6950 6396 6952 7299 7301 7302 6 6951 6396 6397 6953 7044 7302 6 6952 6397 6400 6954 7044 7045 6 6953 6400 6401 6955 6956 7045 6 6954 6401 6402 6956 6957 6961 6 6954 6955 6957 6958 7045 7046 6 6956 6955 6958 6959 6960 6961 6 6956 6957 6959 7046 7049 7050 6 6958 6957 6960 6962 6963 7050 6 6959 6957 6961 6411 6412 6962 6 6960 6957 6955 6402 6403 6411 6 6960 6412 6959 6963 6964 6413 6 6959 6962 6964 7052 7050 7053 6 6963 6962 6413 6415 6965 7053 6 6964 6415 6417 6560 6966 7053 6 6965 6560 6562 6967 7053 6972 6 6966 6562 6968 6969 6971 6972 6 6967 6562 6969 6970 6563 6984 6 6967 6968 6970 6971 6975 6976 6 6969 6968 6982 6976 6983 6984 6 6967 6969 6972 6973 6974 6975 6 6967 6971 6973 7053 6966 7052 6 6972 6971 6974 7052 7051 7054 6 6973 6971 6975 7063 7054 7064 6 6974 6971 6969 6976 6977 7064 6 6975 6969 6977 6978 6982 6970 6 6975 6976 6978 6979 7064 7065 6 6977 6976 6979 6980 6981 6982 6 6977 6978 6980 7065 7066 7067 6 6979 6978 6981 7067 7068 7072 6 6980 6978 6982 7072 7073 7074 6 6981 6978 6976 6970 6983 7074 6 6982 6970 6984 6985 7074 7075 6 6983 6970 6985 6986 6563 6968 6 6983 6984 6986 7075 7076 7077 6 6985 6984 6563 6564 6987 7077 6 6986 6564 6568 6988 6989 7077 6 6987 6568 6989 6990 6991 6569 6 6987 6988 6990 6992 7077 7078 6 6989 6988 6991 6992 6993 6997 6 6990 6988 6997 6998 6571 6569 6 6989 6990 6993 6994 7078 7079 6 6992 6990 6994 6995 6996 6997 6 6992 6993 6995 7079 7082 7083 6 6994 6993 6996 7083 7086 7087 6 6995 6993 6997 7087 7088 7089 6 6996 6993 6990 6991 6998 7089 6 6997 6991 6571 6999 7000 7089 6 6998 6571 7000 7001 7002 6572 6 6998 6999 7001 7089 7090 7093 6 7000 6999 7002 7003 7093 7094 6 7001 6999 7003 7004 6576 6572 6 7001 7002 7004 7094 7095 7096 6 7003 7002 6576 6577 7005 7096 6 7004 6577 6579 7006 7096 7097 6 7005 6579 7007 7097 7098 7099 6 7006 6579 6580 7008 7013 7099 6 7007 6580 6583 7009 7010 7013 6 7008 6583 7010 6723 6721 6584 6 7008 7009 6723 6725 7011 7013 6 7010 6725 7012 7013 7014 7015 6 7011 6725 7023 7021 7015 6726 6 7010 7011 7008 7007 7014 7099 6 7013 7011 7015 7016 7099 7100 6 7014 7011 7016 7017 7021 7012 6 7014 7015 7017 7018 7100 7101 6 7016 7015 7018 7019 7020 7021 6 7016 7017 7019 7108 7101 7114 6 7018 7017 7020 7115 7114 7116 6 7019 7017 7021 7022 7116 7117 6 7020 7017 7015 7022 7023 7012 6 7020 7021 7023 7025 7117 7118 6 7022 7021 7012 6726 7024 7025 6 7023 6726 6727 7025 7026 7027 6 7022 7023 7024 7026 7118 7119 6 7025 7024 7027 7119 7120 7121 6 7026 7024 6727 7028 7029 7121 6 7027 6727 6728 7029 7030 7031 6 7027 7028 7030 7123 7121 7124 6 7029 7028 7031 7124 7035 7032 6 7030 7028 6728 6729 6730 7032 6 7031 6730 7033 7035 7030 7034 6 7032 6730 6731 6732 6733 7034 6 7033 6733 6735 6736 7035 7032 6 7034 6736 7036 7124 7030 7032 5 7035 6736 6737 7037 7124 6 7036 6737 6741 7038 7124 7123 7 7037 6741 6742 7039 7123 7125 7126 6 7038 6742 7040 7136 7126 7137 6 7039 6742 6743 7041 7137 7138 6 7040 6743 6744 7042 7138 7139 5 7041 6744 6755 7142 7139 6 6755 6744 6745 6747 6751 6753 6 6952 6953 7045 7302 7303 7047 6 7044 6953 6954 6956 7046 7047 6 7045 6956 6958 7047 7048 7049 6 7045 7046 7048 7303 7044 7304 6 7047 7046 7049 7304 7057 7055 6 7048 7046 6958 7050 7051 7055 6 7049 6958 7051 7052 6963 6959 6 7049 7050 7052 6973 7054 7055 6 7051 7050 6963 7053 6972 6973 6 7052 6963 6964 6965 6966 6972 6 7051 6973 7055 7056 7063 6974 6 7051 7054 7056 7057 7048 7049 6 7055 7054 7057 7058 7059 7063 6 7055 7056 7058 7304 7048 7305 6 7057 7056 7059 7060 7308 7305 6 7058 7056 7060 7061 7062 7063 6 7058 7059 7061 7308 7477 7478 6 7060 7059 7062 7478 7479 7480 6 7061 7059 7063 7064 7065 7480 6 7062 7059 7056 7054 6974 7064 6 7063 6974 6975 6977 7062 7065 6 7062 7064 6977 6979 7066 7480 6 7065 6979 7067 7480 7481 7482 6 7066 6979 6980 7068 7069 7482 6 7067 6980 7069 7070 7071 7072 6 7067 7068 7070 7484 7482 7463 6 7069 7068 7071 7463 7485 7486 6 7070 7068 7072 7486 7487 7488 6 7071 7068 6980 6981 7073 7488 6 7072 6981 7074 7488 7489 7493 6 7073 6981 6982 6983 7075 7493 6 7074 6983 6985 7076 7494 7493 6 7075 6985 7077 7494 7080 7078 6 7076 6985 6986 6987 6989 7078 6 7077 6989 6992 7079 7080 7076 6 7078 6992 6994 7080 7081 7082 6 7078 7079 7081 7692 7494 7076 6 7080 7079 7082 7224 7225 7692 6 7081 7079 6994 7083 7084 7224 6 7082 6994 6995 7084 7085 7086 6 7082 7083 7085 7227 7224 7228 6 7084 7083 7086 7228 7229 7230 6 7085 7083 6995 7087 7233 7230 6 7086 6995 6996 7088 7233 7234 6 7087 6996 7089 7090 7091 7234 6 7088 6996 6997 6998 7000 7090 6 7089 7000 7088 7091 7092 7093 6 7088 7090 7092 7234 7235 7236 6 7091 7090 7093 7236 7237 7238 6 7092 7090 7000 7001 7094 7238 6 7093 7001 7003 7095 7238 7239 6 7094 7003 7096 7239 7240 7104 6 7095 7003 7004 7005 7097 7104 6 7096 7005 7006 7098 7103 7104 6 7097 7006 7099 7100 7102 7103 6 7098 7006 7007 7013 7014 7100 6 7099 7014 7016 7101 7102 7098 6 7100 7016 7102 7107 7108 7018 6 7100 7101 7098 7103 7106 7107 6 7098 7102 7097 7104 7105 7106 6 7097 7103 7105 7240 7095 7096 6 7104 7103 7106 7242 7240 7243 6 7105 7103 7102 7107 7243 7244 6 7106 7102 7101 7108 7109 7244 6 7107 7101 7018 7109 7110 7114 6 7107 7108 7110 7111 7244 7245 6 7109 7108 7111 7112 7113 7114 6 7109 7110 7112 7248 7245 7249 6 7111 7110 7113 7249 7250 7251 6 7112 7110 7114 7115 7251 7252 6 7113 7110 7115 7019 7018 7108 6 7113 7114 7019 7116 7252 7255 6 7115 7019 7020 7117 7255 7256 6 7116 7020 7022 7118 7259 7256 6 7117 7022 7025 7119 7259 7260 6 7118 7025 7026 7120 7260 7129 6 7119 7026 7121 7122 7128 7129 6 7120 7026 7122 7123 7029 7027 6 7120 7121 7123 7125 7127 7128 7 7122 7121 7029 7124 7037 7038 7125 6 7123 7029 7030 7035 7036 7037 5 7123 7038 7126 7127 7122 5 7125 7038 7127 7136 7039 7 7125 7126 7122 7128 7131 7132 7136 6 7122 7127 7120 7129 7130 7131 6 7120 7128 7130 7262 7260 7119 6 7129 7128 7131 7262 7533 7531 6 7130 7128 7127 7132 7133 7533 6 7131 7127 7133 7134 7135 7136 6 7131 7132 7134 7533 7532 7534 6 7133 7132 7135 7534 7535 7536 6 7134 7132 7136 7536 7537 7137 6 7135 7132 7127 7126 7039 7137 6 7136 7039 7040 7138 7537 7135 6 7137 7040 7041 7139 7140 7537 6 7138 7041 7140 7141 7142 7042 6 7138 7139 7141 7149 7151 7537 6 7140 7139 7142 7143 7148 7149 7 7141 7139 7042 6755 6756 6760 7143 6 7141 7142 6760 6761 7144 7148 6 7143 6761 7145 7146 7147 7148 7 7144 6761 7146 4553 4552 6764 6762 5 7144 7145 4553 4555 7147 6 7146 4555 4557 7144 7148 7149 5 7144 7147 7149 7141 7143 7 7148 7147 4557 7141 7140 7150 7151 6 7149 4557 7151 7152 7153 7154 6 7149 7150 7140 7152 7537 7536 6 7151 7150 7153 7536 7535 7538 6 7152 7150 7154 7155 7156 7538 6 7153 7150 7155 4650 4556 4557 6 7153 7154 7156 7157 7167 4650 6 7153 7155 7157 7158 7538 7539 6 7156 7155 7158 7159 7160 7167 6 7156 7157 7159 7539 7540 7555 6 7158 7157 7160 7161 7555 7556 6 7159 7157 7161 7162 7163 7167 6 7159 7160 7162 7164 7168 7556 6 7161 7160 7163 7164 4138 7165 5 7162 7160 7165 7166 7167 6 7161 7162 4138 7168 7169 4139 7 4138 7162 7163 7166 4414 4135 4136 5 7165 7163 4414 4416 7167 7 4416 7166 7163 7160 7157 7155 4650 6 7161 7164 7169 7556 7557 7561 7 7168 7164 4139 7170 7561 7562 7563 5 7169 4139 4140 7171 7563 7 7170 4140 4141 7172 7563 7564 7565 6 7171 4141 4125 7173 7174 7565 6 7172 4125 7174 7175 4123 9790 6 7172 7173 7175 7176 7177 7565 6 7174 7173 7176 9789 9788 9790 6 7174 7175 7177 7178 7179 9789 7 7174 7176 7178 7565 7564 7569 7570 6 7177 7176 7179 7180 7181 7570 6 7178 7176 7180 9789 3536 3538 6 7178 7179 7181 7182 7183 3538 6 7178 7180 7182 7571 7570 7572 6 7181 7180 7183 7572 7573 7574 6 7182 7180 3538 3539 7184 7574 6 7183 3539 7185 7576 7574 7188 6 7184 3539 3540 7186 7187 7188 6 7185 3540 7187 7212 7211 7213 6 7185 7186 7188 7189 7212 7193 6 7185 7187 7189 7190 7576 7184 6 7188 7187 7190 7191 7192 7193 6 7188 7189 7191 7576 7577 7580 6 7190 7189 7192 7194 7580 7581 6 7191 7189 7193 7194 7195 7199 6 7192 7189 7199 7200 7212 7187 6 7191 7192 7195 7196 7581 7582 6 7194 7192 7196 7197 7198 7199 6 7194 7195 7197 7582 7583 7584 6 7196 7195 7198 7584 3197 3196 6 7197 7195 7199 3196 7201 7204 6 7198 7195 7192 7193 7200 7201 6 7199 7193 7201 7202 7212 7209 6 7199 7200 7202 7203 7204 7198 6 7201 7200 7203 7207 7208 7209 6 7201 7202 7204 7205 7206 7207 6 7201 7203 7205 3195 3196 7198 6 7204 7203 7206 7221 7222 3195 6 7205 7203 7207 9746 7219 7221 6 7206 7203 7202 7208 9746 9747 6 7207 7202 7209 7210 9747 7214 6 7208 7202 7210 7211 7212 7200 6 7208 7209 7211 4374 4375 7214 6 7210 7209 7212 7186 7213 4374 6 7211 7209 7200 7193 7187 7186 6 7211 7186 3540 3541 4373 4374 6 7210 4375 4376 7215 9747 7208 6 7214 4376 4378 7216 7217 9747 6 7215 4378 7217 2864 1628 2863 6 7215 7216 2864 7218 9746 9747 6 7217 2864 2865 2866 7219 9746 6 7218 2866 7220 7221 7206 9746 5 7219 2866 7221 3215 2867 6 7219 7220 3215 7222 7206 7205 6 7221 3215 3216 7223 3195 7205 5 7222 3216 3217 3194 3195 6 7081 7082 7225 7226 7227 7084 6 7081 7224 7226 7692 7691 7693 6 7225 7224 7227 7693 7694 7675 6 7226 7224 7084 7228 7675 7695 6 7227 7084 7085 7229 7695 7696 6 7228 7085 7230 7231 7696 7697 6 7229 7085 7231 7232 7233 7086 6 7229 7230 7232 7697 7698 7702 6 7231 7230 7233 7702 7703 7704 6 7232 7230 7086 7087 7234 7704 6 7233 7087 7088 7091 7235 7704 6 7234 7091 7236 7719 7705 7704 6 7235 7091 7092 7237 7719 7718 6 7236 7092 7238 7718 7720 7721 6 7237 7092 7093 7094 7239 7721 6 7238 7094 7095 7240 7241 7721 6 7239 7095 7104 7241 7242 7105 6 7239 7240 7242 7721 7722 7723 6 7241 7240 7105 7243 7723 7726 6 7242 7105 7106 7244 7246 7726 6 7243 7106 7107 7109 7245 7246 6 7244 7109 7246 7247 7248 7111 6 7244 7245 7247 7729 7726 7243 6 7246 7245 7248 7965 7729 7966 6 7247 7245 7111 7249 7966 7967 6 7248 7111 7112 7250 7967 7968 6 7249 7112 7251 7512 7968 7969 6 7250 7112 7113 7252 7253 7512 6 7251 7113 7115 7253 7254 7255 6 7251 7252 7254 7512 7513 7517 6 7253 7252 7255 7257 9776 7517 6 7254 7252 7115 7116 7256 7257 6 7255 7116 7257 7258 7259 7117 6 7255 7256 7258 7524 7254 9776 6 7257 7256 7259 7261 7525 7524 6 7258 7256 7117 7118 7260 7261 6 7259 7118 7119 7261 7262 7129 6 7259 7260 7262 7530 7525 7258 6 7261 7260 7129 7130 7531 7530 6 6908 6909 7264 7441 7443 7444 6 7263 6909 6910 7265 7444 7445 6 7264 6910 6912 7266 7445 7446 6 7265 6912 6913 7267 7446 7447 6 7266 6913 6914 7268 7450 7447 6 7267 6914 6915 7269 7450 7451 6 7268 6915 7270 7451 7452 7453 6 7269 6915 6916 6918 7271 7453 6 7270 6918 6919 7272 7453 7454 6 7271 6919 6920 7273 7274 7454 6 7272 6920 7274 7275 6922 6921 6 7272 7273 7275 7454 7455 7456 6 7274 7273 6922 7276 7456 7457 6 7275 6922 6923 7277 7457 7458 6 7276 6923 6924 7278 7458 7459 6 7277 6924 6925 7279 7459 7460 6 7278 6925 6926 7280 7281 7460 6 7279 6926 7281 7282 6928 6927 6 7279 7280 7282 7460 7461 7465 6 7281 7280 6928 6929 7283 7465 6 7282 6929 7284 7465 7466 7467 6 7283 6929 6930 6931 7285 7467 6 7284 6931 7286 7467 7468 7469 6 7285 6931 6932 6933 7287 7469 6 7286 6933 7288 7469 7470 7289 6 7287 6933 6934 6935 6937 7289 6 7288 6937 6939 7290 7470 7287 6 7289 6939 7291 7470 7471 7472 6 7290 6939 6940 7292 7472 7473 6 7291 6940 6942 6944 7293 7473 6 7292 6944 7294 7473 7474 7475 6 7293 6944 6945 7295 7475 7300 6 7294 6945 7296 7298 7299 7300 6 7295 6945 6946 6947 7297 7298 5 7296 6947 6948 6949 7298 6 7297 6949 6950 7296 7295 7299 6 7295 7298 6950 6951 7300 7301 5 7295 7299 7301 7475 7294 7 7300 7299 6951 7302 7475 7306 7303 5 7301 6951 6952 7044 7303 6 7302 7044 7047 7304 7306 7301 6 7303 7047 7048 7057 7305 7306 6 7304 7057 7306 7307 7308 7058 6 7304 7305 7307 7475 7301 7303 6 7306 7305 7308 7475 7474 7476 6 7307 7305 7058 7060 7476 7477 5 4703 4704 7310 7856 7857 6 7309 4704 4705 7311 7857 7858 6 7310 4705 4706 7312 7858 7859 6 7311 4706 4707 7313 7859 7860 6 7312 4707 4708 5171 7314 7860 6 7313 5171 7315 7860 7861 7862 6 7314 5171 5172 7316 7862 7863 6 7315 5172 5173 7317 7863 7864 6 7316 5173 5174 7318 7864 7865 6 7317 5174 5175 7319 7865 7866 6 7318 5175 5176 7320 7866 7867 6 7319 5176 5177 7321 7867 7868 6 7320 5177 5178 5179 7322 7868 6 7321 5179 7323 7868 7869 7870 6 7322 5179 5180 7324 7870 7871 6 7323 5180 5181 5412 7325 7871 6 7324 5412 7326 7871 7872 7873 6 7325 5412 5413 7327 7873 7874 6 7326 5413 5414 5415 7328 7874 6 7327 5415 7329 7874 7875 7876 6 7328 5415 5416 5417 7330 7876 6 7329 5417 7331 7876 7877 7878 6 7330 5417 5418 5419 7332 7878 6 7331 5419 6792 7333 7878 7879 6 7332 6792 7334 7879 7880 7881 6 7333 6792 6793 6794 7335 7881 6 7334 6794 6795 7336 7881 7882 6 7335 6795 6796 6797 7337 7882 6 7336 6797 6798 7338 7882 7883 6 7337 6798 6799 7339 7883 7884 6 7338 6799 6800 7340 7884 7885 6 7339 6800 6801 7341 7885 7886 6 7340 6801 6802 7342 7886 7887 6 7341 6802 7343 7887 7888 7889 6 7342 6802 6803 6804 7344 7889 6 7343 6804 6805 7345 7889 7890 6 7344 6805 6806 7346 7890 7891 6 7345 6806 6807 7347 7891 7892 6 7346 6807 6808 7348 7892 7893 6 7347 6808 6809 7349 7893 7894 6 7348 6809 7350 7894 7895 7896 7 7349 6809 6810 6812 6813 7351 7896 6 7350 6813 6814 7352 7896 7897 6 7351 6814 6815 7353 7897 7898 5 7352 6815 6816 7354 7898 7 7353 6816 6817 7355 7898 7899 7900 5 7354 6817 6818 7356 7900 7 7355 6818 6819 7357 7900 7901 7902 6 7356 6819 7358 7902 7903 7904 7 7357 6819 6820 6821 6822 7359 7904 6 7358 6822 7360 7904 7905 7906 6 7359 6822 6823 7361 7362 7906 6 7360 6823 6824 7362 7363 6826 6 7360 7361 7363 7906 7907 7908 6 7362 7361 6826 6829 7364 7908 6 7363 6829 7365 7908 7909 7910 5 7364 6829 6830 7366 7910 7 7365 6830 7367 7370 7372 7910 7911 6 7366 6830 6831 6832 7368 7370 6 7367 6832 7369 7370 7371 7376 5 7368 6832 7376 6836 6835 6 7367 7368 7371 7366 7372 7373 6 7370 7368 7373 7374 7375 7376 6 7366 7370 7373 7911 7912 7913 6 7372 7370 7371 7374 7913 7914 6 7373 7371 7375 7914 7915 7916 6 7374 7371 7376 6837 7377 7916 6 7375 7371 7368 7369 6836 6837 6 7375 6837 7378 7916 7917 7918 6 7377 6837 6838 6839 7379 7918 5 7378 6839 7380 7602 7918 6 7379 6839 6840 6842 7381 7602 6 7380 6842 6843 7382 7602 7603 6 7381 6843 6844 7383 7606 7603 6 7382 6844 7384 7385 7606 7607 6 7383 6844 7385 6848 6846 6845 6 7383 7384 6848 7386 7607 7608 6 7385 6848 6849 7387 7608 7393 6 7386 6849 7388 7389 7392 7393 6 7387 6849 6850 6851 6852 7389 6 7388 6852 6855 7390 7392 7387 6 7389 6855 6856 6860 7391 7392 6 7390 6860 7392 7397 7394 7398 6 7390 7391 7389 7387 7393 7394 6 7387 7392 7394 7395 7608 7386 6 7393 7392 7395 7396 7397 7391 6 7393 7394 7396 7608 7609 7612 6 7395 7394 7397 7612 7613 7623 6 7396 7394 7391 7398 7623 7624 6 7397 7391 6860 6861 7399 7624 5 7398 6861 7400 7624 7625 6 7399 6861 6862 7401 7625 7626 7 7400 6862 6863 6866 7402 7626 7627 6 7401 6866 6868 7403 7404 7627 6 7402 6868 7404 7405 7406 6870 6 7402 7403 7405 7627 7628 7629 6 7404 7403 7406 7409 7629 7630 6 7405 7403 6870 7407 7408 7409 6 7406 6870 7408 7412 7413 6871 6 7406 7407 7409 7410 7411 7412 6 7406 7408 7405 7410 7633 7630 6 7409 7408 7411 7633 7634 7635 6 7410 7408 7412 7635 7636 7643 6 7411 7408 7407 7413 7643 7644 6 7412 7407 6871 7414 7415 7644 6 7413 6871 7415 7416 7417 6872 6 7413 7414 7416 7644 7645 7646 6 7415 7414 7417 7418 7646 7647 6 7416 7414 7418 7419 7420 6872 6 7416 7417 7419 7421 7422 7647 7 7418 7417 7420 6875 6877 6885 7421 5 7419 7417 6872 6873 6875 6 7419 6885 7418 7422 7423 7427 6 7418 7421 7423 7424 7647 7648 6 7422 7421 7424 7425 7426 7427 6 7422 7423 7425 7648 7649 7650 6 7424 7423 7426 7650 7651 7652 6 7425 7423 7427 7652 7653 7428 6 7426 7423 7421 6885 6886 7428 6 7427 6886 7429 7653 7426 7654 6 7428 6886 6887 7430 7654 7655 6 7429 6887 6888 7431 7432 7655 6 7430 6888 6889 7432 7433 7434 6 7430 7431 7433 6898 7435 7655 6 7432 7431 7434 6894 6895 6898 6 7433 7431 6889 6891 6892 6894 6 7432 6898 6899 7436 7656 7655 6 7435 6899 7437 7656 7657 7661 6 7436 6899 6900 7438 7661 7439 6 7437 6900 6901 6905 6906 7439 6 7438 6906 7440 7661 7437 7662 6 7439 6906 6907 7441 7442 7662 6 7440 6907 6908 7263 7442 7443 6 7440 7441 7443 7662 7663 7664 6 7442 7441 7263 7444 7664 7665 6 7443 7263 7264 7445 7665 7666 6 7444 7264 7265 7446 7666 7667 6 7445 7265 7266 7447 7448 7667 6 7446 7266 7448 7449 7450 7267 6 7446 7447 7449 7669 7667 7672 6 7448 7447 7450 7672 7677 7674 6 7449 7447 7267 7268 7451 7677 6 7450 7268 7269 7452 7677 7678 6 7451 7269 7453 7678 7679 7683 6 7452 7269 7270 7271 7454 7683 6 7453 7271 7272 7274 7455 7683 6 7454 7274 7456 7683 7682 7684 6 7455 7274 7275 7457 7687 7684 6 7456 7275 7276 7458 7687 7688 6 7457 7276 7277 7459 7688 7689 6 7458 7277 7278 7460 7689 7462 6 7459 7278 7279 7281 7461 7462 6 7460 7281 7462 7463 7464 7465 6 7460 7461 7463 7689 7459 7485 7 7462 7461 7464 7484 7069 7070 7485 6 7463 7461 7465 7484 7483 7466 6 7464 7461 7281 7282 7283 7466 6 7465 7283 7467 7483 7464 7495 6 7466 7283 7284 7285 7468 7495 6 7467 7285 7469 7495 7496 7497 6 7468 7285 7286 7287 7470 7497 6 7469 7287 7289 7290 7471 7497 6 7470 7290 7472 7497 7498 7499 6 7471 7290 7291 7473 7499 7476 6 7472 7291 7292 7293 7474 7476 5 7473 7293 7475 7307 7476 7 7474 7293 7294 7300 7301 7306 7307 7 7474 7307 7308 7477 7499 7472 7473 5 7476 7308 7060 7478 7499 6 7477 7060 7061 7479 7498 7499 7 7478 7061 7480 7481 7498 7496 7500 6 7479 7061 7062 7065 7066 7481 6 7479 7480 7066 7482 7483 7500 6 7481 7066 7483 7484 7069 7067 7 7481 7482 7484 7464 7466 7495 7500 5 7483 7482 7069 7463 7464 5 7463 7070 7486 7689 7462 6 7485 7070 7071 7487 7688 7689 6 7486 7071 7488 7687 7688 7686 7 7487 7071 7072 7073 7489 7490 7686 6 7488 7073 7490 7491 7492 7493 5 7488 7489 7491 7686 7685 6 7490 7489 7492 7685 7690 7691 6 7491 7489 7493 7494 7691 7692 6 7492 7489 7494 7075 7074 7073 6 7492 7493 7075 7076 7692 7080 6 7483 7466 7467 7468 7496 7500 6 7495 7468 7497 7498 7479 7500 6 7496 7468 7469 7470 7471 7498 6 7497 7471 7499 7478 7479 7496 6 7498 7471 7472 7478 7477 7476 5 7496 7479 7481 7483 7495 6 428 5613 5614 7502 7503 9769 6 7501 5614 7503 7504 7505 7506 6 7501 7502 7504 9769 9770 9771 6 7503 7502 7505 6475 9771 9781 5 7504 7502 6475 6473 7506 7 6473 7505 7502 5614 5615 7507 6471 5 7506 5615 7508 6470 6471 6 7507 5615 5616 7509 7510 6470 6 7508 5616 7510 7511 9735 4519 5 7508 7509 7511 6470 6469 6 7510 7509 6469 9733 9734 9735 6 7250 7251 7253 7513 7514 7969 6 7512 7253 7514 7515 7516 7517 6 7512 7513 7515 7969 7970 7971 6 7514 7513 7516 7971 7972 7973 6 7515 7513 7517 7518 7519 7973 6 7516 7513 7253 7518 9776 7254 6 7516 7517 7519 7520 7521 9776 6 7516 7518 7520 7973 7974 7978 6 7519 7518 7521 7522 7978 7979 6 7520 7518 7522 7523 7524 9776 6 7520 7521 7523 7990 7979 7527 6 7522 7521 7524 7525 7526 7527 6 7523 7521 7525 7257 7258 9776 6 7523 7524 7526 7261 7530 7258 6 7523 7525 7527 7528 7529 7530 6 7523 7526 7528 7990 7522 7991 6 7527 7526 7529 7991 7547 7546 6 7528 7526 7530 7531 7532 7546 6 7529 7526 7531 7262 7261 7525 6 7529 7530 7262 7532 7533 7130 7 7529 7531 7533 7133 7534 7544 7546 5 7532 7531 7130 7131 7133 6 7532 7133 7134 7535 7545 7544 6 7534 7134 7536 7152 7538 7545 6 7535 7134 7135 7537 7151 7152 6 7536 7135 7137 7138 7140 7151 6 7535 7152 7153 7156 7539 7545 6 7538 7156 7158 7540 7541 7545 6 7539 7158 7541 7542 7554 7555 6 7539 7540 7542 7543 7544 7545 6 7541 7540 7543 7548 7554 7551 6 7541 7542 7544 7546 7547 7548 6 7541 7543 7545 7534 7532 7546 6 7541 7544 7534 7535 7538 7539 6 7532 7544 7543 7547 7528 7529 6 7546 7543 7548 7549 7991 7528 6 7547 7543 7542 7549 7550 7551 6 7547 7548 7550 7991 7990 7992 6 7549 7548 7551 7552 7992 7993 6 7550 7548 7552 7553 7554 7542 6 7550 7551 7553 7993 7995 7996 7 7552 7551 7554 7558 7557 7559 7996 6 7553 7551 7542 7540 7555 7558 6 7554 7540 7158 7159 7556 7558 6 7555 7159 7161 7168 7557 7558 7 7556 7168 7558 7553 7559 7560 7561 5 7556 7557 7555 7554 7553 5 7553 7557 7560 7996 7997 7 7559 7557 7561 7997 8000 7567 7562 5 7560 7557 7168 7169 7562 6 7561 7169 7563 7566 7567 7560 6 7562 7169 7170 7171 7564 7566 6 7563 7171 7565 7177 7566 7569 5 7564 7171 7172 7174 7177 6 7563 7564 7562 7567 7568 7569 6 7562 7566 7568 8000 7560 8001 6 7567 7566 7569 7570 7571 8001 5 7568 7566 7564 7177 7570 6 7569 7177 7568 7571 7181 7178 6 7568 7570 7181 7572 8001 8002 6 7571 7181 7182 7573 8002 8003 6 7572 7182 7574 7575 8003 8004 6 7573 7182 7575 7576 7184 7183 6 7573 7574 7576 7577 7578 8004 6 7575 7574 7184 7188 7190 7577 6 7576 7190 7575 7578 7579 7580 6 7575 7577 7579 8004 8005 8006 6 7578 7577 7580 8006 8007 8008 6 7579 7577 7190 7191 7581 8008 6 7580 7191 7194 7582 8008 8009 6 7581 7194 7196 7583 8009 8010 6 7582 7196 7584 7586 8013 8010 6 7583 7196 7197 3197 7585 7586 6 7584 3197 3187 7586 7587 3188 6 7584 7585 7587 7588 7583 8013 6 7586 7585 7588 7589 3959 3188 6 7586 7587 7589 7730 8014 8013 6 7588 7587 3959 3961 7590 7730 6 7589 3961 7591 7730 7731 7732 6 7590 3961 3962 7592 7732 7733 6 7591 3962 7593 7739 7733 7740 6 7592 3962 2891 2892 7594 7740 6 7593 2892 7595 7596 7740 7741 6 7594 2892 7596 7597 7598 2893 6 7594 7595 7597 7741 7742 7746 6 7596 7595 7598 7599 7746 7747 6 7597 7595 7599 7600 7601 2893 6 7597 7598 7600 4090 7747 7752 5 7599 7598 7601 4090 4087 6 7600 7598 4087 2881 2880 2893 7 7379 7380 7381 7603 7604 7918 7919 6 7602 7381 7604 7605 7606 7382 6 7602 7603 7605 7927 7921 7919 5 7604 7603 7606 7927 7928 7 7605 7603 7382 7383 7607 7610 7928 6 7606 7383 7385 7608 7609 7610 6 7607 7385 7386 7393 7395 7609 6 7608 7395 7607 7610 7611 7612 6 7607 7609 7611 7930 7928 7606 6 7610 7609 7612 7614 7617 7930 6 7611 7609 7395 7396 7613 7614 6 7612 7396 7614 7615 7622 7623 6 7612 7613 7615 7616 7617 7611 6 7614 7613 7616 7620 7621 7622 6 7614 7615 7617 7618 7619 7620 6 7614 7616 7618 8158 7930 7611 6 7617 7616 7619 8156 8158 8157 6 7618 7616 7620 8157 8159 8160 6 7619 7616 7615 7621 8160 8161 6 7620 7615 7622 8161 8162 8163 6 7621 7615 7613 7623 8163 8164 6 7622 7613 7396 7397 7624 8164 6 7623 7397 7398 7399 7625 8164 6 7624 7399 7400 7626 8164 8165 6 7625 7400 7401 7627 8165 7628 5 7626 7401 7402 7404 7628 6 7627 7404 7629 8165 7626 8166 6 7628 7404 7405 7630 7631 8166 6 7629 7405 7631 7632 7633 7409 6 7629 7630 7632 8166 8167 8168 6 7631 7630 7633 8171 8168 8172 6 7632 7630 7409 7410 7634 8172 6 7633 7410 7635 8174 8172 8175 6 7634 7410 7411 7636 7637 8175 6 7635 7411 7637 7638 7642 7643 6 7635 7636 7638 7639 8175 8176 6 7637 7636 7639 7640 7641 7642 6 7637 7638 7640 8176 8177 8178 6 7639 7638 7641 8178 8179 8180 6 7640 7638 7642 8180 8181 8182 6 7641 7638 7636 7643 8182 8183 6 7642 7636 7411 7412 7644 8183 6 7643 7412 7413 7415 7645 8183 6 7644 7415 7646 8184 8183 8185 6 7645 7415 7416 7647 8185 8186 6 7646 7416 7418 7422 7648 8186 6 7647 7422 7424 7649 8186 8187 6 7648 7424 7650 8187 8188 8189 6 7649 7424 7425 7651 8189 8190 6 7650 7425 7652 8190 8191 8192 6 7651 7425 7426 7653 8192 8193 6 7652 7426 7428 7654 8193 7658 6 7653 7428 7429 7655 7656 7658 6 7654 7429 7430 7656 7435 7432 6 7654 7655 7435 7436 7657 7658 6 7656 7436 7658 7659 7660 7661 6 7656 7657 7659 8193 7653 7654 6 7658 7657 7660 8193 8194 8195 6 7659 7657 7661 8195 7663 7662 6 7660 7657 7436 7437 7439 7662 6 7661 7439 7440 7442 7663 7660 6 7662 7442 7664 8195 7660 8196 6 7663 7442 7443 7665 8209 8196 6 7664 7443 7444 7666 8209 8208 6 7665 7444 7445 7667 7668 8208 6 7666 7445 7668 7669 7448 7446 6 7666 7667 7669 7670 8207 8208 6 7668 7667 7448 7670 7671 7672 6 7668 7669 7671 7699 8207 9791 6 7670 7669 7672 7673 7696 9791 6 7671 7669 7448 7449 7673 7674 6 7671 7672 7674 7675 7696 7695 6 7673 7672 7675 7676 7677 7449 7 7673 7674 7676 7694 7226 7227 7695 6 7675 7674 7677 7678 7680 7694 6 7676 7674 7449 7450 7451 7678 6 7677 7451 7452 7679 7680 7676 6 7678 7452 7680 7681 7682 7683 7 7678 7679 7681 7676 7694 7693 7690 5 7680 7679 7682 7690 7685 6 7681 7679 7683 7455 7684 7685 6 7682 7679 7452 7453 7454 7455 6 7682 7455 7685 7686 7687 7456 7 7682 7684 7686 7490 7491 7690 7681 6 7685 7684 7687 7487 7488 7490 6 7686 7684 7456 7457 7688 7487 6 7687 7457 7458 7487 7486 7689 6 7486 7688 7458 7459 7462 7485 6 7685 7491 7691 7693 7680 7681 6 7690 7491 7492 7692 7225 7693 6 7691 7492 7494 7080 7081 7225 6 7691 7225 7226 7694 7680 7690 5 7693 7226 7675 7676 7680 5 7675 7227 7228 7696 7673 7 7695 7228 7229 7697 7671 7673 9791 6 7696 7229 7231 7698 7699 9791 6 7697 7231 7699 7700 7701 7702 6 7697 7698 7700 8207 7670 9791 6 7699 7698 7701 8206 8204 8207 6 7700 7698 7702 8319 8206 7708 6 7701 7698 7231 7232 7703 7708 6 7702 7232 7704 7705 7706 7708 6 7703 7232 7705 7235 7234 7233 6 7703 7704 7706 7707 7719 7235 6 7703 7705 7707 7708 7709 7710 6 7706 7705 7710 7711 7712 7719 6 7703 7706 7709 8319 7701 7702 6 7708 7706 7710 8319 8482 8318 6 7709 7706 7707 7711 8482 8483 6 7710 7707 7712 7713 7714 8483 6 7711 7707 7713 7717 7718 7719 6 7711 7712 7714 7715 7716 7717 6 7711 7713 7715 8483 8484 8485 6 7714 7713 7716 8485 9766 8487 6 7715 7713 7717 9766 7724 9768 6 7716 7713 7712 7718 9768 7720 6 7717 7712 7719 7236 7237 7720 6 7718 7712 7707 7705 7235 7236 6 7718 7237 7721 9768 7717 7722 6 7720 7237 7238 7239 7241 7722 6 7721 7241 7723 7724 9768 7720 6 7722 7241 7242 7724 7725 7726 7 7722 7723 7725 7727 9766 7716 9768 6 7724 7723 7726 7727 7728 7729 6 7725 7723 7729 7246 7243 7242 6 7724 7725 7728 7963 9766 9765 6 7727 7725 7729 7963 7964 7965 6 7728 7725 7726 7246 7965 7247 6 7588 7589 7590 7731 8014 8015 6 7730 7590 7732 8015 8016 7735 6 7731 7590 7591 7733 7734 7735 6 7732 7591 7734 7738 7739 7592 6 7732 7733 7735 7736 7737 7738 6 7732 7734 7736 8016 7731 8017 6 7735 7734 7737 8017 8018 8019 6 7736 7734 7738 8019 8020 8021 6 7737 7734 7733 7739 8021 8022 6 7738 7733 7592 7740 9767 8022 6 7739 7592 7593 7594 7741 9767 6 7740 7594 7596 7742 7743 9767 6 7741 7596 7743 7744 7745 7746 6 7741 7742 7744 8026 8024 9767 6 7743 7742 7745 8026 8027 8028 6 7744 7742 7746 7748 7749 8028 6 7745 7742 7596 7597 7747 7748 6 7746 7597 7599 7748 7751 7752 6 7746 7747 7745 7749 7750 7751 6 7745 7748 7750 8028 8032 8033 6 7749 7748 7751 8033 8037 7760 6 7750 7748 7747 7752 7753 7760 7 7751 7747 7599 4090 4091 7753 7754 7 7751 7752 7754 4380 7755 7759 7760 4 7753 7752 4091 4380 5 7753 4380 4381 7756 7759 6 7755 4381 4383 7757 7758 7759 6 7756 4383 7758 7763 7764 7765 6 7756 7757 7759 7761 7762 7763 6 7756 7758 7755 7753 7760 7761 6 7753 7759 7761 8037 7750 7751 5 7760 7759 7758 7762 8037 7 7761 7758 7763 8037 8641 8636 8036 7 7762 7758 7757 7764 8853 8640 8641 6 7763 7757 7765 7766 8853 8854 6 7764 7757 4383 4384 4390 7766 6 7764 7765 4390 7767 8320 8854 6 7766 4390 4391 7768 8320 8321 6 7767 4391 3143 7769 7770 8321 6 7768 3143 7770 7771 7775 3144 6 7768 7769 7771 7772 8323 8321 6 7770 7769 7772 7773 7774 7775 6 7770 7771 7773 8323 8324 8325 6 7772 7771 7774 8325 8326 7778 6 7773 7771 7775 7776 7777 7778 6 7774 7771 7769 3144 3145 7776 6 7775 3145 7774 7777 3146 9792 6 7774 7776 7778 7779 3415 9792 6 7774 7777 7779 8326 7773 8327 6 7778 7777 3415 3416 7780 8327 6 7779 3416 5383 5385 7781 8327 6 7780 5385 5387 7782 8327 8328 6 7781 5387 5389 7783 8330 8328 6 7782 5389 5617 7784 8330 8331 6 7783 5617 7785 8331 8332 8333 6 7784 5617 5618 7786 8038 8333 6 7785 5618 7787 7788 8038 8039 6 7786 5618 5619 7788 7789 7790 6 7786 7787 7789 8039 8040 8041 6 7788 7787 7790 8046 8041 7795 6 7789 7787 5619 5620 7791 7795 6 7790 5620 7792 7793 7794 7795 6 7791 5620 7793 3780 3779 5621 6 7791 7792 7794 7798 7799 3780 6 7791 7793 7795 7796 7797 7798 6 7791 7794 7796 8046 7789 7790 6 7795 7794 7797 8046 8047 8048 6 7796 7794 7798 8049 8048 8050 6 7797 7794 7793 7799 8050 7800 6 7798 7793 3780 3781 3784 7800 6 7799 3784 3785 7801 8050 7798 6 7800 3785 3786 3789 7802 8050 6 7801 3789 3791 7803 8049 8050 6 7802 3791 3792 3794 7804 8049 6 7803 3794 7805 7807 8048 8049 6 7804 3794 3795 7806 7807 7808 6 7805 3795 7808 7809 7810 3796 6 7804 7805 7808 8047 8048 8344 6 7807 7805 7806 7809 8345 8344 6 7808 7806 7810 8345 8346 7931 6 7809 7806 3796 3797 7811 7931 6 7810 3797 3953 7812 7931 7932 6 7811 3953 7813 7932 7933 7937 6 7812 3953 3954 7814 7937 7938 6 7813 3954 3955 7815 7938 7939 6 7814 3955 7816 7939 7940 7817 6 7815 3955 3956 3957 4239 7817 6 7816 4239 4504 7818 7940 7815 6 7817 4504 4505 7819 7940 7941 6 7818 4505 7820 7941 7942 7943 6 7819 4505 4506 7821 7943 7944 6 7820 4506 4507 4508 7822 7944 6 7821 4508 7823 7944 7945 7946 6 7822 4508 4509 7824 7946 7947 6 7823 4509 4510 7825 7947 7948 6 7824 4510 7826 7827 7948 7949 6 7825 4510 4511 7827 7828 7829 6 7825 7826 7828 7949 7950 7951 6 7827 7826 7829 7951 7952 7953 6 7828 7826 4511 4420 7830 7953 6 7829 4420 4248 7831 7953 7833 6 7830 4248 4249 4740 7832 7833 6 7831 4740 5004 7833 7834 7835 6 7831 7832 7834 7953 7830 7954 6 7833 7832 7835 7954 7955 7956 6 7834 7832 5004 5005 7836 7956 6 7835 5005 5006 7837 7956 7957 6 7836 5006 7838 7957 7958 7959 6 7837 5006 4751 4752 7839 7959 6 7838 4752 4758 7840 7959 7960 6 7839 4758 7841 7960 7961 7847 6 7840 4758 4759 7842 7847 7962 6 7841 4759 4662 4663 7843 7962 6 7842 4663 4664 4690 7844 7962 6 7843 4690 4691 7845 7962 7846 6 7844 4691 4692 5159 5160 7846 5 7845 5160 7847 7962 7844 7 7846 5160 7848 7961 7840 7841 7962 6 7847 5160 5161 7849 8083 7961 6 7848 5161 5162 7850 8083 8084 6 7849 5162 5163 7851 8084 8085 6 7850 5163 7852 8085 8086 8087 6 7851 5163 5164 5165 7853 8087 6 7852 5165 7854 8087 8088 8089 6 7853 5165 5166 7855 8089 8090 7 7854 5166 4701 4702 4703 7856 8090 5 7855 4703 7309 7857 8090 7 7856 7309 7310 7858 8090 8091 8092 7 7857 7310 7311 7859 8092 8093 8094 6 7858 7311 7312 7860 8094 8095 6 7859 7312 7313 7314 7861 8095 6 7860 7314 7862 8095 8096 8097 6 7861 7314 7315 7863 8097 8098 6 7862 7315 7316 7864 8098 8099 6 7863 7316 7317 7865 8099 8100 6 7864 7317 7318 7866 8100 8101 6 7865 7318 7319 7867 8101 8102 6 7866 7319 7320 7868 8102 8103 6 7867 7320 7321 7322 7869 8103 6 7868 7322 7870 8103 8104 8105 6 7869 7322 7323 7871 8105 8106 6 7870 7323 7324 7325 7872 8106 6 7871 7325 7873 8106 8107 8108 6 7872 7325 7326 7874 8108 8109 6 7873 7326 7327 7328 7875 8109 6 7874 7328 7876 8109 8110 8111 6 7875 7328 7329 7330 7877 8111 6 7876 7330 7878 8111 8112 8113 6 7877 7330 7331 7332 7879 8113 6 7878 7332 7333 7880 8113 8114 6 7879 7333 7881 8114 8115 8116 6 7880 7333 7334 7335 7882 8116 6 7881 7335 7336 7337 7883 8116 6 7882 7337 7338 7884 8116 8117 7 7883 7338 7339 7885 8117 8118 8119 6 7884 7339 7340 7886 8119 8120 6 7885 7340 7341 7887 8120 8121 6 7886 7341 7342 7888 8121 8122 6 7887 7342 7889 8122 8123 8124 6 7888 7342 7343 7344 7890 8124 6 7889 7344 7345 7891 8124 8125 6 7890 7345 7346 7892 8125 8126 6 7891 7346 7347 7893 8126 8127 6 7892 7347 7348 7894 8127 8128 6 7893 7348 7349 7895 8128 8129 6 7894 7349 7896 8129 8130 8131 6 7895 7349 7350 7351 7897 8131 6 7896 7351 7352 7898 8131 8132 7 7897 7352 7353 7354 7899 8132 8133 5 7898 7354 7900 8133 8134 7 7899 7354 7355 7356 7901 8134 8135 6 7900 7356 7902 8135 8136 8137 5 7901 7356 7357 7903 8137 7 7902 7357 7904 8137 8138 8139 7905 5 7903 7357 7358 7359 7905 6 7904 7359 7906 8139 7903 8140 6 7905 7359 7360 7362 7907 8140 6 7906 7362 7908 8140 8141 8142 6 7907 7362 7363 7364 7909 8142 6 7908 7364 7910 8142 8143 8144 6 7909 7364 7365 7366 7911 8144 6 7910 7366 7372 7912 8144 8145 6 7911 7372 7913 8145 8146 8147 5 7912 7372 7373 7914 8147 7 7913 7373 7374 7915 8147 8148 8149 6 7914 7374 7916 8149 8150 8151 6 7915 7374 7375 7377 7917 8151 6 7916 7377 7918 7919 7920 8151 6 7917 7377 7378 7379 7602 7919 6 7918 7602 7917 7920 7921 7604 6 7917 7919 7921 7922 7923 8151 6 7920 7919 7922 7926 7927 7604 6 7920 7921 7923 7924 7925 7926 6 7920 7922 7924 8151 8152 8150 6 7923 7922 7925 8152 8153 8154 6 7924 7922 7926 8154 8155 8156 6 7925 7922 7921 7927 8156 7929 6 7926 7921 7604 7605 7928 7929 6 7927 7605 7929 7930 7610 7606 6 7927 7928 7930 8156 7926 8158 6 7929 7928 7610 8158 7617 7611 6 7810 7811 7932 8051 8346 7809 6 7931 7811 7812 7933 7934 8051 6 7932 7812 7934 7935 7936 7937 6 7932 7933 7935 8051 8052 8053 6 7934 7933 7936 8053 8054 8058 6 7935 7933 7937 8060 8058 8061 6 7936 7933 7812 7813 7938 8061 6 7937 7813 7814 7939 8061 8062 6 7938 7814 7815 7940 8062 8063 6 7939 7815 7817 7818 7941 8063 6 7940 7818 7819 7942 8063 8064 6 7941 7819 7943 8064 8065 8066 6 7942 7819 7820 7944 8066 8067 6 7943 7820 7821 7822 7945 8067 6 7944 7822 7946 8067 8068 8069 6 7945 7822 7823 7947 8069 8070 6 7946 7823 7824 7948 8070 8071 6 7947 7824 7825 7949 8071 8072 6 7948 7825 7827 7950 8072 8073 6 7949 7827 7951 8073 8074 8075 6 7950 7827 7828 7952 8075 8076 6 7951 7828 7953 8076 8077 7954 6 7952 7828 7829 7830 7833 7954 6 7953 7833 7834 7955 8077 7952 6 7954 7834 7956 8077 8078 8079 6 7955 7834 7835 7836 7957 8079 6 7956 7836 7837 7958 8079 8080 6 7957 7837 7959 8080 8081 8082 6 7958 7837 7838 7839 7960 8082 6 7959 7839 7840 7961 8082 8083 5 7960 7840 7847 8083 7848 6 7847 7841 7842 7843 7844 7846 6 7727 7728 7964 8467 8469 9765 6 7963 7728 7965 8467 8488 8489 6 7964 7728 7729 7247 7966 8489 6 7965 7247 7248 7967 8489 8490 6 7966 7248 7249 7968 8490 8491 6 7967 7249 7250 7969 8491 8492 6 7968 7250 7512 7514 7970 8492 6 7969 7514 7971 8494 8492 8495 6 7970 7514 7515 7972 8495 8496 6 7971 7515 7973 8496 8497 7975 6 7972 7515 7516 7519 7974 7975 6 7973 7519 7975 7976 7977 7978 6 7973 7974 7976 8497 7972 8498 6 7975 7974 7977 8501 8498 7982 6 7976 7974 7978 7980 7981 7982 6 7977 7974 7519 7520 7979 7980 6 7978 7520 7980 7989 7990 7522 6 7978 7979 7977 7981 7988 7989 6 7977 7980 7982 7983 7987 7988 6 7977 7981 7983 7984 8501 7976 6 7982 7981 7984 7985 7986 7987 6 7982 7983 7985 8501 8502 8503 6 7984 7983 7986 8503 8504 8505 6 7985 7983 7987 8505 8506 8507 6 7986 7983 7981 7988 8507 7994 7 7987 7981 7980 7989 7992 7993 7994 5 7988 7980 7979 7990 7992 7 7989 7979 7522 7527 7991 7549 7992 5 7990 7527 7528 7547 7549 6 7990 7549 7550 7993 7988 7989 6 7992 7550 7552 7988 7994 7995 6 7988 7993 7995 8507 7987 8508 6 7994 7993 7552 8508 7998 7996 6 7552 7553 7559 7997 7998 7995 6 7996 7559 7560 7998 7999 8000 6 7996 7997 7999 8508 7995 8509 6 7998 7997 8000 8509 8510 8511 6 7999 7997 7560 7567 8001 8511 6 8000 7567 7568 7571 8002 8511 7 8001 7571 7572 8003 8511 8523 8512 6 8002 7572 7573 8004 8523 8524 7 8003 7573 7575 7578 8005 8521 8524 7 8004 7578 8006 8520 8518 8521 8542 5 8005 7578 7579 8007 8542 6 8006 7579 8008 8611 8541 8542 6 8007 7579 7580 7581 8009 8611 6 8008 7581 7582 8010 8011 8611 6 8009 7582 8011 8012 8013 7583 8 8009 8010 8012 8610 8538 8539 8541 8611 5 8011 8010 8013 8014 8610 6 8012 8010 8014 7588 7583 7586 7 8012 8013 7588 7730 8015 8609 8610 6 8014 7730 7731 8016 8608 8609 6 8015 7731 7735 8017 8612 8608 6 8016 7735 7736 8018 8612 8613 6 8017 7736 8019 8613 8614 8615 6 8018 7736 7737 8020 8615 8616 6 8019 7737 8021 8616 8619 8620 6 8020 7737 7738 8022 8023 8620 6 8021 7738 8023 8024 9767 7739 6 8021 8022 8024 8025 8620 8621 6 8023 8022 8025 8026 7743 9767 6 8023 8024 8026 8621 8622 8029 6 8025 8024 7743 7744 8027 8029 6 8026 7744 8028 8029 8030 8031 6 8027 7744 7745 7749 8031 8032 6 8026 8027 8030 8622 8025 8623 6 8029 8027 8031 8629 8623 8630 6 8030 8027 8028 8032 8034 8630 6 8031 8028 7749 8033 8034 8035 6 8032 7749 7750 8035 8036 8037 6 8031 8032 8035 8630 8631 8632 6 8034 8032 8033 8036 8632 8633 6 8035 8033 8037 7762 8636 8633 6 8036 8033 7750 7760 7761 7762 6 7785 7786 8039 8333 8334 8335 6 8038 7786 7788 8040 8042 8335 6 8039 7788 8041 8042 8043 8044 6 8040 7788 8044 8045 8046 7789 6 8039 8040 8043 8335 8336 8337 6 8042 8040 8044 8337 8338 8342 6 8043 8040 8041 8045 8342 8343 6 8044 8041 8046 8343 8344 8047 6 8045 8041 7789 7795 7796 8047 6 8046 7796 8048 7807 8344 8045 6 8047 7796 7807 7804 8049 7797 6 7804 8048 7797 7803 7802 8050 6 7802 8049 7797 7798 7800 7801 6 7931 7932 7934 8052 8346 8347 6 8051 7934 8053 8347 8348 8349 6 8052 7934 7935 8054 8055 8349 6 8053 7935 8055 8056 8057 8058 6 8053 8054 8056 8349 8350 8351 6 8055 8054 8057 8351 8352 8353 6 8056 8054 8058 8059 8353 8354 6 8057 8054 8059 8060 7936 7935 6 8057 8058 8060 8354 8355 8356 6 8059 8058 7936 8061 8356 8357 6 8060 7936 7937 7938 8062 8357 6 8061 7938 7939 8063 8357 8359 6 8062 7939 7940 7941 8064 8359 6 8063 7941 7942 8065 8360 8359 6 8064 7942 8066 8360 8361 8362 6 8065 7942 7943 8067 8362 8363 6 8066 7943 7944 7945 8068 8363 6 8067 7945 8069 8363 8364 8365 6 8068 7945 7946 8070 8365 8366 6 8069 7946 7947 8071 8366 8367 6 8070 7947 7948 8072 8367 8368 6 8071 7948 7949 8073 8368 8369 6 8072 7949 7950 8074 8369 8370 6 8073 7950 8075 8370 8371 8372 6 8074 7950 7951 8076 8372 8373 6 8075 7951 7952 8077 8373 8374 6 8076 7952 7954 7955 8078 8374 6 8077 7955 8079 8376 8374 8377 6 8078 7955 7956 7957 8080 8377 6 8079 7957 7958 8081 8377 8378 6 8080 7958 8082 8210 8378 8379 6 8081 7958 7959 7960 8083 8210 7 8082 7960 7961 7848 7849 8084 8210 6 8083 7849 7850 8085 8210 8211 6 8084 7850 7851 8086 8211 8212 6 8085 7851 8087 8212 8213 8214 6 8086 7851 7852 7853 8088 8214 6 8087 7853 8089 8214 8215 8216 6 8088 7853 7854 8090 8216 8091 6 8089 7854 7855 7856 7857 8091 5 8090 7857 8092 8216 8089 7 8091 7857 7858 8093 8216 8217 8218 5 8092 7858 8094 8218 8219 6 8093 7858 7859 8095 8219 8220 6 8094 7859 7860 7861 8096 8220 6 8095 7861 8097 8220 8221 8222 6 8096 7861 7862 8098 8222 8223 6 8097 7862 7863 8099 8223 8224 6 8098 7863 7864 8100 8224 8225 6 8099 7864 7865 8101 8225 8226 6 8100 7865 7866 8102 8226 8227 6 8101 7866 7867 8103 8227 8228 6 8102 7867 7868 7869 8104 8228 6 8103 7869 8105 8228 8229 8230 6 8104 7869 7870 8106 8230 8231 6 8105 7870 7871 7872 8107 8231 6 8106 7872 8108 8231 8232 8233 6 8107 7872 7873 8109 8233 8234 6 8108 7873 7874 7875 8110 8234 6 8109 7875 8111 8234 8235 8236 6 8110 7875 7876 7877 8112 8236 6 8111 7877 8113 8236 8237 8238 6 8112 7877 7878 7879 8114 8238 6 8113 7879 7880 8115 8238 8239 6 8114 7880 8116 8239 8240 8117 6 8115 7880 7881 7882 7883 8117 6 8116 7883 7884 8118 8240 8115 6 8117 7884 8119 8240 8241 8242 5 8118 7884 7885 8120 8242 6 8119 7885 7886 8121 8242 8243 6 8120 7886 7887 8122 8243 8244 6 8121 7887 7888 8123 8244 8245 6 8122 7888 8124 8245 8246 8247 6 8123 7888 7889 7890 8125 8247 6 8124 7890 7891 8126 8247 8248 6 8125 7891 7892 8127 8248 8249 6 8126 7892 7893 8128 8249 8250 6 8127 7893 7894 8129 8250 8251 6 8128 7894 7895 8130 8251 8252 6 8129 7895 8131 8252 8253 8254 6 8130 7895 7896 7897 8132 8254 6 8131 7897 7898 8133 8254 8255 5 8132 7898 7899 8134 8255 7 8133 7899 7900 8135 8255 8256 8257 5 8134 7900 7901 8136 8257 7 8135 7901 8137 8257 8258 8259 8260 6 8136 7901 7902 7903 8138 8260 6 8137 7903 8139 8260 8261 8262 6 8138 7903 7905 8140 8262 8263 6 8139 7905 7906 7907 8141 8263 6 8140 7907 8142 8263 8264 8265 6 8141 7907 7908 7909 8143 8265 6 8142 7909 8144 8265 8266 8267 6 8143 7909 7910 7911 8145 8267 6 8144 7911 7912 8146 8267 8268 6 8145 7912 8147 8268 8269 8270 6 8146 7912 7913 7914 8148 8270 6 8147 7914 8149 8270 8271 8272 6 8148 7914 7915 8150 8152 8272 5 8149 7915 8151 8152 7923 6 8150 7915 7916 7917 7920 7923 7 8149 8150 7923 7924 8153 8272 8273 5 8152 7924 8154 8273 8274 7 8153 7924 7925 8155 8274 8275 8276 6 8154 7925 8156 8157 8276 8277 7 8155 7925 8157 7926 7929 8158 7618 6 8155 8156 7618 7619 8159 8277 5 8156 7929 7930 7617 7618 6 8157 7619 8160 8277 8278 8279 6 8159 7619 7620 8161 8279 8280 7 8160 7620 7621 8162 8280 8281 8282 5 8161 7621 8163 8282 8283 7 8162 7621 7622 8164 8283 8284 8165 6 8163 7622 7623 7624 7625 8165 7 8164 7625 7626 7628 8166 8284 8163 6 8165 7628 7629 7631 8167 8284 6 8166 7631 8168 8169 8284 8283 6 8167 7631 8169 8170 8171 7632 6 8167 8168 8170 8283 8285 8286 6 8169 8168 8171 8286 8287 8288 6 8170 8168 7632 8172 8173 8288 6 8171 7632 8173 8174 7634 7633 6 8171 8172 8174 8288 8289 8290 6 8173 8172 7634 8175 8290 8291 6 8174 7634 7635 7637 8176 8291 6 8175 7637 7639 8177 8291 8292 6 8176 7639 8178 8292 8293 8294 6 8177 7639 7640 8179 8294 8295 6 8178 7640 8180 8295 8296 8297 6 8179 7640 7641 8181 8297 8298 6 8180 7641 8182 8308 8298 8309 6 8181 7641 7642 8183 8184 8309 6 8182 7642 8184 7645 7644 7643 6 8182 8183 7645 8185 8309 8310 6 8184 7645 7646 8186 8310 8311 7 8185 7646 7647 7648 8187 8311 8312 6 8186 7648 7649 8188 8312 8313 6 8187 7649 8189 8313 8314 8315 6 8188 7649 7650 8190 8315 8316 6 8189 7650 7651 8191 8316 8201 6 8190 7651 8192 8198 8200 8201 6 8191 7651 7652 8193 8198 8194 6 8192 7652 7653 7658 7659 8194 6 8193 7659 8195 8197 8198 8192 6 8194 7659 7660 7663 8196 8197 6 8195 7663 8197 8209 8205 7664 6 8195 8196 8194 8198 8199 8205 6 8194 8197 8199 8200 8191 8192 6 8198 8197 8200 8203 8204 8205 6 8198 8199 8191 8201 8202 8203 6 8191 8200 8202 8316 8190 8317 6 8201 8200 8203 8317 8318 8319 6 8202 8200 8199 8204 8206 8319 6 8203 8199 8205 8206 7700 8207 7 8204 8199 8207 8208 8209 8196 8197 5 8203 8204 7700 8319 7701 7 7700 8204 8205 7699 7670 7668 8208 6 7668 8207 8205 8209 7665 7666 5 8208 8205 8196 7664 7665 6 8081 8082 8083 8084 8211 8379 5 8210 8084 8085 8212 8379 6 8211 8085 8086 8213 8379 8380 6 8212 8086 8214 8380 8381 8382 6 8213 8086 8087 8088 8215 8382 6 8214 8088 8216 8382 8383 8217 6 8215 8088 8089 8091 8092 8217 6 8216 8092 8218 8383 8215 8384 6 8217 8092 8093 8219 8384 8385 6 8218 8093 8094 8220 8385 8386 6 8219 8094 8095 8096 8221 8386 5 8220 8096 8222 8386 8387 6 8221 8096 8097 8223 8387 8388 6 8222 8097 8098 8224 8388 8389 6 8223 8098 8099 8225 8389 8390 6 8224 8099 8100 8226 8390 8391 6 8225 8100 8101 8227 8391 8392 6 8226 8101 8102 8228 8392 8393 6 8227 8102 8103 8104 8229 8393 6 8228 8104 8230 8393 8394 8395 6 8229 8104 8105 8231 8395 8396 6 8230 8105 8106 8107 8232 8396 6 8231 8107 8233 8396 8397 8398 6 8232 8107 8108 8234 8398 8399 6 8233 8108 8109 8110 8235 8399 6 8234 8110 8236 8399 8400 8401 6 8235 8110 8111 8112 8237 8401 6 8236 8112 8238 8401 8402 8403 6 8237 8112 8113 8114 8239 8403 6 8238 8114 8115 8240 8403 8404 6 8239 8115 8117 8118 8241 8404 6 8240 8118 8242 8404 8405 8406 6 8241 8118 8119 8120 8243 8406 6 8242 8120 8121 8244 8406 8407 6 8243 8121 8122 8245 8407 8408 6 8244 8122 8123 8246 8408 8409 6 8245 8123 8247 8409 8410 8411 6 8246 8123 8124 8125 8248 8411 6 8247 8125 8126 8249 8411 8412 6 8248 8126 8127 8250 8412 8413 6 8249 8127 8128 8251 8413 8414 6 8250 8128 8129 8252 8414 8415 6 8251 8129 8130 8253 8415 8416 6 8252 8130 8254 8416 8417 8418 6 8253 8130 8131 8132 8255 8418 7 8254 8132 8133 8134 8256 8418 8419 5 8255 8134 8257 8419 8420 7 8256 8134 8135 8136 8258 8420 8421 5 8257 8136 8259 8421 8422 6 8258 8136 8260 8422 8423 8261 5 8259 8136 8137 8138 8261 6 8260 8138 8262 8423 8259 8424 6 8261 8138 8139 8263 8424 8425 6 8262 8139 8140 8141 8264 8425 6 8263 8141 8265 8425 8426 8427 6 8264 8141 8142 8143 8266 8427 6 8265 8143 8267 8427 8428 8429 7 8266 8143 8144 8145 8268 8429 8430 6 8267 8145 8146 8269 8430 8431 6 8268 8146 8270 8431 8432 8433 6 8269 8146 8147 8148 8271 8433 6 8270 8148 8272 8433 8434 8435 6 8271 8148 8149 8152 8273 8435 5 8272 8152 8153 8274 8435 7 8273 8153 8154 8275 8435 8436 8437 6 8274 8154 8276 8437 8438 8439 6 8275 8154 8155 8277 8439 8278 5 8276 8155 8157 8159 8278 6 8277 8159 8279 8439 8276 8440 6 8278 8159 8160 8280 8440 8441 7 8279 8160 8161 8281 8441 8442 8446 6 8280 8161 8282 8446 8447 8285 5 8281 8161 8162 8283 8285 7 8282 8162 8163 8284 8167 8169 8285 5 8283 8163 8165 8166 8167 6 8283 8169 8286 8447 8281 8282 6 8285 8169 8170 8287 8447 8448 6 8286 8170 8288 8448 8450 8451 6 8287 8170 8171 8173 8289 8451 6 8288 8173 8290 8451 8452 8453 6 8289 8173 8174 8291 8453 8454 6 8290 8174 8175 8176 8292 8454 6 8291 8176 8177 8293 8454 8455 6 8292 8177 8294 8455 8456 8457 6 8293 8177 8178 8295 8457 8458 6 8294 8178 8179 8296 8458 8459 6 8295 8179 8297 8462 8459 8300 6 8296 8179 8180 8298 8299 8300 6 8297 8180 8299 8308 8306 8181 6 8297 8298 8300 8301 8302 8306 6 8297 8299 8301 8462 8296 8463 6 8300 8299 8302 8303 8463 8464 6 8301 8299 8303 8304 8305 8306 6 8301 8302 8304 8464 8465 8466 6 8303 8302 8305 8466 8467 8468 6 8304 8302 8306 8307 8471 8468 6 8305 8302 8299 8307 8308 8298 6 8305 8306 8308 8471 8472 8473 6 8307 8306 8298 8181 8309 8473 6 8308 8181 8182 8184 8310 8473 6 8309 8184 8185 8311 8473 8474 6 8310 8185 8186 8312 8474 8475 5 8311 8186 8187 8313 8475 6 8312 8187 8188 8314 8475 8476 6 8313 8188 8315 8479 8476 8480 6 8314 8188 8189 8316 8480 8481 6 8315 8189 8190 8201 8317 8481 5 8316 8201 8202 8318 8481 6 8317 8202 8319 8481 8482 7709 7 8318 8202 8203 8206 7701 7708 7709 6 7766 7767 8321 8322 8854 8855 6 8320 7767 7768 8322 8323 7770 7 8320 8321 8323 8855 8856 8857 8324 5 8322 8321 7770 7772 8324 6 8323 7772 8325 8857 8322 8858 6 8324 7772 7773 8326 8858 8329 6 8325 7773 7778 8327 8328 8329 6 8326 7778 7779 7780 7781 8328 6 8327 7781 8326 8329 8330 7782 6 8326 8328 8330 8858 8325 8859 6 8329 8328 7782 7783 8331 8859 6 8330 7783 7784 8332 8859 8860 6 8331 7784 8333 8866 8863 8860 6 8332 7784 7785 8038 8334 8866 6 8333 8038 8335 8867 8866 8868 6 8334 8038 8039 8042 8336 8868 6 8335 8042 8337 8868 8869 8870 6 8336 8042 8043 8338 8339 8870 6 8337 8043 8339 8340 8341 8342 6 8337 8338 8340 8870 8871 8875 6 8339 8338 8341 8875 8876 8348 6 8340 8338 8342 8348 8347 8877 6 8341 8338 8043 8044 8343 8877 6 8342 8044 8045 8344 8345 8877 6 8343 8045 8345 7808 7807 8047 6 8343 8344 7808 7809 8346 8877 6 8345 7809 7931 8051 8347 8877 6 8346 8051 8052 8348 8341 8877 6 8347 8052 8349 8876 8340 8341 6 8348 8052 8053 8055 8350 8876 6 8349 8055 8351 8903 8876 8902 6 8350 8055 8056 8352 8902 8904 6 8351 8056 8353 8904 8905 8906 6 8352 8056 8057 8354 8906 8907 6 8353 8057 8059 8355 8907 8908 6 8354 8059 8356 8908 8909 8910 6 8355 8059 8060 8357 8358 8910 6 8356 8060 8061 8062 8358 8359 6 8356 8357 8359 8360 8910 8911 6 8358 8357 8062 8063 8360 8064 6 8358 8359 8064 8065 8361 8911 6 8360 8065 8362 8913 8911 8914 6 8361 8065 8066 8363 8914 8915 6 8362 8066 8067 8068 8364 8915 6 8363 8068 8365 8917 8915 8918 6 8364 8068 8069 8366 8918 8919 6 8365 8069 8070 8367 8919 8920 6 8366 8070 8071 8368 8920 8921 6 8367 8071 8072 8369 8921 8922 6 8368 8072 8073 8370 8922 8923 6 8369 8073 8074 8371 8923 8924 6 8370 8074 8372 8924 8925 8926 6 8371 8074 8075 8373 8926 8927 6 8372 8075 8076 8374 8375 8927 6 8373 8076 8077 8375 8376 8078 6 8373 8374 8376 8927 8928 8929 6 8375 8374 8078 8377 8929 8930 6 8376 8078 8079 8080 8378 8930 6 8377 8080 8081 8379 8930 8380 6 8378 8081 8210 8211 8212 8380 7 8379 8212 8213 8381 8930 8378 8931 5 8380 8213 8382 8931 8932 7 8381 8213 8214 8215 8383 8744 8932 6 8382 8215 8217 8384 8642 8744 6 8383 8217 8218 8385 8642 8643 6 8384 8218 8219 8386 8643 8644 6 8385 8219 8220 8221 8387 8644 7 8386 8221 8222 8388 8644 8645 8646 6 8387 8222 8223 8389 8646 8647 6 8388 8223 8224 8390 8647 8648 6 8389 8224 8225 8391 8648 8649 7 8390 8225 8226 8392 8649 8650 8651 6 8391 8226 8227 8393 8651 8652 6 8392 8227 8228 8229 8394 8652 6 8393 8229 8395 8652 8653 8654 6 8394 8229 8230 8396 8654 8655 6 8395 8230 8231 8232 8397 8655 5 8396 8232 8398 8655 8656 6 8397 8232 8233 8399 8656 8657 7 8398 8233 8234 8235 8400 8657 8658 5 8399 8235 8401 8658 8659 7 8400 8235 8236 8237 8402 8659 8660 5 8401 8237 8403 8660 8661 6 8402 8237 8238 8239 8404 8661 6 8403 8239 8240 8241 8405 8661 6 8404 8241 8406 8661 8662 8663 6 8405 8241 8242 8243 8407 8663 6 8406 8243 8244 8408 8663 8664 7 8407 8244 8245 8409 8664 8665 8666 6 8408 8245 8246 8410 8666 8667 6 8409 8246 8411 8667 8668 8669 6 8410 8246 8247 8248 8412 8669 6 8411 8248 8249 8413 8669 8670 6 8412 8249 8250 8414 8670 8671 6 8413 8250 8251 8415 8671 8672 6 8414 8251 8252 8416 8672 8673 6 8415 8252 8253 8417 8673 8674 6 8416 8253 8418 8674 8675 8676 6 8417 8253 8254 8255 8419 8676 6 8418 8255 8256 8420 8676 8677 6 8419 8256 8257 8421 8677 8678 6 8420 8257 8258 8422 8678 8679 6 8421 8258 8259 8423 8679 8680 6 8422 8259 8261 8424 8680 8681 7 8423 8261 8262 8425 8681 8682 8683 6 8424 8262 8263 8264 8426 8683 6 8425 8264 8427 8683 8684 8688 6 8426 8264 8265 8266 8428 8688 6 8427 8266 8429 8688 8689 8690 6 8428 8266 8267 8430 8690 8691 5 8429 8267 8268 8431 8691 6 8430 8268 8269 8432 8543 8691 6 8431 8269 8433 8543 8544 8545 6 8432 8269 8270 8271 8434 8545 6 8433 8271 8435 8545 8546 8547 7 8434 8271 8272 8273 8274 8436 8547 6 8435 8274 8437 8547 8548 8549 6 8436 8274 8275 8438 8549 8550 6 8437 8275 8439 8550 8551 8440 5 8438 8275 8276 8278 8440 7 8439 8278 8279 8441 8551 8438 8552 6 8440 8279 8280 8442 8443 8552 6 8441 8280 8443 8444 8445 8446 6 8441 8442 8444 8552 8553 8554 6 8443 8442 8445 8554 8555 8556 7 8444 8442 8446 8447 8448 8449 8556 5 8445 8442 8280 8281 8447 6 8446 8281 8285 8286 8448 8445 6 8447 8286 8287 8445 8449 8450 5 8445 8448 8450 8556 8557 6 8449 8448 8287 8451 8557 8558 7 8450 8287 8288 8289 8452 8558 8559 6 8451 8289 8453 8559 8560 8561 6 8452 8289 8290 8454 8561 8562 6 8453 8290 8291 8292 8455 8562 6 8454 8292 8293 8456 8562 8563 6 8455 8293 8457 8563 8564 8565 6 8456 8293 8294 8458 8565 8566 6 8457 8294 8295 8459 8460 8566 6 8458 8295 8460 8461 8462 8296 6 8458 8459 8461 8566 8567 8568 6 8460 8459 8462 8568 8569 8570 6 8461 8459 8296 8300 8463 8570 6 8462 8300 8301 8464 8570 8571 6 8463 8301 8303 8465 8571 8572 6 8464 8303 8466 8572 8573 8574 6 8465 8303 8304 8467 8574 8488 7 8466 8304 8468 8469 7963 7964 8488 6 8467 8304 8469 8470 8471 8305 6 8467 8468 8470 7963 9764 9765 7 8469 8468 8471 9095 8486 9764 8487 6 8470 8468 8305 8307 8472 9095 6 8471 8307 8473 8477 9095 8474 6 8472 8307 8308 8309 8310 8474 6 8473 8310 8311 8475 8477 8472 6 8474 8311 8312 8313 8476 8477 6 8475 8313 8477 8478 8479 8314 7 8475 8476 8478 8486 9095 8472 8474 6 8477 8476 8479 8484 8485 8486 6 8478 8476 8314 8480 8484 8483 6 8479 8314 8315 8481 8483 8482 6 8480 8315 8316 8317 8318 8482 6 8481 8318 7709 7710 8483 8480 7 8482 7710 7711 7714 8484 8479 8480 5 8483 7714 8485 8478 8479 6 8484 7714 7715 8478 8486 8487 6 8478 8485 8487 8470 9095 8477 6 8486 8485 9766 9764 8470 7715 5 8467 7964 8489 8574 8466 7 8488 7964 7965 7966 8490 8574 8575 5 8489 7966 7967 8491 8575 7 8490 7967 7968 8492 8493 8575 8576 6 8491 7968 8493 8494 7970 7969 5 8491 8492 8494 8576 8577 6 8493 8492 7970 8495 8577 8578 6 8494 7970 7971 8496 8578 8579 6 8495 7971 7972 8497 8579 8580 6 8496 7972 7975 8498 8499 8580 6 8497 7975 8499 8500 8501 7976 6 8497 8498 8500 8580 8581 8582 6 8499 8498 8501 8582 8583 8502 6 8500 8498 7976 7982 7984 8502 6 8501 7984 8503 8583 8500 8584 6 8502 7984 7985 8504 8587 8584 6 8503 7985 8505 8528 8587 8527 6 8504 7985 7986 8506 8527 8589 6 8505 7986 8507 8589 8514 8590 6 8506 7986 7987 7994 8508 8590 6 8507 7994 7995 7998 8509 8590 6 8508 7998 7999 8510 8514 8590 6 8509 7999 8511 8512 8513 8514 6 8510 7999 8000 8001 8002 8512 6 8510 8511 8513 8522 8523 8002 6 8510 8512 8514 8515 8516 8522 7 8510 8513 8515 8589 8506 8590 8509 6 8514 8513 8516 8517 8527 8589 6 8515 8513 8517 8518 8521 8522 6 8515 8516 8518 8519 8525 8527 6 8517 8516 8519 8520 8005 8521 6 8517 8518 8520 8525 8526 8532 6 8519 8518 8005 8542 8540 8532 6 8005 8518 8004 8516 8522 8524 6 8521 8516 8513 8512 8523 8524 5 8522 8512 8002 8003 8524 5 8523 8003 8522 8521 8004 6 8517 8519 8526 8527 8528 8529 6 8525 8519 8529 8530 8531 8532 7 8517 8525 8528 8504 8505 8589 8515 5 8527 8525 8529 8587 8504 6 8528 8525 8526 8530 8588 8587 6 8529 8526 8531 8603 8588 8604 6 8530 8526 8532 8533 8534 8604 6 8531 8526 8533 8520 8540 8519 6 8531 8532 8534 8535 8539 8540 6 8531 8533 8535 8536 8604 8605 6 8534 8533 8536 8537 8538 8539 6 8534 8535 8537 8605 8606 8607 6 8536 8535 8538 8607 8608 8609 6 8537 8535 8539 8609 8610 8011 6 8538 8535 8533 8540 8541 8011 6 8539 8533 8541 8542 8520 8532 6 8539 8540 8542 8011 8611 8007 6 8541 8540 8520 8007 8006 8005 6 8431 8432 8544 8691 8692 8693 6 8543 8432 8545 8693 8694 8695 6 8544 8432 8433 8434 8546 8695 6 8545 8434 8547 8695 8696 8548 5 8546 8434 8435 8436 8548 6 8547 8436 8549 8696 8546 8697 6 8548 8436 8437 8550 8697 8698 6 8549 8437 8438 8551 8698 8699 6 8550 8438 8440 8552 8699 8553 5 8551 8440 8441 8443 8553 7 8552 8443 8554 8699 8551 8700 8701 6 8553 8443 8444 8555 8701 8702 6 8554 8444 8556 8702 8703 8704 6 8555 8444 8445 8449 8557 8704 6 8556 8449 8450 8558 8704 8705 6 8557 8450 8451 8559 8705 8706 6 8558 8451 8452 8560 8706 8707 6 8559 8452 8561 8707 8708 8709 5 8560 8452 8453 8562 8709 6 8561 8453 8454 8455 8563 8709 6 8562 8455 8456 8564 8709 8710 6 8563 8456 8565 8710 8711 8712 6 8564 8456 8457 8566 8712 8713 7 8565 8457 8458 8460 8567 8713 8714 5 8566 8460 8568 8714 8715 6 8567 8460 8461 8569 8715 8716 6 8568 8461 8570 8716 8717 8718 6 8569 8461 8462 8463 8571 8718 7 8570 8463 8464 8572 8591 8593 8718 5 8571 8464 8465 8573 8591 7 8572 8465 8574 8575 8576 8577 8591 6 8573 8465 8466 8488 8489 8575 6 8574 8489 8490 8491 8576 8573 5 8575 8491 8493 8577 8573 7 8576 8493 8494 8578 8573 8591 8592 6 8577 8494 8495 8579 8595 8592 6 8578 8495 8496 8580 8595 8596 6 8579 8496 8497 8499 8581 8596 6 8580 8499 8582 8596 8597 8598 6 8581 8499 8500 8583 8598 8599 6 8582 8500 8502 8584 8585 8599 6 8583 8502 8585 8586 8587 8503 6 8583 8584 8586 8599 8600 8601 6 8585 8584 8587 8588 8601 8602 7 8586 8584 8588 8529 8528 8504 8503 6 8586 8587 8529 8602 8603 8530 5 8527 8505 8506 8514 8515 5 8514 8506 8507 8509 8508 6 8573 8577 8592 8572 8571 8593 6 8591 8577 8593 8594 8595 8578 5 8571 8591 8592 8594 8718 7 8593 8592 8595 8718 8717 8719 8720 6 8594 8592 8578 8579 8596 8720 7 8595 8579 8580 8581 8597 8720 8721 6 8596 8581 8598 8721 8722 8723 6 8597 8581 8582 8599 8723 8724 6 8598 8582 8583 8585 8600 8724 6 8599 8585 8601 8724 8725 8726 6 8600 8585 8586 8602 8726 8727 6 8601 8586 8588 8603 8727 8728 5 8602 8588 8530 8604 8728 6 8603 8530 8531 8534 8605 8728 6 8604 8534 8536 8606 8728 8729 6 8605 8536 8607 8729 8732 8733 6 8606 8536 8537 8608 8612 8733 6 8607 8537 8609 8612 8016 8015 6 8608 8537 8538 8610 8015 8014 5 8609 8538 8011 8014 8012 5 8011 8541 8009 8008 8007 6 8607 8608 8016 8017 8613 8733 6 8612 8017 8018 8614 8733 8734 6 8613 8018 8615 8734 8735 8736 6 8614 8018 8019 8616 8617 8736 6 8615 8019 8020 8617 8618 8619 6 8615 8616 8618 8736 8737 8738 6 8617 8616 8619 8738 8739 8740 6 8618 8616 8020 8620 8740 8743 6 8619 8020 8021 8023 8621 8743 6 8620 8023 8025 8622 8625 8743 6 8621 8025 8029 8623 8624 8625 6 8622 8029 8624 8628 8629 8030 6 8622 8623 8625 8626 8627 8628 6 8622 8624 8626 8742 8743 8621 6 8625 8624 8627 8838 8742 8839 6 8626 8624 8628 8839 8840 8841 6 8627 8624 8623 8629 8841 8842 6 8628 8623 8030 8630 8842 8843 6 8629 8030 8031 8034 8631 8843 6 8630 8034 8632 8843 8844 8845 6 8631 8034 8035 8633 8634 8845 6 8632 8035 8634 8635 8636 8036 6 8632 8633 8635 8845 8846 8847 6 8634 8633 8636 8637 8638 8847 6 8635 8633 8637 8641 7762 8036 6 8635 8636 8638 8639 8640 8641 6 8635 8637 8639 8847 8849 8850 6 8638 8637 8640 8850 8851 8852 6 8639 8637 8641 8852 8853 7763 5 8640 8637 8636 7762 7763 6 8383 8384 8643 8744 8745 8746 6 8642 8384 8385 8644 8746 8747 6 8643 8385 8386 8387 8645 8747 6 8644 8387 8646 8747 8748 8749 6 8645 8387 8388 8647 8749 8750 6 8646 8388 8389 8648 8750 8751 6 8647 8389 8390 8649 8751 8752 6 8648 8390 8391 8650 8752 8753 6 8649 8391 8651 8753 8754 8755 5 8650 8391 8392 8652 8755 6 8651 8392 8393 8394 8653 8755 6 8652 8394 8654 8755 8756 8757 6 8653 8394 8395 8655 8757 8758 6 8654 8395 8396 8397 8656 8758 6 8655 8397 8398 8657 8758 8759 7 8656 8398 8399 8658 8759 8760 8761 5 8657 8399 8400 8659 8761 7 8658 8400 8401 8660 8761 8762 8763 5 8659 8401 8402 8661 8763 8 8660 8402 8403 8404 8405 8662 8763 8764 5 8661 8405 8663 8764 8765 6 8662 8405 8406 8407 8664 8765 6 8663 8407 8408 8665 8765 8766 6 8664 8408 8666 8766 8767 8768 5 8665 8408 8409 8667 8768 6 8666 8409 8410 8668 8768 8769 6 8667 8410 8669 8769 8770 8771 6 8668 8410 8411 8412 8670 8771 6 8669 8412 8413 8671 8771 8772 6 8670 8413 8414 8672 8772 8773 6 8671 8414 8415 8673 8773 8774 6 8672 8415 8416 8674 8774 8775 6 8673 8416 8417 8675 8775 8776 6 8674 8417 8676 8776 8777 8778 6 8675 8417 8418 8419 8677 8778 6 8676 8419 8420 8678 8778 8779 6 8677 8420 8421 8679 8779 8780 6 8678 8421 8422 8680 8780 8781 6 8679 8422 8423 8681 8781 8782 6 8680 8423 8424 8682 8782 8783 6 8681 8424 8683 8783 8784 8685 6 8682 8424 8425 8426 8684 8685 6 8683 8426 8685 8686 8687 8688 5 8683 8684 8686 8784 8682 6 8685 8684 8687 8784 8785 8786 6 8686 8684 8688 8786 8787 8788 7 8687 8684 8426 8427 8428 8689 8788 5 8688 8428 8690 8788 8789 6 8689 8428 8429 8691 8789 8790 7 8690 8429 8430 8431 8543 8692 8790 6 8691 8543 8693 8790 8791 8792 5 8692 8543 8544 8694 8792 7 8693 8544 8695 8792 8793 8794 8795 6 8694 8544 8545 8546 8696 8795 6 8695 8546 8548 8697 8795 8796 7 8696 8548 8549 8698 8796 8797 8798 6 8697 8549 8550 8699 8798 8799 6 8698 8550 8551 8553 8700 8799 6 8699 8553 8701 8799 8800 8801 6 8700 8553 8554 8702 8801 8804 6 8701 8554 8555 8703 8804 8805 6 8702 8555 8704 8805 8806 8807 6 8703 8555 8556 8557 8705 8807 6 8704 8557 8558 8706 8807 8808 6 8705 8558 8559 8707 8808 8809 6 8706 8559 8560 8708 8809 8810 6 8707 8560 8709 8810 8811 8812 7 8708 8560 8561 8562 8563 8710 8812 5 8709 8563 8564 8711 8812 7 8710 8564 8712 8812 8813 8814 8815 6 8711 8564 8565 8713 8815 8816 6 8712 8565 8566 8714 8816 8817 5 8713 8566 8567 8715 8817 7 8714 8567 8568 8716 8817 8818 8819 6 8715 8568 8569 8717 8819 8820 6 8716 8569 8718 8594 8719 8820 6 8717 8569 8570 8571 8593 8594 6 8717 8594 8720 8820 8821 8721 5 8719 8594 8595 8596 8721 6 8720 8596 8597 8722 8821 8719 6 8721 8597 8723 8821 8822 8823 5 8722 8597 8598 8724 8823 6 8723 8598 8599 8600 8725 8823 6 8724 8600 8726 8823 8824 8825 6 8725 8600 8601 8727 8825 8826 6 8726 8601 8602 8728 8826 8730 7 8727 8602 8603 8604 8605 8729 8730 6 8728 8605 8606 8730 8731 8732 5 8728 8729 8731 8826 8727 6 8730 8729 8732 8826 8828 8829 6 8731 8729 8606 8733 8829 8830 7 8732 8606 8607 8612 8613 8734 8830 6 8733 8613 8614 8735 8831 8830 6 8734 8614 8736 8831 8832 8737 5 8735 8614 8615 8617 8737 6 8736 8617 8738 8832 8735 8833 6 8737 8617 8618 8739 8833 8834 6 8738 8618 8740 8741 8834 8835 6 8739 8618 8619 8741 8742 8743 6 8739 8740 8742 8835 8836 8837 7 8741 8740 8743 8625 8837 8838 8626 6 8742 8740 8625 8621 8620 8619 6 8382 8383 8642 8745 8932 8933 5 8744 8642 8746 8933 8934 6 8745 8642 8643 8747 8934 8935 6 8746 8643 8644 8645 8748 8935 6 8747 8645 8749 8935 8936 8937 6 8748 8645 8646 8750 8937 8938 6 8749 8646 8647 8751 8938 8939 6 8750 8647 8648 8752 8939 8940 6 8751 8648 8649 8753 8940 8941 6 8752 8649 8650 8754 8941 8942 6 8753 8650 8755 8942 8943 8944 7 8754 8650 8651 8652 8653 8756 8944 5 8755 8653 8757 8944 8945 6 8756 8653 8654 8758 8945 8946 6 8757 8654 8655 8656 8759 8946 7 8758 8656 8657 8760 8946 8947 8948 5 8759 8657 8761 8948 8949 6 8760 8657 8658 8659 8762 8949 6 8761 8659 8763 8949 8950 8951 6 8762 8659 8660 8661 8764 8951 5 8763 8661 8662 8765 8951 7 8764 8662 8663 8664 8766 8951 8952 6 8765 8664 8665 8767 8952 8953 6 8766 8665 8768 8953 8954 8955 6 8767 8665 8666 8667 8769 8955 6 8768 8667 8668 8770 8955 8956 6 8769 8668 8771 8956 8957 8958 6 8770 8668 8669 8670 8772 8958 6 8771 8670 8671 8773 8958 8959 6 8772 8671 8672 8774 8959 8960 6 8773 8672 8673 8775 8960 8961 6 8774 8673 8674 8776 8961 8962 6 8775 8674 8675 8777 8962 8963 6 8776 8675 8778 8963 8964 8965 6 8777 8675 8676 8677 8779 8965 6 8778 8677 8678 8780 8965 8966 6 8779 8678 8679 8781 8966 8967 6 8780 8679 8680 8782 8967 8968 6 8781 8680 8681 8783 8968 8969 6 8782 8681 8682 8784 8969 8970 6 8783 8682 8685 8686 8785 8970 6 8784 8686 8786 8970 8971 8972 6 8785 8686 8687 8787 8972 8973 6 8786 8687 8788 8973 8974 8975 6 8787 8687 8688 8689 8789 8975 6 8788 8689 8690 8790 8975 8976 6 8789 8690 8691 8692 8791 8976 6 8790 8692 8792 8976 8977 8978 6 8791 8692 8693 8694 8793 8978 6 8792 8694 8794 8978 8979 8980 6 8793 8694 8795 8980 8981 8796 5 8794 8694 8695 8696 8796 6 8795 8696 8697 8797 8981 8794 6 8796 8697 8798 8981 8982 8983 6 8797 8697 8698 8799 8983 8800 5 8798 8698 8699 8700 8800 6 8799 8700 8801 8802 8983 8798 6 8800 8700 8701 8802 8803 8804 6 8800 8801 8803 8983 8984 8985 6 8802 8801 8804 8985 8986 8987 6 8803 8801 8701 8702 8805 8987 6 8804 8702 8703 8806 8987 8988 6 8805 8703 8807 8988 8989 8990 6 8806 8703 8704 8705 8808 8990 6 8807 8705 8706 8809 8990 8991 7 8808 8706 8707 8810 8993 8991 8994 5 8809 8707 8708 8811 8994 6 8810 8708 8812 8994 8995 8813 6 8811 8708 8709 8710 8711 8813 6 8812 8711 8814 8995 8811 8996 6 8813 8711 8815 8996 8997 8998 6 8814 8711 8712 8816 8998 8999 5 8815 8712 8713 8817 8999 7 8816 8713 8714 8715 8818 8999 9000 6 8817 8715 8819 9000 9001 9002 6 8818 8715 8716 8820 9002 9003 6 8819 8716 8717 8719 8821 9003 6 8820 8719 8721 8722 8822 9003 6 8821 8722 8823 9003 9004 8824 6 8822 8722 8723 8724 8725 8824 6 8823 8725 8825 9004 8822 9005 6 8824 8725 8726 8826 8827 9005 7 8825 8726 8727 8730 8731 8827 8828 6 8825 8826 8828 9005 9006 9007 6 8827 8826 8731 8829 9013 9007 6 8828 8731 8732 8830 8831 9013 5 8829 8732 8831 8734 8733 7 8829 8830 8734 8735 8832 9012 9013 6 8831 8735 8737 8833 9014 9012 7 8832 8737 8738 8834 9014 9015 9016 6 8833 8738 8739 8835 9016 9017 6 8834 8739 8741 8836 9017 9018 6 8835 8741 8837 9018 9019 9020 6 8836 8741 8742 8838 9020 9021 5 8837 8742 8626 8839 9021 6 8838 8626 8627 8840 9021 9022 6 8839 8627 8841 9022 9023 9024 6 8840 8627 8628 8842 9024 9025 6 8841 8628 8629 8843 9025 9026 6 8842 8629 8630 8631 8844 9026 6 8843 8631 8845 9026 9027 9031 6 8844 8631 8632 8634 8846 9031 6 8845 8634 8847 8848 9032 9031 6 8846 8634 8635 8638 8848 8849 6 8846 8847 8849 9032 9033 9034 6 8848 8847 8638 8850 9043 9034 6 8849 8638 8639 8851 9044 9043 6 8850 8639 8852 9044 9045 9046 6 8851 8639 8640 8853 9046 9049 6 8852 8640 7763 7764 8854 9049 6 8853 7764 7766 8320 8855 9049 6 8854 8320 8322 8856 9048 9049 6 8855 8322 8857 9048 9050 9051 5 8856 8322 8324 8858 9051 7 8857 8324 8325 8329 8859 9051 8861 6 8858 8329 8330 8331 8860 8861 6 8859 8331 8861 8862 8863 8332 6 8859 8860 8862 9051 8858 9052 6 8861 8860 8863 8864 9052 9053 6 8862 8860 8864 8865 8866 8332 6 8862 8863 8865 8878 9059 9053 6 8864 8863 8866 8867 8878 8879 6 8865 8863 8867 8334 8333 8332 6 8865 8866 8334 8868 8879 8880 6 8867 8334 8335 8336 8869 8880 6 8868 8336 8870 8880 8881 8872 6 8869 8336 8337 8339 8871 8872 6 8870 8339 8872 8873 8874 8875 6 8870 8871 8873 8895 8881 8869 6 8872 8871 8874 8897 8895 8898 6 8873 8871 8875 8898 8899 8903 6 8874 8871 8339 8340 8876 8903 6 8875 8340 8348 8903 8350 8349 6 8347 8341 8342 8343 8345 8346 5 8864 8865 8879 9059 8883 6 8878 8865 8867 8880 8882 8883 6 8879 8867 8868 8869 8881 8882 6 8880 8869 8882 8894 8895 8872 6 8880 8881 8879 8883 8884 8894 6 8879 8882 8884 8885 9059 8878 6 8883 8882 8885 8886 8893 8894 6 8883 8884 8886 8887 8888 9059 6 8885 8884 8887 8891 8892 8893 6 8885 8886 8888 8889 8890 8891 6 8885 8887 8889 9059 9058 9060 6 8888 8887 8890 9060 9061 9062 6 8889 8887 8891 9062 9063 9064 6 8890 8887 8886 8892 9064 9065 6 8891 8886 8893 9065 9066 9067 6 8892 8886 8884 8894 9067 8896 6 8893 8884 8882 8881 8895 8896 6 8894 8881 8896 8897 8873 8872 6 8894 8895 8897 9067 8893 9068 6 8896 8895 8873 8898 9068 9069 6 8897 8873 8874 8899 8900 9069 6 8898 8874 8900 8901 8902 8903 6 8898 8899 8901 9069 9070 9071 6 8900 8899 8902 9071 9072 8904 6 8901 8899 8903 8350 8351 8904 6 8902 8899 8874 8875 8876 8350 6 8902 8351 8352 8905 9072 8901 6 8904 8352 8906 9072 9073 9074 6 8905 8352 8353 8907 9074 9075 6 8906 8353 8354 8908 9075 9076 6 8907 8354 8355 8909 9076 9077 6 8908 8355 8910 9077 9078 8912 6 8909 8355 8356 8358 8911 8912 6 8910 8358 8912 8913 8361 8360 6 8910 8911 8913 9078 8909 9079 6 8912 8911 8361 8914 9079 9080 6 8913 8361 8362 8915 8916 9080 6 8914 8362 8363 8916 8917 8364 6 8914 8915 8917 9080 9081 9082 6 8916 8915 8364 8918 9082 9083 6 8917 8364 8365 8919 9083 9084 6 8918 8365 8366 8920 9084 9085 6 8919 8366 8367 8921 9094 9085 6 8920 8367 8368 8922 9094 9101 6 8921 8368 8369 8923 9101 9102 6 8922 8369 8370 8924 9102 9103 6 8923 8370 8371 8925 9103 9104 6 8924 8371 8926 9104 9105 9106 6 8925 8371 8372 8927 9106 9107 6 8926 8372 8373 8375 8928 9107 6 8927 8375 8929 9107 9108 8932 6 8928 8375 8376 8930 8932 8931 6 8929 8376 8377 8378 8380 8931 5 8930 8380 8381 8932 8929 8 8931 8381 8382 8744 8933 9108 8928 8929 5 8932 8744 8745 8934 9108 8 8933 8745 8746 8935 9108 9107 9106 9109 6 8934 8746 8747 8748 8936 9109 6 8935 8748 8937 9109 9110 9111 6 8936 8748 8749 8938 9111 9112 6 8937 8749 8750 8939 9112 9113 6 8938 8750 8751 8940 9113 9114 6 8939 8751 8752 8941 9114 9115 6 8940 8752 8753 8942 9115 9116 6 8941 8753 8754 8943 9116 9117 6 8942 8754 8944 9117 9118 8945 5 8943 8754 8755 8756 8945 7 8944 8756 8757 8946 9118 8943 9119 7 8945 8757 8758 8759 8947 9119 9120 5 8946 8759 8948 9120 9121 6 8947 8759 8760 8949 9121 9122 7 8948 8760 8761 8762 8950 9122 9123 6 8949 8762 8951 9123 9124 8952 6 8950 8762 8763 8764 8765 8952 6 8951 8765 8766 8953 9124 8950 6 8952 8766 8767 8954 9124 9125 6 8953 8767 8955 9125 9126 9127 6 8954 8767 8768 8769 8956 9127 6 8955 8769 8770 8957 9127 9128 6 8956 8770 8958 9128 9129 9130 6 8957 8770 8771 8772 8959 9130 6 8958 8772 8773 8960 9130 9131 6 8959 8773 8774 8961 9131 9132 6 8960 8774 8775 8962 9132 9133 6 8961 8775 8776 8963 9133 9134 6 8962 8776 8777 8964 9134 9135 6 8963 8777 8965 9135 9136 9137 6 8964 8777 8778 8779 8966 9137 6 8965 8779 8780 8967 9137 9138 6 8966 8780 8781 8968 9138 9139 6 8967 8781 8782 8969 9139 9140 6 8968 8782 8783 8970 9140 9141 7 8969 8783 8784 8785 8971 9141 9142 5 8970 8785 8972 9142 9143 7 8971 8785 8786 8973 9143 9144 9145 6 8972 8786 8787 8974 9145 9146 6 8973 8787 8975 9146 9147 9148 6 8974 8787 8788 8789 8976 9148 6 8975 8789 8790 8791 8977 9148 6 8976 8791 8978 9148 9149 9150 6 8977 8791 8792 8793 8979 9150 6 8978 8793 8980 9150 9151 9152 6 8979 8793 8794 8981 9152 9153 6 8980 8794 8796 8797 8982 9153 6 8981 8797 8983 9153 9154 8984 6 8982 8797 8798 8800 8802 8984 6 8983 8802 8985 9154 8982 9155 6 8984 8802 8803 8986 9155 9156 6 8985 8803 8987 9156 9157 9158 7 8986 8803 8804 8805 8988 9158 9159 5 8987 8805 8806 8989 9159 7 8988 8806 8990 8991 8992 9159 9160 5 8989 8806 8807 8808 8991 6 8990 8808 8989 8992 8993 8809 6 8989 8991 8993 9160 9161 9162 6 8992 8991 8809 8994 9165 9162 6 8993 8809 8810 8811 8995 9165 6 8994 8811 8813 8996 9165 9166 7 8995 8813 8814 8997 9166 9168 9169 5 8996 8814 8998 9169 9170 6 8997 8814 8815 8999 9170 9171 7 8998 8815 8816 8817 9000 9171 9172 5 8999 8817 8818 9001 9172 6 9000 8818 9002 9172 9173 9174 6 9001 8818 8819 9003 9174 9004 6 9002 8819 8820 8821 8822 9004 6 9003 8822 8824 9005 9174 9002 6 9004 8824 8825 8827 9006 9174 6 9005 8827 9007 9008 9009 9174 6 9006 8827 9008 9012 9013 8828 6 9006 9007 9009 9010 9011 9012 6 9006 9008 9010 9174 9173 9175 5 9009 9008 9011 9175 9178 6 9010 9008 9012 9014 9178 9015 7 9011 9008 9007 9013 9014 8832 8831 5 9012 9007 8831 8829 8828 5 9011 9012 8832 8833 9015 6 9014 8833 9016 9178 9011 9179 6 9015 8833 8834 9017 9182 9179 5 9016 8834 8835 9018 9182 7 9017 8835 8836 9019 9182 9183 9189 6 9018 8836 9020 9189 9190 9191 6 9019 8836 8837 9021 9191 9192 6 9020 8837 8838 8839 9022 9192 6 9021 8839 8840 9023 9192 9193 6 9022 8840 9024 9193 9196 9197 6 9023 8840 8841 9025 9197 9198 6 9024 8841 8842 9026 9198 9028 6 9025 8842 8843 8844 9027 9028 6 9026 8844 9028 9029 9030 9031 6 9026 9027 9029 9198 9025 9199 6 9028 9027 9030 9199 9200 9204 5 9029 9027 9031 9032 9204 6 9030 9027 8844 9032 8846 8845 7 9030 9031 8846 8848 9033 9204 9205 6 9032 8848 9034 9035 9205 9206 6 9033 8848 9035 9036 9043 8849 6 9033 9034 9036 9037 9038 9206 6 9035 9034 9037 9041 9042 9043 6 9035 9036 9038 9039 9040 9041 6 9035 9037 9039 9206 9207 9208 6 9038 9037 9040 9208 9209 9210 6 9039 9037 9041 9210 9063 9062 6 9040 9037 9036 9042 9062 9061 6 9041 9036 9043 9044 9061 9211 6 9042 9036 9034 8849 9044 8850 6 9042 9043 8850 8851 9045 9211 7 9044 8851 9046 9047 9056 9057 9211 6 9045 8851 8852 9047 9048 9049 6 9045 9046 9048 9054 9056 9050 6 9047 9046 9049 8855 8856 9050 6 9048 9046 8852 8855 8854 8853 6 9048 8856 9051 9052 9054 9047 6 9050 8856 8857 8858 8861 9052 6 9051 8861 8862 9053 9054 9050 6 9052 8862 9054 9055 9059 8864 6 9052 9053 9055 9056 9047 9050 6 9054 9053 9056 9057 9058 9059 5 9054 9055 9047 9045 9057 6 9045 9056 9055 9058 9060 9211 5 9057 9055 9059 8888 9060 8 9058 9055 9053 8864 8878 8883 8885 8888 6 9058 8888 8889 9061 9211 9057 6 9060 8889 9062 9041 9042 9211 6 9061 8889 8890 9063 9040 9041 6 9062 8890 9064 9210 9040 9212 6 9063 8890 8891 9065 9212 9213 6 9064 8891 8892 9066 9213 9214 6 9065 8892 9067 9214 9215 9216 6 9066 8892 8893 8896 9068 9216 6 9067 8896 8897 9069 9216 9217 6 9068 8897 8898 8900 9070 9217 6 9069 8900 9071 9217 9218 9219 6 9070 8900 8901 9072 9219 9220 7 9071 8901 8904 8905 9073 9220 9221 5 9072 8905 9074 9221 9222 7 9073 8905 8906 9075 9222 9223 9224 6 9074 8906 8907 9076 9224 9226 6 9075 8907 8908 9077 9226 9227 5 9076 8908 8909 9078 9227 7 9077 8909 8912 9079 9227 9228 9229 5 9078 8912 8913 9080 9229 6 9079 8913 8914 8916 9081 9229 6 9080 8916 9082 9229 9230 9231 6 9081 8916 8917 9083 9231 9232 6 9082 8917 8918 9084 9232 9233 6 9083 8918 8919 9085 9086 9233 6 9084 8919 9086 9087 9094 8920 6 9084 9085 9087 9088 9233 9234 6 9086 9085 9088 9089 9093 9094 6 9086 9087 9089 9090 9234 9235 6 9088 9087 9090 9091 9092 9093 6 9088 9089 9091 9096 9235 9236 6 9090 9089 9092 9096 9097 9098 6 9091 9089 9093 9098 9099 9100 6 9092 9089 9087 9094 9100 9101 6 9093 9087 9085 8920 8921 9101 5 8470 8471 8486 8477 8472 6 9090 9091 9097 9236 9237 9238 6 9096 9091 9098 9238 9239 9240 6 9097 9091 9092 9099 9240 9241 6 9098 9092 9100 9241 9242 9243 6 9099 9092 9093 9101 9243 9102 6 9100 9093 9094 8921 8922 9102 6 9101 8922 8923 9103 9243 9100 6 9102 8923 8924 9104 9243 9244 6 9103 8924 8925 9105 9244 9245 6 9104 8925 9106 9110 9245 9109 6 9105 8925 8926 9107 8934 9109 6 9106 8926 8927 8928 9108 8934 5 9107 8928 8932 8933 8934 6 9106 8934 8935 8936 9110 9105 5 9109 8936 9111 9245 9105 7 9110 8936 8937 9112 9246 9245 9349 6 9111 8937 8938 9113 9351 9349 5 9112 8938 8939 9114 9351 6 9113 8939 8940 9115 9351 9352 6 9114 8940 8941 9116 9352 9353 6 9115 8941 8942 9117 9353 9354 6 9116 8942 8943 9118 9247 9354 6 9117 8943 8945 9119 9247 9248 6 9118 8945 8946 9120 9248 9249 5 9119 8946 8947 9121 9249 7 9120 8947 8948 9122 9249 9250 9251 6 9121 8948 8949 9123 9251 9252 5 9122 8949 8950 9124 9252 6 9123 8950 8952 8953 9125 9252 6 9124 8953 8954 9126 9252 9253 6 9125 8954 9127 9253 9254 9255 6 9126 8954 8955 8956 9128 9255 6 9127 8956 8957 9129 9255 9256 6 9128 8957 9130 9256 9257 9258 6 9129 8957 8958 8959 9131 9258 6 9130 8959 8960 9132 9258 9259 6 9131 8960 8961 9133 9259 9260 6 9132 8961 8962 9134 9260 9261 6 9133 8962 8963 9135 9261 9262 6 9134 8963 8964 9136 9262 9263 6 9135 8964 9137 9263 9264 9265 6 9136 8964 8965 8966 9138 9265 6 9137 8966 8967 9139 9265 9266 6 9138 8967 8968 9140 9266 9267 6 9139 8968 8969 9141 9267 9268 6 9140 8969 8970 9142 9268 9269 5 9141 8970 8971 9143 9269 7 9142 8971 8972 9144 9269 9270 9271 6 9143 8972 9145 9271 9272 9273 5 9144 8972 8973 9146 9273 6 9145 8973 8974 9147 9273 9274 6 9146 8974 9148 9274 9275 9149 6 9147 8974 8975 8976 8977 9149 6 9148 8977 9150 9275 9147 9276 6 9149 8977 8978 8979 9151 9276 6 9150 8979 9152 9276 9277 9278 6 9151 8979 8980 9153 9278 9279 7 9152 8980 8981 8982 9154 9279 9280 6 9153 8982 8984 9155 9280 9281 6 9154 8984 8985 9156 9281 9282 6 9155 8985 8986 9157 9282 9283 6 9156 8986 9158 9283 9284 9285 6 9157 8986 8987 9159 9285 9286 6 9158 8987 8988 8989 9160 9286 6 9159 8989 8992 9161 9286 9287 6 9160 8992 9162 9163 9287 9288 6 9161 8992 9163 9164 9165 8993 6 9161 9162 9164 9288 9289 9290 6 9163 9162 9165 9166 9167 9290 6 9164 9162 8993 8994 8995 9166 6 9165 8995 8996 9164 9167 9168 6 9164 9166 9168 9290 9291 9187 6 9167 9166 8996 9169 9187 9186 6 9168 8996 8997 9170 9186 9185 7 9169 8997 8998 9171 9185 9180 9177 6 9170 8998 8999 9172 9177 9176 6 9171 8999 9000 9001 9173 9176 6 9172 9001 9174 9009 9175 9176 7 9173 9001 9002 9004 9005 9006 9009 6 9173 9009 9010 9176 9177 9178 5 9173 9175 9177 9171 9172 6 9176 9175 9178 9180 9170 9171 7 9177 9175 9010 9011 9015 9179 9180 6 9178 9015 9180 9181 9182 9016 6 9178 9179 9181 9185 9170 9177 6 9180 9179 9182 9183 9184 9185 6 9181 9179 9016 9017 9018 9183 6 9182 9018 9181 9184 9188 9189 6 9181 9183 9185 9186 9187 9188 6 9181 9184 9186 9169 9170 9180 5 9185 9184 9187 9168 9169 6 9186 9184 9188 9291 9167 9168 6 9187 9184 9183 9189 9291 9292 6 9188 9183 9018 9019 9190 9292 5 9189 9019 9191 9292 9293 6 9190 9019 9020 9192 9293 9194 6 9191 9020 9021 9022 9193 9194 6 9192 9022 9023 9194 9195 9196 6 9192 9193 9195 9293 9191 9294 6 9194 9193 9196 9294 9295 9296 6 9195 9193 9023 9197 9296 9297 6 9196 9023 9024 9198 9303 9297 7 9197 9024 9025 9028 9199 9303 9304 6 9198 9028 9029 9200 9201 9304 6 9199 9029 9201 9202 9203 9204 6 9199 9200 9202 9304 9302 9305 6 9201 9200 9203 9305 9306 9307 6 9202 9200 9204 9307 9308 9205 6 9203 9200 9029 9030 9032 9205 7 9204 9032 9033 9206 9308 9203 9207 5 9205 9033 9035 9038 9207 6 9206 9038 9208 9308 9205 9309 6 9207 9038 9039 9209 9309 9310 6 9208 9039 9210 9310 9311 9315 6 9209 9039 9040 9063 9212 9315 6 9061 9042 9044 9060 9057 9045 6 9210 9063 9064 9213 9315 9316 6 9212 9064 9065 9214 9316 9317 6 9213 9065 9066 9215 9320 9317 6 9214 9066 9216 9320 9321 9322 6 9215 9066 9067 9068 9217 9322 6 9216 9068 9069 9070 9218 9322 7 9217 9070 9219 9322 9321 9323 9324 5 9218 9070 9071 9220 9324 7 9219 9071 9072 9221 9324 9325 9326 5 9220 9072 9073 9222 9326 7 9221 9073 9074 9223 9326 9327 9328 6 9222 9074 9224 9225 9328 9329 5 9223 9074 9075 9225 9226 6 9223 9224 9226 9329 9330 9331 6 9225 9224 9075 9076 9227 9331 7 9226 9076 9077 9078 9228 9331 9332 6 9227 9078 9229 9332 9333 9230 6 9228 9078 9079 9080 9081 9230 7 9229 9081 9231 9333 9228 9334 9335 6 9230 9081 9082 9232 9335 9336 6 9231 9082 9083 9233 9336 9337 7 9232 9083 9084 9086 9234 9337 9338 5 9233 9086 9088 9235 9338 7 9234 9088 9090 9236 9338 9339 9340 5 9235 9090 9096 9237 9340 7 9236 9096 9238 9340 9341 9342 9343 6 9237 9096 9097 9239 9343 9344 6 9238 9097 9240 9344 9345 9346 6 9239 9097 9098 9241 9346 9347 6 9240 9098 9099 9242 9347 9348 6 9241 9099 9243 9348 9246 9244 6 9242 9099 9100 9102 9103 9244 6 9243 9103 9104 9245 9246 9242 6 9244 9104 9246 9111 9110 9105 6 9244 9245 9111 9348 9242 9349 6 9117 9118 9248 9354 9355 9356 6 9247 9118 9119 9249 9356 9357 6 9248 9119 9120 9121 9250 9357 6 9249 9121 9251 9357 9358 9359 6 9250 9121 9122 9252 9359 9253 6 9251 9122 9123 9124 9125 9253 7 9252 9125 9126 9254 9359 9251 9360 5 9253 9126 9255 9360 9361 7 9254 9126 9127 9128 9256 9361 9362 6 9255 9128 9129 9257 9362 9363 6 9256 9129 9258 9363 9364 9365 6 9257 9129 9130 9131 9259 9365 7 9258 9131 9132 9260 9365 9366 9367 6 9259 9132 9133 9261 9367 9368 6 9260 9133 9134 9262 9368 9369 6 9261 9134 9135 9263 9369 9370 6 9262 9135 9136 9264 9370 9371 6 9263 9136 9265 9371 9372 9373 6 9264 9136 9137 9138 9266 9373 6 9265 9138 9139 9267 9373 9374 6 9266 9139 9140 9268 9374 9375 6 9267 9140 9141 9269 9375 9376 7 9268 9141 9142 9143 9270 9376 9377 5 9269 9143 9271 9377 9378 6 9270 9143 9144 9272 9378 9382 6 9271 9144 9273 9382 9383 9384 6 9272 9144 9145 9146 9274 9384 6 9273 9146 9147 9275 9384 9385 6 9274 9147 9149 9276 9385 9386 7 9275 9149 9150 9151 9277 9386 9387 5 9276 9151 9278 9387 9389 6 9277 9151 9152 9279 9389 9390 6 9278 9152 9153 9280 9390 9391 6 9279 9153 9154 9281 9391 9392 5 9280 9154 9155 9282 9392 6 9281 9155 9156 9283 9394 9392 6 9282 9156 9157 9284 9394 9395 6 9283 9157 9285 9395 9396 9397 6 9284 9157 9158 9286 9397 9398 6 9285 9158 9159 9160 9287 9398 6 9286 9160 9161 9288 9398 9399 5 9287 9161 9163 9289 9399 7 9288 9163 9290 9399 9400 9401 9402 6 9289 9163 9164 9167 9291 9402 7 9290 9167 9187 9188 9292 9403 9402 6 9291 9188 9189 9190 9293 9403 7 9292 9190 9191 9194 9294 9403 9401 6 9293 9194 9195 9295 9401 9404 6 9294 9195 9296 9404 9405 9406 6 9295 9195 9196 9297 9298 9406 6 9296 9196 9298 9299 9303 9197 6 9296 9297 9299 9300 9406 9407 6 9298 9297 9300 9301 9302 9303 6 9298 9299 9301 9410 9407 9411 6 9300 9299 9302 9411 9412 9413 7 9301 9299 9303 9304 9201 9305 9413 6 9302 9299 9297 9197 9198 9304 5 9303 9198 9199 9201 9302 5 9302 9201 9202 9306 9413 7 9305 9202 9307 9413 9414 9415 9419 5 9306 9202 9203 9308 9419 6 9307 9203 9205 9207 9309 9419 6 9308 9207 9208 9310 9418 9419 6 9309 9208 9209 9311 9312 9418 6 9310 9209 9312 9313 9314 9315 6 9310 9311 9313 9417 9418 9420 6 9312 9311 9314 9420 9421 9425 7 9313 9311 9315 9425 9426 9318 9316 6 9314 9311 9209 9210 9212 9316 6 9315 9212 9213 9317 9318 9314 6 9316 9213 9318 9319 9320 9214 6 9316 9317 9319 9426 9314 9427 6 9318 9317 9320 9427 9428 9429 6 9319 9317 9214 9215 9321 9429 6 9320 9215 9322 9218 9323 9429 5 9321 9215 9216 9217 9218 6 9321 9218 9324 9429 9430 9431 6 9323 9218 9219 9220 9325 9431 6 9324 9220 9326 9431 9432 9433 6 9325 9220 9221 9222 9327 9433 6 9326 9222 9328 9433 9434 9435 6 9327 9222 9223 9329 9435 9436 5 9328 9223 9225 9330 9436 7 9329 9225 9331 9436 9437 9438 9439 6 9330 9225 9226 9227 9332 9439 6 9331 9227 9228 9333 9439 9440 6 9332 9228 9230 9334 9443 9440 6 9333 9230 9335 9443 9444 9447 5 9334 9230 9231 9336 9447 6 9335 9231 9232 9337 9447 9448 6 9336 9232 9233 9338 9448 9449 6 9337 9233 9234 9235 9339 9449 6 9338 9235 9340 9449 9450 9451 6 9339 9235 9236 9237 9341 9451 6 9340 9237 9342 9451 9452 9453 6 9341 9237 9343 9453 9454 9455 6 9342 9237 9238 9344 9455 9456 5 9343 9238 9239 9345 9456 7 9344 9239 9346 9456 9457 9458 9459 6 9345 9239 9240 9347 9459 9350 5 9346 9240 9241 9348 9350 6 9347 9241 9242 9246 9349 9350 6 9348 9246 9350 9351 9112 9111 7 9348 9349 9351 9459 9346 9347 9352 6 9350 9349 9112 9113 9114 9352 7 9351 9114 9115 9353 9459 9350 9460 6 9352 9115 9116 9354 9460 9461 6 9353 9116 9117 9247 9355 9461 6 9354 9247 9356 9461 9462 9463 6 9355 9247 9248 9357 9463 9464 6 9356 9248 9249 9250 9358 9464 6 9357 9250 9359 9464 9465 9466 6 9358 9250 9251 9253 9360 9466 5 9359 9253 9254 9361 9466 7 9360 9254 9255 9362 9466 9467 9468 5 9361 9255 9256 9363 9468 6 9362 9256 9257 9364 9468 9469 6 9363 9257 9365 9469 9470 9471 6 9364 9257 9258 9259 9366 9471 6 9365 9259 9367 9471 9472 9473 5 9366 9259 9260 9368 9473 6 9367 9260 9261 9369 9473 9474 6 9368 9261 9262 9370 9474 9475 6 9369 9262 9263 9371 9475 9476 6 9370 9263 9264 9372 9476 9477 6 9371 9264 9373 9477 9478 9479 6 9372 9264 9265 9266 9374 9479 6 9373 9266 9267 9375 9479 9480 6 9374 9267 9268 9376 9480 9481 6 9375 9268 9269 9377 9481 9482 6 9376 9269 9270 9378 9379 9482 7 9377 9270 9271 9379 9380 9381 9382 5 9377 9378 9380 9482 9483 6 9379 9378 9381 9483 9484 9485 6 9380 9378 9382 9485 9486 9383 5 9381 9378 9271 9272 9383 6 9382 9272 9384 9486 9381 9487 7 9383 9272 9273 9274 9385 9487 9488 6 9384 9274 9275 9386 9488 9489 6 9385 9275 9276 9387 9388 9489 5 9386 9276 9277 9388 9389 6 9386 9387 9389 9489 9490 9491 7 9388 9387 9277 9278 9390 9491 9492 6 9389 9278 9279 9391 9492 9493 6 9390 9279 9280 9392 9393 9493 6 9391 9280 9393 9394 9282 9281 6 9391 9392 9394 9493 9494 9495 6 9393 9392 9282 9283 9395 9495 6 9394 9283 9284 9396 9495 9496 6 9395 9284 9397 9496 9497 9498 6 9396 9284 9285 9398 9499 9498 6 9397 9285 9286 9287 9399 9499 6 9398 9287 9288 9289 9400 9499 6 9399 9289 9401 9499 9405 9404 7 9400 9289 9402 9403 9293 9294 9404 5 9401 9289 9403 9291 9290 5 9401 9402 9291 9292 9293 5 9401 9294 9295 9405 9400 6 9404 9295 9406 9499 9400 9408 6 9405 9295 9296 9298 9407 9408 6 9406 9298 9408 9409 9410 9300 6 9406 9407 9409 9498 9499 9405 6 9408 9407 9410 9497 9498 9500 6 9409 9407 9300 9411 9500 9501 6 9410 9300 9301 9412 9501 9502 6 9411 9301 9413 9502 9503 9414 6 9412 9301 9302 9305 9306 9414 6 9413 9306 9415 9416 9503 9412 6 9414 9306 9416 9417 9418 9419 6 9414 9415 9417 9503 9504 9505 6 9416 9415 9418 9312 9420 9505 6 9417 9415 9419 9309 9310 9312 6 9418 9415 9309 9308 9307 9306 6 9417 9312 9313 9421 9422 9505 6 9420 9313 9422 9423 9424 9425 6 9420 9421 9423 9505 9506 9507 6 9422 9421 9424 9507 9508 9509 6 9423 9421 9425 9512 9509 9513 6 9424 9421 9313 9314 9426 9513 5 9425 9314 9318 9427 9513 6 9426 9318 9319 9428 9513 9514 6 9427 9319 9429 9514 9515 9430 6 9428 9319 9320 9321 9323 9430 6 9429 9323 9431 9518 9515 9428 6 9430 9323 9324 9325 9432 9518 6 9431 9325 9433 9525 9518 9526 6 9432 9325 9326 9327 9434 9526 6 9433 9327 9435 9526 9527 9528 6 9434 9327 9328 9436 9528 9529 6 9435 9328 9329 9330 9437 9529 6 9436 9330 9438 9529 9531 9532 6 9437 9330 9439 9532 9533 9441 6 9438 9330 9331 9332 9440 9441 6 9439 9332 9441 9442 9443 9333 5 9439 9440 9442 9533 9438 7 9441 9440 9443 9444 9445 9533 9534 5 9442 9440 9333 9334 9444 6 9443 9334 9442 9445 9446 9447 5 9442 9444 9446 9534 9535 6 9445 9444 9447 9535 9536 9537 7 9446 9444 9334 9335 9336 9448 9537 6 9447 9336 9337 9449 9537 9538 6 9448 9337 9338 9339 9450 9538 6 9449 9339 9451 9538 9539 9452 5 9450 9339 9340 9341 9452 7 9451 9341 9453 9539 9450 9540 9541 6 9452 9341 9342 9454 9541 9542 6 9453 9342 9455 9542 9543 9544 6 9454 9342 9343 9456 9544 9545 6 9455 9343 9344 9345 9457 9545 6 9456 9345 9458 9545 9546 9462 6 9457 9345 9459 9462 9461 9460 6 9458 9345 9346 9350 9352 9460 5 9459 9352 9353 9461 9458 6 9460 9353 9354 9355 9462 9458 6 9461 9355 9463 9546 9457 9458 5 9462 9355 9356 9464 9546 7 9463 9356 9357 9358 9465 9546 9547 6 9464 9358 9466 9547 9548 9549 7 9465 9358 9359 9360 9361 9467 9549 6 9466 9361 9468 9549 9550 9551 6 9467 9361 9362 9363 9469 9551 6 9468 9363 9364 9470 9551 9552 6 9469 9364 9471 9552 9553 9554 6 9470 9364 9365 9366 9472 9554 6 9471 9366 9473 9554 9555 9556 6 9472 9366 9367 9368 9474 9556 6 9473 9368 9369 9475 9556 9557 6 9474 9369 9370 9476 9557 9558 6 9475 9370 9371 9477 9558 9559 6 9476 9371 9372 9478 9559 9560 6 9477 9372 9479 9560 9561 9562 6 9478 9372 9373 9374 9480 9562 6 9479 9374 9375 9481 9562 9563 6 9480 9375 9376 9482 9563 9564 6 9481 9376 9377 9379 9483 9564 6 9482 9379 9380 9484 9564 9565 6 9483 9380 9485 9565 9566 9567 6 9484 9380 9381 9486 9567 9568 6 9485 9381 9383 9487 9568 9569 6 9486 9383 9384 9488 9569 9570 6 9487 9384 9385 9489 9570 9571 6 9488 9385 9386 9388 9490 9571 6 9489 9388 9491 9571 9572 9573 6 9490 9388 9389 9492 9573 9574 6 9491 9389 9390 9493 9574 9575 6 9492 9390 9391 9393 9494 9575 6 9493 9393 9495 9575 9576 9577 6 9494 9393 9394 9395 9496 9577 6 9495 9395 9396 9497 9577 9578 6 9496 9396 9498 9409 9500 9578 6 9497 9396 9409 9408 9499 9397 7 9408 9498 9397 9398 9399 9400 9405 5 9497 9409 9410 9501 9578 7 9500 9410 9411 9502 9578 9579 9580 6 9501 9411 9412 9503 9580 9581 6 9502 9412 9414 9416 9504 9581 6 9503 9416 9505 9581 9582 9583 7 9504 9416 9417 9420 9422 9506 9583 5 9505 9422 9507 9583 9584 6 9506 9422 9423 9508 9584 9585 6 9507 9423 9509 9510 9585 9586 6 9508 9423 9510 9511 9512 9424 6 9508 9509 9511 9586 9587 9588 6 9510 9509 9512 9519 9588 9522 6 9511 9509 9424 9513 9519 9520 7 9512 9424 9425 9426 9427 9514 9520 6 9513 9427 9428 9515 9516 9520 6 9514 9428 9516 9517 9518 9430 6 9514 9515 9517 9520 9519 9521 6 9516 9515 9518 9524 9521 9525 6 9517 9515 9430 9431 9525 9432 6 9511 9512 9520 9516 9521 9522 5 9519 9512 9513 9514 9516 6 9519 9516 9522 9523 9524 9517 6 9519 9521 9523 9588 9511 9589 6 9522 9521 9524 9589 9590 9591 6 9523 9521 9517 9525 9591 9592 6 9524 9517 9518 9432 9526 9592 7 9525 9432 9433 9434 9527 9592 9593 5 9526 9434 9528 9593 9594 6 9527 9434 9435 9529 9530 9594 6 9528 9435 9436 9437 9530 9531 6 9528 9529 9531 9594 9595 9596 6 9530 9529 9437 9532 9596 9597 6 9531 9437 9438 9533 9597 9598 7 9532 9438 9441 9442 9534 9598 9599 5 9533 9442 9445 9535 9599 7 9534 9445 9446 9536 9599 9600 9601 6 9535 9446 9537 9601 9602 9603 7 9536 9446 9447 9448 9538 9603 9604 6 9537 9448 9449 9450 9539 9604 6 9538 9450 9452 9540 9604 9605 6 9539 9452 9541 9605 9606 9607 6 9540 9452 9453 9542 9607 9608 5 9541 9453 9454 9543 9608 7 9542 9454 9544 9608 9609 9610 9611 5 9543 9454 9455 9545 9611 7 9544 9455 9456 9457 9546 9611 9547 6 9545 9457 9462 9463 9464 9547 6 9546 9464 9465 9548 9611 9545 6 9547 9465 9549 9611 9610 9550 5 9548 9465 9466 9467 9550 6 9549 9467 9551 9610 9548 9612 6 9550 9467 9468 9469 9552 9612 6 9551 9469 9470 9553 9612 9613 6 9552 9470 9554 9613 9614 9615 6 9553 9470 9471 9472 9555 9615 6 9554 9472 9556 9615 9616 9617 6 9555 9472 9473 9474 9557 9617 6 9556 9474 9475 9558 9617 9618 6 9557 9475 9476 9559 9618 9619 6 9558 9476 9477 9560 9619 9620 6 9559 9477 9478 9561 9620 9621 6 9560 9478 9562 9621 9622 9623 6 9561 9478 9479 9480 9563 9623 6 9562 9480 9481 9564 9623 9624 6 9563 9481 9482 9483 9565 9624 6 9564 9483 9484 9566 9624 9625 6 9565 9484 9567 9625 9626 9627 6 9566 9484 9485 9568 9627 9628 6 9567 9485 9486 9569 9628 9629 7 9568 9486 9487 9570 9629 9630 9631 6 9569 9487 9488 9571 9631 9632 6 9570 9488 9489 9490 9572 9632 6 9571 9490 9573 9632 9633 9634 6 9572 9490 9491 9574 9634 9635 6 9573 9491 9492 9575 9635 9636 6 9574 9492 9493 9494 9576 9636 6 9575 9494 9577 9636 9637 9579 6 9576 9494 9495 9496 9578 9579 6 9577 9496 9497 9500 9501 9579 6 9578 9501 9580 9637 9576 9577 6 9579 9501 9502 9581 9637 9582 5 9580 9502 9503 9504 9582 6 9581 9504 9583 9637 9580 9638 6 9582 9504 9505 9506 9584 9638 6 9583 9506 9507 9585 9638 9639 6 9584 9507 9508 9586 9639 9634 6 9585 9508 9510 9587 9634 9633 6 9586 9510 9588 9633 9640 9630 6 9587 9510 9511 9522 9589 9630 6 9588 9522 9523 9590 9630 9629 6 9589 9523 9591 9629 9628 9641 6 9590 9523 9524 9592 9641 9642 6 9591 9524 9525 9526 9593 9642 6 9592 9526 9527 9594 9642 9643 7 9593 9527 9528 9530 9595 9643 9644 5 9594 9530 9596 9644 9645 6 9595 9530 9531 9597 9645 9646 6 9596 9531 9532 9598 9646 9647 6 9597 9532 9533 9599 9647 9648 6 9598 9533 9534 9535 9600 9648 5 9599 9535 9601 9648 9649 7 9600 9535 9536 9602 9649 9650 9651 5 9601 9536 9603 9651 9652 6 9602 9536 9537 9604 9652 9605 5 9603 9537 9538 9539 9605 6 9604 9539 9540 9606 9652 9603 6 9605 9540 9607 9652 9653 9654 6 9606 9540 9541 9608 9654 9614 6 9607 9541 9542 9543 9609 9614 6 9608 9543 9610 9614 9613 9612 6 9609 9543 9611 9548 9550 9612 6 9610 9543 9544 9545 9547 9548 6 9610 9550 9551 9552 9613 9609 5 9612 9552 9553 9614 9609 7 9613 9553 9615 9654 9607 9608 9609 6 9614 9553 9554 9555 9616 9654 6 9615 9555 9617 9654 9653 9655 6 9616 9555 9556 9557 9618 9655 6 9617 9557 9558 9619 9655 9656 6 9618 9558 9559 9620 9656 9657 6 9619 9559 9560 9621 9657 9658 6 9620 9560 9561 9622 9658 9659 6 9621 9561 9623 9659 9660 9661 6 9622 9561 9562 9563 9624 9661 6 9623 9563 9564 9565 9625 9661 7 9624 9565 9566 9626 9661 9662 9663 5 9625 9566 9627 9663 9664 7 9626 9566 9567 9628 9664 9665 9641 6 9627 9567 9568 9629 9590 9641 6 9628 9568 9569 9630 9589 9590 7 9629 9569 9631 9640 9587 9588 9589 5 9630 9569 9570 9632 9640 6 9631 9570 9571 9572 9633 9640 6 9632 9572 9634 9586 9587 9640 7 9633 9572 9573 9635 9639 9585 9586 6 9634 9573 9574 9636 9638 9639 6 9635 9574 9575 9576 9637 9638 6 9636 9576 9579 9580 9582 9638 7 9637 9582 9583 9584 9639 9636 9635 5 9638 9584 9585 9634 9635 5 9633 9587 9630 9631 9632 6 9628 9590 9591 9642 9665 9627 6 9641 9591 9592 9593 9643 9665 6 9642 9593 9594 9644 9665 9664 6 9643 9594 9595 9645 9664 9663 7 9644 9595 9596 9646 9663 9662 9666 7 9645 9596 9597 9647 9666 9660 9667 6 9646 9597 9598 9648 9667 9668 6 9647 9598 9599 9600 9649 9668 6 9648 9600 9601 9650 9668 9669 6 9649 9601 9651 9669 9657 9656 6 9650 9601 9602 9652 9656 9670 7 9651 9602 9603 9605 9606 9653 9670 6 9652 9606 9654 9616 9655 9670 6 9653 9606 9607 9614 9615 9616 6 9653 9616 9617 9618 9656 9670 7 9655 9618 9619 9657 9650 9651 9670 6 9656 9619 9620 9658 9669 9650 5 9657 9620 9621 9659 9669 6 9658 9621 9622 9660 9669 9667 6 9659 9622 9661 9666 9646 9667 7 9660 9622 9623 9624 9625 9662 9666 5 9661 9625 9663 9645 9666 6 9662 9625 9626 9664 9644 9645 6 9663 9626 9627 9665 9643 9644 5 9664 9627 9641 9642 9643 5 9662 9645 9646 9660 9661 6 9660 9646 9647 9668 9669 9659 5 9667 9647 9648 9649 9669 7 9668 9649 9650 9657 9658 9659 9667 5 9656 9651 9652 9653 9655 6 6654 6651 6652 9672 9692 9682 6 9671 6652 9673 9677 9681 9682 6 9672 6652 9674 9675 9676 9677 6 9673 6652 9675 6650 9728 6366 6 9673 9674 9676 9726 9727 9728 6 9673 9675 9677 9678 9679 9726 6 9673 9676 9678 9680 9681 9672 5 9677 9676 9679 5236 9680 7 9678 9676 5236 9735 4520 9726 9734 6 9678 5236 5237 9677 9681 9684 7 9677 9680 9672 9682 9683 4655 9684 6 9672 9681 9683 9692 9671 9686 5 9682 9681 4655 4656 9686 6 4655 9681 9680 5237 4653 9685 6 4653 9684 4651 423 5238 5237 6 9683 4656 9687 9688 9692 9682 6 9686 4656 9688 3170 9689 4657 6 9686 9687 3170 3171 9692 3173 7 3170 9687 4657 9690 3169 2844 9691 5 9689 4657 5381 431 9691 6 2844 9689 9690 431 2842 430 6 9686 9688 3173 6654 9671 9682 6 6476 6479 6475 9780 9775 9781 6 6461 6462 6466 6468 6378 6379 6 5863 5864 9696 9703 9704 9701 6 9695 5864 5865 9697 5720 9701 5 9696 5865 5866 5719 5720 6 5719 5866 5867 5868 9699 9700 6 9698 5868 9700 5696 5695 5869 5 9698 9699 5696 5697 5719 6 9696 5720 5721 9702 9703 9695 5 9701 5721 5722 5725 9703 6 9702 5725 6096 9704 9695 9701 6 9703 6096 6384 9695 5863 5862 6 6491 2253 416 2195 6489 6490 7 6489 2196 6488 6481 2197 9774 9779 5 2252 6492 3337 6493 3336 6 3336 6493 3335 6500 6494 6495 6 6503 6504 9710 2190 9712 9713 6 6503 9709 2190 6502 9711 2191 6 6502 9710 6501 2191 2192 2513 7 9709 6504 6513 9713 9716 9717 9718 5 9709 9712 2190 9714 9716 6 2190 9713 2188 2198 9715 9716 6 2198 9714 9716 2216 2217 9721 6 9715 9714 9713 9712 9717 2216 7 9716 9712 9718 9719 9720 2215 2216 6 9717 9712 6513 6514 6515 9719 5 9718 6515 6517 9720 9717 5 9719 6517 9717 2215 6523 6 9715 2217 2218 2201 2199 2198 6 6670 6776 9723 9724 6657 6659 5 9722 6776 9724 9725 9799 6 9722 9723 9725 6647 6657 6656 6 9724 9723 6647 6646 9800 9799 6 9676 9675 9727 9679 9734 9736 6 9726 9675 9728 9730 9736 9729 6 9727 9675 9674 6366 6367 9729 6 9728 6367 6369 6371 9730 9727 6 9729 6371 9731 9732 9736 9727 6 9730 6371 6372 6376 6468 9732 6 9731 6468 6467 9733 9736 9730 6 9732 6467 6469 7511 9734 9736 6 9733 7511 9735 9736 9679 9726 6 9734 7511 7509 4519 4520 9679 6 9733 9734 9732 9730 9727 9726 6 6042 6040 6039 6020 5873 5875 6 6133 6399 6393 6394 6116 9739 6 9738 6116 6117 6133 6132 6123 6 570 572 9741 9745 569 9744 6 9740 572 574 9742 9743 9744 6 9741 574 917 918 9743 919 6 9741 9742 919 9744 922 920 6 9741 9743 922 564 9745 9740 6 9744 564 565 568 569 9740 6 7206 7207 9747 7219 7218 7217 6 9746 7207 7208 7214 7217 7215 6 3492 3493 3497 3503 6707 6556 5 6707 3503 9750 3504 6711 5 6707 9749 6711 6708 6706 5 6683 5158 4668 6682 9762 5 3202 3471 3411 3201 3412 6 5933 5911 5916 5917 9756 5932 5 4916 4918 9755 4881 4880 7 9754 4918 4912 4881 9757 4905 9760 7 9753 5917 5932 5922 5921 5920 9759 6 4881 9755 9758 4896 4898 9760 5 4881 9757 4896 4885 4882 5 5920 9756 5919 5917 5918 6 9755 4905 4902 4899 4898 9757 6 4639 4913 4876 4873 4870 4869 7 6682 9751 4668 4669 9763 4561 9793 5 9762 4669 4547 4549 4561 5 8469 8470 9765 9766 8487 5 8469 9764 9766 7727 7963 7 9765 9764 8487 7715 7716 7724 7727 6 8024 8022 7739 7740 7741 7743 5 7724 7716 7717 7720 7722 6 428 7501 7503 9770 47 46 6 9769 7503 9771 9773 45 46 7 9770 7503 7504 9772 9773 9775 9781 7 2197 44 2 9773 9771 9774 9775 5 9772 2 9771 9770 45 6 2197 9772 9775 9706 9779 9780 6 9774 9772 9771 9780 9693 9781 6 7254 7257 7524 7521 7518 7517 6 2096 2084 2085 6094 3139 3132 5 6639 6640 6643 6788 6786 5 9706 9774 9780 6479 6481 5 9779 9774 9775 9693 6479 5 9693 9775 6475 9771 7504 6 3853 3130 27 26 1527 3131 6 6788 6643 6644 9784 6790 6171 5 9783 6644 6169 6170 6171 6 4397 4530 4396 4122 4120 4531 6 6638 6784 6780 6637 6636 6772 6 4119 3530 3532 9788 9790 4121 6 9787 3532 3534 9789 7175 9790 6 9788 3534 3536 7179 7176 7175 6 9788 7175 9787 4121 4123 7173 5 7671 7696 7697 7699 7670 6 7776 3146 4232 3414 3415 7777 6 4561 6676 6677 6678 6682 9762 6 3660 3661 4909 9795 4370 4372 5 9794 4909 4643 4371 4370 6 5544 5546 5701 5541 5542 5543 6 6178 6179 9798 9799 6182 9800 6 6783 6178 9797 9799 6777 6781 7 9798 9797 6777 9800 9725 9723 6776 6 9797 6182 6184 6646 9725 9799 scotch-6.0.4.dfsg/src/check/data/m16x16_b1.grf0000644002563400244210000000760712374701360023707 0ustar trophimeutilisateurs du domaine0 256 960 1 000 2 2 17 3 1 3 18 3 2 4 19 3 3 5 20 3 4 6 21 3 5 7 22 3 6 8 23 3 7 9 24 3 8 10 25 3 9 11 26 3 10 12 27 3 11 13 28 3 12 14 29 3 13 15 30 3 14 16 31 2 15 32 3 1 18 33 4 2 17 19 34 4 3 18 20 35 4 4 19 21 36 4 5 20 22 37 4 6 21 23 38 4 7 22 24 39 4 8 23 25 40 4 9 24 26 41 4 10 25 27 42 4 11 26 28 43 4 12 27 29 44 4 13 28 30 45 4 14 29 31 46 4 15 30 32 47 3 16 31 48 3 17 34 49 4 18 33 35 50 4 19 34 36 51 4 20 35 37 52 4 21 36 38 53 4 22 37 39 54 4 23 38 40 55 4 24 39 41 56 4 25 40 42 57 4 26 41 43 58 4 27 42 44 59 4 28 43 45 60 4 29 44 46 61 4 30 45 47 62 4 31 46 48 63 3 32 47 64 3 33 50 65 4 34 49 51 66 4 35 50 52 67 4 36 51 53 68 4 37 52 54 69 4 38 53 55 70 4 39 54 56 71 4 40 55 57 72 4 41 56 58 73 4 42 57 59 74 4 43 58 60 75 4 44 59 61 76 4 45 60 62 77 4 46 61 63 78 4 47 62 64 79 3 48 63 80 3 49 66 81 4 50 65 67 82 4 51 66 68 83 4 52 67 69 84 4 53 68 70 85 4 54 69 71 86 4 55 70 72 87 4 56 71 73 88 4 57 72 74 89 4 58 73 75 90 4 59 74 76 91 4 60 75 77 92 4 61 76 78 93 4 62 77 79 94 4 63 78 80 95 3 64 79 96 3 65 82 97 4 66 81 83 98 4 67 82 84 99 4 68 83 85 100 4 69 84 86 101 4 70 85 87 102 4 71 86 88 103 4 72 87 89 104 4 73 88 90 105 4 74 89 91 106 4 75 90 92 107 4 76 91 93 108 4 77 92 94 109 4 78 93 95 110 4 79 94 96 111 3 80 95 112 3 81 98 113 4 82 97 99 114 4 83 98 100 115 4 84 99 101 116 4 85 100 102 117 4 86 101 103 118 4 87 102 104 119 4 88 103 105 120 4 89 104 106 121 4 90 105 107 122 4 91 106 108 123 4 92 107 109 124 4 93 108 110 125 4 94 109 111 126 4 95 110 112 127 3 96 111 128 3 97 114 129 4 98 113 115 130 4 99 114 116 131 4 100 115 117 132 4 101 116 118 133 4 102 117 119 134 4 103 118 120 135 4 104 119 121 136 4 105 120 122 137 4 106 121 123 138 4 107 122 124 139 4 108 123 125 140 4 109 124 126 141 4 110 125 127 142 4 111 126 128 143 3 112 127 144 3 113 130 145 4 114 129 131 146 4 115 130 132 147 4 116 131 133 148 4 117 132 134 149 4 118 133 135 150 4 119 134 136 151 4 120 135 137 152 4 121 136 138 153 4 122 137 139 154 4 123 138 140 155 4 124 139 141 156 4 125 140 142 157 4 126 141 143 158 4 127 142 144 159 3 128 143 160 3 129 146 161 4 130 145 147 162 4 131 146 148 163 4 132 147 149 164 4 133 148 150 165 4 134 149 151 166 4 135 150 152 167 4 136 151 153 168 4 137 152 154 169 4 138 153 155 170 4 139 154 156 171 4 140 155 157 172 4 141 156 158 173 4 142 157 159 174 4 143 158 160 175 3 144 159 176 3 145 162 177 4 146 161 163 178 4 147 162 164 179 4 148 163 165 180 4 149 164 166 181 4 150 165 167 182 4 151 166 168 183 4 152 167 169 184 4 153 168 170 185 4 154 169 171 186 4 155 170 172 187 4 156 171 173 188 4 157 172 174 189 4 158 173 175 190 4 159 174 176 191 3 160 175 192 3 161 178 193 4 162 177 179 194 4 163 178 180 195 4 164 179 181 196 4 165 180 182 197 4 166 181 183 198 4 167 182 184 199 4 168 183 185 200 4 169 184 186 201 4 170 185 187 202 4 171 186 188 203 4 172 187 189 204 4 173 188 190 205 4 174 189 191 206 4 175 190 192 207 3 176 191 208 3 177 194 209 4 178 193 195 210 4 179 194 196 211 4 180 195 197 212 4 181 196 198 213 4 182 197 199 214 4 183 198 200 215 4 184 199 201 216 4 185 200 202 217 4 186 201 203 218 4 187 202 204 219 4 188 203 205 220 4 189 204 206 221 4 190 205 207 222 4 191 206 208 223 3 192 207 224 3 193 210 225 4 194 209 211 226 4 195 210 212 227 4 196 211 213 228 4 197 212 214 229 4 198 213 215 230 4 199 214 216 231 4 200 215 217 232 4 201 216 218 233 4 202 217 219 234 4 203 218 220 235 4 204 219 221 236 4 205 220 222 237 4 206 221 223 238 4 207 222 224 239 3 208 223 240 3 209 226 241 4 210 225 227 242 4 211 226 228 243 4 212 227 229 244 4 213 228 230 245 4 214 229 231 246 4 215 230 232 247 4 216 231 233 248 4 217 232 234 249 4 218 233 235 250 4 219 234 236 251 4 220 235 237 252 4 221 236 238 253 4 222 237 239 254 4 223 238 240 255 3 224 239 256 2 225 242 3 226 241 243 3 227 242 244 3 228 243 245 3 229 244 246 3 230 245 247 3 231 246 248 3 232 247 249 3 233 248 250 3 234 249 251 3 235 250 252 3 236 251 253 3 237 252 254 3 238 253 255 3 239 254 256 2 240 255 scotch-6.0.4.dfsg/src/check/data/m16x16.grf0000644002563400244210000000760012374701337023322 0ustar trophimeutilisateurs du domaine0 256 960 0 000 2 1 16 3 0 2 17 3 1 3 18 3 2 4 19 3 3 5 20 3 4 6 21 3 5 7 22 3 6 8 23 3 7 9 24 3 8 10 25 3 9 11 26 3 10 12 27 3 11 13 28 3 12 14 29 3 13 15 30 2 14 31 3 0 17 32 4 1 16 18 33 4 2 17 19 34 4 3 18 20 35 4 4 19 21 36 4 5 20 22 37 4 6 21 23 38 4 7 22 24 39 4 8 23 25 40 4 9 24 26 41 4 10 25 27 42 4 11 26 28 43 4 12 27 29 44 4 13 28 30 45 4 14 29 31 46 3 15 30 47 3 16 33 48 4 17 32 34 49 4 18 33 35 50 4 19 34 36 51 4 20 35 37 52 4 21 36 38 53 4 22 37 39 54 4 23 38 40 55 4 24 39 41 56 4 25 40 42 57 4 26 41 43 58 4 27 42 44 59 4 28 43 45 60 4 29 44 46 61 4 30 45 47 62 3 31 46 63 3 32 49 64 4 33 48 50 65 4 34 49 51 66 4 35 50 52 67 4 36 51 53 68 4 37 52 54 69 4 38 53 55 70 4 39 54 56 71 4 40 55 57 72 4 41 56 58 73 4 42 57 59 74 4 43 58 60 75 4 44 59 61 76 4 45 60 62 77 4 46 61 63 78 3 47 62 79 3 48 65 80 4 49 64 66 81 4 50 65 67 82 4 51 66 68 83 4 52 67 69 84 4 53 68 70 85 4 54 69 71 86 4 55 70 72 87 4 56 71 73 88 4 57 72 74 89 4 58 73 75 90 4 59 74 76 91 4 60 75 77 92 4 61 76 78 93 4 62 77 79 94 3 63 78 95 3 64 81 96 4 65 80 82 97 4 66 81 83 98 4 67 82 84 99 4 68 83 85 100 4 69 84 86 101 4 70 85 87 102 4 71 86 88 103 4 72 87 89 104 4 73 88 90 105 4 74 89 91 106 4 75 90 92 107 4 76 91 93 108 4 77 92 94 109 4 78 93 95 110 3 79 94 111 3 80 97 112 4 81 96 98 113 4 82 97 99 114 4 83 98 100 115 4 84 99 101 116 4 85 100 102 117 4 86 101 103 118 4 87 102 104 119 4 88 103 105 120 4 89 104 106 121 4 90 105 107 122 4 91 106 108 123 4 92 107 109 124 4 93 108 110 125 4 94 109 111 126 3 95 110 127 3 96 113 128 4 97 112 114 129 4 98 113 115 130 4 99 114 116 131 4 100 115 117 132 4 101 116 118 133 4 102 117 119 134 4 103 118 120 135 4 104 119 121 136 4 105 120 122 137 4 106 121 123 138 4 107 122 124 139 4 108 123 125 140 4 109 124 126 141 4 110 125 127 142 3 111 126 143 3 112 129 144 4 113 128 130 145 4 114 129 131 146 4 115 130 132 147 4 116 131 133 148 4 117 132 134 149 4 118 133 135 150 4 119 134 136 151 4 120 135 137 152 4 121 136 138 153 4 122 137 139 154 4 123 138 140 155 4 124 139 141 156 4 125 140 142 157 4 126 141 143 158 3 127 142 159 3 128 145 160 4 129 144 146 161 4 130 145 147 162 4 131 146 148 163 4 132 147 149 164 4 133 148 150 165 4 134 149 151 166 4 135 150 152 167 4 136 151 153 168 4 137 152 154 169 4 138 153 155 170 4 139 154 156 171 4 140 155 157 172 4 141 156 158 173 4 142 157 159 174 3 143 158 175 3 144 161 176 4 145 160 162 177 4 146 161 163 178 4 147 162 164 179 4 148 163 165 180 4 149 164 166 181 4 150 165 167 182 4 151 166 168 183 4 152 167 169 184 4 153 168 170 185 4 154 169 171 186 4 155 170 172 187 4 156 171 173 188 4 157 172 174 189 4 158 173 175 190 3 159 174 191 3 160 177 192 4 161 176 178 193 4 162 177 179 194 4 163 178 180 195 4 164 179 181 196 4 165 180 182 197 4 166 181 183 198 4 167 182 184 199 4 168 183 185 200 4 169 184 186 201 4 170 185 187 202 4 171 186 188 203 4 172 187 189 204 4 173 188 190 205 4 174 189 191 206 3 175 190 207 3 176 193 208 4 177 192 194 209 4 178 193 195 210 4 179 194 196 211 4 180 195 197 212 4 181 196 198 213 4 182 197 199 214 4 183 198 200 215 4 184 199 201 216 4 185 200 202 217 4 186 201 203 218 4 187 202 204 219 4 188 203 205 220 4 189 204 206 221 4 190 205 207 222 3 191 206 223 3 192 209 224 4 193 208 210 225 4 194 209 211 226 4 195 210 212 227 4 196 211 213 228 4 197 212 214 229 4 198 213 215 230 4 199 214 216 231 4 200 215 217 232 4 201 216 218 233 4 202 217 219 234 4 203 218 220 235 4 204 219 221 236 4 205 220 222 237 4 206 221 223 238 3 207 222 239 3 208 225 240 4 209 224 226 241 4 210 225 227 242 4 211 226 228 243 4 212 227 229 244 4 213 228 230 245 4 214 229 231 246 4 215 230 232 247 4 216 231 233 248 4 217 232 234 249 4 218 233 235 250 4 219 234 236 251 4 220 235 237 252 4 221 236 238 253 4 222 237 239 254 3 223 238 255 2 224 241 3 225 240 242 3 226 241 243 3 227 242 244 3 228 243 245 3 229 244 246 3 230 245 247 3 231 246 248 3 232 247 249 3 233 248 250 3 234 249 251 3 235 250 252 3 236 251 253 3 237 252 254 3 238 253 255 2 239 254 scotch-6.0.4.dfsg/src/check/test_scotch_graph_map.c0000644002563400244210000002324112412034737025446 0ustar trophimeutilisateurs du domaine/* Copyright 2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : test_scotch_graph_map.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module tests the operation of **/ /** the SCOTCH_graphMap*() routines. **/ /** **/ /** DATES : # Version 6.0 : from : 12 aug 2014 **/ /** to 20 sep 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #include #include #if (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) #include #endif /* (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) */ #include #include #include "scotch.h" #define ARCHNBR 4 #define STRANBR 2 #define COORD(x,y) ((y) * xdimsiz + (x)) /*********************/ /* */ /* The main routine. */ /* */ /*********************/ int main ( int argc, char * argv[]) { SCOTCH_Mapping mappdat; /* Mapping to compute */ SCOTCH_Mapping mapodat; /* Old mapping */ FILE * fileptr; SCOTCH_Graph grafdat; SCOTCH_Num xdimsiz; int archnum; SCOTCH_Arch archtab[ARCHNBR]; SCOTCH_Strat stratab[STRANBR]; int stranum; int typenum; SCOTCH_Num baseval; SCOTCH_Num vertnbr; SCOTCH_Num vertnum; SCOTCH_Num * parttab; SCOTCH_Num * parotab; SCOTCH_Num * vmlotab; SCOTCH_Num * vmloptr; /* vmlotab or NULL */ SCOTCH_errorProg (argv[0]); if (SCOTCH_graphInit (&grafdat) != 0) { /* Initialize source graph */ SCOTCH_errorPrint ("main: cannot initialize graph"); return (1); } if ((fileptr = fopen (argv[1], "r")) == NULL) { /* Read a square 2D grid graph */ SCOTCH_errorPrint ("main: cannot open file (1)"); return (1); } if (SCOTCH_graphLoad (&grafdat, fileptr, -1, 0) != 0) { /* Read source graph */ SCOTCH_errorPrint ("main: cannot load graph"); return (1); } fclose (fileptr); SCOTCH_graphSize (&grafdat, &vertnbr, NULL); xdimsiz = (SCOTCH_Num) sqrt ((double) vertnbr); if (vertnbr != (xdimsiz * xdimsiz)) { SCOTCH_errorPrint ("main: graph is not a square grid"); return (1); } if (((parttab = malloc (vertnbr * sizeof (SCOTCH_Num))) == NULL) || ((parotab = malloc (vertnbr * sizeof (SCOTCH_Num))) == NULL) || ((vmlotab = malloc (vertnbr * sizeof (SCOTCH_Num))) == NULL)) { SCOTCH_errorPrint ("main: out of memory"); return (1); } for (vertnum = 0; vertnum < vertnbr; vertnum ++) /* Fill vertex migration load array */ vmlotab[vertnum] = vertnum % 3; for (stranum = 0; stranum < STRANBR; stranum ++) { /* Initialize mapping strategies */ if (SCOTCH_stratInit (&stratab[stranum]) != 0) { SCOTCH_errorPrint ("main: cannot initialize strategy"); return (1); } } SCOTCH_stratGraphMapBuild (&stratab[0], SCOTCH_STRATRECURSIVE, 4, 0.05); SCOTCH_stratGraphMapBuild (&stratab[1], SCOTCH_STRATDEFAULT, 4, 0.05); for (archnum = 0; archnum < ARCHNBR; archnum ++) { /* Initialize architectures */ if (SCOTCH_archInit (&archtab[archnum]) != 0) { SCOTCH_errorPrint ("main: cannot initialize architecture"); return (1); } } SCOTCH_archCmplt (&archtab[0], 5); SCOTCH_archMesh2 (&archtab[1], 2, 2); SCOTCH_archMesh2 (&archtab[2], xdimsiz * 2, xdimsiz * 2); /* Oversized architecture */ SCOTCH_archVhcub (&archtab[3]); if ((fileptr = tmpfile ()) == NULL) { /* Open temporary file for resulting output */ SCOTCH_errorPrint ("main: cannot open file (2)"); return (1); } for (stranum = 0; stranum < STRANBR; stranum ++) { for (archnum = 0; archnum < ARCHNBR; archnum ++) { SCOTCH_Num archsiz; if (SCOTCH_graphMapInit (&grafdat, &mappdat, &archtab[archnum], parttab) != 0) { /* Initialize new mapping */ SCOTCH_errorPrint ("main: cannot initialize mapping (1)"); return (1); } if (SCOTCH_graphMapInit (&grafdat, &mapodat, &archtab[archnum], parotab) != 0) { /* Initialize old mapping */ SCOTCH_errorPrint ("main: cannot initialize mapping (2)"); return (1); } archsiz = SCOTCH_archSize (&archtab[archnum]); for (typenum = 0; typenum < 6; typenum ++) { int i; int o; memset (parttab, ~0, xdimsiz * xdimsiz * sizeof (SCOTCH_Num)); /* Assume all vertices are not fixed */ if (archnum < 2) { /* For fixed-size architectures */ for (i = 0; i < (xdimsiz - 1); i ++) { /* Place fixed vertices at all four sides */ parttab[COORD (0, i)] = 0; parttab[COORD (i + 1, 0)] = 1; parttab[COORD (xdimsiz - 1, i + 1)] = archsiz - 2; parttab[COORD (i, xdimsiz - 1)] = archsiz - 1; } } else { /* For variable-sized architectures */ for (i = 0; i < (xdimsiz - 1); i ++) { /* Place fixed vertices at all four sides */ parttab[COORD (0, i)] = vertnbr - 2; parttab[COORD (i + 1, 0)] = vertnbr - 1; parttab[COORD (xdimsiz - 1, i + 1)] = vertnbr; parttab[COORD (i, xdimsiz - 1)] = vertnbr + 1; } } printf ("Strat %d, arch %d, type %d\n", stranum, archnum, typenum); vmloptr = vmlotab; switch (typenum) { case 0 : /* Plain mapping */ o = SCOTCH_graphMapCompute (&grafdat, &mappdat, &stratab[stranum]); memcpy (parotab, parttab, vertnbr * sizeof (SCOTCH_Num)); /* Use plain mapping as old mapping in the following */ break; case 1 : /* Plain mapping with fixed vertices */ o = SCOTCH_graphMapFixedCompute (&grafdat, &mappdat, &stratab[stranum]); break; case 2 : /* Remapping without vertex migration load array */ vmloptr = NULL; case 3 : /* Remapping with vertex migration load array */ o = SCOTCH_graphRemapCompute (&grafdat, &mappdat, &mapodat, 0.2, vmloptr, &stratab[stranum]); break; case 4 : /* Remapping with fixed vertices and without vertex migration load array */ vmloptr = NULL; case 5 : /* Remapping with fixed vertices and with vertex migration load array */ o = SCOTCH_graphRemapFixedCompute (&grafdat, &mappdat, &mapodat, 0.2, vmloptr, &stratab[stranum]); break; } if (o != 0) { SCOTCH_errorPrint ("main: cannot compute mapping"); return (1); } } SCOTCH_graphMapSave (&grafdat, &mappdat, fileptr); SCOTCH_graphMapExit (&grafdat, &mapodat); SCOTCH_graphMapExit (&grafdat, &mappdat); } } for (archnum = 0; archnum < ARCHNBR; archnum ++) SCOTCH_archExit (&archtab[archnum]); for (stranum = 0; stranum < STRANBR; stranum ++) SCOTCH_stratExit (&stratab[stranum]); free (vmlotab); free (parotab); free (parttab); SCOTCH_graphExit (&grafdat); fclose (fileptr); return (0); } scotch-6.0.4.dfsg/src/check/test_scotch_dgraph_check.c0000644002563400244210000001301612500613416026104 0ustar trophimeutilisateurs du domaine/* Copyright 2014,2015 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : test_scotch_dgraph_check.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module tests the operation of **/ /** the SCOTCH_dgraphCheck() routine. **/ /** **/ /** DATES : # Version 6.0 : from : 28 sep 2014 **/ /** to 02 mar 2015 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #include #include #if (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) #include #endif /* (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) */ #include #include #include #include #include #include "ptscotch.h" #define errorProg SCOTCH_errorProg #define errorPrint SCOTCH_errorPrint /*********************/ /* */ /* The main routine. */ /* */ /*********************/ int main ( int argc, char * argv[]) { MPI_Comm proccomm; int procglbnbr; /* Number of processes sharing graph data */ int proclocnum; /* Number of this process */ SCOTCH_Dgraph grafdat; FILE * file; #ifdef SCOTCH_PTHREAD int thrdlvlreqval; int thrdlvlproval; #endif /* SCOTCH_PTHREAD */ errorProg (argv[0]); #ifdef SCOTCH_PTHREAD thrdlvlreqval = MPI_THREAD_MULTIPLE; if (MPI_Init_thread (&argc, &argv, thrdlvlreqval, &thrdlvlproval) != MPI_SUCCESS) errorPrint ("main: Cannot initialize (1)"); if (thrdlvlreqval > thrdlvlproval) errorPrint ("main: MPI implementation is not thread-safe: recompile without SCOTCH_PTHREAD"); #else /* SCOTCH_PTHREAD */ if (MPI_Init (&argc, &argv) != MPI_SUCCESS) errorPrint ("main: Cannot initialize (2)"); #endif /* SCOTCH_PTHREAD */ if (argc != 2) { errorPrint ("main: invalid number of parameters"); exit (1); } proccomm = MPI_COMM_WORLD; MPI_Comm_size (proccomm, &procglbnbr); /* Get communicator data */ MPI_Comm_rank (proccomm, &proclocnum); fprintf (stderr, "Proc %2d of %2d, pid %d\n", proclocnum, procglbnbr, getpid ()); #ifdef SCOTCH_CHECK_NOAUTO if (proclocnum == 0) { /* Synchronize on keybord input */ char c; printf ("Waiting for key press...\n"); scanf ("%c", &c); } #endif /* SCOTCH_CHECK_NOAUTO */ if (MPI_Barrier (proccomm) != MPI_SUCCESS) { /* Synchronize for debug */ errorPrint ("main: cannot communicate"); return (1); } if (SCOTCH_dgraphInit (&grafdat, proccomm) != 0) { /* Initialize source graph */ errorPrint ("main: cannot initialize graph"); return (1); } file = NULL; if ((proclocnum == 0) && ((file = fopen (argv[1], "r")) == NULL)) { errorPrint ("main: cannot open graph file"); return (1); } if (SCOTCH_dgraphLoad (&grafdat, file, 0, 0) != 0) { errorPrint ("main: cannot load graph"); return (1); } if (file != NULL) fclose (file); if (SCOTCH_dgraphCheck (&grafdat) != 0) { errorPrint ("main: invalid graph"); return (1); } if (MPI_Barrier (proccomm) != MPI_SUCCESS) { /* Synchronize for debug */ errorPrint ("main: cannot communicate"); return (1); } SCOTCH_dgraphExit (&grafdat); MPI_Finalize (); exit (0); } scotch-6.0.4.dfsg/src/check/test_scotch_dgraph_coarsen.c0000644002563400244210000002031112500613416026455 0ustar trophimeutilisateurs du domaine/* Copyright 2014,2015 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : test_scotch_dgraph_coarsen.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module tests the operation of **/ /** the SCOTCH_dgraphCoarsen() routine. **/ /** **/ /** DATES : # Version 6.0 : from : 28 sep 2014 **/ /** to 02 mar 2015 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #include #include #if (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) #include #endif /* (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) */ #include #include #include #include #include #include "ptscotch.h" #define errorProg SCOTCH_errorProg #define errorPrint SCOTCH_errorPrint /*********************/ /* */ /* The main routine. */ /* */ /*********************/ int main ( int argc, char * argv[]) { MPI_Comm proccomm; int procglbnbr; /* Number of processes sharing graph data */ int proclocnum; /* Number of this process */ SCOTCH_Num vertglbnbr; SCOTCH_Num vertlocnbr; SCOTCH_Num baseval; SCOTCH_Dgraph grafdat; SCOTCH_Dgraph coargrafdat; SCOTCH_Num coarvertglbnbr; SCOTCH_Num coarvertlocnbr; double coarrat; FILE * file; #ifdef SCOTCH_PTHREAD int thrdlvlreqval; int thrdlvlproval; #endif /* SCOTCH_PTHREAD */ int i; errorProg (argv[0]); #ifdef SCOTCH_PTHREAD thrdlvlreqval = MPI_THREAD_MULTIPLE; if (MPI_Init_thread (&argc, &argv, thrdlvlreqval, &thrdlvlproval) != MPI_SUCCESS) errorPrint ("main: Cannot initialize (1)"); if (thrdlvlreqval > thrdlvlproval) errorPrint ("main: MPI implementation is not thread-safe: recompile without SCOTCH_PTHREAD"); #else /* SCOTCH_PTHREAD */ if (MPI_Init (&argc, &argv) != MPI_SUCCESS) errorPrint ("main: Cannot initialize (2)"); #endif /* SCOTCH_PTHREAD */ if (argc != 2) { errorPrint ("main: invalid number of parameters"); exit (1); } proccomm = MPI_COMM_WORLD; MPI_Comm_size (proccomm, &procglbnbr); /* Get communicator data */ MPI_Comm_rank (proccomm, &proclocnum); fprintf (stderr, "Proc %2d of %2d, pid %d\n", proclocnum, procglbnbr, getpid ()); #ifdef SCOTCH_CHECK_NOAUTO if (proclocnum == 0) { /* Synchronize on keybord input */ char c; printf ("Waiting for key press...\n"); scanf ("%c", &c); } #endif /* SCOTCH_CHECK_NOAUTO */ if (MPI_Barrier (proccomm) != MPI_SUCCESS) { /* Synchronize for debug */ errorPrint ("main: cannot communicate"); return (1); } if (SCOTCH_dgraphInit (&grafdat, proccomm) != 0) { /* Initialize source graph */ errorPrint ("main: cannot initialize graph (1)"); return (1); } file = NULL; if ((proclocnum == 0) && ((file = fopen (argv[1], "r")) == NULL)) { errorPrint ("main: cannot open graph file"); return (1); } if (SCOTCH_dgraphLoad (&grafdat, file, 0, 0) != 0) { errorPrint ("main: cannot load graph"); return (1); } if (file != NULL) fclose (file); if (MPI_Barrier (proccomm) != MPI_SUCCESS) { /* Synchronize for debug */ errorPrint ("main: cannot communicate"); return (1); } SCOTCH_dgraphData (&grafdat, NULL, &vertglbnbr, &vertlocnbr, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); coarrat = 0.8; /* Lazy coarsening ratio */ for (i = 0; i < 3; i ++) { /* For all test cases */ SCOTCH_Num * multloctab; SCOTCH_Num multlocsiz; SCOTCH_Num foldval; char * foldstr; char * coarstr; int procnum; int o; switch (i) { case 0 : multlocsiz = vertlocnbr; foldval = SCOTCH_COARSENNONE; foldstr = "Plain coarsening"; break; case 1 : multlocsiz = (SCOTCH_Num) (((double) vertglbnbr * coarrat) / (double) (procglbnbr / 2)) + 1; foldval = SCOTCH_COARSENFOLD; foldstr = "Folding"; break; case 2 : multlocsiz = (SCOTCH_Num) (((double) vertglbnbr * coarrat) / (double) (procglbnbr / 2)) + 1; foldval = SCOTCH_COARSENFOLDDUP; foldstr = "Folding with duplication"; break; } if (proclocnum == 0) printf ("%s\n", foldstr); if ((multloctab = malloc (multlocsiz * 2 * sizeof (SCOTCH_Num))) == NULL) { errorPrint ("main: cannot allocate multinode array"); return (1); } if (SCOTCH_dgraphInit (&coargrafdat, proccomm) != 0) { /* Initialize band graph */ errorPrint ("main: cannot initialize graph (2)"); return (1); } o = SCOTCH_dgraphCoarsen (&grafdat, 0, coarrat, foldval, &coargrafdat, multloctab); SCOTCH_dgraphData (&coargrafdat, NULL, &coarvertglbnbr, &coarvertlocnbr, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); for (procnum = 0; procnum < procglbnbr; procnum ++) { switch (o) { case 0 : coarstr = "coarse graph created"; break; case 1 : coarstr = "graph could not be coarsened"; break; case 2 : coarstr = "folded graph not created here"; break; case 3 : coarstr = "cannot create coarse graph"; break; } if (procnum == proclocnum) printf ("%d: %s (%ld / %ld / %ld)\n", procnum, coarstr, (long) multlocsiz, (long) coarvertlocnbr, (long) vertlocnbr); MPI_Barrier (proccomm); } if (coarvertlocnbr > multlocsiz) { errorPrint ("main: invalid local multinode array size"); return (1); } SCOTCH_dgraphExit (&coargrafdat); free (multloctab); } SCOTCH_dgraphExit (&grafdat); MPI_Finalize (); exit (0); } scotch-6.0.4.dfsg/src/check/test_scotch_dgraph_band.c0000644002563400244210000001631612500613415025740 0ustar trophimeutilisateurs du domaine/* Copyright 2011,2012,2014,2015 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : test_scotch_dgraph_band.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module tests the operation of **/ /** the SCOTCH_dgraphBand() routine. **/ /** **/ /** DATES : # Version 6.0 : from : 10 nov 2011 **/ /** to 02 mar 2015 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #include #include #if (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) #include #endif /* (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) */ #include #include #include #include #include #include "ptscotch.h" #define errorProg SCOTCH_errorProg #define errorPrint SCOTCH_errorPrint /*********************/ /* */ /* The main routine. */ /* */ /*********************/ int main ( int argc, char * argv[]) { MPI_Comm proccomm; int procglbnbr; /* Number of processes sharing graph data */ int proclocnum; /* Number of this process */ SCOTCH_Num vertglbnbr; SCOTCH_Num vertlocnbr; SCOTCH_Num * fronloctab; SCOTCH_Num baseval; SCOTCH_Dgraph grafdat; SCOTCH_Dgraph bandgrafdat; SCOTCH_Num bandvertglbnbr; SCOTCH_Num bandvertlocnbr; SCOTCH_Num * bandvlblloctab; FILE * file; int procnum; #ifdef SCOTCH_PTHREAD int thrdlvlreqval; int thrdlvlproval; #endif /* SCOTCH_PTHREAD */ errorProg (argv[0]); #ifdef SCOTCH_PTHREAD thrdlvlreqval = MPI_THREAD_MULTIPLE; if (MPI_Init_thread (&argc, &argv, thrdlvlreqval, &thrdlvlproval) != MPI_SUCCESS) errorPrint ("main: Cannot initialize (1)"); if (thrdlvlreqval > thrdlvlproval) errorPrint ("main: MPI implementation is not thread-safe: recompile without SCOTCH_PTHREAD"); #else /* SCOTCH_PTHREAD */ if (MPI_Init (&argc, &argv) != MPI_SUCCESS) errorPrint ("main: Cannot initialize (2)"); #endif /* SCOTCH_PTHREAD */ if (argc != 2) { errorPrint ("main: invalid number of parameters"); exit (1); } proccomm = MPI_COMM_WORLD; MPI_Comm_size (proccomm, &procglbnbr); /* Get communicator data */ MPI_Comm_rank (proccomm, &proclocnum); fprintf (stderr, "Proc %2d of %2d, pid %d\n", proclocnum, procglbnbr, getpid ()); #ifdef SCOTCH_CHECK_NOAUTO if (proclocnum == 0) { /* Synchronize on keybord input */ char c; printf ("Waiting for key press...\n"); scanf ("%c", &c); } #endif /* SCOTCH_CHECK_NOAUTO */ if (MPI_Barrier (proccomm) != MPI_SUCCESS) { /* Synchronize for debug */ errorPrint ("main: cannot communicate"); return (1); } if (SCOTCH_dgraphInit (&grafdat, proccomm) != 0) { /* Initialize source graph */ errorPrint ("main: cannot initialize graph (1)"); return (1); } file = NULL; if ((proclocnum == 0) && ((file = fopen (argv[1], "r")) == NULL)) { errorPrint ("main: cannot open graph file"); return (1); } if (SCOTCH_dgraphLoad (&grafdat, file, 0, 0) != 0) { errorPrint ("main: cannot load graph"); return (1); } if (file != NULL) fclose (file); if (MPI_Barrier (proccomm) != MPI_SUCCESS) { /* Synchronize for debug */ errorPrint ("main: cannot communicate"); return (1); } SCOTCH_dgraphData (&grafdat, NULL, &vertglbnbr, &vertlocnbr, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if ((fronloctab = malloc (vertlocnbr * sizeof (SCOTCH_Num))) == NULL) { errorPrint ("main: cannot allocate frontier array"); return (1); } if (SCOTCH_dgraphInit (&bandgrafdat, proccomm) != 0) { /* Initialize band graph */ errorPrint ("main: cannot initialize graph (2)"); return (1); } fronloctab[0] = 0; if (SCOTCH_dgraphBand (&grafdat, (proclocnum == 1) ? 1 : 0, fronloctab, 4, &bandgrafdat) != 0) { errorPrint ("main: cannot compute band graph"); return (1); } free (fronloctab); SCOTCH_dgraphData (&bandgrafdat, &baseval, &bandvertglbnbr, &bandvertlocnbr, NULL, NULL, NULL, NULL, NULL, &bandvlblloctab, NULL, NULL, NULL, NULL, NULL, NULL, NULL); for (procnum = 0; procnum < procglbnbr; procnum ++) { SCOTCH_Num bandvertlocnum; MPI_Barrier (proccomm); if (procnum == proclocnum) { if ((file = fopen ("/tmp/test_scotch_dgraph_band.map", (procnum == 0) ? "w" : "a+")) == NULL) { errorPrint ("main: cannot open mapping file"); return (1); } if (procnum == 0) fprintf (file, "%ld\n", (long) bandvertglbnbr); for (bandvertlocnum = 0; bandvertlocnum < bandvertlocnbr; bandvertlocnum ++) fprintf (file, "%ld\t1\n", (long) bandvlblloctab[bandvertlocnum]); fclose (file); } } SCOTCH_dgraphExit (&bandgrafdat); SCOTCH_dgraphExit (&grafdat); MPI_Finalize (); exit (0); } scotch-6.0.4.dfsg/src/check/test_common_random.c0000644002563400244210000001257012474563700025005 0ustar trophimeutilisateurs du domaine/* Copyright 2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : test_common_thread.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module tests the sequential **/ /** strategy building routines. **/ /** **/ /** DATES : # Version 6.0 : from : 01 oct 2014 **/ /** to 16 oct 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE 600 #endif /* _XOPEN_SOURCE */ #ifndef __USE_XOPEN2K #define __USE_XOPEN2K /* For POSIX pthread_barrier_t */ #endif /* __USE_XOPEN2K */ #include #include #include #include #include "../libscotch/module.h" #include "../libscotch/common.h" #define RANDNBR 100 /*********************/ /* */ /* The main routine. */ /* */ /*********************/ int main ( int argc, char * argv[]) { INT * randtab; int randnbr; int randnum; struct stat statdat; FILE * fileptr; int passnum; if (argc != 3) { errorPrint ("usage: %s file passnum", argv[0]); return (1); } if ((randtab = malloc (RANDNBR * sizeof (INT))) == NULL) { errorPrint ("main: out of memory"); return (1); } intRandInit (); /* Initialize random generator */ for (randnum = 0; randnum < RANDNBR; randnum ++) randtab[randnum] = intRandVal (INTVALMAX); intRandReset (); passnum = (atoi (argv[2]) == 0); /* First pass to write file; second pass to read it */ if ((fileptr = fopen (argv[1], (passnum) ? "w+" : "r")) == NULL) { errorPrint ("main: cannot open file"); return (1); } if (passnum) { /* If first pass */ for (randnum = 0; randnum < RANDNBR; randnum ++) { if (randtab[randnum] != intRandVal (INTVALMAX)) { errorPrint ("main: cannot replay random sequence"); return (1); } } if (fwrite (randtab, sizeof (INT), RANDNBR, fileptr) < RANDNBR) { errorPrint ("main: cannot write to file"); return (1); } sleep (1); /* Next run will not get the same time() value */ } else { /* Second pass */ const char * const bufftab = ""; char * charptr; int o; if (fread (randtab, sizeof (INT), RANDNBR, fileptr) < RANDNBR) { errorPrint ("main: cannot read from file"); return (1); } for (randnum = 0; randnum < RANDNBR; randnum ++) { if (randtab[randnum] != intRandVal (INTVALMAX)) break; } o = (randnum == RANDNBR); charptr = (o) ? "same" : "different"; #if ((defined COMMON_DEBUG) || (defined COMMON_RANDOM_FIXED_SEED) || (defined SCOTCH_DETERMINISTIC)) o ^= 1; #endif /* ((defined COMMON_DEBUG) || (defined COMMON_RANDOM_FIXED_SEED) || (defined SCOTCH_DETERMINISTIC)) */ if (o) { errorPrint ("main: two consecutive runs yield %s values.", charptr); return (1); } printf ("Two consecutive runs yield %s values.\n", charptr); } fclose (fileptr); free (randtab); return (0); } scotch-6.0.4.dfsg/src/check/test_scotch_graph_color.c0000644002563400244210000001117412474563560026022 0ustar trophimeutilisateurs du domaine/* Copyright 2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : test_scotch_graph_color.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module tests the operation of **/ /** the SCOTCH_graphColor() routine. **/ /** **/ /** DATES : # Version 6.0 : from : 06 jan 2012 **/ /** to 15 oct 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #include #if (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) #include #endif /* (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) */ #include #include #include "scotch.h" /*********************/ /* */ /* The main routine. */ /* */ /*********************/ int main ( int argc, char * argv[]) { FILE * fileptr; SCOTCH_Graph grafdat; SCOTCH_Num vertnbr; SCOTCH_Num vertnum; SCOTCH_Num colonbr; SCOTCH_Num colonum; SCOTCH_Num * colotab; SCOTCH_Num * cnbrtab; SCOTCH_errorProg (argv[0]); if (SCOTCH_graphInit (&grafdat) != 0) { /* Initialize source graph */ SCOTCH_errorPrint ("main: cannot initialize graph"); return (1); } if ((fileptr = fopen (argv[1], "r")) == NULL) { SCOTCH_errorPrint ("main: cannot open file"); return (1); } if (SCOTCH_graphLoad (&grafdat, fileptr, -1, 0) != 0) { /* Read source graph */ SCOTCH_errorPrint ("main: cannot load graph"); return (1); } fclose (fileptr); SCOTCH_graphSize (&grafdat, &vertnbr, NULL); if ((colotab = malloc (vertnbr * sizeof (SCOTCH_Num))) == NULL) { SCOTCH_errorPrint ("main: out of memory (1)"); return (1); } if ((cnbrtab = malloc (vertnbr * sizeof (SCOTCH_Num))) == NULL) { SCOTCH_errorPrint ("main: out of memory (1)"); return (1); } memset (cnbrtab, 0, vertnbr * sizeof (SCOTCH_Num)); if (SCOTCH_graphColor (&grafdat, colotab, &colonbr, 0) != 0) { SCOTCH_errorPrint ("main: cannot color graph"); return (1); } printf ("Number of colors: %ld\n", (long) colonbr); for (vertnum = 0; vertnum < vertnbr; vertnum ++) /* Sum-up color histogram */ cnbrtab[colotab[vertnum]] ++; for (colonum = 0; colonum < colonbr; colonum ++) printf ("Color %5ld: %ld\n", (long) colonum, (long) cnbrtab[colonum]); free (cnbrtab); free (colotab); SCOTCH_graphExit (&grafdat); return (0); } scotch-6.0.4.dfsg/src/check/test_scotch_dgraph_grow.c0000644002563400244210000001760012500613417026011 0ustar trophimeutilisateurs du domaine/* Copyright 2012,2014,2015 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : test_scotch_dgraph_grow.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module tests the operation of **/ /** the SCOTCH_dgraphGrow() routine. **/ /** **/ /** DATES : # Version 6.0 : from : 26 sep 2012 **/ /** to 02 mar 2015 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #include #include #if (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) #include #endif /* (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) */ #include #include #include #include #include #include #include "ptscotch.h" #define errorProg SCOTCH_errorProg #define errorPrint SCOTCH_errorPrint void _SCOTCHintRandInit (void); SCOTCH_Num _SCOTCHintRandVal (SCOTCH_Num); /*********************/ /* */ /* The main routine. */ /* */ /*********************/ int main ( int argc, char * argv[]) { MPI_Status statdat; MPI_Comm proccomm; int procglbnbr; /* Number of processes sharing graph data */ int proclocnum; /* Number of this process */ long vertlocadj; SCOTCH_Num vertglbnbr; SCOTCH_Num vertlocnbr; SCOTCH_Num vertgstnbr; SCOTCH_Num * seedloctab; SCOTCH_Num * partgsttab; SCOTCH_Num baseval; SCOTCH_Dgraph grafdat; FILE * file; int procnum; #ifdef SCOTCH_PTHREAD int thrdlvlreqval; int thrdlvlproval; #endif /* SCOTCH_PTHREAD */ errorProg (argv[0]); #ifdef SCOTCH_PTHREAD thrdlvlreqval = MPI_THREAD_MULTIPLE; if (MPI_Init_thread (&argc, &argv, thrdlvlreqval, &thrdlvlproval) != MPI_SUCCESS) errorPrint ("main: Cannot initialize (1)"); if (thrdlvlreqval > thrdlvlproval) errorPrint ("main: MPI implementation is not thread-safe: recompile without SCOTCH_PTHREAD"); #else /* SCOTCH_PTHREAD */ if (MPI_Init (&argc, &argv) != MPI_SUCCESS) errorPrint ("main: Cannot initialize (2)"); #endif /* SCOTCH_PTHREAD */ if (argc != 2) { errorPrint ("main: invalid number of parameters"); exit (1); } proccomm = MPI_COMM_WORLD; MPI_Comm_size (proccomm, &procglbnbr); /* Get communicator data */ MPI_Comm_rank (proccomm, &proclocnum); fprintf (stderr, "Proc %2d of %2d, pid %d\n", proclocnum, procglbnbr, getpid ()); #ifdef SCOTCH_CHECK_NOAUTO if (proclocnum == 0) { /* Synchronize on keybord input */ char c; printf ("Waiting for key press...\n"); scanf ("%c", &c); } #endif /* SCOTCH_CHECK_NOAUTO */ if (MPI_Barrier (proccomm) != MPI_SUCCESS) { /* Synchronize for debug */ errorPrint ("main: cannot communicate"); return (1); } if (SCOTCH_dgraphInit (&grafdat, proccomm) != 0) { /* Initialize source graph */ errorPrint ("main: cannot initialize graph"); return (1); } file = NULL; if ((proclocnum == 0) && ((file = fopen (argv[1], "r")) == NULL)) { errorPrint ("main: cannot open graph file"); return (1); } if (SCOTCH_dgraphLoad (&grafdat, file, 0, 0) != 0) { errorPrint ("main: cannot load graph"); return (1); } if (file != NULL) fclose (file); if (MPI_Barrier (proccomm) != MPI_SUCCESS) { /* Synchronize for debug */ errorPrint ("main: cannot communicate"); return (1); } if (SCOTCH_dgraphGhst (&grafdat) != 0) { errorPrint ("main: cannot compute ghost edge array"); return (1); } SCOTCH_dgraphData (&grafdat, &baseval, &vertglbnbr, &vertlocnbr, NULL, &vertgstnbr, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if ((seedloctab = malloc (vertlocnbr * sizeof (SCOTCH_Num))) == NULL) { errorPrint ("main: cannot allocate seed array"); return (1); } if ((partgsttab = malloc (vertgstnbr * sizeof (SCOTCH_Num))) == NULL) { errorPrint ("main: cannot allocate part array"); return (1); } memset (partgsttab, ~0, vertgstnbr * sizeof (SCOTCH_Num)); _SCOTCHintRandInit (); seedloctab[0] = _SCOTCHintRandVal (vertlocnbr); seedloctab[1] = _SCOTCHintRandVal (vertlocnbr); seedloctab[2] = _SCOTCHintRandVal (vertlocnbr); partgsttab[seedloctab[0] - baseval] = 0; partgsttab[seedloctab[1] - baseval] = 1; partgsttab[seedloctab[2] - baseval] = 2; if (SCOTCH_dgraphGrow (&grafdat, 3, seedloctab, 4, partgsttab) != 0) { errorPrint ("main: cannot compute grown regions"); return (1); } free (seedloctab); for (procnum = 0; procnum < procglbnbr; procnum ++) { SCOTCH_Num vertlocnum; MPI_Barrier (proccomm); if (procnum == proclocnum) { if ((file = fopen ("/tmp/test_scotch_dgraph_grow.map", (procnum == 0) ? "w" : "a+")) == NULL) { errorPrint ("main: cannot open mapping file"); return (1); } if (procnum == 0) { fprintf (file, "%ld\n", (long) vertglbnbr); vertlocadj = (long) baseval; } else MPI_Recv (&vertlocadj, 1, MPI_LONG, procnum - 1, 0, MPI_COMM_WORLD, &statdat); for (vertlocnum = 0; vertlocnum < vertlocnbr; vertlocnum ++) fprintf (file, "%ld\t%ld\n", vertlocadj + (long) vertlocnum, (long) partgsttab[vertlocnum]); fclose (file); if (procnum < (procglbnbr - 1)) { vertlocadj += (long) vertlocnbr; MPI_Send (&vertlocadj, 1, MPI_LONG, procnum + 1, 0, MPI_COMM_WORLD); } } } SCOTCH_dgraphExit (&grafdat); MPI_Finalize (); exit (0); } scotch-6.0.4.dfsg/src/check/test_strat_seq.c0000644002563400244210000001207412412034737024154 0ustar trophimeutilisateurs du domaine/* Copyright 2012,2013 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : test_strat_seq.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module tests the sequential **/ /** strategy building routines. **/ /** **/ /** DATES : # Version 6.0 : from : 08 jan 2012 **/ /** to 11 oct 2013 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #include #if (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) #include #endif /* (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) */ #include #include "scotch.h" /*********************/ /* */ /* The main routine. */ /* */ /*********************/ int main ( int argc, char * argv[]) { SCOTCH_Strat stradat; SCOTCH_errorProg (argv[0]); printf ("Sequential mapping strategy, SCOTCH_STRATDEFAULT\n"); SCOTCH_stratInit (&stradat); SCOTCH_stratGraphMapBuild (&stradat, SCOTCH_STRATDEFAULT, 16, 0.03); SCOTCH_stratExit (&stradat); printf ("Sequential mapping strategy, SCOTCH_STRATRECURSIVE\n"); SCOTCH_stratInit (&stradat); SCOTCH_stratGraphMapBuild (&stradat, SCOTCH_STRATRECURSIVE, 16, 0.03); SCOTCH_stratExit (&stradat); printf ("Sequential mapping strategy, SCOTCH_STRATREMAP\n"); SCOTCH_stratInit (&stradat); SCOTCH_stratGraphMapBuild (&stradat, SCOTCH_STRATREMAP, 16, 0.03); SCOTCH_stratExit (&stradat); printf ("Sequential mapping strategy, SCOTCH_STRATRECURSIVE | SCOTCH_STRATREMAP\n"); SCOTCH_stratInit (&stradat); SCOTCH_stratGraphMapBuild (&stradat, SCOTCH_STRATRECURSIVE | SCOTCH_STRATREMAP, 16, 0.03); SCOTCH_stratExit (&stradat); printf ("Sequential ordering strategy, SCOTCH_STRATDEFAULT\n"); SCOTCH_stratInit (&stradat); SCOTCH_stratGraphOrderBuild (&stradat, SCOTCH_STRATDEFAULT, 0, 0.2); SCOTCH_stratExit (&stradat); printf ("Sequential ordering strategy, SCOTCH_STRATLEVELMAX\n"); SCOTCH_stratInit (&stradat); SCOTCH_stratGraphOrderBuild (&stradat, SCOTCH_STRATLEVELMAX, 3, 0.2); SCOTCH_stratExit (&stradat); printf ("Sequential ordering strategy, SCOTCH_STRATLEVELMIN\n"); SCOTCH_stratInit (&stradat); SCOTCH_stratGraphOrderBuild (&stradat, SCOTCH_STRATLEVELMIN, 3, 0.2); SCOTCH_stratExit (&stradat); printf ("Sequential ordering strategy, SCOTCH_STRATLEVELMAX | SCOTCH_STRATLEVELMIN\n"); SCOTCH_stratInit (&stradat); SCOTCH_stratGraphOrderBuild (&stradat, SCOTCH_STRATLEVELMAX | SCOTCH_STRATLEVELMIN, 3, 0.2); SCOTCH_stratExit (&stradat); printf ("Sequential ordering strategy, SCOTCH_STRATLEAFSIMPLE\n"); SCOTCH_stratInit (&stradat); SCOTCH_stratGraphOrderBuild (&stradat, SCOTCH_STRATLEAFSIMPLE, 3, 0.2); SCOTCH_stratExit (&stradat); printf ("Sequential ordering strategy, SCOTCH_STRATSEPASIMPLE\n"); SCOTCH_stratInit (&stradat); SCOTCH_stratGraphOrderBuild (&stradat, SCOTCH_STRATSEPASIMPLE, 3, 0.2); SCOTCH_stratExit (&stradat); return (0); } scotch-6.0.4.dfsg/src/check/test_scotch_graph_coarsen.c0000644002563400244210000001335412474563753026344 0ustar trophimeutilisateurs du domaine/* Copyright 2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : test_scotch_graph_coarsen.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module tests the operation of **/ /** the SCOTCH_graphColor() routine. **/ /** **/ /** DATES : # Version 6.0 : from : 15 oct 2014 **/ /** to 15 oct 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #include #if (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) #include #endif /* (((defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined HAVE_STDINT_H)) */ #include #include #include "scotch.h" /*********************/ /* */ /* The main routine. */ /* */ /*********************/ int main ( int argc, char * argv[]) { SCOTCH_Num baseval; FILE * fileptr; SCOTCH_Num finevertnbr; SCOTCH_Graph finegrafdat; double coarrat; SCOTCH_Num coarvertmax; SCOTCH_Graph coargrafdat; SCOTCH_Num * coarmulttab; int o; SCOTCH_errorProg (argv[0]); if (SCOTCH_graphInit (&finegrafdat) != 0) { /* Initialize source, fine graph */ SCOTCH_errorPrint ("main: cannot initialize fine graph"); return (1); } if (SCOTCH_graphInit (&coargrafdat) != 0) { /* Initialize coarse graph */ SCOTCH_errorPrint ("main: cannot initialize coarse graph"); return (1); } if ((fileptr = fopen (argv[1], "r")) == NULL) { SCOTCH_errorPrint ("main: cannot open file"); return (1); } if (SCOTCH_graphLoad (&finegrafdat, fileptr, -1, 0) != 0) { /* Read source graph */ SCOTCH_errorPrint ("main: cannot load graph"); return (1); } fclose (fileptr); SCOTCH_graphData (&finegrafdat, &baseval, &finevertnbr, NULL, NULL, NULL, NULL, NULL, NULL, NULL); coarrat = 0.8; coarvertmax = (SCOTCH_Num) (coarrat * (double) finevertnbr); if ((coarmulttab = malloc (coarvertmax * 2 * sizeof (SCOTCH_Num))) == NULL) { SCOTCH_errorPrint ("main: out of memory (1)"); return (1); } if ((o = SCOTCH_graphCoarsen (&finegrafdat, &coargrafdat, coarmulttab, 1, coarrat)) >= 2) { SCOTCH_errorPrint ("main: cannot coarsen graph"); return (1); } if (o == 0) { SCOTCH_Num finevertnnd; SCOTCH_Num coarvertnbr; SCOTCH_Num coarvertnum; SCOTCH_Num coarverttmp; SCOTCH_graphSize (&coargrafdat, &coarvertnbr, NULL); printf ("Graph coarsened with a ratio of %lg\n", (double) coarvertnbr / (double) finevertnbr); for (coarvertnum = 0, coarverttmp = finevertnbr, finevertnnd = finevertnbr + baseval; coarvertnum < coarvertnbr; coarvertnum ++) { SCOTCH_Num finevertnum0; SCOTCH_Num finevertnum1; finevertnum0 = coarmulttab[2 * coarvertnum]; finevertnum1 = coarmulttab[2 * coarvertnum + 1]; if ((finevertnum0 < baseval) || (finevertnum0 >= finevertnnd) || (finevertnum1 < baseval) || (finevertnum1 >= finevertnnd)) { SCOTCH_errorPrint ("main: invalid multinode array (1)"); return (1); } if (finevertnum0 != finevertnum1) coarverttmp --; } if (coarverttmp != coarvertnbr) { SCOTCH_errorPrint ("main: invalid multinode array (2)"); return (1); } } else printf ("Graph could not be coarsened with a ratio of %lg\n", coarrat); free (coarmulttab); SCOTCH_graphExit (&coargrafdat); SCOTCH_graphExit (&finegrafdat); return (0); } scotch-6.0.4.dfsg/src/scotch/0000755002563400244210000000000012474551106021150 5ustar trophimeutilisateurs du domainescotch-6.0.4.dfsg/src/scotch/gcv.h0000644002563400244210000001113012473176651022103 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gcv.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a graph file converter. **/ /** This module contains the data declara- **/ /** tions for the main module. **/ /** **/ /** DATES : # Version 0.0 : from : 02 apr 1993 **/ /** to 02 apr 1993 **/ /** # Version 2.0 : from : 28 oct 1994 **/ /** to 16 nov 1994 **/ /** # Version 3.0 : from : 08 sep 1995 **/ /** to 17 sep 1995 **/ /** # Version 3.1 : from : 22 mar 1996 **/ /** to 22 mar 1996 **/ /** # Version 3.2 : from : 04 oct 1996 **/ /** to 04 mar 1997 **/ /** # Version 3.3 : from : 06 oct 1998 **/ /** to : 06 oct 1998 **/ /** # Version 3.4 : from : 13 oct 1999 **/ /** to : 14 oct 1999 **/ /** # Version 4.0 : from : 29 nov 2003 **/ /** to : 29 nov 2003 **/ /** # Version 6.0 : from : 12 nov 2014 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines */ /*+ File name aliases. +*/ #define C_FILENBR 3 /* Number of files in list */ #define C_FILEARGNBR 3 /* Number of files which can be arguments */ #define C_filenamesrcinp fileBlockName (C_fileTab, 0) /* External graph input file name */ #define C_filenamesrcout fileBlockName (C_fileTab, 1) /* Source graph output file name */ #define C_filenamegeoout fileBlockName (C_fileTab, 2) /* Source graph geometry file name */ #define C_filepntrsrcinp fileBlockFile (C_fileTab, 0) /* External graph input file */ #define C_filepntrsrcout fileBlockFile (C_fileTab, 1) /* Source graph output file */ #define C_filepntrgeoout fileBlockFile (C_fileTab, 2) /* Source graph geometry file */ /* ** The type and structure definitions. */ /*+ This structure defines the method array element. +*/ typedef struct C_Format_ { char code; /* Format type code */ int (* func) (); /* Function to call */ } C_Format; scotch-6.0.4.dfsg/src/scotch/gtst.h0000644002563400244210000000705612473176651022321 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gtst.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the declarations **/ /** for the source graph analyzer. **/ /** **/ /** DATES : # Version 2.0 : from : 31 oct 1993 **/ /** to 31 oct 1993 **/ /** # Version 3.2 : from : 03 jun 1997 **/ /** to : 03 jun 1997 **/ /** # Version 3.3 : from : 19 oct 1998 **/ /** to : 19 oct 1998 **/ /** # Version 4.0 : from : 10 sep 2003 **/ /** to : 10 sep 2003 **/ /** # Version 6.0 : from : 12 nov 2014 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /** File name aliases. **/ #define C_FILENBR 2 /* Number of files in list */ #define C_FILEARGNBR 2 /* Number of files which can be arguments */ #define C_filenamesrcinp fileBlockName (C_fileTab, 0) /* Source graph input file name */ #define C_filenamedatout fileBlockName (C_fileTab, 1) /* Statistics output file name */ #define C_filepntrsrcinp fileBlockFile (C_fileTab, 0) /* Source graph input file */ #define C_filepntrdatout fileBlockFile (C_fileTab, 1) /* Statistics output file */ scotch-6.0.4.dfsg/src/scotch/amk_hy.c0000644002563400244210000002023012473176651022570 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : amk_hy.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Creates the distance map for hypercube **/ /** graphs, to be used to build the archi- **/ /** tecture description files for these **/ /** graphs. **/ /** **/ /** DATES : # Version 2.0 : from : 14 nov 1994 **/ /** to : 14 nov 1994 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to : 19 sep 1995 **/ /** # Version 3.2 : from : 31 may 1997 **/ /** to : 02 jun 1997 **/ /** # Version 3.3 : from : 02 oct 1998 **/ /** to : 02 oct 1998 **/ /** # Version 3.4 : from : 03 feb 2000 **/ /** to : 03 feb 2000 **/ /** # Version 5.0 : from : 23 dec 2007 **/ /** to : 16 mar 2008 **/ /** # Version 5.1 : from : 01 jul 2010 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define AMK_HY #include "module.h" #include "common.h" #include "scotch.h" #include "amk_hy.h" /* ** The static definitions. */ static int C_paraNum = 0; /* Number of parameters */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[C_FILENBR] = { /* The file array */ { "w" } }; static const char * C_usageList[] = { "amk_hy [] ", " -h : Display this help", " -V : Print program version and copyright", NULL }; /*************************************************/ /* */ /* The main routine, which computes the distance */ /* triangular table. */ /* */ /*************************************************/ int main ( int argc, char * argv[]) { SCOTCH_Num hdim; /* Hypercube dimension */ SCOTCH_Num hnbr; /* Number of hypercube vertices */ SCOTCH_Num hmax; /* Number of domains */ SCOTCH_Num hv0, hv1; SCOTCH_Num i, j; errorProg ("amk_hy"); if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } hdim = 1; /* Preset hypercube dimension */ fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_paraNum < 1) { /* If number of parameters not reached */ if ((hdim = atoi (argv[i])) < 1) { /* Get the dimension */ errorPrint ("main: invalid dimension '%s'", argv[i]); return (1); } C_paraNum ++; continue; /* Process the other parameters */ } if (C_fileNum < C_FILEARGNBR) /* A file name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else { errorPrint ("main: too many file names given"); return (1); } } else { /* If found an option name */ switch (argv[i][1]) { case 'H' : /* Give the usage message */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'V' : fprintf (stderr, "amk_hy, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: unprocessed option '%s'", argv[i]); return (1); } } } fileBlockOpen (C_fileTab, C_FILENBR); /* Open all files */ hnbr = 1 << hdim; /* Compute number of terminals */ hmax = (1 << (hdim + 1)) - 1; /* Maximum terminal value */ fprintf (C_filepntrtgtout, "deco\n0\n" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n", /* Print the file header */ (SCOTCH_Num) hnbr, /* Print number of terminal domains */ (SCOTCH_Num) hmax); /* Print the biggest terminal value */ for (i = 0; i < hnbr; i ++) /* For all vertices */ fprintf (C_filepntrtgtout, SCOTCH_NUMSTRING "\t1\t" SCOTCH_NUMSTRING "\n", (SCOTCH_Num) i, /* Print terminal label */ (SCOTCH_Num) (hnbr + i)); /* Print terminal number */ for (hv0 = 1; hv0 < hnbr; hv0 ++) { /* For all vertices */ for (hv1 = 0; hv1 < hv0; hv1 ++) { for (i = hv0 ^ hv1, j = 0; i > 0; i >>=1) j += (i & 1); fprintf (C_filepntrtgtout, (hv1 == 0) ? SCOTCH_NUMSTRING : " " SCOTCH_NUMSTRING, (SCOTCH_Num) j); } fprintf (C_filepntrtgtout, "\n"); } fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } scotch-6.0.4.dfsg/src/scotch/mtst.c0000644002563400244210000001667412473176651022330 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mtst.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This program gives statistics on source **/ /** meshes. **/ /** **/ /** DATES : # Version 4.0 : from : 25 feb 2003 **/ /** to 27 jan 2004 **/ /** # Version 5.0 : from : 23 dec 2007 **/ /** to : 16 mar 2008 **/ /** # Version 5.1 : from : 01 jul 2010 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define MTST #include "module.h" #include "common.h" #include "scotch.h" #include "mtst.h" /* ** The static definitions. */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[C_FILENBR] = { /* The file array */ { "r" }, { "w" } }; static const char * C_usageList[] = { "mtst [ []] ", " -h : Display this help", " -V : Print program version and copyright", NULL }; /******************************/ /* */ /* This is the main function. */ /* */ /******************************/ int main ( int argc, char * argv[]) { SCOTCH_Mesh meshdat; SCOTCH_Num velmnbr; SCOTCH_Num vnodnbr; SCOTCH_Num vnlomin; SCOTCH_Num vnlomax; SCOTCH_Num vnlosum; double vnloavg; double vnlodlt; SCOTCH_Num edegmin; SCOTCH_Num edegmax; double edegavg; double edegdlt; SCOTCH_Num ndegmin; SCOTCH_Num ndegmax; double ndegavg; double ndegdlt; SCOTCH_Num edgenbr; int i; errorProg ("mtst"); if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); exit (0); } fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_fileNum < C_FILEARGNBR) /* File name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else { errorPrint ("main: too many file names given"); exit (1); } } else { /* If found an option name */ switch (argv[i][1]) { case 'H' : /* Give the usage message */ case 'h' : usagePrint (stdout, C_usageList); exit (0); case 'V' : fprintf (stderr, "mtst, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: unprocessed option '%s'", argv[i]); exit (1); } } } fileBlockOpen (C_fileTab, C_FILENBR); /* Open all files */ SCOTCH_meshInit (&meshdat); SCOTCH_meshLoad (&meshdat, C_filepntrsrcinp, -1); SCOTCH_meshCheck (&meshdat); SCOTCH_meshSize (&meshdat, &velmnbr, &vnodnbr, &edgenbr); SCOTCH_meshStat (&meshdat, &vnlomin, &vnlomax, &vnlosum, &vnloavg, &vnlodlt, &edegmin, &edegmax, &edegavg, &edegdlt, &ndegmin, &ndegmax, &ndegavg, &ndegdlt); fprintf (C_filepntrdatout, "S\tElements\tnbr=" SCOTCH_NUMSTRING "\n", (SCOTCH_Num) velmnbr); fprintf (C_filepntrdatout, "S\tNodes\tnbr=" SCOTCH_NUMSTRING "\n", (SCOTCH_Num) vnodnbr); fprintf (C_filepntrdatout, "S\tNode load\tmin=" SCOTCH_NUMSTRING "\tmax=" SCOTCH_NUMSTRING "\tsum=" SCOTCH_NUMSTRING "\tavg=%g\tdlt=%g\n", (SCOTCH_Num) vnlomin, (SCOTCH_Num) vnlomax, (SCOTCH_Num) vnlosum, vnloavg, vnlodlt); fprintf (C_filepntrdatout, "S\tElement degree\tmin=" SCOTCH_NUMSTRING "\tmax=" SCOTCH_NUMSTRING "\tsum=" SCOTCH_NUMSTRING "\tavg=%g\tdlt=%g\n", (SCOTCH_Num) edegmin, (SCOTCH_Num) edegmax, (SCOTCH_Num) (edgenbr / 2), edegavg, edegdlt); fprintf (C_filepntrdatout, "S\tNode degree\tmin=" SCOTCH_NUMSTRING "\tmax=" SCOTCH_NUMSTRING "\tsum=" SCOTCH_NUMSTRING "\tavg=%g\tdlt=%g\n", (SCOTCH_Num) ndegmin, (SCOTCH_Num) ndegmax, (SCOTCH_Num) (edgenbr / 2), ndegavg, ndegdlt); fprintf (C_filepntrdatout, "S\tEdge\tnbr=" SCOTCH_NUMSTRING "\n", (SCOTCH_Num) (edgenbr / 2)); fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ SCOTCH_meshExit (&meshdat); #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } scotch-6.0.4.dfsg/src/scotch/amk_grf.c0000644002563400244210000002665112473176651022743 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : amk_grf.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Creates the architecture description **/ /** file for any source graph. **/ /** **/ /** DATES : # Version 3.0 : from : 06 jul 1995 **/ /** to : 02 oct 1995 **/ /** # Version 3.1 : from : 26 mar 1996 **/ /** to : 26 mar 1996 **/ /** # Version 3.2 : from : 23 apr 1997 **/ /** to : 03 jun 1998 **/ /** # Version 3.3 : from : 15 may 1999 **/ /** to : 15 may 1999 **/ /** # Version 3.4 : from : 03 feb 2000 **/ /** to : 03 feb 2000 **/ /** # Version 4.0 : from : 11 dec 2001 **/ /** to : 17 mar 2005 **/ /** # Version 5.0 : from : 23 dec 2007 **/ /** to : 16 mar 2008 **/ /** # Version 5.1 : from : 11 dec 2008 **/ /** to : 17 jul 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define AMK_GRF #include "module.h" #include "common.h" #include "scotch.h" #include "amk_grf.h" /* ** The static variables. */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[C_FILENBR] = { /* File array */ { "r" }, { "w" }, { "r" } }; static const char * C_usageList[] = { /* Usage */ "amk_grf [ []] ", " -b : Apply bipartitioning strategy ", " -h : Display this help", " -l : Load vertex list from ", " -V : Print program version and copyright", "", "Default option set is : '-Bhf{move=1000}/((load0=load)|(load0=0))?x;'", NULL }; /******************************/ /* */ /* This is the main function. */ /* */ /******************************/ int main ( int argc, char * argv[]) { SCOTCH_Strat bipastrat; /* Bipartitioning strategy */ SCOTCH_Arch archdat; /* Target (terminal) architecture */ SCOTCH_Graph grafdat; /* Source graph to turn into architecture */ SCOTCH_Num vertnbr; /* Number of vertices in graph */ SCOTCH_Num * vlbltab; /* Pointer to vertex label array, if present */ SCOTCH_Num listnbr; /* Size of list array */ SCOTCH_Num * listtab; /* Pointer to list array */ C_VertSort * sorttab; /* Vertex label sort area */ SCOTCH_Num baseval; int flagval; /* Process flags */ int i; errorProg ("amk_grf"); if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } flagval = C_FLAGNONE; SCOTCH_stratInit (&bipastrat); fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_fileNum < C_FILEARGNBR) /* File name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else { errorPrint ("main: too many file names given"); return (1); } } else { /* If found an option name */ switch (argv[i][1]) { case 'B' : /* Bipartitioning strategy */ case 'b' : SCOTCH_stratExit (&bipastrat); SCOTCH_stratInit (&bipastrat); if ((SCOTCH_stratGraphBipart (&bipastrat, &argv[i][2])) != 0) { errorPrint ("main: invalid bipartitioning strategy"); return (1); } break; case 'H' : /* Give the usage message */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'L' : /* Input vertex list */ case 'l' : flagval |= C_FLAGVRTINP; if (argv[i][2] != '\0') C_filenamevrtinp = &argv[i][2]; break; case 'V' : fprintf (stderr, "amk_grf, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: unprocessed option '%s'", argv[i]); return (1); } } } fileBlockOpen (C_fileTab, C_FILENBR); /* Open all files */ SCOTCH_graphInit (&grafdat); /* Create graph structure */ SCOTCH_graphLoad (&grafdat, C_filepntrgrfinp, -1, 0); /* Load source graph */ SCOTCH_graphData (&grafdat, &baseval, &vertnbr, NULL, NULL, NULL, /* Get graph data */ &vlbltab, NULL, NULL, NULL); listnbr = 0; /* Initialize vertex list */ listtab = NULL; if (flagval & C_FLAGVRTINP) { /* If list of vertices provided */ SCOTCH_Num listnum; if ((intLoad (C_filepntrvrtinp, &listnbr) != 1) || /* Read list size */ (listnbr < 0) || (listnbr > vertnbr)) { errorPrint ("main: bad list input (1)"); return (1); } if ((listtab = (SCOTCH_Num *) memAlloc (listnbr * sizeof (SCOTCH_Num) + 1)) == NULL) { errorPrint ("main: out of memory (1)"); return (1); } for (listnum = 0; listnum < listnbr; listnum ++) { /* Read list data */ if (intLoad (C_filepntrvrtinp, &listtab[listnum]) != 1) { errorPrint ("main: bad list input (2)"); return (1); } } intSort1asc1 (listtab, listnbr); for (listnum = 0; listnum < listnbr - 1; listnum ++) { /* Search for duplicates */ if (listtab[listnum] == listtab[listnum + 1]) { errorPrint ("main: duplicate list labels"); memFree (listtab); return (1); } } if (vlbltab != NULL) { /* If graph has vertex labels */ SCOTCH_Num vertnum; if ((sorttab = (C_VertSort *) memAlloc (vertnbr * sizeof (C_VertSort))) == NULL) { errorPrint ("main: out of memory (2)"); memFree (listtab); return (1); } for (vertnum = 0; vertnum < vertnbr; vertnum ++) { /* Initialize sort area */ sorttab[vertnum].vlblnum = vlbltab[vertnum]; sorttab[vertnum].vertnum = vertnum; } intSort2asc1 (sorttab, vertnbr); /* Sort by ascending labels */ for (listnum = 0, vertnum = 0; listnum < listnbr; listnum ++) { /* For all labels in list */ while ((vertnum < vertnbr) && (sorttab[vertnum].vlblnum < listtab[listnum])) vertnum ++; /* Search vertex graph with corresponding label */ if ((vertnum >= vertnbr) || /* If label not found */ (sorttab[vertnum].vlblnum > listtab[listnum])) { errorPrint ("main: list label '" SCOTCH_NUMSTRING "' not in graph", (SCOTCH_Num) listtab[listnum]); memFree (sorttab); memFree (listtab); return (1); } listtab[listnum] = sorttab[vertnum ++].vertnum; /* Replace label by number */ } memFree (sorttab); /* Free sort area */ } } SCOTCH_archInit (&archdat); /* Initialize target architecture */ SCOTCH_archBuild (&archdat, &grafdat, listnbr, listtab, &bipastrat); /* Compute architecture */ SCOTCH_archSave (&archdat, C_filepntrtgtout); /* Write target architecture */ fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end potential (un)compression tasks */ SCOTCH_graphExit (&grafdat); /* Free target graph */ SCOTCH_archExit (&archdat); /* Free target architecture */ SCOTCH_stratExit (&bipastrat); /* Free strategy string */ if (listtab != NULL) /* If vertex list provided */ memFree (listtab); /* Free it */ #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } scotch-6.0.4.dfsg/src/scotch/gcv.c0000644002563400244210000002422612473176651022110 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gcv.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** Bruno MARCUSSEAU (v3.1) **/ /** **/ /** FUNCTION : Part of a graph file converter. **/ /** This module contains the main function. **/ /** **/ /** DATES : # Version 0.0 : from : 02 apr 1993 **/ /** to 02 apr 1993 **/ /** # Version 2.0 : from : 28 oct 1994 **/ /** to 16 nov 1994 **/ /** # Version 3.0 : from : 08 sep 1995 **/ /** to 20 sep 1995 **/ /** # Version 3.1 : from : 22 mar 1996 **/ /** to 22 mar 1996 **/ /** # Version 3.2 : from : 04 oct 1996 **/ /** to 26 may 1997 **/ /** # Version 3.3 : from : 06 oct 1998 **/ /** to : 21 dec 1998 **/ /** # Version 3.4 : from : 05 oct 1999 **/ /** to : 03 feb 2000 **/ /** # Version 4.0 : from : 29 nov 2003 **/ /** to : 19 jan 2004 **/ /** # Version 5.0 : from : 23 dec 2007 **/ /** to : 11 jun 2008 **/ /** # Version 5.1 : from : 01 jul 2010 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GCV #include "module.h" #include "common.h" #include "scotch.h" #include "gcv.h" /* ** The static and global variables. */ static int C_inpFormatType = 0; /* Input graph format */ static char * C_inpFormatData = "\0"; /* Pointer to auxiliary data */ static const C_Format C_inpFormatTab[] = { /* Table of input formats */ { 'B', SCOTCH_graphGeomLoadHabo }, { 'b', SCOTCH_graphGeomLoadHabo }, { 'C', SCOTCH_graphGeomLoadChac }, { 'c', SCOTCH_graphGeomLoadChac }, { 'M', SCOTCH_graphGeomLoadMmkt }, { 'm', SCOTCH_graphGeomLoadMmkt }, { 'S', SCOTCH_graphGeomLoadScot }, { 's', SCOTCH_graphGeomLoadScot }, { '\0', NULL } }; static int C_outFormatType = 4; /* Output graph format */ static char * C_outFormatData = "\0"; /* Pointer to auxiliary data */ static C_Format C_outFormatTab[] = { /* Table of output formats */ { 'C', SCOTCH_graphGeomSaveChac }, { 'c', SCOTCH_graphGeomSaveChac }, { 'M', SCOTCH_graphGeomSaveMmkt }, { 'm', SCOTCH_graphGeomSaveMmkt }, { 'S', SCOTCH_graphGeomSaveScot }, { 's', SCOTCH_graphGeomSaveScot }, { '\0', NULL } }; static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[3] = { /* File array */ { "r" }, { "w" }, { "w" } }; static const char * C_usageList[] = { "gcv [ [ []]] ", " -h : Display this help", " -i : Select input file format", " b : Boeing-Harwell format (matrices)", " c : Chaco v2.0 format (adjacency)", " m : Matrix Market format (edges, symmetrized)", " s : Scotch v3.0 format (adjacency)", " -o : Select output file format", " c : Chaco v2.0 format (adjacency)", " m : Matrix Market symmetric pattern format (edges)", " s : Scotch v3.0 format (adjacency)", " -V : Print program version and copyright", "", "Default option set is : '-Ib -Os'", NULL }; /*****************************/ /* */ /* This is the main function */ /* */ /*****************************/ int main ( int argc, char * argv[]) { SCOTCH_Graph grafdat; SCOTCH_Geom geomdat; int i, j; errorProg ("gcv"); if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_fileNum < C_FILEARGNBR) /* File name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else { errorPrint ("main: too many file names given"); return (1); } } else { /* If found an option name */ switch (argv[i][1]) { case 'H' : /* Give help */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'I' : /* Select input file type */ case 'i' : for (j = 0; C_inpFormatTab[j].code != '\0'; j ++) { /* Find proper format code */ if (C_inpFormatTab[j].code == argv[i][2]) { C_inpFormatType = j; C_inpFormatData = &argv[i][3]; break; } } if (C_inpFormatTab[j].code == '\0') { errorPrint ("main: unprocessed option '%s'", argv[i]); return (1); } break; case 'O' : /* Select input file type */ case 'o' : for (j = 0; C_outFormatTab[j].code != '\0'; j ++) { /* Find proper format code */ if (C_outFormatTab[j].code == argv[i][2]) { C_outFormatType = j; C_outFormatData = &argv[i][3]; break; } } if (C_inpFormatTab[j].code == '\0') { errorPrint ("main: unprocessed option '%s'", argv[i]); return (1); } break; case 'V' : fprintf (stderr, "gcv, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2004,2007,2008,2010-2012,2014 Universite de Bordeaux, INRIA & CNRS\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: unprocessed option '%s'", argv[i]); return (1); } } } fileBlockOpen (C_fileTab, C_FILENBR); /* Open all files */ SCOTCH_graphInit (&grafdat); SCOTCH_geomInit (&geomdat); C_inpFormatTab[C_inpFormatType].func (&grafdat, &geomdat, C_filepntrsrcinp, NULL, C_inpFormatData); #ifdef SCOTCH_DEBUG_ALL if (SCOTCH_graphCheck (&grafdat) != 0) { errorPrint ("main: bad graph structure"); return (1); } #endif /* SCOTCH_DEBUG_ALL */ C_outFormatTab[C_outFormatType].func (&grafdat, &geomdat, C_filepntrsrcout, C_filepntrgeoout, C_outFormatData); fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ SCOTCH_geomExit (&geomdat); SCOTCH_graphExit (&grafdat); #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } scotch-6.0.4.dfsg/src/scotch/dgord.c0000644002563400244210000004020212473176651022420 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgord.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Cedric CHEVALIER (v5.0) **/ /** **/ /** FUNCTION : Part of a parallel sparse matrix **/ /** ordering software. **/ /** This module contains the main function. **/ /** **/ /** DATES : # Version 5.0 : from : 30 apr 2006 **/ /** to : 16 jun 2008 **/ /** # Version 5.1 : from : 26 oct 2008 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DGORD #define SCOTCH_PTSCOTCH #include #include "module.h" #include "common.h" #include "ptscotch.h" #include "dgord.h" /* ** The static and global definitions. */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[C_FILENBR] = { /* File array */ { "r" }, { "w" }, { "w" }, { "w" }, { "w" } }; static const char * C_usageList[] = { "dgord [ [ []]] ", " -b : Output block ordering data instead of plain ordering data", " -c : Choose default ordering strategy according to one or several of :", " b : enforce load balance as much as possible", " q : privilege quality over speed (default)", " s : privilege speed over quality", " t : enforce safety", " x : enforce scalability", " -h : Display this help", " -m : Save column block mapping data to ", " -o : Set parallel ordering strategy (see user's manual)", " -r : Set root process for centralized files (default is 0)", " -t : Save partitioning tree data to ", " -V : Print program version and copyright", " -v : Set verbose mode to :", " a : memory allocation information", " s : strategy information", " t : timing information", "", "See default strategy with option '-vs'", NULL }; /*********************/ /* */ /* The main routine. */ /* */ /*********************/ int main ( int argc, char * argv[]) { SCOTCH_Dgraph grafdat; SCOTCH_Dordering ordedat; SCOTCH_Strat stradat; SCOTCH_Num straval; char * straptr; int flagval; int procglbnbr; int proclocnum; int protglbnum; /* Root process */ Clock runtime[2]; /* Timing variables */ double reduloctab[12]; /* 3 * (min, max, sum) */ double reduglbtab[12]; MPI_Datatype redutype; MPI_Op reduop; int i, j; #ifdef SCOTCH_PTHREAD int thrdlvlreqval; int thrdlvlproval; #endif /* SCOTCH_PTHREAD */ errorProg ("dgord"); #ifdef SCOTCH_PTHREAD thrdlvlreqval = MPI_THREAD_MULTIPLE; if (MPI_Init_thread (&argc, &argv, thrdlvlreqval, &thrdlvlproval) != MPI_SUCCESS) errorPrint ("main: Cannot initialize (1)"); if (thrdlvlreqval > thrdlvlproval) errorPrint ("main: MPI implementation is not thread-safe: recompile without SCOTCH_PTHREAD"); #else /* SCOTCH_PTHREAD */ if (MPI_Init (&argc, &argv) != MPI_SUCCESS) errorPrint ("main: Cannot initialize (2)"); #endif /* SCOTCH_PTHREAD */ MPI_Comm_size (MPI_COMM_WORLD, &procglbnbr); /* Get communicator data */ MPI_Comm_rank (MPI_COMM_WORLD, &proclocnum); protglbnum = 0; /* Assume root process is process 0 */ if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } SCOTCH_randomProc (proclocnum); /* Record process number to initialize pseudo-random seed */ flagval = C_FLAGNONE; /* Default behavior */ straval = 0; /* No strategy flags */ straptr = NULL; SCOTCH_stratInit (&stradat); fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_fileNum < C_FILEARGNBR) /* File name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else errorPrint ("main: too many file names given"); } else { /* If found an option name */ switch (argv[i][1]) { case 'B' : case 'b' : flagval |= C_FLAGBLOCK; break; case 'C' : case 'c' : /* Strategy selection parameters */ for (j = 2; argv[i][j] != '\0'; j ++) { switch (argv[i][j]) { case 'B' : case 'b' : straval |= SCOTCH_STRATBALANCE; break; case 'Q' : case 'q' : straval |= SCOTCH_STRATQUALITY; break; case 'S' : case 's' : straval |= SCOTCH_STRATSPEED; break; case 'T' : case 't' : straval |= SCOTCH_STRATSAFETY; break; case 'X' : case 'x' : straval |= SCOTCH_STRATSCALABILITY; break; default : errorPrint ("main: invalid strategy selection option '%c'", argv[i][j]); } } break; #ifdef SCOTCH_DEBUG_ALL case 'D' : case 'd' : flagval |= C_FLAGDEBUG; break; #endif /* SCOTCH_DEBUG_ALL */ case 'H' : /* Give the usage message */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'M' : /* Output separator mapping */ case 'm' : flagval |= C_FLAGMAPOUT; if (argv[i][2] != '\0') C_filenamemapout = &argv[i][2]; break; case 'O' : /* Ordering strategy */ case 'o' : straptr = &argv[i][2]; SCOTCH_stratExit (&stradat); SCOTCH_stratInit (&stradat); SCOTCH_stratDgraphOrder (&stradat, straptr); break; case 'R' : /* Root process (if necessary) */ case 'r' : protglbnum = atoi (&argv[i][2]); if ((protglbnum < 0) || (protglbnum >= procglbnbr) || ((protglbnum == 0) && (argv[i][2] != '0'))) errorPrint ("main: invalid root process number"); break; case 'T' : /* Output separator tree */ case 't' : flagval |= C_FLAGTREOUT; if (argv[i][2] != '\0') C_filenametreout = &argv[i][2]; break; case 'V' : fprintf (stderr, "dgord, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2007-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); case 'v' : /* Output control info */ for (j = 2; argv[i][j] != '\0'; j ++) { switch (argv[i][j]) { case 'A' : case 'a' : #ifdef COMMON_MEMORY_TRACE flagval |= C_FLAGVERBMEM; #else /* COMMON_MEMORY_TRACE */ errorPrint ("main: not compiled with COMMON_MEMORY_TRACE"); #endif /* COMMON_MEMORY_TRACE */ break; case 'S' : case 's' : flagval |= C_FLAGVERBSTR; break; case 'T' : case 't' : flagval |= C_FLAGVERBTIM; break; default : errorPrint ("main: unprocessed parameter '%c' in '%s'", argv[i][j], argv[i]); } } break; default : errorPrint ("main: unprocessed option '%s'", argv[i]); } } } #ifdef SCOTCH_DEBUG_ALL if ((flagval & C_FLAGDEBUG) != 0) { fprintf (stderr, "Proc %4d of %d, pid %d\n", proclocnum, procglbnbr, getpid ()); if (proclocnum == protglbnum) { /* Synchronize on keybord input */ char c; printf ("Waiting for key press...\n"); scanf ("%c", &c); } MPI_Barrier (MPI_COMM_WORLD); } #endif /* SCOTCH_DEBUG_ALL */ fileBlockOpenDist (C_fileTab, C_FILENBR, procglbnbr, proclocnum, protglbnum); /* Open all files */ clockInit (&runtime[0]); clockStart (&runtime[0]); SCOTCH_dgraphInit (&grafdat, MPI_COMM_WORLD); SCOTCH_dgraphLoad (&grafdat, C_filepntrsrcinp, -1, 0); if (straval != 0) { if (straptr != NULL) errorPrint ("main: options '-c' and '-o' are exclusive"); SCOTCH_stratDgraphOrderBuild (&stradat, straval, (SCOTCH_Num) procglbnbr, 0, 0.2); } clockStop (&runtime[0]); /* Get input time */ clockInit (&runtime[1]); #ifdef SCOTCH_DEBUG_ALL if ((flagval & C_FLAGDEBUG) != 0) MPI_Barrier (MPI_COMM_WORLD); #endif /* SCOTCH_DEBUG_ALL */ clockStart (&runtime[1]); SCOTCH_dgraphGhst (&grafdat); /* Compute it once for good */ SCOTCH_dgraphOrderInit (&grafdat, &ordedat); SCOTCH_dgraphOrderCompute (&grafdat, &ordedat, &stradat); clockStop (&runtime[1]); /* Get ordering time */ #ifdef SCOTCH_DEBUG_ALL if ((flagval & C_FLAGDEBUG) != 0) MPI_Barrier (MPI_COMM_WORLD); #endif /* SCOTCH_DEBUG_ALL */ clockStart (&runtime[0]); if (proclocnum == protglbnum) { if ((flagval & C_FLAGBLOCK) == 0) SCOTCH_dgraphOrderSave (&grafdat, &ordedat, C_filepntrordout); else SCOTCH_dgraphOrderSaveBlock (&grafdat, &ordedat, C_filepntrordout); if ((flagval & C_FLAGMAPOUT) != 0) /* If mapping wanted */ SCOTCH_dgraphOrderSaveMap (&grafdat, &ordedat, C_filepntrmapout); /* Write mapping */ if ((flagval & C_FLAGTREOUT) != 0) /* If separator tree wanted */ SCOTCH_dgraphOrderSaveTree (&grafdat, &ordedat, C_filepntrtreout); /* Write tree */ } else { if ((flagval & C_FLAGBLOCK) == 0) SCOTCH_dgraphOrderSave (&grafdat, &ordedat, NULL); else SCOTCH_dgraphOrderSaveBlock (&grafdat, &ordedat, NULL); if ((flagval & C_FLAGMAPOUT) != 0) SCOTCH_dgraphOrderSaveMap (&grafdat, &ordedat, NULL); if ((flagval & C_FLAGTREOUT) != 0) SCOTCH_dgraphOrderSaveTree (&grafdat, &ordedat, NULL); } clockStop (&runtime[0]); #ifdef SCOTCH_DEBUG_ALL if ((flagval & C_FLAGDEBUG) != 0) MPI_Barrier (MPI_COMM_WORLD); #endif /* SCOTCH_DEBUG_ALL */ MPI_Type_contiguous (3, MPI_DOUBLE, &redutype); MPI_Type_commit (&redutype); MPI_Op_create ((MPI_User_function *) dgordStatReduceOp, 1, &reduop); if ((flagval & C_FLAGVERBTIM) != 0) { reduloctab[0] = reduloctab[1] = reduloctab[2] = (double) clockVal (&runtime[1]); reduloctab[3] = reduloctab[4] = reduloctab[5] = (double) clockVal (&runtime[0]); reduloctab[6] = reduloctab[7] = reduloctab[8] = reduloctab[0] + reduloctab[3]; MPI_Allreduce (&reduloctab[0], &reduglbtab[0], 3, redutype, reduop, MPI_COMM_WORLD); } #ifdef COMMON_MEMORY_TRACE if ((flagval & C_FLAGVERBMEM) != 0) { reduloctab[9] = reduloctab[10] = reduloctab[11] = (double) memMax (); MPI_Allreduce (&reduloctab[9], &reduglbtab[9], 1, redutype, reduop, MPI_COMM_WORLD); } #endif /* COMMON_MEMORY_TRACE */ MPI_Op_free (&reduop); MPI_Type_free (&redutype); if (C_filepntrlogout != NULL) { if ((flagval & C_FLAGVERBSTR) != 0) { fprintf (C_filepntrlogout, "S\tStrat="); SCOTCH_stratSave (&stradat, C_filepntrlogout); putc ('\n', C_filepntrlogout); } if ((flagval & C_FLAGVERBTIM) != 0) { fprintf (C_filepntrlogout, "T\tOrder\tmin=%g\tmax=%g\tavg=%g\nT\tI/O\tmin=%g\tmax=%g\tavg=%g\nT\tTotal\tmin=%g\tmax=%g\tavg=%g\n", reduglbtab[0], reduglbtab[1], reduglbtab[2] / (double) procglbnbr, reduglbtab[3], reduglbtab[4], reduglbtab[5] / (double) procglbnbr, reduglbtab[6], reduglbtab[7], reduglbtab[8] / (double) procglbnbr); } #ifdef COMMON_MEMORY_TRACE if ((flagval & C_FLAGVERBMEM) != 0) fprintf (C_filepntrlogout, "A\tMemory\tmin=%g\tmax=%g\tavg=%g\n", reduglbtab[9], reduglbtab[10], reduglbtab[11] / (double) procglbnbr); #endif /* COMMON_MEMORY_TRACE */ } fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ SCOTCH_dgraphOrderExit (&grafdat, &ordedat); SCOTCH_dgraphExit (&grafdat); SCOTCH_stratExit (&stradat); MPI_Finalize (); #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } /* Reduction routine for statistics output. */ void dgordStatReduceOp ( double * in, double * inout, int * len, MPI_Datatype * datatype) { int i; for (i = 0; i < *len; i ++) { inout[3 * i] = MIN (in[3 * i], inout[3 * i]); inout[3 * i + 1] = MAX (in[3 * i + 1], inout[3 * i + 1]); inout[3 * i + 2] = in[3 * i + 2] + inout[3 * i + 2]; } } scotch-6.0.4.dfsg/src/scotch/gout_c.c0000644002563400244210000007726412473176651022623 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gout_c.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a result viewer. **/ /** This module contains the main function. **/ /** **/ /** DATES : # Version 2.0 : from : 06 oct 1994 **/ /** to 23 dec 1994 **/ /** # Version 3.0 : from : 14 jul 1995 **/ /** to 11 oct 1995 **/ /** # Version 3.1 : from : 27 mar 1996 **/ /** to 03 apr 1996 **/ /** # Version 3.2 : from : 02 dec 1996 **/ /** to 05 jun 1998 **/ /** # Version 3.3 : from : 29 may 1999 **/ /** to : 03 jun 1999 **/ /** # Version 3.4 : from : 03 feb 2000 **/ /** to : 03 feb 2000 **/ /** # Version 4.0 : from : 11 dec 2001 **/ /** to 08 feb 2004 **/ /** # Version 5.0 : from : 25 may 2007 **/ /** to 25 may 2007 **/ /** # Version 5.1 : from : 25 oct 2007 **/ /** to 14 feb 2011 **/ /** # Version 6.0 : from : 16 oct 2010 **/ /** to 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes */ #define GOUT #include "module.h" #include "common.h" #include "scotch.h" #include "gout_c.h" #include "gout_o.h" /* ** The static and global variables */ static int C_fileNum = 0; /* Number of file in arg list */ File C_fileTab[C_FILENBR] = { /* The file array; public */ { "r" }, { "r" }, { "r" }, { "w" } }; static unsigned int C_geoFlag = C_GEOFLAGDEFAULT; /* Geometry flag */ static const char * C_usageList[] = { /* Usage */ "gout [ [ [ []]]] ", " -g : Geometry parameters :", " n : do not read geometry data (matrix display)", " p : permute Y and Z geometry dimensions", " r : rotate geometry by 90 degrees", " -h : Display this help", " -mn : Do not read mapping data", " -Oi[{}] : Open Inventor mesh file :", " c : color output", " g : gray level output", " r : remove cut edges", " v : view cut edges", " -Om[{}] : PostScript matrix file :", " e : EPSF-type output", " f : full-page output", " -Op[{}] : PostScript mesh file :", " c : color output", " g : gray level output", " e : EPSF-type output", " f : full-page output", " s : short clipping (disks excluded)", " l : large clipping (disks included)", " a : avoid displaying disks", " d : display disks", " r : remove cut edges", " v : view cut edges", " X= : maximum x clipping ratio (in [0.0;1.0])", " x= : minimum x clipping ratio", " Y= : maximum y clipping ratio", " y= : minimum y clipping ratio", " -Ot[{}] : Tulip graph file :", " b : b/w output", " c : color output", " a : avoid displaying disks", " d : display disks", " r : remove cut edges", " v : view cut edges", " -V : Print program version and copyright", "", "Default option set is : -Oi{c,v}", NULL }; /*****************************/ /* */ /* This is the main function */ /* */ /*****************************/ int main ( int argc, char * argv[]) { C_Graph grafdat; /* Source graph */ C_Geometry geo; /* Graph geometry */ C_Mapping map; /* Result mapping */ int i, j; errorProg ("gout"); if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_fileNum < C_FILEARGNBR) /* File name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else errorPrint ("main: too many file names given"); } else { /* If found an option name */ switch (argv[i][1]) { case 'G' : /* Geometry parameters */ case 'g' : if ((j = C_geoParse (&argv[i][2])) != 0) errorPrint ("main: error in geometry option string '%d'", j); break; case 'H' : /* Give the usage message */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'M' : /* No-mapping flag */ case 'm' : if (((argv[i][2] != 'N') && (argv[i][2] != 'n')) || (argv[i][3] != '\0')) errorPrint ("main: error in mapping option string '%s'", &argv[i][2]); C_filenamemapinp = "-"; /* Default name to avoid opening */ C_filepntrmapinp = NULL; /* NULL file pointer means no file */ break; case 'O' : /* Output parameters */ case 'o' : if ((j = outDrawParse (&argv[i][2])) != 0) errorPrint ("main: error in output option string (%d)", j); break; case 'V' : fprintf (stderr, "gout, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: Unprocessed option '%s'", argv[i]); } } } fileBlockOpen (C_fileTab, C_FILENBR); /* Open all files */ SCOTCH_graphInit (&grafdat.grafdat); /* Create graph structure */ SCOTCH_graphLoad (&grafdat.grafdat, C_filepntrsrcinp, 0, 3); /* Read source graph */ SCOTCH_graphData (&grafdat.grafdat, &grafdat.baseval, &grafdat.vertnbr, &grafdat.verttab, &grafdat.vendtab, NULL, &grafdat.vlbltab, &grafdat.edgenbr, &grafdat.edgetab, NULL); C_geoInit (&geo, &grafdat); /* Create geometry structure */ if (C_geoFlag & C_GEOFLAGUSE) /* If geometry is wanted */ C_geoLoad (&geo, C_filepntrgeoinp); /* Read graph geometry */ C_mapInit (&map, &grafdat); /* Create mapping structure */ C_mapLoad (&map, C_filepntrmapinp); /* Read result mapping */ outDraw (&grafdat, &geo, &map, C_filepntrdatout); /* Build and write the output */ fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ C_mapExit (&map); /* Free data structures */ C_geoExit (&geo); SCOTCH_graphExit (&grafdat.grafdat); #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } /***********************************/ /* */ /* These routines handle geometry. */ /* */ /***********************************/ /* This routine parses the source graph ** option string. ** It returns: ** - 0 : if string successfully scanned. ** - 1 : if invalid options ** - 2 : if invalid option arguments. ** - 3 : if syntax error in string. */ int C_geoParse ( const char * const string) { const char * cptr; for (cptr = string; ; cptr ++) { switch (*cptr) { case 'N' : /* Do not read geometry data */ case 'n' : C_geoFlag &= ~C_GEOFLAGUSE; break; case 'P' : /* Permute Y and Z */ case 'p' : C_geoFlag |= C_GEOFLAGPERMUT; break; case 'R' : /* If want to rotate */ case 'r' : C_geoFlag |= C_GEOFLAGROTATE; break; case '\0' : return (0); default : return (1); } } } /* This routine creates a geometry with ** respect to a given source graph. ** It returns: ** - VOID : in all cases. */ void C_geoInit ( C_Geometry * const geomptr, const C_Graph * const grafptr) { geomptr->grafptr = grafptr; geomptr->verttab = NULL; } /* This routine deletes a geometry. ** It returns: ** - VOID : in all cases. */ void C_geoExit ( C_Geometry * const geomptr) { if (geomptr->verttab != NULL) /* If there is a geometry array */ memFree (geomptr->verttab); /* Free it */ } /* This routine loads a mapping. ** It returns: ** - 0 : on success. ** - !0 : on error. */ /* This is the comparison function used by the quicksort algorithm, to sort by increasing labels. */ static int C_geoLoad2 ( const C_VertSort * const vert0, const C_VertSort * const vert1) { return ((vert0->labl > vert1->labl) ? 1 : -1); } /** This is the loading routine. **/ int C_geoLoad ( C_Geometry * const geomptr, FILE * const stream) { C_VertSort * vertsorttab; /* Pointer to graph sorting array */ int vertsortflag; /* Flag set if graph data sorted by label */ C_VertSort * geomsorttab; /* Pointer to geometric data sorting array */ int geomsortflag; /* Flag set if geometric data sorted by label */ int geomfiletype; /* Type of geometry file */ SCOTCH_Num geomfilenbr; /* Number of geometric coordinates in file */ SCOTCH_Num geomfileval; /* Value of maximum size for compatibility */ C_GeoVert * geomfiletab; /* Pointer to geometric data read from file */ SCOTCH_Num vertlablval; /* Value of maximum size for compatibility */ SCOTCH_Num i, j; int o; if ((geomptr->verttab == NULL) && /* Allocate geometry if necessary */ ((geomptr->verttab = (C_GeoVert *) memAlloc (geomptr->grafptr->vertnbr * sizeof (C_GeoVert))) == NULL)) { errorPrint ("C_geoLoad: out of memory (1)"); return (1); } if ((fscanf (stream, "%d" SCOTCH_NUMSTRING, /* Read type and number of geometry items */ &geomfiletype, &geomfileval) != 2) || (geomfiletype < 1) || (geomfiletype > 3) || (geomfileval < 1)) { errorPrint ("C_geoLoad: bad input (1)"); return (1); } geomfilenbr = (SCOTCH_Num) geomfileval; if (memAllocGroup ((void **) (void *) &geomfiletab, (size_t) (geomfilenbr * sizeof (C_GeoVert)), &geomsorttab, (size_t) (geomfilenbr * sizeof (C_VertSort)), &vertsorttab, (size_t) (geomptr->grafptr->vertnbr * sizeof (C_VertSort)), NULL) == NULL) { errorPrint ("C_geoLoad: out of memory (2)"); return (1); } o = 0; geomsortflag = 1; /* Assume geometry data sorted */ switch (geomfiletype) { case 1 : /* Load 2D coordinates array */ for (i = 0; (i < geomfilenbr) && (o == 0); i ++) { if (fscanf (stream, SCOTCH_NUMSTRING "%lf", &vertlablval, &geomfiletab[i].x) != 2) o = 1; geomsorttab[i].labl = (SCOTCH_Num) vertlablval; geomfiletab[i].y = /* No Y and Z coordinates */ geomfiletab[i].z = 0.0; geomsorttab[i].num = i; if (C_geoFlag & C_GEOFLAGROTATE) { /* Rotate picture if necessary */ double t; /* Temporary swap variable */ t = geomfiletab[i].y; geomfiletab[i].y = geomfiletab[i].x; geomfiletab[i].x = - t; } if ((i > 0) && /* Check if geometry data sorted */ (geomsorttab[i].labl < geomsorttab[i - 1].labl)) geomsortflag = 0; /* Geometry data not sorted */ } break; case 2 : /* Load 2D coordinates array */ for (i = 0; (i < geomfilenbr) && (o == 0); i ++) { if (fscanf (stream, SCOTCH_NUMSTRING "%lf%lf", &vertlablval, &geomfiletab[i].x, &geomfiletab[i].y) != 3) o = 1; geomsorttab[i].labl = (SCOTCH_Num) vertlablval; geomfiletab[i].z = 0.0; /* No Z coordinate */ geomsorttab[i].num = i; if (C_geoFlag & C_GEOFLAGROTATE) { /* Rotate picture if necessary */ double t; /* Temporary swap variable */ t = geomfiletab[i].y; geomfiletab[i].y = geomfiletab[i].x; geomfiletab[i].x = - t; } if ((i > 0) && /* Check if geometry data sorted */ (geomsorttab[i].labl < geomsorttab[i - 1].labl)) geomsortflag = 0; /* Geometry data are not sorted */ } break; case 3 : /* Load 3D coordinates array */ for (i = 0; (i < geomfilenbr) && (o == 0); i ++) { if (fscanf (stream, SCOTCH_NUMSTRING "%lf%lf%lf", &vertlablval, &geomfiletab[i].x, &geomfiletab[i].y, &geomfiletab[i].z) != 4) o = 1; geomsorttab[i].labl = (SCOTCH_Num) vertlablval; geomsorttab[i].num = i; if (C_geoFlag & C_GEOFLAGPERMUT) { /* Rotate picture if necessary */ double t; /* Temporary swap variable */ t = geomfiletab[i].z; geomfiletab[i].z = geomfiletab[i].y; geomfiletab[i].y = t; } if ((i > 0) && /* Check if geometry data sorted */ (geomsorttab[i].labl < geomsorttab[i - 1].labl)) geomsortflag = 0; /* Geometry data not sorted */ } break; default : errorPrint ("C_geoLoad: invalid geometry type (%d)", geomfiletype); memFree (geomfiletab); /* Free group leader */ return (1); } if (o != 0) { errorPrint ("C_geoLoad: bad input (2)"); memFree (geomfiletab); /* Free group leader */ return (1); } if (geomsortflag != 1) /* If geometry data not sorted */ qsort ((char *) geomsorttab, geomfilenbr, /* Sort sort area by ascending labels */ sizeof (C_VertSort), (int (*) (const void *, const void *)) C_geoLoad2); for (i = 1; i < geomfilenbr; i ++) { /* Check geometric data integrity */ if (geomsorttab[i].labl == geomsorttab[i - 1].labl) { errorPrint ("C_geoLoad: duplicate vertex label"); memFree (geomfiletab); /* Free group leader */ return (1); } } if (geomptr->grafptr->vlbltab != NULL) { /* If graph has vertex labels */ vertsortflag = 1; /* Assume graph data sorted */ for (i = 0; i < geomptr->grafptr->vertnbr; i ++) { vertsorttab[i].labl = geomptr->grafptr->vlbltab[i]; vertsorttab[i].num = i; if ((i > 0) && /* Check if graph data sorted */ (vertsorttab[i].labl < vertsorttab[i - 1].labl)) vertsortflag = 0; /* Graph data not sorted */ } if (vertsortflag != 1) /* If graph data not sorted */ qsort ((char *) vertsorttab, geomptr->grafptr->vertnbr, /* Sort sort area by ascending labels */ sizeof (C_VertSort), (int (*) (const void *, const void *)) C_geoLoad2); } else { /* Graph does not have vertex labels */ for (i = 0; i < geomptr->grafptr->vertnbr; i ++) { vertsorttab[i].labl = i + geomsorttab[0].labl; /* Use first index as base value */ vertsorttab[i].num = i; } } for (i = 0, j = 0; i < geomptr->grafptr->vertnbr; i ++) { /* For all vertices in graph */ while ((j < geomfilenbr) && (geomsorttab[j].labl < vertsorttab[i].labl)) j ++; /* Search geometry vertex with same label */ if ((j >= geomfilenbr) || (geomsorttab[j].labl > vertsorttab[i].labl)) { /* If label does not exist */ errorPrint ("C_geoLoad: vertex geometry data not found for label '" SCOTCH_NUMSTRING "'", vertsorttab[i].labl); memFree (geomfiletab); /* Free group leader */ return (1); } geomptr->verttab[vertsorttab[i].num] = geomfiletab[geomsorttab[j ++].num]; } memFree (geomfiletab); /* Free group leader */ return (0); } /***********************************/ /* */ /* These routines handle mappings. */ /* */ /***********************************/ /* This routine creates a mapping with ** respect to a given source graph. ** It returns: ** - VOID : in all cases. */ void C_mapInit ( C_Mapping * const mapptr, const C_Graph * const grafptr) { mapptr->grafptr = grafptr; mapptr->labltab = NULL; } /* This routine deletes a mapping. ** It returns: ** - VOID : in all cases. */ void C_mapExit ( C_Mapping * const mapptr) { if (mapptr->labltab != NULL) /* If there is a domain array */ memFree (mapptr->labltab); /* Free it */ } /* This routine loads a mapping. ** It returns: ** - 0 : on success. ** - !0 : on error. */ int C_mapLoad ( C_Mapping * const mapptr, FILE * const stream) { C_VertSort * vertsorttab; /* Pointer to graph sorting array */ int vertsortflag; /* Flag set if graph data sorted by label */ C_VertSort * mapsorttab; /* Pointer to mapping data sorting array */ int mapsortflag; /* Flag set if mapping data sorted by label */ SCOTCH_Num mapsortval; /* Value of maximum size for compatibility */ SCOTCH_Num mapfileval; /* Value of maximum size for compatibility */ SCOTCH_Num mapfilenbr; /* Number of mapping pairs in file */ SCOTCH_Num * mapfiletab; /* Pointer to mapping data read from file */ SCOTCH_Num i, j; if ((mapptr->labltab == NULL) && /* Allocate array if necessary */ ((mapptr->labltab = (SCOTCH_Num *) memAlloc (mapptr->grafptr->vertnbr * sizeof (SCOTCH_Num))) == NULL)) { errorPrint ("C_mapLoad: out of memory (1)"); return (1); } memset (mapptr->labltab, ~0, mapptr->grafptr->vertnbr * sizeof (SCOTCH_Num)); /* Pre-initialize mapping */ if (stream == NULL) /* If stream is invalid */ return (0); if ((fscanf (stream, SCOTCH_NUMSTRING, /* Read number of mapping pairs */ &mapfileval) != 1) || (mapfileval < 1)) { errorPrint ("C_mapLoad: bad input (1)"); return (1); } mapfilenbr = (SCOTCH_Num) mapfileval; if (memAllocGroup ((void **) (void *) &mapfiletab, (size_t) (mapfilenbr * sizeof (SCOTCH_Num)), &mapsorttab, (size_t) (mapfilenbr * sizeof (C_VertSort)), &vertsorttab, (size_t) (mapptr->grafptr->vertnbr * sizeof (C_VertSort)), NULL) == NULL) { errorPrint ("C_mapLoad: out of memory (2)"); return (1); } mapsortflag = 1; /* Assume mapping data sorted */ for (i = 0; i < mapfilenbr; i ++) { if (fscanf (stream, SCOTCH_NUMSTRING SCOTCH_NUMSTRING, &mapsortval, &mapfileval) != 2) { errorPrint ("C_mapLoad: bad input (2)"); memFree (mapfiletab); /* Free group leader */ return (1); } mapsorttab[i].labl = mapsortval; mapsorttab[i].num = i; mapfiletab[i] = mapfileval; if ((i > 0) && /* Check if mapping data sorted */ (mapsorttab[i].labl < mapsorttab[i - 1].labl)) mapsortflag = 0; /* Mapping data not sorted */ } if (mapsortflag != 1) /* If mapping data not sorted */ qsort ((char *) mapsorttab, mapfilenbr, /* Sort sort area by ascending labels */ sizeof (C_VertSort), (int (*) (const void *, const void *)) C_geoLoad2); for (i = 1; i < mapfilenbr; i ++) { /* Check mapping data integrity */ if (mapsorttab[i].labl == mapsorttab[i - 1].labl) { errorPrint ("C_mapLoad: duplicate vertex label"); memFree (mapfiletab); /* Free group leader */ return (1); } } if (mapptr->grafptr->vlbltab != NULL) { /* If graph has vertex labels */ vertsortflag = 1; /* Assume graph data sorted */ for (i = 0; i < mapptr->grafptr->vertnbr; i ++) { vertsorttab[i].labl = mapptr->grafptr->vlbltab[i]; vertsorttab[i].num = i; if ((i > 0) && /* Check if graph data sorted */ (vertsorttab[i].labl < vertsorttab[i - 1].labl)) vertsortflag = 0; /* Graph data not sorted */ } if (vertsortflag != 1) /* If graph data not sorted */ qsort ((char *) vertsorttab, mapptr->grafptr->vertnbr, /* Sort sort area by ascending labels */ sizeof (C_VertSort), (int (*) (const void *, const void *)) C_geoLoad2); } else { /* Graph does not have vertex labels */ for (i = 0; i < mapptr->grafptr->vertnbr; i ++) { vertsorttab[i].labl = i + mapptr->grafptr->baseval; vertsorttab[i].num = i; } } for (i = 0, j = 0; i < mapptr->grafptr->vertnbr; i ++) { /* For all vertices in graph */ while ((j < mapfilenbr) && (mapsorttab[j].labl < vertsorttab[i].labl)) j ++; /* Search mapping vertex with same label */ if ((j >= mapfilenbr) || (mapsorttab[j].labl > vertsorttab[i].labl)) /* If label does not exist */ continue; /* This vertex has no related mapping data */ mapptr->labltab[vertsorttab[i].num] = mapfiletab[mapsorttab[j ++].num]; } memFree (mapfiletab); /* Free group leader */ return (0); } /**************************************/ /* */ /* The option string parsing routine. */ /* */ /**************************************/ /* This routine parses an option string. ** It returns: ** - 0 : if string successfully scanned. ** - 1 : if invalid code name. ** - 2 : if invalid arguments for the code. ** - 3 : if syntax error in string. */ int C_parse ( const C_ParseCode * const codeptr, /* Pointer to the code array */ const C_ParseArg * const argptr, /* Pointer to the code argument array */ int * const codeval, /* Pointer to the code value to set */ char * const string) /* Pointer to the string to parse */ { int code; /* Code found */ int codelen; /* Code name length */ char argbuf[128]; /* Buffer for argument scanning */ int arglen; /* Length of the current argument */ char * argbeg; /* Pointer to beginning of argument */ char * argend; /* Pointer to end of argument */ char * argequ; /* Position of the '=' character */ int i, j; code = codelen = 0; /* No code recognized yet */ for (i = 0; codeptr[i].name != NULL; i ++) { /* For all the codes */ if ((strncasecmp (string, /* Find the longest matching code name */ codeptr[i].name, j = strlen (codeptr[i].name)) == 0) && (j > codelen)) { code = codeptr[i].code; codelen = j; } } if (codelen == 0) /* If no code recognized */ return (1); /* Return the error value */ *codeval = code; /* Set the code value */ argbeg = string + codelen; /* Point to the end of the code name */ if (*argbeg == '{') { /* If there are arguments */ argbeg ++; /* Point to argument beginning */ do { /* For all arguments */ argend = strpbrk (argbeg, ",}\0"); /* Search for the argument end */ if (*argend == '\0') /* If there is no end delimiter */ return (3); /* Return the syntax error value */ arglen = ((argend - argbeg) < 127) /* Get argument bounded length */ ? (argend - argbeg) : 127; strncpy (argbuf, argbeg, arglen); /* Copy the argument to the buffer */ argbuf[arglen] = '\0'; /* Mark the end of the argument */ argequ = strpbrk (argbuf, "="); /* Search for the '=' character */ if (argequ != NULL) /* If it exists */ *argequ++ = '\0'; /* Turn it into a separating null */ for (i = 0, j = -1; argptr[i].name != NULL; i ++) { /* Scan all the possible arguments */ if ((argptr[i].code == code) && /* If the proper name is found */ (strcmp (argbuf, argptr[i].name) == 0)) { j = i; /* Record the position */ break; /* Exit the loop */ } } if (j == -1) /* If invalid argument */ return (2); /* Return the proper value */ if (argptr[j].format != NULL) { /* If there is a value to read */ if (argequ == NULL) /* If none has been given however */ return (2); /* Return the error value */ if (sscanf (argequ, /* Try to read the argument value */ argptr[j].format, argptr[j].ptr) != 1) return (2); /* Return if error */ if (argptr[j].func != NULL) /* If there is a control function */ if (argptr[j].func (argptr[j].ptr) != 0) /* If the function fails */ return (2); /* Return the error value */ } else { /* If no value needed */ if (argequ != NULL) /* If there is one however */ return (2); /* Return the error code */ *((char *) argptr[j].ptr) = argbuf[0]; /* Copy the first argument char */ } argbeg = argend + 1; /* Skip the processed argument */ } while (*argend != '}'); /* Loop as long as there are arguments */ } return ((*argbeg == '\0') ? 0 : 3); /* Check if no extraneous characters */ } scotch-6.0.4.dfsg/src/scotch/acpl.h0000644002563400244210000000721512473176651022254 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : acpl.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the target archi- **/ /** tecture compilation function defini- **/ /** tions. **/ /** **/ /** DATES : # Version 2.0 : from : 12 nov 1994 **/ /** to : 12 nov 1994 **/ /** # Version 3.0 : from : 06 jul 1995 **/ /** to : 06 jul 1995 **/ /** # Version 3.2 : from : 24 sep 1996 **/ /** to : 01 jun 1997 **/ /** # Version 3.3 : from : 02 oct 1998 **/ /** to : 02 oct 1998 **/ /** # Version 6.0 : from : 12 nov 2014 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ File name aliases. +*/ #define C_FILENBR 2 /* Number of files in list */ #define C_FILEARGNBR 2 /* Number of files which can be arguments */ #define C_filenametgtinp fileBlockName (C_fileTab, 0) /* Target architecture input file name */ #define C_filenametgtout fileBlockName (C_fileTab, 1) /* Target architecture output file name */ #define C_filepntrtgtinp fileBlockFile (C_fileTab, 0) /* Target architecture input file */ #define C_filepntrtgtout fileBlockFile (C_fileTab, 1) /* Target architecture output file */ scotch-6.0.4.dfsg/src/scotch/dgscat.h0000644002563400244210000000722112473176651022577 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgscat.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a parallel sparse matrix **/ /** ordering software. **/ /** This module contains the data declara- **/ /** tions for the graph file scattering **/ /** program. **/ /** **/ /** DATES : # Version 5.0 : from : 21 may 2007 **/ /** to : 21 may 2007 **/ /** # Version 6.0 : from : 10 nov 2014 **/ /** to : 10 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ File name aliases. +*/ #define C_FILENBR 2 /* Number of files in list */ #define C_FILEARGNBR 2 /* Number of files which can be arguments */ #define C_filenamesrcinp fileBlockName (C_fileTab, 0) /* Source graph input file name */ #define C_filenamesrcout fileBlockName (C_fileTab, 1) /* Source graph output file name */ #define C_filepntrsrcinp fileBlockFile (C_fileTab, 0) /* Source graph input file */ #define C_filepntrsrcout fileBlockFile (C_fileTab, 1) /* Source graph output file */ /*+ Process flags. +*/ #define C_FLAGNONE 0x0000 /* No flags */ #define C_FLAGCHECK 0x0001 /* Check distributed source graph */ #define C_FLAGDEBUG 0x0002 /* Enable easy debugger attachment */ scotch-6.0.4.dfsg/src/scotch/dggath.c0000644002563400244210000002103312473176651022560 0ustar trophimeutilisateurs du domaine/* Copyright 2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dggath.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This program gathers the fragments of a **/ /** distributed graph and saves it as a **/ /** centralized source graph. **/ /** This module contains the main function. **/ /** **/ /** DATES : # Version 5.1 : from : 26 oct 2008 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DGGATH #define SCOTCH_PTSCOTCH #include "module.h" #include "common.h" #include "ptscotch.h" #include "dggath.h" /* ** The static and global definitions. */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[C_FILENBR] = { /* File array */ { "r" }, { "w" } }; static const char * C_usageList[] = { "dggath [ []] ", " -c : Check the input graph after loading", " -h : Display this help", " -r : Set root process for centralized files (default is 0)", " -V : Print program version and copyright", NULL }; /*********************/ /* */ /* The main routine. */ /* */ /*********************/ int main ( int argc, char * argv[]) { SCOTCH_Graph * cgrfptr; SCOTCH_Graph cgrfdat; SCOTCH_Dgraph dgrfdat; int procglbnbr; int proclocnum; int protglbnum; /* Root process */ int flagval; int i; int reduloctab[2]; int reduglbtab[2]; #ifdef SCOTCH_PTHREAD int thrdlvlreqval; int thrdlvlproval; #endif /* SCOTCH_PTHREAD */ errorProg ("dggath"); #ifdef SCOTCH_PTHREAD thrdlvlreqval = MPI_THREAD_MULTIPLE; if (MPI_Init_thread (&argc, &argv, thrdlvlreqval, &thrdlvlproval) != MPI_SUCCESS) errorPrint ("main: Cannot initialize (1)"); if (thrdlvlreqval > thrdlvlproval) errorPrint ("main: MPI implementation is not thread-safe: recompile without SCOTCH_PTHREAD"); #else /* SCOTCH_PTHREAD */ if (MPI_Init (&argc, &argv) != MPI_SUCCESS) errorPrint ("main: Cannot initialize (2)"); #endif /* SCOTCH_PTHREAD */ MPI_Comm_size (MPI_COMM_WORLD, &procglbnbr); /* Get communicator data */ MPI_Comm_rank (MPI_COMM_WORLD, &proclocnum); protglbnum = 0; /* Assume root process is process 0 */ if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } flagval = C_FLAGNONE; fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_fileNum < C_FILEARGNBR) /* File name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else errorPrint ("main: too many file names given"); } else { /* If found an option name */ switch (argv[i][1]) { case 'C' : case 'c' : flagval |= C_FLAGCHECK; break; #ifdef SCOTCH_DEBUG_ALL case 'D' : case 'd' : flagval |= C_FLAGDEBUG; break; #endif /* SCOTCH_DEBUG_ALL */ case 'H' : /* Give the usage message */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'R' : /* Root process (if necessary) */ case 'r' : protglbnum = atoi (&argv[i][2]); if ((protglbnum < 0) || (protglbnum >= procglbnbr) || ((protglbnum == 0) && (argv[i][2] != '0'))) { errorPrint ("main: invalid root process number"); } break; case 'V' : case 'v' : fprintf (stderr, "dggath, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: unprocessed option '%s'", argv[i]); } } } #ifdef SCOTCH_DEBUG_ALL if ((flagval & C_FLAGDEBUG) != 0) { fprintf (stderr, "Proc %4d of %d, pid %d\n", proclocnum, procglbnbr, getpid ()); if (proclocnum == protglbnum) { /* Synchronize on keybord input */ char c; printf ("Waiting for key press...\n"); scanf ("%c", &c); } MPI_Barrier (MPI_COMM_WORLD); } #endif /* SCOTCH_DEBUG_ALL */ fileBlockOpenDist (C_fileTab, C_FILENBR, procglbnbr, proclocnum, protglbnum); /* Open all files */ if (C_filepntrsrcout == NULL) { cgrfptr = NULL; reduloctab[0] = reduloctab[1] = 0; } else { cgrfptr = &cgrfdat; reduloctab[0] = 1; reduloctab[1] = proclocnum; } if (MPI_Allreduce (reduloctab, reduglbtab, 2, MPI_INT, MPI_SUM, MPI_COMM_WORLD) != MPI_SUCCESS) errorPrint ("main: communication error"); if (reduglbtab[0] != 1) errorPrint ("main: should have only one root"); if (reduglbtab[1] != protglbnum) errorPrint ("main: root process mismatch"); SCOTCH_dgraphInit (&dgrfdat, MPI_COMM_WORLD); SCOTCH_dgraphLoad (&dgrfdat, C_filepntrsrcinp, -1, 0); if ((flagval & C_FLAGCHECK) != 0) SCOTCH_dgraphCheck (&dgrfdat); SCOTCH_graphInit (&cgrfdat); SCOTCH_dgraphGather (&dgrfdat, cgrfptr); if (cgrfptr != NULL) SCOTCH_graphSave (cgrfptr, C_filepntrsrcout); fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ SCOTCH_graphExit (&cgrfdat); SCOTCH_dgraphExit (&dgrfdat); MPI_Finalize (); #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } scotch-6.0.4.dfsg/src/scotch/gtst.c0000644002563400244210000002005012473176651022301 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gtst.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This program gives statistics on source **/ /** graphs. **/ /** **/ /** DATES : # Version 2.0 : from : 31 oct 1994 **/ /** to 03 nov 1994 **/ /** # Version 3.0 : from : 15 sep 1995 **/ /** to 19 sep 1995 **/ /** # Version 3.2 : from : 03 jun 1997 **/ /** to : 25 may 1998 **/ /** # Version 3.3 : from : 19 oct 1998 **/ /** to : 19 oct 1998 **/ /** # Version 3.4 : from : 10 oct 1999 **/ /** to 12 oct 1999 **/ /** # Version 4.0 : from : 10 sep 2003 **/ /** to : 10 sep 2003 **/ /** # Version 5.0 : from : 23 dec 2007 **/ /** to : 16 mar 2008 **/ /** # Version 5.1 : from : 01 jul 2010 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GTST #include "module.h" #include "common.h" #include "scotch.h" #include "gtst.h" /* ** The static definitions. */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[C_FILENBR] = { /* The file array */ { "r" }, { "w" } }; static const char * C_usageList[] = { "gtst [ []] ", " -h : Display this help", " -V : Print program version and copyright", NULL }; /******************************/ /* */ /* This is the main function. */ /* */ /******************************/ int main ( int argc, char * argv[]) { SCOTCH_Graph grafdat; /* Source graph */ SCOTCH_Num vertnbr; SCOTCH_Num velomin; SCOTCH_Num velomax; SCOTCH_Num velosum; double veloavg; double velodlt; SCOTCH_Num degrmin; SCOTCH_Num degrmax; double degravg; double degrdlt; SCOTCH_Num edgenbr; SCOTCH_Num edlomin; SCOTCH_Num edlomax; SCOTCH_Num edlosum; double edloavg; double edlodlt; int i; errorProg ("gtst"); if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); exit (0); } fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_fileNum < C_FILEARGNBR) /* File name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else { errorPrint ("main: too many file names given"); exit (1); } } else { /* If found an option name */ switch (argv[i][1]) { case 'H' : /* Give the usage message */ case 'h' : usagePrint (stdout, C_usageList); exit (0); case 'V' : fprintf (stderr, "gtst, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: unprocessed option '%s'", argv[i]); exit (1); } } } fileBlockOpen (C_fileTab, C_FILENBR); /* Open all files */ SCOTCH_graphInit (&grafdat); SCOTCH_graphLoad (&grafdat, C_filepntrsrcinp, -1, 0); SCOTCH_graphCheck (&grafdat); SCOTCH_graphSize (&grafdat, &vertnbr, &edgenbr); SCOTCH_graphStat (&grafdat, &velomin, &velomax, &velosum, &veloavg, &velodlt, °rmin, °rmax, °ravg, °rdlt, &edlomin, &edlomax, &edlosum, &edloavg, &edlodlt); if (C_filepntrdatout != NULL) { fprintf (C_filepntrdatout, "S\tVertex\tnbr=" SCOTCH_NUMSTRING "\n", (SCOTCH_Num) vertnbr); fprintf (C_filepntrdatout, "S\tVertex load\tmin=" SCOTCH_NUMSTRING "\tmax=" SCOTCH_NUMSTRING "\tsum=" SCOTCH_NUMSTRING "\tavg=%g\tdlt=%g\n", (SCOTCH_Num) velomin, (SCOTCH_Num) velomax, (SCOTCH_Num) velosum, veloavg, velodlt); fprintf (C_filepntrdatout, "S\tVertex degree\tmin=" SCOTCH_NUMSTRING "\tmax=" SCOTCH_NUMSTRING "\tsum=" SCOTCH_NUMSTRING "\tavg=%g\tdlt=%g\n", (SCOTCH_Num) degrmin, (SCOTCH_Num) degrmax, (SCOTCH_Num) edgenbr, degravg, degrdlt); fprintf (C_filepntrdatout, "S\tEdge\tnbr=" SCOTCH_NUMSTRING "\n", (SCOTCH_Num) (edgenbr / 2)); fprintf (C_filepntrdatout, "S\tEdge load\tmin=" SCOTCH_NUMSTRING "\tmax=" SCOTCH_NUMSTRING "\tsum=" SCOTCH_NUMSTRING "\tavg=%g\tdlt=%g\n", (SCOTCH_Num) edlomin, (SCOTCH_Num) edlomax, (SCOTCH_Num) edlosum, edloavg, edlodlt); } SCOTCH_graphExit (&grafdat); fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } scotch-6.0.4.dfsg/src/scotch/gbase.c0000644002563400244210000001460612473176651022413 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gbase.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This program changes the base of source **/ /** graphs. **/ /** **/ /** DATES : # Version 4.0 : from : 12 may 2006 **/ /** to : 12 may 2006 **/ /** # Version 5.0 : from : 23 dec 2007 **/ /** to : 16 mar 2008 **/ /** # Version 5.1 : from : 01 jul 2010 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GBASE #include "module.h" #include "common.h" #include "scotch.h" #include "gbase.h" /* ** The static definitions. */ static int C_paraNum = 0; /* Number of parameters */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[C_FILENBR] = { /* The file array */ { "r" }, { "w" } }; static const char * C_usageList[] = { "gbase [ []] ", " -h : Display this help", " -V : Print program version and copyright", NULL }; /******************************/ /* */ /* This is the main function. */ /* */ /******************************/ int main ( int argc, char * argv[]) { SCOTCH_Graph grafdat; /* Source graph */ int baseval; int i; errorProg ("gbase"); if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); exit (0); } fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_paraNum < 1) { /* If number of parameters not reached */ C_paraNum ++; /* One more parameter */ baseval = atoi (argv[i]); /* Get the base value */ if ((baseval < 0) || (baseval > 1)) { errorPrint ("main: invalid base value '%s'", argv[i]); return (1); } continue; /* Process the other parameters */ } if (C_fileNum < C_FILEARGNBR) /* A file name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else { errorPrint ("main: too many file names given"); exit (1); } } else { /* If found an option name */ switch (argv[i][1]) { case 'H' : /* Give the usage message */ case 'h' : usagePrint (stdout, C_usageList); exit (0); case 'V' : fprintf (stderr, "gbase, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: unprocessed option '%s'", argv[i]); exit (1); } } } fileBlockOpen (C_fileTab, C_FILENBR); /* Open all files */ SCOTCH_graphInit (&grafdat); SCOTCH_graphLoad (&grafdat, C_filepntrsrcinp, (SCOTCH_Num) baseval, 0); SCOTCH_graphSave (&grafdat, C_filepntrsrcout); fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ SCOTCH_graphExit (&grafdat); #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } scotch-6.0.4.dfsg/src/scotch/dggath.h0000644002563400244210000000701612473176651022572 0ustar trophimeutilisateurs du domaine/* Copyright 2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dggath.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module contains the data declara- **/ /** tions for the distributed graph file **/ /** gathering program. **/ /** **/ /** DATES : # Version 5.1 : from : 26 oct 2008 **/ /** to : 26 oct 2008 **/ /** # Version 6.0 : from : 10 nov 2014 **/ /** to : 10 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ File name aliases. +*/ #define C_FILENBR 2 /* Number of files in list */ #define C_FILEARGNBR 2 /* Number of files which can be arguments */ #define C_filenamesrcinp fileBlockName (C_fileTab, 0) /* Source graph input file name */ #define C_filenamesrcout fileBlockName (C_fileTab, 1) /* Source graph output file name */ #define C_filepntrsrcinp fileBlockFile (C_fileTab, 0) /* Source graph input file */ #define C_filepntrsrcout fileBlockFile (C_fileTab, 1) /* Source graph output file */ /*+ Process flags. +*/ #define C_FLAGNONE 0x0000 /* No flags */ #define C_FLAGCHECK 0x0001 /* Check distributed source graph */ #define C_FLAGDEBUG 0x0002 /* Enable easy debugger attachment */ scotch-6.0.4.dfsg/src/scotch/amk_m2.h0000644002563400244210000001117012473176651022476 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : amk_m2.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Creates the target architecture file **/ /** for bidimensional mesh graphs. **/ /** Here are the data declaration for the **/ /** target machine architecture functions. **/ /** **/ /** DATES : # Version 1.3 : from : 21 apr 1994 **/ /** to : 22 apr 1994 **/ /** # Version 2.0 : from : 12 jul 1994 **/ /** to : 13 nov 1994 **/ /** # Version 2.0 : from : 18 sep 1995 **/ /** to : 19 sep 1995 **/ /** # Version 3.1 : from : 30 may 1996 **/ /** to : 30 may 1996 **/ /** # Version 3.2 : from : 31 may 1997 **/ /** to : 02 jun 1997 **/ /** # Version 4.0 : from : 09 feb 2004 **/ /** to : 09 feb 2004 **/ /** # Version 6.0 : from : 12 nov 2014 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /** File name aliases. **/ #define C_FILENBR 1 /* Number of files in list */ #define C_FILEARGNBR 1 /* Number of files which can be arguments */ #define C_filenamearcout fileBlockName (C_fileTab, 0) /* Architecture output file name */ #define C_filepntrarcout fileBlockFile (C_fileTab, 0) /* Architecture output file */ /* ** The type and structure definitions. */ /** The method type. **/ typedef enum C_MethType_ { C_METHNESTED, /*+ Nested decomposition +*/ C_METHONEWAY /*+ One-way decomposition +*/ } C_MethType; /* ** The function prototypes. */ void C_termBipart (ArchMesh2 *, ArchMesh2Dom *, unsigned int, unsigned int *, unsigned int *, int (*) ()); int C_methBipartOne (const ArchMesh2 * const, const ArchMesh2Dom * const, ArchMesh2Dom * restrict const, ArchMesh2Dom * restrict const); /* ** The macro definitions. */ #ifndef abs #define abs(a) (((a) >= 0) ? (a) : -(a)) #endif /* abs */ #define C_termDist(x0,y0,x1,y1) ((unsigned int) (abs ((int) (x0) - (int) (x1)) + \ abs ((int) (y0) - (int) (y1)))) scotch-6.0.4.dfsg/src/scotch/gord.c0000644002563400244210000002742012473176651022263 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gord.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a sparse matrix graph ordering **/ /** software. **/ /** This module contains the main function. **/ /** **/ /** DATES : # Version 3.2 : from : 24 aug 1996 **/ /** to : 21 aug 1998 **/ /** # Version 3.3 : from : 07 oct 1998 **/ /** to : 31 may 1999 **/ /** # Version 3.4 : from : 07 oct 1998 **/ /** to : 03 feb 2000 **/ /** # Version 4.0 : from : 02 feb 2002 **/ /** to : 08 jan 2006 **/ /** # Version 5.0 : from : 26 jan 2007 **/ /** to : 16 mar 2008 **/ /** # Version 5.1 : from : 01 jul 2010 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GORD #include "module.h" #include "common.h" #include "scotch.h" #include "gord.h" /* ** The static and global definitions. */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[C_FILENBR] = { /* File array */ { "r" }, { "w" }, { "w" }, { "w" }, { "w" } }; static const char * C_usageList[] = { "gord [ [ []]] ", " -c : Choose default ordering strategy according to one or several of :", " b : enforce load balance as much as possible", " q : privilege quality over speed (default)", " s : privilege speed over quality", " t : enforce safety", " -h : Display this help", " -m : Save column block mapping data to ", " -o : Set ordering strategy (see user's manual)", " -t : Save partitioning tree data to ", " -V : Print program version and copyright", " -v : Set verbose mode to :", " s : strategy information", " t : timing information", "", "See default strategy with option '-vs'", NULL }; /******************************/ /* */ /* This is the main function. */ /* */ /******************************/ int main ( int argc, char * argv[]) { SCOTCH_Num vertnbr; /* Number of vertices */ SCOTCH_Graph grafdat; /* Source graph */ SCOTCH_Ordering ordedat; /* Graph ordering */ SCOTCH_Num * permtab; /* Permutation array */ SCOTCH_Strat stradat; /* Ordering strategy */ SCOTCH_Num straval; char * straptr; int flagval; Clock runtime[2]; /* Timing variables */ int i, j; errorProg ("gord"); if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } flagval = C_FLAGNONE; /* Default behavior */ straval = 0; /* No strategy flags */ straptr = NULL; SCOTCH_stratInit (&stradat); fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_fileNum < C_FILEARGNBR) /* File name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else errorPrint ("main: too many file names given"); } else { /* If found an option name */ switch (argv[i][1]) { case 'C' : case 'c' : /* Strategy selection parameters */ for (j = 2; argv[i][j] != '\0'; j ++) { switch (argv[i][j]) { case 'B' : case 'b' : straval |= SCOTCH_STRATBALANCE; break; case 'Q' : case 'q' : straval |= SCOTCH_STRATQUALITY; break; case 'S' : case 's' : straval |= SCOTCH_STRATSPEED; break; case 'T' : case 't' : straval |= SCOTCH_STRATSAFETY; break; default : errorPrint ("main: invalid strategy selection option '%c'", argv[i][j]); } } break; case 'H' : /* Give the usage message */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'M' : /* Output separator mapping */ case 'm' : flagval |= C_FLAGMAPOUT; if (argv[i][2] != '\0') C_filenamemapout = &argv[i][2]; break; case 'O' : /* Ordering strategy */ case 'o' : straptr = &argv[i][2]; SCOTCH_stratExit (&stradat); SCOTCH_stratInit (&stradat); SCOTCH_stratGraphOrder (&stradat, straptr); break; case 'T' : /* Output separator tree */ case 't' : flagval |= C_FLAGTREOUT; if (argv[i][2] != '\0') C_filenametreout = &argv[i][2]; break; case 'V' : fprintf (stderr, "gord, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); case 'v' : /* Output control info */ for (j = 2; argv[i][j] != '\0'; j ++) { switch (argv[i][j]) { case 'S' : case 's' : flagval |= C_FLAGVERBSTR; break; case 'T' : case 't' : flagval |= C_FLAGVERBTIM; break; default : errorPrint ("main: unprocessed parameter '%c' in '%s'", argv[i][j], argv[i]); } } break; default : errorPrint ("main: unprocessed option '%s'", argv[i]); } } } fileBlockOpen (C_fileTab, C_FILENBR); /* Open all files */ clockInit (&runtime[0]); clockStart (&runtime[0]); SCOTCH_graphInit (&grafdat); /* Create graph structure */ SCOTCH_graphLoad (&grafdat, C_filepntrsrcinp, -1, 2); /* Read source graph */ SCOTCH_graphSize (&grafdat, &vertnbr, NULL); /* Get graph characteristics */ if (straval != 0) { if (straptr != NULL) errorPrint ("main: options '-c' and '-o' are exclusive"); SCOTCH_stratGraphOrderBuild (&stradat, straval, 0, 0.2); } clockStop (&runtime[0]); /* Get input time */ clockInit (&runtime[1]); clockStart (&runtime[1]); if ((permtab = (SCOTCH_Num *) memAlloc (vertnbr * sizeof (SCOTCH_Num))) == NULL) { errorPrint ("main: out of memory"); return (1); } SCOTCH_graphOrderInit (&grafdat, &ordedat, permtab, NULL, NULL, NULL, NULL); /* Create ordering */ SCOTCH_graphOrderCompute (&grafdat, &ordedat, &stradat); /* Perform ordering */ clockStop (&runtime[1]); /* Get ordering time */ #ifdef SCOTCH_DEBUG_ALL if (SCOTCH_graphOrderCheck (&grafdat, &ordedat) != 0) return (1); #endif /* SCOTCH_DEBUG_ALL */ clockStart (&runtime[0]); SCOTCH_graphOrderSave (&grafdat, &ordedat, C_filepntrordout); /* Write ordering */ if (flagval & C_FLAGMAPOUT) /* If mapping wanted */ SCOTCH_graphOrderSaveMap (&grafdat, &ordedat, C_filepntrmapout); /* Write mapping */ if (flagval & C_FLAGTREOUT) /* If separator tree wanted */ SCOTCH_graphOrderSaveTree (&grafdat, &ordedat, C_filepntrtreout); /* Write tree */ clockStop (&runtime[0]); /* Get output time */ if (flagval & C_FLAGVERBSTR) { fprintf (C_filepntrlogout, "S\tStrat="); SCOTCH_stratSave (&stradat, C_filepntrlogout); putc ('\n', C_filepntrlogout); } if (flagval & C_FLAGVERBTIM) { fprintf (C_filepntrlogout, "T\tOrder\t\t%g\nT\tI/O\t\t%g\nT\tTotal\t\t%g\n", (double) clockVal (&runtime[1]), (double) clockVal (&runtime[0]), (double) clockVal (&runtime[0]) + (double) clockVal (&runtime[1])); } fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ SCOTCH_graphOrderExit (&grafdat, &ordedat); SCOTCH_stratExit (&stradat); SCOTCH_graphExit (&grafdat); memFree (permtab); #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } scotch-6.0.4.dfsg/src/scotch/CMakeLists.txt0000644002563400244210000001602512474553475023727 0ustar trophimeutilisateurs du domaine## Copyright 2014,2015 IPB, Universite de Bordeaux, INRIA & CNRS ## ## This file is part of the Scotch software package for static mapping, ## graph partitioning and sparse matrix ordering. ## ## This software is governed by the CeCILL-C license under French law ## and abiding by the rules of distribution of free software. You can ## use, modify and/or redistribute the software under the terms of the ## CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ## URL: "http://www.cecill.info". ## ## As a counterpart to the access to the source code and rights to copy, ## modify and redistribute granted by the license, users are provided ## only with a limited warranty and the software's author, the holder of ## the economic rights, and the successive licensors have only limited ## liability. ## ## In this respect, the user's attention is drawn to the risks associated ## with loading, using, modifying and/or developing or reproducing the ## software by the user in light of its specific status of free software, ## that may mean that it is complicated to manipulate, and that also ## therefore means that it is reserved for developers and experienced ## professionals having in-depth computer knowledge. Users are therefore ## encouraged to load and test the software's suitability as regards ## their requirements in conditions enabling the security of their ## systems and/or data to be ensured and, more generally, to use and ## operate it in the same conditions as regards security. ## ## The fact that you are presently reading this means that you have had ## knowledge of the CeCILL-C license and that you accept its terms. ## ############################################################## ### ### ### AUTHOR : Cedric LACHAT ### ### ### ### FUNCTION : Secondary configuration file for CMake ### ### ### ### DATES : # Version 6.0 : from : 01 sep 2014 ### ### to 01 mar 2015 ### ### ### ############################################################## include_directories(include ${SCOTCH_BINARY_DIR}/src/libscotch) include_directories(${SCOTCH_SOURCE_DIR}/src/libscotch) ########### # Execs # ########### # Search source files with components set (SCOTCH_EXECS acpl amk_ccc amk_fft2 amk_grf amk_hy amk_m2 amk_p2 atst gbase gcv gmap gmk_hy gmk_m2 gmk_m3 gmk_msh gmk_ub2 gmtst gord gotst gout gpart gscat gtst mcv mmk_m2 mmk_m3 mord mtst ) if (PTSCOTCH) set (PTSCOTCH_EXECS dggath dgmap dgord dgpart dgscat dgtst ) endif (PTSCOTCH) #################### # Parallel execs # #################### # Combine parallel source file with execution file foreach(EXEC_NAME ${PTSCOTCH_EXECS}) if (NOT ${EXEC_NAME} STREQUAL "dgpart") add_executable(${EXEC_NAME} ${EXEC_NAME}.c) else () add_executable(${EXEC_NAME} dgmap.c) set_target_properties(${EXEC_NAME} PROPERTIES COMPILE_FLAGS "-DSCOTCH_COMPILE_PART") endif () target_link_libraries(${EXEC_NAME} scotcherr ptscotch scotch ${SCOTCH_DEPENDENCIES}) install (FILES ${CMAKE_CURRENT_BINARY_DIR}/${EXEC_NAME} DESTINATION bin PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE) list(APPEND C_EXECS ${EXEC_NAME}) ## Add test #if (TEST_FILES MATCHES ".*${EXEC_NAME}.*") # if (OLD_CMAKE) # add_test( ${EXEC_NAME} # ${CMAKE_MODULE_PATH}/run-partests.sh ${MPIEXEC} ${NB_PROC} # ${CMAKE_CURRENT_BINARY_DIR}/${EXEC_NAME} ${CMAKE_CURRENT_BINARY_DIR}/${EXEC_NAME}-out ${TEST_DIR}/${EXEC_NAME}) # else () # add_test(NAME ${EXEC_NAME} # COMMAND ${CMAKE_MODULE_PATH}/run-partests.sh ${MPIEXEC} ${NB_PROC} ${CMAKE_CURRENT_BINARY_DIR}/${EXEC_NAME} # ${CMAKE_CURRENT_BINARY_DIR}/${EXEC_NAME}-out ${TEST_DIR}/${EXEC_NAME}) # set_tests_properties (${EXEC_NAME} PROPERTIES # TIMEOUT 60 # ) # endif () #endif () ## Add memory test # if (OLD_CMAKE) # add_test( MEM_${EXEC_NAME} # ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${NB_PROC} ${VALGRIND_EXE} ${VALGRIND_ARGS} # ${CMAKE_CURRENT_BINARY_DIR}/${EXEC_NAME}) # else () # add_test(NAME MEM_${EXEC_NAME} # COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${NB_PROC} ${VALGRIND_EXE} ${VALGRIND_ARGS} # ${CMAKE_CURRENT_BINARY_DIR}/${EXEC_NAME}) # endif () #set_tests_properties (MEM_${EXEC_NAME} PROPERTIES # FAIL_REGULAR_EXPRESSION "problem with execution of;mpiexec was unable to launch;definitely lost: [^0][0-9,]* bytes in [^0][0-9,]* blocks;indirectly lost: [^0][0-9,]* bytes in [^0][0-9,]* blocks;possibly lost: [^0][0-9,]* bytes in [^0][0-9,]* blocks;ERROR SUMMARY: [^0][0-9,]* errors from [^0][0-9,]* contexts;Conditional jump or move depends on uninitialised value;Invalid write;Invalid read" # TIMEOUT 60 # PASS_REGULAR_EXPRESSION "fin du prog") endforeach() ###################### # Sequential execs # ###################### # Combine sequential source file with execution file message (STATUS "depend: ${SCOTCH_DEPENDENCIES}") foreach (EXEC_NAME ${SCOTCH_EXECS}) if (NOT ${EXEC_NAME} STREQUAL "gout" AND NOT ${EXEC_NAME} STREQUAL "gpart") add_executable(${EXEC_NAME} ${EXEC_NAME}.c) else () if (${EXEC_NAME} STREQUAL "gout") add_executable (${EXEC_NAME} ${EXEC_NAME}_c.c ${EXEC_NAME}_o.c) else () add_executable (${EXEC_NAME} gmap.c) set_target_properties (${EXEC_NAME} PROPERTIES COMPILE_FLAGS "-DSCOTCH_COMPILE_PART") endif () endif () target_link_libraries (${EXEC_NAME} scotcherr scotch ${SCOTCH_DEPENDENCIES}) install (FILES ${CMAKE_CURRENT_BINARY_DIR}/${EXEC_NAME} DESTINATION bin PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE) list (APPEND C_EXECS ${EXEC_NAME}) ## Add test #if (TEST_FILES MATCHES ".*${EXEC_NAME}.*") # if (OLD_CMAKE) # add_test (${EXEC_NAME} # ${CMAKE_MODULE_PATH}/run-seqtests.sh # ${CMAKE_CURRENT_BINARY_DIR}/${EXEC_NAME} ${CMAKE_CURRENT_BINARY_DIR}/${EXEC_NAME}-out ${TEST_DIR}/${EXEC_NAME}) # else () # add_test (NAME ${EXEC_NAME} # COMMAND ${CMAKE_MODULE_PATH}/run-seqtests.sh # ${CMAKE_CURRENT_BINARY_DIR}/${EXEC_NAME} ${CMAKE_CURRENT_BINARY_DIR}/${EXEC_NAME}-out ${TEST_DIR}/${EXEC_NAME}) # endif () #endif() ## Add memory test # if (OLD_CMAKE) # add_test (MEM_${EXEC_NAME} # ${VALGRIND_EXE} ${VALGRIND_ARGS} # ${CMAKE_CURRENT_BINARY_DIR}/${EXEC_NAME}) # else () # add_test (NAME MEM_${EXEC_NAME} # COMMAND ${VALGRIND_EXE} ${VALGRIND_ARGS} # ${CMAKE_CURRENT_BINARY_DIR}/${EXEC_NAME}) # endif () #set_tests_properties (MEM_${EXEC_NAME} PROPERTIES # FAIL_REGULAR_EXPRESSION "definitely lost: [^0][0-9,]* bytes in [^0][0-9,]* blocks;indirectly lost: [^0][0-9,]* bytes in [^0][0-9,]* blocks;possibly lost: [^0][0-9,]* bytes in [^0][0-9,]* blocks;ERROR SUMMARY: [^0][0-9,]* errors from [^0][0-9,]* contexts;Conditional jump or move depends on uninitialised value;Invalid write;Invalid read") endforeach() scotch-6.0.4.dfsg/src/scotch/amk_fft2.h0000644002563400244210000001400712473176651023023 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : amk_fft2.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Creates the distance map for FFT **/ /** graphs, to be used to build the archi- **/ /** tecture description files for these **/ /** graphs. **/ /** **/ /** DATES : # Version 1.3 : from : 19 apr 1994 **/ /** to : 20 apr 1994 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to : 04 jul 1995 **/ /** # Version 3.2 : from : 07 may 1997 **/ /** to : 07 may 1997 **/ /** # Version 3.3 : from : 02 oct 1998 **/ /** to : 02 oct 1998 **/ /** # Version 5.0 : from : 01 jan 2008 **/ /** to : 01 jan 2008 **/ /** # Version 6.0 : from : 12 nov 2014 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The type and structure definitions */ /*+ File name aliases. +*/ #define C_FILENBR 1 /* Number of files in list */ #define C_filenamearcout fileBlockName (C_fileTab, 0) /* Architecture output file name */ #define C_filepntrarcout fileBlockFile (C_fileTab, 0) /* Architecture output file */ /*+ This structure defines an FFT vertex. +*/ typedef struct C_Vertex_ { SCOTCH_Num lvl; /*+ Vertex level +*/ SCOTCH_Num pos; /*+ Vertex position +*/ } C_Vertex; /*+ This structure defines a vertex distance information. +*/ typedef struct C_VertDist_ { int queued; /*+ Flag set if vertex queued +*/ SCOTCH_Num dist; /*+ Distance to initial vertex +*/ } C_VertDist; /*+ This is a neighbor queue element. +*/ typedef struct C_QueueElem_ { C_Vertex vert; /*+ Vertex number +*/ SCOTCH_Num dist; /*+ Distance reached +*/ } C_QueueElem; /*+ This is the distance queue. +*/ typedef struct C_Queue_ { C_QueueElem * tab; /*+ Pointer to queue data +*/ SCOTCH_Num min; /*+ Pointer to first element +*/ SCOTCH_Num max; /*+ Pointer to last element +*/ } C_Queue; /* ** The macro definitions. */ #define C_vertLabl(v) (((v)->lvl << fdim) | (v)->pos) #define C_queueInit(q,n) ((((q)->tab = (C_QueueElem *) memAlloc ((n) * sizeof (C_QueueElem))) == NULL) ? 1 : 0) #define C_queueExit(q) memFree ((q)->tab) #define C_queueFlush(q) (q)->min = \ (q)->max = 0 #define C_queuePut(q,v,d) ((q)->tab[(q)->max].vert = *(v), \ (q)->tab[(q)->max ++].dist = (d)) #define C_queueGet(q,v,d) (((q)->min < (q)->max) ? (*(v) = (q)->tab[(q)->min].vert, \ *(d) = (q)->tab[(q)->min ++].dist, \ 1) \ : 0) #define C_distaRoot(v) (C_queueFlush (&C_distaQueue), \ C_queuePut (&C_distaQueue, (v), 0), \ C_distaTab[C_vertLabl (v)].queued = 1) #define C_distaGet(v,d) (C_queueGet (&C_distaQueue, (v), (d))) #define C_distaPut(v,d) ((C_distaTab[C_vertLabl (v)].queued == 0) \ ? C_queuePut (&C_distaQueue, (v), d), \ C_distaTab[C_vertLabl (v)].queued = 1 \ : 0) scotch-6.0.4.dfsg/src/scotch/gmap.h0000644002563400244210000001602412473176651022257 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gmap.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : Part of a graph static mapper. **/ /** These lines are the data declaration **/ /** for the main routine. **/ /** **/ /** DATES : # Version 0.0 : from : 05 jan 1993 **/ /** to 12 may 1993 **/ /** # Version 1.3 : from : 09 apr 1994 **/ /** to 30 apr 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to 08 nov 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to 09 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 15 aug 1995 **/ /** # Version 3.1 : from : 07 nov 1995 **/ /** to 10 nov 1995 **/ /** # Version 3.2 : from : 04 oct 1996 **/ /** to 18 jul 1997 **/ /** # Version 3.3 : from : 07 oct 1998 **/ /** to : 31 may 1999 **/ /** # Version 4.0 : from : 16 jan 2004 **/ /** to : 16 jan 2004 **/ /** # Version 5.0 : from : 12 jun 2008 **/ /** to : 18 jun 2008 **/ /** # Version 5.1 : from : 28 aug 2010 **/ /** to : 18 jul 2011 **/ /** # Version 6.0 : from : 29 may 2010 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ File name aliases. +*/ #define C_FILENBR 7 /* Number of files in list */ #define C_filenamesrcinp fileBlockName (C_fileTab, 0) /* Source graph input file name */ #define C_filenametgtinp fileBlockName (C_fileTab, 1) /* Target architecture input file name */ #define C_filenamemapout fileBlockName (C_fileTab, 2) /* Mapping result output file name */ #define C_filenamelogout fileBlockName (C_fileTab, 3) /* Log file name */ #define C_filenamevfxinp fileBlockName (C_fileTab, 4) /* Fixed vertex file */ #define C_filenamemaoinp fileBlockName (C_fileTab, 5) /* Old mapping file */ #define C_filenamevmlinp fileBlockName (C_fileTab, 6) /* Vertex migration load file */ #define C_filepntrsrcinp fileBlockFile (C_fileTab, 0) /* Source graph input file */ #define C_filepntrtgtinp fileBlockFile (C_fileTab, 1) /* Target architecture input file */ #define C_filepntrmapout fileBlockFile (C_fileTab, 2) /* Mapping result output file */ #define C_filepntrlogout fileBlockFile (C_fileTab, 3) /* Log file */ #define C_filepntrvfxinp fileBlockFile (C_fileTab, 4) /* Fixed vertex file */ #define C_filepntrmaoinp fileBlockFile (C_fileTab, 5) /* Old mapping file */ #define C_filepntrvmlinp fileBlockFile (C_fileTab, 6) /* Vertex migration load file */ /*+ Process flags. +*/ #define C_FLAGNONE 0x0000 /* No flags */ #define C_FLAGPART 0x0001 /* Partitioning */ #define C_FLAGPARTOVL 0x0002 /* Partitioning with overlap */ #define C_FLAGVERBSTR 0x0004 /* Verbose flags */ #define C_FLAGVERBTIM 0x0008 #define C_FLAGVERBMAP 0x0010 #define C_FLAGKBALVAL 0x0020 /* Imbalance tolerance */ #define C_FLAGCLUSTER 0x0040 /* Clustering */ #define C_FLAGFIXED 0x0080 /* Fixed vertices input file */ #define C_FLAGRMAPOLD 0x0100 /* Old mapping file */ #define C_FLAGRMAPRAT 0x0200 /* Edge migration ratio */ #define C_FLAGRMAPCST 0x0400 /* Vertex migration cost file */ /* ** The type and structure definitions. */ /*+ This structure stores part lists. +*/ typedef struct C_PartList_ { SCOTCH_Num vertnum; /*+ Number of vertex of which part is neighbor +*/ SCOTCH_Num nextidx; /*+ Pointer to index of next recorded neighbor +*/ } C_PartList; /* ** The function prototypes. */ void C_partSave (SCOTCH_Graph * restrict const, SCOTCH_Num * restrict const, FILE * const); void C_partViewOvl (SCOTCH_Graph * restrict const, SCOTCH_Num * restrict const, FILE * const); scotch-6.0.4.dfsg/src/scotch/gotst.c0000644002563400244210000004324712473176651022475 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gotst.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** Bruno MARCUSSEAU (v3.1) **/ /** **/ /** FUNCTION : Graph symbolic factorizer. **/ /** This module contains the main function. **/ /** **/ /** DATES : # Version 4.0 : from : 27 jan 2004 **/ /** to : 28 nov 2005 **/ /** # Version 5.0 : from : 25 jun 2007 **/ /** to : 16 mar 2008 **/ /** # Version 5.1 : from : 20 apr 2010 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /** NOTES : # The cost analysis routine leaves the **/ /** memory management to malloc and free **/ /** because it is assumed to be the most **/ /** efficient to merge free blocks and **/ /** reallocate them. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GOTST #include "module.h" #include "common.h" #include "scotch.h" #include "gotst.h" /* ** The static and global variables. */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[3] = { /* File array */ { "r" }, { "r" }, { "w" } }; static const char * C_usageList[] = { "gotst [ [ []]] ", " -h : Display this help", " -V : Print program version and copyright", NULL }; /*****************************/ /* */ /* This is the main function */ /* */ /*****************************/ int main ( int argc, char * argv[]) { SCOTCH_Graph grafdat; SCOTCH_Num vertnbr; SCOTCH_Num * verttab; SCOTCH_Num * vendtab; SCOTCH_Num edgenbr; SCOTCH_Num * edgetab; SCOTCH_Num baseval; SCOTCH_Ordering ordedat; SCOTCH_Num * permtab; SCOTCH_Num * peritab; int i; errorProg ("gotst"); if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_fileNum < C_FILEARGNBR) /* File name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else { errorPrint ("main: too many file names given"); return (1); } } else { /* If found an option name */ switch (argv[i][1]) { case 'H' : /* Give help */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'V' : fprintf (stderr, "gotst, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: unprocessed option '%s'", argv[i]); return (1); } } } fileBlockOpen (C_fileTab, C_FILENBR); /* Open all files */ SCOTCH_graphInit (&grafdat); SCOTCH_graphLoad (&grafdat, C_filepntrgrfinp, -1, 3); SCOTCH_graphData (&grafdat, &baseval, &vertnbr, &verttab, &vendtab, NULL, NULL, &edgenbr, &edgetab, NULL); #ifdef SCOTCH_DEBUG_ALL if (vendtab != (verttab + 1)) { errorPrint ("main: graph should be compact"); return (1); } #endif /* SCOTCH_DEBUG_ALL */ if (memAllocGroup ((void **) (void *) &peritab, (size_t) (vertnbr * sizeof (SCOTCH_Num)), &permtab, (size_t) (vertnbr * sizeof (SCOTCH_Num)), NULL) == NULL) { errorPrint ("main: out of memory"); return (1); } SCOTCH_graphOrderInit (&grafdat, &ordedat, permtab, peritab, NULL, NULL, NULL); SCOTCH_graphOrderLoad (&grafdat, &ordedat, C_filepntrordinp); if (SCOTCH_graphOrderCheck (&grafdat, &ordedat) != 0) { errorPrint ("main: invalid ordering"); return (1); } factorView (baseval, vertnbr, verttab, edgenbr, edgetab, permtab, peritab, C_filepntrdatout); fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ memFree (peritab); SCOTCH_graphOrderExit (&grafdat, &ordedat); SCOTCH_graphExit (&grafdat); #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } /*************************************/ /* */ /* These routines compute statistics */ /* on orderings. */ /* */ /*************************************/ static int factorView ( const SCOTCH_Num baseval, const SCOTCH_Num vertnbr, const SCOTCH_Num * const verttab, const SCOTCH_Num edgenbr, const SCOTCH_Num * const edgetab, const SCOTCH_Num * const permtab, const SCOTCH_Num * const peritab, FILE * restrict const stream) { SCOTCH_Num * restrict ldadtab; SCOTCH_Num * restrict lsontab; SCOTCH_Num * restrict lbrotab; SCOTCH_Num * restrict fnnztab; double fopcsum; double heigsum; FactorStat statdat; SCOTCH_Num vertnum; int o; if (memAllocGroup ((void **) (void *) &ldadtab, (size_t) (vertnbr * sizeof (SCOTCH_Num)), &lsontab, (size_t) (vertnbr * sizeof (SCOTCH_Num)), &lbrotab, (size_t) (vertnbr * sizeof (SCOTCH_Num)), &fnnztab, (size_t) (vertnbr * sizeof (SCOTCH_Num)), NULL) == NULL) { errorPrint ("factorView: out of memory"); return (1); } statdat.ldadtax = ldadtab - baseval; statdat.lsontax = lsontab - baseval; statdat.lbrotax = lbrotab - baseval; statdat.fnnztax = fnnztab - baseval; if (factorView2 (baseval, vertnbr, verttab - baseval, edgetab - baseval, permtab - baseval, peritab - baseval, ldadtab - baseval, lsontab - baseval, lbrotab - baseval, fnnztab - baseval) != 0) { errorPrint ("factorView: factored matrix too large"); memFree (ldadtab); /* Free group leader */ return (1); } statdat.heigmin = SCOTCH_NUMMAX; statdat.heigmax = statdat.heignbr = 0; heigsum = 0.0L; for (vertnum = 0; vertnum < vertnbr; vertnum ++) { /* Get height sum */ if (ldadtab[vertnum] == -1) /* If column is a root */ factorView3 (&statdat, 1, vertnum + baseval, &heigsum); /* Scan subtree */ } statdat.heigavg = heigsum / (double) statdat.heignbr; statdat.heigdlt = 0.0L; statdat.fnnzsum = 0.0L; fopcsum = 0.0L; for (vertnum = 0; vertnum < vertnbr; vertnum ++) { /* Get delta */ if (ldadtab[vertnum] == -1) /* If column is a root */ factorView4 (&statdat, 1, vertnum + baseval, &fopcsum); } statdat.heigdlt /= (double) statdat.heignbr; o = (fprintf (stream, "O\tLeaf=" SCOTCH_NUMSTRING "\nO\tHeight min=" SCOTCH_NUMSTRING "\tmax=" SCOTCH_NUMSTRING "\tavg=%f\tdlt=%f (%5.2f)\n", /* Write tree height statistics */ (SCOTCH_Num) statdat.heignbr, (SCOTCH_Num) statdat.heigmin, (SCOTCH_Num) statdat.heigmax, statdat.heigavg, statdat.heigdlt, ((statdat.heigdlt / statdat.heigavg) * (double) 100.0L)) == EOF); o |= (fprintf (stream, "O\tNNZ=%e\nO\tOPC=%e\n", statdat.fnnzsum, fopcsum) == EOF); if (o != 0) errorPrint ("factorView: bad output"); memFree (ldadtab); /* Free group leader */ return (o); } static int factorView2 ( const SCOTCH_Num baseval, const SCOTCH_Num vertnbr, const SCOTCH_Num * const verttax, const SCOTCH_Num * const edgetax, const SCOTCH_Num * const permtax, const SCOTCH_Num * const peritax, SCOTCH_Num * restrict ldadtax, SCOTCH_Num * restrict lsontax, SCOTCH_Num * restrict lbrotax, SCOTCH_Num * restrict fnnztax) { SCOTCH_Num * restrict frowtab; SCOTCH_Num * restrict fnxttab; SCOTCH_Num ** restrict facttax; SCOTCH_Num vertnnd; SCOTCH_Num pcolnum; memSet (lsontax + baseval, ~0, vertnbr * sizeof (SCOTCH_Num)); /* Assume columns have no sons at all */ if (memAllocGroup ((void **) (void *) &frowtab, (size_t) ((vertnbr + 1) * sizeof (SCOTCH_Num)), &fnxttab, (size_t) ((vertnbr + 1) * sizeof (SCOTCH_Num)), &facttax, (size_t) (vertnbr * sizeof (SCOTCH_Num *)), NULL) == NULL) { errorPrint ("factorView2: out of memory (1)"); return (1); } memSet (facttax, 0, vertnbr * sizeof (SCOTCH_Num *)); /* Set all factored column pointers to NULL */ facttax -= baseval; vertnnd = vertnbr + baseval; for (pcolnum = baseval; pcolnum < vertnnd; pcolnum ++) { /* For all columns of the permuted matrix */ SCOTCH_Num * fcoltab; SCOTCH_Num * restrict fcolptr; SCOTCH_Num frownbr; SCOTCH_Num frowidx; SCOTCH_Num frowidd; SCOTCH_Num scolnum; SCOTCH_Num icolnum; SCOTCH_Num irownum; SCOTCH_Num dcolnum; icolnum = peritax[pcolnum]; /* Get the original number of the column */ frownbr = 1; /* Start array of factored terms for column */ frowtab[0] = pcolnum; /* Add diagonal element as unmoveable starter */ for (irownum = verttax[icolnum]; irownum < verttax[icolnum + 1]; irownum ++) { SCOTCH_Num prownum; prownum = permtax[edgetax[irownum]]; /* Get permuted row */ if (prownum >= pcolnum) frowtab[frownbr ++] = prownum; } intSort1asc1 (frowtab + 1, frownbr - 1); /* Sort rows in ascending order */ frowtab[frownbr ++] = vertnnd; /* Add trailer */ for (frowidx = 0; frowidx < (frownbr - 1); frowidx ++) /* Create initial links */ fnxttab[frowidx] = frowidx + 1; frowidd = frowidx; /* Save index of trailer */ for (scolnum = lsontax[pcolnum]; scolnum != -1; scolnum = lbrotax[scolnum]) { /* For all son columns in elimination tree */ const SCOTCH_Num * restrict srowtab; SCOTCH_Num srownbr; SCOTCH_Num srowidx; SCOTCH_Num frowidx; SCOTCH_Num foldidx; SCOTCH_Num frownum; srowtab = facttax[scolnum]; /* Point to array of factors for son column */ srownbr = fnnztax[scolnum]; /* Get size of array */ for (srowidx = 1, frowidx = 0, foldidx = -1, frownum = frowtab[frowidx]; srowidx < srownbr; srowidx ++) { SCOTCH_Num srownum; srownum = srowtab[srowidx]; while (frownum < srownum) { /* While factor to add not in place */ foldidx = frowidx; /* Skip to next position */ frowidx = fnxttab[frowidx]; frownum = frowtab[frowidx]; } if (srownum == frownum) /* If factor already in column */ continue; frowtab[frownbr] = srownum; /* Add new slot */ fnxttab[frownbr] = frowidx; /* Link new slot */ fnxttab[foldidx] = frownbr; foldidx = frownbr ++; } memFree ((void *) srowtab); /* Free now useless factored column */ #ifdef SCOTCH_DEBUG_ALL facttax[scolnum] = NULL; #endif /* SCOTCH_DEBUG_ALL */ } frownbr -= 2; /* Remove markers from number of extra-diagonals */ fnnztax[pcolnum] = frownbr; /* Save number of extra-diagonals */ if (frownbr <= 0) { /* If factored column has no extra-diagonals */ ldadtax[pcolnum] = -1; /* Column has no father */ #ifdef SCOTCH_DEBUG_ALL lbrotax[pcolnum] = -1; #endif /* SCOTCH_DEBUG_ALL */ continue; /* Skip to next column without allocating or linking */ } if ((fcoltab = memAlloc (frownbr * sizeof (SCOTCH_Num))) == NULL) { /* Allocate array for factored column */ errorPrint ("factorView2: out of memory (2)"); return (1); } for (frowidx = fnxttab[0], fcolptr = fcoltab; frowidx != frowidd; frowidx = fnxttab[frowidx]) /* Fill factored array for column */ *fcolptr ++ = frowtab[frowidx]; dcolnum = fcoltab[0]; /* Get number of father, that it, first extra-diagonal */ ldadtax[pcolnum] = dcolnum; /* Link factored column to the separation tree */ lbrotax[pcolnum] = lsontax[dcolnum]; lsontax[dcolnum] = pcolnum; facttax[pcolnum] = fcoltab; /* Save factored array */ } memFree (frowtab); /* Free group leader */ return (0); } static void factorView3 ( FactorStat * restrict const statptr, SCOTCH_Num levlnum, SCOTCH_Num vertnum, double * restrict const hsumptr) { double hsumtmp; hsumtmp = 0.0; if (statptr->lsontax[vertnum] != -1) { /* If node has descendants */ SCOTCH_Num csonnum; for (csonnum = statptr->lsontax[vertnum]; csonnum != -1; csonnum = statptr->lbrotax[csonnum]) factorView3 (statptr, levlnum + 1, csonnum, &hsumtmp); } else { hsumtmp = (double) levlnum; statptr->heignbr ++; if (levlnum < statptr->heigmin) statptr->heigmin = levlnum; if (levlnum > statptr->heigmax) statptr->heigmax = levlnum; } *hsumptr += hsumtmp; } static void factorView4 ( FactorStat * restrict const statptr, SCOTCH_Num levlnum, SCOTCH_Num vertnum, double * restrict const fopcptr) { SCOTCH_Num fnnztmp; double fopctmp; fnnztmp = statptr->fnnztax[vertnum] + 1; /* Get extra-diagonals, plus diagonal */ fopctmp = (double) fnnztmp; statptr->fnnzsum += fopctmp; fopctmp *= fopctmp; if (statptr->lsontax[vertnum] != -1) { /* If node has descendants */ SCOTCH_Num csonnum; for (csonnum = statptr->lsontax[vertnum]; csonnum != -1; csonnum = statptr->lbrotax[csonnum]) factorView4 (statptr, levlnum + 1, csonnum, &fopctmp); /* Accumulate OPC on local sum */ } else statptr->heigdlt += fabs ((double) levlnum - statptr->heigavg); *fopcptr += fopctmp; /* Aggregate local sum at higher level */ } scotch-6.0.4.dfsg/src/scotch/mtst.h0000644002563400244210000000626012473176651022323 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mtst.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the declarations **/ /** for the source mesh analyzer. **/ /** **/ /** DATES : # Version 4.0 : from : 25 feb 2003 **/ /** to 27 jan 2004 **/ /** # Version 6.0 : from : 12 nov 2014 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /** File name aliases. **/ #define C_FILENBR 2 /* Number of files in list */ #define C_FILEARGNBR 2 /* Number of files which can be arguments */ #define C_filenamesrcinp fileBlockName (C_fileTab, 0) /* Source mesh input file name */ #define C_filenamedatout fileBlockName (C_fileTab, 1) /* Statistics output file name */ #define C_filepntrsrcinp fileBlockFile (C_fileTab, 0) /* Source mesh input file */ #define C_filepntrdatout fileBlockFile (C_fileTab, 1) /* Statistics output file */ scotch-6.0.4.dfsg/src/scotch/gout_o.h0000644002563400244210000002055012473176651022626 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008 ENSEIRB, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gout_o.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a result viewer. **/ /** This module contains the data declara- **/ /** tions for the output module. **/ /** **/ /** DATES : # Version 2.0 : from : 08 oct 1994 **/ /** to 02 nov 1994 **/ /** # Version 3.0 : from : 14 jul 1995 **/ /** to 03 oct 1995 **/ /** # Version 3.1 : from : 05 apr 1996 **/ /** to 05 apr 1996 **/ /** # Version 3.2 : from : 03 dec 1996 **/ /** to 05 jun 1998 **/ /** # Version 3.3 : from : 02 jun 1999 **/ /** to 02 jun 1999 **/ /** # Version 5.0 : from : 25 may 2007 **/ /** to 25 may 2007 **/ /** # Version 5.1 : from : 25 oct 2007 **/ /** to 26 oct 2007 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ Generic PostScript output definitions. +*/ #define O_PSDPI 72 /* PostScript dots-per-inch */ #define O_PSPAGEHEIGHT 11.6 /* PostScript page height (in inches) */ #define O_PSPAGEWIDTH 8.2 /* PostScript page witdh (in inches) */ #define O_PSPICTHEIGHT 10.0 /* PostScript picture height (in inches) */ #define O_PSPICTWIDTH 6.6 /* PostScript picture witdh (in inches) */ /*+ PostScript mesh output definitions. +*/ #define O_POSMESHPICTRESOL 10000.0 /* Picture resolution */ #define O_POSMESHISOCOS 0.866025404 /* cos(30 degrees) */ #define O_POSMESHISOSIN 0.5 /* sin(30 degrees) */ #define O_POSMESHISOREDUC 0.20 /* Z-axis reduction coefficient */ #define O_POSMESHCOLNBR 16 /* Number of colors */ /*+ Tulip graph output definitions. +*/ #define O_TULMESHDISKRATIO 0.1 /* Node disk ratio */ /* ** The type and structure definitions. */ /*+ The 2D point type. +*/ typedef struct O_Point_ { double c[2]; /*+ Page coordinates +*/ } O_Point; /*+ The output type type. +*/ typedef enum O_OutType_ { O_OUTTYPEINVMESH, /*+ Mesh SGI Open Inventor (3D) +*/ O_OUTTYPEPOSMATR, /*+ Matrix PostScript (2D) +*/ O_OUTTYPEPOSMESH, /*+ Mesh PostScript (2D) +*/ O_OUTTYPETULMESH, /*+ Mesh Tulip (3D) +*/ O_OUTTYPENBR /*+ Number of output types +*/ } O_OutType; /*+ The output parameter data structure. +*/ typedef struct O_OutParam_ { O_OutType type; /*+ Output type +*/ struct { /*+ Inventor mesh structure +*/ char color; /*+ 'c' : color; 'g' : gray +*/ char edge; /*+ 'r' : remove; 'v' : view +*/ } InvMesh; struct { /*+ PostScript matrix structure +*/ char type; /*+ 'f' : page; 'e' : EPSF +*/ } PosMatr; struct { /*+ PostScript mesh structure +*/ char type; /*+ 'f' : page; 'e' : EPSF +*/ char color; /*+ 'c' : color; 'g' : gray +*/ char edge; /*+ 'r' : remove; 'v' : view +*/ char disk; /*+ 'd' : draw; 'a' : avoid +*/ char clip; /*+ 'l' : large; 's' : short +*/ O_Point min; /*+ Clipping ratios +*/ O_Point max; } PosMesh; struct { /*+ Tulip graph structure +*/ char color; /*+ 'b' : b/w; 'c' : color +*/ char edge; /*+ 'r' : remove; 'v' : view +*/ char disk; /*+ 'd' : draw; 'a' : avoid +*/ } TulMesh; } O_OutParam; /*+ The Inventor path array element. +*/ typedef struct O_InvMeshPath_ { SCOTCH_Num nbr; /*+ Number of output paths +*/ SCOTCH_Num idx; /*+ Index from which to search +*/ } O_InvMeshPath; /*+ The PostScript path array element. +*/ typedef struct O_PosMeshPath_ { SCOTCH_Num nbr; /*+ Number of output paths +*/ SCOTCH_Num idx; /*+ Index from which to search +*/ } O_PosMeshPath; /*+ The PostScript mesh graph vertex. +*/ typedef struct O_PosMeshVertex_ { int vis; /*+ Visibility flag +*/ O_Point pos; /*+ Point position +*/ double rad; /*+ Disk radius +*/ int col; /*+ Disk color index +*/ } O_PosMeshVertex; /* ** The function prototypes. */ void outColorBlw (const SCOTCH_Num, double[]); void outColorColor (const SCOTCH_Num, double[]); int outDrawParse (char * const); void outDraw (const C_Graph * const, const C_Geometry * const, const C_Mapping * const, FILE * const); int outDrawInvMesh (const C_Graph * const, const C_Geometry * const, const C_Mapping * const, FILE * const); int outDrawPosMatr (const C_Graph * const, const C_Geometry * const, const C_Mapping * const, FILE * const); int outDrawPosMesh (const C_Graph * const, const C_Geometry * const, const C_Mapping * const, FILE * const); int outDrawTulMesh (const C_Graph * const, const C_Geometry * const, const C_Mapping * const, FILE * const); scotch-6.0.4.dfsg/src/scotch/gmk_ub2.c0000644002563400244210000002147512473176651022662 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gmk_ub2.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Creates the source graph for undirected **/ /** de Bruijn graphs, to be used to build **/ /** the architecture description files for **/ /** these graphs. **/ /** **/ /** DATES : # Version 1.2 : from : 11 feb 1994 **/ /** to : 11 feb 1994 **/ /** # Version 2.0 : from : 05 nov 1994 **/ /** to 05 nov 1994 **/ /** # Version 3.0 : from : 11 jul 1995 **/ /** to 12 jul 1995 **/ /** # Version 3.2 : from : 03 jun 1997 **/ /** to : 03 jun 1997 **/ /** # Version 3.3 : from : 07 jun 1999 **/ /** to : 07 jun 1999 **/ /** # Version 3.4 : from : 03 feb 2000 **/ /** to : 03 feb 2000 **/ /** # Version 5.0 : from : 22 jan 2008 **/ /** to : 16 mar 2008 **/ /** # Version 5.1 : from : 01 jul 2010 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GMK_UB2 #include "module.h" #include "common.h" #include "scotch.h" #include "gmk_ub2.h" #define ngbadd(v) if ((v) != vertnum) { \ int k; \ for (k = 0; k < ngbnbr; k ++) \ if ((v) == ngbtab[k]) \ break; \ if (k == ngbnbr) \ ngbtab[ngbnbr ++] = (v); \ } /* ** The static definitions. */ static int C_paraNum = 0; /* Number of parameters */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[C_FILENBR] = { /* The file array */ { "w" } }; static const char * C_usageList[] = { "gmk_ub2 [] ", " -h : Display this help", " -V : Print program version and copyright", NULL }; /****************************************/ /* */ /* The main routine, which computes the */ /* source graph description. */ /* */ /****************************************/ int main ( int argc, char * argv[]) { SCOTCH_Num ubdim = 1; /* Graph dimension */ SCOTCH_Num ubnbr; /* Number of vertices */ SCOTCH_Num ubbit; /* Most significant bit */ SCOTCH_Num ngbtab[4]; /* Array of neighbors */ int ngbnbr; /* Current number of neighbors */ SCOTCH_Num vertnum; /* Current vertex number */ int i, j; errorProg ("gmk_ub2"); if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_paraNum < 1) { /* If number of parameters not reached */ if ((ubdim = (SCOTCH_Num) atol (argv[i])) < 1) { /* Get dimension */ errorPrint ("main: invalid dimension '%s'", argv[i]); return (1); } C_paraNum ++; continue; /* Process the other parameters */ } if (C_fileNum < C_FILEARGNBR) /* A file name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else { errorPrint ("main: too many file names given"); return (1); } } else { /* If found an option name */ switch (argv[i][1]) { case 'H' : /* Give the usage message */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'V' : fprintf (stderr, "gmk_ub2, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: unprocessed option '%s'", argv[i]); return (1); } } } fileBlockOpen (C_fileTab, C_FILENBR); /* Open all files */ ubnbr = 1 << ubdim; /* Compute number of vertices */ ubbit = 1 << (ubdim - 1); /* Bit to add on the left */ fprintf (C_filepntrsrcout, "0\n" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n0\t000\n", (SCOTCH_Num) ubnbr, /* Print number of vertices */ (SCOTCH_Num) (4 * ubnbr - 6)); /* Print number of edges (arcs) */ for (vertnum = 0; vertnum < ubnbr; vertnum ++) { /* For all vertices */ ngbnbr = 0; /* No neighbors defined yet */ ngbadd ((vertnum << 1) & (ubnbr - 1)); /* Register vertex neighbors */ ngbadd (((vertnum << 1) & (ubnbr - 1)) | 1); ngbadd ((vertnum >> 1) & (ubnbr - 1)); ngbadd (((vertnum >> 1) & (ubnbr - 1)) | ubbit); fprintf (C_filepntrsrcout, "%d", ngbnbr); /* Output number of neighbors */ for (j = 0; j < ngbnbr; j ++) fprintf (C_filepntrsrcout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) ngbtab[j]); fprintf (C_filepntrsrcout, "\n"); } fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } scotch-6.0.4.dfsg/src/scotch/atst.c0000644002563400244210000002136112473176651022301 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : atst.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Target architecture graph analyzer. **/ /** **/ /** DATES : # Version 1.3 : from : 17 may 1994 **/ /** to : 17 may 1994 **/ /** # Version 2.0 : from : 11 nov 1994 **/ /** to : 11 nov 1994 **/ /** # Version 3.0 : from : 05 jul 1995 **/ /** to : 19 aug 1995 **/ /** # Version 3.2 : from : 24 sep 1996 **/ /** to : 12 may 1998 **/ /** # Version 3.4 : from : 03 feb 2000 **/ /** to : 03 feb 2000 **/ /** # Version 4.0 : from : 09 feb 2004 **/ /** to : 23 nov 2005 **/ /** # Version 5.0 : from : 23 dec 2007 **/ /** to : 16 mar 2008 **/ /** # Version 5.1 : from : 01 jul 2010 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define ATST #include "module.h" #include "common.h" #include "scotch.h" #include "arch.h" #include "arch_deco.h" #include "arch_mesh.h" #include "atst.h" /* ** The static variables. */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[C_FILENBR] = { /* File array */ { "r" }, { "w" } }; static const char * C_usageList[] = { "atst [ []] ", " -h : Display this help", " -V : Print program version and copyright", NULL }; /******************************/ /* */ /* This is the main function. */ /* */ /******************************/ int main (argc, argv) int argc; char * argv[]; { Arch archdat; /* The architecture read */ ArchDeco * deco; /* Its decomposition */ ArchDecoDom dom0; ArchDecoDom dom1; Anum dstval; Anum dstmin; Anum dstmax; Anum dstsum; double dstavg; double dstdlt; int i; errorProg ("atst"); if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_fileNum < C_FILEARGNBR) /* File name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else { errorPrint ("main: too many file names given"); return (1); } } else { /* If found an option name */ switch (argv[i][1]) { case 'H' : /* Give the usage message */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'V' : fprintf (stderr, "atst, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: unprocessed option '%s'", argv[i]); return (1); } } } fileBlockOpen (C_fileTab, C_FILENBR); /* Open all files */ archInit (&archdat); /* Initialize architecture structure */ archLoad (&archdat, C_filepntrtgtinp); /* Load architecture */ if (strcmp (archName (&archdat), "deco") != 0) { /* If it is not a decomposition */ errorPrint ("main: architecture is not decomposition-defined"); return (1); } deco = (ArchDeco *) (void *) &archdat.data; /* Point to the decomposition */ dstmin = (Anum) (((unsigned long) ((Anum) -1)) >> 1); /* Set to maximum number in Anum */ dstmax = 0; dstsum = 0; for (dom0.num = 1; dom0.num <= deco->domvertnbr; dom0.num ++) { /* For all pairs of vertices */ if (archDecoDomSize (deco, &dom0) == 1) { /* If vertex is a terminal */ for (dom1.num = dom0.num + 1; dom1.num <= deco->domvertnbr; dom1.num ++) { if (archDecoDomSize (deco, &dom1) == 1) { /* If vertex is a terminal */ dstval = archDecoDomDist (deco, &dom0, &dom1); /* Compute distance between pairs */ if (dstmin > dstval) dstmin = dstval; if (dstmax < dstval) dstmax = dstval; dstsum += dstval; /* Compute distance between pairs */ } } } } dstavg = (deco->domtermnbr > 1) ? (double) dstsum / (double) (deco->domtermnbr * (deco->domtermnbr - 1) / 2) : 0.0L; dstdlt = 0.0L; for (dom0.num = 1; dom0.num <= deco->domvertnbr; dom0.num ++) { /* For all pairs of vertices */ if (archDecoDomSize (deco, &dom0) == 1) { /* If vertex is a terminal */ for (dom1.num = dom0.num + 1; dom1.num <= deco->domvertnbr; dom1.num ++) { if (archDecoDomSize (deco, &dom1) == 1) /* If vertex is a terminal */ dstdlt += fabs (archDecoDomDist (deco, &dom0, &dom1) - dstavg); } } } if (deco->domtermnbr > 1) dstdlt /= (double) (deco->domtermnbr * (deco->domtermnbr - 1) / 2); fprintf (C_filepntrlogout, "A\tTerminals\tnbr=" SCOTCH_NUMSTRING "\n", (SCOTCH_Num) deco->domtermnbr); fprintf (C_filepntrlogout, "A\tDistance\tmin=" SCOTCH_NUMSTRING "\tmax=" SCOTCH_NUMSTRING "\tavg=%g\tdlt=%g\n", (SCOTCH_Num) dstmin, (SCOTCH_Num) dstmax, dstavg, dstdlt); fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ archExit (&archdat); #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } scotch-6.0.4.dfsg/src/scotch/mmk_m2.c0000644002563400244210000002433312473176651022512 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mmk_m2.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Creates source meshes for tridimen- **/ /** sional finite element grids. **/ /** **/ /** DATES : # Version 4.0 : from : 26 sep 2002 **/ /** to : 06 feb 2003 **/ /** # Version 5.0 : from : 13 dec 2007 **/ /** to : 16 mar 2008 **/ /** # Version 5.1 : from : 01 jul 2010 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /** NOTES : # The nodes and elements of the **/ /** (dX,dY) mesh are numbered so that **/ /** t(0,0) = 0, t(1,0) = 1, **/ /** t(dX - 1, 0) = dX - 1, t(0,1) = **/ /** dX, and t(x,y) = y * dX + x. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define MMK_M2 #include "module.h" #include "common.h" #include "scotch.h" #include "mmk_m2.h" /* ** The static definitions. */ static int C_paraNum = 0; /* Number of parameters */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[C_FILENBR] = { /* The file array */ { "w" }, { "w" } }; static const int C_nghbTab[3] = { 4, 2, 1 }; static const char * C_usageList[] = { "mmk_m2 [ []] ", " -g : Output mesh geometry to ", " -h : Display this help", " -V : Print program version and copyright", NULL }; /****************************************/ /* */ /* The main routine, which computes the */ /* source mesh description. */ /* */ /****************************************/ int main ( int argc, char * argv[]) { SCOTCH_Num e[2] = { 1, 1 }; /* Mesh element dimensions */ SCOTCH_Num n[2]; /* Mesh node dimensions */ SCOTCH_Num c[2]; /* Vertex coordinates */ SCOTCH_Num velmnbr; /* First node number */ int flagval; /* Process flags */ int i; errorProg ("mmk_m2"); flagval = C_FLAGDEFAULT; /* Set default flags */ if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_paraNum < 2) { /* If number of parameters not reached */ if ((e[C_paraNum ++] = atoi (argv[i])) < 1) { /* Get the dimension */ errorPrint ("main: invalid dimension '%s'", argv[i]); return (1); } continue; /* Process the other parameters */ } if (C_fileNum < C_FILEARGNBR) /* A file name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else { errorPrint ("main: too many file names given"); return (1); } } else { /* If found an option name */ switch (argv[i][1]) { case 'G' : /* Output mesh geometry */ case 'g' : flagval |= C_FLAGGEOOUT; if (argv[i][2] != '\0') C_filenamegeoout = &argv[i][2]; break; case 'H' : /* Give program usage message */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'V' : fprintf (stderr, "mmk_m2, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: unprocessed option '%s'", argv[i]); return (1); } } } fileBlockOpen (C_fileTab, C_FILENBR); /* Open all files */ n[0] = e[0] + 1; n[1] = e[1] + 1; velmnbr = e[0] * e[1]; fprintf (C_filepntrmshout, "1\n" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n0\t" SCOTCH_NUMSTRING "\t000\n", /* Print mesh file header */ (SCOTCH_Num) velmnbr, (SCOTCH_Num) (n[0] * n[1]), (SCOTCH_Num) (((velmnbr + n[0] * n[1]) - (e[0] + e[1] + 1)) * 4), (SCOTCH_Num) velmnbr); for (c[1] = 0; c[1] < e[1]; c[1] ++) { /* Output element neighbor list */ for (c[0] = 0; c[0] < e[0]; c[0] ++) { fprintf (C_filepntrmshout, "4\t" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n", /* Output neighbors of element */ (SCOTCH_Num) (c[1] * n[0] + c[0]), (SCOTCH_Num) (c[1] * n[0] + c[0] + 1), (SCOTCH_Num) ((c[1] + 1) * n[0] + c[0]), (SCOTCH_Num) ((c[1] + 1) * n[0] + c[0] + 1)); } } for (c[1] = 0; c[1] < n[1]; c[1] ++) { /* Output node neighbor list */ for (c[0] = 0; c[0] < n[0]; c[0] ++) { fprintf (C_filepntrmshout, "%d", /* Output number of neighboring elements */ C_nghbTab[(((c[0] != 0) && (c[0] != e[0])) ? 0 : 1) + (((c[1] != 0) && (c[1] != e[1])) ? 0 : 1)]); if (c[1] != 0) { /* Output neighbors of nodes */ if (c[0] != 0) fprintf (C_filepntrmshout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) ((c[1] - 1) * e[0] + (c[0] - 1))); if (c[0] != e[0]) fprintf (C_filepntrmshout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) ((c[1] - 1) * e[0] + c[0])); } if (c[1] != e[1]) { if (c[0] != 0) fprintf (C_filepntrmshout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) (c[1] * e[0] + (c[0] - 1))); if (c[0] != e[0]) fprintf (C_filepntrmshout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) (c[1] * e[0] + c[0])); } fprintf (C_filepntrmshout, "\n"); } } if (flagval & C_FLAGGEOOUT) { /* If geometry is wanted */ fprintf (C_filepntrgeoout, "2\n" SCOTCH_NUMSTRING "\n", /* Output geometry file header */ (SCOTCH_Num) (velmnbr + n[0] * n[1])); for (c[1] = 0; c[1] < e[1]; c[1] ++) { /* Output element coordinates */ for (c[0] = 0; c[0] < e[0]; c[0] ++) fprintf (C_filepntrgeoout, SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING ".5\t" SCOTCH_NUMSTRING ".5\n", (SCOTCH_Num) (c[1] * e[0] + c[0]), (SCOTCH_Num) c[0], (SCOTCH_Num) (e[1] - 1 - c[1])); } for (c[1] = 0; c[1] < n[1]; c[1] ++) { /* Output node coordinates */ for (c[0] = 0; c[0] < n[0]; c[0] ++) fprintf (C_filepntrgeoout, SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n", (SCOTCH_Num) (velmnbr + c[1] * n[0] + c[0]), (SCOTCH_Num) c[0], (SCOTCH_Num) (e[1] - c[1])); } } fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } scotch-6.0.4.dfsg/src/scotch/mcv.h0000644002563400244210000000734012473176651022121 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mcv.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a mesh file converter. **/ /** This module contains the data declara- **/ /** tions for the main module. **/ /** **/ /** DATES : # Version 4.0 : from : 19 jan 2004 **/ /** to : 19 jan 2004 **/ /** # Version 6.0 : from : 12 nov 2014 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines */ /*+ File name aliases. +*/ #define C_FILENBR 3 /* Number of files in list */ #define C_FILEARGNBR 3 /* Number of files which can be arguments */ #define C_filenamesrcinp fileBlockName (C_fileTab, 0) /* External mesh input file name */ #define C_filenamesrcout fileBlockName (C_fileTab, 1) /* Source mesh output file name */ #define C_filenamegeoout fileBlockName (C_fileTab, 2) /* Source mesh geometry file name */ #define C_filepntrsrcinp fileBlockFile (C_fileTab, 0) /* External mesh input file */ #define C_filepntrsrcout fileBlockFile (C_fileTab, 1) /* Source mesh output file */ #define C_filepntrgeoout fileBlockFile (C_fileTab, 2) /* Source mesh geometry file */ /* ** The type and structure definitions. */ /*+ This structure defines the method array element. +*/ typedef struct C_Format_ { char code; /* Format type code */ int (* func) (); /* Function to call */ } C_Format; scotch-6.0.4.dfsg/src/scotch/gord.h0000644002563400244210000001102412473176651022261 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gord.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a sparse matrix graph orderer. **/ /** This module contains the data declara- **/ /** tions for the main routine. **/ /** **/ /** DATES : # Version 3.2 : from : 24 aug 1996 **/ /** to : 20 oct 1997 **/ /** # Version 3.3 : from : 07 oct 1998 **/ /** to : 31 may 1999 **/ /** # Version 4.0 : from : 11 dec 2002 **/ /** to : 27 dec 2004 **/ /** # Version 6.0 : from : 12 nov 2014 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ File name aliases. +*/ #define C_FILENBR 5 /* Number of files in list */ #define C_FILEARGNBR 3 /* Number of files which can be arguments */ #define C_filenamesrcinp fileBlockName (C_fileTab, 0) /* Source graph input file name */ #define C_filenameordout fileBlockName (C_fileTab, 1) /* Ordering output file name */ #define C_filenamelogout fileBlockName (C_fileTab, 2) /* Log file name */ #define C_filenamemapout fileBlockName (C_fileTab, 3) /* Separator mapping file name */ #define C_filenametreout fileBlockName (C_fileTab, 4) /* Separator tree file name */ #define C_filepntrsrcinp fileBlockFile (C_fileTab, 0) /* Source graph input file */ #define C_filepntrordout fileBlockFile (C_fileTab, 1) /* Ordering output file */ #define C_filepntrlogout fileBlockFile (C_fileTab, 2) /* Log file */ #define C_filepntrmapout fileBlockFile (C_fileTab, 3) /* Separator mapping file */ #define C_filepntrtreout fileBlockFile (C_fileTab, 4) /* Separator tree file */ /*+ Process flags. +*/ #define C_FLAGNONE 0x0000 /* No flags */ #define C_FLAGMAPOUT 0x0001 /* Output mapping data */ #define C_FLAGTREOUT 0x0002 /* Output separator tree data */ #define C_FLAGVERBSTR 0x0004 /* Output strategy string */ #define C_FLAGVERBTIM 0x0008 /* Output timing information */ scotch-6.0.4.dfsg/src/scotch/dgmap.c0000644002563400244210000005025112473176651022416 0ustar trophimeutilisateurs du domaine/* Copyright 2008-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgmap.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a parallel static mapping **/ /** software. **/ /** This module contains the main function. **/ /** **/ /** DATES : # Version 5.0 : from : 12 jun 2008 **/ /** to : 28 aug 2008 **/ /** # Version 5.1 : from : 26 oct 2008 **/ /** to : 31 aug 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DGMAP #define SCOTCH_PTSCOTCH #include #include "module.h" #include "common.h" #include "ptscotch.h" #include "dgmap.h" /* ** The static variables. */ static int C_partNbr = 1; /* Default number of parts / cluster load */ static int C_paraNum = 0; /* Number of parameters */ static int C_paraNbr = 0; /* No parameters for mapping */ static int C_fileNum = 0; /* Number of file in arg list */ static int C_fileNbr = 4; /* Number of files for mapping */ static File C_fileTab[C_FILENBR] = { /* File array */ { "r" }, { "r" }, { "w" }, { "w" } }; static const char * C_usageList[] = { /* Usage */ "dgmap [ [ [ []]]] ", "dgpart [] [ [ []]] ", " -b : Load imbalance tolerance (default: 0.05)", " -c : Choose default mapping strategy according to one or several of :", " b : enforce load balance as much as possible", " q : privilege quality over speed (default)", " s : privilege speed over quality", " t : enforce safety", " x : enforce scalability", " -h : Display this help", " -m : Set parallel mapping strategy (see user's manual)", " -q : Do graph clustering instead of graph partitioning (for dgpart)", " -q : Do graph clustering instead of static mapping (for dgmap)", " -r : Set root process for centralized files (default is 0)", " -s : Force unity weights on :", " e : edges", " v : vertices", " -V : Print program version and copyright", " -v : Set verbose mode to :", " a : memory allocation information", " m : mapping information", " s : strategy information", " t : timing information", "", "See default strategy with option '-vs'", NULL }; /******************************/ /* */ /* This is the main function. */ /* */ /******************************/ int main ( int argc, char * argv[]) { SCOTCH_Dgraph grafdat; /* Source graph */ SCOTCH_Num grafflag; /* Source graph properties */ SCOTCH_Arch archdat; /* Target architecture */ SCOTCH_Dmapping mappdat; /* Mapping data */ SCOTCH_Strat stradat; /* Mapping strategy */ SCOTCH_Num straval; char * straptr; int flagval; double kbalval; /* Imbalance tolerance value */ int procglbnbr; int proclocnum; int protglbnum; /* Root process */ Clock runtime[2]; /* Timing variables */ double reduloctab[12]; /* 3 * (min, max, sum) */ double reduglbtab[12]; MPI_Datatype redutype; MPI_Op reduop; int i, j; #ifdef SCOTCH_PTHREAD int thrdlvlreqval; int thrdlvlproval; #endif /* SCOTCH_PTHREAD */ flagval = C_FLAGNONE; /* Default behavior */ kbalval = 0.05; /* Default imbalance */ straval = 0; /* No strategy flags */ straptr = NULL; #ifdef SCOTCH_COMPILE_PART flagval |= C_FLAGPART; C_paraNbr = 1; /* One more parameter */ C_fileNbr = 3; /* One less file to provide */ errorProg ("dgpart"); #else errorProg ("dgmap"); #endif /* SCOTCH_COMPILE_PART */ #ifdef SCOTCH_PTHREAD thrdlvlreqval = MPI_THREAD_MULTIPLE; if (MPI_Init_thread (&argc, &argv, thrdlvlreqval, &thrdlvlproval) != MPI_SUCCESS) errorPrint ("main: Cannot initialize (1)"); if (thrdlvlreqval > thrdlvlproval) errorPrint ("main: MPI implementation is not thread-safe: recompile without SCOTCH_PTHREAD"); #else /* SCOTCH_PTHREAD */ if (MPI_Init (&argc, &argv) != MPI_SUCCESS) errorPrint ("main: Cannot initialize (2)"); #endif /* SCOTCH_PTHREAD */ MPI_Comm_size (MPI_COMM_WORLD, &procglbnbr); /* Get communicator data */ MPI_Comm_rank (MPI_COMM_WORLD, &proclocnum); protglbnum = 0; /* Assume root process is process 0 */ if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } SCOTCH_randomProc (proclocnum); /* Record process number to initialize pseudo-random seed */ grafflag = 0; /* Use vertex and edge weights */ SCOTCH_stratInit (&stradat); fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_paraNum < C_paraNbr) { /* If number of parameters not reached */ if ((C_partNbr = atoi (argv[i])) < 1) /* Get the number of parts */ errorPrint ("main: invalid number of parts '%s'", argv[i]); C_paraNum ++; continue; /* Process the other parameters */ } if (C_fileNum < C_fileNbr) /* A file name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else errorPrint ("main: too many file names given"); } else { /* If found an option name */ switch (argv[i][1]) { case 'B' : case 'b' : flagval |= C_FLAGKBALVAL; kbalval = atof (&argv[i][2]); if ((kbalval < 0.0) || (kbalval > 1.0) || ((kbalval == 0.0) && ((argv[i][2] != '0') && (argv[i][2] != '.')))) { errorPrint ("main: invalid load imbalance ratio"); } break; case 'C' : case 'c' : /* Strategy selection parameters */ for (j = 2; argv[i][j] != '\0'; j ++) { switch (argv[i][j]) { case 'B' : case 'b' : straval |= SCOTCH_STRATBALANCE; break; case 'Q' : case 'q' : straval |= SCOTCH_STRATQUALITY; break; case 'S' : case 's' : straval |= SCOTCH_STRATSPEED; break; case 'T' : case 't' : straval |= SCOTCH_STRATSAFETY; break; case 'X' : case 'x' : straval |= SCOTCH_STRATSCALABILITY; break; default : errorPrint ("main: invalid strategy selection option '%c'", argv[i][j]); } } break; #ifdef SCOTCH_DEBUG_ALL case 'D' : case 'd' : flagval |= C_FLAGDEBUG; break; #endif /* SCOTCH_DEBUG_ALL */ case 'H' : /* Give the usage message */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'M' : case 'm' : straptr = &argv[i][2]; SCOTCH_stratExit (&stradat); SCOTCH_stratInit (&stradat); SCOTCH_stratDgraphMap (&stradat, straptr); break; case 'Q' : case 'q' : flagval |= C_FLAGCLUSTER; if ((flagval & C_FLAGPART) != 0) { /* If partitioning program */ if (argv[i][2] != '\0') errorPrint ("main: invalid parameter '%s' after '-q' for dgpart", argv[i] + 2); } else { if (argv[i][1] == '\0') errorPrint ("main: missing parameter after '-q' for dgmap"); if ((C_partNbr = atoi (argv[i] + 2)) < 1) /* Get maximum cluster load */ errorPrint ("main: invalid cluster load '%s'", argv[i] + 2); } break; case 'R' : /* Root process (if necessary) */ case 'r' : protglbnum = atoi (&argv[i][2]); if ((protglbnum < 0) || (protglbnum >= procglbnbr) || ((protglbnum == 0) && (argv[i][2] != '0'))) errorPrint ("main: invalid root process number"); break; case 'S' : case 's' : /* Source graph parameters */ for (j = 2; argv[i][j] != '\0'; j ++) { switch (argv[i][j]) { case 'E' : case 'e' : grafflag |= 2; /* Do not load edge weights */ break; case 'V' : case 'v' : grafflag |= 1; /* Do not load vertex weights */ break; default : errorPrint ("main: invalid source graph option '%c'", argv[i][j]); } } break; case 'V' : fprintf (stderr, "dgmap/dgpart, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2008-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); case 'v' : /* Output control info */ for (j = 2; argv[i][j] != '\0'; j ++) { switch (argv[i][j]) { case 'A' : case 'a' : #ifdef COMMON_MEMORY_TRACE flagval |= C_FLAGVERBMEM; #else /* COMMON_MEMORY_TRACE */ errorPrint ("main: not compiled with COMMON_MEMORY_TRACE"); #endif /* COMMON_MEMORY_TRACE */ break; case 'M' : case 'm' : flagval |= C_FLAGVERBMAP; break; case 'S' : case 's' : flagval |= C_FLAGVERBSTR; break; case 'T' : case 't' : flagval |= C_FLAGVERBTIM; break; default : errorPrint ("main: unprocessed parameter '%c' in '%s'", argv[i][j], argv[i]); } } break; default : errorPrint ("main: unprocessed option '%s'", argv[i]); } } } if ((flagval & C_FLAGPART) != 0) { /* If program run as the partitioner */ fileBlockName (C_fileTab, 3) = fileBlockName (C_fileTab, 2); /* Put provided file names at their right place */ fileBlockName (C_fileTab, 2) = fileBlockName (C_fileTab, 1); fileBlockName (C_fileTab, 1) = "-"; } #ifdef SCOTCH_DEBUG_ALL if ((flagval & C_FLAGDEBUG) != 0) { fprintf (stderr, "Proc %4d of %d, pid %d\n", proclocnum, procglbnbr, getpid ()); if (proclocnum == protglbnum) { /* Synchronize on keybord input */ char c; printf ("Waiting for key press...\n"); scanf ("%c", &c); } MPI_Barrier (MPI_COMM_WORLD); } #endif /* SCOTCH_DEBUG_ALL */ fileBlockOpenDist (C_fileTab, C_FILENBR, procglbnbr, proclocnum, protglbnum); /* Open all files */ clockInit (&runtime[0]); clockStart (&runtime[0]); SCOTCH_dgraphInit (&grafdat, MPI_COMM_WORLD); /* Initialize distributed source graph */ SCOTCH_dgraphLoad (&grafdat, C_filepntrsrcinp, -1, 0); SCOTCH_archInit (&archdat); /* Create architecture structure */ if ((flagval & C_FLAGPART) != 0) { /* If program run as the partitioner */ if ((flagval & C_FLAGCLUSTER) != 0) /* If program run as graph clustering */ SCOTCH_archVcmplt (&archdat); /* Create a variable-sized complete graph */ else /* Program is run as plain graph partitioner */ SCOTCH_archCmplt (&archdat, C_partNbr); /* Create a complete graph of proper size */ } else { if (C_filepntrtgtinp == NULL) errorPrint ("main: target architecture file not provided"); SCOTCH_archLoad (&archdat, C_filepntrtgtinp); /* Read target architecture */ if ((flagval & C_FLAGCLUSTER) == 0) /* If part size not to be preserved */ C_partNbr = SCOTCH_archSize (&archdat); else { if (SCOTCH_archVar (&archdat) == 0) errorPrint ("main: non variable-sized architecture provided while '-q' flag set"); } } if (((straval != 0) || ((flagval & C_FLAGKBALVAL) != 0)) && (straptr != NULL)) errorPrint ("main: options '-b' / '-c' and '-m' are exclusive"); if ((flagval & C_FLAGCLUSTER) != 0) /* If clustering wanted */ SCOTCH_stratDgraphClusterBuild (&stradat, straval, (SCOTCH_Num) procglbnbr, (SCOTCH_Num) C_partNbr, 1.0, kbalval); else SCOTCH_stratDgraphMapBuild (&stradat, straval, (SCOTCH_Num) procglbnbr, (SCOTCH_Num) C_partNbr, kbalval); clockStop (&runtime[0]); /* Get input time */ clockInit (&runtime[1]); #ifdef SCOTCH_DEBUG_ALL if ((flagval & C_FLAGDEBUG) != 0) MPI_Barrier (MPI_COMM_WORLD); #endif /* SCOTCH_DEBUG_ALL */ clockStart (&runtime[1]); SCOTCH_dgraphGhst (&grafdat); /* Compute it once for good */ SCOTCH_dgraphMapInit (&grafdat, &mappdat, &archdat, NULL); SCOTCH_dgraphMapCompute (&grafdat, &mappdat, &stradat); /* Perform mapping */ clockStop (&runtime[1]); /* Get computation time */ #ifdef SCOTCH_DEBUG_ALL if ((flagval & C_FLAGDEBUG) != 0) MPI_Barrier (MPI_COMM_WORLD); #endif /* SCOTCH_DEBUG_ALL */ clockStart (&runtime[0]); SCOTCH_dgraphMapSave (&grafdat, &mappdat, (proclocnum == protglbnum) ? C_filepntrmapout : NULL); /* Write mapping */ clockStop (&runtime[0]); /* Get output time */ #ifdef SCOTCH_DEBUG_ALL if ((flagval & C_FLAGDEBUG) != 0) MPI_Barrier (MPI_COMM_WORLD); #endif /* SCOTCH_DEBUG_ALL */ MPI_Type_contiguous (3, MPI_DOUBLE, &redutype); MPI_Type_commit (&redutype); MPI_Op_create ((MPI_User_function *) dgmapStatReduceOp, 1, &reduop); if ((flagval & C_FLAGVERBTIM) != 0) { reduloctab[0] = reduloctab[1] = reduloctab[2] = (double) clockVal (&runtime[1]); reduloctab[3] = reduloctab[4] = reduloctab[5] = (double) clockVal (&runtime[0]); reduloctab[6] = reduloctab[7] = reduloctab[8] = reduloctab[0] + reduloctab[3]; MPI_Allreduce (&reduloctab[0], &reduglbtab[0], 3, redutype, reduop, MPI_COMM_WORLD); } #ifdef COMMON_MEMORY_TRACE if ((flagval & C_FLAGVERBMEM) != 0) { reduloctab[9] = reduloctab[10] = reduloctab[11] = (double) memMax (); MPI_Allreduce (&reduloctab[9], &reduglbtab[9], 1, redutype, reduop, MPI_COMM_WORLD); } #endif /* COMMON_MEMORY_TRACE */ MPI_Op_free (&reduop); MPI_Type_free (&redutype); if (C_filepntrlogout != NULL) { if ((flagval & C_FLAGVERBSTR) != 0) { fprintf (C_filepntrlogout, "S\tStrat="); SCOTCH_stratSave (&stradat, C_filepntrlogout); putc ('\n', C_filepntrlogout); } if ((flagval & C_FLAGVERBTIM) != 0) { fprintf (C_filepntrlogout, "T\tMapping\tmin=%g\tmax=%g\tavg=%g\nT\tI/O\tmin=%g\tmax=%g\tavg=%g\nT\tTotal\tmin=%g\tmax=%g\tavg=%g\n", reduglbtab[0], reduglbtab[1], reduglbtab[2] / (double) procglbnbr, reduglbtab[3], reduglbtab[4], reduglbtab[5] / (double) procglbnbr, reduglbtab[6], reduglbtab[7], reduglbtab[8] / (double) procglbnbr); } #ifdef COMMON_MEMORY_TRACE if ((flagval & C_FLAGVERBMEM) != 0) fprintf (C_filepntrlogout, "A\tMemory\tmin=%g\tmax=%g\tavg=%g\n", reduglbtab[9], reduglbtab[10], reduglbtab[11] / (double) procglbnbr); #endif /* COMMON_MEMORY_TRACE */ } if (flagval & C_FLAGVERBMAP) SCOTCH_dgraphMapView (&grafdat, &mappdat, C_filepntrlogout); fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ SCOTCH_dgraphMapExit (&grafdat, &mappdat); SCOTCH_dgraphExit (&grafdat); SCOTCH_stratExit (&stradat); SCOTCH_archExit (&archdat); MPI_Finalize (); #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } /* Reduction routine for statistics output. */ void dgmapStatReduceOp ( double * in, double * inout, int * len, MPI_Datatype * datatype) { int i; for (i = 0; i < *len; i ++) { inout[3 * i] = MIN (in[3 * i], inout[3 * i]); inout[3 * i + 1] = MAX (in[3 * i + 1], inout[3 * i + 1]); inout[3 * i + 2] = in[3 * i + 2] + inout[3 * i + 2]; } } scotch-6.0.4.dfsg/src/scotch/amk_ccc.c0000644002563400244210000002553012473176651022710 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : amk_ccc.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Creates the distance map for CCC **/ /** graphs, to be used to build the archi- **/ /** tecture description files for these **/ /** graphs. **/ /** **/ /** DATES : # Version 1.3 : from : 24 apr 1994 **/ /** to : 24 apr 1994 **/ /** # Version 2.0 : from : 13 jul 1994 **/ /** to : 12 nov 1994 **/ /** # Version 3.0 : from : 18 sep 1995 **/ /** to : 19 sep 1995 **/ /** # Version 3.2 : from : 07 may 1997 **/ /** to : 07 may 1997 **/ /** # Version 3.3 : from : 02 oct 1998 **/ /** to : 02 oct 1998 **/ /** # Version 3.4 : from : 03 feb 2000 **/ /** to : 03 feb 2000 **/ /** # Version 5.0 : from : 23 dec 2007 **/ /** to : 16 mar 2008 **/ /** # Version 5.1 : from : 01 jul 2010 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define AMK_CCC #include "module.h" #include "common.h" #include "scotch.h" #include "amk_ccc.h" /* ** The static and global definitions. */ static int C_paraNum = 0; /* Number of parameters */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[C_FILENBR] = { /* The file array */ { "w" } }; static C_VertDist * C_distaTab; /* Pointer to distance map table */ static C_Queue C_distaQueue; /* Distance queue */ static const char * C_usageList[] = { /* Usage list */ "amk_ccc [] ", " -h : Display this help", " -V : Print program version and copyright", NULL }; /*************************************************/ /* */ /* The main routine, which computes the distance */ /* triangular table. */ /* */ /*************************************************/ int main ( int argc, char * argv[]) { SCOTCH_Num ccdim; /* Dimension of the graph */ SCOTCH_Num ccnbr; /* Number of vertices */ SCOTCH_Num ccbit; /* Mask variable */ SCOTCH_Num ccmax; /* Maximum terminal */ C_Vertex v, w, x; /* Vertex variables */ SCOTCH_Num d; /* Vertex distance to root */ SCOTCH_Num t; /* Vertex terminal value */ SCOTCH_Num i, j, k; errorProg ("amk_ccc"); ccdim = 2; if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_paraNum < 1) { /* If number of parameters not reached */ if ((ccdim = atoi (argv[i])) < 1) { /* Get the dimension */ errorPrint ("main: invalid dimension '%s'", argv[i]); return (1); } C_paraNum ++; continue; /* Process the other parameters */ } if (C_fileNum < C_FILENBR) /* A file name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else { errorPrint ("main: too many file names given"); return (1); } } else { /* If found an option name */ switch (argv[i][1]) { case 'H' : /* Give the usage message */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'V' : fprintf (stderr, "amk_ccc, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: unprocessed option '%s'", argv[i]); return (1); } } } fileBlockOpen (C_fileTab, C_FILENBR); /* Open all files */ ccnbr = ccdim * (1 << ccdim); /* Compute number of vertices */ ccbit = (1 << ccdim) - 1; /* Get maximum position number */ for (ccmax = ((1 << (ccdim + 1)) - 1), i = ccdim - 1; /* Compute biggest terminal value */ i != 0; i >>= 1) ccmax = (ccmax << 1) | (i & 1); fprintf (C_filepntrarcout, "deco\n0\n" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n", /* Print the file header */ (SCOTCH_Num) ccnbr, /* Print number of terminal domains */ (SCOTCH_Num) ccmax); /* Print biggest terminal value */ for (v.lvl = 0; v.lvl < ccdim; v.lvl ++) { /* For all levels */ for (v.pos = 0; v.pos <= ccbit; v.pos ++) { /* For all positions in these levels */ t = (1 << ccdim) | v.pos; /* Perform the hypercube cuts */ for (i = v.lvl, j = ccdim; j != 1; ) { /* Perform the cycle cuts */ t <<= 1; k = (j + 1) >> 1; if (i >= k) { /* If upper (smallest) half */ t |= 1; i -= k; j -= k; } else /* If lower (biggest) half */ j = k; } fprintf (C_filepntrarcout, SCOTCH_NUMSTRING "\t1\t" SCOTCH_NUMSTRING "\n", (SCOTCH_Num) C_vertLabl (&v), /* Print terminal label */ (SCOTCH_Num) t); /* Print terminal number */ } } if ((C_queueInit (&C_distaQueue, ccmax) != 0) || /* Allocate the distance array */ ((C_distaTab = (C_VertDist *) memAlloc (ccmax * sizeof (C_VertDist))) == NULL)) { errorPrint ("main: out of memory"); return (1); } for (v.lvl = 0; v.lvl < ccdim; v.lvl ++) { /* For all levels */ for (v.pos = 0; v.pos <= ccbit; v.pos ++) { /* For all positions in these levels */ for (i = 0; i < ccnbr; i ++) /* Initialize vertex table */ C_distaTab[i].queued = 0; /* Vertex not queued yet */ C_distaRoot (&v); /* Set the queue with root v */ while (C_distaGet (&w, &d)) { /* As long as the queue is not empty */ C_distaTab[C_vertLabl (&w)].dist = d; /* Keep the distance information */ d ++; /* Search for neighbors at next level */ x.lvl = w.lvl; /* Add neighbors to queue */ x.pos = w.pos ^ (1 << x.lvl); C_distaPut (&x, d); x.lvl = (w.lvl == 0) ? (ccdim - 1) : (w.lvl - 1); x.pos = w.pos; C_distaPut (&x, d); x.lvl = (w.lvl == (ccdim - 1)) ? 0 : (w.lvl + 1); C_distaPut (&x, d); } if (v.lvl + v.pos > 0) { /* Print distance triangular map line */ fprintf (C_filepntrarcout, SCOTCH_NUMSTRING, (SCOTCH_Num) C_distaTab[0].dist); for (i = 1; i < C_vertLabl (&v); i ++) fprintf (C_filepntrarcout, " " SCOTCH_NUMSTRING, (SCOTCH_Num) C_distaTab[i].dist); fprintf (C_filepntrarcout, "\n"); } } } fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ C_queueExit (&C_distaQueue); memFree (C_distaTab); #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } scotch-6.0.4.dfsg/src/scotch/dgscat.c0000644002563400244210000001762412473176651022602 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgscat.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This program distributes a source graph **/ /** across processors and saves it as a **/ /** distributed source graph. **/ /** This module contains the main function. **/ /** **/ /** DATES : # Version 5.0 : from : 17 may 2007 **/ /** to : 16 jun 2008 **/ /** # Version 5.1 : from : 01 jul 2010 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DGSCAT #define SCOTCH_PTSCOTCH #include "module.h" #include "common.h" #include "ptscotch.h" #include "dgscat.h" /* ** The static and global definitions. */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[C_FILENBR] = { /* File array */ { "r" }, { "w" } }; static const char * C_usageList[] = { "dgscat [ []] ", " -c : Check the input graph after loading", " -h : Display this help", " -r : Set root process for centralized files (default is 0)", " -V : Print program version and copyright", NULL }; /*********************/ /* */ /* The main routine. */ /* */ /*********************/ int main ( int argc, char * argv[]) { SCOTCH_Dgraph grafdat; int procglbnbr; int proclocnum; int protglbnum; /* Root process */ int flagval; int i; #ifdef SCOTCH_PTHREAD int thrdlvlreqval; int thrdlvlproval; #endif /* SCOTCH_PTHREAD */ errorProg ("dgscat"); #ifdef SCOTCH_PTHREAD thrdlvlreqval = MPI_THREAD_MULTIPLE; if (MPI_Init_thread (&argc, &argv, thrdlvlreqval, &thrdlvlproval) != MPI_SUCCESS) errorPrint ("main: Cannot initialize (1)"); if (thrdlvlreqval > thrdlvlproval) errorPrint ("main: MPI implementation is not thread-safe: recompile without SCOTCH_PTHREAD"); #else /* SCOTCH_PTHREAD */ if (MPI_Init (&argc, &argv) != MPI_SUCCESS) errorPrint ("main: Cannot initialize (2)"); #endif /* SCOTCH_PTHREAD */ MPI_Comm_size (MPI_COMM_WORLD, &procglbnbr); /* Get communicator data */ MPI_Comm_rank (MPI_COMM_WORLD, &proclocnum); protglbnum = 0; /* Assume root process is process 0 */ if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } flagval = C_FLAGNONE; fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_fileNum < C_FILEARGNBR) /* File name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else errorPrint ("main: too many file names given"); } else { /* If found an option name */ switch (argv[i][1]) { case 'C' : case 'c' : flagval |= C_FLAGCHECK; break; #ifdef SCOTCH_DEBUG_ALL case 'D' : case 'd' : flagval |= C_FLAGDEBUG; break; #endif /* SCOTCH_DEBUG_ALL */ case 'H' : /* Give the usage message */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'R' : /* Root process (if necessary) */ case 'r' : protglbnum = atoi (&argv[i][2]); if ((protglbnum < 0) || (protglbnum >= procglbnbr) || ((protglbnum == 0) && (argv[i][2] != '0'))) errorPrint ("main: invalid root process number"); break; case 'V' : case 'v' : fprintf (stderr, "dgscat, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: unprocessed option '%s'", argv[i]); } } } #ifdef SCOTCH_DEBUG_ALL if ((flagval & C_FLAGDEBUG) != 0) { fprintf (stderr, "Proc %4d of %d, pid %d\n", proclocnum, procglbnbr, getpid ()); if (proclocnum == protglbnum) { /* Synchronize on keybord input */ char c; printf ("Waiting for key press...\n"); scanf ("%c", &c); } MPI_Barrier (MPI_COMM_WORLD); } #endif /* SCOTCH_DEBUG_ALL */ fileBlockOpenDist (C_fileTab, C_FILENBR, procglbnbr, proclocnum, protglbnum); /* Open all files */ SCOTCH_dgraphInit (&grafdat, MPI_COMM_WORLD); SCOTCH_dgraphLoad (&grafdat, C_filepntrsrcinp, -1, 0); if ((flagval & C_FLAGCHECK) != 0) SCOTCH_dgraphCheck (&grafdat); SCOTCH_dgraphSave (&grafdat, C_filepntrsrcout); fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ SCOTCH_dgraphExit (&grafdat); MPI_Finalize (); #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } scotch-6.0.4.dfsg/src/scotch/dgtst.c0000644002563400244210000002234512473176651022456 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgtst.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This program gives statistics on **/ /** distributed source graphs. **/ /** **/ /** DATES : # Version 5.0 : from : 23 jun 2007 **/ /** to : 16 jun 2008 **/ /** # Version 5.1 : from : 26 oct 2008 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define DGTST #define SCOTCH_PTSCOTCH #include "module.h" #include "common.h" #include "ptscotch.h" #include "dgtst.h" /* ** The static and global definitions. */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[C_FILENBR] = { /* File array */ { "r" }, { "w" } }; static const char * C_usageList[] = { "dgtst [ []] ", " -h : Display this help", " -r : Set root process for centralized files (default is 0)", " -V : Print program version and copyright", NULL }; /*********************/ /* */ /* The main routine. */ /* */ /*********************/ int main ( int argc, char * argv[]) { SCOTCH_Dgraph grafdat; int procglbnbr; int proclocnum; int protglbnum; /* Root process */ SCOTCH_Num vertnbr; SCOTCH_Num velomin; SCOTCH_Num velomax; SCOTCH_Num velosum; double veloavg; double velodlt; SCOTCH_Num degrmin; SCOTCH_Num degrmax; double degravg; double degrdlt; SCOTCH_Num edgenbr; SCOTCH_Num edlomin; SCOTCH_Num edlomax; SCOTCH_Num edlosum; double edloavg; double edlodlt; int flagval; int i; #ifdef SCOTCH_PTHREAD int thrdlvlreqval; int thrdlvlproval; #endif /* SCOTCH_PTHREAD */ errorProg ("dgtst"); #ifdef SCOTCH_PTHREAD thrdlvlreqval = MPI_THREAD_MULTIPLE; if (MPI_Init_thread (&argc, &argv, thrdlvlreqval, &thrdlvlproval) != MPI_SUCCESS) errorPrint ("main: Cannot initialize (1)"); if (thrdlvlreqval > thrdlvlproval) errorPrint ("main: MPI implementation is not thread-safe: recompile without SCOTCH_PTHREAD"); #else /* SCOTCH_PTHREAD */ if (MPI_Init (&argc, &argv) != MPI_SUCCESS) errorPrint ("main: Cannot initialize (2)"); #endif /* SCOTCH_PTHREAD */ MPI_Comm_size (MPI_COMM_WORLD, &procglbnbr); /* Get communicator data */ MPI_Comm_rank (MPI_COMM_WORLD, &proclocnum); protglbnum = 0; /* Assume root process is process 0 */ if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } flagval = C_FLAGNONE; fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '+') && /* If found a file name */ ((argv[i][0] != '-') || (argv[i][1] == '\0'))) { if (C_fileNum < C_FILEARGNBR) /* A file name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else errorPrint ("main: too many file names given"); } else { /* If found an option name */ switch (argv[i][1]) { #ifdef SCOTCH_DEBUG_ALL case 'D' : case 'd' : flagval |= C_FLAGDEBUG; break; #endif /* SCOTCH_DEBUG_ALL */ case 'H' : /* Give the usage message */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'R' : /* Root process (if necessary) */ case 'r' : protglbnum = atoi (&argv[i][2]); if ((protglbnum < 0) || (protglbnum >= procglbnbr) || ((protglbnum == 0) && (argv[i][2] != '0'))) errorPrint ("main: invalid root process number"); break; case 'V' : case 'v' : fprintf (stderr, "dgtst, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: unprocessed option '%s'", argv[i]); } } } #ifdef SCOTCH_DEBUG_ALL if ((flagval & C_FLAGDEBUG) != 0) { fprintf (stderr, "Proc %4d of %d, pid %d\n", proclocnum, procglbnbr, getpid ()); if (proclocnum == protglbnum) { /* Synchronize on keybord input */ char c; printf ("Waiting for key press...\n"); scanf ("%c", &c); } MPI_Barrier (MPI_COMM_WORLD); } #endif /* SCOTCH_DEBUG_ALL */ fileBlockOpenDist (C_fileTab, C_FILENBR, procglbnbr, proclocnum, protglbnum); /* Open all files */ SCOTCH_dgraphInit (&grafdat, MPI_COMM_WORLD); SCOTCH_dgraphLoad (&grafdat, C_filepntrsrcinp, -1, 0); SCOTCH_dgraphCheck (&grafdat); SCOTCH_dgraphSize (&grafdat, &vertnbr, NULL, &edgenbr, NULL); SCOTCH_dgraphStat (&grafdat, &velomin, &velomax, &velosum, &veloavg, &velodlt, °rmin, °rmax, °ravg, °rdlt, &edlomin, &edlomax, &edlosum, &edloavg, &edlodlt); if (C_filepntrdatout != NULL) { fprintf (C_filepntrdatout, "S\tVertex\tnbr=" SCOTCH_NUMSTRING "\n", (SCOTCH_Num) vertnbr); fprintf (C_filepntrdatout, "S\tVertex load\tmin=" SCOTCH_NUMSTRING "\tmax=" SCOTCH_NUMSTRING "\tsum=" SCOTCH_NUMSTRING "\tavg=%g\tdlt=%g\n", (SCOTCH_Num) velomin, (SCOTCH_Num) velomax, (SCOTCH_Num) velosum, veloavg, velodlt); fprintf (C_filepntrdatout, "S\tVertex degree\tmin=" SCOTCH_NUMSTRING "\tmax=" SCOTCH_NUMSTRING "\tsum=" SCOTCH_NUMSTRING "\tavg=%g\tdlt=%g\n", (SCOTCH_Num) degrmin, (SCOTCH_Num) degrmax, (SCOTCH_Num) edgenbr, degravg, degrdlt); fprintf (C_filepntrdatout, "S\tEdge\tnbr=" SCOTCH_NUMSTRING "\n", (SCOTCH_Num) (edgenbr / 2)); fprintf (C_filepntrdatout, "S\tEdge load\tmin=" SCOTCH_NUMSTRING "\tmax=" SCOTCH_NUMSTRING "\tsum=" SCOTCH_NUMSTRING "\tavg=%g\tdlt=%g\n", (SCOTCH_Num) edlomin, (SCOTCH_Num) edlomax, (SCOTCH_Num) edlosum, edloavg, edlodlt); } fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ SCOTCH_dgraphExit (&grafdat); MPI_Finalize (); #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } scotch-6.0.4.dfsg/src/scotch/Makefile0000644002563400244210000002711012473176660022620 0ustar trophimeutilisateurs du domaine## Copyright 2004,2007-2012 IPB, Universite de Bordeaux, INRIA & CNRS ## ## This file is part of the Scotch software package for static mapping, ## graph partitioning and sparse matrix ordering. ## ## This software is governed by the CeCILL-C license under French law ## and abiding by the rules of distribution of free software. You can ## use, modify and/or redistribute the software under the terms of the ## CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ## URL: "http://www.cecill.info". ## ## As a counterpart to the access to the source code and rights to copy, ## modify and redistribute granted by the license, users are provided ## only with a limited warranty and the software's author, the holder of ## the economic rights, and the successive licensors have only limited ## liability. ## ## In this respect, the user's attention is drawn to the risks associated ## with loading, using, modifying and/or developing or reproducing the ## software by the user in light of its specific status of free software, ## that may mean that it is complicated to manipulate, and that also ## therefore means that it is reserved for developers and experienced ## professionals having in-depth computer knowledge. Users are therefore ## encouraged to load and test the software's suitability as regards ## their requirements in conditions enabling the security of their ## systems and/or data to be ensured and, more generally, to use and ## operate it in the same conditions as regards security. ## ## The fact that you are presently reading this means that you have had ## knowledge of the CeCILL-C license and that you accept its terms. ## bindir = ../../bin includedir = ../../include libdir = ../../lib ## ## General inference rules. ## include ../Makefile.inc %$(EXE) : %$(OBJ) $(CC) $(CFLAGS) -I$(includedir) -I../libscotch $(<) -o $(@) -L$(libdir) -l$(SCOTCHLIB) -lscotch -l$(SCOTCHLIB)errexit $(LDFLAGS) %$(OBJ) : %.c $(CC) $(CFLAGS) -I$(includedir) -I../libscotch -c $(<) -o $(@) %$(EXE) : %.c $(CC) $(CFLAGS) -I$(includedir) -I../libscotch $(<) -o $(@) -L$(libdir) -l$(SCOTCHLIB) -lscotch -l$(SCOTCHLIB)errexit $(LDFLAGS) ## ## Project rules. ## .PHONY : ptscotch scotch ptinstall install clean realclean scotch : $(MAKE) CC="$(CCS)" SCOTCHLIB=scotch \ acpl$(EXE) \ amk_ccc$(EXE) \ amk_fft2$(EXE) \ amk_grf$(EXE) \ amk_hy$(EXE) \ amk_m2$(EXE) \ amk_p2$(EXE) \ atst$(EXE) \ gbase$(EXE) \ gcv$(EXE) \ gmap$(EXE) \ gmk_hy$(EXE) \ gmk_m2$(EXE) \ gmk_m3$(EXE) \ gmk_msh$(EXE) \ gmk_ub2$(EXE) \ gmtst$(EXE) \ gord$(EXE) \ gotst$(EXE) \ gout$(EXE) \ gpart$(EXE) \ gscat$(EXE) \ gtst$(EXE) \ mcv$(EXE) \ mmk_m2$(EXE) \ mmk_m3$(EXE) \ mord$(EXE) \ mtst$(EXE) ptscotch : $(MAKE) CC="$(CCP)" SCOTCHLIB=ptscotch \ dggath$(EXE) \ dgmap$(EXE) \ dgord$(EXE) \ dgpart$(EXE) \ dgscat$(EXE) \ dgtst$(EXE) install : scotch -$(CP) acpl$(EXE) amk_ccc$(EXE) amk_fft2$(EXE) amk_grf$(EXE) amk_hy$(EXE) amk_m2$(EXE) amk_p2$(EXE) atst$(EXE) gbase$(EXE) gcv$(EXE) gmap$(EXE) gmk_hy$(EXE) gmk_m2$(EXE) gmk_m3$(EXE) gmk_msh$(EXE) gmk_ub2$(EXE) gmtst$(EXE) gord$(EXE) gotst$(EXE) gout$(EXE) gpart$(EXE) *gtst$(EXE) gscat$(EXE) mcv$(EXE) mmk_m2$(EXE) mmk_m3$(EXE) mord$(EXE) mtst$(EXE) $(bindir) ptinstall : ptscotch -$(CP) dggath$(EXE) dgmap$(EXE) dgord$(EXE) dgpart$(EXE) dgscat$(EXE) dgtst$(EXE) $(bindir) clean : -$(RM) *~ *$(OBJ) acpl$(EXE) amk_ccc$(EXE) amk_fft2$(EXE) amk_grf$(EXE) amk_hy$(EXE) amk_m2$(EXE) amk_p2$(EXE) atst$(EXE) gbase$(EXE) gcv$(EXE) *ggath$(EXE) *gmap$(EXE) gmk_hy$(EXE) gmk_m2$(EXE) gmk_m3$(EXE) gmk_msh$(EXE) gmk_ub2$(EXE) gmtst$(EXE) *gord$(EXE) gotst$(EXE) gout$(EXE) *gpart$(EXE) *gscat$(EXE) *gtst$(EXE) mcv$(EXE) mmk_m2$(EXE) mmk_m3$(EXE) mord$(EXE) mtst$(EXE) realclean : clean ## ## Todo list. ## acpl$(EXE) : acpl.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ acpl.h amk_ccc$(EXE) : amk_ccc.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ amk_ccc.h amk_fft2$(EXE) : amk_fft2.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ amk_fft2.h amk_grf$(EXE) : amk_grf.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ amk_grf.h amk_hy$(EXE) : amk_hy.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ amk_hy.h amk_m2$(EXE) : amk_m2.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ amk_m2.h amk_p2$(EXE) : amk_p2.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ amk_p2.h atst$(EXE) : atst.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ atst.h dggath$(EXE) : dggath.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/ptscotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libptscotch$(LIB) \ $(libdir)/libptscotcherrexit$(LIB) \ dggath.h dgmap$(EXE) : dgmap.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/ptscotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libptscotch$(LIB) \ $(libdir)/libptscotcherrexit$(LIB) \ dgmap.h dgord$(EXE) : dgord.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/ptscotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libptscotch$(LIB) \ $(libdir)/libptscotcherrexit$(LIB) \ dgord.h dgpart$(EXE) : dgmap.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/ptscotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libptscotch$(LIB) \ $(libdir)/libptscotcherrexit$(LIB) \ dgmap.h $(CC) $(CFLAGS) -I$(includedir) -I../libscotch $(<) -DSCOTCH_COMPILE_PART -o $(@) -L$(libdir) -lptscotch -lscotch -lptscotcherrexit $(LDFLAGS) dgscat$(EXE) : dgscat.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/ptscotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libptscotch$(LIB) \ $(libdir)/libptscotcherrexit$(LIB) \ dgscat.h dgtst$(EXE) : dgtst.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/ptscotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libptscotch$(LIB) \ $(libdir)/libptscotcherrexit$(LIB) \ dgtst.h gbase$(EXE) : gbase.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ gbase.h gcv$(EXE) : gcv.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ gcv.h gmap$(EXE) : gmap.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ gmap.h gmk_hy$(EXE) : gmk_hy.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ gmk_hy.h gmk_m2$(EXE) : gmk_m2.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ gmk_m2.h gmk_m3$(EXE) : gmk_m3.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ gmk_m3.h gmk_msh$(EXE) : gmk_msh.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ gmk_msh.h gmk_ub2$(EXE) : gmk_ub2.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ gmk_ub2.h gmtst$(EXE) : gmtst.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ gmtst.h gord$(EXE) : gord.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ gord.h gotst$(EXE) : gotst.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ gotst.h gout$(EXE) : gout_c.c \ gout_o.c \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) $(CC) $(CFLAGS) -I../libscotch -I$(includedir) gout_c.c gout_o.c -o $(@) -L$(libdir) -lscotch -lscotcherrexit $(LDFLAGS) gpart$(EXE) : gmap.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ gmap.h $(CC) $(CFLAGS) -I$(includedir) -I../libscotch $(<) -DSCOTCH_COMPILE_PART -o $(@) -L$(libdir) -lscotch -lscotcherrexit $(LDFLAGS) gscat$(EXE) : gscat.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ gscat.h gtst$(EXE) : gtst.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ gtst.h mcv$(EXE) : mcv.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ mcv.h mmk_m2$(EXE) : mmk_m2.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ mmk_m2.h mmk_m3$(EXE) : mmk_m3.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ mmk_m3.h mord$(EXE) : mord.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ mord.h mtst$(EXE) : mtst.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ $(libdir)/libscotch$(LIB) \ $(libdir)/libscotcherrexit$(LIB) \ mtst.h scotch-6.0.4.dfsg/src/scotch/gout_c.h0000644002563400244210000002057612473176651022622 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gout_c.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a result viewer. **/ /** This module contains the data declara- **/ /** tions for the main module. **/ /** **/ /** DATES : # Version 2.0 : from : 06 oct 1994 **/ /** to 01 nov 1994 **/ /** # Version 3.0 : from : 14 jul 1995 **/ /** to 02 oct 1995 **/ /** # Version 3.2 : from : 02 dec 1996 **/ /** to 05 jun 1998 **/ /** # Version 3.3 : from : 01 jun 1999 **/ /** to 01 jun 1999 **/ /** # Version 4.0 : from : 11 dec 2001 **/ /** to 11 dec 2001 **/ /** # Version 5.0 : from : 13 dec 2007 **/ /** to 15 mar 2008 **/ /** # Version 6.0 : from : 12 nov 2014 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ File name aliases. +*/ #define C_FILENBR 4 /* Number of files in list */ #define C_FILEARGNBR 4 /* Number of files which can be arguments */ #define C_filenamesrcinp fileBlockName (C_fileTab, 0) /* Source graph file name */ #define C_filenamegeoinp fileBlockName (C_fileTab, 1) /* Source graph geometry file name */ #define C_filenamemapinp fileBlockName (C_fileTab, 2) /* Mapping result file name */ #define C_filenamedatout fileBlockName (C_fileTab, 3) /* Output data file name */ #define C_filepntrsrcinp fileBlockFile (C_fileTab, 0) /* Source graph input file */ #define C_filepntrgeoinp fileBlockFile (C_fileTab, 1) /* Source graph geometry file */ #define C_filepntrmapinp fileBlockFile (C_fileTab, 2) /* Mapping result input file */ #define C_filepntrdatout fileBlockFile (C_fileTab, 3) /* Data output file */ #define C_filemodemapinp fileBlockMode (C_fileTab, 2) /* Mapping result mode */ /*+ Dimension definitions. +*/ #define x c[0] #define y c[1] #define z c[2] /*+ Geometry flags. +*/ #define C_GEOFLAGDEFAULT 0x0001 /* Default geometry flag */ #define C_GEOFLAGUSE 0x0001 /* Use geometry */ #define C_GEOFLAGROTATE 0x0002 /* Rotate the picture by 90 degrees */ #define C_GEOFLAGPERMUT 0x0004 /* Permute Y and Z dimensions */ /* ** The type and structure definitions. */ /*+ This structure defines a source graph. +*/ typedef struct C_Graph_ { SCOTCH_Graph grafdat; /*+ Source graph data +*/ SCOTCH_Num baseval; /*+ Base value +*/ SCOTCH_Num vertnbr; /*+ Number of vertices +*/ SCOTCH_Num * verttab; /*+ Vertex array +*/ SCOTCH_Num * vendtab; /*+ Vertex end array +*/ SCOTCH_Num * vlbltab; /*+ Vertex label array +*/ SCOTCH_Num edgenbr; /*+ Number of edges +*/ SCOTCH_Num * edgetab; /*+ Edge array +*/ } C_Graph; /*+ This structure defines a geometrical vertex. +*/ typedef struct C_GeoVert_ { double c[3]; /*+ Vertex coordinates (x,y,z) +*/ } C_GeoVert; /*+ This structure defines a geometrical mapping which contains the positions of the graph vertices. +*/ typedef struct C_Geometry_ { const C_Graph * grafptr; /*+ Pointer to source graph +*/ C_GeoVert * verttab; /*+ Pointer to coordinates array +*/ } C_Geometry; /*+ This structure defines a domain label mapping, which contains the reference to the mapping source graph. +*/ typedef struct C_Mapping_ { const C_Graph * grafptr; /*+ Pointer to source graph +*/ SCOTCH_Num * labltab; /*+ Pointer to label array +*/ } C_Mapping; /*+ The sort structure, used to sort graph vertices by label. +*/ typedef struct C_VertSort_ { SCOTCH_Num labl; /*+ Vertex label +*/ SCOTCH_Num num; /*+ Vertex number +*/ } C_VertSort; /*+ This structure is the code name array entries. +*/ typedef struct C_ParseCode_ { int code; /*+ Code value +*/ char * name; /*+ Code name +*/ } C_ParseCode; /* This structure defines the code argument array entries. */ typedef struct C_ParseArg_ { const char * name; /*+ Name of the argument +*/ int code; /*+ Code value +*/ const char * format; /*+ scanf-like format; NULL means char, no value +*/ const void * ptr; /*+ Pointer to the argument location +*/ int (* func) (); /*+ Pointer to the argument test function +*/ } C_ParseArg; /* ** The global data declarations. */ extern File C_fileTab[C_FILENBR]; /*+ File array +*/ /* ** The function prototypes. */ int C_geoParse (const char * const); void C_geoInit (C_Geometry * const, const C_Graph * const); void C_geoExit (C_Geometry * const); int C_geoLoad (C_Geometry * const, FILE * const); void C_mapInit (C_Mapping * const, const C_Graph * const); void C_mapExit (C_Mapping * const); int C_mapLoad (C_Mapping * const, FILE * const); int C_parse (const C_ParseCode * const, const C_ParseArg * const, int * const, char * const); scotch-6.0.4.dfsg/src/scotch/mord.c0000644002563400244210000003011612473176651022265 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mord.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a mesh reordering software. **/ /** This module contains the main function. **/ /** **/ /** DATES : # Version 4.0 : from : 15 nov 2002 **/ /** to : 06 jan 2006 **/ /** # Version 5.0 : from : 22 jan 2008 **/ /** to : 16 mar 2008 **/ /** # Version 5.1 : from : 08 sep 2008 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define MORD #include "module.h" #include "common.h" #include "scotch.h" #include "mord.h" /* ** The static and global definitions. */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[C_FILENBR] = { /* File array */ { "r" }, { "w" }, { "w" }, { "w" } }; static const char * C_usageList[] = { "mord [ [ []]] ", " -c : Choose default ordering strategy according to one or several of :", " b : enforce load balance as much as possible", " q : privilege quality over speed (default)", " s : privilege speed over quality", " t : enforce safety", " -h : Display this help", " -m : Save column block mapping data to ", " -o : Use mesh ordering strategy (see user's manual)", " (see default strategy with option '-vs')", " -t : Save partitioning tree data to ", " -V : Print program version and copyright", " -v : Set verbose mode to :", " s : strategy information", " t : timing information", NULL }; /******************************/ /* */ /* This is the main function. */ /* */ /******************************/ int main ( int argc, char * argv[]) { SCOTCH_Num vnodnbr; /* Number of nodes */ SCOTCH_Mesh meshdat; /* Source graph */ SCOTCH_Ordering ordedat; /* Graph ordering */ SCOTCH_Num * permtab; /* Permutation array */ SCOTCH_Strat stradat; /* Ordering strategy */ SCOTCH_Num straval; char * straptr; int flagval; Clock runtime[2]; /* Timing variables */ int i, j; errorProg ("mord"); if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } flagval = C_FLAGNONE; /* Default behavior */ straval = 0; /* No strategy flags */ straptr = NULL; SCOTCH_stratInit (&stradat); fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_fileNum < C_FILEARGNBR) /* File name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else { errorPrint ("main: too many file names given"); return (1); } } else { /* If found an option name */ switch (argv[i][1]) { case 'C' : case 'c' : /* Strategy selection parameters */ for (j = 2; argv[i][j] != '\0'; j ++) { switch (argv[i][j]) { case 'B' : case 'b' : straval |= SCOTCH_STRATBALANCE; break; case 'Q' : case 'q' : straval |= SCOTCH_STRATQUALITY; break; case 'S' : case 's' : straval |= SCOTCH_STRATSPEED; break; case 'T' : case 't' : straval |= SCOTCH_STRATSAFETY; break; default : errorPrint ("main: invalid strategy selection option '%c'", argv[i][j]); } } break; case 'H' : /* Give the usage message */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'M' : /* Output separator mapping */ case 'm' : flagval |= C_FLAGMAPOUT; if (argv[i][2] != '\0') C_filenamemapout = &argv[i][2]; break; case 'O' : /* Ordering strategy */ case 'o' : straptr = &argv[i][2]; SCOTCH_stratExit (&stradat); SCOTCH_stratInit (&stradat); if ((SCOTCH_stratMeshOrder (&stradat, straptr)) != 0) { errorPrint ("main: invalid ordering strategy"); return (1); } break; case 'V' : fprintf (stderr, "mord, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); break; case 'v' : /* Output control info */ for (j = 2; argv[i][j] != '\0'; j ++) { switch (argv[i][j]) { case 'S' : case 's' : flagval |= C_FLAGVERBSTR; break; case 'T' : case 't' : flagval |= C_FLAGVERBTIM; break; default : errorPrint ("main: unprocessed parameter '%c' in '%s'", argv[i][j], argv[i]); return (1); } } break; default : errorPrint ("main: unprocessed option '%s'", argv[i]); return (1); } } } fileBlockOpen (C_fileTab, C_FILENBR); /* Open all files */ clockInit (&runtime[0]); clockStart (&runtime[0]); SCOTCH_meshInit (&meshdat); /* Create mesh structure */ SCOTCH_meshLoad (&meshdat, C_filepntrsrcinp, -1); /* Read source mesh */ SCOTCH_meshSize (&meshdat, NULL, &vnodnbr, NULL); /* Get number of nodes */ if (straval != 0) { if (straptr != NULL) errorPrint ("main: options '-c' and '-o' are exclusive"); SCOTCH_stratMeshOrderBuild (&stradat, straval, 0.1); } clockStop (&runtime[0]); /* Get input time */ clockInit (&runtime[1]); clockStart (&runtime[1]); if ((permtab = (SCOTCH_Num *) memAlloc (vnodnbr * sizeof (SCOTCH_Num))) == NULL) { errorPrint ("main: out of memory"); return (1); } SCOTCH_meshOrderInit (&meshdat, &ordedat, permtab, NULL, NULL, NULL, NULL); /* Create ordering */ SCOTCH_meshOrderCompute (&meshdat, &ordedat, &stradat); /* Perform ordering */ clockStop (&runtime[1]); /* Get ordering time */ #ifdef SCOTCH_DEBUG_ALL if (SCOTCH_meshOrderCheck (&meshdat, &ordedat) != 0) return (1); #endif /* SCOTCH_DEBUG_ALL */ clockStart (&runtime[0]); SCOTCH_meshOrderSave (&meshdat, &ordedat, C_filepntrordout); /* Write ordering */ if (flagval & C_FLAGMAPOUT) /* If mapping wanted */ SCOTCH_meshOrderSaveMap (&meshdat, &ordedat, C_filepntrmapout); /* Write mapping */ clockStop (&runtime[0]); /* Get output time */ if (flagval & C_FLAGVERBSTR) { fprintf (C_filepntrlogout, "S\tStrat="); SCOTCH_stratSave (&stradat, C_filepntrlogout); putc ('\n', C_filepntrlogout); } if (flagval & C_FLAGVERBTIM) { fprintf (C_filepntrlogout, "T\tOrder\t\t%g\nT\tI/O\t\t%g\nT\tTotal\t\t%g\n", (double) clockVal (&runtime[1]), (double) clockVal (&runtime[0]), (double) clockVal (&runtime[0]) + (double) clockVal (&runtime[1])); } fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ SCOTCH_meshOrderExit (&meshdat, &ordedat); SCOTCH_stratExit (&stradat); SCOTCH_meshExit (&meshdat); memFree (permtab); #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } /*******************************************/ /* */ /* Stubs to avoid including target module. */ /* */ /*******************************************/ SCOTCH_Num T_domWght ( const void * const arch, const void * const dom) { errorPrint ("T_domWghtMord: internal error"); return (1); } SCOTCH_Num _SCOTCHTdomWght ( const void * const arch, const void * const dom) { errorPrint ("T_domWghtMord: internal error"); return (1); } SCOTCH_Num T_domDist ( const void * const arch, const void * const dom0, const void * const dom1) { errorPrint ("T_domDistMord: internal error"); return (1); } SCOTCH_Num _SCOTCHTdomDist ( const void * const arch, const void * const dom0, const void * const dom1) { errorPrint ("T_domDistMord: internal error"); return (1); } scotch-6.0.4.dfsg/src/scotch/mmk_m3.h0000644002563400244210000000665012473176651022522 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mmk_m3.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the data declara- **/ /** tions for the tridimensional finite **/ /** element grid mesh building program. **/ /** **/ /** DATES : # Version 4.0 : from : 26 sep 2002 **/ /** to : 26 sep 2002 **/ /** # Version 6.0 : from : 12 nov 2014 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ File name aliases. +*/ #define C_FILENBR 2 /* Number of files in list */ #define C_FILEARGNBR 1 /* Number of files which can be arguments */ #define C_filenamemshout fileBlockName (C_fileTab, 0) /* Source mesh output file name */ #define C_filenamegeoout fileBlockName (C_fileTab, 1) /* Geometry mesh output file name */ #define C_filepntrmshout fileBlockFile (C_fileTab, 0) /* Source mesh output file */ #define C_filepntrgeoout fileBlockFile (C_fileTab, 1) /* Geometry mesh output file */ /*+ Process flags. +*/ #define C_FLAGGEOOUT 0x0001 /* Output mesh geometry */ #define C_FLAGDEFAULT 0x0000 /* Default flags */ scotch-6.0.4.dfsg/src/scotch/dgtst.h0000644002563400244210000000706512473176651022465 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgtst.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a parallel sparse matrix **/ /** ordering software. **/ /** This module contains the data declara- **/ /** tions for the distributed source graph **/ /** analyzer. **/ /** **/ /** DATES : # Version 5.0 : from : 23 jun 2007 **/ /** to : 24 jun 2007 **/ /** # Version 6.0 : from : 10 nov 2014 **/ /** to : 10 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ File name aliases. +*/ #define C_FILENBR 2 /* Number of files in list */ #define C_FILEARGNBR 2 /* Number of files which can be arguments */ #define C_filenamesrcinp fileBlockName (C_fileTab, 0) /* Source graph input file name */ #define C_filenamedatout fileBlockName (C_fileTab, 1) /* Statistics output file name */ #define C_filepntrsrcinp fileBlockFile (C_fileTab, 0) /* Source graph input file */ #define C_filepntrdatout fileBlockFile (C_fileTab, 1) /* Statistics output file */ /*+ Process flags. +*/ #define C_FLAGNONE 0x0000 /* No flags */ #define C_FLAGDEBUG 0x0001 /* Enable easy debugger attachment */ scotch-6.0.4.dfsg/src/scotch/amk_ccc.h0000644002563400244210000001404012473176651022707 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : amk_ccc.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Creates the distance map for CCC **/ /** graphs, to be used to build the **/ /** architecture description files for **/ /** these graphs. **/ /** **/ /** DATES : # Version 1.3 : from : 24 apr 1994 **/ /** to : 24 apr 1994 **/ /** # Version 2.0 : from : 13 jul 1994 **/ /** to : 18 jul 1994 **/ /** # Version 3.0 : from : 18 sep 1995 **/ /** to : 18 sep 1995 **/ /** # Version 3.2 : from : 07 may 1997 **/ /** to : 07 may 1997 **/ /** # Version 3.3 : from : 02 oct 1998 **/ /** to : 02 oct 1998 **/ /** # Version 6.0 : from : 12 nov 2014 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ File name aliases. +*/ #define C_FILENBR 1 /* Number of files in list */ #define C_filenamearcout fileBlockName (C_fileTab, 0) /* Architecture output file name */ #define C_filepntrarcout fileBlockFile (C_fileTab, 0) /* Architecture output file */ /* ** The type and structure definitions. */ /*+ This structure defines a CCC vertex. +*/ typedef struct C_Vertex_ { SCOTCH_Num lvl; /*+ Vertex level +*/ SCOTCH_Num pos; /*+ Vertex position +*/ } C_Vertex; /*+ This structure defines a vertex distance information. +*/ typedef struct C_VertDist_ { int queued; /*+ Flag set if vertex queued +*/ SCOTCH_Num dist; /*+ Distance to initial vertex +*/ } C_VertDist; /*+ This is a neighbor queue element. +*/ typedef struct C_QueueElem_ { C_Vertex vert; /*+ Vertex number +*/ SCOTCH_Num dist; /*+ Distance reached +*/ } C_QueueElem; /*+ This is the distance queue. +*/ typedef struct C_Queue_ { C_QueueElem * tab; /*+ Pointer to queue data +*/ SCOTCH_Num min; /*+ Pointer to first element +*/ SCOTCH_Num max; /*+ Pointer to last element +*/ } C_Queue; /* ** The macro definitions. */ #define C_vertLabl(v) (((v)->lvl << ccdim) | (v)->pos) #define C_queueInit(q,n) ((((q)->tab = (C_QueueElem *) memAlloc ((n) * sizeof (C_QueueElem))) == NULL) ? 1 : 0) #define C_queueExit(q) memFree ((q)->tab) #define C_queueFlush(q) (q)->min = \ (q)->max = 0 #define C_queuePut(q,v,d) ((q)->tab[(q)->max].vert = *(v), \ (q)->tab[(q)->max ++].dist = (d)) #define C_queueGet(q,v,d) (((q)->min < (q)->max) ? (*(v) = (q)->tab[(q)->min].vert, \ *(d) = (q)->tab[(q)->min ++].dist, \ 1) \ : 0) #define C_distaRoot(v) (C_queueFlush (&C_distaQueue), \ C_queuePut (&C_distaQueue, (v), 0), \ C_distaTab[C_vertLabl (v)].queued = 1) #define C_distaGet(v,d) (C_queueGet (&C_distaQueue, (v), (d))) #define C_distaPut(v,d) ((C_distaTab[C_vertLabl (v)].queued == 0) \ ? C_queuePut (&C_distaQueue, (v), d), \ C_distaTab[C_vertLabl (v)].queued = 1 \ : 0) scotch-6.0.4.dfsg/src/scotch/amk_m2.c0000644002563400244210000003247212473176651022501 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : amk_m2.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Creates the distance map for **/ /** bidimensional mesh graphs, to be used **/ /** to build the architecture description **/ /** files for these graphs. **/ /** **/ /** DATES : # Version 1.3 : from : 21 apr 1994 **/ /** to : 21 apr 1994 **/ /** # Version 2.0 : from : 12 jul 1994 **/ /** to : 12 nov 1994 **/ /** # Version 3.0 : from : 17 jul 1995 **/ /** to : 19 sep 1995 **/ /** # Version 3.2 : from : 31 may 1997 **/ /** to : 02 jun 1997 **/ /** # Version 3.4 : from : 03 feb 2000 **/ /** to : 03 feb 2000 **/ /** # Version 4.0 : from : 09 feb 2004 **/ /** to : 09 feb 2004 **/ /** # Version 5.0 : from : 23 dec 2007 **/ /** to : 21 apr 2008 **/ /** # Version 5.1 : from : 01 jul 2010 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /** NOTES : # The vertices of the (dX,dY) mesh are **/ /** numbered as terminals so that **/ /** t (0,0)=0, t (1,0) = 1, **/ /** t (dX - 1, 0) = dX - 1, **/ /** t (0,1) = dX, and **/ /** t(x,y) = (y * dX) + x. **/ /** **/ /** # The nested dissection method should **/ /** behave like the architecture built in **/ /** the mapper. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define AMK_M2 #include "module.h" #include "common.h" #include "scotch.h" #include "arch.h" #include "arch_mesh.h" #include "amk_m2.h" /* ** The static definitions. */ static int C_paraNum = 0; /* Number of parameters */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[C_FILENBR] = { /* File array */ { "w" } }; static const char * C_usageList[] = { "amk_m2 [ []] ", " -h : Display this help", " -m : Decomposition method", " n : Nested dissection (cut biggest dimension)", " o : One-way dissection (y, then x)", " -V : Print program version and copyright", "", "Default option set is : '-Mn'", NULL }; /*************************************************/ /* */ /* The main routine, which computes the distance */ /* triangular table. */ /* */ /*************************************************/ int main ( int argc, char * argv[]) { ArchMesh2 arch; /* Mesh dimensions */ ArchMesh2Dom dom; /* Initial domain */ C_MethType methtype; /* Bipartitioning method */ unsigned int termnbr; /* Number of terminal domains */ unsigned int termmax; /* Maximum terminal number */ unsigned int * termtab; /* Terminal numbers table */ unsigned int x0, y0, x1, y1; int i; errorProg ("amk_m2"); if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } methtype = C_METHNESTED; arch.c[0] = /* Preset mesh dimensions */ arch.c[1] = 1; fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_paraNum < 2) { /* If number of parameters not reached */ if ((arch.c[C_paraNum ++] = atoi (argv[i])) < 1) { /* Get the dimension */ errorPrint ("main: invalid dimension '%s'", argv[i]); return (1); } continue; /* Process the other parameters */ } if (C_fileNum < C_FILEARGNBR) /* A file name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else { errorPrint ("main: too many file names given"); return (1); } } else { /* If found an option name */ switch (argv[i][1]) { case 'M' : /* Use a built-in method */ case 'm' : switch (argv[i][2]) { case 'N' : /* Nested dissection */ case 'n' : methtype = C_METHNESTED; break; case 'O' : /* One-way dissection */ case 'o' : methtype = C_METHONEWAY; break; default : errorPrint ("main: unprocessed option '%s'", argv[i]); return (1); } break; case 'H' : /* Give the usage message */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'V' : fprintf (stderr, "amk_m2, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: unprocessed option '%s'", argv[i]); return (1); } } } fileBlockOpen (C_fileTab, C_FILENBR); /* Open all files */ dom.c[0][0] = 0; /* Set the initial domain */ dom.c[0][1] = arch.c[0] - 1; dom.c[1][0] = 0; dom.c[1][1] = arch.c[1] - 1; termnbr = arch.c[0] * arch.c[1]; /* Compute number of terminals */ termmax = 0; /* Maximum terminal value not known yet */ if ((termtab = (unsigned int *) memAlloc (termnbr * sizeof (unsigned int))) == NULL) { /* Allocate terminal array */ errorPrint ("main: out of memory"); return (1); } memset (termtab, -1, termnbr * sizeof (unsigned int)); /* Initilize mapping table */ C_termBipart (&arch, &dom, 1, termtab, &termmax, /* Compute terminal numbers */ (methtype == C_METHNESTED) ? archMesh2DomBipart : C_methBipartOne); fprintf (C_filepntrarcout, "deco\n0\n%u\t%u\n", /* Print file header */ termnbr, /* Print number of terminal domains */ termmax); /* Print biggest terminal value */ for (i = 0; i < termnbr; i ++) /* For all terminals */ fprintf (C_filepntrarcout, "%u\t1\t%u\n", /* Print terminal data */ i, termtab[i]); for (y0 = 0; y0 < arch.c[1]; y0 ++) { /* For all vertices */ for (x0 = 0; x0 < arch.c[0]; x0 ++) { for (y1 = 0; y1 <= y0; y1 ++) { /* Compute distance to smaller vertices */ for (x1 = 0; (x1 < arch.c[0]) && ((y1 < y0) || (x1 < x0)); x1 ++) fprintf (C_filepntrarcout, ((x1 == 0) && (y1 == 0)) ? "%u" : " %u", C_termDist (x0, y0, x1, y1)); } fprintf (C_filepntrarcout, "\n"); } } fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ memFree (termtab); /* Free terminal number array */ #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } /* This routine recursively determines the values ** of all the terminal vertices of the mesh domain, ** and puts them in table. */ void C_termBipart ( ArchMesh2 * archptr, ArchMesh2Dom * domptr, unsigned int num, unsigned int * termtab, unsigned int * termmax, int (* methfunc) ()) { ArchMesh2Dom dom0; ArchMesh2Dom dom1; if (methfunc (archptr, domptr, &dom0, &dom1) == 0) { /* If we can bipartition */ C_termBipart (archptr, &dom0, num + num, termtab, termmax, methfunc); /* Bipartition recursively */ C_termBipart (archptr, &dom1, num + num + 1, termtab, termmax, methfunc); } else { /* If we have reached the end */ termtab[domptr->c[1][0] * archptr->c[0] + /* Set the terminal number */ domptr->c[0][0]] = num; if (*termmax < num) /* If we have reached a new maximum */ *termmax = num; /* Record it */ } } /* This function tries to split a rectangular domain into ** two subdomains using a one-way dissection method, by ** cutting first in the Y dimension, then in the X one. ** It returns: ** - 1 : if the domain has been bipartitioned. ** - 0 : else. */ int C_methBipartOne ( const ArchMesh2 * const archptr, const ArchMesh2Dom * const domptr, ArchMesh2Dom * restrict const dom0ptr, ArchMesh2Dom * restrict const dom1ptr) { if ((domptr->c[0][0] == domptr->c[0][1]) && /* Return if cannot split more */ (domptr->c[1][0] == domptr->c[1][1])) return (0); if (domptr->c[1][1] == domptr->c[1][0]) { /* If the Y dimension cannot be cut */ dom0ptr->c[0][0] = domptr->c[0][0]; /* Cut in the X dimension */ dom0ptr->c[0][1] = (domptr->c[0][0] + domptr->c[0][1]) / 2; dom1ptr->c[0][0] = dom0ptr->c[0][1] + 1; dom1ptr->c[0][1] = domptr->c[0][1]; dom0ptr->c[1][0] = dom1ptr->c[1][0] = domptr->c[1][0]; dom0ptr->c[1][1] = dom1ptr->c[1][1] = domptr->c[1][1]; } else { /* If the Y dimension can be cut, cut it */ dom0ptr->c[0][0] = dom1ptr->c[0][0] = domptr->c[0][0]; dom0ptr->c[0][1] = dom1ptr->c[0][1] = domptr->c[0][1]; dom0ptr->c[1][0] = domptr->c[1][0]; dom0ptr->c[1][1] = (domptr->c[1][0] + domptr->c[1][1]) / 2; dom1ptr->c[1][0] = dom0ptr->c[1][1] + 1; dom1ptr->c[1][1] = domptr->c[1][1]; } return (1); } scotch-6.0.4.dfsg/src/scotch/gmk_ub2.h0000644002563400244210000000665412473176651022671 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gmk_ub2.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the data declara- **/ /** tions for the de Bruijn source graph **/ /** building program. **/ /** **/ /** DATES : # Version 2.0 : from : 05 nov 1994 **/ /** to 05 nov 1994 **/ /** # Version 3.2 : from : 03 jun 1997 **/ /** to : 03 jun 1997 **/ /** # Version 3.3 : from : 07 jun 1999 **/ /** to : 07 jun 1999 **/ /** # Version 3.3 : from : 07 jun 1999 **/ /** to : 07 jun 1999 **/ /** # Version 6.0 : from : 12 nov 2014 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ File name aliases. +*/ #define C_FILENBR 1 /* Number of files in list */ #define C_FILEARGNBR 1 /* Number of files which can be arguments */ #define C_filenamesrcout fileBlockName (C_fileTab, 0) /* Source graph output file name */ #define C_filepntrsrcout fileBlockFile (C_fileTab, 0) /* Source graph output file */ scotch-6.0.4.dfsg/src/scotch/acpl.c0000644002563400244210000001534612473176651022253 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : acpl.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module compiles target architec- **/ /** ture decomposition files for fast **/ /** loading. **/ /** **/ /** DATES : # Version 2.0 : from : 12 nov 1994 **/ /** to : 12 nov 1994 **/ /** # Version 3.0 : from : 06 jul 1995 **/ /** to : 19 sep 1995 **/ /** # Version 3.2 : from : 24 sep 1996 **/ /** to : 12 may 1998 **/ /** # Version 3.3 : from : 02 oct 1998 **/ /** to : 02 oct 1998 **/ /** # Version 3.4 : from : 03 feb 2000 **/ /** to : 03 feb 2000 **/ /** # Version 4.0 : from : 09 feb 2004 **/ /** to : 09 feb 2004 **/ /** # Version 5.0 : from : 23 dec 2007 **/ /** to : 16 mar 2008 **/ /** # Version 5.1 : from : 01 jul 2010 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define ACPL #include "module.h" #include "common.h" #include "scotch.h" #include "acpl.h" /* ** The static variables. */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[C_FILENBR] = { /* File array */ { "r" }, { "w" } }; static const char * C_usageList[] = { "acpl [ []] ", " -h : Display this help", " -V : Print program version and copyright", NULL }; /******************************/ /* */ /* This is the main function. */ /* */ /******************************/ int main ( int argc, char * argv[]) { SCOTCH_Arch arch; /* Architecture read and written */ int i; errorProg ("acpl"); if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_fileNum < C_FILEARGNBR) /* File name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else { errorPrint ("main: too many file names given"); return (1); } } else { /* If found an option name */ switch (argv[i][1]) { case 'H' : /* Give the usage message */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'V' : fprintf (stderr, "acpl, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: unprocessed option '%s'", argv[i]); return (1); } } } fileBlockOpen (C_fileTab, C_FILENBR); /* Open all files */ SCOTCH_archInit (&arch); /* Initialize architecture structure */ SCOTCH_archLoad (&arch, C_filepntrtgtinp); /* Load architecture */ if (strcmp (SCOTCH_archName (&arch), "deco") != 0) { /* If not a decomposition */ errorPrint ("main: architecture is not decomposition-defined"); return (1); } SCOTCH_archSave (&arch, C_filepntrtgtout); /* Save the compiled architecture */ fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ SCOTCH_archExit (&arch); #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } scotch-6.0.4.dfsg/src/scotch/amk_p2.h0000644002563400244210000000655512473176651022514 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : amk_p2.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Creates the target architecture file **/ /** for a weighted path with two vertices **/ /** used to bipartition graphs in parts of **/ /** different sizes. **/ /** Here are the data declaration for the **/ /** target machine architecture functions. **/ /** **/ /** DATES : # Version 3.0 : from : 17 jul 1995 **/ /** to : 17 jul 1995 **/ /** # Version 3.2 : from : 02 jun 1997 **/ /** to : 02 jun 1997 **/ /** # Version 6.0 : from : 12 nov 2014 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /** File name aliases. **/ #define C_FILENBR 1 /* Number of files in list */ #define C_FILEARGNBR 1 /* Number of files which can be arguments */ #define C_filenametgtout fileBlockName (C_fileTab, 0) /* Architecture output file name */ #define C_filepntrtgtout fileBlockFile (C_fileTab, 0) /* Architecture output file */ scotch-6.0.4.dfsg/src/scotch/gbase.h0000644002563400244210000000627012473176651022416 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gbase.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the declarations **/ /** for the source graph base changer. **/ /** **/ /** DATES : # Version 4.0 : from : 12 may 2006 **/ /** to : 12 may 2006 **/ /** # Version 6.0 : from : 12 nov 2014 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /** File name aliases. **/ #define C_FILENBR 2 /* Number of files in list */ #define C_FILEARGNBR 2 /* Number of files which can be arguments */ #define C_filenamesrcinp fileBlockName (C_fileTab, 0) /* Source graph input file name */ #define C_filenamesrcout fileBlockName (C_fileTab, 1) /* Source graph output file name */ #define C_filepntrsrcinp fileBlockFile (C_fileTab, 0) /* Source graph input file */ #define C_filepntrsrcout fileBlockFile (C_fileTab, 1) /* Source graph output file */ scotch-6.0.4.dfsg/src/scotch/gotst.h0000644002563400244210000001215112473176651022470 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gotst.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a graph scalar factorizer. **/ /** This module contains the data declara- **/ /** tions for the main module. **/ /** **/ /** DATES : # Version 4.0 : from : 27 jan 2004 **/ /** to : 27 jan 2004 **/ /** # Version 5.0 : from : 25 jun 2007 **/ /** to : 25 jul 2007 **/ /** # Version 6.0 : from : 12 nov 2014 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines */ /*+ File name aliases. +*/ #define C_FILENBR 3 /* Number of files in list */ #define C_FILEARGNBR 3 /* Number of files which can be arguments */ #define C_filenamegrfinp fileBlockName (C_fileTab, 0) /* Graph input file name */ #define C_filenamesrcout fileBlockName (C_fileTab, 1) /* Ordering input file name */ #define C_filenamedatout fileBlockName (C_fileTab, 2) /* Output data file name */ #define C_filepntrgrfinp fileBlockFile (C_fileTab, 0) /* Graph input file */ #define C_filepntrordinp fileBlockFile (C_fileTab, 1) /* Ordering output file */ #define C_filepntrdatout fileBlockFile (C_fileTab, 2) /* Output data file */ /* ** The type and structure definitions. */ /* Factorization node */ typedef struct C_FactorNode_ { struct C_FactorNode_ * linkdad; /*+ Father of node +*/ struct C_FactorNode_ * linkson; /*+ First son of node +*/ struct C_FactorNode_ * linkbro; /*+ Brother of node +*/ } C_FactorNode; /* Data structure for computing factored matrix statistics. */ typedef struct FactorStat_ { const SCOTCH_Num * ldadtax; const SCOTCH_Num * lsontax; const SCOTCH_Num * lbrotax; SCOTCH_Num heigmin; SCOTCH_Num heigmax; SCOTCH_Num heignbr; double heigavg; double heigdlt; const SCOTCH_Num * fnnztax; double fnnzsum; } FactorStat; /* ** The function prototypes. */ static int factorView (const SCOTCH_Num, const SCOTCH_Num, const SCOTCH_Num * const, const SCOTCH_Num, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, FILE * restrict const); static int factorView2 (const SCOTCH_Num, const SCOTCH_Num, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, SCOTCH_Num * restrict, SCOTCH_Num * restrict, SCOTCH_Num * restrict, SCOTCH_Num * restrict); static void factorView3 (FactorStat * restrict const, SCOTCH_Num, SCOTCH_Num, double * restrict const); static void factorView4 (FactorStat * restrict const, SCOTCH_Num, SCOTCH_Num, double * restrict const); scotch-6.0.4.dfsg/src/scotch/gmk_msh.h0000644002563400244210000000703512473176651022762 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gmk_msh.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a mesh-to-graph converter. **/ /** This module contains the data declara- **/ /** tions for the main module. **/ /** **/ /** DATES : # Version 4.0 : from : 21 jan 2004 **/ /** to : 21 jan 2004 **/ /** # Version 6.0 : from : 12 nov 2014 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines */ /*+ File name aliases. +*/ #define C_FILENBR 2 /* Number of files in list */ #define C_FILEARGNBR 2 /* Number of files which can be arguments */ #define C_filenamemshinp fileBlockName (C_fileTab, 0) /* External graph input file name */ #define C_filenamegrfout fileBlockName (C_fileTab, 1) /* Source graph output file name */ #define C_filepntrmshinp fileBlockFile (C_fileTab, 0) /* External graph input file */ #define C_filepntrgrfout fileBlockFile (C_fileTab, 1) /* Source graph output file */ /* ** The type and structure definitions. */ /*+ This structure defines the method array element. +*/ typedef struct C_Format_ { char code; /* Format type code */ int (* func) (); /* Function to call */ } C_Format; scotch-6.0.4.dfsg/src/scotch/gmk_m2.h0000644002563400244210000001004012473176651022477 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gmk_m2.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the data declara- **/ /** tions for the bidimensional mesh source **/ /** graph building program. **/ /** **/ /** DATES : # Version 2.0 : from : 30 oct 1994 **/ /** to 08 nov 1994 **/ /** # Version 3.0 : from : 11 jul 1995 **/ /** to 11 jul 1995 **/ /** # Version 3.2 : from : 03 jun 1997 **/ /** to : 03 jun 1997 **/ /** # Version 3.3 : from : 06 oct 1998 **/ /** to : 06 oct 1998 **/ /** # Version 6.0 : from : 12 nov 2014 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ File name aliases. +*/ #define C_FILENBR 2 /* Number of files in list */ #define C_FILEARGNBR 1 /* Number of files which can be arguments */ #define C_filenamesrcout fileBlockName (C_fileTab, 0) /* Source graph output file name */ #define C_filenamegeoout fileBlockName (C_fileTab, 1) /* Geometry graph output file name */ #define C_filepntrsrcout fileBlockFile (C_fileTab, 0) /* Source graph output file */ #define C_filepntrgeoout fileBlockFile (C_fileTab, 1) /* Geometry graph output file */ /*+ Process flags. +*/ #define C_FLAGGEOOUT 0x0001 /* Output the geometry graph */ #define C_FLAGTORUS 0x0002 /* Build a torus rather than a mesh */ #define C_FLAGELEM 0x0004 /* Build a 8-neighbor grid rather than a 4-neighbor one */ #define C_FLAGDEFAULT 0x0000 /* Default flags */ scotch-6.0.4.dfsg/src/scotch/atst.h0000644002563400244210000000676012473176651022314 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : atst.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Target architecture graph analyzer. **/ /** **/ /** DATES : # Version 1.3 : from : 17 may 1994 **/ /** to : 17 may 1994 **/ /** # Version 2.0 : from : 11 nov 1994 **/ /** to : 11 nov 1994 **/ /** # Version 3.0 : from : 05 jul 1995 **/ /** to : 05 jul 1995 **/ /** # Version 3.2 : from : 01 jun 1997 **/ /** to : 01 jun 1997 **/ /** # Version 6.0 : from : 12 nov 2014 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /** File name aliases. **/ #define C_FILENBR 2 /* Number of files in list */ #define C_FILEARGNBR 2 /* Number of files which can be arguments */ #define C_filenametgtinp fileBlockName (C_fileTab, 0) /* Target graph input file name */ #define C_filenamelogout fileBlockName (C_fileTab, 1) /* Statistics output file name */ #define C_filepntrtgtinp fileBlockFile (C_fileTab, 0) /* Target graph input file */ #define C_filepntrlogout fileBlockFile (C_fileTab, 1) /* Statistics output file */ scotch-6.0.4.dfsg/src/scotch/gscat.h0000644002563400244210000000662412473176651022441 0ustar trophimeutilisateurs du domaine/* Copyright 2009,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gscat.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the data declara- **/ /** tions for the sequential graph scatter- **/ /** ing program. **/ /** **/ /** DATES : # Version 5.1 : from : 26 apr 2009 **/ /** to : 26 apr 2009 **/ /** # Version 6.0 : from : 12 nov 2014 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ File name aliases. +*/ #define C_FILENBR 2 /* Number of files in list */ #define C_FILEARGNBR 2 /* Number of files which can be arguments */ #define C_filenamesrcinp fileBlockName (C_fileTab, 0) /* Centralized source graph input file name */ #define C_filenamesrcout fileBlockName (C_fileTab, 1) /* Distributed source graph output file name */ #define C_filepntrsrcinp fileBlockFile (C_fileTab, 0) /* Centralized source graph input file */ #define C_filepntrsrcout fileBlockFile (C_fileTab, 1) /* Distributed source graph output file */ /* ** The function prototypes. */ static int C_graphScat (FILE * const, SCOTCH_Num, char * const); scotch-6.0.4.dfsg/src/scotch/amk_fft2.c0000644002563400244210000002635112473176651023023 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : amk_fft2.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Creates the distance map for FFT **/ /** graphs, to be used to build the archi- **/ /** tecture description files for these **/ /** graphs. **/ /** **/ /** DATES : # Version 1.3 : from : 19 apr 1994 **/ /** to : 20 apr 1994 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to : 19 sep 1995 **/ /** # Version 3.2 : from : 07 may 1997 **/ /** to : 07 may 1997 **/ /** # Version 3.3 : from : 02 oct 1998 **/ /** to : 02 oct 1998 **/ /** # Version 3.4 : from : 03 feb 2000 **/ /** to : 03 feb 2000 **/ /** # Version 5.0 : from : 23 dec 2007 **/ /** to : 16 mar 2008 **/ /** # Version 5.1 : from : 01 jul 2010 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define AMK_FFT2 #include "module.h" #include "common.h" #include "scotch.h" #include "amk_fft2.h" /* ** The static and global definitions. */ static int C_paraNum = 0; /* Number of parameters */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[C_FILENBR] = { /* The file array */ { "w" } }; static C_VertDist * C_distaTab; /* Pointer to distance map table */ static C_Queue C_distaQueue; /* Distance queue */ static const char * C_usageList[] = { /* Usage list */ "amk_fft2 [ []] ", " -h : Display this help", " -V : Print program version and copyright", NULL }; /*************************************************/ /* */ /* The main routine, which computes the distance */ /* triangular table. */ /* */ /*************************************************/ int main ( int argc, char * argv[]) { SCOTCH_Num fdim; /* FFT dimension */ SCOTCH_Num fnbr; /* Number of FFT vertices */ SCOTCH_Num fmax; /* Maximum terminal number */ SCOTCH_Num fmsk; /* Position bit mask */ C_Vertex v, w, x; /* A FFT vertex (lvl, pos) */ SCOTCH_Num b, d; /* Mask and bit variables */ SCOTCH_Num i; /* Loop counter */ SCOTCH_Num t; /* Vertex terminal value */ errorProg ("amk_fft2"); fdim = 2; if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_paraNum < 1) { /* If number of parameters not reached */ if ((fdim = atoi (argv[i])) < 1) { /* Get the dimension */ errorPrint ("main: invalid dimension '%s'", argv[i]); return (1); } C_paraNum ++; continue; /* Process the other parameters */ } if (C_fileNum < C_FILENBR) /* A file name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else { errorPrint ("main: too many file names given"); return (1); } } else { /* If found an option name */ switch (argv[i][1]) { case 'H' : /* Give the usage message */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'V' : fprintf (stderr, "amk_fft2, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: unprocessed option '%s'", argv[i]); return (1); } } } fileBlockOpen (C_fileTab, C_FILENBR); /* Open all files */ fnbr = (fdim + 1) * (1 << fdim); /* Compute number of vertices */ fmax = (1 << (fdim * 2 - 1)) - 1; /* Compute maximum terminal number */ fmsk = (1 << fdim) - 1; /* Get maximum position number */ fprintf (C_filepntrarcout, "deco\n0\n" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n", /* Print file header */ (SCOTCH_Num) fnbr, /* Print number of terminal domains */ (SCOTCH_Num) fmax); /* Print the biggest terminal value */ for (v.lvl = 0; v.lvl <= fdim; v.lvl ++) { /* For all vertices */ for (v.pos = 0; v.pos <= fmsk; v.pos ++) { for (i = v.lvl, b = 1 << (fdim - 1), t = 1; /* Recurse through the vertical + horizontal cuts */ i <= fdim; i ++, b >>= 1) { t <<= 1; /* Vertical cut: tell if vertex is in left or... */ t |= (v.pos & b) ? 1 : 0; /* right part from the position heaviest bits */ t <<= 1; /* Vertex is still in upper part of horizontal cut */ } if (v.lvl == 0) /* If vertex is in the first level... */ t >>= 2; /* We have gone one step too far */ else { /* Else */ t |= 1; /* This time vertex is in the lower part */ t <<= (v.lvl - 1); /* Make space for the chain bipartition */ t |= v.pos & ((1 << (v.lvl - 1)) - 1); /* Bipartition the chain following the lowest bits */ } printf (((v.lvl == fdim) && (v.pos == fmsk)) /* Print terminal domain number */ ? SCOTCH_NUMSTRING "\n\n" : SCOTCH_NUMSTRING " ", t); } } if ((C_queueInit (&C_distaQueue, fnbr) != 0) || /* Allocate distance array */ ((C_distaTab = (C_VertDist *) memAlloc (fnbr * sizeof (C_VertDist))) == NULL)) { errorPrint ("main: out of memory"); return (1); } for (v.lvl = 0; v.lvl <= fdim; v.lvl ++) { /* For all vertices */ for (v.pos = 0; v.pos <= fmsk; v.pos ++) { for (i = 0; i < fnbr; i ++) /* Initialize the vertex table */ C_distaTab[i].queued = 0; /* Vertex not queued yet */ C_distaRoot (&v); /* Set the queue with root v */ while (C_distaGet (&w, &d)) { /* As long as the queue is not empty */ C_distaTab[C_vertLabl (&w)].dist = d; /* Keep the distance information */ d ++; /* Search for neighbors at next level */ if (w.lvl > 0) { /* Add new neighbors to the queue */ x.lvl = w.lvl - 1; x.pos = w.pos; C_distaPut (&x, d); x.pos = w.pos ^ (1 << (w.lvl - 1)); C_distaPut (&x, d); } if (w.lvl < fdim) { x.lvl = w.lvl + 1; x.pos = w.pos; C_distaPut (&x, d); x.pos = w.pos ^ (1 << w.lvl); C_distaPut (&x, d); } } if (v.lvl + v.pos > 0) { /* Print the distance triangular map line */ fprintf (C_filepntrarcout, SCOTCH_NUMSTRING, (SCOTCH_Num) C_distaTab[0].dist); for (i = 1; i < (v.lvl << fdim) + v.pos; i ++) fprintf (C_filepntrarcout, " " SCOTCH_NUMSTRING, (SCOTCH_Num) C_distaTab[i].dist); fprintf (C_filepntrarcout, "\n"); } } } C_queueExit (&C_distaQueue); memFree (C_distaTab); fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } scotch-6.0.4.dfsg/src/scotch/gmk_m2.c0000644002563400244210000003012312473176651022476 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gmk_m2.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Creates the source graph for 2D mesh **/ /** graphs. **/ /** **/ /** DATES : # Version 2.0 : from : 30 oct 1994 **/ /** to 08 nov 1994 **/ /** # Version 3.0 : from : 11 jul 1995 **/ /** to 02 oct 1995 **/ /** # Version 3.2 : from : 03 jun 1997 **/ /** to : 03 jun 1997 **/ /** # Version 3.3 : from : 06 oct 1998 **/ /** to : 06 oct 1998 **/ /** # Version 3.4 : from : 03 feb 2000 **/ /** to : 18 may 2004 **/ /** # Version 5.0 : from : 13 dec 2007 **/ /** to : 16 mar 2008 **/ /** # Version 5.1 : from : 01 jul 2010 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /** NOTES : # The vertices of the (dX,dY) mesh are **/ /** numbered as terminals so that **/ /** t(0,0) = 0, t(1,0) = 1, **/ /** t(dX - 1, 0) = dX - 1, t(0,1) = dX, **/ /** and t(x,y) = (y * dX) + x. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GMK_M2 #include "module.h" #include "common.h" #include "scotch.h" #include "gmk_m2.h" /* ** The static definitions. */ static int C_paraNum = 0; /* Number of parameters */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[C_FILENBR] = { /* The file array */ { "w" }, { "w" } }; static const char * C_usageList[] = { "gmk_m2 [ []] ", " -b : Set base value for output (0 or 1)", " -e : Build a 8-neighbor grid rather than a 4-neighbor one", " -g : Output the geometry to ", " -h : Display this help", " -t : Build a torus rather than a mesh", " -V : Print program version and copyright", NULL }; /****************************************/ /* */ /* The main routine, which computes the */ /* source graph description. */ /* */ /****************************************/ int main ( int argc, char * argv[]) { int flagval; /* Process flags */ SCOTCH_Num baseval; /* Base value */ SCOTCH_Num d[2] = { 1, 1 }; /* Mesh dimensions */ SCOTCH_Num c[2]; /* Vertex coordinates */ int i; errorProg ("gmk_m2"); flagval = C_FLAGDEFAULT; /* Set default flags */ baseval = 0; if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_paraNum < 2) { /* If number of parameters not reached */ if ((d[C_paraNum ++] = atoi (argv[i])) < 1) { /* Get the dimension */ errorPrint ("main: invalid dimension '%s'", argv[i]); return (1); } continue; /* Process the other parameters */ } if (C_fileNum < C_FILEARGNBR) /* A file name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else { errorPrint ("main: too many file names given"); return (1); } } else { /* If found an option name */ switch (argv[i][1]) { case 'B' : /* Set base value */ case 'b' : baseval = (SCOTCH_Num) atol (&argv[i][2]); if ((baseval < 0) || (baseval > 1)) { errorPrint ("main: invalid base value '" SCOTCH_NUMSTRING "'", (SCOTCH_Num) baseval); } break; case 'E' : /* Build a finite-element grid */ case 'e' : flagval |= C_FLAGELEM; break; case 'G' : /* Output the geometry */ case 'g' : flagval |= C_FLAGGEOOUT; if (argv[i][2] != '\0') C_filenamegeoout = &argv[i][2]; break; case 'H' : /* Give the usage message */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'T' : /* Build a torus */ case 't' : flagval |= C_FLAGTORUS; break; case 'V' : fprintf (stderr, "gmk_m2, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: unprocessed option '%s'", argv[i]); return (1); } } } fileBlockOpen (C_fileTab, C_FILENBR); /* Open all files */ if (flagval & C_FLAGELEM) { /* Build a 8-neighbor grid */ errorPrint ("main: elements not supported"); return (1); } if (flagval & C_FLAGTORUS) { /* Build a torus */ fprintf (C_filepntrsrcout, "0\n" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n" SCOTCH_NUMSTRING "\t000\n", (SCOTCH_Num) (d[0] * d[1]), /* Print number of vertices */ (SCOTCH_Num) ((4 * d[0] * d[1]) - /* Print number of edges (arcs) */ ((d[0] < 3) ? (2 * d[1]) : 0) - ((d[1] < 3) ? (2 * d[0]) : 0)), (SCOTCH_Num) baseval); for (c[1] = 0; c[1] < d[1]; c[1] ++) { /* Output neighbor list */ for (c[0] = 0; c[0] < d[0]; c[0] ++) { fprintf (C_filepntrsrcout, SCOTCH_NUMSTRING, (SCOTCH_Num) (((d[0] > 2) ? 3 : d[0]) + /* Output number of neighbors */ ((d[1] > 2) ? 3 : d[1]) - 2)); if (d[1] > 2) fprintf (C_filepntrsrcout, "\t" SCOTCH_NUMSTRING, /* Output the neighbors */ (SCOTCH_Num) (((c[1] + d[1] - 1) % d[1]) * d[0] + c[0] + baseval)); if (d[0] > 2) fprintf (C_filepntrsrcout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) ((c[1] * d[0] + (c[0] + d[0] - 1) % d[0]) + baseval)); if (d[0] > 1) fprintf (C_filepntrsrcout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) (c[1] * d[0] + ((c[0] + 1) % d[0]) + baseval)); if (d[1] > 1) fprintf (C_filepntrsrcout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) (((c[1] + 1) % d[1]) * d[0] + c[0] + baseval)); fprintf (C_filepntrsrcout, "\n"); } } } else { /* Build a mesh */ fprintf (C_filepntrsrcout, "0\n" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n" SCOTCH_NUMSTRING "\t000\n", (SCOTCH_Num) (d[0] * d[1]), (SCOTCH_Num) ((d[0] * d[1] * 2 - (d[0] + d[1])) * 2), (SCOTCH_Num) baseval); for (c[1] = 0; c[1] < d[1]; c[1] ++) { /* Output neighbor list */ for (c[0] = 0; c[0] < d[0]; c[0] ++) { fprintf (C_filepntrsrcout, "%d", ((c[0] == 0) ? 0 : 1) + /* Output number of neighbors */ ((c[0] == (d[0] - 1)) ? 0 : 1) + ((c[1] == 0) ? 0 : 1) + ((c[1] == (d[1] - 1)) ? 0 : 1)); if (c[1] != 0) /* Output the neighbors */ fprintf (C_filepntrsrcout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) ((c[1] - 1) * d[0] + c[0] + baseval)); if (c[0] != 0) fprintf (C_filepntrsrcout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) (c[1] * d[0] + (c[0] - 1) + baseval)); if (c[0] != (d[0] - 1)) fprintf (C_filepntrsrcout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) (c[1] * d[0] + (c[0] + 1) + baseval)); if (c[1] != (d[1] - 1)) fprintf (C_filepntrsrcout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) ((c[1] + 1) * d[0] + c[0] + baseval)); fprintf (C_filepntrsrcout, "\n"); } } } if (flagval & C_FLAGGEOOUT) { /* If geometry is wanted */ fprintf (C_filepntrgeoout, "2\n" SCOTCH_NUMSTRING "\n", /* Output geometry file header */ (SCOTCH_Num) (d[0] * d[1])); for (c[1] = 0; c[1] < d[1]; c[1] ++) { /* Output mesh coordinates */ for (c[0] = 0; c[0] < d[0]; c[0] ++) fprintf (C_filepntrgeoout, SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n", (SCOTCH_Num) (c[1] * d[0] + c[0] + baseval), (SCOTCH_Num) c[0], (SCOTCH_Num) (d[1] - 1 - c[1])); } } fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } scotch-6.0.4.dfsg/src/scotch/gmk_m3.h0000644002563400244210000000702112473176651022505 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gmk_m3.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the data declara- **/ /** tions for the tridimensional mesh **/ /** source graph building program. **/ /** **/ /** DATES : # Version 4.0 : from : 11 feb 2002 **/ /** to : 11 feb 2002 **/ /** # Version 6.0 : from : 12 nov 2014 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ File name aliases. +*/ #define C_FILENBR 2 /* Number of files in list */ #define C_FILEARGNBR 1 /* Number of files which can be arguments */ #define C_filenamesrcout fileBlockName (C_fileTab, 0) /* Source graph output file name */ #define C_filenamegeoout fileBlockName (C_fileTab, 1) /* Geometry graph output file name */ #define C_filepntrsrcout fileBlockFile (C_fileTab, 0) /* Source graph output file */ #define C_filepntrgeoout fileBlockFile (C_fileTab, 1) /* Geometry graph output file */ /*+ Process flags. +*/ #define C_FLAGGEOOUT 0x0001 /* Output the geometry graph */ #define C_FLAGTORUS 0x0002 /* Build a torus rather than a mesh */ #define C_FLAGDEFAULT 0x0000 /* Default flags */ scotch-6.0.4.dfsg/src/scotch/mcv.c0000644002563400244210000002066412473176651022120 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mcv.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a mesh file converter. **/ /** This module contains the main function. **/ /** **/ /** DATES : # Version 4.0 : from : 19 jan 2004 **/ /** to : 19 jan 2004 **/ /** # Version 5.0 : from : 23 dec 2007 **/ /** to : 16 mar 2008 **/ /** # Version 5.1 : from : 01 jul 2010 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define MCV #include "module.h" #include "common.h" #include "scotch.h" #include "mcv.h" /* ** The static and global variables. */ static int C_inpFormatType = 0; /* Input mesh format */ static char * C_inpFormatData = "\0"; /* Pointer to auxiliary data */ static const C_Format C_inpFormatTab[] = { /* Table of input formats */ { 'B', SCOTCH_meshGeomLoadHabo }, { 'b', SCOTCH_meshGeomLoadHabo }, { 'S', SCOTCH_meshGeomLoadScot }, { 's', SCOTCH_meshGeomLoadScot }, { '\0', NULL } }; static int C_outFormatType = 0; /* Output mesh format */ static char * C_outFormatData = "\0"; /* Pointer to auxiliary data */ static C_Format C_outFormatTab[] = { /* Table of output formats */ { 'S', SCOTCH_meshGeomSaveScot }, { 's', SCOTCH_meshGeomSaveScot }, { '\0', NULL } }; static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[3] = { /* File array */ { "r" }, { "w" }, { "w" } }; static const char * C_usageList[] = { "mcv [ [ []]] ", " -h : Display this help", " -i : Select input file format", " b : Boeing-Harwell format (elemental)", " s : Scotch format", " -o : Select output file format", " s : Scotch format", " -V : Print program version and copyright", "", "Default option set is : '-Ib -Os'", NULL }; /*****************************/ /* */ /* This is the main function */ /* */ /*****************************/ int main ( int argc, char * argv[]) { SCOTCH_Mesh meshdat; SCOTCH_Geom geomdat; int i, j; errorProg ("mcv"); if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_fileNum < C_FILEARGNBR) /* File name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else { errorPrint ("main: too many file names given"); return (1); } } else { /* If found an option name */ switch (argv[i][1]) { case 'H' : /* Give help */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'I' : /* Select input file type */ case 'i' : for (j = 0; C_inpFormatTab[j].code != '\0'; j ++) { /* Find proper format code */ if (C_inpFormatTab[j].code == argv[i][2]) { C_inpFormatType = j; C_inpFormatData = &argv[i][3]; break; } } if (C_inpFormatTab[j].code == '\0') { errorPrint ("main: unprocessed option '%s'", argv[i]); return (1); } break; case 'O' : /* Select input file type */ case 'o' : for (j = 0; C_outFormatTab[j].code != '\0'; j ++) { /* Find proper format code */ if (C_outFormatTab[j].code == argv[i][2]) { C_outFormatType = j; C_outFormatData = &argv[i][3]; break; } } if (C_inpFormatTab[j].code == '\0') { errorPrint ("main: unprocessed option '%s'", argv[i]); return (1); } break; case 'V' : fprintf (stderr, "mcv, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: unprocessed option '%s'", argv[i]); return (1); } } } fileBlockOpen (C_fileTab, C_FILENBR); /* Open all files */ SCOTCH_meshInit (&meshdat); SCOTCH_geomInit (&geomdat); C_inpFormatTab[C_inpFormatType].func (&meshdat, &geomdat, C_filepntrsrcinp, NULL, C_inpFormatData); #ifdef SCOTCH_DEBUG_ALL if (SCOTCH_meshCheck (&meshdat) != 0) { errorPrint ("main: bad graph structure"); return (1); } #endif /* SCOTCH_DEBUG_ALL */ C_outFormatTab[C_outFormatType].func (&meshdat, &geomdat, C_filepntrsrcout, C_filepntrgeoout, C_outFormatData); fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ SCOTCH_geomExit (&geomdat); SCOTCH_meshExit (&meshdat); #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } scotch-6.0.4.dfsg/src/scotch/amk_hy.h0000644002563400244210000000734712473176651022613 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : amk_hy.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Creates the target architecture file **/ /** for hypercube graphs. **/ /** Here are the data declaration for the **/ /** target machine architecture functions. **/ /** **/ /** DATES : # Version 2.0 : from : 14 nov 1994 **/ /** to : 14 nov 1994 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to : 07 jul 1995 **/ /** # Version 3.1 : from : 30 may 1996 **/ /** to : 30 may 1996 **/ /** # Version 3.2 : from : 31 may 1997 **/ /** to : 31 may 1997 **/ /** # Version 3.3 : from : 02 oct 1998 **/ /** to : 02 oct 1998 **/ /** # Version 6.0 : from : 12 nov 2014 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /** File name aliases. **/ #define C_FILENBR 1 /* Number of files in list */ #define C_FILEARGNBR 1 /* Number of files which can be arguments */ #define C_filenametgtout fileBlockName (C_fileTab, 0) /* Architecture output file name */ #define C_filepntrtgtout fileBlockFile (C_fileTab, 0) /* Architecture output file */ /* ** The macro definitions. */ #ifndef abs #define abs(a) (((a) >= 0) ? (a) : -(a)) #endif /* abs */ scotch-6.0.4.dfsg/src/scotch/gmk_m3.c0000644002563400244210000003134312473176651022504 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gmk_m3.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Creates the source graph for **/ /** tridimensional mesh source graphs. **/ /** **/ /** DATES : # Version 4.0 : from : 11 feb 2002 **/ /** to : 18 may 2004 **/ /** # Version 5.0 : from : 13 dec 2007 **/ /** to : 16 mar 2008 **/ /** # Version 5.1 : from : 01 jul 2010 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /** NOTES : # The vertices of the (dX,dY,dZ) mesh **/ /** are numbered as terminals so that **/ /** t(0,0,0) = 0, t(1,0,0) = 1, **/ /** t(dX - 1, 0, 0) = dX - 1, t(0,1,0) = **/ /** dX, t (0, 0, 1) = dX * dY - 1, **/ /** and t(x,y,z) = (z * dY + y) * dX + x. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GMK_M3 #include "module.h" #include "common.h" #include "scotch.h" #include "gmk_m3.h" /* ** The static definitions. */ static int C_paraNum = 0; /* Number of parameters */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[C_FILENBR] = { /* The file array */ { "w" }, { "w" } }; static const char * C_usageList[] = { "gmk_m3 [ [ []]] ", " -b : Set base value for output (0 or 1)", " -g : Output the geometry to ", " -h : Display this help", " -t : Build a torus rather than a mesh", " -V : Print program version and copyright", NULL }; /****************************************/ /* */ /* The main routine, which computes the */ /* source graph description. */ /* */ /****************************************/ int main ( int argc, char * argv[]) { int flagval; /* Process flags */ SCOTCH_Num baseval; /* Base value */ SCOTCH_Num d[3] = { 1, 1, 1 }; /* Mesh dimensions */ SCOTCH_Num c[3]; /* Vertex coordinates */ int i; errorProg ("gmk_m3"); flagval = C_FLAGDEFAULT; /* Set default flags */ baseval = 0; if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_paraNum < 3) { /* If number of parameters not reached */ if ((d[C_paraNum ++] = atoi (argv[i])) < 1) { /* Get the dimension */ errorPrint ("main: invalid dimension '%s'", argv[i]); return (1); } continue; /* Process the other parameters */ } if (C_fileNum < C_FILEARGNBR) /* A file name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else { errorPrint ("main: too many file names given"); return (1); } } else { /* If found an option name */ switch (argv[i][1]) { case 'B' : /* Set base value */ case 'b' : baseval = (SCOTCH_Num) atol (&argv[i][2]); if ((baseval < 0) || (baseval > 1)) { errorPrint ("main: invalid base value '" SCOTCH_NUMSTRING "'", (SCOTCH_Num) baseval); } break; case 'G' : /* Output the geometry */ case 'g' : flagval |= C_FLAGGEOOUT; if (argv[i][2] != '\0') C_filenamegeoout = &argv[i][2]; break; case 'H' : /* Give the usage message */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'T' : /* Build a torus */ case 't' : flagval |= C_FLAGTORUS; break; case 'V' : fprintf (stderr, "gmk_m3, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: unprocessed option '%s'", argv[i]); return (1); } } } fileBlockOpen (C_fileTab, C_FILENBR); /* Open all files */ if (flagval & C_FLAGTORUS) { /* Build a torus */ fprintf (C_filepntrsrcout, "0\n" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n" SCOTCH_NUMSTRING "\t000\n", (SCOTCH_Num) (d[0] * d[1] * d[2]), /* Print number of vertices */ (SCOTCH_Num) ((6 * d[0] * d[1] * d[2]) - /* Print number of edges (arcs) */ ((d[0] < 3) ? (2 * d[1] * d[2]) : 0) - ((d[1] < 3) ? (2 * d[0] * d[2]) : 0) - ((d[2] < 3) ? (2 * d[0] * d[1]) : 0)), (SCOTCH_Num) baseval); for (c[2] = 0; c[2] < d[2]; c[2] ++) { /* Output neighbor list */ for (c[1] = 0; c[1] < d[1]; c[1] ++) { for (c[0] = 0; c[0] < d[0]; c[0] ++) { fprintf (C_filepntrsrcout, SCOTCH_NUMSTRING, (SCOTCH_Num) (((d[0] > 2) ? 3 : d[0]) + /* Output number of neighbors */ ((d[1] > 2) ? 3 : d[1]) + ((d[2] > 2) ? 3 : d[2]) - 3)); if (d[2] > 2) fprintf (C_filepntrsrcout, "\t" SCOTCH_NUMSTRING, /* Output the neighbors */ (SCOTCH_Num) ((((c[2] + d[2] - 1) % d[2]) * d[1] + c[1]) * d[0] + c[0] + baseval)); if (d[1] > 2) fprintf (C_filepntrsrcout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) ((c[2] * d[1] + ((c[1] + d[1] - 1) % d[1])) * d[0] + c[0] + baseval)); if (d[0] > 2) fprintf (C_filepntrsrcout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) (((c[2] * d[1] + c[1]) * d[0] + (c[0] + d[0] - 1) % d[0])) + baseval); if (d[0] > 1) fprintf (C_filepntrsrcout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) ((c[2] * d[1] + c[1]) * d[0] + ((c[0] + 1) % d[0]) + baseval)); if (d[1] > 1) fprintf (C_filepntrsrcout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) ((c[2] * d[1] + ((c[1] + 1) % d[1])) * d[0] + c[0] + baseval)); if (d[2] > 1) fprintf (C_filepntrsrcout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) ((((c[2] + 1) % d[2]) * d[1] + c[1]) * d[0] + c[0] + baseval)); fprintf (C_filepntrsrcout, "\n"); } } } } else { /* Build a mesh */ fprintf (C_filepntrsrcout, "0\n" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n" SCOTCH_NUMSTRING "\t000\n", (SCOTCH_Num) (d[0] * d[1] * d[2]), (SCOTCH_Num) ((d[0] * d[1] * d[2] * 3 - (d[0] * d[1] + d[0] * d[2] + d[1] * d[2])) * 2), (SCOTCH_Num) baseval); for (c[2] = 0; c[2] < d[2]; c[2] ++) { /* Output neighbor list */ for (c[1] = 0; c[1] < d[1]; c[1] ++) { for (c[0] = 0; c[0] < d[0]; c[0] ++) { fprintf (C_filepntrsrcout, "%d", ((c[0] == 0) ? 0 : 1) + /* Output number of neighbors */ ((c[0] == (d[0] - 1)) ? 0 : 1) + ((c[1] == 0) ? 0 : 1) + ((c[1] == (d[1] - 1)) ? 0 : 1) + ((c[2] == 0) ? 0 : 1) + ((c[2] == (d[2] - 1)) ? 0 : 1)); if (c[2] != 0) /* Output the neighbors */ fprintf (C_filepntrsrcout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) (((c[2] - 1) * d[1] + c[1]) * d[0] + c[0] + baseval)); if (c[1] != 0) fprintf (C_filepntrsrcout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) ((c[2] * d[1] + c[1] - 1) * d[0] + c[0] + baseval)); if (c[0] != 0) fprintf (C_filepntrsrcout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) ((c[2] * d[1] + c[1]) * d[0] + c[0] - 1 + baseval)); if (c[0] != (d[0] - 1)) fprintf (C_filepntrsrcout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) ((c[2] * d[1] + c[1]) * d[0] + c[0] + 1 + baseval)); if (c[1] != (d[1] - 1)) fprintf (C_filepntrsrcout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) ((c[2] * d[1] + c[1] + 1) * d[0] + c[0] + baseval)); if (c[2] != (d[2] - 1)) fprintf (C_filepntrsrcout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) (((c[2] + 1) * d[1] + c[1]) * d[0] + c[0] + baseval)); fprintf (C_filepntrsrcout, "\n"); } } } } if (flagval & C_FLAGGEOOUT) { /* If geometry is wanted */ fprintf (C_filepntrgeoout, "3\n" SCOTCH_NUMSTRING "\n", /* Output geometry file header */ (SCOTCH_Num) (d[0] * d[1] * d[2])); for (c[2] = 0; c[2] < d[2]; c[2] ++) { /* Output mesh coordinates */ for (c[1] = 0; c[1] < d[1]; c[1] ++) { for (c[0] = 0; c[0] < d[0]; c[0] ++) fprintf (C_filepntrgeoout, SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n", (SCOTCH_Num) ((c[2] * d[1] + c[1]) * d[0] + c[0] + baseval), (SCOTCH_Num) c[0], (SCOTCH_Num) (d[1] - 1 - c[1]), (SCOTCH_Num) c[2]); } } } fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } scotch-6.0.4.dfsg/src/scotch/gmtst.h0000644002563400244210000000770012473176651022472 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gmtst.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This program computes statistics on **/ /** graph mappings. **/ /** **/ /** DATES : # Version 3.1 : from : 17 jul 1996 **/ /** to 23 jul 1996 **/ /** # Version 3.2 : from : 02 jun 1997 **/ /** to 02 jun 1997 **/ /** # Version 3.3 : from : 06 jun 1999 **/ /** to 07 jun 1999 **/ /** # Version 4.0 : from : 12 feb 2004 **/ /** to 29 nov 2005 **/ /** # Version 6.0 : from : 12 nov 2014 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ File name aliases. +*/ #define C_FILENBR 4 /* Number of files in list */ #define C_FILEARGNBR 4 /* Number of files which can be arguments */ #define C_filenamesrcinp fileBlockName (C_fileTab, 0) /* Source graph file name */ #define C_filenametgtinp fileBlockName (C_fileTab, 1) /* Target architecture file name */ #define C_filenamemapinp fileBlockName (C_fileTab, 2) /* Mapping result file name */ #define C_filenamedatout fileBlockName (C_fileTab, 3) /* Statistics file name */ #define C_filepntrsrcinp fileBlockFile (C_fileTab, 0) /* Source graph input file */ #define C_filepntrtgtinp fileBlockFile (C_fileTab, 1) /* Target architecture file */ #define C_filepntrmapinp fileBlockFile (C_fileTab, 2) /* Mapping result input file */ #define C_filepntrdatout fileBlockFile (C_fileTab, 3) /* Statistics output file */ scotch-6.0.4.dfsg/src/scotch/gmk_hy.c0000644002563400244210000001726112473176651022610 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gmk_hy.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Creates the source graph for hypercube **/ /** graphs. **/ /** **/ /** DATES : # Version 2.0 : from : 03 nov 1994 **/ /** to 03 nov 1994 **/ /** # Version 3.0 : from : 11 jul 1995 **/ /** to 11 jul 1995 **/ /** # Version 3.2 : from : 03 jun 1997 **/ /** to : 03 jun 1997 **/ /** # Version 3.3 : from : 06 oct 1998 **/ /** to : 06 oct 1998 **/ /** # Version 3.4 : from : 03 feb 2000 **/ /** to : 03 feb 2000 **/ /** # Version 5.0 : from : 23 dec 2007 **/ /** to : 16 map 2008 **/ /** # Version 5.1 : from : 01 jul 2010 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GMK_HY #include "module.h" #include "common.h" #include "scotch.h" #include "gmk_hy.h" /* ** The static definitions. */ static int C_paraNum = 0; /* Number of parameters */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[C_FILENBR] = { /* The file array */ { "w" } }; static const char * C_usageList[] = { "gmk_hy [] ", " -h : Display this help", " -V : Print program version and copyright", NULL }; /****************************************/ /* */ /* The main routine, which computes the */ /* source graph description. */ /* */ /****************************************/ int main ( int argc, char * argv[]) { SCOTCH_Num hdim = 1; /* Graph dimension */ SCOTCH_Num hnbr; /* Number of vertices */ SCOTCH_Num hbit; /* Most significant bit */ SCOTCH_Num hvrt; SCOTCH_Num hngb; int i; errorProg ("gmk_hy"); if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); exit (0); } fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_paraNum < 1) { /* If number of parameters not reached */ if ((hdim = atoi (argv[i])) < 1) { /* Get the dimension */ errorPrint ("main: invalid dimension '%s'", argv[i]); exit (1); } C_paraNum ++; continue; /* Process the other parameters */ } if (C_fileNum < C_FILEARGNBR) /* A file name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else { errorPrint ("main: too many file names given"); exit (1); } } else { /* If found an option name */ switch (argv[i][1]) { case 'H' : /* Give the usage message */ case 'h' : usagePrint (stdout, C_usageList); exit (0); case 'V' : fprintf (stderr, "gmk_hy, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: unprocessed option '%s'", argv[i]); exit (1); } } } fileBlockOpen (C_fileTab, C_FILENBR); /* Open all files */ hnbr = 1 << hdim; /* Compute number of vertices */ hbit = 1 << (hdim - 1); /* Compute highest bit value */ fprintf (C_filepntrsrcout, "0\n" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n0\t000\n", (SCOTCH_Num) hnbr, /* Print number of vertices */ (SCOTCH_Num) (hdim * hnbr)); /* Print number of edges (arcs) */ for (hvrt = 0; hvrt < hnbr; hvrt ++) { /* For all vertices */ fprintf (C_filepntrsrcout, "" SCOTCH_NUMSTRING "", (SCOTCH_Num) hdim); /* Output number of neighbors */ for (hngb = hbit; hngb > 0; hngb >>= 1) /* For all vertex bits */ fprintf (C_filepntrsrcout, "\t" SCOTCH_NUMSTRING, /* Write corresponding neighbor */ (SCOTCH_Num) (hvrt ^ hngb)); fprintf (C_filepntrsrcout, "\n"); } fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } scotch-6.0.4.dfsg/src/scotch/gmk_msh.c0000644002563400244210000001402012473176651022745 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gmk_msh.c **/ /** **/ /** AUTHORS : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a mesh-to-graph converter. **/ /** This module contains the main function. **/ /** **/ /** DATES : # Version 4.0 : from : 21 jan 2004 **/ /** to : 21 jan 2004 **/ /** # Version 5.0 : from : 23 dec 2007 **/ /** to : 16 mar 2008 **/ /** # Version 5.1 : from : 01 jul 2010 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GMK_MSH #include "module.h" #include "common.h" #include "scotch.h" #include "gmk_msh.h" /* ** The static and global variables. */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[2] = { /* File array */ { "r" }, { "w" } }; static const char * C_usageList[] = { "gmk_msh [ []] ", " -h : Display this help", " -V : Print program version and copyright", NULL }; /*****************************/ /* */ /* This is the main function */ /* */ /*****************************/ int main ( int argc, char * argv[]) { SCOTCH_Mesh meshdat; SCOTCH_Graph grafdat; int i; errorProg ("gmk_msh"); if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_fileNum < C_FILEARGNBR) /* File name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else { errorPrint ("main: too many file names given"); return (1); } } else { /* If found an option name */ switch (argv[i][1]) { case 'H' : /* Give help */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'V' : fprintf (stderr, "gmk_msh, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: unprocessed option '%s'", argv[i]); return (1); } } } fileBlockOpen (C_fileTab, C_FILENBR); /* Open all files */ SCOTCH_meshInit (&meshdat); SCOTCH_graphInit (&grafdat); SCOTCH_meshLoad (&meshdat, C_filepntrmshinp, -1); SCOTCH_meshCheck (&meshdat); SCOTCH_meshGraph (&meshdat, &grafdat); #ifdef SCOTCH_DEBUG_ALL if (SCOTCH_graphCheck (&grafdat) != 0) { errorPrint ("main: bad graph structure"); return (1); } #endif /* SCOTCH_DEBUG_ALL */ SCOTCH_graphSave (&grafdat, C_filepntrgrfout); fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ SCOTCH_graphExit (&grafdat); SCOTCH_meshExit (&meshdat); #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } scotch-6.0.4.dfsg/src/scotch/amk_grf.h0000644002563400244210000001060212473176651022735 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2011,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : amk_grf.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Decomposition architecture builder. **/ /** These lines are the data declarations **/ /** for the program routines. **/ /** **/ /** DATES : # Version 3.0 : from : 06 jul 1995 **/ /** to : 02 oct 1995 **/ /** # Version 3.1 : from : 26 mar 1996 **/ /** to : 26 mar 1996 **/ /** # Version 3.2 : from : 23 apr 1997 **/ /** to : 02 jun 1997 **/ /** # Version 3.3 : from : 15 may 1999 **/ /** to : 15 may 1999 **/ /** # Version 5.1 : from : 17 jul 2011 **/ /** to : 17 jul 2011 **/ /** # Version 6.0 : from : 12 nov 2014 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ File name aliases. +*/ #define C_FILENBR 3 /* Number of files in list */ #define C_FILEARGNBR 2 /* Number of files which can be arguments */ #define C_filenamegrfinp fileBlockName (C_fileTab, 0) /* Source graph input file name */ #define C_filenametgtout fileBlockName (C_fileTab, 1) /* Architecture output file name */ #define C_filenamevrtinp fileBlockName (C_fileTab, 2) /* Vertex list input file name */ #define C_filepntrgrfinp fileBlockFile (C_fileTab, 0) /* Source graph input file */ #define C_filepntrtgtout fileBlockFile (C_fileTab, 1) /* Architecture output file */ #define C_filepntrvrtinp fileBlockFile (C_fileTab, 2) /* Vertex list input file */ /*+ Process flags. +*/ #define C_FLAGVRTINP 0x0001 /* Input vertex list */ #define C_FLAGNONE 0x0000 /* Default flags */ /* ** The type and structure definitions. */ /*+ The sort structure, used to sort graph vertices by label. +*/ typedef struct C_VertSort_ { SCOTCH_Num vlblnum; /*+ Vertex label +*/ SCOTCH_Num vertnum; /*+ Vertex number +*/ } C_VertSort; scotch-6.0.4.dfsg/src/scotch/dgord.h0000644002563400244210000001154612473176651022436 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgord.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Cedric CHEVALIER **/ /** **/ /** FUNCTION : Part of a parallel sparse matrix **/ /** ordering software. **/ /** This module contains the data declara- **/ /** tions for the main routine. **/ /** **/ /** DATES : # Version 5.0 : from : 30 apr 2006 **/ /** to : 27 may 2008 **/ /** # Version 5.1 : from : 22 nov 2008 **/ /** to : 22 nov 2008 **/ /** # Version 6.0 : from : 10 nov 2014 **/ /** to : 10 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ File name aliases. +*/ #define C_FILENBR 5 /* Number of files in list */ #define C_FILEARGNBR 3 /* Number of files which can be arguments */ #define C_filenamesrcinp fileBlockName (C_fileTab, 0) /* Source graph input file name */ #define C_filenameordout fileBlockName (C_fileTab, 1) /* Ordering output file name */ #define C_filenamelogout fileBlockName (C_fileTab, 2) /* Log file name */ #define C_filenamemapout fileBlockName (C_fileTab, 3) /* Separator mapping file name */ #define C_filenametreout fileBlockName (C_fileTab, 4) /* Separator tree file name */ #define C_filepntrsrcinp fileBlockFile (C_fileTab, 0) /* Source graph input file */ #define C_filepntrordout fileBlockFile (C_fileTab, 1) /* Ordering output file */ #define C_filepntrlogout fileBlockFile (C_fileTab, 2) /* Log file */ #define C_filepntrmapout fileBlockFile (C_fileTab, 3) /* Separator mapping file */ #define C_filepntrtreout fileBlockFile (C_fileTab, 4) /* Separator tre file */ /*+ Process flags. +*/ #define C_FLAGNONE 0x0000 /* No flags */ #define C_FLAGMAPOUT 0x0001 /* Output mapping data */ #define C_FLAGTREOUT 0x0002 /* Output separator tree data */ #define C_FLAGVERBSTR 0x0004 /* Output strategy string */ #define C_FLAGVERBTIM 0x0008 /* Output timing information */ #define C_FLAGVERBMEM 0x0010 /* Output memory information */ #define C_FLAGBLOCK 0x0020 /* Output block ordering */ #define C_FLAGDEBUG 0x0040 /* Debugging */ /* ** The function prototypes. */ void dgordStatReduceOp (double *, double *, int *, MPI_Datatype *); scotch-6.0.4.dfsg/src/scotch/amk_p2.c0000644002563400244210000001475012473176651022503 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : amk_p2.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Creates the target architecture file **/ /** for a weighted path with two vertices **/ /** used to bipartition graphs in parts of **/ /** different sizes. **/ /** **/ /** DATES : # Version 3.0 : from : 17 jul 1995 **/ /** to : 17 jul 1995 **/ /** # Version 3.2 : from : 02 jun 1997 **/ /** to : 02 jun 1997 **/ /** # Version 3.4 : from : 03 feb 2000 **/ /** to : 03 feb 2000 **/ /** # Version 5.1 : from : 16 dec 2007 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define AMK_P2 #include "module.h" #include "common.h" #include "scotch.h" #include "amk_p2.h" /* ** The static variables. */ static int C_paraNum = 0; /* Number of parameters */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[C_FILENBR] = { /* File array */ { "w" } }; static const char * C_usageList[] = { "amk_p2 [ []] ", " -h : Display this help", " -V : Print program version and copyright", NULL }; /************************************/ /* */ /* The main routine, which computes */ /* the decomposition. */ /* */ /************************************/ int main ( int argc, char * argv[]) { int wght[2] = {1, 1}; /* Vertex weights */ int i; errorProg ("amk_p2"); if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_paraNum < 2) { /* If number of parameters not reached */ if ((wght[C_paraNum ++] = atoi (argv[i])) < 1) { /* Get vertex weights */ errorPrint ("main: invalid weight '%s'", argv[i]); return (1); } continue; /* Process remaining parameters */ } if (C_fileNum < C_FILEARGNBR) /* File name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else { errorPrint ("main: too many file names given"); return (1); } } else { /* If found an option name */ switch (argv[i][1]) { case 'H' : /* Give the usage message */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'V' : fprintf (stderr, "amk_p2, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: unprocessed option '%s'", argv[i]); return (1); } } } fileBlockOpen (C_fileTab, C_FILENBR); /* Open all files */ fprintf (C_filepntrtgtout, "cmpltw\t2\t" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n", /* Print target description */ (SCOTCH_Num) wght[0], (SCOTCH_Num) wght[1]); fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } scotch-6.0.4.dfsg/src/scotch/gmk_hy.h0000644002563400244210000000665412473176651022621 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gmk_hy.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the data declara- **/ /** tions for the hypercube source graph **/ /** building program. **/ /** **/ /** DATES : # Version 2.0 : from : 03 nov 1994 **/ /** to 03 nov 1994 **/ /** # Version 3.0 : from : 11 jul 1995 **/ /** to 11 jul 1995 **/ /** # Version 3.2 : from : 03 jun 1997 **/ /** to : 03 jun 1997 **/ /** # Version 3.3 : from : 06 oct 1998 **/ /** to : 06 oct 1998 **/ /** # Version 6.0 : from : 12 nov 2014 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ File name aliases. +*/ #define C_FILENBR 1 /* Number of files in list */ #define C_FILEARGNBR 1 /* Number of files which can be arguments */ #define C_filenamesrcout fileBlockName (C_fileTab, 0) /* Source graph output file name */ #define C_filepntrsrcout fileBlockFile (C_fileTab, 0) /* Source graph output file */ scotch-6.0.4.dfsg/src/scotch/gmtst.c0000644002563400244210000002004212473176651022457 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gmtst.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This program computes statistics on **/ /** graph mappings. **/ /** **/ /** DATES : # Version 3.1 : from : 17 jul 1996 **/ /** to 23 jul 1996 **/ /** # Version 3.2 : from : 02 jun 1997 **/ /** to : 16 jul 1997 **/ /** # Version 3.3 : from : 07 jun 1999 **/ /** to : 07 jun 1999 **/ /** # Version 4.0 : from : 12 feb 2004 **/ /** to 16 nov 2005 **/ /** # Version 5.0 : from : 22 jan 2008 **/ /** to 16 mar 2008 **/ /** # Version 5.1 : from : 01 jul 2010 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GMTST #include "module.h" #include "common.h" #include "scotch.h" #include "gmtst.h" /* ** The static variables. */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[C_FILENBR] = { /* The file array */ { "r" }, { "r" }, { "r" }, { "w" } }; static const char * C_usageList[] = { /* Usage */ "gmtst [ [ [ []]]] ", " -h : Display this help", " -V : Print program version and copyright", "", NULL }; /******************************/ /* */ /* This is the main function. */ /* */ /******************************/ int main ( int argc, char * argv[]) { SCOTCH_Graph grafdat; /* Source graph */ SCOTCH_Num vertnbr; /* Source graph size */ SCOTCH_Num * vlbltab; /* Source graph vertex label array */ SCOTCH_Arch archdat; /* Target architecture */ SCOTCH_Num archnbr; /* Size of the target architecture */ SCOTCH_Mapping mappdat; /* Mapping data */ int i; errorProg ("gmtst"); if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_fileNum < C_FILEARGNBR) /* File name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else { errorPrint ("main: too many file names given"); return (1); } } else { /* If found an option name */ switch (argv[i][1]) { case 'H' : /* Give the usage message */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'M' : /* No mapping flag */ case 'm' : C_filenamemapinp = "-"; /* Default name to avoid opening */ C_filepntrmapinp = NULL; /* NULL file pointer means no file */ break; case 'V' : fprintf (stderr, "gmtst, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: unprocessed option '%s'", argv[i]); return (1); } } } fileBlockOpen (C_fileTab, C_FILENBR); /* Open all files */ SCOTCH_graphInit (&grafdat); /* Create graph structure */ SCOTCH_graphLoad (&grafdat, C_filepntrsrcinp, -1, 0); /* Read source graph */ SCOTCH_graphData (&grafdat, NULL, /* Get graph characteristics */ &vertnbr, NULL, NULL, NULL, &vlbltab, NULL, NULL, NULL); SCOTCH_archInit (&archdat); /* Create architecture structure */ SCOTCH_archLoad (&archdat, C_filepntrtgtinp); /* Read target architecture */ if (strcmp (SCOTCH_archName (&archdat), "term") == 0) { /* If target architecture is variable-sized */ errorPrint ("main: variable-sized architectures cannot be mapped"); return (1); } archnbr = SCOTCH_archSize (&archdat); /* Get architecture size */ SCOTCH_graphMapInit (&grafdat, &mappdat, &archdat, NULL); /* Create mapping structure */ if (SCOTCH_graphMapLoad (&grafdat, &mappdat, C_filepntrmapinp) != 0) errorPrint ("main: bad input (1)"); SCOTCH_graphMapView (&grafdat, &mappdat, C_filepntrdatout); /* Display mapping statistics */ fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ SCOTCH_graphMapExit (&grafdat, &mappdat); SCOTCH_archExit (&archdat); SCOTCH_graphExit (&grafdat); #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } scotch-6.0.4.dfsg/src/scotch/gscat.c0000644002563400244210000002627612473176651022441 0ustar trophimeutilisateurs du domaine/* Copyright 2009-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gscat.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This program writes a centralized **/ /** source graph file in the form of a **/ /** distributed source graph. **/ /** **/ /** DATES : # Version 5.1 : from : 26 apr 2009 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GSCAT #include "module.h" #include "common.h" #include "scotch.h" #include "gscat.h" /* ** The static variables. */ static int C_paraNum = 0; /* Number of parameters */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[C_FILENBR] = { /* File array */ { "r" }, { "w" } }; static const char * C_usageList[] = { /* Usage */ "gscat ", " -h : Display this help", " -V : Print program version and copyright", NULL }; /******************************/ /* */ /* This is the main function. */ /* */ /******************************/ int main ( int argc, char * argv[]) { SCOTCH_Num p[1] = { 1 }; /* Number of parts */ int i; errorProg ("gscat"); if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_paraNum < 1) { /* If number of parameters not reached */ if ((p[C_paraNum ++] = atoi (argv[i])) < 1) { /* Get number of parts */ errorPrint ("main: invalid number of parts '%s'", argv[i]); return (1); } continue; /* Process the other parameters */ } if (C_fileNum < C_FILEARGNBR) /* A file name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else { errorPrint ("main: too many file names given"); return (1); } } else { /* If found an option name */ switch (argv[i][1]) { case 'H' : /* Give the usage message */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'V' : fprintf (stderr, "gscat, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2009-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: unprocessed option '%s'", argv[i]); return (1); } } } fileBlockOpen (C_fileTab, 1); /* Open input graph file */ C_graphScat (C_filepntrsrcinp, p[0], C_filenamesrcout); fileBlockClose (C_fileTab, 1); /* Always close explicitely to end eventual (un)compression tasks */ #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } static int C_graphScat ( FILE * const stream, SCOTCH_Num procnbr, char * const nameptr) { SCOTCH_Num versval; SCOTCH_Num propval; char proptab[4]; int flagtab[3]; SCOTCH_Num baseval; SCOTCH_Num vertglbnbr; SCOTCH_Num edgeglbnbr; SCOTCH_Num procnum; if (intLoad (stream, &versval) != 1) { /* Read version number */ errorPrint ("C_graphScat: bad input (1)"); return (1); } if (versval != 0) { /* If version not zero */ errorPrint ("C_graphScat: only centralized graphs supported"); return (1); } if ((intLoad (stream, &vertglbnbr) != 1) || /* Read rest of header */ (intLoad (stream, &edgeglbnbr) != 1) || (intLoad (stream, &baseval) != 1) || (intLoad (stream, &propval) != 1) || (propval < 0) || (propval > 111)) { errorPrint ("C_graphScat: bad input (2)"); return (1); } sprintf (proptab, "%3.3d", (int) propval); /* Compute file properties */ flagtab[0] = proptab[0] - '0'; /* Vertex labels flag */ flagtab[1] = proptab[1] - '0'; /* Edge weights flag */ flagtab[2] = proptab[2] - '0'; /* Vertex loads flag */ for (procnum = 0; procnum < procnbr; procnum ++) { char * nametmp; FILE * ostream; SCOTCH_Num vertlocnbr; SCOTCH_Num vertlocnum; SCOTCH_Num edgelocnbr; nametmp = nameptr; ostream = NULL; if (fileNameDistExpand (&nametmp, procnbr, procnum, -1) == 0) { ostream = fopen (nametmp, "w+"); memFree (nametmp); /* Expanded name no longer needed anyway */ } if (ostream == NULL) { errorPrint ("C_graphScat: cannot open file"); return (1); } vertlocnbr = DATASIZE (vertglbnbr, procnbr, procnum); if (fprintf (ostream, "2\n" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n" SCOTCH_NUMSTRING "\t%015d\n" SCOTCH_NUMSTRING "\t%3s\n", /* Write file header */ (SCOTCH_Num) procnbr, (SCOTCH_Num) procnum, (SCOTCH_Num) vertglbnbr, (SCOTCH_Num) edgeglbnbr, (SCOTCH_Num) vertlocnbr, 0, /* Number of edges not yet known */ (SCOTCH_Num) baseval, proptab) == EOF) { errorPrint ("C_graphScat: bad output (1)"); return (1); } for (vertlocnum = edgelocnbr = 0; vertlocnum < vertlocnbr; vertlocnum ++) { SCOTCH_Num degrval; if (flagtab[0] != 0) { /* If must read label */ SCOTCH_Num vlblval; /* Value where to read vertex label */ if (intLoad (stream, &vlblval) != 1) { /* Read label data */ errorPrint ("C_graphScat: bad input (3)"); return (1); } intSave (ostream, vlblval); putc ('\t', ostream); } if (flagtab[2] != 0) { /* If must read vertex load */ SCOTCH_Num veloval; /* Value where to read vertex load */ if (intLoad (stream, &veloval) != 1) { /* Read vertex load data */ errorPrint ("C_graphScat: bad input (4)"); return (1); } intSave (ostream, veloval); putc ('\t', ostream); } if (intLoad (stream, °rval) != 1) { /* Read vertex degree */ errorPrint ("C_graphScat: bad input (5)"); return (1); } intSave (ostream, degrval); edgelocnbr += degrval; for ( ; degrval > 0; degrval --) { SCOTCH_Num edgeval; /* Value where to read edge end */ if (flagtab[1] != 0) { /* If must read edge load */ SCOTCH_Num edloval; /* Value where to read edge load */ if (intLoad (stream, &edloval) != 1) { /* Read edge load data */ errorPrint ("C_graphScat: bad input (6)"); return (1); } putc ('\t', ostream); intSave (ostream, edloval); } if (intLoad (stream, &edgeval) != 1) { /* Read edge data */ errorPrint ("C_graphScat: bad input (7)"); return (1); } putc ('\t', ostream); intSave (ostream, edgeval); } putc ('\n', ostream); } rewind (ostream); if (fprintf (ostream, "2\n" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n" SCOTCH_NUMSTRING "\t%015lld\n" SCOTCH_NUMSTRING "\t%3s\n", /* Write file header */ (SCOTCH_Num) procnbr, (SCOTCH_Num) procnum, (SCOTCH_Num) vertglbnbr, (SCOTCH_Num) edgeglbnbr, (SCOTCH_Num) vertlocnbr, (long long) edgelocnbr, /* Now we know the exact number of edges */ (SCOTCH_Num) baseval, proptab) == EOF) { errorPrint ("C_graphScat: bad output (2)"); return (1); } fclose (ostream); } return (0); } scotch-6.0.4.dfsg/src/scotch/mmk_m3.c0000644002563400244210000003056512473176651022517 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mmk_m3.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Creates the source meshes for **/ /** tridimensional mesh source graphs. **/ /** **/ /** DATES : # Version 4.0 : from : 26 sep 2002 **/ /** to : 17 feb 2004 **/ /** # Version 5.0 : from : 13 dec 2007 **/ /** to : 16 mar 2008 **/ /** # Version 5.1 : from : 01 jul 2010 **/ /** to : 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 12 nov 2014 **/ /** **/ /** NOTES : # The nodes and elements of the **/ /** (dX,dY,dZ) mesh are numbered so that **/ /** t(0,0,0) = 0, t(1,0,0) = 1, **/ /** t(dX - 1, 0, 0) = dX - 1, t(0,1,0) = **/ /** dX, t (0, 0, 1) = dX * dY - 1, **/ /** and t(x,y,z) = (z * dY + y) * dX + x. **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define MMK_M3 #include "module.h" #include "common.h" #include "scotch.h" #include "mmk_m3.h" /* ** The static definitions. */ static int C_paraNum = 0; /* Number of parameters */ static int C_fileNum = 0; /* Number of file in arg list */ static File C_fileTab[C_FILENBR] = { /* The file array */ { "w" }, { "w" } }; static const int C_nghbTab[4] = { 8, 4, 2, 1 }; static const char * C_usageList[] = { "mmk_m3 [ [ []]] ", " -g : Output mesh geometry to ", " -h : Display this help", " -V : Print program version and copyright", NULL }; /****************************************/ /* */ /* The main routine, which computes the */ /* source graph description. */ /* */ /****************************************/ int main ( int argc, char * argv[]) { SCOTCH_Num e[3] = { 1, 1, 1 }; /* Mesh element dimensions */ SCOTCH_Num n[3]; /* Mesh node dimensions */ SCOTCH_Num c[3]; /* Vertex coordinates */ SCOTCH_Num velmnbr; /* First node number */ int flagval; /* Process flags */ int i; errorProg ("mmk_m3"); flagval = C_FLAGDEFAULT; /* Set default flags */ if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_paraNum < 3) { /* If number of parameters not reached */ if ((e[C_paraNum ++] = atoi (argv[i])) < 1) { /* Get the dimension */ errorPrint ("main: invalid dimension '%s'", argv[i]); return (1); } continue; /* Process the other parameters */ } if (C_fileNum < C_FILEARGNBR) /* A file name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else { errorPrint ("main: too many file names given"); return (1); } } else { /* If found an option name */ switch (argv[i][1]) { case 'G' : /* Output mesh geometry */ case 'g' : flagval |= C_FLAGGEOOUT; if (argv[i][2] != '\0') C_filenamegeoout = &argv[i][2]; break; case 'H' : /* Give program usage message */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'V' : fprintf (stderr, "mmk_m3, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); default : errorPrint ("main: unprocessed option '%s'", argv[i]); return (1); } } } fileBlockOpen (C_fileTab, C_FILENBR); /* Open all files */ n[0] = e[0] + 1; n[1] = e[1] + 1; n[2] = e[2] + 1; velmnbr = e[0] * e[1] * e[2]; fprintf (C_filepntrmshout, "1\n" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n0\t" SCOTCH_NUMSTRING "\t000\n", /* Print mesh file header */ (SCOTCH_Num) velmnbr, (SCOTCH_Num) (n[0] * n[1] * n[2]), (SCOTCH_Num) ((velmnbr + (n[0] * n[1] * n[2]) - (n[0] * n[1] + n[0] * n[2] + n[1] * n[2]) + n[0] + n[1] + n[2] - 1) * 8), (SCOTCH_Num) velmnbr); for (c[2] = 0; c[2] < e[2]; c[2] ++) { /* Output element neighbor list */ for (c[1] = 0; c[1] < e[1]; c[1] ++) { for (c[0] = 0; c[0] < e[0]; c[0] ++) fprintf (C_filepntrmshout, "8\t" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n", /* Output neighbors of element */ (SCOTCH_Num) ((c[2] * n[1] + c[1]) * n[0] + c[0]), (SCOTCH_Num) ((c[2] * n[1] + c[1]) * n[0] + (c[0] + 1)), (SCOTCH_Num) ((c[2] * n[1] + (c[1] + 1)) * n[0] + c[0]), (SCOTCH_Num) ((c[2] * n[1] + (c[1] + 1)) * n[0] + (c[0] + 1)), (SCOTCH_Num) (((c[2] + 1) * n[1] + c[1]) * n[0] + c[0]), (SCOTCH_Num) (((c[2] + 1) * n[1] + c[1]) * n[0] + (c[0] + 1)), (SCOTCH_Num) (((c[2] + 1) * n[1] + (c[1] + 1)) * n[0] + c[0]), (SCOTCH_Num) (((c[2] + 1) * n[1] + (c[1] + 1)) * n[0] + (c[0] + 1))); } } for (c[2] = 0; c[2] < n[2]; c[2] ++) { /* Output node neighbor list */ for (c[1] = 0; c[1] < n[1]; c[1] ++) { for (c[0] = 0; c[0] < n[0]; c[0] ++) { fprintf (C_filepntrmshout, "%d", /* Output number of neighboring elements */ C_nghbTab[(((c[0] != 0) && (c[0] != e[0])) ? 0 : 1) + (((c[1] != 0) && (c[1] != e[1])) ? 0 : 1) + (((c[2] != 0) && (c[2] != e[2])) ? 0 : 1)]); if (c[2] != 0) { /* Output neighbors of nodes */ if (c[1] != 0) { if (c[0] != 0) fprintf (C_filepntrmshout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) (((c[2] - 1) * e[1] + (c[1] - 1)) * e[0] + (c[0] - 1))); if (c[0] != e[0]) fprintf (C_filepntrmshout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) (((c[2] - 1) * e[1] + (c[1] - 1)) * e[0] + c[0])); } if (c[1] != e[1]) { if (c[0] != 0) fprintf (C_filepntrmshout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) (((c[2] - 1) * e[1] + c[1]) * e[0] + (c[0] - 1))); if (c[0] != e[0]) fprintf (C_filepntrmshout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) (((c[2] - 1) * e[1] + c[1]) * e[0] + c[0])); } } if (c[2] != e[2]) { if (c[1] != 0) { if (c[0] != 0) fprintf (C_filepntrmshout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) ((c[2] * e[1] + (c[1] - 1)) * e[0] + (c[0] - 1))); if (c[0] != e[0]) fprintf (C_filepntrmshout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) ((c[2] * e[1] + (c[1] - 1)) * e[0] + c[0])); } if (c[1] != e[1]) { if (c[0] != 0) fprintf (C_filepntrmshout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) ((c[2] * e[1] + c[1]) * e[0] + (c[0] - 1))); if (c[0] != e[0]) fprintf (C_filepntrmshout, "\t" SCOTCH_NUMSTRING, (SCOTCH_Num) ((c[2] * e[1] + c[1]) * e[0] + c[0])); } } fprintf (C_filepntrmshout, "\n"); } } } if (flagval & C_FLAGGEOOUT) { /* If geometry is wanted */ fprintf (C_filepntrgeoout, "3\n" SCOTCH_NUMSTRING "\n", /* Output geometry file header */ (SCOTCH_Num) (velmnbr + n[0] * n[1] * n[2])); for (c[2] = 0; c[2] < e[2]; c[2] ++) { /* Output element coordinates */ for (c[1] = 0; c[1] < e[1]; c[1] ++) { for (c[0] = 0; c[0] < e[0]; c[0] ++) fprintf (C_filepntrgeoout, SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING ".5\t" SCOTCH_NUMSTRING ".5\t" SCOTCH_NUMSTRING ".5\n", (SCOTCH_Num) (((c[2] * e[1]) + c[1]) * e[0] + c[0]), (SCOTCH_Num) c[0], (SCOTCH_Num) (e[1] - 1 - c[1]), (SCOTCH_Num) c[2]); } } for (c[2] = 0; c[2] <= e[2]; c[2] ++) { /* Output node coordinates */ for (c[1] = 0; c[1] <= e[1]; c[1] ++) { for (c[0] = 0; c[0] <= e[0]; c[0] ++) fprintf (C_filepntrgeoout, SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n", (SCOTCH_Num) (velmnbr + ((c[2] * n[1]) + c[1]) * n[0] + c[0]), (SCOTCH_Num) c[0], (SCOTCH_Num) (e[1] - c[1]), (SCOTCH_Num) c[2]); } } } fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } scotch-6.0.4.dfsg/src/scotch/mmk_m2.h0000644002563400244210000000665012473176651022521 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mmk_m2.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the data declara- **/ /** tions for the bidimensional finite **/ /** element grid mesh building program. **/ /** **/ /** DATES : # Version 4.0 : from : 26 sep 2002 **/ /** to : 26 sep 2002 **/ /** # Version 6.0 : from : 12 nov 2014 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ File name aliases. +*/ #define C_FILENBR 2 /* Number of files in list */ #define C_FILEARGNBR 1 /* Number of files which can be arguments */ #define C_filenamemshout fileBlockName (C_fileTab, 0) /* Source mesh output file name */ #define C_filenamegeoout fileBlockName (C_fileTab, 1) /* Geometry mesh output file name */ #define C_filepntrmshout fileBlockFile (C_fileTab, 0) /* Source mesh output file */ #define C_filepntrgeoout fileBlockFile (C_fileTab, 1) /* Geometry mesh output file */ /*+ Process flags. +*/ #define C_FLAGGEOOUT 0x0001 /* Output mesh geometry */ #define C_FLAGDEFAULT 0x0000 /* Default flags */ scotch-6.0.4.dfsg/src/scotch/dgmap.h0000644002563400244210000001044212473176651022421 0ustar trophimeutilisateurs du domaine/* Copyright 2008,2010,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : dgmap.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a parallel static mapper. **/ /** These lines are the data declaration **/ /** for the main routine. **/ /** **/ /** DATES : # Version 5.1 : from : 12 jun 2008 **/ /** to : 18 jul 2011 **/ /** # Version 6.0 : from : 10 nov 2014 **/ /** to : 10 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ File name aliases. +*/ #define C_FILENBR 4 /* Number of files in list */ #define C_filenamesrcinp fileBlockName (C_fileTab, 0) /* Source graph input file name */ #define C_filenametgtinp fileBlockName (C_fileTab, 1) /* Target architecture input file name */ #define C_filenamemapout fileBlockName (C_fileTab, 2) /* Mapping result output file name */ #define C_filenamelogout fileBlockName (C_fileTab, 3) /* Log file name */ #define C_filepntrsrcinp fileBlockFile (C_fileTab, 0) /* Source graph input file */ #define C_filepntrtgtinp fileBlockFile (C_fileTab, 1) /* Target architecture input file */ #define C_filepntrmapout fileBlockFile (C_fileTab, 2) /* Mapping result output file */ #define C_filepntrlogout fileBlockFile (C_fileTab, 3) /* Log file */ /*+ Process flags. +*/ #define C_FLAGNONE 0x0000 /* No flags */ #define C_FLAGPART 0x0001 /* Partitioning */ #define C_FLAGVERBSTR 0x0002 /* Verbose flags */ #define C_FLAGVERBTIM 0x0004 #define C_FLAGVERBMAP 0x0008 #define C_FLAGVERBMEM 0x0010 #define C_FLAGDEBUG 0x0020 /* Debugging */ #define C_FLAGKBALVAL 0x0040 /* Imbalance tolerance */ #define C_FLAGCLUSTER 0x0080 /* Clustering */ /* ** The function prototypes. */ void dgmapStatReduceOp (double *, double *, int *, MPI_Datatype *); scotch-6.0.4.dfsg/src/scotch/mord.h0000644002563400244210000000773212473176651022302 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : mord.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a mesh orderer. **/ /** This module contains the data declara- **/ /** tions for the main routine. **/ /** **/ /** DATES : # Version 4.0 : from : 15 nov 2002 **/ /** to : 22 oct 2003 **/ /** # Version 6.0 : from : 12 nov 2014 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines. */ /*+ File name aliases. +*/ #define C_FILENBR 4 /* Number of files in list */ #define C_FILEARGNBR 3 /* Number of files which can be arguments */ #define C_filenamesrcinp fileBlockName (C_fileTab, 0) /* Source graph input file name */ #define C_filenameordout fileBlockName (C_fileTab, 1) /* Ordering output file name */ #define C_filenamelogout fileBlockName (C_fileTab, 2) /* Log file name */ #define C_filenamemapout fileBlockName (C_fileTab, 3) /* Separator mapping file name */ #define C_filepntrsrcinp fileBlockFile (C_fileTab, 0) /* Source graph input file */ #define C_filepntrordout fileBlockFile (C_fileTab, 1) /* Ordering output file */ #define C_filepntrlogout fileBlockFile (C_fileTab, 2) /* Log file */ #define C_filepntrmapout fileBlockFile (C_fileTab, 3) /* Separator mapping file */ /*+ Process flags. +*/ #define C_FLAGNONE 0x0000 /* No flags */ #define C_FLAGMAPOUT 0x0001 /* Output mapping data */ #define C_FLAGVERBSTR 0x0002 /* Output strategy string */ #define C_FLAGVERBTIM 0x0004 /* Output timing information */ scotch-6.0.4.dfsg/src/scotch/gmap.c0000644002563400244210000007175512473176651022266 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gmap.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** Sebastien FOURESTIER (v6.0) **/ /** **/ /** FUNCTION : Part of a graph mapping software. **/ /** This module contains the main function. **/ /** **/ /** DATES : # Version 0.0 : from : 05 jan 1993 **/ /** to 12 may 1993 **/ /** # Version 1.1 : from : 15 oct 1993 **/ /** to 15 oct 1993 **/ /** # Version 1.3 : from : 06 apr 1994 **/ /** to 18 may 1994 **/ /** # Version 2.0 : from : 06 jun 1994 **/ /** to 17 nov 1994 **/ /** # Version 2.1 : from : 07 apr 1995 **/ /** to 18 jun 1995 **/ /** # Version 3.0 : from : 01 jul 1995 **/ /** to 02 oct 1995 **/ /** # Version 3.1 : from : 07 nov 1995 **/ /** to 25 apr 1996 **/ /** # Version 3.2 : from : 24 sep 1996 **/ /** to 26 may 1998 **/ /** # Version 3.3 : from : 19 oct 1998 **/ /** to : 30 mar 1999 **/ /** # Version 3.4 : from : 03 feb 2000 **/ /** to : 03 feb 2000 **/ /** # Version 4.0 : from : 16 jan 2004 **/ /** to : 27 dec 2004 **/ /** # Version 5.0 : from : 23 dec 2007 **/ /** to : 18 jun 2008 **/ /** # Version 5.1 : from : 30 jun 2010 **/ /** to : 31 aug 2011 **/ /** # Version 6.0 : from : 29 may 2010 **/ /** to : 12 nov 2014 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define GMAP #include "module.h" #include "common.h" #include "scotch.h" #include "gmap.h" /* ** The static variables. */ static int C_partNbr = 1; /* Default number of parts / cluster size */ static int C_paraNum = 0; /* Number of parameters */ static int C_paraNbr = 0; /* No parameters for mapping */ static int C_fileNum = 0; /* Number of file in arg list */ static int C_fileNbr = 4; /* Number of files for mapping */ static File C_fileTab[C_FILENBR] = { /* File array */ { "r" }, { "r" }, { "w" }, { "w" }, { "r" }, { "r" }, { "r" } }; static const char * C_usageList[] = { /* Usage */ "gmap [ [ [ []]]] ", "gpart [] [ [ []]] ", " -b : Load imbalance tolerance (default: 0.05)", " -c : Choose default mapping strategy according to one or several of :", " b : enforce load balance as much as possible", " q : privilege quality over speed (default)", " r : use only recursive bipartitioning", " s : privilege speed over quality", " t : enforce safety", " -f : Fixed vertices input file", " -h : Display this help", " -m : Set mapping strategy (see user's manual)", " -o : Use partitioning with overlap (only for gpart)", " -q : Do graph clustering instead of graph partitioning (for gpart)", " -q : Do graph clustering instead of static mapping (for gmap)", " -ro : Old mapping input file (for remapping)", " -rr : Edge migration ratio (for remapping, default: 1)", " -rv : Vertex migration cost input file (for remapping)", " -s : Force unity weights on :", " e : edges", " v : vertices", " -V : Print program version and copyright", " -v : Set verbose mode to :", " m : mapping information", " s : strategy information", " t : timing information", "", "See default strategy with option '-vs'", NULL }; static const SCOTCH_Num C_loadOne = 1; /******************************/ /* */ /* This is the main function. */ /* */ /******************************/ int main ( int argc, char * argv[]) { SCOTCH_Graph grafdat; /* Source graph */ SCOTCH_Num grafflag; /* Source graph properties */ SCOTCH_Arch archdat; /* Target architecture */ SCOTCH_Strat stradat; /* Mapping strategy */ char * straptr; /* Strategy string to use */ SCOTCH_Num straval; SCOTCH_Mapping mappdat; /* Mapping data */ SCOTCH_Mapping mapodat; /* Old mapping data */ SCOTCH_Num * restrict parttab; /* Partition array */ SCOTCH_Num * restrict vmlotab; /* Vertex migration cost array */ SCOTCH_Num vertnbr; /* Number of graph vertices */ Clock runtime[2]; /* Timing variables */ int flagval; double kbalval; /* Imbalance tolerance value */ double emraval; /* Edge migration ratio */ int i, j; flagval = C_FLAGNONE; /* Default behavior */ kbalval = 0.01; /* Default imbalance */ emraval = 1; /* Default edge migration ratio */ straval = 0; /* No strategy flags */ straptr = NULL; vmlotab = NULL; #ifdef SCOTCH_COMPILE_PART flagval |= C_FLAGPART; C_paraNbr = 1; /* One more parameter */ C_fileNbr = 3; /* One less file to provide */ errorProg ("gpart"); #else errorProg ("gmap"); #endif /* SCOTCH_COMPILE_PART */ if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */ usagePrint (stdout, C_usageList); return (0); } grafflag = 0; /* Use vertex and edge weights */ SCOTCH_stratInit (&stradat); /* Set default mapping strategy */ fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */ for (i = 1; i < argc; i ++) { /* Loop for all option codes */ if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */ if (C_paraNum < C_paraNbr) { /* If number of parameters not reached */ if ((C_partNbr = atoi (argv[i])) < 1) /* Get the number of parts */ errorPrint ("main: invalid number of parts '%s'", argv[i]); C_paraNum ++; continue; /* Process the other parameters */ } if (C_fileNum < C_fileNbr) /* A file name has been given */ fileBlockName (C_fileTab, C_fileNum ++) = argv[i]; else errorPrint ("main: too many file names given"); } else { /* If found an option name */ switch (argv[i][1]) { case 'B' : case 'b' : flagval |= C_FLAGKBALVAL; kbalval = atof (&argv[i][2]); if ((kbalval < 0.0) || (kbalval > 1.0) || ((kbalval == 0.0) && ((argv[i][2] != '0') && (argv[i][2] != '.')))) { errorPrint ("main: invalid load imbalance ratio"); } break; case 'C' : case 'c' : /* Strategy selection parameters */ for (j = 2; argv[i][j] != '\0'; j ++) { switch (argv[i][j]) { case 'B' : case 'b' : straval |= SCOTCH_STRATBALANCE; break; case 'Q' : case 'q' : straval |= SCOTCH_STRATQUALITY; break; case 'R' : case 'r' : straval |= SCOTCH_STRATRECURSIVE; break; case 'S' : case 's' : straval |= SCOTCH_STRATSPEED; break; case 'T' : case 't' : straval |= SCOTCH_STRATSAFETY; break; default : errorPrint ("main: invalid strategy selection option '%c' after '-C'", argv[i][j]); } } break; case 'F' : case 'f' : /* Fixed vertex file */ flagval |= C_FLAGFIXED; C_filenamevfxinp = &argv[i][2]; break; case 'H' : /* Give the usage message */ case 'h' : usagePrint (stdout, C_usageList); return (0); case 'M' : case 'm' : straptr = &argv[i][2]; break; case 'O' : case 'o' : flagval |= C_FLAGPARTOVL; break; case 'Q' : case 'q' : flagval |= C_FLAGCLUSTER; if ((flagval & C_FLAGPART) != 0) { /* If partitioning program */ if (argv[i][2] != '\0') errorPrint ("main: invalid parameter '%s' after '-q' for gpart", argv[i] + 2); } else { if (argv[i][1] == '\0') errorPrint ("main: missing parameter after '-q' for gmap"); if ((C_partNbr = atoi (argv[i] + 2)) < 1) /* Get maximum cluster load */ errorPrint ("main: invalid cluster load '%s'", argv[i] + 2); } break; case 'R' : case 'r' : /* Remapping parameters */ switch (argv[i][2]) { case 'O' : case 'o' : /* Old mapping input file */ flagval |= C_FLAGRMAPOLD; C_filenamemaoinp = &argv[i][3]; break; case 'R' : case 'r' : /* Edge migration ratio */ flagval |= C_FLAGRMAPRAT; emraval = atof (&argv[i][3]); if (emraval <= 0.0) errorPrint ("main: invalid edge migration ratio"); break; case 'V' : case 'v' : /* Vertex migration cost */ flagval |= C_FLAGRMAPCST; C_filenamevmlinp = &argv[i][3]; break; default : errorPrint ("main: invalid remapping option '%c'", argv[i][2]); } break; case 'S' : case 's' : /* Source graph parameters */ for (j = 2; argv[i][j] != '\0'; j ++) { switch (argv[i][j]) { case 'E' : case 'e' : grafflag |= 2; /* Do not load edge weights */ break; case 'V' : case 'v' : grafflag |= 1; /* Do not load vertex weights */ break; default : errorPrint ("main: invalid source graph option '%c'", argv[i][j]); } } break; case 'V' : fprintf (stderr, "gmap/gpart, version " SCOTCH_VERSION_STRING "\n"); fprintf (stderr, "Copyright 2004,2007,2008,2010-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n"); fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n"); return (0); case 'v' : /* Output control info */ for (j = 2; argv[i][j] != '\0'; j ++) { switch (argv[i][j]) { case 'M' : case 'm' : flagval |= C_FLAGVERBMAP; break; case 'S' : case 's' : flagval |= C_FLAGVERBSTR; break; case 'T' : case 't' : flagval |= C_FLAGVERBTIM; break; default : errorPrint ("main: unprocessed parameter '%c' in '%s'", argv[i][j], argv[i]); } } break; default : errorPrint ("main: unprocessed option '%s'", argv[i]); } } } if ((flagval & C_FLAGPART) != 0) { /* If program run as the partitioner */ fileBlockName (C_fileTab, 3) = fileBlockName (C_fileTab, 2); /* Put provided file names at their right place */ fileBlockName (C_fileTab, 2) = fileBlockName (C_fileTab, 1); fileBlockName (C_fileTab, 1) = "-"; } fileBlockOpen (C_fileTab, C_FILENBR); /* Open all files */ clockInit (&runtime[0]); clockStart (&runtime[0]); SCOTCH_graphInit (&grafdat); /* Create graph structure */ SCOTCH_graphLoad (&grafdat, C_filepntrsrcinp, -1, grafflag); /* Read source graph */ SCOTCH_archInit (&archdat); /* Create architecture structure */ if ((flagval & C_FLAGPART) != 0) { /* If program run as the partitioner */ if ((flagval & C_FLAGCLUSTER) != 0) /* If program run as graph clustering */ SCOTCH_archVcmplt (&archdat); /* Create a variable-sized complete graph */ else /* Program is run as plain graph partitioner */ SCOTCH_archCmplt (&archdat, C_partNbr); /* Create a complete graph of proper size */ } else { SCOTCH_archLoad (&archdat, C_filepntrtgtinp); /* Read target architecture */ if ((flagval & C_FLAGCLUSTER) == 0) /* If part size not to be preserved */ C_partNbr = SCOTCH_archSize (&archdat); else { if (SCOTCH_archVar (&archdat) == 0) errorPrint ("main: non variable-sized architecture provided while '-q' flag set"); } } if (((flagval & (C_FLAGPART | C_FLAGPARTOVL)) == C_FLAGPARTOVL) && /* If the mapper was asked to compute an overlap */ (strcmp (SCOTCH_archName (&archdat), "cmplt") != 0)) /* And the given target architecture is not a complete graph */ errorPrint ("main: option '-o' only valid for graph partitioning"); if ((flagval & (C_FLAGPARTOVL | C_FLAGCLUSTER)) == (C_FLAGPARTOVL | C_FLAGCLUSTER)) errorPrint ("main: options '-o' and '-q' are exclusive"); if ((flagval & (C_FLAGPARTOVL | C_FLAGFIXED)) == (C_FLAGPARTOVL | C_FLAGFIXED)) errorPrint ("main: options '-o' and '-f' are exclusive"); if ((flagval & (C_FLAGPARTOVL | C_FLAGRMAPOLD)) == (C_FLAGPARTOVL | C_FLAGRMAPOLD)) errorPrint ("main: options '-o' and '-ro' are exclusive"); if (((flagval & C_FLAGRMAPOLD) == 0) && (((flagval & C_FLAGRMAPRAT) != 0) || ((flagval & C_FLAGRMAPCST) != 0))) errorPrint ("main: an old mapping file must be provided ('-ro' flag) when '-rr' or '-rv' flags are set"); if ((straval != 0) || ((flagval & C_FLAGKBALVAL) != 0)) { if (straptr != NULL) errorPrint ("main: options '-b' / '-c' and '-m' are exclusive"); if ((flagval & C_FLAGPARTOVL) != 0) /* If overlap partitioning wanted */ SCOTCH_stratGraphPartOvlBuild (&stradat, straval, (SCOTCH_Num) C_partNbr, kbalval); else if ((flagval & C_FLAGCLUSTER) != 0) /* If clustering wanted */ SCOTCH_stratGraphClusterBuild (&stradat, straval, (SCOTCH_Num) C_partNbr, 1.0, kbalval); else SCOTCH_stratGraphMapBuild (&stradat, straval, (SCOTCH_Num) C_partNbr, kbalval); } SCOTCH_graphSize (&grafdat, &vertnbr, NULL); if ((parttab = memAlloc (vertnbr * sizeof (SCOTCH_Num))) == NULL) /* Allocate by hand in case of overlap partitioning */ errorPrint ("main: out of memory"); if ((flagval & C_FLAGPARTOVL) == 0) { if ((flagval & C_FLAGFIXED) != 0) SCOTCH_graphTabLoad (&grafdat, parttab, C_filepntrvfxinp); if ((flagval & C_FLAGRMAPOLD) != 0) { SCOTCH_graphMapInit (&grafdat, &mapodat, &archdat, NULL); SCOTCH_graphMapLoad (&grafdat, &mapodat, C_filepntrmaoinp); if ((flagval & C_FLAGRMAPCST) != 0) { if ((vmlotab = memAlloc (vertnbr * sizeof (SCOTCH_Num))) == NULL) errorPrint ("main: out of memory (2)"); SCOTCH_graphTabLoad (&grafdat, vmlotab, C_filepntrvmlinp); } } } clockStop (&runtime[0]); /* Get input time */ clockInit (&runtime[1]); clockStart (&runtime[1]); if ((flagval & C_FLAGPARTOVL) != 0) { /* If overlap partitioning wanted */ SCOTCH_graphPartOvl (&grafdat, C_partNbr, &stradat, parttab); /* Perform overlap partitioning */ clockStop (&runtime[1]); /* Get computation time */ clockStart (&runtime[0]); C_partSave (&grafdat, parttab, C_filepntrmapout); /* Write partitioning */ } else { /* Regular partitioning / mapping / clustering wanted */ if (straptr != NULL) /* Set static mapping strategy if needed */ SCOTCH_stratGraphMap (&stradat, straptr); SCOTCH_graphMapInit (&grafdat, &mappdat, &archdat, parttab); if ((flagval & C_FLAGRMAPOLD) != 0) { if ((flagval & C_FLAGFIXED) != 0) SCOTCH_graphRemapFixedCompute (&grafdat, &mappdat, &mapodat, emraval, vmlotab, &stradat); /* Perform remapping */ else SCOTCH_graphRemapCompute (&grafdat, &mappdat, &mapodat, emraval, vmlotab, &stradat); } else { if ((flagval & C_FLAGFIXED) != 0) SCOTCH_graphMapFixedCompute (&grafdat, &mappdat, &stradat); /* Perform mapping */ else SCOTCH_graphMapCompute (&grafdat, &mappdat, &stradat); } clockStop (&runtime[1]); /* Get computation time */ clockStart (&runtime[0]); SCOTCH_graphMapSave (&grafdat, &mappdat, C_filepntrmapout); /* Write mapping */ } clockStop (&runtime[0]); /* Get output time */ if (flagval & C_FLAGVERBSTR) { fprintf (C_filepntrlogout, "S\tStrat="); SCOTCH_stratSave (&stradat, C_filepntrlogout); putc ('\n', C_filepntrlogout); } if (flagval & C_FLAGVERBTIM) { fprintf (C_filepntrlogout, "T\tMapping\t\t%g\nT\tI/O\t\t%g\nT\tTotal\t\t%g\n", (double) clockVal (&runtime[1]), (double) clockVal (&runtime[0]), (double) clockVal (&runtime[0]) + (double) clockVal (&runtime[1])); } if ((flagval & C_FLAGPARTOVL) != 0) { /* If overlap partitioning wanted */ if (flagval & C_FLAGVERBMAP) C_partViewOvl (&grafdat, parttab, C_filepntrlogout); } else { /* Regular partitioning / mapping wanted */ if (flagval & C_FLAGVERBMAP) { if ((flagval & C_FLAGRMAPOLD) != 0) SCOTCH_graphRemapView (&grafdat, &mappdat, &mapodat, emraval, vmlotab, C_filepntrlogout); else SCOTCH_graphMapView (&grafdat, &mappdat, C_filepntrlogout); } SCOTCH_graphMapExit (&grafdat, &mappdat); /* Free mapping structure only when used, that is, not for overlay */ if ((flagval & C_FLAGRMAPOLD) != 0) { SCOTCH_graphMapExit (&grafdat, &mapodat); if ((flagval & C_FLAGRMAPCST) != 0) memFree (vmlotab); } } fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */ SCOTCH_graphExit (&grafdat); SCOTCH_stratExit (&stradat); SCOTCH_archExit (&archdat); memFree (parttab); /* Free hand-made partition array */ #ifdef COMMON_PTHREAD pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */ #endif /* COMMON_PTHREAD */ return (0); } /* This routine writes a partition to ** the given stream. ** It returns : ** - void : in case of success ** - exit : on error (because of errorPrint) */ void C_partSave ( SCOTCH_Graph * restrict const grafptr, SCOTCH_Num * restrict const parttab, FILE * const stream) { SCOTCH_Num baseval; const SCOTCH_Num * restrict parttax; SCOTCH_Num * vlbltab; const SCOTCH_Num * restrict vlbltax; SCOTCH_Num vertnbr; SCOTCH_Num vertnum; SCOTCH_graphData (grafptr, &baseval, &vertnbr, NULL, NULL, NULL, &vlbltab, NULL, NULL, NULL); parttax = parttab - baseval; vlbltax = (vlbltab != NULL) ? (vlbltab - baseval) : NULL; if (fprintf (stream, SCOTCH_NUMSTRING "\n", (SCOTCH_Num) vertnbr) == EOF) errorPrint ("C_partSave: bad output (1)"); for (vertnum = baseval; vertnum < (vertnbr + baseval); vertnum ++) { if (fprintf (stream, SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n", (SCOTCH_Num) ((vlbltax != NULL) ? vlbltax[vertnum] : vertnum), (SCOTCH_Num) parttax[vertnum]) == EOF) { errorPrint ("C_mapSave: bad output (2)"); } } } /* This routine writes the characteristics ** of the given overlap partition to the ** given stream. ** It returns : ** - void : in case of success ** - exit : on error (because of errorPrint) */ void C_partViewOvl ( SCOTCH_Graph * restrict const grafptr, SCOTCH_Num * restrict const parttab, FILE * const stream) { SCOTCH_Num baseval; SCOTCH_Num vertnbr; SCOTCH_Num vertnum; SCOTCH_Num * verttab; const SCOTCH_Num * restrict verttax; SCOTCH_Num * vendtab; const SCOTCH_Num * restrict vendtax; SCOTCH_Num * velotab; SCOTCH_Num velomsk; const SCOTCH_Num * restrict velobax; /* Data for handling of optional arrays */ SCOTCH_Num * edgetab; const SCOTCH_Num * restrict edgetax; const SCOTCH_Num * restrict parttax; SCOTCH_Num partnum; C_PartList * restrict listtab; SCOTCH_Num fronnbr; SCOTCH_Num fronload; SCOTCH_Num * restrict compload; SCOTCH_Num * restrict compsize; SCOTCH_Num comploadsum; SCOTCH_Num comploadmax; SCOTCH_Num comploadmin; double comploadavg; if (memAllocGroup ((void **) (void *) &compload, (size_t) (C_partNbr * sizeof (SCOTCH_Num)), &compsize, (size_t) (C_partNbr * sizeof (SCOTCH_Num)), &listtab, (size_t) ((C_partNbr + 1) * sizeof (C_PartList)), NULL) == NULL) { errorPrint ("C_partViewOvl: out of memory"); } listtab ++; /* TRICK: Trim array so that listtab[-1] is valid */ memSet (listtab, ~0, C_partNbr * sizeof (C_PartList)); /* Set vertex indices to ~0 */ memSet (compload, 0, C_partNbr * sizeof (SCOTCH_Num)); memSet (compsize, 0, C_partNbr * sizeof (SCOTCH_Num)); SCOTCH_graphData (grafptr, &baseval, &vertnbr, &verttab, &vendtab, &velotab, NULL, NULL, &edgetab, NULL); if (velotab == NULL) { /* Set accesses to optional arrays */ velobax = &C_loadOne; /* In case vertices not weighted (least often) */ velomsk = 0; } else { velobax = velotab - baseval; velomsk = ~((SCOTCH_Num) 0); } verttax = verttab - baseval; vendtax = vendtab - baseval; edgetax = edgetab - baseval; parttax = parttab - baseval; fronnbr = fronload = 0; for (vertnum = baseval; vertnum < (vertnbr + baseval); vertnum ++) { SCOTCH_Num partval; partval = parttax[vertnum]; if (partval >= 0) { compload[partval] += velobax[vertnum & velomsk]; compsize[partval] ++; } else { /* Vertex is in separator */ SCOTCH_Num listidx; /* Index of first neighbor part */ SCOTCH_Num edgenum; SCOTCH_Num veloval; fronnbr ++; /* Add vertex to frontier */ fronload += velobax[vertnum & velomsk]; listidx = -1; /* No neighboring parts recorded yet */ listtab[-1].vertnum = vertnum; /* Separator neighbors will not be considered */ for (edgenum = verttax[vertnum]; edgenum < vendtax[vertnum]; edgenum ++) { /* Compute gain */ SCOTCH_Num vertend; SCOTCH_Num partend; vertend = edgetax[edgenum]; partend = parttax[vertend]; if (listtab[partend].vertnum != vertnum) { /* If part not yet considered */ listtab[partend].vertnum = vertnum; /* Link it in list of neighbors */ listtab[partend].nextidx = listidx; listidx = partend; } } veloval = velobax[vertnum & velomsk]; while (listidx != -1) { /* For all neighboring parts found */ compload[listidx] += veloval; /* Add load of separator vertex to part */ compsize[listidx] ++; listidx = listtab[listidx].nextidx; } } } comploadsum = 0; for (partnum = 0; partnum < C_partNbr; partnum ++) comploadsum += compload[partnum]; comploadmax = 0; comploadmin = comploadsum; for (partnum = 0; partnum < C_partNbr; partnum ++) { if (compload[partnum] > comploadmax) comploadmax = compload[partnum]; if (compload[partnum] < comploadmin) comploadmin = compload[partnum]; } comploadavg = (double) comploadsum / (double) C_partNbr; fprintf (stream, "P\tsep=" SCOTCH_NUMSTRING "\n", (SCOTCH_Num) fronload); fprintf (stream, "P\tmin=" SCOTCH_NUMSTRING "\tmax=" SCOTCH_NUMSTRING "\tavg=%g\n", (SCOTCH_Num) comploadmin, (SCOTCH_Num) comploadmax, (double) comploadavg); #if 0 /* TODO REMOVE */ for (partnum = 0; partnum < C_partNbr; partnum ++) fprintf (stream, "P\tload[" SCOTCH_NUMSTRING "]=" SCOTCH_NUMSTRING "\n", (SCOTCH_Num) partnum, (SCOTCH_Num) compload[partnum]); #endif fprintf (stream, "P\tmaxavg=%g\tminavg=%g\n", ((double) comploadmax / comploadavg), ((double) comploadmin / comploadavg)); memFree (compload); } scotch-6.0.4.dfsg/src/scotch/gout_o.c0000644002563400244210000012631412473176651022626 0ustar trophimeutilisateurs du domaine/* Copyright 2004,2007,2008,2011,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : gout_o.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Part of a result viewer. **/ /** This module contains output routines. **/ /** **/ /** DATES : # Version 2.0 : from : 07 oct 1994 **/ /** to 23 dec 1994 **/ /** # Version 3.0 : from : 14 jul 1995 **/ /** to 03 oct 1995 **/ /** # Version 3.1 : from : 28 mar 1996 **/ /** to 03 jun 1996 **/ /** # Version 3.2 : from : 02 dec 1996 **/ /** to 05 jun 1998 **/ /** # Version 3.3 : from : 29 may 1999 **/ /** to : 03 jun 1999 **/ /** # Version 4.0 : from : 11 dec 2001 **/ /** to 11 dec 2001 **/ /** # Version 5.0 : from : 25 may 2007 **/ /** to 18 jun 2007 **/ /** # Version 5.1 : from : 25 oct 2007 **/ /** to 14 feb 2011 **/ /** # Version 6.0 : from : 01 jan 2012 **/ /** to : 01 jan 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes */ #define GOUT #include "module.h" #include "common.h" #include "scotch.h" #include "gout_c.h" #include "gout_o.h" /* ** The static and global variables */ static O_OutParam O_outParam = { /* Parameter structure */ O_OUTTYPEINVMESH, /* Default output type */ { 'c', 'v' }, /* OpenInventor mesh defaults */ { 'f' }, /* PostScript matrix defaults */ { 'f', 'g', /* PostScript mesh defaults */ 'v', 'd', 's', { { 0.0, 0.0 } }, { { 1.0, 1.0 } } }, { 'c', 'v', 'a' } }; /* Tulip graph defaults */ static C_ParseCode O_outList[] = { /* Output code list */ { O_OUTTYPEINVMESH, "i" }, { O_OUTTYPEPOSMATR, "m" }, { O_OUTTYPEPOSMESH, "p" }, { O_OUTTYPETULMESH, "t" }, { O_OUTTYPENBR, NULL } }; static C_ParseArg O_outArg[] = { /* Output type argument list */ { "c", O_OUTTYPEINVMESH, NULL, &O_outParam.InvMesh.color }, { "g", O_OUTTYPEINVMESH, NULL, &O_outParam.InvMesh.color }, { "r", O_OUTTYPEINVMESH, NULL, &O_outParam.InvMesh.edge }, { "v", O_OUTTYPEINVMESH, NULL, &O_outParam.InvMesh.edge }, { "e", O_OUTTYPEPOSMATR, NULL, &O_outParam.PosMatr.type }, { "f", O_OUTTYPEPOSMATR, NULL, &O_outParam.PosMatr.type }, { "c", O_OUTTYPEPOSMESH, NULL, &O_outParam.PosMesh.color }, { "g", O_OUTTYPEPOSMESH, NULL, &O_outParam.PosMesh.color }, { "e", O_OUTTYPEPOSMESH, NULL, &O_outParam.PosMesh.type }, { "f", O_OUTTYPEPOSMESH, NULL, &O_outParam.PosMesh.type }, { "l", O_OUTTYPEPOSMESH, NULL, &O_outParam.PosMesh.clip }, { "s", O_OUTTYPEPOSMESH, NULL, &O_outParam.PosMesh.clip }, { "a", O_OUTTYPEPOSMESH, NULL, &O_outParam.PosMesh.disk }, { "d", O_OUTTYPEPOSMESH, NULL, &O_outParam.PosMesh.disk }, { "r", O_OUTTYPEPOSMESH, NULL, &O_outParam.PosMesh.edge }, { "v", O_OUTTYPEPOSMESH, NULL, &O_outParam.PosMesh.edge }, { "x", O_OUTTYPEPOSMESH, "%lf", &O_outParam.PosMesh.min.x }, { "X", O_OUTTYPEPOSMESH, "%lf", &O_outParam.PosMesh.max.x }, { "y", O_OUTTYPEPOSMESH, "%lf", &O_outParam.PosMesh.min.y }, { "Y", O_OUTTYPEPOSMESH, "%lf", &O_outParam.PosMesh.max.y }, { "b", O_OUTTYPETULMESH, NULL, &O_outParam.TulMesh.color }, { "c", O_OUTTYPETULMESH, NULL, &O_outParam.TulMesh.color }, { "r", O_OUTTYPETULMESH, NULL, &O_outParam.TulMesh.edge }, { "v", O_OUTTYPETULMESH, NULL, &O_outParam.TulMesh.edge }, { "a", O_OUTTYPETULMESH, NULL, &O_outParam.TulMesh.disk }, { "d", O_OUTTYPETULMESH, NULL, &O_outParam.TulMesh.disk }, { NULL, O_OUTTYPENBR, "", NULL } }; static double outcolorcoltab[16][3] = { /* Color list */ { 1.00, 0.00, 0.00 }, /* Red */ { 0.00, 1.00, 0.00 }, /* Green */ { 1.00, 1.00, 0.00 }, /* Yellow */ { 0.00, 0.00, 1.00 }, /* Blue */ { 1.00, 0.00, 1.00 }, /* Magenta */ { 0.00, 1.00, 1.00 }, /* Cyan */ { 1.00, 0.50, 0.20 }, /* Orange */ { 0.30, 0.55, 0.00 }, /* Olive */ { 0.72, 0.47, 0.47 }, /* Dark pink */ { 0.33, 0.33, 0.81 }, /* Sea blue */ { 1.00, 0.63, 0.63 }, /* Pink */ { 0.62, 0.44, 0.65 }, /* Violet */ { 0.60, 0.80, 0.70 }, /* Pale green */ { 0.47, 0.20, 0.00 }, /* Brown */ { 0.00, 0.68, 0.68 }, /* Turquoise */ { 0.81, 0.00, 0.40 } }; /* Purple */ static double outcolorblwtab[8][3] = { /* Grey list */ { 1.00, 1.00, 1.00 }, { 0.20, 0.20, 0.20 }, { 0.50, 0.50, 0.50 }, { 0.80, 0.80, 0.80 }, { 0.30, 0.30, 0.30 }, { 0.90, 0.90, 0.90 }, { 0.40, 0.40, 0.40 }, { 0.70, 0.70, 0.70 } }; /****************************************/ /* */ /* This is the color selection routine. */ /* */ /****************************************/ void outColorBlw ( const SCOTCH_Num labl, double color[]) { if (labl == (-1)) { color[0] = color[1] = color[2] = 1.0L; } else { color[0] = (double) outcolorblwtab[labl % 8][0]; color[1] = (double) outcolorblwtab[labl % 8][1]; color[2] = (double) outcolorblwtab[labl % 8][2]; } } void outColorColor ( const SCOTCH_Num labl, double color[]) { if (labl == (-1)) { color[0] = color[1] = color[2] = 1.0L; } else { color[0] = (double) outcolorcoltab[labl % 16][0]; color[1] = (double) outcolorcoltab[labl % 16][1]; color[2] = (double) outcolorcoltab[labl % 16][2]; } } /****************************/ /* */ /* The main output routine. */ /* */ /****************************/ /* This routine parses the output ** option string. ** It returns: ** - 0 : if string successfully scanned. ** - 1 : if invalid options ** - 2 : if invalid option arguments. ** - 3 : if syntax error in string. */ int outDrawParse ( char * const string) { return (C_parse (O_outList, O_outArg, (int * const) (void *) &O_outParam.type, string)); } /* This routine is the generic output call. ** It returns: ** - VOID : in all cases. */ void outDraw ( const C_Graph * const grafptr, /* Graph structure */ const C_Geometry * const geomptr, /* Graph geometry */ const C_Mapping * const mapptr, /* Result mapping */ FILE * const stream) /* Output stream */ { switch (O_outParam.type) { case O_OUTTYPEINVMESH : /* Mesh OpenInventor output type */ outDrawInvMesh (grafptr, geomptr, mapptr, stream); break; case O_OUTTYPEPOSMATR : /* Matrix PostScript output type */ outDrawPosMatr (grafptr, geomptr, mapptr, stream); break; case O_OUTTYPEPOSMESH : /* Mesh PostScript output type */ outDrawPosMesh (grafptr, geomptr, mapptr, stream); break; case O_OUTTYPETULMESH : /* Mesh Tulip output type */ outDrawTulMesh (grafptr, geomptr, mapptr, stream); break; default : errorPrint ("outDraw: invalid output method '%d'", O_outParam.type); } } /****************************************/ /* */ /* This is the Inventor output routine. */ /* */ /****************************************/ int outDrawInvMesh ( const C_Graph * const grafptr, /* Graph structure, sorted by vertex index */ const C_Geometry * const geomptr, /* Graph geometry, sorted by vertex label */ const C_Mapping * const mapptr, /* Result mapping, sorted by vertex label */ FILE * const stream) /* Output stream */ { void (* outcolor) (const SCOTCH_Num, double[]); /* Color routine */ O_InvMeshPath * pattab; /* Array of path building data */ int * idxtab; /* Array of indexes */ int idxnbr; /* Number of indexes */ time_t pictime; /* Creation time */ double color[3]; /* Vertex color */ int i, j, k; if (geomptr->verttab == NULL) { errorPrint ("outDrawInvMesh: geometry not provided"); return (1); } time (&pictime); /* Get current time */ outcolor = (O_outParam.InvMesh.color == 'c') ? outColorColor : outColorBlw; /* Select color output routine */ if (((idxtab = (int *) memAlloc ((grafptr->edgenbr / 2) * 3 * sizeof (int))) == NULL) || ((pattab = (O_InvMeshPath *) memAlloc (grafptr->vertnbr * sizeof (O_InvMeshPath))) == NULL)) { errorPrint ("outDrawInvMesh: out of memory"); if (idxtab != NULL) memFree (idxtab); return (1); } idxnbr = 0; /* No indexes yet */ for (i = 0, j = 0; i < grafptr->vertnbr; i ++) { /* For all vertices */ pattab[i].nbr = 0; /* Compute the number of output paths */ pattab[i].idx = grafptr->verttab[i]; for ( ; j < grafptr->vendtab[i]; j ++) { if ((grafptr->edgetab[j] > i) && /* If it can be an output edge */ ((O_outParam.InvMesh.edge != 'r') || /* And this edge can be drawn */ (mapptr->labltab[i] == mapptr->labltab[grafptr->edgetab[j]]))) pattab[i].nbr ++; /* One more path to higher vertices */ } } for (i = 0; i < grafptr->vertnbr; ) { /* For all vertices */ if (pattab[i].nbr == 0) { /* If no output path for this vertex */ i ++; /* Skip to next vertex */ continue; } j = i; /* Begin with this vertex */ idxtab[idxnbr ++] = j; /* Add it to the current segment */ do { for (k = pattab[j].idx; k < grafptr->vendtab[j]; k ++) { /* Search for first output */ if ((grafptr->edgetab[k] > j) && /* If it can be an output edge */ ((O_outParam.InvMesh.edge != 'r') || /* And this edge can be drawn */ (mapptr->labltab[j] == mapptr->labltab[grafptr->edgetab[k]]))) break; } pattab[j].nbr --; /* One less output path remaining */ pattab[j].idx = k + 1; /* Search from the next position */ j = grafptr->edgetab[k]; /* Get the path end vertex number */ idxtab[idxnbr ++] = j; /* Add it to the current segment */ } while (pattab[j].nbr > 0); /* As long as there is a path */ idxtab[idxnbr ++] = ~0; /* Mark end of path */ } fprintf (stream, "#Inventor V2.0 ascii\n"); /* Write header */ fprintf (stream, "#Title: %s %s %s\n", C_filenamesrcinp, C_filenamegeoinp, C_filenamemapinp); fprintf (stream, "#Creator: out (F. Pellegrini, LaBRI, Bordeaux)\n"); fprintf (stream, "#CreationDate: %s", ctime (&pictime)); if (idxnbr == 0) /* If nothing to write */ return (0); fprintf (stream, "Separator {\n"); fprintf (stream, " LightModel {\n model\t\tBASE_COLOR\n }\n"); fprintf (stream, " DrawStyle {\n style\t\tLINES\n }\n"); fprintf (stream, " MaterialBinding {\n value\t\tPER_VERTEX\n }\n"); fprintf (stream, " Coordinate3 {\n point [\n\t%g\t%g\t%g", /* Write vertex coordinates */ geomptr->verttab[0].x, geomptr->verttab[0].y, geomptr->verttab[0].z); for (i = 1; i < grafptr->vertnbr; i ++) fprintf (stream, ",\n\t%g\t%g\t%g", geomptr->verttab[i].x, geomptr->verttab[i].y, geomptr->verttab[i].z); fprintf (stream, " ]\n }\n"); fprintf (stream, " BaseColor {\n rgb ["); /* Write color vector */ for (i = 0; i < idxnbr - 2; i ++) { if (idxtab[i] != ~0) { outcolor (mapptr->labltab[idxtab[i]], color); fprintf (stream, "\n\t%g\t%g\t%g,", (double) color[0], (double) color[1], (double) color[2]); } } outcolor (mapptr->labltab[idxtab[idxnbr - 2]], color); fprintf (stream, "\n\t%g\t%g\t%g ]\n }\n", (double) color[0], (double) color[1], (double) color[2]); fprintf (stream, " IndexedLineSet {\n coordIndex ["); /* Write set of lines */ for (i = 0; i < idxnbr - 1; i ++) { if ((i % 8) == 0) fprintf (stream, "\n"); if (idxtab[i] == ~0) fprintf (stream, "\t-1,"); else fprintf (stream, "\t%u,", idxtab[i]); } if (((idxnbr - 1) % 8) == 0) fprintf (stream, "\n"); fprintf (stream, "\t-1 ]\n }\n"); fprintf (stream, "}\n"); /* Write end of separator */ #if 0 for (i = 0; i < grafptr->vertnbr; i ++) { /* For all vertices */ outcolor (mapptr->labltab[i], color); fprintf (stream, "Separator { Translation { translation %lg %lg %lg } BaseColor { rgb [ %lg %lg %lg ] } Sphere { radius 0.3 } }\n", geomptr->verttab[i].x, geomptr->verttab[i].y, geomptr->verttab[i].z, (double) color[0], (double) color[1], (double) color[2]); } #endif memFree (pattab); /* Free path array */ memFree (idxtab); /* Free index array */ return (0); } /*************************************************/ /* */ /* This is the PostScript matrix output routine. */ /* */ /*************************************************/ int outDrawPosMatr ( const C_Graph * const grafptr, /* Graph structure, sorted by vertex index */ const C_Geometry * const geomptr, /* Graph geometry, sorted by vertex label */ const C_Mapping * const mapptr, /* Result mapping, sorted by vertex label */ FILE * const stream) /* Output stream */ { SCOTCH_Num * nonztab; /* Array of non-zero entries */ SCOTCH_Num nonzfrst; /* First non-zero entry of area */ SCOTCH_Num nonzlast; /* Last non-zero entry of area */ double pictsize; /* Number of distinct coordinates */ double pictdisp; /* Size of the matrix display (in inches) */ time_t picttime; /* Creation time */ SCOTCH_Num colnum; SCOTCH_Num vertnum; SCOTCH_Num * edgeptr; if ((nonztab = memAlloc ((grafptr->vertnbr + 1) * sizeof (SCOTCH_Num))) == NULL) { errorPrint ("outDrawPosMatr: out of memory"); return (1); } time (&picttime); /* Get current time */ pictsize = (double) (grafptr->vertnbr + 1); /* Get matrix size */ pictdisp = MIN (O_PSPICTWIDTH, O_PSPICTHEIGHT); if (O_outParam.PosMatr.type == 'e') { /* EPSF-type output */ fprintf (stream, "%%!PS-Adobe-2.0 EPSF-2.0\n"); fprintf (stream, "%%%%Title: %s %s %s\n", C_filenamesrcinp, C_filenamegeoinp, C_filenamemapinp); fprintf (stream, "%%%%Creator: out (F. Pellegrini, LaBRI, Bordeaux)\n"); fprintf (stream, "%%%%CreationDate: %s", ctime (&picttime)); fprintf (stream, "%%%%BoundingBox: 0 0 %d %d\n", (int) (pictdisp * O_PSDPI), (int) (pictdisp * O_PSDPI)); fprintf (stream, "%%%%Pages: 0\n"); fprintf (stream, "%%%%EndComments\n"); } else { /* Full page output */ fprintf (stream, "%%!PS-Adobe-2.0\n"); fprintf (stream, "%%%%Title: %s %s %s\n", C_filenamesrcinp, C_filenamegeoinp, C_filenamemapinp); fprintf (stream, "%%%%Creator: out (F. Pellegrini, LaBRI, Bordeaux)\n"); fprintf (stream, "%%%%CreationDate: %s", ctime (&picttime)); } fprintf (stream, "/p { pop } bind def\n"); fprintf (stream, "/h { 3 1 roll exch 2 copy moveto 2 copy 1 add 5 -3 roll 3 1 roll add exch 2 copy lineto 1 add lineto lineto fill } bind def\n"); fprintf (stream, "/v { 3 copy pop moveto 2 copy add exch pop exch 3 copy pop pop 1 add dup 3 -1 roll lineto exch dup 3 1 roll lineto lineto fill } bind def\n"); fprintf (stream, "/b { 3 copy v 3 copy h pop pop } bind def\n"); fprintf (stream, "/c { 1 3 copy v 3 copy h pop pop } bind def\n"); fprintf (stream, "gsave\n"); /* Save the context */ fprintf (stream, "0 setlinecap\n"); /* Perform miter caps */ if (O_outParam.PosMatr.type == 'f') /* If full page output */ fprintf (stream, "%d %d translate\n", /* Center the picture */ (int) (O_PSDPI * (O_PSPAGEWIDTH - pictdisp)) / 2, (int) (O_PSDPI * (O_PSPAGEWIDTH - pictdisp)) / 2); fprintf (stream, "%f %f scale\n", /* Print scaling factor */ (double) O_PSDPI * pictdisp / pictsize, (double) O_PSDPI * pictdisp / pictsize); fprintf (stream, "[ 1 0 0 -1 0 %d ] concat\n", /* Reverse Y coordinate */ (int) (grafptr->vertnbr + 1)); fprintf (stream, "0 setgray newpath\n"); /* Select black color */ for (vertnum = 0; vertnum < grafptr->vertnbr; vertnum ++) { colnum = (mapptr->labltab[vertnum] == ~0) ? vertnum : mapptr->labltab[vertnum]; fprintf (stream, SCOTCH_NUMSTRING "\n", /* Set column value */ (SCOTCH_Num) colnum); memset (nonztab, 0, (colnum + 2) * sizeof (SCOTCH_Num)); for (edgeptr = grafptr->edgetab + grafptr->verttab[colnum]; edgeptr < grafptr->edgetab + grafptr->vendtab[colnum]; edgeptr ++) { if (*edgeptr < colnum) nonztab[*edgeptr] = 1; } nonztab[colnum] = 1; /* Diagonal is non-zero */ for (nonzfrst = 0; nonzfrst <= vertnum; nonzfrst ++) { if (nonztab[nonzfrst] != 0) { /* A non-zero has been found */ for (nonzlast = nonzfrst; nonztab[nonzlast] != 0; nonzlast ++) ; if ((nonzlast - nonzfrst) > 1) /* Draw row block coefficient */ fprintf (stream, SCOTCH_NUMSTRING " " SCOTCH_NUMSTRING " b\n", (SCOTCH_Num) nonzfrst, (SCOTCH_Num) (nonzlast - nonzfrst)); else fprintf (stream, SCOTCH_NUMSTRING " c\n", (SCOTCH_Num) nonzfrst); nonzfrst = nonzlast - 1; } } fprintf (stream, "p "); /* Close the column */ } fprintf (stream, "\ngrestore\n"); /* Restore context */ if (O_outParam.PosMatr.type == 'f') /* If full page output */ fprintf (stream, "showpage\n"); /* Display the page */ memFree (nonztab); return (0); } /***********************************************/ /* */ /* This is the PostScript mesh output routine. */ /* */ /***********************************************/ int outDrawPosMesh ( const C_Graph * const grafptr, /* Graph structure, sorted by vertex index */ const C_Geometry * const geomptr, /* Graph geometry, sorted by vertex label */ const C_Mapping * const mapptr, /* Result mapping, sorted by vertex label */ FILE * const stream) /* Output stream */ { int idxnbr; /* Number of indexes */ int * idxtab; /* Array of indexes */ O_PosMeshPath * pattab; /* Array of path building data */ O_PosMeshVertex * pictab; /* Array of 2D coordinates, sorted by vertex index */ O_Point picmin; /* Picture minimum and maximum coordinates */ O_Point picmax; O_Point picdelt; double picscale; /* Scaling factor */ double picsrad; /* Square of circle radius */ time_t pictime; /* Creation time */ double color[3]; /* Color values */ int i, j, k; if (geomptr->verttab == NULL) { errorPrint ("outDrawPosMesh: geometry not provided"); return (1); } time (&pictime); /* Get current time */ if (((pictab = (O_PosMeshVertex *) memAlloc (grafptr->vertnbr * sizeof (O_PosMeshVertex))) == NULL) || ((idxtab = (int *) memAlloc ((grafptr->edgenbr / 2) * 3 * sizeof (int))) == NULL) || ((pattab = (O_PosMeshPath *) memAlloc (grafptr->vertnbr * sizeof (O_PosMeshPath))) == NULL)) { errorPrint ("outDrawPosMesh: out of memory"); if (pictab != NULL) { if (idxtab != NULL) memFree (idxtab); memFree (pictab); } return (1); } for (i = 0; i < grafptr->vertnbr; i ++) { /* For all vertex indices */ pictab[i].pos.x = geomptr->verttab[i].x + /* Project 3D coordinates into 2D ones */ geomptr->verttab[i].z * (O_POSMESHISOCOS * O_POSMESHISOREDUC); pictab[i].pos.y = geomptr->verttab[i].y + geomptr->verttab[i].z * (O_POSMESHISOSIN * O_POSMESHISOREDUC); } picmin.x = picmin.y = 1e30; /* Pre-set coordinates extrema */ picmax.x = picmax.y = -1e30; if (O_outParam.PosMesh.clip == 'l') { /* If clipping encompasses disks */ for (i = 0, j = 0; i < grafptr->vertnbr; i ++) { pictab[i].rad = 1e30; /* Assume a huge square of radius */ for ( ; j < grafptr->vendtab[i]; j ++) { k = grafptr->edgetab[j]; picsrad = (pictab[i].pos.x - pictab[k].pos.x) * (pictab[i].pos.x - pictab[k].pos.x) + (pictab[i].pos.y - pictab[k].pos.y) * (pictab[i].pos.y - pictab[k].pos.y); if (picsrad < pictab[i].rad) /* Get the smallest square of radius */ pictab[i].rad = picsrad; } pictab[i].rad = sqrt (pictab[i].rad) / 2.0; /* Keep the half-distance for radius */ if ((pictab[i].pos.x - pictab[i].rad) < picmin.x) /* Update extrema if necessary */ picmin.x = pictab[i].pos.x - pictab[i].rad; if ((pictab[i].pos.y - pictab[i].rad) < picmin.y) picmin.y = pictab[i].pos.y - pictab[i].rad; if ((pictab[i].pos.x + pictab[i].rad) > picmax.x) picmax.x = pictab[i].pos.x + pictab[i].rad; if ((pictab[i].pos.y + pictab[i].rad) > picmax.y) picmax.y = pictab[i].pos.y + pictab[i].rad; } } else { /* Border clipping */ for (i = 0; i < grafptr->vertnbr; i ++) { /* For all vertex indices */ if (pictab[i].pos.x < picmin.x) /* Update extrema if necessary */ picmin.x = pictab[i].pos.x; if (pictab[i].pos.y < picmin.y) picmin.y = pictab[i].pos.y; if (pictab[i].pos.x > picmax.x) picmax.x = pictab[i].pos.x; if (pictab[i].pos.y > picmax.y) picmax.y = pictab[i].pos.y; } } picdelt.x = picmax.x - picmin.x; /* Compute picture extents */ picdelt.y = picmax.y - picmin.y; picmin.x += picdelt.x * O_outParam.PosMesh.min.x; /* Resize picture (if necessary) */ picmin.y += picdelt.y * O_outParam.PosMesh.min.y; picmax.x -= picdelt.x * (1.0L - O_outParam.PosMesh.max.x); picmax.y -= picdelt.y * (1.0L - O_outParam.PosMesh.max.y); picdelt.x = picmax.x - picmin.x; /* Recompute picture extents */ picdelt.y = picmax.y - picmin.y; picscale = (picdelt.x == 0.0L) /* Compute scaling factor */ ? ((picdelt.y == 0.0L) ? 1.0L : (O_PSPICTHEIGHT / picdelt.y)) : ((picdelt.y == 0.0L) ? (O_PSPICTWIDTH / picdelt.x) : MIN (O_PSPICTWIDTH / picdelt.x, O_PSPICTHEIGHT / picdelt.y)); picdelt.x *= picscale * O_POSMESHPICTRESOL; /* Rescale extents */ picdelt.y *= picscale * O_POSMESHPICTRESOL; for (i = 0; i < grafptr->vertnbr; i ++) { pictab[i].pos.x = (pictab[i].pos.x - picmin.x) * picscale * O_POSMESHPICTRESOL; /* Rescale coordinates */ pictab[i].pos.y = (pictab[i].pos.y - picmin.y) * picscale * O_POSMESHPICTRESOL; } if (O_outParam.PosMesh.disk == 'd') { /* If disks wanted */ for (i = 0, j = 0; i < grafptr->vertnbr; i ++) { pictab[i].rad = 1e30; /* Assume huge square of radius */ for ( ; j < grafptr->vendtab[i]; j ++) { k = grafptr->edgetab[j]; picsrad = (pictab[i].pos.x - pictab[k].pos.x) * (pictab[i].pos.x - pictab[k].pos.x) + (pictab[i].pos.y - pictab[k].pos.y) * (pictab[i].pos.y - pictab[k].pos.y); if (picsrad < pictab[i].rad) /* Get smallest square of radius */ pictab[i].rad = picsrad; } pictab[i].rad = sqrt (pictab[i].rad) / 2.0; /* Keep the half-distance for radius */ if (pictab[i].rad < 1.0L) /* Always get a non-zero radius */ pictab[i].rad = 1.0L; pictab[i].vis = ((pictab[i].pos.x > - pictab[i].rad) && /* Compute vertex visibility */ (pictab[i].pos.x < picdelt.x + pictab[i].rad) && (pictab[i].pos.y > - pictab[i].rad) && (pictab[i].pos.y < picdelt.y + pictab[i].rad)) ? 1 : 0; } } else { /* If disks not wanted */ for (i = 0; i < grafptr->vertnbr; i ++) pictab[i].vis = ((pictab[i].pos.x > 0.0L) && /* Compute vertex visibility */ (pictab[i].pos.x < picdelt.x) && (pictab[i].pos.y > 0.0L) && (pictab[i].pos.y < picdelt.y)) ? 1 : 0; } for (i = 0; i < grafptr->vertnbr; i ++) { pictab[i].pos.x += 0.5L; /* Prepare to switch to integer coordinates */ pictab[i].pos.y += 0.5L; } picdelt.x += 0.5L; picdelt.y += 0.5L; if (O_outParam.PosMesh.color == 'c') { /* If color output */ for (i = 0; i < grafptr->vertnbr; i ++) /* Select color for all vertices */ pictab[i].col = mapptr->labltab[i] % O_POSMESHCOLNBR; } else { /* If gray level output */ for (i = 0; i < grafptr->vertnbr; i ++) { /* Select color for all vertices */ for (j = mapptr->labltab[i] & 255, k = 7, pictab[i].col = 0; /* Half-tone color */ j > 0; /* As long as there are subdivision bits */ j >>= 1, k --) /* (Same as reversing the last 8 bits ) */ pictab[i].col |= ((j & 1) << k); } } for (i = 0, j = 0; i < grafptr->vertnbr; i ++) { /* For all vertices */ pattab[i].nbr = 0; /* Compute the number of output paths */ pattab[i].idx = grafptr->verttab[i]; for ( ; j < grafptr->vendtab[i]; j ++) { if ((grafptr->edgetab[j] > i) && /* If it can be an output edge */ ((pictab[i].vis | pictab[grafptr->edgetab[j]].vis) != 0) && /* And it is visible */ ((O_outParam.PosMesh.edge != 'r') || /* And it can be drawn */ (mapptr->labltab[i] == mapptr->labltab[grafptr->edgetab[j]]))) pattab[i].nbr ++; /* One more path to higher vertices */ } } idxnbr = 0; /* No indexes yet */ for (i = 0; i < grafptr->vertnbr; ) { if (pattab[i].nbr == 0) { /* If no output path */ i ++; /* Skip to the next vertex */ continue; } j = i; /* Begin with this vertex */ idxtab[idxnbr ++] = j; /* Add it to the current segment */ do { for (k = pattab[j].idx; k < grafptr->vendtab[j]; k ++) { /* Search for first output */ if ((grafptr->edgetab[k] > j) && /* If it can be an output edge */ ((pictab[j].vis | pictab[grafptr->edgetab[k]].vis) != 0) && /* And it is visible */ ((O_outParam.InvMesh.edge != 'r') || /* And it can be drawn */ (mapptr->labltab[j] == mapptr->labltab[grafptr->edgetab[k]]))) break; } pattab[j].nbr --; /* One less output path remaining */ pattab[j].idx = k + 1; /* Search from the next position */ j = grafptr->edgetab[k]; /* Get the path end vertex number */ idxtab[idxnbr ++] = j; /* Add it to the current segment */ } while (pattab[j].nbr > 0); /* As long as there is a path */ idxtab[idxnbr ++] = ~0; /* Mark end of path */ } if (O_outParam.PosMesh.type == 'e') { /* EPSF-type output */ fprintf (stream, "%%!PS-Adobe-2.0 EPSF-2.0\n"); fprintf (stream, "%%%%Title: %s %s %s\n", C_filenamesrcinp, C_filenamegeoinp, C_filenamemapinp); fprintf (stream, "%%%%Creator: out (F. Pellegrini, LaBRI, Bordeaux)\n"); fprintf (stream, "%%%%CreationDate: %s", ctime (&pictime)); fprintf (stream, "%%%%BoundingBox: 0 0 %d %d\n", (int) ((picdelt.x * O_PSDPI) / O_POSMESHPICTRESOL), (int) ((picdelt.y * O_PSDPI) / O_POSMESHPICTRESOL)); fprintf (stream, "%%%%Pages: 0\n"); fprintf (stream, "%%%%EndComments\n"); } else { /* Full page output */ fprintf (stream, "%%!PS-Adobe-2.0\n"); fprintf (stream, "%%%%Title: %s %s %s\n", C_filenamesrcinp, C_filenamegeoinp, C_filenamemapinp); fprintf (stream, "%%%%Creator: out (F. Pellegrini, LaBRI, Bordeaux)\n"); fprintf (stream, "%%%%CreationDate: %s", ctime (&pictime)); } fprintf (stream, "/A { 0 360 arc fill } bind def\n"); /* Macro definitions */ if (O_outParam.PosMesh.color == 'c') { /* If color output */ for (i = 0; i < O_POSMESHCOLNBR; i ++) { /* Build color indexes */ outColorColor (i, color); fprintf (stream, "/C%c { %g %g %g setrgbcolor } bind def\n", ('a' + i), color[0], color[1], color[2]); } } fprintf (stream, "/G { 255 div setgray } bind def\n"); fprintf (stream, "/L { lineto stroke } bind def\n"); fprintf (stream, "/l { lineto } bind def\n"); fprintf (stream, "/m { moveto } bind def\n"); fprintf (stream, "gsave\n"); /* Save the context */ fprintf (stream, "1 setlinecap\n"); /* Perform round caps */ if (O_outParam.PosMesh.type == 'f') /* If full page output */ fprintf (stream, "%d %d translate\n", /* Center the picture */ (int) ((O_PSDPI * (O_PSPAGEWIDTH * O_POSMESHPICTRESOL - picdelt.x)) / (2 * O_POSMESHPICTRESOL)), (int) ((O_PSDPI * (O_PSPAGEHEIGHT * O_POSMESHPICTRESOL - picdelt.y)) / (2 * O_POSMESHPICTRESOL))); fprintf (stream, "%f %f scale\n", /* Print scaling factor */ (double) O_PSDPI / O_POSMESHPICTRESOL, (double) O_PSDPI / O_POSMESHPICTRESOL); fprintf (stream, "newpath 0 0 m %d 0 l %d %d l 0 %d l closepath clip\n", /* Clip picture */ (int) picdelt.x, (int) picdelt.x, (int) picdelt.y, (int) picdelt.y); fprintf (stream, "0 G\n"); /* Select black color */ for (i = 0; i < idxnbr; i ++) { fprintf (stream, "%d\t%d\tm\n", /* Set initial point */ (int) pictab[idxtab[i]].pos.x, (int) pictab[idxtab[i]].pos.y); for (i ++; idxtab[i] != ~0; i ++ ) { /* Build path */ fprintf (stream, "%d\t%d\t%c\n", (int) pictab[idxtab[i]].pos.x, (int) pictab[idxtab[i]].pos.y, (idxtab[i + 1] == ~0) ? 'L' : 'l'); } } if (O_outParam.PosMesh.disk == 'd') { /* If disks wanted */ for (i = 0, j = ~0; i < grafptr->vertnbr; i ++) { if ((pictab[i].vis > 0) && /* If disk is visible */ (mapptr->labltab[i] != (-1))) { /* And is mapped */ if ((j == ~0) || (pictab[i].col != pictab[j].col)) { /* Update drawing color */ if (O_outParam.PosMesh.color == 'c') fprintf (stream, "C%c\n", 'a' + pictab[i].col); else fprintf (stream, "%u G\n", pictab[i].col); j = i; /* Record the new current color */ } fprintf (stream, "%d %d %d A\n", /* Draw the disk */ (int) pictab[i].pos.x, (int) pictab[i].pos.y, (int) pictab[i].rad); } } } fprintf (stream, "grestore\n"); /* Restore the context */ if (O_outParam.PosMesh.type == 'f') /* If full page output */ fprintf (stream, "showpage\n"); /* Display the page */ memFree (pattab); memFree (idxtab); memFree (pictab); return (0); } /*************************************/ /* */ /* This is the Tulip output routine. */ /* */ /*************************************/ int outDrawTulMesh ( const C_Graph * const grafptr, /* Graph structure, sorted by vertex index */ const C_Geometry * const geomptr, /* Graph geometry, sorted by vertex label */ const C_Mapping * const mapptr, /* Result mapping, sorted by vertex label */ FILE * const stream) /* Output stream */ { time_t pictime; /* Creation time */ char * pictimeptr; char pictimestr[64]; double color[3]; /* Vertex color */ SCOTCH_Num vertnum; const SCOTCH_Num * edgetax; SCOTCH_Num edgeidx; char c; if (geomptr->verttab == NULL) { errorPrint ("outDrawInvMesh: geometry not provided"); return (1); } time (&pictime); /* Get current time */ pictimeptr = ctime (&pictime); strncpy (pictimestr, pictimeptr, 63); pictimestr[63] = '\0'; pictimestr[strlen (pictimestr) - 1] = '\0'; fprintf (stream, "(tlp \"2.0\"\n(author \"out (F. Pellegrini, LaBRI, Bordeaux)\")\n(date \"%s\")\n(comment \"%s %s %s\")\n", /* Write header */ pictimestr, C_filenamesrcinp, C_filenamegeoinp, C_filenamemapinp); if (grafptr->vertnbr == 0) { /* If nothing to write */ fprintf (stream, ")\n"); return (0); } fprintf (stream, "(nodes\n"); /* Write node list */ for (vertnum = 0; vertnum < (grafptr->vertnbr - 1); vertnum ++) fprintf (stream, SCOTCH_NUMSTRING "%c", (SCOTCH_Num) (vertnum + grafptr->baseval), ((vertnum & 7) == 7) ? '\n' : '\t'); fprintf (stream, SCOTCH_NUMSTRING ")\n", (SCOTCH_Num) (vertnum + grafptr->baseval)); edgetax = grafptr->edgetab - grafptr->baseval; for (vertnum = 0, edgeidx = grafptr->baseval; vertnum < grafptr->vertnbr; vertnum ++) { SCOTCH_Num edgenum; SCOTCH_Num edgennd; for (edgenum = grafptr->verttab[vertnum], edgennd = grafptr->vendtab[vertnum]; edgenum < edgennd; edgenum ++) { SCOTCH_Num vertend; vertend = edgetax[edgenum]; if (vertend <= vertnum) /* True even if baseval=1 and as vertnum unbased */ continue; fprintf (stream, "(edge " SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING ")\n", (SCOTCH_Num) (edgeidx ++), (SCOTCH_Num) (vertnum + grafptr->baseval), (SCOTCH_Num) vertend); } } fprintf (stream, "(property 0 layout \"viewLayout\"\n"); /* Write node coordinates */ c = '\n'; for (vertnum = 0; vertnum < grafptr->vertnbr; vertnum ++) { if (vertnum == (grafptr->vertnbr - 1)) c = ')'; fprintf (stream, "(node " SCOTCH_NUMSTRING "\t\"(%lf,%lf,%lf)\")%c", (SCOTCH_Num) (vertnum + grafptr->baseval), (double) geomptr->verttab[vertnum].x, (double) geomptr->verttab[vertnum].y, (double) geomptr->verttab[vertnum].z, c); } fprintf (stream, "\n"); if (O_outParam.TulMesh.color == 'c') { fprintf (stream, "(property 0 color \"viewColor\"\n(default \"(255,255,255,255)\" \"(0,0,0,0)\")\n"); /* Write node color values */ c = '\n'; for (vertnum = 0; vertnum < grafptr->vertnbr; vertnum ++) { if (vertnum == (grafptr->vertnbr - 1)) c = ')'; outColorColor (mapptr->labltab[vertnum], color); fprintf (stream, "(node " SCOTCH_NUMSTRING " \"(%d,%d,%d,255)\")%c", (SCOTCH_Num) (vertnum + grafptr->baseval), (int) (color[0] * 255.0), (int) (color[1] * 255.0), (int) (color[2] * 255.0), c); } fprintf (stream, "\n"); } fprintf (stream, "(property 0 size \"viewSize\"\n(default \"(0,0,0)\" \"(0,0,0)\")"); /* Write default node size */ if (O_outParam.TulMesh.disk == 'd') { /* If disks wanted */ const C_GeoVert * geomtax; geomtax = geomptr->verttab - grafptr->baseval; fprintf (stream, "\n"); c = '\n'; for (vertnum = 0; vertnum < grafptr->vertnbr; vertnum ++) { SCOTCH_Num edgenum; SCOTCH_Num edgennd; double distmin; C_GeoVert vertpos; if (vertnum == (grafptr->vertnbr - 1)) c = ')'; distmin = 1e30; /* Huge distance assumed */ vertpos.x = geomptr->verttab[vertnum].x; vertpos.y = geomptr->verttab[vertnum].y; vertpos.z = geomptr->verttab[vertnum].z; for (edgenum = grafptr->verttab[vertnum], edgennd = grafptr->vendtab[vertnum]; edgenum < edgennd; edgenum ++) { SCOTCH_Num vertend; double distval; vertend = edgetax[edgenum]; distval = (geomtax[vertend].x - vertpos.x) * (geomtax[vertend].x - vertpos.x) + (geomtax[vertend].y - vertpos.y) * (geomtax[vertend].y - vertpos.y) + (geomtax[vertend].z - vertpos.z) * (geomtax[vertend].z - vertpos.z); if (distval < distmin) distmin = distval; } distmin = sqrt (distmin) * (0.5 * O_TULMESHDISKRATIO); fprintf (stream, "(node " SCOTCH_NUMSTRING " \"(%lf,%lf,%lf)\")%c", (SCOTCH_Num) (vertnum + grafptr->baseval), distmin, distmin, distmin, c); } fprintf (stream, "\n"); } else fprintf (stream, ")\n"); fprintf (stream, ")\n"); return (0); } scotch-6.0.4.dfsg/src/libscotchmetis/0000755002563400244210000000000012407352724022702 5ustar trophimeutilisateurs du domainescotch-6.0.4.dfsg/src/libscotchmetis/metis.h0000644002563400244210000001342012024377470024174 0ustar trophimeutilisateurs du domaine/********************************************************* ** ** ** WARNING: THIS IS NOT THE ORIGINAL INCLUDE FILE OF ** ** THE MeTiS SOFTWARE PACKAGE. ** ** This file is a compatibility include file provided ** ** as part of the Scotch software distribution. ** ** Preferably use the original MeTiS include file to ** ** keep definitions of routines not overloaded by ** ** the libScotchMeTiS library. ** ** ** *********************************************************/ /* Copyright 2007,2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : metis.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Compatibility declaration file for the **/ /** MeTiS interface routines provided by **/ /** the Scotch project. **/ /** **/ /** DATES : # Version 5.0 : from : 08 sep 2006 **/ /** to 07 jun 2007 **/ /** # Version 5.1 : from : 30 jun 2010 **/ /** to 30 jun 2010 **/ /** # Version 6.0 : from : 13 sep 2012 **/ /** to 13 sep 2012 **/ /** **/ /************************************************************/ /* ** The defines. */ #ifdef SCOTCH_METIS_PREFIX #define SCOTCH_METIS_PREFIXL scotch_ #define SCOTCH_METIS_PREFIXU SCOTCH_ #endif /* SCOTCH_METIS_PREFIX */ #ifndef SCOTCH_METIS_PREFIXL #define SCOTCH_METIS_PREFIXL #endif /* SCOTCH_METIS_PREFIXL */ #ifndef SCOTCH_METIS_PREFIXU #define SCOTCH_METIS_PREFIXU #endif /* SCOTCH_METIS_PREFIXU */ #ifndef METISNAMEL #define METISNAMEL(s) METISNAME2(METISNAME3(SCOTCH_METIS_PREFIXL),s) #define METISNAMEU(s) METISNAME2(METISNAME3(SCOTCH_METIS_PREFIXU),s) #define METISNAME2(p,s) METISNAME4(p,s) #define METISNAME3(s) s #define METISNAME4(p,s) p##s #endif /* METISNAMEL */ /* ** The function prototypes. */ void METISNAMEU(METIS_EdgeND) (const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const); void METISNAMEU(METIS_NodeND) (const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const); void METISNAMEU(METIS_NodeWND) (const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const); void METISNAMEU(METIS_PartGraphKway) (const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const); void METISNAMEU(METIS_PartGraphRecursive) (const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const); void METISNAMEU(METIS_PartGraphVKway) (const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const); scotch-6.0.4.dfsg/src/libscotchmetis/parmetis.h0000644002563400244210000001252212024377241024675 0ustar trophimeutilisateurs du domaine/********************************************************* ** ** ** WARNING: THIS IS NOT THE ORIGINAL INCLUDE FILE OF ** ** THE ParMeTiS SOFTWARE PACKAGE. ** ** This file is a compatibility include file provided ** ** as part of the Scotch software distribution. ** ** Preferably use the original ParMeTiS include file ** ** to keep definitions of routines not overloaded by ** ** the libPTScotchMeTiS library. ** ** ** *********************************************************/ /* Copyright 2007,2008,2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : parmetis.h **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : Compatibility declaration file for the **/ /** MeTiS interface routines provided by **/ /** the Scotch project. **/ /** **/ /** DATES : # Version 5.0 : from : 17 oct 2007 **/ /** to 18 oct 2007 **/ /** # Version 5.1 : from : 19 jun 2008 **/ /** to 30 jun 2010 **/ /** # Version 6.0 : from : 13 sep 2012 **/ /** to 13 sep 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #ifndef __parmetis_h__ #define __parmetis_h__ #include /* Since ParMeTiS does it, do it too */ #endif /* __parmetis_h__ */ #ifdef SCOTCH_METIS_PREFIX #define SCOTCH_METIS_PREFIXL scotch_ #define SCOTCH_METIS_PREFIXU SCOTCH_ #endif /* SCOTCH_METIS_PREFIX */ #ifndef SCOTCH_METIS_PREFIXL #define SCOTCH_METIS_PREFIXL #endif /* SCOTCH_METIS_PREFIXL */ #ifndef SCOTCH_METIS_PREFIXU #define SCOTCH_METIS_PREFIXU #endif /* SCOTCH_METIS_PREFIXU */ #ifndef METISNAMEL #define METISNAMEL(s) METISNAME2(METISNAME3(SCOTCH_METIS_PREFIXL),s) #define METISNAMEU(s) METISNAME2(METISNAME3(SCOTCH_METIS_PREFIXU),s) #define METISNAME2(p,s) METISNAME4(p,s) #define METISNAME3(s) s #define METISNAME4(p,s) p##s #endif /* METISNAMEL */ /* ** The function prototypes. */ void METISNAMEU(ParMETIS_V3_NodeND) (const SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, MPI_Comm * const); void METISNAMEU(ParMETIS_V3_PartGeomKway) (const SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const float * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const float * const, const float * const, const SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, MPI_Comm * const); void METISNAMEU(ParMETIS_V3_PartKway) (const SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const SCOTCH_Num * const, const float * const, const float * const, const SCOTCH_Num * const, SCOTCH_Num * const, SCOTCH_Num * const, MPI_Comm * const); scotch-6.0.4.dfsg/src/libscotchmetis/metis_graph_order_f.c0000644002563400244210000001256612024373570027057 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : metis_graph_order_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API of **/ /** the compatibility library for the **/ /** MeTiS ordering routines. **/ /** **/ /** DATES : # Version 5.0 : from : 10 sep 2006 **/ /** to 10 sep 2006 **/ /** # Version 5.1 : from : 30 jun 2010 **/ /** to 30 jun 2010 **/ /** # Version 6.0 : from : 13 sep 2012 **/ /** to 13 sep 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "common.h" #include "scotch.h" #include "metis.h" /* Our "metis.h" file */ /**************************************/ /* */ /* These routines are the Fortran API */ /* for the graph ordering routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ METISNAMEU(METIS_EDGEND), METISNAMEL(metis_edgend), ( \ const SCOTCH_Num * const n, \ const SCOTCH_Num * const xadj, \ const SCOTCH_Num * const adjncy, \ const SCOTCH_Num * const numflag, \ const SCOTCH_Num * const options, \ SCOTCH_Num * const perm, \ SCOTCH_Num * const iperm), \ (n, xadj, adjncy, numflag, options, perm, iperm)) { METISNAMEU(METIS_EdgeND) (n, xadj, adjncy, numflag, options, perm, iperm); } /* ** */ FORTRAN ( \ METISNAMEU(METIS_NODEND), METISNAMEL(metis_nodend), ( \ const SCOTCH_Num * const n, \ const SCOTCH_Num * const xadj, \ const SCOTCH_Num * const adjncy, \ const SCOTCH_Num * const numflag, \ const SCOTCH_Num * const options, \ SCOTCH_Num * const perm, \ SCOTCH_Num * const iperm), \ (n, xadj, adjncy, numflag, options, perm, iperm)) { METISNAMEU(METIS_NodeND) (n, xadj, adjncy, numflag, options, perm, iperm); } /* When an input stream is built from the given ** file handle, it is set as unbuffered, so as to ** allow for multiple stream reads from the same ** file handle. If it were buffered, too many ** input characters would be read on the first ** block read. */ FORTRAN ( \ METISNAMEU(METIS_NODEWND), METISNAMEL(metis_nodewnd), ( \ const SCOTCH_Num * const n, \ const SCOTCH_Num * const xadj, \ const SCOTCH_Num * const adjncy, \ const SCOTCH_Num * const vwgt, \ const SCOTCH_Num * const numflag, \ const SCOTCH_Num * const options, \ SCOTCH_Num * const perm, \ SCOTCH_Num * const iperm), \ (n, xadj, adjncy, vwgt, numflag, options, perm, iperm)) { METISNAMEU(METIS_NodeWND) (n, xadj, adjncy, vwgt, numflag, options, perm, iperm); } scotch-6.0.4.dfsg/src/libscotchmetis/parmetis_dgraph_order_f.c0000644002563400244210000001003412024374150027705 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : parmetis_dgraph_order_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API of **/ /** the compatibility library for the **/ /** ParMeTiS ordering routine. **/ /** **/ /** DATES : # Version 5.0 : from : 17 oct 2007 **/ /** to 17 oct 2007 **/ /** # Version 5.1 : from : 30 jun 2010 **/ /** to 30 jun 2010 **/ /** # Version 6.0 : from : 13 sep 2012 **/ /** to 13 sep 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "common.h" #include "ptscotch.h" #include "parmetis.h" /* Our "parmetis.h" file */ /**************************************/ /* */ /* These routines are the Fortran API */ /* for the distributed graph ordering */ /* routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ METISNAMEU(PARMETIS_V3_NODEND), METISNAMEL(parmetis_v3_nodend), ( \ const SCOTCH_Num * const vtxdist, \ SCOTCH_Num * const xadj, \ SCOTCH_Num * const adjncy, \ const SCOTCH_Num * const numflag, \ const SCOTCH_Num * const options, \ SCOTCH_Num * const order, \ SCOTCH_Num * const sizes, \ MPI_Comm * const commptr), \ (vtxdist, xadj, adjncy, numflag, options, order, sizes, commptr)) { METISNAMEU(ParMETIS_V3_NodeND) (vtxdist, xadj, adjncy, numflag, options, order, sizes, commptr); } scotch-6.0.4.dfsg/src/libscotchmetis/metis_graph_part.c0000644002563400244210000003101012024415511026356 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : metis_graph_part.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the compatibility **/ /** library for the MeTiS partitioning **/ /** routines. **/ /** **/ /** DATES : # Version 5.0 : from : 08 sep 2006 **/ /** to 07 jun 2007 **/ /** # Version 5.1 : from : 06 jun 2009 **/ /** to 30 jun 2010 **/ /** # Version 6.0 : from : 23 dec 2011 **/ /** to 13 sep 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" #include "metis.h" /* Our "metis.h" file */ /************************************/ /* */ /* These routines are the C API for */ /* MeTiS graph ordering routines. */ /* */ /************************************/ /* This routine is the interface between MeTiS ** and Scotch. It computes the partition of a ** weighted or unweighted graph. ** It returns: ** - 0 : if the partition could be computed. ** - !0 : on error. */ static int _SCOTCH_METIS_PartGraph2 ( const SCOTCH_Num * const n, const SCOTCH_Num * const xadj, const SCOTCH_Num * const adjncy, const SCOTCH_Num * const vwgt, const SCOTCH_Num * const adjwgt, const SCOTCH_Num * const numflag, const SCOTCH_Num * const nparts, SCOTCH_Num * const part, SCOTCH_Num flagval, double kbalval) { SCOTCH_Graph grafdat; /* Scotch graph object to interface with libScotch */ SCOTCH_Strat stradat; SCOTCH_Num baseval; SCOTCH_Num vertnbr; int o; SCOTCH_graphInit (&grafdat); baseval = *numflag; vertnbr = *n; o = 1; /* Assume something will go wrong */ if (SCOTCH_graphBuild (&grafdat, baseval, vertnbr, xadj, xadj + 1, vwgt, NULL, xadj[vertnbr] - baseval, adjncy, adjwgt) == 0) { SCOTCH_stratInit (&stradat); SCOTCH_stratGraphMapBuild (&stradat, flagval, *nparts, kbalval); #ifdef SCOTCH_DEBUG_ALL if (SCOTCH_graphCheck (&grafdat) == 0) /* TRICK: next instruction called only if graph is consistent */ #endif /* SCOTCH_DEBUG_ALL */ o = SCOTCH_graphPart (&grafdat, *nparts, &stradat, part); SCOTCH_stratExit (&stradat); } SCOTCH_graphExit (&grafdat); if (o != 0) return (1); if (baseval != 0) { /* MeTiS part array is based, Scotch is not */ SCOTCH_Num vertnum; for (vertnum = 0; vertnum < vertnbr; vertnum ++) part[vertnum] += baseval; } return (0); } /* ** */ static void _SCOTCH_METIS_PartGraph ( const SCOTCH_Num * const n, const SCOTCH_Num * const xadj, const SCOTCH_Num * const adjncy, const SCOTCH_Num * const vwgt, const SCOTCH_Num * const adjwgt, const SCOTCH_Num * const wgtflag, const SCOTCH_Num * const numflag, const SCOTCH_Num * const nparts, const SCOTCH_Num * const options, SCOTCH_Num * const edgecut, SCOTCH_Num * const part, SCOTCH_Num flagval, double kbalval) { const SCOTCH_Num * vwgt2; const SCOTCH_Num * adjwgt2; const SCOTCH_Num * restrict parttax; const SCOTCH_Num * restrict verttax; const SCOTCH_Num * restrict edgetax; SCOTCH_Num vertnnd; SCOTCH_Num vertnum; SCOTCH_Num edgenum; SCOTCH_Num commcut; vwgt2 = (((*wgtflag & 2) != 0) ? vwgt : NULL); adjwgt2 = (((*wgtflag & 1) != 0) ? adjwgt : NULL); if (_SCOTCH_METIS_PartGraph2 (n, xadj, adjncy, vwgt2, adjwgt2, numflag, nparts, part, flagval, kbalval) != 0) { *edgecut = -1; /* Indicate error */ return; } parttax = part - *numflag; verttax = xadj - *numflag; edgetax = adjncy - *numflag; edgenum = *numflag; vertnum = *numflag; vertnnd = *n + vertnum; commcut = 0; if (adjwgt2 == NULL) { /* If graph does not have edge weights */ for ( ; vertnum < vertnnd; vertnum ++) { SCOTCH_Num edgennd; SCOTCH_Num partval; partval = parttax[vertnum]; for (edgennd = verttax[vertnum + 1]; edgenum < edgennd; edgenum ++) { if (parttax[edgetax[edgenum]] != partval) commcut ++; } } } else { /* Graph has edge weights */ const SCOTCH_Num * restrict edlotax; edlotax = adjwgt2 - *numflag; for ( ; vertnum < vertnnd; vertnum ++) { SCOTCH_Num edgennd; SCOTCH_Num partval; partval = parttax[vertnum]; for (edgennd = verttax[vertnum + 1]; edgenum < edgennd; edgenum ++) { SCOTCH_Num vertend; vertend = edgetax[edgenum]; if (parttax[vertend] != partval) commcut += edlotax[edgenum]; } } } *edgecut = commcut / 2; } /* ** */ void METISNAMEU (METIS_PartGraphKway) ( const SCOTCH_Num * const n, const SCOTCH_Num * const xadj, const SCOTCH_Num * const adjncy, const SCOTCH_Num * const vwgt, const SCOTCH_Num * const adjwgt, const SCOTCH_Num * const wgtflag, const SCOTCH_Num * const numflag, const SCOTCH_Num * const nparts, const SCOTCH_Num * const options, SCOTCH_Num * const edgecut, SCOTCH_Num * const part) { _SCOTCH_METIS_PartGraph (n, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part, SCOTCH_STRATDEFAULT, 0.01); } void METISNAMEU (METIS_PartGraphRecursive) ( const SCOTCH_Num * const n, const SCOTCH_Num * const xadj, const SCOTCH_Num * const adjncy, const SCOTCH_Num * const vwgt, const SCOTCH_Num * const adjwgt, const SCOTCH_Num * const wgtflag, const SCOTCH_Num * const numflag, const SCOTCH_Num * const nparts, const SCOTCH_Num * const options, SCOTCH_Num * const edgecut, SCOTCH_Num * const part) { _SCOTCH_METIS_PartGraph (n, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part, SCOTCH_STRATRECURSIVE, 0.01); } /* Scotch does not directly consider communication volume. ** Instead, wertex communication loads are added to the edge ** loads so as to emulate this behavior: heavily weighted ** edges, connected to heavily communicating vertices, will ** be less likely to be cut. */ void METISNAMEU (METIS_PartGraphVKway) ( const SCOTCH_Num * const n, const SCOTCH_Num * const xadj, const SCOTCH_Num * const adjncy, const SCOTCH_Num * const vwgt, const SCOTCH_Num * const vsize, const SCOTCH_Num * const wgtflag, const SCOTCH_Num * const numflag, const SCOTCH_Num * const nparts, const SCOTCH_Num * const options, SCOTCH_Num * const volume, SCOTCH_Num * const part) { SCOTCH_Num baseval; const SCOTCH_Num * vwgt2; const SCOTCH_Num * vsize2; SCOTCH_Num vsizval; /* Communication volume of current vertex */ SCOTCH_Num vertnbr; SCOTCH_Num vertnum; SCOTCH_Num edgenum; const SCOTCH_Num * restrict edgetax; const SCOTCH_Num * restrict parttax; SCOTCH_Num * restrict nghbtab; SCOTCH_Num commvol; vsize2 = ((*wgtflag & 1) != 0) ? vsize : NULL; vwgt2 = ((*wgtflag & 2) != 0) ? vwgt : NULL; baseval = *numflag; vertnbr = *n; edgetax = adjncy - baseval; if (vsize2 == NULL) { /* If no communication load data provided */ if (_SCOTCH_METIS_PartGraph2 (n, xadj, adjncy, vwgt2, NULL, numflag, nparts, part, SCOTCH_STRATDEFAULT, 0.01) != 0) return; } else { /* Will have to turn communication volumes into edge loads */ const SCOTCH_Num * restrict vsiztax; SCOTCH_Num edgenbr; SCOTCH_Num * restrict edlotax; int o; edgenbr = xadj[vertnbr] - baseval; if ((edlotax = memAlloc (edgenbr * sizeof (SCOTCH_Num))) == NULL) return; edlotax -= baseval; /* Base access to edlotax */ vsiztax = vsize2 - baseval; for (vertnum = 0, edgenum = baseval; /* Un-based scan of vertex array xadj */ vertnum < vertnbr; vertnum ++) { SCOTCH_Num vsizval; /* Communication size of current vertex */ SCOTCH_Num edgennd; vsizval = vsize2[vertnum]; for (edgennd = xadj[vertnum + 1]; edgenum < edgennd; edgenum ++) { /* Based traversal of edge array adjncy */ SCOTCH_Num vertend; /* Based end vertex number */ vertend = edgetax[edgenum]; edlotax[edgenum] = vsizval + vsiztax[vertend]; } } o = _SCOTCH_METIS_PartGraph2 (n, xadj, adjncy, vwgt2, edlotax + baseval, numflag, nparts, part, SCOTCH_STRATDEFAULT, 0.01); memFree (edlotax + baseval); if (o != 0) return; } if ((nghbtab = memAlloc (*nparts * sizeof (SCOTCH_Num))) == NULL) return; memSet (nghbtab, ~0, *nparts * sizeof (SCOTCH_Num)); parttax = part - baseval; vsizval = 1; /* Assume no vertex communication sizes */ for (vertnum = 0, edgenum = baseval, commvol = 0; /* Un-based scan of vertex array xadj */ vertnum < vertnbr; vertnum ++) { SCOTCH_Num partval; SCOTCH_Num edgennd; partval = part[vertnum]; nghbtab[partval] = vertnum; /* Do not count local neighbors in communication volume */ if (vsize2 != NULL) vsizval = vsize2[vertnum]; for (edgennd = xadj[vertnum + 1]; edgenum < edgennd; edgenum ++) { /* Based traversal of edge array adjncy */ SCOTCH_Num vertend; /* Based end vertex number */ SCOTCH_Num partend; vertend = edgetax[edgenum]; partend = parttax[vertend]; if (nghbtab[partend] != vertnum) { /* If first neighbor in this part */ nghbtab[partend] = vertnum; /* Set part as accounted for */ commvol += vsizval; } } } *volume = commvol; memFree (nghbtab); } scotch-6.0.4.dfsg/src/libscotchmetis/parmetis_dgraph_part_f.c0000644002563400244210000001450212024374312027544 0ustar trophimeutilisateurs du domaine/* Copyright 2008,2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : parmetis_dgraph_part_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API of **/ /** the compatibility library for the **/ /** ParMeTiS partitioning routine. **/ /** **/ /** DATES : # Version 5.1 : from : 19 jun 2008 **/ /** to 30 jun 2010 **/ /** # Version 6.0 : from : 13 sep 2012 **/ /** to 13 sep 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "common.h" #include "ptscotch.h" #include "parmetis.h" /* Our "parmetis.h" file */ /**************************************/ /* */ /* These routines are the Fortran API */ /* for the distributed graph ordering */ /* routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ METISNAMEU(PARMETIS_V3_PARTKWAY), METISNAMEL(parmetis_v3_partkway), ( \ const SCOTCH_Num * const vtxdist, \ SCOTCH_Num * const xadj, \ SCOTCH_Num * const adjncy, \ SCOTCH_Num * const vwgt, \ SCOTCH_Num * const adjwgt, \ const SCOTCH_Num * const wgtflag, \ const SCOTCH_Num * const numflag, \ const SCOTCH_Num * const ncon, \ const SCOTCH_Num * const nparts, \ const float * const tpwgts, \ const float * const ubvec, \ const SCOTCH_Num * const options, \ SCOTCH_Num * const edgecut, \ SCOTCH_Num * const part, \ MPI_Comm * const commptr), \ (vtxdist, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, ncon, nparts, tpwgts, ubvec, options, edgecut, part, commptr)) { METISNAMEU(ParMETIS_V3_PartKway) (vtxdist, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, ncon, nparts, tpwgts, ubvec, options, edgecut, part, commptr); } /* ** */ FORTRAN ( \ METISNAMEU(PARMETIS_V3_PARTGEOMKWAY), METISNAMEL(parmetis_v3_partgeomkway), ( \ const SCOTCH_Num * const vtxdist, \ SCOTCH_Num * const xadj, \ SCOTCH_Num * const adjncy, \ SCOTCH_Num * const vwgt, \ SCOTCH_Num * const adjwgt, \ const SCOTCH_Num * const wgtflag, \ const SCOTCH_Num * const numflag, \ const SCOTCH_Num * const ndims, \ const float * const xyz, \ const SCOTCH_Num * const ncon, \ const SCOTCH_Num * const nparts, \ const float * const tpwgts, \ const float * const ubvec, \ const SCOTCH_Num * const options, \ SCOTCH_Num * const edgecut, \ SCOTCH_Num * const part, \ MPI_Comm * const commptr), \ (vtxdist, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, ndims, xyz, ncon, nparts, tpwgts, ubvec, options, edgecut, part, commptr)) { METISNAMEU(ParMETIS_V3_PartGeomKway) (vtxdist, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, ndims, xyz, ncon, nparts, tpwgts, ubvec, options, edgecut, part, commptr); } scotch-6.0.4.dfsg/src/libscotchmetis/parmetis_dgraph_order.c0000644002563400244210000002307512024376601027414 0ustar trophimeutilisateurs du domaine/* Copyright 2007-2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : parmetis_dgraph_order.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the compatibility **/ /** library for the ParMeTiS ordering **/ /** routines. **/ /** **/ /** DATES : # Version 5.0 : from : 17 oct 2007 **/ /** to 07 dec 2007 **/ /** # Version 5.1 : from : 18 mar 2009 **/ /** to 30 jun 2010 **/ /** # Version 6.0 : from : 13 sep 2012 **/ /** to 13 sep 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "ptscotch.h" #include "parmetis.h" /* Our "parmetis.h" file */ /************************************/ /* */ /* These routines are the C API for */ /* the ParMeTiS graph ordering */ /* routine. */ /* */ /************************************/ static void _SCOTCH_ParMETIS_V3_NodeNDTree ( SCOTCH_Num * const sizeglbtnd, SCOTCH_Num * const sizeglbtab, SCOTCH_Num * const sepaglbtab, const SCOTCH_Num levlmax, const SCOTCH_Num levlnum, const SCOTCH_Num cblknum, SCOTCH_Num cblkidx) { SCOTCH_Num sizeval; sizeval = sizeglbtab[cblknum]; /* Assume node is terminal or has no nested dissection sons */ if (levlnum < levlmax) { if ((sepaglbtab[3 * cblknum] >= 0) && /* If node has at least two sons, assume is is a nested dissection node */ (sepaglbtab[3 * cblknum + 1] >= 0)) { _SCOTCH_ParMETIS_V3_NodeNDTree (sizeglbtnd, sizeglbtab, sepaglbtab, levlmax, levlnum + 1, sepaglbtab[3 * cblknum], (cblkidx << 1) + 1); _SCOTCH_ParMETIS_V3_NodeNDTree (sizeglbtnd, sizeglbtab, sepaglbtab, levlmax, levlnum + 1, sepaglbtab[3 * cblknum + 1], (cblkidx << 1)); sizeval = (sepaglbtab[3 * cblknum + 2] < 0) ? 0 : sizeglbtab[sepaglbtab[3 * cblknum + 2]]; /* Get size of separator, if any */ } } sizeglbtnd[- cblkidx] = sizeval; /* Set size of current column block */ } /* ** */ void METISNAMEU(ParMETIS_V3_NodeND) ( const SCOTCH_Num * const vtxdist, SCOTCH_Num * const xadj, SCOTCH_Num * const adjncy, const SCOTCH_Num * const numflag, const SCOTCH_Num * const options, /* Not used */ SCOTCH_Num * const order, SCOTCH_Num * const sizes, /* Of size twice the number of processors ; not used */ MPI_Comm * comm) { MPI_Comm proccomm; int procglbnbr; int proclocnum; SCOTCH_Num baseval; SCOTCH_Dgraph grafdat; /* Scotch distributed graph object to interface with libScotch */ SCOTCH_Dordering ordedat; /* Scotch distributed ordering object to interface with libScotch */ SCOTCH_Strat stradat; SCOTCH_Num vertlocnbr; SCOTCH_Num edgelocnbr; proccomm = *comm; if (SCOTCH_dgraphInit (&grafdat, proccomm) != 0) return; MPI_Comm_size (proccomm, &procglbnbr); MPI_Comm_rank (proccomm, &proclocnum); baseval = *numflag; vertlocnbr = vtxdist[proclocnum + 1] - vtxdist[proclocnum]; edgelocnbr = xadj[vertlocnbr] - baseval; if (sizes != NULL) memSet (sizes, ~0, (2 * procglbnbr - 1) * sizeof (SCOTCH_Num)); /* Array not used if procglbnbr is not a power of 2 or if error */ if (SCOTCH_dgraphBuild (&grafdat, baseval, vertlocnbr, vertlocnbr, xadj, xadj + 1, NULL, NULL, edgelocnbr, edgelocnbr, adjncy, NULL, NULL) == 0) { SCOTCH_stratInit (&stradat); #ifdef SCOTCH_DEBUG_ALL if (SCOTCH_dgraphCheck (&grafdat) == 0) /* TRICK: next instruction called only if graph is consistent */ #endif /* SCOTCH_DEBUG_ALL */ { if (SCOTCH_dgraphOrderInit (&grafdat, &ordedat) == 0) { SCOTCH_Num levlmax; SCOTCH_Num bitsnbr; SCOTCH_Num proctmp; SCOTCH_dgraphOrderCompute (&grafdat, &ordedat, &stradat); SCOTCH_dgraphOrderPerm (&grafdat, &ordedat, order); for (levlmax = -1, bitsnbr = 0, proctmp = procglbnbr; /* Count number of bits set to 1 in procglbnbr */ proctmp != 0; levlmax ++, proctmp >>= 1) bitsnbr += proctmp & 1; if (bitsnbr == 1) { SCOTCH_Num cblkglbnbr; if ((cblkglbnbr = SCOTCH_dgraphOrderCblkDist (&grafdat, &ordedat)) >= 0) { SCOTCH_Num * treeglbtab; SCOTCH_Num * sizeglbtab; SCOTCH_Num * sepaglbtab; if (memAllocGroup ((void **) (void *) &treeglbtab, (size_t) (cblkglbnbr * sizeof (SCOTCH_Num)), &sizeglbtab, (size_t) (cblkglbnbr * sizeof (SCOTCH_Num)), &sepaglbtab, (size_t) (cblkglbnbr * sizeof (SCOTCH_Num) * 3), NULL) != NULL) { if (SCOTCH_dgraphOrderTreeDist (&grafdat, &ordedat, treeglbtab, sizeglbtab) == 0) { SCOTCH_Num rootnum; SCOTCH_Num cblknum; memSet (sepaglbtab, ~0, cblkglbnbr * sizeof (SCOTCH_Num) * 3); for (rootnum = -1, cblknum = 0; cblknum < cblkglbnbr; cblknum ++) { SCOTCH_Num fathnum; fathnum = treeglbtab[cblknum] - baseval; /* Use un-based indices */ if (fathnum < 0) { /* If father index indicates root */ if (rootnum != -1) { /* If another root already found */ rootnum = -1; /* Indicate an error */ break; } rootnum = cblknum; /* Record index of root node */ } else { SCOTCH_Num i; for (i = 0; i < 3; i ++) { SCOTCH_Num j; j = 3 * fathnum + i; /* Slot number of prospective son */ if (sepaglbtab[j] < 0) { /* If potentially empty slot found */ if (sepaglbtab[j] == -1) /* If we don't have too many sons */ sepaglbtab[j] = cblknum; /* Add link to son in slot */ break; } } if (i == 3) { /* If no empty slot found */ sepaglbtab[3 * fathnum] = -2; /* Indicate there are too many sons */ break; } } } if ((rootnum >= 0) && (sizes != NULL)) { /* If no error above, go on processing separator tree */ memSet (sizes, 0, (2 * procglbnbr - 1) * sizeof (SCOTCH_Num)); /* Set array of sizes to 0 by default */ _SCOTCH_ParMETIS_V3_NodeNDTree (sizes + (2 * procglbnbr - 1), sizeglbtab, sepaglbtab, levlmax, 0, rootnum, 1); } } memFree (treeglbtab); /* Free group leader */ } } } SCOTCH_dgraphOrderExit (&grafdat, &ordedat); } } SCOTCH_stratExit (&stradat); } SCOTCH_dgraphExit (&grafdat); } scotch-6.0.4.dfsg/src/libscotchmetis/Makefile0000644002563400244210000001033211631447170024337 0ustar trophimeutilisateurs du domaine## Copyright 2007-2010 ENSEIRB, INRIA & CNRS ## ## This file is part of the Scotch software package for static mapping, ## graph partitioning and sparse matrix ordering. ## ## This software is governed by the CeCILL-C license under French law ## and abiding by the rules of distribution of free software. You can ## use, modify and/or redistribute the software under the terms of the ## CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ## URL: "http://www.cecill.info". ## ## As a counterpart to the access to the source code and rights to copy, ## modify and redistribute granted by the license, users are provided ## only with a limited warranty and the software's author, the holder of ## the economic rights, and the successive licensors have only limited ## liability. ## ## In this respect, the user's attention is drawn to the risks associated ## with loading, using, modifying and/or developing or reproducing the ## software by the user in light of its specific status of free software, ## that may mean that it is complicated to manipulate, and that also ## therefore means that it is reserved for developers and experienced ## professionals having in-depth computer knowledge. Users are therefore ## encouraged to load and test the software's suitability as regards ## their requirements in conditions enabling the security of their ## systems and/or data to be ensured and, more generally, to use and ## operate it in the same conditions as regards security. ## ## The fact that you are presently reading this means that you have had ## knowledge of the CeCILL-C license and that you accept its terms. ## bindir = ../../bin includedir = ../../include libdir = ../../lib ## ## General inference rules. ## include ../Makefile.inc %$(OBJ) : %.c $(CC) $(CFLAGS) $(CLIBFLAGS) -I$(includedir) -I../libscotch -c $(<) -o $(@) %$(EXE) : %.c $(CC) $(CFLAGS) -I$(includedir) -I../libscotch $(<) -o $(@) -L$(libdir) $(LDFLAGS) ## ## Project rules. ## .PHONY : ptscotch scotch ptinstall install clean realclean scotch : $(MAKE) CC="$(CCS)" SCOTCHLIB=ptscotch \ libscotchmetis$(LIB) ptscotch : $(MAKE) CFLAGS="$(CFLAGS) -DSCOTCH_PTSCOTCH" CC="$(CCP)" SCOTCHLIB=ptscotch \ libptscotchparmetis$(LIB) install : scotch -$(CP) metis.h $(includedir) -$(CP) libscotchmetis$(LIB) $(libdir) ptinstall : ptscotch -$(CP) parmetis.h $(includedir) -$(CP) libptscotchparmetis$(LIB) $(libdir) clean : -$(RM) *~ *$(OBJ) lib*$(LIB) realclean : clean ## ## Todo list. ## metis_graph_order$(OBJ) : metis_graph_order.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ metis.h metis_graph_order_f$(OBJ) : metis_graph_order_f.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ metis.h metis_graph_part$(OBJ) : metis_graph_part.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ metis.h metis_graph_part_f$(OBJ) : metis_graph_part_f.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/scotch.h \ metis.h parmetis_dgraph_order$(OBJ) : parmetis_dgraph_order.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/ptscotch.h \ parmetis.h parmetis_dgraph_order_f$(OBJ) : parmetis_dgraph_order_f.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/ptscotch.h \ parmetis.h parmetis_dgraph_part$(OBJ) : parmetis_dgraph_part.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/ptscotch.h \ parmetis.h parmetis_dgraph_part_f$(OBJ) : parmetis_dgraph_part_f.c \ ../libscotch/module.h \ ../libscotch/common.h \ $(includedir)/ptscotch.h \ parmetis.h libptscotchparmetis$(LIB) : parmetis_dgraph_order$(OBJ) \ parmetis_dgraph_order_f$(OBJ) \ parmetis_dgraph_part$(OBJ) \ parmetis_dgraph_part_f$(OBJ) $(AR) $(ARFLAGS) $(@) $(^) -$(RANLIB) $(@) libscotchmetis$(LIB) : metis_graph_order$(OBJ) \ metis_graph_order_f$(OBJ) \ metis_graph_part$(OBJ) \ metis_graph_part_f$(OBJ) $(AR) $(ARFLAGS) $(@) $(^) -$(RANLIB) $(@) scotch-6.0.4.dfsg/src/libscotchmetis/parmetis_dgraph_part.c0000644002563400244210000001703712024376724027256 0ustar trophimeutilisateurs du domaine/* Copyright 2008-2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : parmetis_dgraph_part.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the compatibility **/ /** library for the ParMeTiS ordering **/ /** routines. **/ /** **/ /** DATES : # Version 5.1 : from : 19 jun 2008 **/ /** to 30 jun 2010 **/ /** # Version 6.0 : from : 13 sep 2012 **/ /** to 13 sep 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "ptscotch.h" #include "parmetis.h" /* Our "parmetis.h" file */ /************************************/ /* */ /* These routines are the C API for */ /* the ParMeTiS graph ordering */ /* routine. */ /* */ /************************************/ void METISNAMEU(ParMETIS_V3_PartKway) ( const SCOTCH_Num * const vtxdist, SCOTCH_Num * const xadj, SCOTCH_Num * const adjncy, SCOTCH_Num * const vwgt, SCOTCH_Num * const adjwgt, const SCOTCH_Num * const wgtflag, const SCOTCH_Num * const numflag, const SCOTCH_Num * const ncon, /* Not used */ const SCOTCH_Num * const nparts, const float * const tpwgts, const float * const ubvec, /* Not used */ const SCOTCH_Num * const options, /* Not used */ SCOTCH_Num * const edgecut, SCOTCH_Num * const part, MPI_Comm * comm) { MPI_Comm proccomm; int procglbnbr; int proclocnum; SCOTCH_Num baseval; SCOTCH_Arch archdat; SCOTCH_Dgraph grafdat; /* Scotch distributed graph object to interface with libScotch */ SCOTCH_Dmapping mappdat; /* Scotch distributed mapping object to interface with libScotch */ SCOTCH_Strat stradat; SCOTCH_Num vertlocnbr; SCOTCH_Num * veloloctab; SCOTCH_Num edgelocnbr; SCOTCH_Num * edloloctab; SCOTCH_Num * velotab; double * vwgttab; SCOTCH_Num i; if ((vwgttab = malloc (*nparts * sizeof (double))) == NULL) return; if ((velotab = malloc (*nparts * sizeof (SCOTCH_Num))) == NULL) { free (vwgttab); return; } for (i = 0; i < *nparts; i ++) vwgttab[i] = (double) tpwgts[i] * (double) (*nparts); for (i = 0; i < *nparts; i ++) { double deltval; deltval = fabs (vwgttab[i] - floor (vwgttab[i] + 0.5)); if (deltval > 0.01) { SCOTCH_Num j; deltval = 1.0 / deltval; for (j = 0; j < *nparts; j ++) vwgttab[j] *= deltval; } } for (i = 0; i < *nparts; i ++) velotab[i] = (SCOTCH_Num) (vwgttab[i] + 0.5); proccomm = *comm; if (SCOTCH_dgraphInit (&grafdat, proccomm) != 0) return; MPI_Comm_size (proccomm, &procglbnbr); MPI_Comm_rank (proccomm, &proclocnum); baseval = *numflag; vertlocnbr = vtxdist[proclocnum + 1] - vtxdist[proclocnum]; edgelocnbr = xadj[vertlocnbr] - baseval; veloloctab = ((vwgt != NULL) && ((*wgtflag & 2) != 0)) ? vwgt : NULL; edloloctab = ((adjwgt != NULL) && ((*wgtflag & 1) != 0)) ? adjwgt : NULL; if (SCOTCH_dgraphBuild (&grafdat, baseval, vertlocnbr, vertlocnbr, xadj, xadj + 1, veloloctab, NULL, edgelocnbr, edgelocnbr, adjncy, NULL, edloloctab) == 0) { SCOTCH_stratInit (&stradat); #ifdef SCOTCH_DEBUG_ALL if (SCOTCH_dgraphCheck (&grafdat) == 0) /* TRICK: next instruction called only if graph is consistent */ #endif /* SCOTCH_DEBUG_ALL */ { SCOTCH_archInit (&archdat); if ((SCOTCH_archCmpltw (&archdat, *nparts, velotab) == 0) && (SCOTCH_dgraphMapInit (&grafdat, &mappdat, &archdat, part) == 0)) { SCOTCH_dgraphMapCompute (&grafdat, &mappdat, &stradat); SCOTCH_dgraphMapExit (&grafdat, &mappdat); } SCOTCH_archExit (&archdat); } SCOTCH_stratExit (&stradat); } SCOTCH_dgraphExit (&grafdat); *edgecut = 0; /* TODO : compute real edge cut for people who might want it */ free (vwgttab); free (velotab); if (baseval != 0) { /* MeTiS part array is based, Scotch is not */ SCOTCH_Num vertlocnum; for (vertlocnum = 0; vertlocnum < vertlocnbr; vertlocnum ++) part[vertlocnum] += baseval; } } /* ** */ void METISNAMEU(ParMETIS_V3_PartGeomKway) ( const SCOTCH_Num * const vtxdist, SCOTCH_Num * const xadj, SCOTCH_Num * const adjncy, SCOTCH_Num * const vwgt, SCOTCH_Num * const adjwgt, const SCOTCH_Num * const wgtflag, const SCOTCH_Num * const numflag, const SCOTCH_Num * const ndims, /* Not used */ const float * const xyz, /* Not used */ const SCOTCH_Num * const ncon, /* Not used */ const SCOTCH_Num * const nparts, const float * const tpwgts, const float * const ubvec, const SCOTCH_Num * const options, /* Not used */ SCOTCH_Num * const edgecut, SCOTCH_Num * const part, MPI_Comm * commptr) { METISNAMEU(ParMETIS_V3_PartKway) (vtxdist, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, ncon, nparts, tpwgts, ubvec, options, edgecut, part, commptr); } scotch-6.0.4.dfsg/src/libscotchmetis/metis_graph_part_f.c0000644002563400244210000001513712024374050026701 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : metis_graph_part_f.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This file contains the Fortran API of **/ /** the compatibility library for the **/ /** MeTiS partitioning routines. **/ /** **/ /** DATES : # Version 5.0 : from : 10 sep 2006 **/ /** to 07 jun 2007 **/ /** # Version 5.1 : from : 30 jun 2010 **/ /** to 30 jun 2010 **/ /** # Version 6.0 : from : 13 sep 2012 **/ /** to 13 sep 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "common.h" #include "scotch.h" #include "metis.h" /* Our "metis.h" file */ /**************************************/ /* */ /* These routines are the Fortran API */ /* for the graph ordering routines. */ /* */ /**************************************/ /* ** */ FORTRAN ( \ METISNAMEU(METIS_PARTGRAPHKWAY), METISNAMEL(metis_partgraphkway), ( \ const SCOTCH_Num * const n, \ const SCOTCH_Num * const xadj, \ const SCOTCH_Num * const adjncy, \ const SCOTCH_Num * const vwgt, \ const SCOTCH_Num * const adjwgt, \ const SCOTCH_Num * const wgtflag, \ const SCOTCH_Num * const numflag, \ const SCOTCH_Num * const nparts, \ const SCOTCH_Num * const options, \ SCOTCH_Num * const edgecut, \ SCOTCH_Num * const part), \ (n, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part)) { METISNAMEU(METIS_PartGraphKway) (n, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); } /* ** */ FORTRAN ( \ METISNAMEU(METIS_PARTGRAPHRECURSIVE), METISNAMEL(metis_partgraphrecursive), ( \ const SCOTCH_Num * const n, \ const SCOTCH_Num * const xadj, \ const SCOTCH_Num * const adjncy, \ const SCOTCH_Num * const vwgt, \ const SCOTCH_Num * const adjwgt, \ const SCOTCH_Num * const wgtflag, \ const SCOTCH_Num * const numflag, \ const SCOTCH_Num * const nparts, \ const SCOTCH_Num * const options, \ SCOTCH_Num * const edgecut, \ SCOTCH_Num * const part), \ (n, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part)) { METISNAMEU(METIS_PartGraphRecursive) (n, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); } /* ** */ FORTRAN ( \ METISNAMEU(METIS_PARTGRAPHVKWAY), METISNAMEL(metis_partgraphvkway), ( \ const SCOTCH_Num * const n, \ const SCOTCH_Num * const xadj, \ const SCOTCH_Num * const adjncy, \ const SCOTCH_Num * const vwgt, \ const SCOTCH_Num * const vsize, \ const SCOTCH_Num * const wgtflag, \ const SCOTCH_Num * const numflag, \ const SCOTCH_Num * const nparts, \ const SCOTCH_Num * const options, \ SCOTCH_Num * const volume, \ SCOTCH_Num * const part), \ (n, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, options, volume, part)) { METISNAMEU(METIS_PartGraphVKway) (n, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, options, volume, part); } scotch-6.0.4.dfsg/src/libscotchmetis/metis_graph_order.c0000644002563400244210000001236612024375703026550 0ustar trophimeutilisateurs du domaine/* Copyright 2007,2008,2010,2012 IPB, Universite de Bordeaux, INRIA & CNRS ** ** This file is part of the Scotch software package for static mapping, ** graph partitioning and sparse matrix ordering. ** ** This software is governed by the CeCILL-C license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-C license and that you accept its terms. */ /************************************************************/ /** **/ /** NAME : metis_graph_order.c **/ /** **/ /** AUTHOR : Francois PELLEGRINI **/ /** **/ /** FUNCTION : This module is the compatibility **/ /** library for the MeTiS ordering **/ /** routines. **/ /** **/ /** DATES : # Version 5.0 : from : 08 sep 2006 **/ /** to 07 jun 2007 **/ /** # Version 5.1 : from : 30 jun 2010 **/ /** to 30 jun 2010 **/ /** # Version 6.0 : from : 13 sep 2012 **/ /** to 13 sep 2012 **/ /** **/ /************************************************************/ /* ** The defines and includes. */ #define LIBRARY #include "module.h" #include "common.h" #include "scotch.h" #include "metis.h" /* Our "metis.h" file */ /************************************/ /* */ /* These routines are the C API for */ /* MeTiS graph ordering routines. */ /* */ /************************************/ /* ** */ void METISNAMEU(METIS_EdgeND) ( const SCOTCH_Num * const n, const SCOTCH_Num * const xadj, const SCOTCH_Num * const adjncy, const SCOTCH_Num * const numflag, const SCOTCH_Num * const options, SCOTCH_Num * const perm, SCOTCH_Num * const iperm) { METISNAMEU(METIS_NodeWND) (n, xadj, adjncy, NULL, numflag, options, perm, iperm); } /* ** */ void METISNAMEU(METIS_NodeND) ( const SCOTCH_Num * const n, const SCOTCH_Num * const xadj, const SCOTCH_Num * const adjncy, const SCOTCH_Num * const numflag, const SCOTCH_Num * const options, SCOTCH_Num * const perm, SCOTCH_Num * const iperm) { METISNAMEU(METIS_NodeWND) (n, xadj, adjncy, NULL, numflag, options, perm, iperm); } /* ** */ void METISNAMEU(METIS_NodeWND) ( const SCOTCH_Num * const n, const SCOTCH_Num * const xadj, const SCOTCH_Num * const adjncy, const SCOTCH_Num * const vwgt, const SCOTCH_Num * const numflag, const SCOTCH_Num * const options, SCOTCH_Num * const perm, SCOTCH_Num * const iperm) { SCOTCH_Graph grafdat; /* Scotch graph object to interface with libScotch */ SCOTCH_Ordering ordedat; /* Scotch ordering object to interface with libScotch */ SCOTCH_Strat stradat; SCOTCH_graphInit (&grafdat); if (SCOTCH_graphBuild (&grafdat, *numflag, *n, xadj, xadj + 1, vwgt, NULL, xadj[*n] - *numflag, adjncy, NULL) == 0) { SCOTCH_stratInit (&stradat); #ifdef SCOTCH_DEBUG_ALL if (SCOTCH_graphCheck (&grafdat) == 0) /* TRICK: next instruction called only if graph is consistent */ #endif /* SCOTCH_DEBUG_ALL */ { if (SCOTCH_graphOrderInit (&grafdat, &ordedat, iperm, perm, /* MeTiS and Scotch have opposite definitions for (inverse) permutations */ NULL, NULL, NULL) == 0) { SCOTCH_graphOrderCompute (&grafdat, &ordedat, &stradat); SCOTCH_graphOrderExit (&grafdat, &ordedat); } } SCOTCH_stratExit (&stradat); } SCOTCH_graphExit (&grafdat); } scotch-6.0.4.dfsg/LICENCE_fr.txt0000644002563400244210000000061611653315735021377 0ustar trophimeutilisateurs du domaineCette copie de la distribution logicielle Scotch 6.0 est distribue selon les termes de la licence de logiciel libre CeCILL-C. Une copie du texte de cette licence se trouve dans le sous-rpertoire "doc", dans le fichier appel "CeCILL-C_V1-fr.txt". Veuillez en lire attentivement les clauses. Vous ne pourrez utiliser cette copie de la distribution logicielle Scotch 6.0 que si vous les acceptez. scotch-6.0.4.dfsg/grf/0000755002563400244210000000000011762163747017665 5ustar trophimeutilisateurs du domainescotch-6.0.4.dfsg/grf/4elt.grf.gz0000644002563400244210000051655611631447171021665 0ustar trophimeutilisateurs du domaine[5L[6D?ZJ;9%qde$gy7ko/߿ǧ[}wES=~k+ﯥqtG߿_ #'~9ha;NK]z~~?6V|ڿÒ]gl0kk-~ٟm_(ma ~xw3u3 Cf<[~?w~40O\{þ_aQ!렏h!hz[`s11G`41__爟ƨþqƱFҖhlE-g¯/mio(X"hߏf9<~78UaqúMhuޟ];?/VoV3a,~ۓ?zpq|.D#*N=[ ;~ÏH1hׯşc0 w# =pZࡇmn7 τZa{ cG-s03Wnz'oԿ: ADW_#/?Ya4-8cp{JF~CyEp{Hn_:`'Y~7¢6OB< 'sva _>\3 _tGx=~pן_G#bO~-l'Y~]FףVG~? ?FGDh>p/'4ah75kg?>6~Dun"ShwoP~'C8^,{B?"6t$ߝ;\!Z,.Ll$GS0 Fë5@_84~EN·KHǀ|w[yҽaMK OB /Uph8{d^etާ#H D!wJ1_{/d{ˏX я{^H֏aH3)|bMa3Nc8N.bl|pd7[G<юя-fkt6%hif[d3mmT%Q6HQ%㝸U/|B'$}HGj+ =p?>I#Gmh޿6cÿF?@cHxjI?ZGƁH+[h,Y!*Ub\K8Rݴ;-h)z9b} l(׶/<&-wTL VR*`t:0 D v ?xX0(KDxmp>¤X7?=. RLTйG'@DWOԝl_#{{>˟1ᵟC^m8,j,1$O?E*&"Ke#PZ NP1E n7$]B98HpXЇiƦ`7-O22avo̧{|0|bGᄶOY/X}OgNRj͘v2ݩ?;qZ%[G)ˀD *`0?-^T?}lLe/AN,@rlB$fEBl %:-o#~}}x@8s/ =5tD58VB%V!~i%D 'Ⰶq_\nԅmaA,".+S紴)Xi])jZo XBL\ XB # SJ\;&OMtY2aOY rG+|p%437b +<˪ Nx4!rF4+Gv4+M\, ,k'z8qSGQ!zp ]bNKJHbm~x{,X{3Ѱˡ,e2#>p!;@j9H ?E@[xjklP=z&5K;uK䝐0zU;23.LzP#Z$#+.y=#8<[ 9Z6҈e|"~--c:X}`"JbܱJNq/5ŠRsAkWB7[ƸHy(ᩅx2OAeN>u4vG/㊈tT *A  X)Kk6qeJ< 7*j(7m~g|VM0 meva#:8qt)0b&W㢰=_tpbwZ*mt8&@UOD~,zzmF~W3xf=x&oi cK/+l+c``;^dUfk} J#錾{2'_6sCb>@'^: ēgO}GUDhňnN?—x '5g>Et}ҠLxYrŜ5_UPJGkx\Ɛ}0 CN+ &$T&8Gch("bDF]:;p~G$ nMQ+,>#|JܦlkvfG M<ݷ߯V;(.Jn Pgϰš;NL{{&t5VFڴ-6OL7,h.6H€ȴ+pl! sDw;6D0/$g`}#E=!h@A ʆal5Dേ0[}8DX=0}oD$xBdvՒYu,jq/ᏻ6@? e;FO/J$ðc,"DR O*_a`.2}h ﷥?'Waz4pO. %WRVw#fx><߇WH,i?QQF.?ΤxK b7c]20 z@5(}X K){+ VC^CmÆ܁XIG)KKhF!$ R[0cgŪ$ E:8QQx%9JxûJc1bLۍu1j% u'5ŏn(Ό7ݖcb2 ߮V1DK u+ZH1.ĕDlbCM;0xބ r40 0Wd)%mʀdEڐx/gJ^! XCj#Th€6"1~9E8cRE1)"m U5 #EQx1ū^A!;C3u;a{~!WT3)Mzz>^>{_  b$k7,i X?}ܲ"0QwFрp`' :^{Pq/k>:5t Z=AxCH_?áπ~U@=7Cg;ʗ}2P/ }LwLhW:c)rˆQœ#sh#(rٸ0k T PyD ؎4_'.jħo<~s$14R ?1j#ЉG}Ļ@QV;F?Q Y*Ie<؏'F{z8X ;q)VxfN59~n2^U`wߢ먨<O3zKuKfn$o3FXvީ]Ng"ʼS棏);9Kn'VKAW숩G 7=|tmx:Xs,Pjooxm83WxO_!-3~gd nV'D]aፕTۨXb- &ċD ކp"=a\5F|1r1d\Ӌh""|ɧW#$"ϕwWǛo4"ǽ?#*|D 1Bz<(6 13|t³+EMZ㣀@ ⍱}0m+a>e6x.FڒBH;c!'a-u(~m)r"ƈB {@3=e6uz.N5>bƳ3W=ɵ= 2草V\`M!:'Wŕ!%alb:[`dOѾ87+N'N,:=3>C>[Do8왏(D2=ㅌ(5ڦL;"YRFU|Q qg-U'*_|4hQ4`ۼϥ0=`Ex1u?-1yĉ s>a4|W.~1b>㫳Hӧ% 9ط_;[~1X/ŻOAX~gEK":4ٱo{TQ^Ʉx m`K$`/0R(<5@/b%W&6ӮOo[b59gZ`Rb&\GM{ `d$`݄Q0|1$5Fh@ ) 7кL7.4n@1>i-^#_"H}zYh~Xj~pCn^0t` YfE/1av$1έ0ÿEBLaR[ ⮄O!T*#%AjAh?5qӶD:e7]P3ڎo~f&J#vmrE z+(|xٴ%H&Ohp 'Dg&1Xcg^R> OP q(hSʰ#Æao_/ތBHg܌=HS~%Y#㷘( V :=?OFɧܯ.7 ak9UBy.gH's&mCAe(*F0L@.r 7gĈnsI~KOajYGךB hZ"+ vB$sȌgDpoD[1*qe;!V'V,yܩ ICDqqw#װkȨ,klz9œG_MzǒEW  Dᣖc/!Xތ"bWE:sWė#\qeCT.m`gHoXӇDCiUûC>Zm.D gӄ,j#:-h*%l=p{ĮM"Bh#K'l7ՇmDA[k ZRć'=2[A%%E%v`̈́{a8E" t#HhfXH旓G,"≏b=p Pi$}ĈpǶ -†tvCSU ǯ~ :N #2_g h1&#El,T RRd%Po2wY'mؚ%Lَ=56r)p_f2_+-h^1Ӈ>=vJ [2z[XS쎔ff"@-7[r(EKs%׾$w,O`b"bd~30S]s^yF,?淯TeA#E=£OKX:~}32b}!C᎖v`3 ~Cyd{('JAt?#܁@%/ThqeA*1=M>ZFW{NR+&ƌylyrӢCmm`O53Xƞ83eI‚.)aώ@P-lD9TX-g%ݦf5~"h?/ZP7/I;,x9׎{MxP U]쥴-EX0_&Jgvuy埊k8#\h=ehp>ϐ[=4^b9ZzD!\ˡ}^=߷7q{EgOo:o¥xJ&*hhͫ@mA7q |9<#L#j7Aۭb-\ J/'wL_A@1@&SoBh%pZ جX-h}E€_IO8L 'b 1䞭,,Z^[;'1:(?| .g2l'd,_ICɠar/Ҿhi$f(D_cەlßF_=0gU=whX`PPnv1 !Vl;V ih;ڿXE JO8xJ?l?` iVK!_k Xp쉽CB6F|&⎐6⯫dOHsb4fSk "bQG &el@[݅I/M5(Ec/n^^ aP+1bJ Z>ϒ(Q 4BB;o(S ۇ- jK<#!ຩqw2~}IL*n`cdl1,M W-$k'L`A؝.pe>nAo.|_D G oʾ{}E6gFf!1j ~Ņdwl epSc[ЀPnEM7B&$gSB̀4b;A?Jmۘͽl#gMl<),7 ٛ־:&_GKkPI7[{ׁQ4'T GDZW^$k/kx&uh maa˵|!ͷ@!BKJyi *?_!`8@_5HDƅ_{pt*>w'dtzSy=|ڋ%Мpr(>6cT?pbKpz=j^_,M m$,y`4}mun4 @㴱$*qu1p MoG~BH!hW{ab\Z06o׍Qgsx[_#5QO'Gt~͘zq1va]#,e,1?2!4`(VQ,[8td6%sr h1xul?w]Me:|SM-?幩xXKhGeFKI n~ >ًҙ&=,&q~,0bV0AAp&h }"MLpde߿^2ܪx?AR=yDѮRr%XCmļ`\6ͷܻ 8&g{9`6|7b 댟AOr dҝ\n8߅B)_A+hhoo24ap?YvXS1YL^O9Vno5:$nc`YF]/4bApZ"ۺn1RxY (K30E IȞV҈H.ԧ}>n/Cu{˕RT7${{pF$SkJ,7~HA~k Kzd7I,ДU??C|S`.T;iJ+ g{Ss+5}68JRC(;(t1Ħr{wigCSnv6[@YXq't$D"ӃG#|crV<~ i Ţ RP ;N=r z{Jmة!OpXN@;2vPn2#Xf|_t~Nꂺ %SOᙸa\("]6Vݲ[j3z   lmm@h`*XPpSׯXڕ3ÐD~, rx.Smހ|hPwsӏ#8S1;`oYjd ~FK?) Г c{E<(5Qެ]oVFޞ,#K&afH6-9Yl͙c.DP睑` ctSN-J9C![U͑ix]<ϼ,NvKSYU Gi = *`(1~<zE%|[Evsx=F0d&īF!%Ts[^C @2a rޚPˀ #{/GZ C:%@Vs3q[b*4gEwTK@9g]DA+J6u` r]*%Ν Nb}2j!ף0dixvkќT7uO4Z7~֣4 "0}^nC؟U{oG2@LXwOڻ/WW-E(ךSt2Fh?ط<흳8l%{U| p"JH|΅^fc)H REQ#~DhWp>v:t 4?n R_NnnI!BDt嚱5,oL ~ Goh!:>7qbU;{=WFqz>%bN֍=ٳ6ܱ&_dx ϼ BŎ0LjyTi*"<pY5]G7auГ(_e}cgf2w YYj,ql0\:y4znɍN S {\`,'-/cTQU ӈQ#?`IjNleۋ9\ "C_5uvďTL*.^ā*39g͌ PA!hD(aZGurW_br_vh3[wzŲ7pl,2W #h[bG:eEE \g2G2$g)O=km=udG2י<CeSXǵƗQo0}죒Cu?+xVJ *keԋA/=:J-Yej\ \l R+2m;aP]QX Ve"'ݳNѺFH+ #:E L7*&yd`:~餯'DU $pG??HJ5dWAS|^>ARb-@mQig`pΆUI:4+}QZ}90%T{Ѹw9HmԜ7nQ'Rrs D"r\x}Ϛ:pveFK$i&V^c.F~WF4+XQsN(z9UM'u_wu U1daG=>̃qF5dH,oCb*3;Ek.Y2lbũ6ʹQsn?l?6[@:{3Lģ#:E%(D>6,! j$j-K1mrT#Q?{=Y _JZ}ݬP;kQ?(be6sѳQ{8C'WZ4-$u3x3hL+*TIT*: k0 eHHZ1` =@3x}s+?WyVv *V̝ZUFpJihBءϒ|YRuKg (|Kq8iR ʾGOrO)#2gh໺F|!m%?ZKR: WgOOߗ?J}-N딌|xe *H?`Rz* H߾N`{sUgd/bߺkpi&f-8#=rA$8(BNt_ayNS**@G_L7D а92O@%2:S?+y:*>-cdjW8 A#޾(O}3~d1^sܻo=)zec%Cd "@뤹x3vS|Oqi9ΠsIA)hJ3REI7-CB]Xj OeŃDq^kF/jcc=Dq?[~㴓~-wfi 0)Q2RC5J>.,B[-~2U؆JqH nth$2pQA2껏j2L.PJ5.d¥,᪌r%01Ϻ P8Ӛ$w$^CI(p!Μ>!U!#YZ_'S֑>4KmO?b'Jʴ3YٟHA[S߰:y&%kGn9OQc'zo{'(eb9́?xu#zӲ=MH"Z]DB}|T)[ʶqfIj:KU)OZ+>9"!%>bE _8ٵ( ɷ%}Ი:.&˨tǪA ]>!5<0qjӈjz]GC]BK)3 U# %B'/@ +I'v $ qKJO8u. 1P,#*p+H-e.yRaeg:$a`hNןXd#N䖣}X9F(Cws떗*%lZ#zaL_sk'|\57CbGZ6LafF$e~UIy'SS~ *`,ƬIxReC@Nثb@ƭLpׯw#AnX<%_"cv#>g(?.yk8q0R`mJGΤ-4ʗ-U*l$kI-+>oNA!in}dbb4@ /;I"SdEh B8I p G} 8{%e*Up5dMt$/li)R$a gdj`2WqT)*YT+qmHrARVR|*-p1w32>INPZdQUpɢ>N6 GUo,㗋.@#XeDVuLtcd;ԅN_HL*Æ0x+@Pѫ_ ]%6|%" E!bw2~#8uI0<#Ņ FPR%'.4EUʈF.z2Ǝ_jCbcE:ĭv| ]HIK \#I|%f)o݂+nX{O 7259N= ,/UF~AֽIؔ73#hWת B5}t,i1ňݞa'⽐8)Zj8L$%UzjI4|)dHd("MA䂽2X?dAP ŗ_K^W:-czzMsb 4EEvW=/5d@Eb%{6`5JUʪk]ӑf*Z,n _'2Cʮe;+@2 ßu!rɋc0;IJ[W LKKAM^ZZY_f3!M/TIU +v7̹ \S&*g*(ff6Cb_"/Y9euŝOtT]C@t%68X6O.,Nɉ3Hx@8K"L)J6``]!<\d; TVj\A7CY3 j 2˜lnqrɽ n2aTBG>40.ii4FFp-*E.Ra*q5}a\nI[e:i:R$i6R?tӤӪ<wgV$HY\ $7v'i#$L43>P\::^ 8ۮ?Bu+{EgA.3@'K^MTwH7eBd/{Bc6{jRW|[? FF3WT;\d9bJP+gI3e+{} K8LsY*:.uGA W+6/@\Zw`XSW i=wR)r`:+JYUŒ\{^v^;_EFuմ%QF Qzv?ZBE8R/]?*ӈ j+[J뾔zՉ *PHcRP$[6jee"2N ` 4$Mf6)SyWK%X Zra7΀m@Z͚BrPm!OBҫt 91Zͦ'Iig*KSǭhӇ3i(= NBd^_KIcQ s,:b68b"*AJũBK`t~H: n _.΄x]ڭ3!E^yktX`f;51۳ȠD&YY^HOhPܦ+t'`3fM<¸ ^[%BK'EèjUR1x1!M"c\]776zQU0 3Ww qN,BC>oxU%Nt+%"ݕ )!} 2.Z7Cp Gmu &SJJ%؀2͢'3;kK\pw0vXrw%2R7uŊy+\Y_N v,r [ȑ+G%MLI84Ŏ'bFX pJi|)`v{T9-Z$V8b1R% HDYp甘nE[WO 6ENĂVXv"aY?c^;)гDs2;o0.\ʭ_kd)ဠ914B |N !]"{NmlyigqLb@DKe<]mmbw}H=_p?Pãx>]'+F\qgBr-'2I8XG[;br qWb;%E̿IMsmR$aޓNk37nKVR˦ h;bN[˜]H֑TLjQYd)3\yFu _{#ˡVYxW|>KB&Q' LP/ZKhF/[DK8k^ҐAB90q4l$B{Bqa<")f6eD"90yw'ZPA6Catz3,[Z\4wBQ׺>;5" j:(Ajcף˰yCD[2K'(\J5jRgy?$8B#眾bUf'WQO_`E؂^]2oh;cOEf\%bc ֗ U)PVY!$$c6O-m{!/+VrggGhO^ֆz QuTrF:aH/6O QƇ>>a/';j@ 8!w/tS3š{{ս 0Tǭ+/vUS}lg:(HH8d9mG]5?CSwcs1[ϿYɒ|]815y]F"P^~^z B%!ؚZQuH /Q >BŶLXLXȗ>dVg!0Gl1&2V%MFd )> cQ51F3L'֤C&~1\!HOoyEoZ*=7+IqN֔ ϝC~D,گ1o 2&\8,F`??WO]Bm_@*h9<:oo`)?3jdHPuSVRqpF=,~4&wF!|0!fB-\~ AVB.O1PbP(1`>蹏ˈV7v)9Xx+; h[W}& Fg9_`]fm=F⩴>vz.wAs|Bߖ_.)ʱQ<_\g)˚>hLˁm[7RPkeC ҝ\2Zy,! ӘD\*ZemU3EYX48g+/j㬘A#y?2wNo(;0[+7bA?*8QC` Y"j]X>2֠{9`WN~%CVX:TYkk}-K:y}˃t]bb5XyW^p$+ɐן.=,XՇvHM,PA0Y 8.l?ԗD-V=e+Z<9ήJs%6Cq+,g%O>(|=!L 8tR^ R8e9N(3B_2`(DW  .)r!wF {}/^MJZU#w-[P4D+҃I$Tl0-j(b?<@HDyC.GʈwIJ22=o(BA}SӨd3$RD̖=k3kSTSMalpt{k[pOrmYe%RfYuDaʢIQ^z(8 )8SO32pG>p=+M;ۢ83Ҵ'agվsfi3EK, Mk_gn>Eb{7bL_aNX'Vuq]iQp>9Xr~HSZgh|+&Nls׭>DҧK/\!P PuK#2kj Xq]/2GEiG hJJ16ݹQTı] rI$ݓ K,T^Q.D3v+zxKn791,ɊǬ H[:QiZZxH8Qwzqzqjc;8O"e K ~\$(7VIj(N!6#RVz1IK]S^gq19U۱;GJ[OWHZZ* pBQFeE}e(hۙ @Td.QF[c;({O5bA,!K=;F* ( Z!Ψ0Mtض $}cla]Q Kc$$S$bߺDBkqA+x$62/]#y^\H^}P@xێ*=I]OObԪI"!:zG %0BnL3Jv]@Nf^C XRSOsUDK4b>w@Q/ xg[OcJr}+['a=ثz _q&XNi|qzOv7vq([^jH_SVyb#PNj$qg*.9ҳ9:ĭT ,L 1lx8QoC/ f&κRMt# 2*$:i]?v-c #YBgF:Q岃;nQ{8FzdɹӁ uTgp DWCmCe+c׀EC3@ķAMAʡ/U٨ @}NvE7a:3$=/\zYVU8Lm69(9(A8ZLQqbr,Auh;j<eI . ")I@4P`*Jᅸ@?h KF姕imv2JC-b-ʗ1# wDD(B}JUjIR:)^U7yWPDnEāی5̈́m]{r؊V^24J4*bzE<3( 'U8MwȚ=Ȱx?EtmKqdXj؇<YI5%b - 7a hD4U v@7鎿7R 73N*9SHCQJT%ڇ쌙M(+cߙK:%U.SAKwr's%7qM(> vqvb {F=fI)yC1GR{fWZ mq%[AǑr:r/MY4g0 5T м3"4Yۉ8L92E98&2iDG6bj= Jʜ`h=5[”*J|pMBOfΒ kj'bh+2{O' p$(L*~?ٝg<.#iVmAJ]ܺz_bKLEi|TG w.Ž8SM8x1-Ejv4o%ADәx˾Se몾Bl1P/"Xʹ- `6H`1-(AF /ɒg.s cՏ"|Sg0T OVg(t8GEQ-eO8I*5oc|V믚ݙ*xNQ0N'HiVDڌ<=BmTºފwjD-LeaH$M*qDsI'z5ܥZ18_[jm=6fq_VQ`W"e1s [y@Bk8h'NUb²U~Ķ]jhיŨa0BIrn7{y8]8Qλ.h.R[I4pG*mf$ j,ߴ3u-EZkɝMK nh:(˔qyÝ"q"^VOZy KھCʱr9Ge_2@fb>.yhfP?nVNg &x9 e[~n_9CT>P@]sAk̙,Rh8P[:LXx?j<6VWz3/4܅UIC]z kȶ_1x3Vf3rߐ梥Bxϣp:)rӻrĉa (Em5I0I.Pq.'H[W\+\yCl.o.("ʪZ%l3K΢ f$ w<oG lj2n+n(5vY1&THυv:c]ilWW 9Gy8pZ]V>dQ,Z>^h#͔P"(B\`Il;tMqa ɏUb$$"͏uy SNM {KէJjmfI.}3oz׎9SVi58!N@E4`8$x֛d`U_F~9aOhB$EMXZ:+~QRR6hJ%>0)bl ;BH/֌Yd, [E[k`+.'2nG\#&$ sxtr ɁH Q7Ł(=i^:U|Sq Fd 2C\tu "!>VC#HEf+-zp %w:%%SuH'd E qޤ?ROc w=ł(fPHD8Q?$-Z04';8,9 t qc2zIyvt"Վ0rtKl]qLJZ==:ہv >g '_(ZN;R> M.UTlS3}?F>x>S\v)3Q|&PY9=G;r]jj l,ht/\uƔ%B XqY< .R,9:n"? Ӈ,> L(ʦ_gAڹ􉦀 ^r$ICki0 Z'g-WT]EhکߤR-OHM@5x~􄶧1g͈NC402';ȷ j/ݝo"MHj)vD12_*$*Y]SHvl/P>oc5P*l=%@DK e Fye)cA'kW V c VߥjYrP8}] U<$;8,4>y/ ƭB=MCvBqnld o񐐀]a* 㿏<ahO.`:˹txo;uW2Z}*VTG?oް4 ({]w(2,_Ł)⽿lŖDc@ɂB $f8(:ՑӿUND]@_ܑôYl4m"Z"HC?^cOx#&c]F t gԾ43NKhuʔXhZ Qey(b۩,1;z <)h,.81LJ/#ZA|f,jswBlQ}uez7~Vܺ VV QoLNyid M:aoI狱56͂&N,r$‡":Q15y}wqAj`lѰ<5ދɆD|f&Qg.˛L66fǕ3B r'Rq"a2hn67Rb0 kD+2ޮD,z.!+4#2ثazۢ~/{,m-rzEa+9;t>3SHqj׻%:N6,Do LdkOLPlkӧҦGd/'N :1 2v^`c B:ǿ*~0q5xGa%6'dbSzd]O}|2vV~s;Ye_E˓K^ERl)Ro]hů;7 كrhi?+hQ~~ueg|вXG*3e9rb^uWbw DNhY @:yff޼ND-=$;6y~4v#' ([ BaowE+gxnJreKǛoUs*?#{#3lTF)_[tks@:m׹WC@:R!7r,¶59pqRK nyϧ⃎9$*Y;u@m}ܬ[,H|5ƼZzdJy %sDݕj4I8o3mUG *CmF qrGx%x'ك]L; 7̾B|81+; Xzr 3!b$a7Ӈ dzl=VBD O#?{x3N y ar ,#w*2qdl %A]IǩvEǏ9#BCjH*r\`2@F?0w1ܷdJ#n(3#fndNjC}(<窥x;$(U!S2(¨[V6CHip"I fE+xDF8VdK;@^byĊ8g$ @dN˃LNh t"b+|ł,Xps]᱾Hs9_"X^UҁNFGay3n!X &hzTOfۿKc G e93!nFip3c/`T>Y% 7 3dƽ%_~Y:sͧ7y>0SG౪hTL.&08ooU>MI {° -IK)NB0EIpFmKfȌW@"0GV).#澜eYB7W! 1ZHs!.nqi))²^5M@ࣽmf_`ŴvjYJsً*I{88m^;t* ^3-L%"_L&`9loWM#MՁ8"G>0QaG}KXS`[ gݓɵLJ{kSQrL #&%U܆2A_`,Yٷ~SE?B@2avE8- uesC]}CdR}[BlmX8ǩ'(ΩBWZYH٧\bڗ( i k|$+hzY0R+h( u))Wm'fb&!4Y!f/oFRTU'UDSjz%hq?R?Xo :Ҩ*i[bZuE#HjP6Gދ)o[}+ӄn$}?".=VI/B8$R8+/ԤFH;@1pgߜ3Vi5QowE$EܖȸyM͵yW+f*Θya[TKUo~nG"bᛏ>cWD!`䍊d2|ؤI.By\*pdF]R:e0Ҙ~d4 -,𥸷wZ(wƧ|{ZLl՟${qi/E{q@ڶJ"1P5{W6Wv Ffb:VKpV⇒I7}蛏R<4tFq: |[#0ꊸ]#Q9g#йJG+tWzUث{~u+?2$~w)eUKR}L] K\EUJ ԂTUBeЭ4eDʰ5Z d_W3P_v|UC|:mjEן.Q^@HQkg~ L$1O4`'ָҗk7߃?#%ֲ%$i@x۶uWm=,}[OnY_LWApJ/`/vEU\AF2~ /K}K86ޙC_Cdu;.]'NDpJйd ޫcjb'ePlqZRǩND ]|{mW(T4_to+Ub c3%8Ig;â1T?xɤL:8r" 'N(7w,Hr\^Y c8":㐻| qh{X@m<"<6Ypʐ VJ\Y~]K!̟LI󣰣ЉSFM?w5"W8[p)"B}ڞV&;u&F#cs;+j;g*JTC=MdѮP@+#5OחxPkHxb_8VR#!M)ff6`|5:EO+cd&l4Fˣ(- "-Lv̢%&[ժR);qNǽ}Ǚ©{gn sUw5JtAn'HOm2tr_.+jVGN+3WD_ FŸ(kxeĐ 9P-}׭εz/G6O8!nR)z+V5v/!;jvtSZ[fwKdO+Yss^lya,q %u lWrc7.9yFbҌU':B^jʝ[VlJxUq@jkjS4@Qg$BD8UY8B(hmOm0d{$xbg_kp[6lIIL窔lznqG{99Z/[X LzFذkD5}8)3co -xq? rue8ycen ~?\Aw|6,,o^zhK/(,,E)=W"1sQaRb?R {BI| ?OQ8E[9g C-/52wtT o}g`D~f@SMɨWtOKG'IԔPԴe9ғgXƉtFtNNɚrÕwfÄ#p3ti_߳CXw1x-,.!L_yST6Wrw%B)ZD_^͚ORCI{h=9']-"_pz(%'ϭ ΙE] .nUnu+!%yV1N8ֶ(TC!9GcVP4TDޞq#P_ʥL fAtMnAc(_QG@,*Hq9KUj0+ڑ:X 2/Q.x><6{5x64ҩSu38jdJWВƐcl.77?o fɇʭ,,ѪBE@ҭC:kRέ H`{QV.); ?#.a^ˆ V{ptpO&]44B"rR`v3}0Qg-KehjK@PcHݥq?2gI~ls[ P…? =E0nڶؠQ3o&/W&ّI{ߓS濷1 ޟr&C|5w^j~6]"iE 9| $jM`:/K\>yCDh^ix;4f䄤GƬ[y),VAK 02?\1#:D G9QϾJ1qԌ"d^߳ o XV~c;X1ͭxKV=$zK컎Lg]Cmu\$~Dby%]0*]QR,P~'mgQ66x%Q&A3u7+maqy*6ܐ!/؏'?84r:_LE9Mm{ƾWwyիRUZfXb4 W+BfW$. 㘬G!HN%y> iuJiui܇@G$#8q"Urj򦃪Ao{R*^3%"NĒ 1 jƓ/s8 % 5e t]G8Վk NI Lꆌ-q[sN -vH<;T5_܆Fnde:QSk*:cicS) MTs)wuO适'Y< e}sD\ҙ]xluisiRAwn3^$XDߑ-\Z{U7pNzA#pit~>}P邑BA?~05A 3?ӀV>olZ(8sZa^C*!GWUu;:;p5IYCl+O ̌!,`$r,#ZBqtv*n #Ÿv+g]BFEwX֟q#yӑ|Bdzsh2n4JW-wREΓx6+1$GfJBR =!_QhlˑIBui9 rܲlKvz.@6n'>LF)H;hsNG#$qd*,F _šV o7\UEq(q5RN S$,F T 'p(F_~6;6BPgJ\G  03iιpY=%$V&,~lNfŁoh65fݫ$@`ߒLzQ|% mŤ4ҕ$ۄN]}'܁N(<,~zj|/>"CyTB\@ e,Ba*`%#nN4"+KTLΥYItJ ͿEՒQMTeiVJT<115.Ztb]d%Zg⟁°Ih oc&^VeaMB/==hC@<-Uy䩁jY ]SÙ8f ^ޜlcfg$D%RQ.W&k sAWk0c1fuȄk'MĮ\%+ [h5!+Q\fOKOr3n%9N\S2Ցw;W#7Ϊ􊸥vdIUYFZD}("nT2&sl4;.Ya]}q T7BK 6+9@ZHd<Qƒx%0;7J)r4}F}"eSSFeI%sۙ^0頞L#(t=#'9[a ]9m~Aܓ7;N!9TPI N>҉VrfK;pJ0gje-ApA*m^E=e[{2@dvYj<8$u @h$k;_dnGB%ʬ"io+eU!, 3lN\ $dv3hҚy&?NtH#|3g5br&D=؝)D[45yl8s sqk˴^dҞNnQO/Na.taɚGCO~RaJ ه]Sm'wZ `Nۧ:2N*L" ȣ箚|B4.}iCAF} 31uI/1vo2u8ׁcn ;9HOsИT"rȇl]J:4N=7G|kG<ϵSlz JbbqTXg J*p $b,i?X5. Q:,4SX~gD!{]<*eUɨtJ9yGYIJ2LG(}I9<0rV~$GH\NP!SF*)\_"6881a@& İ*3p7ʑR:GNQ:ȅM\O`u"4Ν]V B-x%,6i]I3u ފP8%EϚRìVYCp#3RK!?w>`xA%:h4i\›I94NKiez3oy7f/I=I.t_I IY޿Y>a}铉Z9P mD Q @rWKӾX]} H2d'xA'lz)^rW+/ c8 ;HO1^Q0Y' MS YZ @*8։Q}z@ԡɨ2VFfm!)Mb㢐 uO3̔`]#v0lqHZOqD2{|wGƱ۾3P,Gs:VF(:|`@s|a}qAܺSHdx"}; K8pyiz?`jC.Xݥ6o VUY9ȴdFkh87yAeNzDAwD'F FX&|HٮfrGmᶟ8~ i2Q9'LHO9}_ĭ2*C-j~C*8G%6"#`b:ŧ2!Ggysd,qj%$5@+Ii[Cbi#$!q˾l:)N~SGdC+ ͷT}t9&D#IDqixtKZu216K "5ZuK :p^$=JlX$qK~d>R)Fڷ ^f"]]8mI谐; '\d!-,HƉMHe3ڕʫ&ꖟ82v_^j }ֵlpصض`y{.A+IJJ]*E|SM?Xi?A vwI=0wCL+sXlܛ5@')G>-[q9a]r(xx\P҈k72`&tLIoQp(_Ez~W=|IHIv%اzb>AvJdx˾8nם'"5ĀRLc+j6ULsSDņ"V?lC>_F}ӝwNI#gƣΎS]E_":ļ\ (3Z>Od3"mvET?̀|?+ %r ~ F˨b. U=_)ve.6t@Ă?#W2$bgm\szs&$`ӧ2?`**Si#[᭣6ÖDiHk:JGϘ. gh^Ҵ_6рQvz5Ȗ}N%M⚟@™{;@0bl7M9:](F ӾVڏ2N`$N6tJH]lJAMJ' 58˩q+U?%diOIߕy"تP9D%̛c +)6qP+ BΏO0t>e)([طz#% #P:&U/N NZ!m>v_ݣcn˰eԂQh O,#Z=T}T37ުRt  YNRkGE΀5Lu+6Y:13F"ĿY+ʘv޵z+kBa( "*VSd2h'ɇh6s!Ȍ ,]Z!"l6#j# 9 8~X`@]~8!uMUc㫸S"s(uw;\uQ=)X5iJr' D]1kLj|Gv(6Vm&9:y4f{׉-#tlϠTM]ɑl)u,Y(+wZɖ(޴K: WEa:b|A99ЫcE6b'Y_;e+Z"0뽟wj84'9&lMF#gE;Gg9Ζ<=3wp\30pd}NL8A& ,N앶}$t_Y8["݁)yWKǹzSMpjBOn`b d]XwAq8gAF.Lĥ=0;~O\Oukd!gmL?Zibq+ "8pre$QSKgUsD_y[):"h>R+ s&^Δ(~*v ' ϱ.) ZIQ\1nul+xm z#ߪ[t_ έ0 ʅ]{03mGg:dJ}Cϲ%^riq=N&"9KA}KԷͦ:ځo^ ^j#aYЩm&԰"od24}-PHXlagO0mcQ LKnj£PVnl'O&ʷ:j<4X=X]P44%9Aɫ0ϔȫf?PӔ..wѵF$UtR^fB*E"\7GyW=2#M&27r?65K[@ ;~#Nh^' EH[gmn#c.wx޷r~CM1"uGL:7s^{_BAa|T=N̥j(A ЦHs+4d)]O䫕Y ֶٞD $")+,91->!4 āc~ SXzfj|OQB0aݶOtExz~UϬK=#x'P[p`qGS-p? 099 h[,h: zy/t*ZN>}j9;+08uH-we *D"Ym2F:pƙ {St/i`PI:F(#KUb,~ӭ@ 0qyШ HORwyzydmU[/.vbUxe%2U"i:Jv m'j; Je^WcJ}ZVOͳ*~*BS'A$&r+o`D0듵o"m['Y]w^T {=אa8m),5h?Bp+@{ykx9%]'tz?B,xH,a8dhv#Yrnzgp/LʗH XqxkW隖SӖ)+"C#>Pi$2B 4'i=;F b|s;|-( e/˓H:82>Gl0S4P uAfTcq![ǯzgENqwQ`X9TqQKYk[$%% ,ޜ't廒RŶTfDx|ӷD>33\^oWKyZhwJA i܁w3'6k_V_ әR1 KO8 SƟ&]w#q4ܡ\Ek]Hkb 췕,?dYDD@KN=_!Ou>A~ƾ]\Lt  #F( Ԁ k4 77Kfy;!!oc,5GJwe)RaƏ,f苛Wg*"83tUfJ_gnfUٕck[^ ͷ ƧV ^e>aDX.dfy9v[TDxwT=_̶a=}F{;Ōb{c S-(̐bD58m˥T8(2-T~;H/(R[5"BI\sSxaS_{cœ7 =s,1_+[5)@t:@,.@0/RUcx<04~Km`|Be?+ {9V9j""c#\Iܣ?8OWtՏHS+@3;}t~f ,fFO6i*S'# (H9B^?iX+x7m{uT4HOc&V󩱻w8t?Ǵe]3|~&ero;D%XeVŽ2tW+tk„V`y Hv t\WRSi=M%>YJ?vz ˫ЁNlZN,c+ϯBes"Z{WXGsBu"Y837$4vDnK } :HTidY(ߎ*S 6^mNkMv>mlhgzDzĶӔmA]2md!,ARDwbdjD)2Lz(eJKb j]*&ƒsssx'|_cGK'Y]w%8dZݦ{j&kZP9gU$m{~\y| cNYRc"zNT}Sp Q1GCOEQP.pO͛~%ytOu[Fl_ji~fR af%*vJE}OҰ"B*NpT\&Fn d"Ne^/0zY@].to*t9pJd4=Q7)3N3Fw:=r$@4"ҿ"+5~) Li:\Q+h9ڇMO oٛkh,ڌWWu^ۿ4~70N koNJU⇈B^QNgoq]+#30?0h++U+q( X,;A/z;~(.Q⸾wbחbCc μ Xswcq-3EQt]O"{vr Mr1)02l [weɛ";UNPutC1RE7Xiy:YLH΋㈒`rGpFŪ "tByCh;<ue>8K(v8(8V >?RBʭ(_Oҷ%: 5zʗ)-Z ?a Щ^|r({yέZˆO|ǮrїQqf)cN4I#5sGbr' d]~N ^ wZ5\&i]A1h6Y"UG$Ej.Gf8;#HБ -Y&Kx^kSzـS9Dj'T~jӁ_'ĺBBEIJOx? Z2tMsW;;}iMl:B33ĩk;Jnzx}%77Jvhͱ+@= Tg:YfK3TUS׸upUɘ]9p`` 8N"} Vϧ ܗH%f}F_`]ޏ3jڗ1Hk]R!ƢWFHJ[)0!GRو3sTz[-"tPoY#7^i,YHr[mQ*[t~-iZ吷؝TBlv#I0+,`BOez]mBF rbrAmzD5l`fy#v;Znr~`tg.&ބ _Q 1Jz]5)sJlC~.au{ip SVe(#%?`u}VKkVLMQ뀍7ˢ='qrE'ha9HLpeɳq;4-I!n̳:rq!A9 !LJ$O8wF5E-ϯ: U"''+|ge*k+waG:0^O-/w4Ufo[쉡4'W=56WpT;/ X)62&MY{V"j)J[F_~MZrgi&ɬ̓pR: Jkt9Vd^n>'ݷ-qD"amIxX Ds*_|\~NJwKZK:.7 ֮qb5i63+~G0~e;0tmVoūtL0 {I@lG0f I3<]}a?Bequ˪G:p=ow<s"BL~3Wv&mǝx o"-cV ;\K8#KM[`ʛ!U{KFr l ndp?Zj5f y#sgpf  0_gRtXVݧQJjwvVͭcIGYEA#ToQjm{ !E 8,HC~)7:@~Sҡ=E"Az v8gԲKw>ZgG L,O;\UНu:|,;!bUlȩE|~T(f!<+3, 9g2JyWR?wpJrunŒWu-'6f{ 3o)IYKh5:-*=)G ǐ3oύ5÷ ?^Ii Bmh;#jJT2`P۩H8$A&$f%. a~N?:jU4=@*N0`#ټVg+ؾ\~ \LKqN߃~ ns"G?Ԯ>JȊh~Cc_ cQ9q_M5;C$@l :kyqӌV<1W5k|Ŭ,tI *rȡ φqΤ%s{? /L`%Dcj1K+kj))?ҷb)m%$hDxJTvYlIVE$B @#^ZuǑ 'F-: qEod՘^x ͝3)lV0ىoí:o۶aժlu0gW UejAxjب/ *V6eG+qfe{fGjY'Z 9/#E:<9։ Z1艣tysb Ү#K{fq\d]~q^F'w7~!'hbx) 7pk4$81Ѿ?"k)@v2#ћȎq^ ԗ٣.񖉝\#F-Y~(,Hq( vLvZ%ŗ赧!ar4nE( az+ [GdVzC(jx5zL3Vqe1pU/R`C4ʺ2rpY57UWV?Jiq 0ZvD+8he- O%3YL\h/4ΑB;@|REQiq*LKrzEV,rDN'k_Ո}{)\D6ֈ4 [,߫ti=*V *@3DpͣO c)tVIKJƹjԊ(BIFp;9$w%㠻)J!]M˦3V? N|I+s&N*ML'򌑒q~XY^Wk>pU^#iU>}Faz ,QpɊ~,7n$Bxgcۤ_U@HR'\IvsFq;2izzNF82@xB۬ShgYY~)A9IZk|Eߣ 7dF=3 |e]Rɀ~s+k u3 ZQs_k<үt]}S. t&/93k|` ݜ'UQԩٳ042MӰ>Wd"?o'=2FDLot<>ff\Yon}ȕE8 qxj$0*tx$لvHd9U O9p1Jwy&QiFQ]]is${w˓1NNmymnܚ\02‚2`͒mTJߌ%0QNߑM6?eW=7}oȰbȏݎȒe@\Β@$.M_!ަEPjC[K x7`)oӒRlDʷZjވ/m7IOvt*E\7rkpHB9l0L11KSUfqU-R̊ f#I0aG\CY=.KM &U?h;ynހtя\w:$`/!8JiHLՂ et!fg,)ʝe_99o P Z1ç[k9%P͔R+&d8cPJyjN*j+äf8TQ6 2&YLW/.PH(qIK@! w2)mu nNR vYg%Es C8!y:i ! pY_ '><(!rԈ/r݊3SDk QY>)Bqa I  O3[Lp?NFY- /Bnx4Pa}+@f8;WxwUG,I3}(.YX|N'~𒨛tJhw4ے}fܷo!j~1m*b㓯!cE-Bwt#_";Y"~7*}2*L6պְ:NL|I hVH{O"g%IuB4zeA讫a'jT5^-t Fa# AXIRĭğ*+e֏<3ɒבW#7T_O! b/_$,rwۮg1Ay1ΑvM6Z+/ծ I?>o-ӟ<`u?r_'[z|'՗S2̯1fVc1vLO-#T}gd+G$BIɌ25A9@abR5 F*E/$doQ{)N4 OSMe~rɉ? G"H%40|v WVSC2?gGXQO>M`ħGP|x\ErP(}TU}˾Ӏ*KGq %7ApC^k uMa^ +~t'XKdo55xg'ӆ՟,b.W7ʈQa[i[[RaK6-4:[uT *D)yvu|k6_ЊMkk  ߵGM2Lb7{E #Xr%9G 9d6DB3ʈqLNZv!:}{f_qiji^aTӬH\8lwi EĽn@b&+gu/'ˍoZu4muNC45 0zs_i]ͮ#Z-NU05A9Rrx! _nοkq .W?ZN`АFf˞R1 ]p;QqHR$#Drzs'1b툹cLi5a;b')<{>?l| /8fJZW@ rr 3}B!珴b|)9FZxT%zv2881uԧ*agUp,Z^:us.tg3L7Oj*@lpc2J^) ;8-qp0ihƦT3t>3D>EWêo+#y}\eҹ'#HG2T. Q ᓒӖ4M NL|\4G@L-Tu>~31FԼgn& U`O,af+ޫS1Fp44W%+;OV,ml5aY([u0F00SS>D#p\?M&1~S,zڈ#qB*"sEoW CPuPy mVdX*&VJG^_ť񊊔VԂxxjFF1t7zigA*؈qO-V<=OVQѪ V:LML5zre|eibZ3t ʼ'*)V5 #E@4bEd荲U J0j7rHO.l쌝("ܝOm&>nR pvVtW1J m'YP,wz1V[4Qq ܢ?2QeeJ\5+HF3ؕB e2g O)!ZFM<̷vH*EfjF}f|dm=3(S?x˵+s6M@?PA0Y(jR>d~X֟hbfC׵+Q!̎(>)g!5X.󧁱VA4yL9 bѳkp6nGMRjNlPOb5Pɍ42zy5jlUt#y1֪ ,d&oݔ6`S UJQfߤ0CH LDxlԴ0(Eh+TpUO  ?8Κvd2>@Tk$"@uˬ07|taw%}Fr$&41@zWRS^< ޯL 14n|"1]NA^;G3lj)|'e?_x]~W;fqЖyl-DUc8D4?%=]$ڀYUFBE &p= 7wQ:"NB|Il_qG$Ħ-/SV y=fO :: $HHeHU IH_U̩ˉ8hHy5@;DgZ[+7`8nc VhsD\{2gqk~]{%NPt_}t35)}F @r1uҸ sG B)vR!;ϢxkJN|j/)3@RjXaF5`lm{ʢ/8cWfg r[+C}"[!D.@)\2GMh~eW{bc.C yo՗MnVNp! ae[t#^+%K tXY $G{=A{yPBl7dߙ1;A[X_DK TR.4L7עiA| Qtu7YYN4&9 6C(eyE~e5IāiI%Kl1Ce0Hle)'fOGxXxm8$Ƈ:'irʞ;aʌG1lZTbPc=Tu(9 byp8R(]<̑os4FvM9 q3U!cqoU r[B™ ć30tb68͜|^wB1jzT`ʠ`Bq.PQݻ㛥q|,)Ʊ_3OA&e} L|g~3[%2~z2KژSuZey߇Z}D->~U%+%$ V*dl'Dߥ$fBaiKe-S^t*eJ-~bfY[ɀ^IP_$u}N.idɴ݈q-*NlP%_@P֯,Bbm$%s_v)lȒ[ GǾraY Ps ~j]eBYƂSwBlz+^p` GF|PrBꫨv==?"X8WUh;48o,^;)B&ٜUӧؽJ鿬u6L>w X7[6$ 8\ -W)`zPkO pMU=Hdn RJ A|:;LB + Xh(zYE' `u,&L}#֕{E>𿅒Q3b1o`atk_mn 5oҬ% B2M4*yI6/>ߕDŘEU,KA=PZhJ i?\pؚmܨO{Ŀ~@QϘrMW$am_r##&494 ujAOm XUd]exxL?uR2GiRģq-?bAk^.~"L ;Q˄—q2TBknH/EF=9?da0490&vVHC:53U@ci8(g^c'l3LdZV!Hx~JiEO̦( Zo뽠FxwdD /qh1ͫ1̏B.Kp)] /24ZkeT_APp d٤2Q'XԨXvĢ*>wˆK]SWd+zcO:|=ey$ t ) ϟ^oeP ~pCد?4oSg͉H1yB%._AJp E[2*VN8Pq 34U>mܪS`9S}FOƖm^W1?m/yUGQ$&4)/,$t.nFJSt(0JztUDpP3R,>\AτQ'e=|~v,b`N26 j=ڧT+៎4aaBGӼbS@Y(lgl6TqZł8C1Mm5A>aAW~JG ieS`玳6jIT@iݿlVC %Äwu@  t  Ql?p)1KvvqV Gk*F4Av|u w@ 1XgY[Ip|`2 %r|8/Ųw*|,`KνJz?p;dOBuh.'j%F5)be8$c8bΙISK"vڛb3!'AǐT&E{zC") JRf>'? Cˆ/X华\eW"#JbRɬ ~&#'·`z"6`Tܖ·.\NvGLuo/էڋĚM|[KB@Lo_}[ )uC PYr`K^dPb5H ©>䬈0IJzr#dQ%҈@e\qh Bf2A%R@MLz֯ GoEq#.ve[w$ OA!f["57> N6>˪pp>70X(`WaOpc^ᶷLgd C'-~ 'jL?UƳ8yT!2cB0%OόWF ^~ijf(J_ƭevaink6aA <)6ב.aSҾjbxT'Q}OP&Wp[v 'f@Sdp&ΐϾM߼̛u+V1/vhL3 p 7BMc_ vJK%c'A70[cLŅ8+.IW ;Wn͹@|x ~y68^M:#cL⛡2[Y -XR'}3;ɩ:JJ0B!XaY2i$@cv\cqdd08ANf+_YiکǛ*vV_J7yJ_~iZ%702RZد/ 66.N7fϭbB,l)QE-vRT/G+i fUUl-8&j_C^8S65ʥ ,"Z8f 89?!Gy-z+ y}Y`?x4U1*V?1d#!'?$R+S w|IY4 5qT[fZ"ޛJtUX&ԏ 7-tbN/)[3?%m_m5mW!h 557,+fвiT `u Ԉ)c_eՂH>iؒVl8eזb F@6-k=Ľrc5G7x 'T=V;ML֣5I_f3X!mUqMB70aW5ӓ/GOQjŕ6M6G1+*0 A:osT1c^ AejPEQv 2 JN(w}[j`[(Lg c!DHeU'Ё G FhUBlp :v3#[ld{1t/bs_Z(8cj8F"$/::qP]ߑs:4oʬ{@C* Fg`8=Ɉl+1c2@bGS<=8J\#|]z+RB.Tlli>Z/@{џ, j2~J% cnF!(!ۜX70T qF3xAֈ|7=jWf1HrZÄ/E Z/5<gϵ*_pOzK,ei|F|h |84M?uRW8pHӻzbʡA4qe ej v t$!m7>G%6Ύ2S>@J^KOJC8A48,D|ď)foIqA_W+ֽ/@2eo^4!M 84ALB= YG~MҘ90\8DBY_Y ¬DEY9M\˱ ٲ2 LL ) Q$64P1V8dԏX:Xt `Q)01*E;幓,ED0KY3_ }L"QFC|O# cUE@~U1j Bk0QXbX1x)B@H":\ j=ɒ#SMCSAe8^+ և9d,GW!  D *f;2]{Ų 8xFLe(/! `Zzr|6{UՄyMءFV*⠵4B;Qu3ZiI03CHb89 7 g e2a'#J]PG4!8$_~Vpb@k:dʅ1-AT*^Gt r@g˞Fϭu'r*0V qygjZ7D 3a [>PLgk32E?׫G9_:S3bP} 5;X |r2i QU0!qSbɌ#QEVR:Q`ޟDkpLkAo:dv30lr KH4)|jWxd4oy}\D킅F *dJ BL9C2;ʗ /cld/}lEH umA3k~pC_,h)tܑ 'qlZ9>V_P #N *t$jy}Wt0t'G>Y[㐢44]-X']j)~Qm#qNe =F"FV͔݀R1դ]^mV?ӈK^3?&wo4×2"eJg4 9u=iaZŞW˿\=G=SK]I2Yc.u^8S(ʨ5\OuL9AXCKu㺐 E,$t7]dqRJi!%!9YPHOVu(-yR5Yxzc\AJ+#re ]9Y4j+MؑWY:Q𬡔hBB97oe4*h -@Vhydִ+3椂l\з߼2O-]ΔkCU (G} =v9 ,#3qߩ0`1zOqOIёEL|? ge>w,r(**Ccrp^1ͫ{(bPT=)#s8*bʿ25iz WPx{}U@AUx%_!Ø-P53̚RpiV}| ͠F]{tZ3-hQ&X[Ms`kL08/~-44kf^!8>W <綠ET3~' !Z+o|C ?eZP*őkl~X( ˗97V`0j9kp.1)!$„e"(7 \ MS7#@ qI}l ,poy^i8438[Ih>[2.O:)=wjX[Z%ΐL'McͰjדN#ѝ ߫˦M&'uQMGz}s \FjJaKhDa΂69 B:0غ.YBP%8nޥi'C!9XU Lwu{` Z V~J em+L_&#/m0+wHh BB N! 2LX(МJꁥlGaԳUYbXхx4gBTY[7t%W Nfͺ2BJ!7E. xI+ԯ&P[Q%56W1h+1 !I15|[1߄2oe">l^Wg B\xsN>:ϰHq5~,{E >А5ZB؂7ɷ>6)h_ d]G&:GX_|)sQ W:y /݇P&wL{wv 8~!!mPp﷣ɭA=129QKpؼAUL 6qY!*<_׾ס=7-]׈:W1R29%*`sɛfQғ`1uIsl VPLo\:VN)}޿Wf\` %6 h}Z 1^SذGf{>]i:f`|-j& Fۊwc d֙nҪw!O4Q,ڔ!zL@f6A6-1 7u=@d =2|Ʒa4=yTkk*w| 8AXrAP0VL-˒ M|iUaCyMBř)H <5j;`~b)Z;_=WS 3v9ǙCkͨNZNFMoi0N`u/ëqYhI7!Qf?82o!̏d8VU qgLr֢7b0b@F|~,|$0Ėqi$WX[ӧSt ٳ#8Ln[+:j&(ġ:Tzg %8V6v79,p(f.m7<k y#as|e gtuKɞrFdei8TT\@aB8Q+()#f e|:ګ|]jIh풑P%^/[-3pʗޜ?Z/*b[IUSk`$":Z$ "~  e$TǔZ-5mP%$OQiж@Q`ݨ9FVW-p˷g2^YUO kQdF]{a:-)TW#&~GyVEQ]HbXB 5V*KyaD+?i`P҈Y҈"}&<4Qͯ$_!Mt{r|<!1 3BLyݮmur#mTVf9jbOVzJɏtD%,4%ԞOKX- Rj% @kW'azAZC&5zd%)߈rfh0L#cPLK57/54bi]hj\`{$8i2aZľGs/9[|WU3dUAUm q8LWpLεB0$뽬ۺcSɹ2ˈ]|z-_n[o8*N|IM~-$& AHEz_i0%u ߎ(hMtC9뭯'Tjz惖c!tL>k=ߒ&3Ύt)|zxsW+ïLɠv'T%; B~>ǀI9H>fMM09TЌA&d.*WGr>J!ZhXO\RWjݨGtƉ:2cݐ|(|L}Zy%yop=&+u D렎<1/MZi!-Ne%4'=eD;_w.G=h4]ḂX2o\YÒw|ܚF"f|jp ?NHt1GfVjUKDx1u+3PҐ&]A _yEO8p'tX7(@:!#+fEiR01U¿^0H?Œns[2r4pM.MY 'aJX`?6T\)0#ۆP3⫐ɄƮB;iCo\-vֈ'4SXA1jJ, ާ'Rjsak.B8w1 ver-Iӝq3o] R4o9 AؙrftwrvR&~j(0z95U+z0hW6kqHWˍk1?z8Acy '!HٞBSոFBEcR M]4uU"e$ַL^dAB/%s|@F*'W'+=2jrw4-v)~t7@mBRCySVkB]3"U( U9^0Bf#UVͻ:3Ǘ>SlIu)?J}J3hnj:08PTg9i84?F N/<7 7f,KNk&ܞ\q~.h<8>,Ujqp"<8.̧^=_Gj$^v"l (23z+U6 w{iqU/~ROhCE0Z*K36&N ]Csr}=МI&~e&aF_Sa80F՗"(6^@Xf rh44~kgDWgܺ"P瓮Q\C ^C1::*]~ aP;2V“8 wLSvh{cWl)AߦnL$L?u.~L~5 '1Ӭ+] EM\f댯Zr/2/8 #R?M-|Jġ@ wxrWؒaE(l%XXC}Q%֝}/Vf]3LT<=B 4#1j*'ύ:z\]]Q5{ag<>l#=C']8N'4'?ߞ\7ų (ƨ=;+pϿ?X~9Gh;+D{4q/8@p;$F!]d%]z)bV؃#YW8E+xV Afb>ͽPS,N2uǶ-և{4FwuסH7?juiʬ''ˣ B6XT$8EP+MA/|4-?&k×йxhȬ F8M&l神<*iFX}c^}+ 03+U-i&?CSAqd|N:Jq:K_҈͇4GjSnL |\B_KL#ba_ =w +f=fNVL3CZEPrKeu B!rȹfa/Kí4kdv%p8C5bCqm1ҿqdQd\Oӷ ~԰i}) 102#1yjU̚P1\5d%Ե)Z}ʹGv^֚N0GEZe2w@[vU ,߫3}tad>#սkժ\ V[6rOxຬf8b,U $l״G-?jv/~p6 'Skw1H0ls*m$<'8Qƛ Am壟oַ[ԡԯNJaZTsUvѠtyE&Q#;G *izT"Mp$APxjBF?c}x-KP&a V5WI1rݓF\5, ,w fNVn"^ҡ'^ -ҀUʸB^M >E$pL|4 7CاUԓZQd}\Gد'>/+rfH ݀\Z",Έf'mkؚ i*c!Ww+Ueگژ !-BKCG!h'7_NwU@]7D/z>`SCձ4kIl&D^ F01ȳ˒:w[K^"_F=m檫9s(ȏ~W7jJN!83' &#trB- A6ZMdqW{R8Tu.)Zu' وQ//jlI22Zlɤ>ez@46ơ/$D]4}Ud}ˀEdIS)Zxѫ+cО0'269Ih ~y)Ӿ(f {*%a̹6'I6asMDNBin84FԴ?Z*0XjLWU+z#UŕD,YKv\m$eB)DV'fi (HZN#*Wp d-xjh tX;~Tǿ930`C,#ĈEV~UC9q&܁N1C抮a)>~ xvtƂC{Θ\&L$) @.az/.A 짚I+%h/ڒuVZ{#u'D0[GW~%VWse`:3=PXOیDL0,Sg(\1A_407t,X1uVחnRNJ/^άX_xt ? {V/#řzg &m-xP,hA r`mdkeb£W$eH*K]`FmәqNvgAtPvfeD35ӡ #&YˆEORYZ܃`5C`M A{`p_i/4faf` $!;eԘw{ 8  3d_gj1Gxk+]2#(@ 46#W0BVA\u@ 3-W&^=S3\?u.ׅ14gj@|<+͌cs}Q0ш71t:wװ~8(%pY3^ (2ofjt$V(qV6eL(W*Y{} ˾KgV*V2bZķ+`<0rq]01<P+ˈ] $16 ԂǠYs i)Hhh;LgQj@+iڐZe-(u¤c;O$,*ZZA'׿7JwTV2g i_@`L*N2g&fYmZglty* >30a"xmߍq ЌxW&9^6=rRImf:C&glӥf@4N7l<8Z)'6͠<6p0N ڂfc8:( r+Vn8qVXmqiѵZa_u~(yrIv/}8Ƕ"++®A-H6# \ tqla/`ЃɔM AxE*|DZ< 2ݥLansii300t H'$Ljfx"n֜Ewl>ǡBN(R<鰡8.w72â6Ute-"$h6ث:r{+W)bG#)+> Pr`hR7'K(/=&`*'[ar9ڲ`{ SW[cV'w6BWtcջ|kH j-٧,z̨8pfgqw깕y܃;ʱdd 5G*#H01iFN3?UbNy>@* d1>\>sOZi> l$.Yg`hٮR쁎l,wi+f}*D)p1Y=46=mO΍X pp*2%WeǔMr]$T(?'iX}{|5G |E`0YPS>d15 f<25Bqx#N7/#Hn]&UE3 p(Wl .̾aWz-e| hi`޹G2xq*B i8+"e^RLqE\;2f`S.dVKΖy8a!&Fygz}u|>׿2Q⁽5}įVב0;ߤVִq؜ zf󪕣ɵ82a2;`0n ]qp̜ڦAI5 ?ul5J#_r uXf4 8gt3 MɍY2͹hjk]ClYQvr%f&[>RQ{F7&LsfWOfuZNT3ix]7 XV-bÜhʮɣ8 4f'XLŹb@iRA8232J^*9QŹi56{9tceԓlEIXs6uW8#A%Zui2Ճ^O;/9k*#h1J_,1eOwth/} o1eY-AgqTq'nYôr}^І20(bM 5H8Y#q+|}Gy ,^ w |kΌd7 5h(H"#AV>z ̗U})k,TY01ҴƤS&XC*f!޿}!TfU P g*͡aOU%wQi?zb6oV5TH~ CIBr4H~2wJ<%=[d75̝ꩡCM|uΆ{u mjB2VFM@0qJ<!_נ',yv`ymqky<> XZ$^Z͏j"^XBQ2 S$c:2WC.G=A4hd|XEt")Z n [ X-_#* D0=X}3rYF!Ps# aHǏ,6\*[+p/\AwgTjuYk_e,p afSp8\Tez+ m8 '9]+ BI?W r|Q/Tp 5£a~7@~ٯTSJq3*A!uOͿ_'en0nI<8C&/ *2ŋg^ߡ= )y/Y~<"WRr=eWKYWg'7j bʒbNևqSL?tPr(0dTV M"U?p`l`%_ eJpF޲8کQy/3 [S$3:Xw>{&7fW٧*=Y jX1:>mk9*v3: M|#,osR`c0YRldi9 ^ _8jU@WGs20HBV)k֟ [3`Ô룴++F.^V~1#,$cgv)"|K Po4edH&m\>"P @`BFbhn@~.¬|:q8>)3NI0l&H>?s+oAas+[f13@ҷPYicsCeYӨ4(yOy9H9xSgy4Qx㱕HYֈЇ?z~Rtn"ԖP6&ޚUHt )Iq0[+/7qPT-tf9p) CS2p\yq  uۡtv&ٕRn4np}a? !\cr91S7D׿)_q6ųR@U7 ^qP|QWe#ݼB/ ;G5.e=euk $7ʿ9H~fΪr\|^*&9Uj&Rŏ=(Rl䚨zŨ@PǼ]&Ix S18>7ZX*7pb)MPG'1jdBLq]7Rz$$'-',⃫" .(K;)QfLe)0Cٮ_>d.7j~v:J}Sܴ$*ZGrv)Nyqf>(Ab2w=O-_d؏C82 :55[W&>9`uȄ$'t:\x,(W|u2` 80aɾ|C0rGڴs&0r"*VyF8Y$y%3:eQ(Aȡ$D6bcX)%1?ӻ>MDeW[|qՎ_P!A''$I BIh}+>$*J M|HJN&8|Ax)d=]{'L:>}RS'i_b&AtH4'2MU`'t`#j' pVn^;Ƿmn0Buz CZ_K.wMUGI4l+QK)=d7y~*OԺ\Zq%~}u0 "\%qJZ[J|K斊gW%Xzi=0f =8蘁S\pkq%ZuE)OqR"uw+ ԷE͵,9ۊ#0Na1+}b HǍb I%2͙|eVJK]EQ~mjJ/gh=D,2ĬxkWt^g&3&˭#u>[cad4ݎF pWۘyEP aYHjfU]0LM =7<#rև>{4<j3 Ipf o _O9cc L Mgh19&A^ Pkx鐠 Xrb%U*`v5KPVJƥeW !jV3H2踮y+PΑ.MP "@C 'iW̙dJ ɶjs곗CThOnȕ55N^YC:NWIX^gԛ%%e9!Ua"ΘӜ>-! ="DCIKeCPV2# Yޢ)@KbX`\u s=r @;uuH}bC})4mFjUB?`LL`AOrer2bd<eqf WZS̷!wɃ0VDaxHO3+sK9!uf.eaڳ_&=[CQ޳Fҽ]]Fr|ma itzfVd\oá7B39~7wbW뒻_^+ī^Q7B <8sj1' +N1S_2y3CR𿴕$ХpC|9]>@99TǞI \x%ݖ+S)!R@Bې_ꩀ0X#}dGDiz߸2/h2Sr+:2l` :l^\|ȫx5Lpż_."< e^\VR<G58?\iU\~ eSP]lMt"B3`d$IV9~.~&>XѴ6 fp~2 9dM*|ZJ*L]OԼ%/:J\w A#Q0${_} m_*/±=% ϕ)|A= P`Yw:C.&!p_3L*?#B88lIDrã"e3 Õdհtg'NF[|a3jGoݭ,m zb4%]a?|z3sFĴj\R,V| + Nwa湀b]@uZdHVR*ƃwedGoNИMJFE4՞I8@o}Ԁ PdHU&OG7z\c" =\WOmx!v>/*M~i Ӄ@{8y ޒd 1c㫅 GbFqVRz>&HL_"Ght ~tc~5(( DtOUשׁPv{RVKuVx)!#N$MJgN=%`P/jy8>e'η~ā$ޒ2"ouv 1jVUfvb}NhWKt0b{ r~?\s'b7@¿*PM hĆ\h>qT -mXAFGrS ^sT~6Rvjj8tI[25SUy%1[+z5zҪQVC=;WS J2񞥘K@(X V#>Pp8+jiUt/ޚziטxp~g畀Ϫ$!aZ6Db"1 [*EAX6d2;%=E:uYCҴ pKc\Tf@f* T8 V\J_q0FqCqMz]0 *j$E`ZN&&6s й)7~%B* ); 11$ NTDt3f_d:2 ެJ=%5)#)NMaKĿC^-T zI1uLĿɢU"hߏj82LSu—`v\P:Z߳Ɣ8$ b)5tԘ&>jIӁ`<n0IBwĕZEu+z -Sq}!K1´&\:!PTubjm\&vr="tF9WI_Z%pCg'I4(^_ 8-M=O03Ӵ 8.![h[r2,v դ:u֬@Z.UGt$QaDTfU!5}_с!ddQG:Ƒe(=y9C UBN q5}~9"# lwmե x#p[&nv5~\3Qc^"3VN:J1 ->@qyH_# %_80lf%-을z•B-}kqqJ˥DU/SͼzJL:Z6l/,31`sz<`{j QWb| 3ٓ9>o *ӗ_#zU*\-_ݿ+al<BdW,㣷khֹ25%q@Vbr|5I53.D5=z9"n'RruÑIoNO{Η3҇ ʱ Tl )6l֝N^' $ =<޺2<+>@5%XR$W%&;R$CԙͺM0Lz*Y%_W\@!eOaGwyTU}Q>$FȌ>4 H\Mq2! "u(@˜?>@g`UFV/|wa?hj@0YL-eU/ Yr>0 ȷ^M/44E&_O.jh$"h|k4=1)f͖+n\j+#@9®;9 ]SiUJ]wSrmIOyY8JaFEo|&{˭dR;@ɼx1|8N<]Mǣ /Z{ҊYz nkJ6}<L@,3 _*f™qb)ʙN7zM\\3 Ecݗ,_^}b[Jd4>b(Y3WbW_@9̪2cAA\0 $#Gj̗cͪk6Qt;ٮEx5[WN O B5:A3}!U(]^?Sb/a[ڏ&4~R2C?x)گvBJՠ,a"U}j|2Valul z98C4Wg(_u_O<,Uq326$Z-\7.UFz̊+w]V!e|_s!@*,Vg0~%nBKP}n NVUz:k_ZeQOM:f0#vd Y+(+K6[lICB! 14iB~'-5ٳA"XZaL}K'ƇHf R ϕI^nTKht N>5Px42\VIfb9bQ@jբ7~vZI!yYBɂ!ivE#h̄ʛn:W/+ޜ(GU଺ZkAdunb{ 6: |ü»I|LW{_z bI*NxeL)M KdW`=ҿH7[X!3id\=q[r J|Hsū$s#aVpdtu@7Až#e f8~|/1AIY??`IWFe)#Ls_-^@oX;_gB*wP6}ˀZk*d9Ћ6s U]Fjݯ$CwSPItJGPe'0 0oU\]wR+L_MG*tVNp|޼?œGʨ%ɼz~0UCR4['(т=X$g>p"&D?/M^KZ0tV5%MG GU :s)8zx4yRAgđz |DUn̿Zdyk;X sU8ԱDp:=_\FH ĭj]g#o ,-~[R1:WP-na/!2s2eN7 ЫOhenK"v;xGh#( g8VڪRF_KP,Owi%2B dF4J<쎧 &M&ksֳԌ# ;GKzC *8ZAHL 5#QpDzV@*z+B#%T[Qf,*B"'+0UWr-gG@w ~ճF|i:i ^)#Xm]%qPԲ_d6Lseaݑ漚S<e 2GZ0q+Qo>ɂ»xWOG&[Sa}Q5%'`{̺_e&((ZAĥ7G%9(^D ܳ.?kcEm^/z 8J2.p%1$e1zV)io>zidF]HI}j lUWҴ}]^.DY Xv b*[dh\mv.b%m#~^8n XƧP`(ګe8jxfcZk|?v,<ܲ 8Ffmr̹3~Z M:rP4Pf uCT c!eO-[%[d [9eǢn+o]hLtAkr? !N"e%qFm>- L@Y0ZUB"!0j%azI1;yr蔝dJntN14V>$i &@St`uB`{.S {]֣@Τm&bM_K{/jm+BqtCT8hRY!1au硓%TqIA[(au&<O6亻j15.Wzy9$dR@nI.bمZiY3Umﴱyrqa83s˩@)g0*.2paEBAֳQS'?_MC]" @F+j|*1>dB$ 2Lp)2nP@i,A:d;vI2DE^Ac:$d$낇ΪM%@4 hM:VO\5`3/ dRET#^er^8 ~6AMx]]/QQ>'aݪBsW#]҃+}//ͫv\&`II.zb9Qah qRKGpQgPIp$zedA[Cל*JY,${*+oK꒗\_5nd՗2zs ~b9瑸хf@;dIV5է s*[]7GȌ𧞯{ā?lGt3N!+a}'$c,gԣՌ0y UxDa`S&Y UnخJ%̿%9 hЅP#yCxAil^c][ |"w;{ MS&W2?hwQͭ[a8.ɦN"$rdy+.fU7 GqyNGd:zzcx~/̘S7 ̡[x_a 9nV`͓/ITU 2ԢCpVRnM;'G)ben0*o2(.!)[p}냅UzCS2{D0L980k[\8ч$Ӫ-uw"כZqDǤgd|K2 3<6_A(DcF.F޳fU>iYjꒋ\L>37EiavlbhX3&Dƅ"mk`.&A$`j`ȸ~6冁d=_G NUr%2B!NQsBrԭ3Z [E$[fI^.eͬ?& J\hif)FzM7T8 LtzIJRə;%9 *YiYB4ԝ% OAE&(dwRG " ic㽚;Jn|7]E**XlKnB7ncG]L}3ʘ":c 䎯EPIiSJ5l  D#%cHçO1:hi'Aeypd_iR$R*n@X-w'#K5 [!do}y <0Ӄ^0Rr;eUZ! #VKq-}n7x&(NAAc>AaCDj 8+ŗ@Z!O bmu;>Q㫁9Z'x*=t_A=&I'YY{rIAzK'ԋ80_t_tWZ|,>L.9:uH`To|s L |)jjkIfG[?'$-50aX/0vqs79 Rf&]1aRd|<ʍ.yJԍt.Ua cYOdS=k$z"NuYO> >~@e&2+u?r4_`o~~rKzrՎ\%65K1ם2,9*NyFl X;iDUk0(' ieBUG0TWuپ\m*ĎOwn>/pL|H4PuX@p{.4RfN⸚nԔx!Z\Wnm @痉tkI UV'*Ns$Nb@Q)g Tʹo/;ſGG3Žo;uUQCGPQ5X^7^B=KM @o!Ыb%SOPi;{ZlCe7V}@ZFuC@ĝ*6m?92^l zRI )yIu o&sVSk`_"<2 #ag"?o(@2d)@2bxn=~|s.tyg^;.!R &UmKFtĬ+:Nrh2S{P OCVׁH4މN6.HF2JAAНBpwݐ׎O`Ѵq]Jy$&F!i&!I ^Z¾kD?7st~% em2p@U>К?RCq\bS,GMꁼ}Ru{(S_=fj! RU ƭHhzk¼:/ [ oN:־r Gn/25S"A 17#NV2 8Q|;h`0|搼 BTvD̬^AP@vWap˶IOܪ=l>q!UUAm?&*7vk2޸okfxߩ;%bYOx ʿ,):ůE-_x n"^qx9Br594`ns1O g[J~WVd{Ƥ%Iz4PCNcK\{#Eu29sσjK<K2S&e<>d:.)&v,[j!=$G`'; ?R" q)`ѓ (\z{e{j V]Mxo_%*tb}bq!KeiW YmVb1^b?p5Dl; m1K ӕNq, y/LbXqz UJqiCЬ04S Ǫ>J27 @(Bk_]YEu{vIc◃4\ >t2+tǾ\7!=)>rkcod^ͧ1(+GHhՅ|ZL` OxXNkH_J^٦&mUcޙ(iKz;XK /e` ;v(R_y罜'/;ԘvO WyUU`r'UA(/,K y@sU4.Sl_gljY7sȋ<1kI Ζ/X!9/8eO7`XT ,4ߋxtE&._5c|*}|? "C212Y_<C0T|5 s?2ed/S;>K38j+ 5/){_޿u7Tϫُ1|΄ Ɓ7u%:oZa)Q t%yiJfr(n9K2Ր-A_WЎ:,jÂ{$& ᖾ@+pIOzK=(ULN2ߟ \'쑌츒ƇWbƉ26tǤO tBj##JǙ<:tߏP&cې%%L[9 FXaRwlj.Vc^FZ0vzᝇ=ay8e5+ ="z\ydovϩӎ.Cݷ^/`jc9]cW)cI h8a| ]AƱJ,i CeTUbj'=t!Br CckZk`]ʁӒ[NiFEg@FEVQ@O3+7]Rrvʼ!˩c2\|2|M c~nlEyr&zrSʻJo\&VX2 e a}00@7x dv xJB97vy]Bqx||ʩsqP-_J2X1w[OBU1`3>eIe D1e.իCA &/]@ y7eGRgK'AseQ@ \TrTG5~׿ysٓh|RߔNdU[iVL=d.:3LOI`G~{A%݇2"$aOA=Wxۙ$+c$d'm7R>0c.BtWx+|qH`-LZxOҧJzGSUJ}x^H"xPjF/s;+5l>GiBRiZ*#W9/<[O } *7Qu_YN3/Y[&LdY0( CA ƞU\^(A\]WGƬ@iSsCC7+%H! V`.5`$(ϯXn[&ٿZȎ/KkwkiӘd|yOv#,؃}H)8Y*ɋf#bt;yAp$1P<='!-Lh6#0@}K(ܵLvnv);G̐6u]LYMMgdo6{Ys؋7i-h6jU1%bT x͙X ґƧ- y>>^$bB"rbJ.Q;e.+3%LdSWa1܌ͤLcEO`ͬ{ћ_ b<*;'=ZfIҧ3}4J dh8x|TGo0ň//I؜,}0F`4ݲO43";fsrkM0SX7쮤:.5Z[:WKBR j̥jƚ>rbRRfF̭1;v̤< ,I)tqIH7U+f1:p'z9_qd9 αDZDФ9l5, !wO%D'W Cú_+5 9bɬ1"8dϹ!h%e|;KorW;]8"~'ےtƒemԵB9i!.%2x ;IznmԏYDacΚbIˌDƱs!6Fz4#`g_10RZ6Q1D\DREcQd0C). KFSRH=};d#"~V-M)]`iė hЁ0ٯfbig:HF րPSfJr"p*p\c=ʍ*@G } -2OH=(Xk98,IaiFSa&vĈvhB|xJc 5 fWƬUFٴOGa`H"u<)_ad 5qÎIʉxfTsEm'TV{"mO*{ 2 q8Q3(:6K~i3ۢM*N _AٖrS4r }Q@R9(6~ޢNh+dzqZ0‡ϑӆ:ܮ,˯} M$Yl%-udVʦB=!}uTԝ`agl_n{?LnRu 3gboO۠~Wʢ`SIj{z|<`xedtp3I1lgދtf_Ing+?'s̷-ۮI"FԎbj<NꃻDf1Qje*3CM4׺|c/؄c'>jeE\>=Wȹi ztΙL z.ߧoNgE(:0S#eQOz0V٨gwsxEîn.kfs&)OoN0*j,@Y6xJ@%ʨ=D8uCuE~> kd{ؚHD̈́B)_'J4C'J0yvRp#M C$&?6f'n@m%L2UroWlJ^")W|5kGL\ CS|!b%OZ%4J<-G 8eٵЮSoW/Pyq Ihfخd,R#/^4Bp4|}C=7ti )jW,PRDsoQj<5m(셹_T!\#蕿=RĬGK+J.k@;@l7NmYͯL䖛-+yu4Ӏ+,m_,xa V{|ȼ=v=7 突"ӕ qGfsPFYIVr8ZVO%l/X1[ͷ۔N@%>y%:]f# #ix~zy uMO/=H1k{hG5T׾PKjk ({yR.+@}+,J$o+:$T`@':WDb b_ȫ៥q+ V6\If[/Q:V4#?ȍ'm)!yٷg!18l N4<ưF8 yȻS (աn|C!W2Eq-KÑY0`&jahŌ6T*wp*#m&: J TqT#v3x| <V`䙿/5yKe/UgB|Ÿ́1FEs\7 5b#S{U",|RKP%g2-7,qX/QLBE+*6e/G4t,.Ӛ^NX:GV[Nv?ܮ2HI$^V fgftߥd<ȯ LE rc{4)zKB2b%Żnk70P0$93>Bٻ&zlLk9 ߤjpWhSXMD(h" 5 Zv*6hQD7UriUx!\HMȠ}<6t[qO 1Ƹl]f^Q.rD|Κ AiL`D59\3S.%+|zF%đ ,b+K6\THjc8,&i-EFK؞D)r]&5Fa%ku\<&xx&ghd}ubJaWz]Wl+njg2Bm3q0d d[IX8r1Ե.0 $__W %ټ>`!( Kdp}|;0xF߻7Z_q.^ƅ^4uǷtJѨZBH€FS8Or0cFr\UD'8^2FAxY&$e2>J]Y`(>GUz OŽnoAz58M-%h˻>X5-"DFi ~ȿ?$`v֟ۇ7J # bגY#;% +3(oO=_^EeU~r3Sl%5oExGDa_b(3\C0]Ej 9[(1k7?4cצhyc=̭t"⭭'_- Ψ&TA@azrqL{'E">peq4b&FEј 4ās{p(3AptCB ,ƓB~%#=pal_ёS;9cz3[F擝݌h2`%nd ,r&{?hrH\{?dhUrOqB'\urqhf"%zN3IźQwmX]=oҧ$d}2F~eq uS*D̟;4 #C(vQaoV*0p$iqZiNR,;p)&d+0z7Owbz?Šv LSh{|w I(}c$C$dedؾ9. -LqS7~WIPjz3T"c;{}.#?Ǘi/$z!iS-!A".t|a!U,jp-eJ~O7v2efծ85KĄYUGAlSwa{֣j%:lo5̾ L-&p8v9ޠb-WO6l{\r?^Cr@2lŮ1,\ 4!b*ȦqAtV*a ਉVJ%pT"w5Iܞ)ѻIdB1[<%1Rh<7W83[Tamk$fg.C,zR%H6l=F$N1;3p"81'e~Bξ2G |kñC8(PgJ9o&C%wR -kP+sӝ\B0l#Js*X$TpN2,ÌdPaD氛V`Մ~P`4D"~Mz7ϧGX \ -_IX4* b_b_B[Ul UT )@35¤*$}M0x 2Zֽ~qZ'zׅkr"d~)^6*z]9+7Nh_vr& ;̅DR¿|sT#'̀'0#.Go4uAmS)GrǨx v&itrjfP $t82փN_RnD~F;vA$pQ{6<ͯ,^yTaUNIrɗo;G'gńErr-0+ٺZxI Hflj;S/5A*lWaQ'͛!!PBV+5 !XOz]ILDQ9jdP3BQ Q4$ȿvJ^4=ŴF@7 TfWM{+jc+`߶T״h?P`jAb3!~.>> Gdc!K+5[q ԝl5'9,7s^ҏVQs7QNdtiU#!Vf$qH iVBλ}E-+LDpWa^YOtXY^0q!ǢI$ ŨA6eԿ!|A0TuOTZɼ+[ߙ e:o5=<xD{J ZrܺPݦhf2{.çA#&yxֆ<OB8dM P5p=vjRI(ʩo*sl 4@f&ǚJ0l؂ߥ$UC"g(:t/3{8$@ZFYNB[7k[Q'X @̵RD~*X(p^eKa^=ڕd:#f\ y̦ +A*?k¾Z|HVS ~50*QO KsUYHנBr쬮 =w8!;+9xbZgDD&vm5yJ­giU ?`޷6t K5Ȅ4r\9^I_yKjhq%to+X0&YVz{T%+2 j *n./HpT  p=,%$[7=FWh_]qa_#H~T&C]VTӄrNiR[ы h_̦TU6s]EVJm#z@odg0ZnyKmc% 1d ~VW^gH_l[$rVKŇX[1劉bjo9 {.5^-)^eѥ<8G@1ɛ:8ZT'!p`XKl@ó{!"@Qk+A|0{e_ r7U|9H-  Uf/c+&+D&_2ěC2Kol]TF|7IΌpEH 9ӣzjCR;hP4Զ- jo-n'D"GuVکOISwOoqP4aSչM`JVxTb3D vǓSLwNe-A;T+ze͋غ& SLKW]ǮXS0o8R~ZV&⩂X"&J!HJPt)Uv̸1nK:&XS%;1x}!BWGڨɚd}h?%bxU8>a+(Hӕm{9;p0Y]ʻ\"J6+'ՇM(ETb -H^|lD.ıUy/G|_x&6 >@e O8W}v4*6kYD͎2mԿ"'V2:3K&ÿ;*x"T'BWV]Wh<8;ᬷcJ`r'ӊ)LŘQy#*;^Kea>v<㏁w#DFtB"!`ى/ݺ@@P0/9 !LsƂM+ ZޗML¼߹O[Geyto:gF}{[a{򡙈8y.NnJoY bB5HbF>̪.5 38cJLh.;A.?,DCJgt:x'krL33.> P$M`ćc=u<dcgnCXNPA< *SA|L~31J}7cmn~ڗ>F7K#) 1ꊼ{kU= r_=fyOژ02'BU$'>K} RNyv№LQ\5q5&d9\f** ofvtpDO奰WQl>`APE;74J87jMna4t*Q'Ωۃv\?=ʊRqK 'Ρ,όx$9͙O<'VBr]/М69Ew7,yJ?O\>x{vyeiߤJo_"@:[o)^@L,*2*Sds`x(n3.E/cA's?gTe =9 $T\+҇퓙QOg`5lhE,SMM]Zd!\6X{n$whϤ[ֱ]gxߪ}ȢPfĴ`np6>(W"2 JYcbTʝ":+g'`oLSg+ءIᲗRې)&gP,Sx~vbG2{S6zpLZ %$7~7D#6%e84~'_B%p6R7Y(<M\Gf!}1mA"63k{(3wU k є;YaE?$qRoɥ?'40qz/M UQS1-nEr C0EWhS>SLi? `J5_FPOls[Jv_W> +0LܫZ)v<@_ "oF$o={{pY1ݾ:at }Zo ?:; ,lT5a~M ܉#[Ƙ>lXF)qQ `F$^3+ǧϷnml=⸜ Nq>K#r3MbƶԮ$'Ρ@I@*P vu(t$΍{00PSh0]Zj>IoblB |6>s'K0ں, ؙPzXq|7$SqӗO#dBBnJly/%:",}уT"l59xJ$ yFnb.4O|n{E qfr,Pޥ2 ѷcfC|>_fW>gt;_K)J$2 D/ne%Ԉ5sơBlڅ\HX7O&^P L=\)z!ino ~||+A8|h / {֘W?(~)Y/IX?~G'HQL6-4+%}vtAwI,IOC1WF8xG)^>)MN8?QQoOS q(6P>(5lx}_aNQ`0{( c.9@E*>uTҘ8I&\oD$ 2AyfI(k@Q>2!}35![h$;+՞Ϝz|xF\={o8 H3'9{ݨNR;%'QAzmӨ(L:41\f3>XbrF @8 >DHQY ] 5Qn3x2s0%7̀XE:U<\qh4B3P_[뭨c~? %kUfW:& Ju+<"UOB|wV/0ĠO4'eaqǖ2~} VyTrz<55 YÀ+xLr&(8.oFʣb`ybVBYC%ZD~hvyy"`9K)9T2 e)OhghtQ|bd+ꎷ4Ѧd=iʡ`4bD!)R|(sI+zD9 xdglT pyOnI4 -h@g0"JV&#K:Ck?sv 35Yhfjk3+Uהi&G'Y &M9B%AE/35Z p (öՃ(8~% ӇMR' ń֛(jV|$uCuvIdFcq,o$4~uި[*{1p[eRX7Z})t9Nk~^ i"~ěa=oMî "3+`r! WmHKF֒L#=0$eLnL4xǢ$ ,]ۊٲs1v~7XG#J-c'RbO)I;0tqzitxPڅyBKCG.9R#.NjكIN"}-尘KvNu-E$-/$@/P/wFJBfL| `#GI5Zu~p0Gyy8(?qi_\O>-uV٨["rz]3م%vd+8d<=0C_W'zE V)l|⛷[~6 wO- ߖi7 K'~giJ|[b52]ćeqo!Me<\0>=cD\ Z$8}]+$-vW g2_?OB?[z֙9lIX?)qR?OŅMяKE|CK:t s2  (`g JR+b"FwI-s#{(pҌm =VYZ3$~սd2P!gR6WdG<:2$/#8ӡR48LmQ:ZǗr#1WE=e . gqKKNJ☥3)!MN3%z Ƭb g-0qh?Pzk֏q޹fqҕbᏛ䔔^(3R\ZBL?[o#r2>eʒSSxhWnN h0xYWQLnm[AA@Qԧبm|MA̛Yme*L ]u¨=htaϟBp('GAz%\|0GTʮ$}04dsfw4 ?wkn#Z;꛷\—^& `]3ߟv+{&oc u֧TY Kwp>)=%,?P=X(1|pJ&Ӳ@kxj6U/\ oX=Jc_frtA7$$2YzT?V餅B9~ PE ʾ /dfLc ֚X"FiPן_ 6|d!M1Ädmx+ӗܹ"~NADkmHJ\!Ym/xI}3|O& 7_Hi'",+zi7Pk:P<:1*,/u6zqLVJa[i 8{2)L0i@$NM%P`푵E? ZJ>f 0*׽WuTPthHBn6 1 YڭiLE[&q$ia6"T\V!!KDFfqV*JTD$\?d}@>=rͳ|ϑD'|Mnp&+=wn#sFc'C[/@mZg*GO`b%`m >cd#Z~F{M4+ǽ+E]#@áMdNbp AaE+KyzSrVg~u8EmFnp]p`RIi}9Ľ623ڄ{"^ L/&| qa S'n sW1CqҾC{sW>e?ww߽JG0g*lH(>kt'i eP{}D֯"X1S|yJ\ȑB@d~tcWgT%䷀\s5l|d'=qL_Jg&G{jyD1B"q_B,ř+Y>naj Z#cnVFN Qh|:?S!ۉ]!7V\D"* >U?ooY,=XjuϠ`MCս # Pa )kYh^2OղOI׉:]/쉼!q>O e*fHeE$ ppz~7ˈVKeLwgD 9@=gO/Rt2b6c"$ܮ<"˜˜*r)oRszx'N,FH@U8ӓ,XXI~Y{>,w>L=/MMkLh19Z뫌 Ɖswݿ* VKWs~`HVܧ#XWmZ#yn)c˼+BJq ~8Ad_P^&fx28MK6f6D2B'Dc-pg)_2˥ia Aq >@ҋH>3t_ ̓NÙ34(] +fD7ưL9l na`L;׳)FK!+pVfj 2$g ?wI:4ɨ  sG՛be<+~`v9$V/ Ž OK{ݓ8!6数fb5ͩG0\?nܲmq {4_0=}7l=2S3 , bɎ  E843:#75)1tbL5 ~QSL&,yQK_$MM1r݀vֿb EVBT}7">-lV^}<F CAM^$–,!s/13S X_fGReǥk;s f\#xg;1Xw.b@HS4 Ȥ W9fI!S+7vpbJ܊ٿOtu{Lj9o sbnFI|8dW<=wzTLX#&B& #BNxDn""`m+5 "&?>>#"#N޼LDEG'BIaW6:x$'x=ẗ!c2`ȏ]lDK``33q[CS51 i0\ &I7{r6$BUGso( fl&sVZ/>9FL$H#_:. c^̜F ȧ7Jbd+H[Tk`}6rKD4L";W 9X"34v{Rk$ )']"s3>xSR>cf8eex cјPt;Yi PNxH{)!zNКՠO*<;Ȉ|A[U<\ TŒ7DR5& ׅ菋nyDp_Fq{[ "DG6[_dWﯢu, Euh*|u6 smGClId<-383{mQ`g.Ztʿ"vg\KuxꀕH+D ZqJXqb>;7}dύ21Wx&pBCJki_qKr ߹AUoj@ޘ\06|eS Z -Hb=tg 4;Da91EmIqG3_ES&{@ϋ(r x |x͍Wچ@"HpxUn9]"MR<֚L;T'ґ(i.N'4`p)1oGvf17B ^d Zy)!ڹ)΂\/H];-N$[/*v]n|<(ޠjupYxʼnI8L}&f 3CϲߵhQ d[ !SqPA 13d Z +#tF+^ckʁq8z%v(`MpQ5ba@?QxG%} kS{HHv+#(Dq_ϊcߧd9z$>w&;M 3xDq]Aǚ1o?d FtLjQU0| Ɲa)2_dI{?: "y38k pyWvʾC~c3L~L)%9_sUxZ3)Hx.1cpWd8g\!x)0ぢ4|arc#$ETU<i@eLbpm` F8GKXz9?0z\>Ii˖bC( Jr +1 ~1yo=!A|eo8%vu_}%iAD$g#P!BAځlHctq'ߗarw'k?.K #[10rtX{%FgVnz_K(_DS E1 02X$#eI} f=n+3lU#pۢe[C `xyO}K]dp=J=-1 >FDa&hǘ8SSbZHuiܿΝܤOMyPoe$-4no7BZuʑ@Ea>>=}Dd bY;cki|j}^TK3=Iĸ=&J|tRkm1yk\qߗ~`;F9oLwu#2g@j_f|uο-QZł|Lqxl=?7S{b*D.g V: aׁ UPAW!*&r kX̚5_-2'[ݡǐtkX٩Qp b%;}#e}DjkF(Y#{0K1"G"iuքO4kԦfH߈ƛ5m o hPUZmӠ7 1xL4 GɐSя 96w>ΣfPVא6c f˛2UV܅˸PX!x!aPŗe<ܳg* _VdWLĜ-P?v0cL&h{V`iҾNىjZD@Ta̠ &1?((`!\}k$aƮ<5V|޾ &<]@|~wsHK߼ϋ+e&& `}V e`:C~9^u&eH⨞VPBtOmas@ZedwQ 4#x S}̈1ap _ y+qj06D4<a&E}\~8 ߹w$hK*k٫@Yld9a]pKE"c {J""e;yO@ f `B:)ĴxC_4X{ZO E'y/Ħ3} y8U#dz)ټ$ê 3h(^=h$D96׏X9}Be9^x _rRۀ\H~pΊ/||~֫ Hp]:Qsl n蟧XvJS+ou3ࢵxދ_G߾a拾 {XZ.eN뮤gU tͭAϟͮoT ?[Ls yr d ,B ~!XYŕ*,Lg"U]noPTgr3.'k[E0ëQ-ً>5 (x!Ri8 ˵LA=Gyx#oJBO1q290003FAC}Pk6E>j|['{ؐڀR#\Zeř96[V_z8 'Zeas%̴߬]Gֲp'*`YiHXpʊ9Q3j8`"|i6 WvTqf58vYM9Ikf;u3Ks  "Hۿ7>/(;K8C3EcvIs׈EvWX19oGBazsO⥞J0C73B-FoK/W)QXkk IBT/y[˄~̺Yd4%QWgҨnak]?+$WT\ľ g^ Za ,`-K\+ `D"g]]Wr+FI}W%\mRЋc."ޤi$n|QVp\WR#2Ues9/˫4̵CvHjDe2px#`sV ^O We8vnF2KUEV ̸*$uzdQw{?磼;m*Y[cSY;q1/Yoħ#ٿu?gH-@ ŷMfk)Vb%WA)70zVQ2o~x# OX3OGyν@⁤;SAJf =s!Cb0]אݜS3b!׮gXf(.mQ~fgK&'>y`zj\]c 4/wZki^b(IƷWx̸t<邪t(,XAJüJ#]Ú{LsG4{khvIp+1{i#x_+qshr5.o@7Ai{;io7, H $٬H]3܃(w+g3T [{8,:⹝ג*uwX3~2WLhgG.[^qd3* ʝ1:t]&O {R#x]rKJh; i] Y_YwgF+lj5#{:~յؠ'z:߀H.߾cBp>`\io(JUPrv~? B 7]:X+pɻ ,AFq⬇,D?Bz#W&h|{rۓOl"̒iUqJE#ݑnYA JnȊe$Y[{=VyBgƌ{vR`xr9dyUݙcsL#˸k##oiad~ SI.#CMm=AZ`voҺw^v" 7lnOg%_=qWىh\bv|f5@v7-qC}a >x70! )% ozDeFyuymřhܖg Q]Kb2_{@G/l T]:_ F$t=5c9,2#~*1:Qcy(׊v#&"#%f"6{W^5ˇ=3&mM'xkM|3ڶ~*7G&vč-G~FN"lrܕV>MquS'רb_g\6V0_籯;11SB;D^S~*>_uOYqX5A䴴W vDRuw#Qbtz+;bEP gGHlŗR ٫n !oˀFr@#,?iu$ଞ*W&((vD`@K) 49 C@^ٕk~aa">bTrI Ȝ淮lĹ2{NhR<|=IQuH)ն]3yA;vҤ<{U ~_k|;>'=Oi믭 v_EjV93 f(ԈRw`"B pK7g!Ҕ nCpG ^Myki"3$G$u >-Q_ R6ɖ@g{:;csJǽ0]~9QbaB.J}U" ~貫;D$;ɫH=(7wY92wa 2kξ]T< D"'U[N&m*DW@Nj?E-W& lD2vHLHjqϏVq6C@<- 6ӡ_ah0T$^u@&KK sl {1 >*T'J3g1%lʦ_V85oAB E$GGVެxgnn &U6`4U }F:aΤ'&0RGTg_}}DXu I/Sħ%ƽn{?W\p]QYJ<Ug Ԃx,bįlv N$-qd2~߸ ԱAMh귎]3f:"6 3: p{RAR1IZxmg-aHߚiTүm"kQ l>{_BmeP$g5:C1-2cz}T>'<9f$= qw La1ʙ93rA==41Fis^dG)@`E6I~mQԬz]x 'Wqt'fI7vP=>&u}кU.昉 dJdw"*M0co7L3Dw&0uI*\"0̐E4뛵b{> xw2(QBg,3Sf->yVb< z?>KH$0Ԙu<;ڝCCu0Onw̺yɷaGӤ$ާl+(UG"nAeX5 brxb#Q zd~x;Xu=/?u@DDg w҆WYKئ_.Sj <8BoKԷ?q&_mL;͊26*G6ni?2%R-mŶ6蹡GH? /26 uYeo>oնqZJs^|i Ջ/>qZF#Iןө2KALbZ4~r .1` ^k  f6?~T ܅Z$GQ&uGSD 7dx0sԈ~6ð&>/\#!bON&]bxQbc=l0^7{=d"O3ƶ-FL$~fa~*a"rFx>I7 IGU(G(4%5^.#\?8#Hsb~ x#ܘ(_Ͳ'~4^IXX*bo+*[;0t ~#8]/k{f8,;ƽ1y@qD;hÆ{ /%>ضy 2O{RB'ug[I鯲;Έ]& 3eDKqBTPjr-f9P{5MN'XncG.,ɵ)9$-~mbWGNp #2_B-0{Q=wvsZj3/uQ^+w{rϏB@ X;fo{jf1H0Q(Kd]v0_!`ژ\"<\a4z Dl͡_enjzt 71,m؛8Ƒ7b~DXū4׶%2o>%W̦ G%^%{[Er QE ߡ3/+(Etk/(f/+mCw^0;%F/of2LEBr?*Dkt7==CW8[/!fEdCj!)2-*o|g꿽,=g|^fxqϿh[7^l{*}7}SD64?r`?з|d>jT$#sc~C;q'ܓ9͟͝kb@.)~RW7fsY|ˍY+yw|oe|` +-q y,̨vD:N&2icwP1.KL4cWx,_LfS} ȇ7_|~ecX/~:&8w\(ZBŦo'߻2\՜ G\6 [sWٺo[NBC}_;ZsS(@0+-8WD&GO)u}wsr b2+BZ/U*|Hy%pΨߑ)ׂK`S:880Ćf5];R׷9 &1]o'O֓ߛO%D1Æ/k2&Y؀/%pfZ@pL uބsi}mR;mAJa=L8r8w'QM%UQ3 D׶V&"Mz$B׼M~e :uħ92c[x^K[ wD/6s?2$ qBM$K = +[7"Y__bIy*Y=mA̰0Vw[rs`nMށ5 D?E@kAs`ryDm9Ib :3Yk&U'B2f;jBE×٩ As~٢_CMu*,lsމ.7umpW?ǸG+QĤc$]3us};7$i?3-md4KS:Qؤ_PD&F#)컧py7w \Csc);E&ٴo)VzU˜P)/m_DptՒyCy&1jH>E0ֻ%w}Uvr~^]fLlRII*qYf-Wsǡ_ְ,M*V望APe=dя;·aL{a h<ۨAޗhQ=bZ(qZ }n?{ɒ=Va%߉^]ECyh!NkM&jMs[Z؟XeHb)8}bP{i1B0c{.$2* r0idh(E@nNlF"~ < ‡-)EK@'H=Aߨ>4: vE3rH$ڛ{s`(;8^u"as㱩Ѳu}ߴ;M};}-Rj툴dcO+:c8VE䝄2 _ 'izԧ<cP3]%[w>Iۿ5/D;<:,@ t17cP _IY˿MZ3TXBE=[Zݲ̫o%׸;Fv]ZPc aa{2SKH8B$&€9W4́'&NP-莣[I+;Fb̫m-"w C|1SW_IyW9 쾜{z*tXΉR_B}GذWdvq% jUZsDLrudORY z u$*d~IL厖D126C}7;>ߟE#Wț3Sb" ֻE:h9XeOf{Ξn 2Ε"O2;UVnUf׻ۮXv[>"CL\@Xȸ|3^Y:b40ʍG7%猐pllndl.3.q&6k)M)ꝅRjdM;wt!2Mi[{] oٕT"6ۗzUBvd=z!*-Dra_e9O'vv+}lENCh "=(( LZy'fwjD$}ӏMD-]ԾNKZkTV>:;|kKb?j9ٿ?}SC[fv4L“llX,6W|ݓ[:Q7-7BGI'd& :V*` BioM=bDn{-&<Z.K+յmsV9X8T6qժ2])^;߄~w+cw^w`hC1ݳos#f#KUhfZM=}4q}>qڴn)@2d4D=Ȼ#/XإwMg%F{%Y;KËk#cD6QC|=~b#{,o673}/v'FyXlboV?+x&ۡ))b>2i=ZSV5&fΈ8~̿ :cČQΈG,?ܥ 9SUrߑocav߁ V`O=ҿdYM? ٲ{NU:GK{[`~4T5SsalWىcy QAw\2ѫɵ\,`>VS{(m0dLj{Fy.fp gCt}'>>#yOf&ς }0rvn> 6}{`g *XR̋ˢ]ëVڄ·)wj9[lDL&Quz ՏͲ{\-e7N%4 WـB\ ~at:NŲaUrê'O_4rd>Cq.jKmR=Ɲa84Qd^h ,=1wHָa-Z*'{v(G,۹,|f>fbxgӛdR^,׽YrK[kksۥa{:1TRVr 7h\~uP];Dq^7MYo!/&w{d*2Lw|UF2 Ǐ\ލ:9j%ʒm~Qd4.w=K|i\)Lכ*k1sۆEҜRq]6lI5DKM6aĦ[;q9snޝL@0<lY4s\Fg-9Z X'{P[< yRkg3U %9o{y _|ѯuC,("{$|c.m{;^]phc.8y$rc{H&xDϝlnTDNrĿDo]-#?DV7ڋ\ F9!8!%J8eGe@sj솭^=8bf/ ^u C;7S^5nNg60g/;l'rQ4ۉСHrRbR^V ;A[*XPg W͑W^U4UUnM6Ϟ7r;U$뼘eE]lKm Yc~,}(tM[Tw A[ƈIIߖd=wD-@ؘ7K 5f2K8=W¨5#*Hc\b&!+l(JGaAazQcx ~BXfD|P02LU؁ywP4deI_}st/uW o+S!}A9ߪ\DdH #U>s0nª][tYKqT!lg֋A(poϝU| "c;&wf,qw^٨ {v8Mθd|]uI48NYv2rxb'#C%bL \Ŕ{[RF6ku&D<_}Ku9irOά;&!Km6n&V@,'nj6ɯ{Gۤ2yCI^9v-,8@4(U6@uTvdvx[ފj\Z8/+U:2Rr,_˵OoWqƉWz.f@E|t90 dHN &PS2Suxi<>WZ97$WˆYAni䋥%xR^̋h^sm{|3G{P!Vd 0CkjGPU+wL2Qy+a;cun]~֎b587Xw38TW|,Ș8u݀eF;KBy}; GQ=c9f"q,=D=Ty b&k r}aȊWVQWj{wC7gg}5wWox0Oi? V8%B [+|وþ-i/lFx]s#7xܟK^v`pZ٠ } =آ+6%˜+XbteHJq=m,RVs7Lxb=Wcv<{a '.$D _-mM V4koB2R Y?jo> Dه8PK#FcWX㷤 i⛅wxJR*Ʀ Ȧ%[Q3 $pulG|r:xؘzv;D7PIϸKn0bZb s|n>"@P+Aq|wnƥUwa6 P)W\~OYkZ;@)@/|_$3Z7Yx3"Kp681 Ce4^]N j\C?IyǍ ieIKGǎG?_r!VEb'ȱufU ʂz;l3{T9_Ƴ Ys3zQ,O8Q .)b}`DP B+V#L2X b(`Uܱ(FW7YK̪hwr#m 0V4}+t߉աR!YAGos]J& ;vh/1͍<1kg1.y?.qqb[8̫ā<#d~J7D,O47=J\b│2E&BGoQms7-7@wkIcUSݒD1,|lo97Lr9yy^1ؾ4>~y ,EٶE%2CFc9lj~oZ H(cy`7!",Mf.*y-ٙfO;cɂIcu/lq8QhW?i, lY θFSMpD)+-wM2-Ʒ1c-q2Q wdUJ>DvO`2<돧<ʌywԩpX}r0U ]Xj)"ȚrhX@}3V<9؎v J 6%/[q;zK67|, LDu}wGaі3s?CG\Ai~f ԱOvaU`LUr{ ֞5o0&;|"WD\FNzgN YUb3]l, &nȶ NEx",LYYD&/ZOid=(IgF'qЕ fŽz'f+ɶbYxmUomPsK\JEWV*f&-)T&] $ZǮҜ:g'j b /cIb'&'sa6]16Jyd&KnMمOYve!_xzƿ ĎgqԃzZ 2T6 .3wY=,4u,:f weՊ]`X5#ZҜh_ YgY)ܾjrq䝖.[llۉuttz{2 Z&r4N0ԪjYzt)< [`=r4e^hD_P{ǻ;Ϛ8gz%_ γNjxBq|_ cqz+=8UϒIY| "Q(\ Lj˺@1x֍ZvԳ{pm2:; .h@l fh+Q8Qso۪j<:D-zc;@(o{v^ ^a౯I{}EV5u.-z`Q~c,( ]щicbnd8@`'9j2;K*?ҷOgEԵsWn᨞/G?uϝɲ2ȵ1274t)oqr-7E3F吖VgI;$*][0 We^7.7 :`m(i&TFTC?.| DF %]Hm묳 ]מ:U@#ZX2g~3vZm 4DA187^c=]TYhƸ&UPkC_- ϐ=@ 4L ^#X_tVpp R X1!R7) \@su_{PáTj:;*2PqA=c\D-[1n[D UY2"BQ;FtôPF4 z_:Ebg&Sj}9{u~"!R L?USݱ܄mAFwvmO< ճ8վUżW>UUX48`wE 6ؚh;1ͨyvCQR^,L[W==|ѕֿxoK-?>|]yMz5MN髴K5_Q6RLCx_-O/097=d]VT k9'=EuC, 'k0)3m}`'^ZWk}F^Tv~>U|SϣR ly׊>~ {0ǫf,56s'kQUDpYB3{Qc9+=_+]}ЭYaۯǬ90RW3O} mXDn1浻5WEIL:WU%vKd%uI*qqx*ȝ=t^]>Ko;ZwZ]j?MeX;TvOo1|ؿ)r\ӌ׶CѦb:wld3Dz~G?j-cjE>*C`~ ТWF޻9N&'3(`&>eOK$ߩ\1fyhR"Xo}Ӵ<3Y8zx,t#i>]H@^} 5X~G6PX4lpEOX9Vpn4V:˳D"6T=Gv>5}6|wUz>];.Pėhf^[N}K HbKo1z*;jzG0l7wr(^r.~G_6~mz V#r2H~C"z.[Q#u-T*C;iU_Ѱ@ą>0rh~Ƹ"Oi;♁_u/*<@RR>≵d .~pΰjjeAlJƆ+QNvY\SFySڹw 5kN*gfnGKņN(% H~[q&ί2Xj PU!zY_aru턎\z-z~|E/=R-=U}8hi.6B7<Q:zoUr`^2\bvmEZhS=rpwLw˃clD=8/vݎBje|{;緟ԠD,P<7=U#OTE>#IŮfhKəO.|kv(#6ܑz*(zO| p]B7קw$r\їz\l7~(-6"G<>KNl代=:d'D+6#nOKCG_R۲s?? ޥ^9KFeʽ>bg%r4^WZZ+5BK}hJ͞p#}%=6I]$R%@f΂J /i?Hfdڒ vy"0'S%"l|f  Sҧ"GQk';w-oap)顷`O% )nNu\xsnȰ M- '}L=+!l0 ׯ˨R&d߃>]qw'<)ŝcKYxJl#rnI}#g*WȭضAFX %>U>.䟶Ě)Z?ocee P_ .j99'NWWU 5@қ3S.$| oL09WG>k u uv]\[3=uԝ*hRv%.Z U]kC_0Sȕ4rc7fcU|xgJz.gL^f79N"DBxެH%㮝J% l7aRdʝEZӗKfk_sRց!T-<jOzΪq`?: 'ߝ)︟#= voV`+: +롾usOAjL'l#ҺxFh6(Hښ鹉b2ѫwP+v _c/;Ȭ޵.vsNz;GkT}Lv: 69VKn2&ʟڽs7'>ezu64s^{ef~iӷ(zEat>?ئ%7I82^WʙK|.r$M߽THel{Zϝ|w<Ǫ)W 'q|莸Oed+qR: mH}ex~`ًS,>7C8~G27W#  kϘ~Ob?܅{FɉbrbWQ1%ܪ*^{FkbZq6ę,eHsc)XTB1/+N;5Qxx|MIG%>͛.W8#}k֨ ;9Jhlfw rZ,"N @CV^ӏ!s%ڡ86G#[X7SPqTݨ7)6\yȦkz8ѕ;f1۪hvchD'/(x A'̦WwEe( ~&g5 j&Ƴ(x% J&Ԟ?%;Ʒn%g,MOŦJ@笓YXMdb9R7#Faß!~nVi&3)HS?*0Nf{mn nNp#g߱ڴ^n;*oV멷=Փ=`yL5]n1>{n6AD41/LXZrq%.ǔ)n]!Ȏ\yv7ehSA@~m02v2J7ACPOG /{)BzlQ"w XW{^Id[A7;>meFuYKAeĈ>]~xBÌ-bûJXReB<h-yͿqӟ^QLC.;ra?jV<(Uֻ${X|@rUkr~^ٔaDq`Hd˓6T[{^7GMXjCͪQQ 0;c}-v%fS/y2Y*KIΒ,ۤ˭~-PrqR-dr*fh#bknT'L+a*2#ml8s0𶝽a,®pr8{3V?lSldّM <1{F^ژYy#Y6@m>d!Զt 9aeO2x 7RuW mԋsY5gy\,wlh1]dn\EU[>~gԸdn.Љd[hWa+VmG-U%uG`?bbŋ=t_'o$ʷ͠u٥L.(`5ʅ@FVFf؄oV8}":"o50Jlӻv8+%2:´:Et_᯺fx,^絶C# W٣hF~uvt,F8b81;Z27!'^]rm~Yk\GqD7Lka)6ū^ d%֡\=b;k6z{TC*k> 졇sJFL^϶Nw K1MePQ1.1I" -+'^9GnnP-Yi3ژqedood`>Z~Q4V㑧#[3/*5xоU/Ki[w1FJ掞Vj8ʇ -HGO|.:4ξ0iƹUhmvFdC0@ED4fw]SU-@1q}Y'S =K5ݮ 2 Akޙ@W+g0refo*ܔ7c޾jjx`WyZ|xpE6LJA@u3gʓ+7=ԊГ[*R on8x泌e Dĉ#k'2 `,؃_'1<5)>nf58 >F^7|j+4Q=u2Xx/uD?1Y?5dh?FtU[ o;h1jQ$㮬~u︎M#Cy׳,J&b&0b0Jw%z d5@xVȋ챢F,gq*TU(nM?1~S̈+! |u(f6႙Zq%,W]0|2Ȓf^l'6y<۸FɫJZâUd@dE.u;0mPzVR4&Vh{.}t*3jm";DIe~Ņ/Zئz4mQF$1n3oc˷bNvF3_ޏCC:ޜu1vbXȿClJӜL)mN#kbگ Xd9).= *uIFĈsӷ)d@W/j 夿{??oT$.ϷLEm#U"1)hҸ;1VY/c F͊♯|KO!^y8?#·?`Եg;li*Huκ 0cDmjȔGJhs6 ]XdKnY6ݻy'%1ged=;׆w,=E38ȱ?jc 8ݓŕͫw Ven\?uT=38(j[٬V\YY* GFλK%ЖH,.!:߫D`*ŁNp؀l)y]1?`Wmg{b@>\ t0}㳍KOQLJ^oGK{Rzg1DS}Wːxe4\7o)o`j|HI-kg=U ޫ ow\yϥ)|cnK 0F{gb8Jε]V,)ƆTpVН&^*˜ݼFؔIK|☋o:փg)y9z-F֞n VU*GXEzD|,w< 2\Q_B[9fΨ35U8|H>c)9]η6#Z3>f[KDwf.ȇިo6es2]dmQ;k[uKxv6[r8J^̃7ܧ|3)" c\UU kA,H~&.1Je^cz7~52 8y}#[02"X2GRZB+ KƈQ?pzLߑ+9RLqt,SanA[,9PuQ4sFSp7 !sX$z1e5GĮkJem#A^Y4];ȿY_~Dw "Y@Q1[ӴQWoU.=R#|q֗QUJ$8qhJWX^k4ssmߟ\h?ȘvaB&g dr{-!==PfHiU@oʰŪ`[70s}|ìusQ0 .Dc3Z2掜'U·aPGgܻC~n ]bR8!8"6N0x ]`}Ļsh`j%Uf!Eazbv(-vqeK; i`Cq֐9},=lrz~+م> r?F@ ; |Gv(gmLwnjUw2?lŦ=뤻*tqZ9=F*a5e@VbU!=5y>؈B媍͢C#%*݅Wq5W_=oH\%ɾuo_ڱ#޻M^bs{K_ C`UjP<;."&& #X,"]Wd ITחUyMp=dkx`ljuFG3eeA^Avʭb-h|#D\?Q>9js]ܩ־=Lmn6PفKn[ǹЉ T>d[ԁs;ogt"ڵ\gxk^_Uf}Wiz(?aUz#[bc_KM$5~7y7uR9 f< }hYʌ9:_BxpqU\wkL vSR2=OX×W>~?%?,لצAjPܪמ蟌:)b8I0y1X89E %:֪@y'^\֛21Cؘg*?"îA* Jq§w t.n׏NFS4tl+!qzmiʬ'z_Puaik;#߮&"c;פ:qZ$mSɅ#bͻɌX绽:f&kwzKrS{6NtU9f~ԄDr.7ܚ#NTMnv51|70T115Tv*_L }VbmX*6/^ i1Fl966.O59!z9J22j% -{0' G>.7?3&j>R7Z@w|²9{v6F;Wk~ jKcZ-e<]e]P'o9:>;g#xux  ɀƮ aEmWdi|Z=c՟^ rjBUV?ph$/8B'>A.k"W.] Ðo{.\ӏ뙞Pqߑ]8[۾CWN樀E&|vGIƵc М;">8Zdf}z=P8%T9V:Y۳% ?\oٍ3b.εN,Εcw4k||= lH̠ĺ@O~Lw,}*W Giab|xbqNDv0yeTUX‘ԧj66\]u7x =gC~U3kV5WkSaqUq=Ys[zF8֭>|fd0Q,E-uw6X(L3&t}zޫF-"`-RX̭W~U?X}  [sֹb*}/vziv_@,fqBf6Hѷ~sX>W[d؈Yc-+IkSp*9$;yYi΀J ND"t{~ٚ765@Cu TY ܙ,K;8*׶"~/kP[GL'LDQ=I׮p;̑[`kY=`e^*Kg? rwi1S"d@+wup\IѼIvg?}uha5NWZWI䝪[_IEm`ofj:O쫞\r$́P֘]Ͱ]r7 ph@}T~쨁SIrʌxӽ(X%ǘw5<#QEqǗyP8SbFhVk[ 6ekjofj5NԶ^B/εԮՅAmDL2ƺkٸ 5&[vxgp񑛶Dm(Ec3W{\wpsp~A.A`XJ'{-jJ|+fߊj5ޭg_Ƃ@{ysj+8vK+˫<+ףFhRO<΋]|hhuUQ\+Vo|$. {ٽ߹D]q硢ʠȏ>v+F+(";iB#DTZ68X߻jѩfqa iUh;qB<| Tp BbM ̝*_«;}ߊիu$sb]ur_ܯ j N/Wn :?;8%Y Bp$o Yz\D|T\\y u-u`-p)-> }AOSdO;k*"Wg}QSjKy 5l Yqm?(J\ ڱ7Uh1T}DeEpo6Jc߾ nst=8;V7CG>. )|U;.2n {eٶ O5L0W7z"/xя|2yۻB͜}V#{9J7db\wTu jSGZQ̪9xEyCaDp4d<ӫzI(8;:u~G/|?>"qpA/sy^U:"h>xlPe+Kˌ.<삍8TNJd^j;6^;0Q\* <Ã|9 wWkn?u^tt=0]ׄKNjw.nϱsljocOVj}3 f|Nr߼vRGyM4y3߼F `%j~:j-fugZߚ`hD9_V›#ƢFw#`X+]!Jߍ@t)}Pt7_fcً%fzPXL;:jPW=K-;O_,VN?~ X'e=|^h8H+=g&vF㨶Wm]+w@GvgLpvx*e?cLzs88CronV^U9W,x;fߓ>fFk~(ϵDq KA'ǵx=^L4 fjuD_rMVr\ ~gͬGĈƧYުEyĽWZޯ-U|kL 3+%VCvԭH9ֳЁX3g Giɹ#$r숻 O|lDk 53?m-Wyn G8. ?xgw39-qJW;^$Ϩ[|쳙]Y#yOȫoimnߡf!Qn۞q|#U]1/""wҮfͨWvoU9Sw&[ ;w~oSjr0ڞp=++RF!"Ļ/].:jZD@Zo,vW.kznkU>seVkY);*+,v"-ڭ|◑5ع s({wrԤxdoUڱ%>:会Nͦ~XFɯ3Q59 qixàE_\޹gLc{S72 bߙYi+qdͧƼ(P oÆ"nz~m}BG>Oj-uUs!'֮`iqUcGwAW0ʫ/;+\T&~B[{޻0C?O\;vx֧  Sñ X܏߾9*9:xsWuDGbS 2Z:Xz: Rbv~U֏<̷xǟ}|6o;v$9t[mXhckw]EYqg9{>k~oZUZ 'ཥ?i r{äz!RdFUu$T 5Zwhn>=U*0.kDVt_\u^7 uX+bOr(UTQ DC\QQ1\J,vn@A$+O*A@hܺ=kG^nz+#T䭾}UrolPqvr?>}ݶ{]5;i{g#{X}NĦO౶m߯ϮmA03g|V߉5TtS f0f݇mU}kt(9 h[ήqZ/Y=*;kڊDzl]ߥ.opD>^U7;v=5س,s.EWwu\;{+~lE m ԜUN~ǵ{?}g7tM{M1=UuNq4ZOq9tY)YǠHX.zH]2/#j<!{V{Domg.*:xv.G{.*9Կk&wՕ7/UX/||xUh8tdjjkGg|dcDZPPn'Sea)^|ۄc'3'RJEvfXћ7gWuaVƚovɦHMdU5__}V" ьq}prJ4MCƴJϧx]R*0.M^д$\T8KKK&wOiYif*n:tz'ĕ1.nƚr.1'K}:zhw%j5wC*k }l^iA~oyV8zsx%-Zg%9P'mNSrtva).t"/;K|,WZ{U]փs1Yc3'mvY5oYZ7='†ֹ\<}`15[7"-hN~' uݏCcYщ%j 9 ރK 5s%/$Xߏ`G͹Jf':TMޕ]õ׽Xrv5PD|,^zo WF'_»ae,2,m[^(/y>kf>7vz Gz6=VD%&_ eN(uZK|R,AumBa54@Fލ{Me||Y9ched]zy%ZSIl|H{殚ơ_JЏI&2Ou\=m?R1U.NxDu-06 bQv(1%a#kQͣ<+T]*we }/nT$#*Rk/\ˊ<֢fn uVTTgܼM_ԧN77iaUF[޿Z8ykoQܿQlUZg^7#ڌCps0Hcֽ~b-yD `;y.|FEPB +^Z|[oY@D\]{L'M}{Φ}!7r-]>X \F(Jr\ b6Kʮ9BOE&?"3_vGLѳU}?8-+pT-c:a՛ά7Y7Qp\1NAAo:O>˶1*1V{ȤImκauVo5oɈQ^݉hUǃc螇bGU'q\F|aώ }\iW^#Qit}&ၹXgĪt2c wqOZt=8'v ͡%ķb Q>VfE'Е;ĵqNډqgj>Nw^fG~*lb\Q&~i0_ZjOi~-5uuFa*qk#JPh9pUnsG>oq/P卑uy`6NW";P42s^;bkI{:aOYKyޛ|ѵZtE1Spnف\*ieG2ZiYqn/~AA|c{q%3}D+Fv|\; F=Q'ޱgw3ޙOg$AQ1g$ϭJcĽ܈5c`uQ.%rRov7ƺBĹB`Z+Z 3'~s@ILghZ=Kd27yѹK7k(ޱj {oW?bXK?ߟSU&"@_Px QS5y/*{6:jU2o n#sɼG;^~ V*M=_ N! ۡ'okkV{&oA~8sZ˨F]moϷ >,و%s2ոYlHWS\*2Tb=}~7J6T/zFJ2n9ա5v=uoqafJ&$?}'q<(ܫÎ Ww> ą;D˿oT+|=Ӎ O=߁h.򑳌S D6LV|@;+K#\jz;wOڬ;4_ ސ͘-#ʡ>fu =VWMgs8)}`e*#+BNjyC͈Yݞ,gr=_N.tŘ2f!jَbVuqe"x8ۑ9wk.r9s/۷G+2Y6cJQoOV5v;n/{ 1p48 NjY~T71#xξ!JВ"D=k-=,kG`FxWd߁̽i 3-?Ax,fdRwZCu*G ͝%b5>9]+A(F4O(,,GyGvYխmF8'5(FffnʘY;&R?wjh*"j6"\ᅤ6p>pF{OTW%(nAbZ+N¿GFƙ鬝3:N~:sN¿GQg-[ndj:C#E>6K1Z:zfosq/ x:{f}8uո{;0Ky~繷+ C@|dD?߱O$Yd8)ҼuHd>v0quTڟWE;=4kܰ81_cӞ4 jTю ۖó5{S!1N|{Wvo[_G9gAlf!Tf!J%gE}k6 aU5 :s{͝D`cQfQWkGԪgwEʠ:yds=.<2?b( o5]NBNQ`xgA+^5͚LGy HAٕsLrob ]j(A`X@3O IBTr۪w1q.o_XOZʳA9b:0p-hDEťGb̕ 6Fuub ܭV2VoUFwN_sK Q$(yheהTaTī(r;֨YӍB qqR#Bu\qn2 r@٥RzTT+Y%~D9uz`* ~i79Z;{.cC?th֊Q nvXX@ lic|wQ DۡG8 =Ziu+QhF3_e!í"}ŖvX3Kh$@j/<.D6Q~ @anh`HDg2Jثe=ĿUsG[Vqqwu?j^Yej7<%w8q9=fޝz'ߍ9~@(][W]IfᏁ֝??? Fhek @'GP_޵dՋ!P1eFR'>0+}77fvv̻QLeuл`v( n}e6,l+f87}Gyշ#hCweusV8tFu}SZS+ԓjYd1O/^e,:wfhqgx=gPEr6c?&5i}q=-k]-Uɷg<1ngiIlU^hPɌΟ88w_pDoޅvv3Ψu= Ԋibu=*Ψw7S@'e/3 "ox0s[2rrx C؛Ȟ&G[eQ1dYWakWn@tu0ZůjP"šFf6x ܬ׏j.bղYo(QUgw=\] 7 r 0v3㪰#TtI+@'J-=*#1.TBE,C1uUs PAfYS3O4TBaYN~׶*U:j]-z/"Z(e h4+kU:Lhiؔ|d|#K{U$ W&OrޤA}U"84ČQdutpyyzͫg3,hdvQ-otN{0%b➘xP#Yѩogkf}]rpYo9u"5O\D,7᫞z]9_:=>ի/=_䬐մC|dEQBvBW*ĤPAaBOTc[$|;HӤ6%ȁG!Dc؀#mڤqz mB %}m=F1Aq*]+c^ь,*u8 Y|̮KX M^5+Ali J_x^cg5ĖlmvvƱ{/#`3A\>x,ѤlDصմN&^Gאec9YP ~G>%ꛑȥ8&r69}+qy%fo祟Mgo7|wq=6W84iZJ4,o8J&?و)R 9v(-K!7{gVD"[NT9ov]dq({ yk!mXؐbXx|sG|'`}g=_酯_!n ~qCn-`wgƚH^2ד -b- }zXg~g:AC?KL:~mpFjc[̃Q0,O<F+> ,ǒොWbmrT`MM+AߡjkTro؀"m;ʺy+O41 jYhu&ԛoŲ%(EZ7 ]D]A~Tr}/b1Nr76Wshp\Za[}1qߝqqaL{7ߕ֪bZ;Vć826$x;=eYvZa?ŽjɄ CV.f{Gkɠ'T4ه[խY%A5eH/p.(u7;,8M9.26OĿ *7Մv*K,k=ݟßTOewFS*%cN8 udZ1jR/8b1Z5P\1ޘTyVOAcw]+[KD#eoUJ7f2u?yǃQuW^oRk7[ݖcA!FCʑwo1x#NtyYRH!]. )_1.PhP:(S,iS {)Mv}GaD6s?'IMN!\CΝTkX`.T :iILؐ.GػAۤx3ٙQ$^WP%e 2s}@Kޙ\e48ē?@oEM|X+w6 2FHo&wd)VDhQ䌧%fk40o;_ȳR(ؠ!N Jd\kQ>aďo1wжR͝Q/Bl^xWiF`UvJ\;*^2t\mܕwh|8?83 'h4bvZ(pәwƿb%.&Bkpy YT#Y76d\r=6kQj%#[| VyvwNF|VfDd0RuW B.'@6*#Z}1V6}ZRu>2澭zMFdACql(#ZQ_aW@#{腙soz_=yruW!32/SS2;{Vk?y2faUvד kT)=wqȿ_ גqEͩ’}FFB|IrDz#TP)xhD?B^2_֥sџP)iuά(+7?Dgx+fJ }KУˬ#qu#Xn;)3U5w^#}V3w"'CgDNo=w_-fVFIn^C|cF]_Z3wQxGhQ wEPс6ܭ1㗷z7*/f`!<_շvWYM%paFնw)qBYh1}U=Ƭ|۪ﻖ}Ψn^y{u zv*4^5wȕ|=qe%orT5F1X>:}T}l'B\b|E߬] q. Ks83F'ތX~eeE{m켺RૈaU+D\uR"wv*S$^ReCz#"HD)Q@4]bD@h ߡ|e*)i_ "ʹWX_Hy" G"hA&a\$Bc Gw"iQuX*t*`JkF! fUtr^32( .Od6Hc]j\$OR = 1/TSNz*KZ^ "i<$~<ͧ0-1YXb? oёp;o!.ʚSX,1,myDR* 0X>cZ-m#^Iʰ4@C|1l^ ϷZgv;C jl=ljX?(gyTG8$Bsy<" zÞGouB;4E3l A'؉BA>WX,pa92yz/"|~bE3cyVly+W|-:7xgT4LC*x!;$;2;A G(U߹r[@HA&W \'Hߌ@,@\E 1ɍNx!~l|Q:b1@<1C}۰3w|AQq߷ L߉F;0Q-a':6~w%Uio[eRęWSEmDkTdDrAxȺOt`$~~摵2B[ $M q0'}WRkI2`IbNmE<=3r߲1O_jʊn+>⦇刱%v 4}TED^Oط*NZ(O'񪷬 J[Q| \ 5~;Gm6hTajݮ1ڻ`V,8Y܈mjnhF=i:elDk2#v2UG5pjM‡qwTxUߞl,!AfFYӚūΟi|j%m7eCTƿӓ[^[ہjYqeOnՖ Z|NxkGr~ Z\a7|-niOWFi߶V-;Y=O|ڕX?ʏb6ޭ; Etk-㟍/y!Q#b{u5BQKlgUtV2 beh#bfYTp؃7+_!q.ک_w0Q}j$qb9I_.χFNY1`[er{1lgҩlE`6a53th׎YJ=F1] .W]8 4_m{a<E`7T'_G(Wj{W4eg>K;^Xi=byr# 6Xeu׆uP{ϛW}{V2[+Xz+#:| a9YI0awZ_^#>ٳd,"'-(j$&(Q,XQnONGF(j&VG.^GD=.9F~ec|q3Y6F#G>qb5G8&W0ۃHZDkYyvлknϪmJ ISwj ѹ[L$wf.u9 #G/և%#&* bNv#NԑD3F ChIO~\Q%Dd]whޓ#ud2scŻ"qb/O0/*WqNpW}fOu2ªu߃eENx_|?,:H ~Oy٫*BF"R_w]r>w[8woc-(D8b'"/ȼ~6Eu׺ݗ1ۭ5gq>VĢ0])*>Jѫ!;c>q;{o;d]w 7|q$W *| mL2d̨絭#{H?"׎^%CȖ88I3+J0^ßā,^}/#Y\D[׷E{{uGql"Z?eĉ}j~TY<2L6v+QhOДȺjuοA:2 ^#iAbB-pepr?]ͣL}>^11kMj.Z90(ă/TTZ}V.DQ:@v# W+E+|Yi?7~_p;wDEx";ơ2~0H6\"xOV3@/-y8wYv{@zre bGq\#>~8qTI1X| >[T Nů8VOt| }ߪd?8f6EKF=0Y34HٿyIvt1A=QUbϟJƫ.[w<85B -> +D~@C[pA` OM= 8w{v.N1]@ 站ጠRBOֹm#x܅=¹z8\B3Pex1oF*Ge .ۯ6E˱.'stk s n됼d y|}KBhycK34{=LE>+]pbzb7Ӫ^Uue R[ w|bk=_ >陃d%莰3"{Av/=Cҧ^ 2+Vh2,=c5aְ_wm=ڵ^󕪽ئu|nN_Y{gs9_ې0%ϴƾ#cig\җ.ȋuu0I7J tLF#n!<KZl~@6iK[7Vs#TВ2um?qPxLKuFvi eMm_5M"Iكx*k$6!jv[3?筰Iˠ!%o$EU=Oeɢ%{9Vj?ھΈʶ?ϵ̣=²d}NH^z*9f.4VjV{|þPغX9Ѱ<5CWy ͥMBho%Iٽ$;Ek,HDEϦ.nkS:Weϑ>rbIYlVC8(=n:1phuy>vE![ϑΈ{Shh22KdmpPUYZ^8ޡsyӣ,<:1[hdօV۸PI<'<0ZKҜb=AΘ.=~KFz~!o~=ct`PZ:#IZO!}-?Cʞ%0Q/jOF~i*l8".ck9Zj0UExf̖{i03jH}*)yc #)=k;OiɳYο2R9ңA<~>Bo=']d}ˀOQMe9N BXg6҉h{!K7Gsⴟ槴4ٰ瓖1:jBZ. CDв/_Fz}@m;ϫa~dI&KM?4ǗFCa!җlޠ<̩yo#6hőM yLG~^O=Һ% 2GolBhȴ3J#^KQZ{:fq/jXFc\^2+Iҁ}h%}tgWVD}Pr%JUϳ&^+Ug9F?ʼR56*k72??= g6% 6{%J Լ:4%#y&)֎:T>ÚwO9Rˍ-ɗzM6ql;n#R{!C+W+'rF˚[ZaZ/5]cQ)W7UG ]m^i=eS]2~Xq$NgXѱD-;z-\:쳭srVz!aϣc}le淂ǣR&e?c%agFJIx>@>BZFõC/dN{Qt{#Bՠ`sϛu _ziR/]^}7r )i-gd*|1Yrׄ^0ڊ >&%Sk|.AL oF6q҈N=/2J[Z[cx*x( %b)Ǟ}oypS_6jVFhl4>J{Qv"M< Cw {W[ UGz5KZr~k|aDp1%gz" yu<›[焱l7m⺐Ina~O$=KMϫ]3"Z]bQ|Pɼz¢k!g(EdDU2yp\3,~+)\z(^QƖ~u==RWXڔ璜d-$*6ê׼v1s͐jV|[f=%(dh~ujsYӵ̜.?>iIl L[A9.f~4ck]SQ!quƾ3 o]6bt3Тo˩YrԫLM eAuS/o%~UgY!'!O_>:ub Uѵ/׌]keu2E)NOg*taCS4>#ul.g/ׂ9I9_th $#1z\Tw$FwCsvi$ψSF-%]~^[HxWH ߄,gZ̍u&|u0ؖ&Lӏ_ƧyIU@ATYuW'G=@ւobM~y[!4(fR @۝}Rf3|iF"tTow6ZX}ݣWE#1CY{3[gƊg?!H! ~~(i μOnI F2P(ۡ_%ֳ'-.Q8%1IT~2:פ1bCxf^CGJM­XgNFhiݲW=[BvTvY0J v[Ҳ7#sV!Y[9Q,~Nkіh!g(xcEfoI+{ K~dKwˬ-˘{N Xilܕe ԆYk:J~uc\D.VݎE{rw4O=_BTٛS=Fj4Sp'ۯ,iֺ ]c?m][3n˃-rpt/˵7w^gRWΌv9Ќ%䒅 i~.y iDR7UVR_߷./ymdyo5KΪԌugq=s?kIe*\51;q#ozOxBŞcLa5\rB3==XbPuvZtd㶬}Fec Z#kRmDFMX[VH繭]OZ,#ѧI3::]\Zmki\W@#eu5z+^Tf@g/gr K@ DrKԶ-_4XsNNÑ!aId$sSΛ_GKEŊVl#tET=NZgWQomN,|oMf`(xrk͖hV+BUE^0\Xcu :v ;{4nԖBu ~)^hV\59EJ˛mKiբ[m8x$ qjGh~YWӥDzݯ*U"Thzo9kuBAFţñheKKL^|!sm6U-^Uh~F!(5Wf˷ZNFŊ۪]TZt TmiN{G5KݞoȮ7h=\W X%|aK$q;uI:;*8HksX<8mDJ+@/lN1 :Ƶ?;,YzNZFxO> B&a?(ez"z[x j_FI.,%8]kC*G~GBΤx o/D6#fEC' ߜSHM8wlKdB_RY8"=xڣQXA}Lb[`C\S,vUmi}Rr,^q6XoGב maAk]͑09QK3ۭ$#"=]+tofWg[ۣ摤&ٖG>)=޵6Xv9G썬9EkÉGpGG\džE؞OD5#JͨC3R 0<ɐ=G4s:-jB9G-z}pPmxg?#)|\E=/~9fb2[ӆruiQ_WjNH6lПDa[։+<8VҤVVTX-(ҿe]^<n{83:֫Q$5ͨWZ%!K%dٺJxxu*J%P 7߃A1_Qì%0 /GKU(kϸK]0o$7! wZڵl6H VQ҇jPPN9d#߈h_ Np[k9.0;\fHb 뢴4C#9la7em?0K(ʌlP-21Ah`MQuL%rƛ9&W %=C<lԬ,Hk^5&y? VYzj^ۭn ܏zW/G_cdnK(!z$&e'|Te~lW]lg$EHARA 2-q0ULg:>FPg#;ԯ0I@ Ғ G+s5XRm4Ь1+$hbў1"M&+Z`hybd4ÔZPbt[2-)R I_կMF!kk>=txڦ:}L]z;բUQ  +YcFgoA.Q`su{\f8[--OGEf=Q\Q?tkf`Y#EbVc[RĺCeχ_eR qnFё^Z'Tb AZ]OsTeGCn[~ۏ ïZ)\RȰ_add԰I\Y=]e}# n5#)}=vVsPR5sj!:e+ߗ0G̓]jH)ѯzz'])k\! Ԟ1u[A cGѿ^Z'sCI-,$hA-:n_%Glɹ^#GQo{^^Sx$Q^ߗpMViRb&NBAdKY 5e;+OztGFh1ݱ=rhi呔edIxcVIGez%k5؊|F-0(/<ѝ5ZafHWb[j5Bɸg~:ߣR ,mJuUQ?C}q19-٨-JgϤ 9FGM4]5z9fZu慖7C$m=P"qyֳpŸt2o!ъZ 7_cUxhm8hp+i]QxܙEzep>\rCo~hݏUsF-gDyyOy%9_G\C?dV#'2{"O.kkǸV/8 Ѐk<8=O(8FK܉3t\5BT@ۨ H) ¾袢hh[yn*`0N}`ÅЀ 'oo\i< .,85hDIG({mvVK`nffhwxgyܑ<|ʓ[KEG? V )1HU.8Vp윎,,i & ָV KA5/bNt_@c`/*T_.y~(]Pȯk"?n1T-(YX׌8(._?MÂZuR=H++UP血.TPf&KA)$wø qc(R`,YW r \.HVȦW:(oeAςsI $:,X gaAb_Ċl?*HX@$HR[HįzPpY2ָ oZ韂%g-+,RS7 9,8^7G UUdKEy 2֩8\SqbJ.3Vp9g91*Wp_}r:C,\8EQZj}J*UO~礵bbmb/Tqb*+N}ÿ+6*Jk"//X?)W b]WRZuQg &6['8)/V1ZܡX8Wn*|KIUs @**BШX/pg}Fn3㥌UV@߯|P+V9@oT,j+sb{k_"^!AEIߊꐵ%רs+*G! JƃJ+a뮢7#ˀy*UT?**U쨨mɪ U>"aE,v|l*>VdH;]Ww6,AH ׈L+ y cRTeE@rpGE!oc@#[.NQq 7V^K*dU.wW8p+~PiSqk6B_,,L^TͪOùٰtj2~VlaOMâzJlÚMÊ#Lo`-C]½V jaKԣ<);AjfUDdVe 0Ocpb-8IdneF&5eff6&cV)fIbA'+8Tq-\WGx'y!9Bypxwy5sx˜x<Ϸ<쓆BJjs{ &Ci,} @.B+_Kc NXAPdf/$ >Xgʿ,_H+.*ï^.$I^i|!cBlq*\| v!T\BJ)¥]H9a%S_^P[km?ǣ%瘠jM_ЫPGvy(tv lݷAjky_M-O6,cc&kO-Fq 78܀F̸qmcNu|Fqhn,N7 ظ7Íb΅{.6 7ko[iauk7ѝ9(:{y!ǂ~؎oҴdf# Yڧ&k6B]8C 4\<oX48z6FolnOmD A톃ޙ$Bݙ%/Lx7@gdëenk#Xވ\7667썝ezkMc$X*XX4ieQdc%}kѧl@&Dx#3܄ld0*dVmV&u, o@7!wZXg3DG&\Sg㣌 >}i6,*Z?S1^j6P}pnx ɭ7DC=FHp/ߗI uW!rGpfkFݨXQ(?s<`ܴ _}"V '* Al!>Xd,,n&VK?;3W1:׵j˃dR QMJD#-x}͚A#h"¦vdSڵM?0^)?8t}Ђϱ4_ٸy9۠EH9r]4;Bbӝ{$FoDzA8 -sk[ۧo#xiPN~X-U6&[5=q~EmǍ76f7™ptmGC7Rx(@bKxz"!AMT [[ߓ]JX#[rΣ`l a雜p"x6|]cWHSUE%]/q\J/v??~ X[f< +gMĪ{J\g팄;1ސ*0z0ۨ) s+_-^xYpT?_;)f d[[/9]Zw|wp ._x_0 Zo!B?Pe(~u4H{gJRxTdI`W=Va+SiT5]Tn[-J S(k | AoFwK'·h.?P;cB_Gڤ@b|V% TWt*P}aA#-baAp0N>/Whąi~ٖNf/8uʐt0.nmz>u8#V i܅u6׭i[婸!}ZT.] m(]XLsJ3|aNrԅe< f-nu;PC2m'hRF\慮0]av ]ɌO:ͯ*W'+/W^.5 F+ST^t9z"5 S*d!V^T]ω֙)Qn΃#8LCQ]^P%UxE*ŧʼnaw _D\{6ϵ~+]p,R:uNI[>+3W6\Tf Ys Wf^\MdM~jogҫ(0) 7_S<:.:\Fc)D`Pr6jx۪eƛ9MG;㍆;7>o4JfJ{\oYsv7 ZuV}xo s,:21r*xˢdSnY{W!fr>c.U,|E7jbcZVc]]T0[ *R^x,[Y!0gc6Ny'DnukQY):)"xWfkYE9nzuvZZk[-M|qxΣWMzum <%m|Y`-#[6a95ڕ͸+-D`u5X;~G_TAnlOiScJ =Sx(&̠.r)`UTƕ&ZMscotch-6.0.4.dfsg/grf/4elt2.grf.gz0000644002563400244210000034456411631447171021745 0ustar trophimeutilisateurs du domaine[5t[쨮lkƼkQTBlð,R-K{{WWM*kyl=Q]is~o{~h6Y~_Rl==v=0 $3 іnsꯛ-}3m)6ْm!L[=8,cٜߊɖis-^7[͹n4k10緢y۸yd{>l.Acsy>l.oEs6R1asi-_7[5{k{Њgߋ{b?6t1e{Ws6b1asm-_7[5[[܊m6n0gfb+oEsa~{\>\[_n[\K}5۬1d\>l~@̸?b1a>m~/c.>>Rl~/c.>l~/c.E>|y9O1a>m~tǜss1b>m~cw>&ǜ3}iJǜ5}̩nǜ8}) 9}̌M513w4[k1?wd_>g1?|Oy,l~o.y}Oylsz#A?~X>=ao- ɶi!k۰#y}m{mBzdo ѿ3lRLے._ )BJB-2<氐tL>-$&c6 I7!$*c I7B2XHYvXRV}ǘR֭1Syn!Ӕ}YHYv!eyb!e;>-yd!c<RїTTѧk<&->-wLћTdyRQ}nRѿSBF%C7R ЭTB~BhBw|-[HM }KHc,$BR?4$_mtY.|}י/(?nS׍mqpN7k -۶4JMX{,,qN,.,nIk4Gϓ&YC{jM ӳs?!glmI+63z"GJKnFD!-qoَj@>4lbMs?)ͤ Hl]%sn9kW-k٪[;˖@ax JRsc\sR'zc:ߚ\_流ːƯV`N6k<@?yY[ Ϫi ~{j5'xCRuK/k_:i]^𞄦 Oc6 0fZ(GVgy UrsX|u'>⮔~j?{ZϚJj_΋foqI*4 WY \#k%~|?t6/2w>&׎и_[\/̡Zd{\Lג_B*=Òc!/%~aYe>uoR#3/ۡ.@Ф s>Rw123(l[ ar׿13CF-cW]:U60k0-M tL>7du YTiB~OC =1,>{ĹY~CH 3w =A =Ɂr:PX9VyL(s:PM!1uLB(#dF(X:PpGy,(#<yX~c@Y+%`+u[~C3!OP<A:ҁ@Bi0<1 y9AOs¦3/C$fI/qVOdylYm?.Phtj2~r;4x'Mt,AK"t`w*_h45,{Y&_~D.:~mF c7? =C_eG-=c{yON|>jQcO81A֬h~Oi߯ق p'Ţ)̳LRkQ2vz[_v_<p[nrPl$1Y|i!gVhj`҈ioXc>1{^AKΏj4gMtE -&i}d+[䤇8a?8)? :b[E뙚 d_}4f[ n3pw ӯMn2CX_ ~o>U~=3KT '~O?jsN|ƑT͜@Dա<>oGUNFf; ~FߦDˆn,/Q߁V?7z3{FuTatY9ɼ--UlLj6kyǚg}T?@~l+|OLӲdf-)٬e}ЁVjx?C idD(ucZ~O&qZ﹈PTZd[ՀBCHr#A'yOu2bU`91[Zn8Cw{;u>t:M5njmו=|zH[Fi虢y᧦4[y豤ng۰m૽S"W_^YT CG8lx$g7G%~WdMLب,7Q=]lRTc{=&]CjJN8d=}XiY^[J }O*d}PmP#V)]C?~cVUtob*dp"e1{2MŬjh ר ..4umʴ}<fe1b*8P{ "oYO;ʕf!$9cծX{C4AB1>-O}OtnLw~+'yxQ-mգ`}XEc+~ޢSoQ?],t `SQhma~ӊ0/MB> [RgF~He=#.O|,뤣u&D\FL0 f+D$4=ct ',W {t(+) K,I_q̖T ?l+|]}6d!R t<]ӇxG=E҇ }I`_x4eMJ{Z)Dm@]̱ ^žm:Mva,wˁCCؑpz-':H29'q4%A걹m-S΍]|WUlmt%]eZӁO流h/}d!tFo<{Mʌ-d+h߹BL!#oZ&!pA:dS#Yuc<-guYu:d-guF翥<1[VLC?<P #,硸/ B~C^*ރpLet^ q%Z~M#@@9yLr!7e9 = p<Cƨm"9NѲBXu{ SPy,h@Dϕ`=DYX84j߈Zd¿ 0SYQY#2h¨FB=ᗪZ|Vk0zyf]%(|iߵz!3e>t$eVO3lr/[ {b̆c[Kl^l[z/ӉNᥞw$s /ӹkY`1?v5ܛ\B"#Wy50vvy5PTHwI|w l*k&C6 ^xB3O_⻕?{{(dM oՕ~ uߘs&gg09|=i?ܭMAc;_Ҵ#i4_!FS1El֐A<.<9=P-qYtàN+ɼ_V^Cƣz$4i2SkEA}*ru.YfTSKsj5sW7"͟Zq`HV<¬& fF NL1'Fn ^ua!.f,°g M왫xwCw=Lǖ~bB-tiJvM*`S>/dQtUL-kz8DQEKP=У!_ "ʥg" zNA$/e5|kpu.h 2r_ҶOhF!/"60HeESRb7vH!ͼ5NM(wyF&ǘV0z\)M2[_{͌23{J赸*(׋dS%HĬ/XC2=!R|:w*q@xH,U4 sL}B!n?3}pmi TShKv{zhY{gI ʿCR~S ϣ3|XP#1&%PS= ̖ĕBm;HwWs1scL@M O#S"13 : $¿ Ĉvajb4tHƂ4`N%$}0 (Oq=`BchշZ-d#)Mc>Io:LӫN (5'Iи95UWi?1I?QBj@AW?9Xx}>2J)=ŻBg UE;L~V&KQZ\z-+`غnU]}>뾠ZO o&'??^V`4|ȓ7^e7~z|hI1À hLâYO>lG﷯AD I@tFF9v3ѷMz:?3Y336z_iʳ.3`qX>GF(p1*X1] EH}ՠ7tuHdoN#]5rc 0(m Y(0LgQˠPQLsDg]b+9 0?QW $Df &CYAc6qRtLr`ۦ<GLsgy߀G f 21 ܲK@&F229_ l(|4Bpakhlwk#LzIwac\JL;:h= w6e#B`'|-J tb$}W |ƯЌMÈ d`{3trabdVQPQ-p( lb$~ 2Yŏ{>HN} #c=̢CcSdшⓞ`.rHq w"4pIr&ѸsN9` [<$z;秉NДWha?Ec B" ^"*`Tic1T3{Ѩ*?dU=]w@Z (J }tODkJq|&.?L<\=_{qXχYל<4Xaap6昞.Z:_cvЩ%j< ·:jBí/' 9Ѐ65(4s(%]ߖ S1 +śxJW>k< vӟ8X= .堚ASV~[_;P;A;*b^4ߖ;n\֩p  p_D!Lo&caJYCYZ_yv`4*rR\/*8cts*I4Ggt aur`NO^0`·4q-Og*-l+mf cV܂ف74-mG]_(Zxd"fCDR:.`N#ۧ`w\%РMv&MauI;8ӄН9ꡞ?u|'@6 5)Ctut1 ! kx'W1I8@|'r"br>7<~.qrx>$|QFɴϕgagc3]:<.+%Ch\wNP\3v 8syEM:|o13ԈjtrPG͌8e9 h-`ZiWx?:%Q}p(f9!۪VKE/x1kXL0ir/ёwŤY15j oDiБOHƒ~ 8z^NoGX6eY?^?臉)d\sݱescH {h̳s4#I%7}qDL9ROZYAnAkUˌ'0.NxI6D8y.^CЏD[M79@gGa dA"7刊((r<&GBjqOA7ڧfㅣ C]} {""u9yY?cA"Sc <;a\Jl@CΛ]>zD߸.nEҌ8!FcݸHykecJ./j5 aj,a"Re:(xՋqC)}[S F5BQC2<)b6 9HL}$q⸇}O}Lz@F$t0ύ8 yFMjD  &T㟄 GQÙ#&ӥ5̏OĨӴgH-yI?dixfYVw4q:#txi1*Qpi s-5brP4RP*՘qيAi>&DbOF iZ#ǹ(XƬ xbO1fDjM ICQ",Ya+ v&f_@, oNR3$hRFgk $EҪO&=\ >')Ȑ&E1)sSUvr_~mӥqZD󥉠BCAPO Q}HϼjP`bW wM eĔIG`Q=6V!E6A0 60sXinS5GJⶪRQCs:JZhF$EE!ȨD>L$ِ2F*L h%E>5Q|TJR`$^nJd*,~./O&n_2)z'i%bL.Dv05AIg~.=$k&QE` \ r<˥׋4٩0{NJ/1"Nb Ƥ 46g;POёSR:ĐioΥY˴J)iV磗K/+Uہ[ #[77b)3brD8] l -Y굕jޏ!1V"A#aO+<[?+';^/i䥮Yө5WA`g4Afu>uj _`Ϛ4uv2c?z:̫O*YK4wN!@ZW 1}}.}Dmd?7o`{~Yy^H+5WM>8B/Ǎ6c[6 dKȒ5Ԣbv$1tRUORdEB2 0 ͂q!M?ɮ<5)hxi%GPIG ,G,e -*=(p10ۉ'%$\|Ձ 8rj3eҼ{NGVzxLWDVY=wxqWk6Vc+d5qT 0*=!I2SwB'j{ЙI9yOW.PNx*ǹ}P.AR^F'U񒨬xj!4>3d‹Xb@PI k%M{-: hѪb; "{8qtm6F6Pcž> $ 4~ӛN>غݗ,uj4S i7̶lL {n|r2zvnrvtOyG :O#3uq^ E} Js.7Nk!}mbgb ^\M[@qMi#b7i^0#/+Rf/LAK1h<V쇉Ca7]kw xIa'p7G8qQk2%\XF4E2T7;1߾~!ʯ[ Ʋ4q =yNId V2B{j-g^dl%-վYdm*RmD+xyED㐀'B{[=qC $Zoyfqtě~ȶw DfWԬ}=V/} rF&ߑfn?i|p.nj^Y&fCkm,]`fVf3|PMe=\:F r>NKϔx^Nulh?ZJu N8Acr$ӍT֥?74#{~ݸdi#Q넍ivp4g3l4@iamg)?Yԓao}mޖN)~"C? F oaM>S~U4ҹ6kޗZ g͡@ZNk ^ր&;l')<6oPM ZgI:# %^ 3cءdy|2/W!S'>h>Fw˨'#kg|xgп:M@3ɜ85t0t܇>hNG%tS K[@ x\z=i oaE6xaYk i@9e.Bb:)©o' k!fm2PYqfvKQgI&Iu@WDp!^q;M rjI"[#L6Ng%3 9fj{vg8A斦aL%'[X: dw^p0Dћ]T}X:^׊*2!6/4k$RV[39;޽S4/l~Ww2-^OfթIbҪFV &WWRfuE>Q46;ƞJWHDz'# In}9^-{8du+MÐR%8D]L]4]hxPU s[=Ft6qi-L o\lp&&7 aKk2Da4Lxk>VkjD;C-䧑s8hH*@7EJpAxHN=y_?pӪj F}"XL 놓=.zgLz퀵Gr58NG|F5%Ӊk 6O} ?gM`TnElɉ>pi 9=)A״tNy^/}NI$0I}rpqv`jӞ#cvIx}̍NZG_apwSSN]ӹT&#٠kOt-􂤢\z ;dKABoGW6 ^7jmbFrU\S'9_fq%*cx&wN_FiF+&\3z]ī$,0 žHAeg2,pNA^cϼ~R/+I`+ƊK.6k۶7m[ިj-(K;!n:y">H8y~&h;ϯnbos,lpI%ߗk0Oit~xP'}{oǷ͉o+b%g%W9rj_T.!rIk47X9RuWS@ A~2oAE^fi0{9h jU kڞº-:NCg48I=C is;Mԍ~ԴB26csirItX?hnIR c :/I1lPSɻNϦ%_37P ƩQYAk:m|pTN_ӥSɚ;-0:lHՃMY[@=P3ـz3kӂ's<k`"r%K@Nݙh,<Fs%$m8hiHKs:j Skj:z3irҍ4՟Za`e5\/CBW-H8V)>V;v*WP[Z?`m?T F@k#K=mtƶ[O)ZT_Z[ 'сn>~'Y1T jcK 6z{3%{4aMUhyKldLPNֹ5gWoϦj"mz-OA=L.]#x~k9Wi!D zEV=O8;otvreNj` lOjz@kϾU]1 ܍ޔLm)cBgT4J[/dl/$y"e!255JAiAwjg;ia+VwBxv#-oͲdBBlWٕTzMS4J'w^M]*]W~@45O\Ŗ27yIh:#@gFf(wJırx|<_mBφ [蔭A$}㚥j PKU`|yt |+upqtArgGq`8`012F&9'HXuU0v%M"Dm IEeb*l]c##f1#s` ;Bݬhe IRSC7i8:l0"r#AZ+c\rܢMnH0b3. n !8u|33GKqLG \Ƌuo@Àd]talc>>`Aڶ58³^, E~Aʐ{nf1qBnCjG L7s^, Q8Ly/8Lo1ݾ1tt$jhN[}d5؆`hKۼEwOվ]ߞjc-9mML3's@4-El ۈH.˟vRxa1j6pS#0ԏ_J=\n =]haH<4Bl8D싙˱m_5B彑kӤJB^򁌟ϗ~ثa;7[HcMh(Fb~Wml'G`],ӟ70pBcuKqYN~uӯirrfCDU 82a'PL33D)PK6'B rJma&^_dHSƊ17= -1q-d^3AKp-N-7П[+GNMZʈyB΢Y!dH8<ӿ_!d酊t*6:eA 5k=e<#="i5HȌۗr);䌪`.rfnVaz#^=>R'-BlF/A .6T\ ;_}=~bNK.ިϢ>:U[ԉdVoƫٳK/z\ kpuk x66tZ`2ȶn$BGMǵ$Kf)=N }Т\[ .,>"f_UDYpzF Rfʿp+\:uȮ#hHs `"f]>rg '>:AV?Hk>nfxB1ruj .{>HZdٜ^tl Ord g`Aa]lU[f^)Hp4F `hTBSos4ŝU< ,QHv;-PYPAuR:̏cDZ$V'3+fhI~&y9} {Mb:fNi5lwr]' ҰD7Hνz`3a5uoLa)05OȮٌbO-״;8vy?RJ"6Z6= hlqigD+Mo6?Wj.Iv=nʠ9G\x jc9S2vS`cxL^ϲ"K]4=e>l Ҏ]պV[[wfXz:q ۲t~<%$ʉ2 g 6&6Y;(aX4c=*53!Z NNWj?T Ͽ̋me cODdcfHѲ`ka1$C&.; ^aZ͑|s9jɚB#&Gn,y8؇ n\b74+vtq7;#!'ҍB f$6ZAHȹ֏:5ق4a]^a7qc*mOKשl,H /;X vqʿccE}g@$Jd$"=Kf*VC)+/!X-tvif)PY`78X ;u8>؎=,f뫍0V hǎ<5\h׉aįiԗ]ռܙE⨑b>-dxx:ovb\DV;^Qv.I/iS;2ѩo=SrvCfckD6L9=u#j.P،c346_"ʬh~4 _Kx-T'_\5],r9=\;H̛RFRd0-0p ?l@sd:؀닷ttoxnE3W.8r!ٱ:SCj vJ]ʹNna^yW;a8+ABr4resJMJ=c~a-NE$k6cJ/,Hk4Y ]闿S= e=z :N>"}}[K;n@e'pRFJћą Y&>{©Ip}2BQ qYE~A2I*?c_jG5ˤ VN#]|, Z0N,Fgy֩? eܺϱL_dTD,s?R&ϭH9 =籆dRץ6?N8ֳϢ~7)ˏcdS:OsX 'pY@|Hَ+3dPshF#0;Nug;g5CMʒI+ߏܜ>&5PcΒٺ/mbd$ 1th$́)qGIL|͋e#HHZ]@N'L MZKҟ8 >eoq|$ӡWt5d}7peYKB~ɱh&iQT'AQ>/fD;dndWY2n 02Շ8eϑ3p{~9kn +yoxx?b:'ڣڵ3K..+yB&N5kz믇7c>#wihrE"B惽{Aʚ2u]TJOǼMwv`?tKyEʼnܮ+MBNZ]];n%E#2N7 ޴V{MlbjcScSn^ +p~6޸Bt664 կQ ŵb]Jp&%k5[:te9:RZo*`FlU N{ɼsԝNp|(3pV2D )Wv\NN$K$ f>戶| 2OVFc!- Pbmqߊq +cO@ Ā44yU~ >6D'G:qdc 4{u-m/f+=p>6,u*>dh@c4yZ[~z]@,_-+'fɩȼ[cYH緞MIoH&M%;e60LʲPr +\hY; Ҵ.߂qD +iݐ_J '痚ׂ=>>FiGuKBr#V3@l9:X&cZh$[sfghH8>NoNo2',xA qw;EwN}q:@ }EsW/jB)ZB8GT~`ܥ5ͩsbs"WOH M7-e{G +Uά׋ )@#N-}qۮzn&f]r 6~zD5:Ev3XءoH*_?t,a^a}<9cQ_Kp$8[ 45|('mMNnvZyuD}|:UǥG}qՈ,k #uˎN3'ˉjlrt"ҀqH4'h;l`8DNBеyUȒiNfF} Cޱitd8.=BA>Fbd|ن@dyg +8Nt*66 ж0]Bp`d1sR>f^E0:M#mD6/9YY =Ȣ[9mXV7t,ׯ|bdٲyZ;mF1ZҾ;#h)q>QSxˇd6q#4jU7n }h,DKdmc-d䫯4gL[];ޯKD&Y6z~4 5ŞxPaYzFnZB8OIxQyB>UrvJDҕ+?TA^FMC&ш SXS0IBSJdno 0[NIӛAM)kUMo6Ew{¾ikjhLMh ^=sr 5[eIopB&^Ƨ>LK z p|گU8 a~? mAii:H9R}L)x­j<`zپi)Z%>챾=[ޜ\ܕlw|9lDYB`j*ʹSZ!ZD e%TKejPez~փcehJ'UYْDqєh.1Klc ",{m}nD/e`D9GЦfY0\j-V8f 6&@K(o_10׶RuQ/"̲snGTX5'LחnZsنd 6wЇi 0hYm4h,VZSgRz8 <>7Kl-]?"X[Ws=t$M Y6sL@hĂjps wFWS]?h]zP1V-?gҰn"vm/7M-O왽gԡ}<[[}~w.#,렽QmxHeֽ!fÁh9۬ y-GYOO RŦ')>Ѝ'2EM̊$be-B֟l|:0p2+\A9xa%jlKmwAh^wP'SF\r6{>BSq1L-ɸdM-tWV5~ )p8?%S/9CMJH46+fp*Kk*h=j酑WG2mD-` RNPوLtK38Ytt,mF}t/3NanwOcS t?l-8zo`gB-`eʀd!n_tpWxn&'o_|?ӱr$+9BhA,F-=o~LN4/-ؙͱD&N&aZuAi'@-j,=N"f ^!Q:eF.u츧 6]Amރ'͵V`tf Z4RXp' aiPU˘'c1Z=aSYϙ($R'1H=4Rpf>R5++k`T}aeFvcjzw3 J*pOw4MJEZ*]yRt *wKHWg\d*8ԍpDm"4^[w!Ʈz;T[-p$hq VyÚW kgDZ#eJSPomVSV#K+-@ ťppFH^Aqwk?fWZ/z׳(Qw6sO ;\UuZ ]}]ߋW7S4#/3Yw6A3k re$"!vuP9vApѓLݔ>3{m-@kJ_ >3U) H}N46Fo3u tGwL*Zqv:hv)|TNFW@>QttYZ=IEahP7E~z=[P7NPqtIMthMÖ00|OSfM;垾X4㞬M4ӡj>WdJ9]z04HS9!8SȶAszUj?nS5uik"GGӥM3:. ഍rOp]T1an)Hn)y;Wp#; oQ vGfY6YDND<\^R}Iu ,:ɶ6#ڄMLne0DfjޗJ&kb 5i(L-CLbQ^xx-glŦ3$U-W_hGA`e\KTeR)t.f۷6^rQvMrTfo|TP` ^i5? m~b[87^]3?*-yq6XKT[e@B!6\B<ߪsd@Á>W. f~'ZKw0V֖\|.1ؕ#ܧh筬7pk-Ku.$n;08ō|:U%F(?E+I^:8㾋T:^rߝDsnDzq`GhWȵ@oJ >@o4oṌ/4GKW8~9np~6 /'pKߢ*Qnz.oo{Uu {AjHtb+\?@N]iw8D>[OqwZrv\ꗞamHumמrTEoOAD ѳ>_/-.k;-BjZfu{ƥUGTK@szmfCW'K{oJ e#}",/ MU!];QZ-u!CwAfkcNUuW- M`|q? hD=-|Лz"9 _b7vfu%v97y*7I+ J8n~XX(T^]BQ$[^cA\xNmr2#Ӂot-iТaH'#[\ߐi595wM"Y#9H)An]}hvSʬk֕bUP khvH Q=())vlw"%Vbhk07ŋֽc0HcÃVJׅ纠 ĵW[]\wQ=XduuUn&-SitedJҕ-)k oS>U$V/z/n<6l}>aʰoQAΝB?/eOC- ??BP7Q v[je5 Tȹ;AB*zq?fr1_pќwk>xͯ#[Xin~B7rľe⢾t}Nd7{ }PM7{wxN}_Z5[m-G;z4 kDAa)槯 kzRxZgOk-l[OIK<\*hʄxw+͖>|x-j5M kIs ~ OKo&E@mSN>m;_Q1e6Q\Vo7zAc(XYSMKѣ~ z9uڥhS.OkWFJVŸvdcTm4ûhO]`ӮjBiᚵ{!N.~~4 i45b miǍ mEr/Z)Yoi7 @#d=߱11u#8< Skɡ&O;{PNP><{s(hi[5Pz}vTʛ7<ȼ{} @>@')6,nb;QxR:(/6lS?vN};TtqAoP<]g }9P;PG;s|/C.P]Pz~%Ю3~yЩq@uFuPrĬC܀ީ;란v:C砺/Z,n6.p~CӒ>)P_A+Ѩ׃eL&N:5u?L'fŪCqXYN([;}uVN4[i^RD0=RQ ߞ]H'H}+u@YzݕwK%[W_f]ƻw%M5J ] ߂ZtmԵ[Ж7]R{pJ][6Mk Л i, 5mX(n+[:ڦh$}Z òh9[ҟ]TM;'f3 E2ٓӐ$|8C2БܦV:9!EW?1s懛?;rzimziC>][J'A)b􄮷DsRhQ$|VG@O{h ϓ0/>y "o8FJd?1zHψ;(-<J )DV5H(Ak41? _|PYd}|ub\߸O=UObo]R80<2NG/˩_Z/F-pP׏7O N$~. c Zży O#?k?OIb!}IE:1z||JHԯB7~EFБA><< UnR8X,@ 똖=ΈZ>fƓT.vzS0w0@昽-mp_f+Gk/XpSzX?`~;X]h${ l\f8δ?EIJr!m@=UyE+N|* ҭnN6] яC3ۡ0>C֩)Y=K $舐*.͜$GCpe$!<76ۛ4>zt ܞS No-}<$,m:'i\80p1dp<O'ͣ*7ijٜn,;Y:!U098݇Cw~H*NG}32W A`n?9-?F N kA&~=qKljC*Dwr_CR[] $ҥ)<续G}N!{9OK:1Ptun~09l0z D ϏTOK"T&WS:йԓOfMpf<8-O&'6$`]p@tStiXGs=uM靖h$8^0.w6݃m'it#`.ts([At::L:xN? S{~`Tp)k>kNJ{׃hot_T0H8ugq8 R'!m7N9ʎ3a9G][ b7)9ݬ[ ϛC>mmG|8H"J0 N7c|ϺaT:އs r5HRv#ze+w<Ŋ|0Ep-"ed$\Z!~N?.prR3r#S"@7,OQa&8gߏUR?xo^6&$f52 ^JU]'?-]Ik?a*Va#p.E%Pduez}h;fCWTWn&[]X v2yHݕ뺑A_x箌T] yɕ4KB' C/MDD}RÑMQW[kc7J'vd#p܋GA6kNBpӂ nL=~Xi%w<%1L:OPK"K/7LC ܏Goz?pIwо~1<ץo$#WdlIE:pU5MV%_%Enwбiӱo8N6ri^42p~<ׯNzO+p$)]uc  dX$_=h| [Na/}P)S! N k('8HPwH^A _+䷹ )'VU)]CӥɉR;4A$[0AmƳއнY^ CzN nttɚÐ׋WZzt^>'„BiYHWDJ ų HDpzd!]TB8JR]C`s ϼNG?=G=U#Gon[PC l.+BΑt[~D#x.1LCη wކy>S:Te\.Gz|_ Z>p9YHW }s9r-KpEnR\.DS1y| L }H^b |;*/#Ys 9zh~Zv2Ak .SCHG#Z tCB9t{Au^ nH_b8k$ 97>x>z%n1n}#pOϘfH҃/> q"sc 7H<~H*ҥoOyy}tAp;4k=uB#v_8׏ uc&W?\Mpp̡4̡yKy \9|<DW tdyR?c[Àؐgq`_$HBl uk>:R.<˥z[o^?.B:8:\m^( rXwse#7qE/dS}s=aw3+ە㔎:(ihyR9,o r3-7&%c? 2puK,sby%%B F-}d?Xm' _dnUnٵ&DOǽPǍYS=i$֢l:GWPr9U.;n'A8^L[٢?dlx &_Zs]d'!oWNmtcAѰyx1{T bNE }mfm,H`> S]\P Gf^E!"bX ,&UK[m-#dE(fEW '% sؠοzr-c?=?lHSgD/O =zZ RQð(wq#(ؠ$D+IgDݔ  `Ϯc@z @(vXF٭g/O iSF__&z)^vz (dA=6~D0t$;] J73U`'tKv~Ͻ'D1PayoXpofgq3fډ/k(˚'P+LH_ \ܻ dhZCb|1q#5bd1{=Sҳ`y Nn5` Txƃq?$%1 ya v=:i0vxbv"#XPҭ @\ pv<*N<N0B w"HKa[0Hh!#$dfIlpp1m"O}5aT/09/{T0H ,ϲӥo2H1\A CGӧ KbdSYv)Cҩ+|bd'8 /~t$;]:nɼ0a|A ^.yQXG`A¢d}`F,=/p3ٝF6@ Tբwz?  F} __kcC!^oDpcGI'oKIkzZ+PxbI~D1Hs*GbE d_@x7vlH*/XPRZP¢U7v)E`]C `ۭ">dDUa~ЩO/=%TW*G8A${?҇ ):vhXIEZ8Ǝ I !}$/23\:uF­ک޶_~XD@ IO[ =(It}hpݐ/ 8S ~ʏA'*5i'bpA gFJ=&jҷuW.8v|OIwSףKA;%1} _?;vpiwnAKo(T&j~nI'D*ztώܐ!g߳_z;n pH* kt N~u_N^D*3o6$IE@;q*ˡ$BB<=eGi~7T~PotA'OR4rݳ2KvIa"#tS{<:z>0B ]9z]?[?בT344s7nIż;$*n]]W?zР!&yًvCH*ʥ5 b[oz[W3"z=gke~Sg$jT#j#Hw GOhqF52{v3)t`fC#v|/t_~H_=~6$O] O!|⃙A9B°/>u_=; (/S]UP#~2åaM&ywAEyTwi  O2 ~Gx㠽|/39JkG 447i" !NF IE@_4c_s/EH#0=9~ 3ho{ZR/O :AN3 3om>XzD n4Eu?8T//=} WL*^eFU~@1(S@BtEĠ xQ48O֩A9:{ bA%5ӥ?BcjWB*φ?WTī~ o^8O!Ə{JjZJy[C o3ݱ>꧳N{htGRy>W"m>C1BoC*񼵸]=t c7H*?Y X} o=ntWr;- {D +96=iT+L.DՍ zWR?HxA-zD t2E@MF#4|h0^H_v(!Iax,A~TKχKw0;[_ȚL]讟p~G] ۞(BI;6ʼnx>)oE#R/:4 aa18 W‰[!DUTT5Y^!e J-Q!^ W7X(wSDBv6[ % uGsW?T_Qږ~;W6>W+ZD:}2=#6C €ȨY?7(zH3F_p7 ןQ5 Wo^a~hw; S4r +sAu#B$|zb @'І:1m0̜ !N}>?A6T'hCAu !n @z!уm*H[@{e8԰ _R,$f@ 8?>SaT1_)АvcՒN\R AʪW85`Y_|_, C"0*p}N%DZXN_gt>)ֵ{ ;/4߳Z ]B/6NF:%`ތiASҧwCQ-N* ;SN D#@R~6? vS s RR9|) a gM}J>4n~m/` Wa|OiUĩ6п jMTUzdKSZ͚Rz9A,F{FJZj<^ U90~=B@JԟVxjԪyCBoZ2:͘?%}wꋲ%^A{ʣj' ?fJɆ @PL !z @^e$.Fn}SA_e ,[73O诶ZPڟ |5Ʒ_=*|%AY*hPO*Aw2DUC::T'FVD-p_e?t :B}aH_hO@BG ~ Pf`;OKBu?ADYgGs1s||8"nW*'t1)txRSX8A{c':CH_=^X{@>d?La~%EUu!T2H.>듒?О_#Au ;??^][[@>u?K sqAbby !81K;lw?e<:7 ]] Z5^;JafQ-Q~˯?]crK3NHTB`z-ohjLi -mWO`uax)<ݾ&mtABo]n)_=|O[mh|) ~wʈZ5Rza j? '@-AdEUpN'SAdʍZ_щ;A} ?XxQQ_oSԷ~qҢ/yʈZQY“N)sAНҢE=Qܩo O/b*8O;#/s]cLz9p WWHaclC*N4E 'yE-=7$d${=FEN @w _ztV.$1yo_QRHQER8A8F:c % w ]ka'6ځ{w_5pj }@ytjS1z}m*uk gnIEt `AR17$lL~KXw_ %iIżq ;/H-)jf;oA ^c&ur;/L/IE yJ@B 7|o7[t7lF`z-oɋ jw$I*];%U-UxʗuX]>~!aKnH٬ OIU3EU R׷Uxʧ/cu5Av) Ux? 6TH,-)_)~սY9?Zx1:˗)Ak@>h ^z t댄[ߐ/tZ8]z]gLdd7 iDwnVQy#$#?Zt^_+7쌏]sՏ Jނu N^1v {į=pg@6S}>=a>hYsB-7uɭo5 z%^giFʉ)$ :hnލ 9ޣBDmw,ߦADuFAC r>FܿcCH[CZ>uJͅD-CVCs;Q-T'0]>DsA =?d-b /"ꄹ!a등lnFvL?sCBn \:i@P iXO'W>1T'1R@A$#!> Iom4')MA$zUkK4b/R4!`x!`|H_Z)M_k3|m}N}'[.}'oXjLM u/=_$oh'm`E/o0DcH_|_PC_~T?Ќ[WJ%9R?|KډF }D#=Nwx~|O:|'K}χ Jx[ʗH*ChOPPQ=$^>k->>԰S:Է7DԦIT/gA ro~QȧLF>C}{mj"_@>%F-%h/tB}SU$?`|OPˈiM TK7S:-ַun489u_Ŀw`FR;QA _GTo~lH*y󿠂I/ԯ#IX?~ N$_PANF">r7 FX rj$ C3 *ho0/C-~ jX k㟟DR}7I߷a=rzMס#u󿠂IC S׃}/aCR톈@ ڃh<Cu7 i.I'/hF@ tC iC5ƍ_H9HwI@oA ҡﲴ^ U)0`1>j꫱!fzmҷ G=f:/tzC6:Y _!}l +sGE| ꤹ#">UէWHGA7˻!NQ? xrpbAR8Q7_չW..{cm'j\c?h]צevn=O>A ' wd|d$_'3^t[?thQK$:1G7*~Ço#iX{@,^>tu}#a~=k?S=WUBTh',H4?:}nx!w9 [#}ݱ~AxiZѝѠF541d:OX?Rvr߇S^_|3h~}΍pyA9Ԯ@AĊ=/Ϩ 4>_|.FM5|C,想z;3{? ./ Fگhp;%6-%.#$H4K; yIL#oCB [%y6t| bBŠ}|t:k aGRn@pNtm#AtwAB'_yn4#"F<N/m4#"FxD#`@cT3?Gq:1m6"$/ 4ȑGj~<_j~O~</$Ǩf_!/_GTڑ$ 0PUyOMMj;&H/KAKv6D#`O [_ejgAIAl8 ~7‰Lԓ"oD-pNnH#htHV.nAp=t 8%}ydB.m4#'wInAp9Q6 ջ}hGN hPH6o}4H'4N|NH4žF%};S/TPN-W.Txn? IPK0>пC{?4>L^#IN]?y+WrHdB򥧀x$9C륗@w<2}Citw$9]£ ܄YZ<>]H#xu:n*8/t~v-MF:ƿ+i돵lT/jNWķy+_Dޑ>.3 PiIRk*>{ 5ȑ:,/a-yQC E}|dJ]+H_H:m`h+a>ҥdc{m# j@0WɄj҇nC ,p@吾l ~|mտm 8׬/8@pܤwԫ$A5!2Dg3T1H6?&&}?Ҥ1T1R6|m6sl &}?2>7?h} c&l MA3A>I`c c&hc3k;Ǩg >IQ@PL1>7?#quH6?f&}?CzRs@PW!}Rk;FJ7 g~3k%w8F8TI_r1s {+|a2ړ C ў$/jX$:C ў$/j،$0Pn'IA=I*סhO jL$wԟ3z˃gBRZxf$KP=>I*\U"hނIR+F{TlCR+&}T!Um>('I#%C>I* IRQX$#DH*:b>xCDNFu@ĩHF}PO"$ IRQX"6$~!bGRkF}Tڸѡ $$~PO _~ bHnt('I IRF}Tzѡp$nt('I IRC5K 7z- 3D|}_7:7 Iz z ՇA.tѹ|^ڍo}ht#lH(Wz5^TpC~@O _ 6=zZګ;5Y_!}C|`rH_^lZ+|mտm UcN} $hpIp̠~LAF~g+Ix AR8]^Ш*i%+j/>P|*)NF;Ap9^~0Rԩ4t4ށUOk?^U~S?d:vG՛W6~lv__C9h}$ ؏{w.tx=QJ~ӰvC>Ut>tԦ_$ olǭUUU%9C^_^aUJw.W$`È_w}u%u$ߧGߖèWw߃D*l'I_vUAwTj;nC|7O;3XWgPc+\5F{?I51#)$|&: \'|({51VEkt ~Q515?H_?Q}HN>4(=}}炄6߫QKIP⥫~9Nn7߫bC{53Vw7U+Yurdh73TStijGVT. W3ThpԦ8msijGS &kcj;'dėLv/WN/W3`>(g\h=_ZyT8> $p|iIR $02T'xn}4H'dKnF׈_1?uLp}_#W.Tx.I_f*Mpay>298hOIN+P7)~F{o$L9?ZP/_o֗C,=\dWo^eVn ^z13NFo~ kBuͤ>#[_tW4U%9E ScOw_4.X_ 4H&T _TPAI?j*ݩ.Jh8戯X#Q}\z?}3^q755Vr#&~,φ䖪ҡY`aU:Zb Vhgtr^PvS Aop{"u.g[ёd}7O}_{6S#?zJ*`O[8PIR?N}z tokD*Ij-1~ ɤ*)#BU?~UYO|9|0[|/>Xp k8+6-|>8p g8|pnW N{kԧv >ӀStON? m8+4|>+)^;| {AB0^:pnW s*=4|/>c@ra4Kja@Ova* ht1^YpC dq|jXoX,Xzq^^ :6Ԉ)?ju~MS4よF{a=GojW@+uCq)L\Fn',) `>5)!E8|?u_vH֟)?j-_o4hIQkzό\z T~Z"|D|z߳5w,8Ur}WfZp]G D| g XottoQ.*[lAA4mmAA4džP=p`az[GP=p򣾅T$D|=ֲxaTto5*j_okTNԷpZֈ*'[lmAJZk z@C5G[GP=pҡΠz@C} ֺֈ S:Zc|5*j_okTNԷpZkԂTNX[P=p`5>ŸTF|3|O9Qdz!ҡ֚Ok@{Jwi[U6|/>Xp Wl[8߫v mWN@ '=C gS?%9;|,B#mza>C} UINeFRZ:An 8)ɩE"I"]K=%9n}Z6.GYp &ʀX?4>~nD[ !m&ӈ973˫uk- Aԓg+p?` =h惆: ?z:hϗV i2 § jehqT0D~h`Cw^<ٺ V˭l)jAxAG| *^qF@#k|QtjD{Tt_|`δz/Oԧ1j$* 㣭A:AnPMumꧮc$m ؝:p~O;@jɫ#/$zv}?$2HF|jSZ#~o)i?7A*[v ҝ߅YjSS9 jSэ>4Sѿ?W݅;;nSKo@wJwH=]@H{6Ջҽz//kS:oߦ~R.=6l@{JwZhPOq^ t_CJwZ?ǍzM֦~z/oS{5ɚ$7/ApA0Swߦ~:|oׂ5A/`u7T1ֈ[᤮c|@0p^cÉ Ŏ ܿwAmꧮcA՟Mu bmꧮcl'oS?uXMu m*NNG6S1F|O] ;oS?u`?zO] ;oS?u]h?zO] Oߦ~N1qktO] 8Mu uj*~ Rt?uFwA,Swߦ~:OE~:O=Q5o#>.4 j9O B yA0SP;H^cԾ#>o5x7ABwv }?1H~^n jVꧮcz~g4H}SP;]cz9kпvǩ]~G_FNAw!ќ^TS~//m v@ *?~H'/`FR~ $7/`ERQ~ 6$7/`GR~ $7/DR1~ r42L2F| *ȩO=A3T r!EERQN@{ Iz`GRH*VNRh[砑/>Z=_gT[3 `ag  V$ nD#>ԯ7 ڷ5O$W :?>o _56 *ȩ">ulT0#HGVgk>h"p`h!p`h#p`ho p`hp"nD#>ul!Nш/5֩0;P#oT/*XTS+`ER4ؐT0 4ؑT0 48T0 48T0 4ȩӈCƩH9u5#0 4T0 4XT0 4XT0 4ؐT0 4ؑT0 48T0 48T0 4ȩӈCΩHGn`hSW#^|0`FRo`h @I0 4ؐT8@I0 48T8~@Ioi/ NFtaAN]x@{I@{IC OPG#mk=h#p`hp p`hp"p`hS8uq`)j_eok:h p`h"n7D#5H*o_PÁH*o_PANF">pjiw^C#k |z`mXaCR;@/!)ڥ|H ߉ *8TN}y }A:uIv>;}Щ3H/t~v~7Dt~O׏m?)q<鳞> N|t_ ~}w^_w8`ԇՍO y_ڹW+oi rxFRXݘ)H^H?Wt n}}a/0SOq}% +si}Y kgOҎC?]:+@k W-">XGʁ">ǀǂԯ@NAt1`0G!}? ,(L։j_'O K?.SPNASR;'OYK?e-SPH]SPNASR;'OKdSR;'OYK?/SPjSPNASR;'O M??6SPHm_'O M?6SP7V_NMD#wR4JhNPO=O=`QLw~ONYM-SVS;OXO=QZྈcT3Sqj~2O|QOW։IeojF-8шՑ'@~ ԉ@!|[ QHmR tQ ~~k>oIm8#)NvsoJU?XM)>~VO|QOډt1@zcT3SOyp}O=։[QjG }?&|~O~O~O~^E|~N|_td }@K?_'>1Su,=Xp'ώC?H;>[ #@@O7ʉt0Sz: @?8?~1O| c2?^bi~꿙O| c2~YO| cf;2~9N| c2~꿹N|EN~꿕v|V>?o[?ߪ'>Oډt>1k??'~5N|och3Su m?j7u|%}M;> Xփ5}m5?C6DՑ4D-?XMCH)6D#9GBӐJ4敄8'VGVSo^IhR twvzsWIUF|rUw_𽕃ߩX_ n:tKG??v<:#QԦ;AՓdݿホQgul<ڑ:-y}sН:P\.;R~n?zװ#Q}\z?o {4B~TCm?ձ|髵~)#!ToX]_CR?F{9H7GTF>ҥz6:.oI!t+_uHI oy~hw!t}mt#]?ToCHRP{ԧ(^AHϷ߃$uy~|GT=t}[G=HQ{>r6d HaX{>rzmM }dJۚAșb|߃ok #g?|G?j?|p#gG|G?l }dJa}V=H9Sa}AȏϷ5߃$ufk#??|GT5L?RX[=H9SѶ{>2zm }L]u߃)uy~hkZ }C]1> ok9Q IoؐT^=)ڥ|>2H>8T!L?A>2H;G&Tc6:#m!?R"V$Q!bCRF>rH6:#mI!+47TƷ1o:R@ }k}|C@>%Am "Ù$!bAR@zSfѡp$nt('IE;z@TlD$g''I6߳N}u]|O[$`H:k l=ߖ/DlH*PO 7:AԧpyC>I*kPO F}"'Oѡp$??F}TSnt('Io>F}Tx} IROѡp$^I*PO _j7:$pqC>I*iPO _Z7: Iz @{ IRF}Trѡp$\ot('I/ IRF}Tѡp$I*PO _7:Wڍ$p~C>I*ePO _7::D0;pql4ύNшF['hO5RKtK ˁ:?mtu2F|Lm7:\:D#>.n %`𿀀T&}T||DLI?ֲ\P _eS=ԧ(^.'I?2F|LI_M$|pqdidHx^{$/?;q}Mw͙@9`X$INCG,_?{F7Փ/: W/tɕ/CtpO_{Yzr!E_==NWɟ(]>r)@]p;+Xy8>Fst Zw-s$ V+*XtrA|Tr NgzOӺbH}-@ݘqc?2uEbG=9_5HtνD3Hă*1Is#w{ g(GwaGg(Fg(FwT75>Fd>FatpUKy賚lrK糚mpg(F^waFg(Fg(FwTc6}>FA6R>F!6R=TGg5(Fg5(Fg(FwaFg(F~g(FvwT#5x=Fd*,i^n6:#r4U#ȳ/s7>_8ռ42#wtP4;:puah+Gj}M܌dnD%{  ^sn1(#0H߽/Q?; # hbh-Lb=)<6`ia,6-,/oZcNX[Eի_i[;:!vheY{NuX/F^ 7"Sf;"fŚ"jz//[WsC 4f ~9; rrM,Ek|`"ӭF;P"f| hu //VfPHH+7>~I}ZU;Ԙ/?+w1s\_?85C+TEVv`EX?~5O(E(p"sEO uEj~H_?=/>~rȿn@MktȿfQg$_{8s*9;cDZx'Ɗ,֕S{\}<#Ŝv}#$;*3G{/hwjs 2δ=B1Dv()#P/=<E-m<ܟQǻX6ϻגw(y%s$Yz N>oVܤ׊seJBg7U4IKYg*5+ڐ{jxZЎ0Ofi%rӥ}f6\"Mr_Zj/iQUB?3*Pz (ciL~ t3uM[Enxs]cES;Pnk~}<5ddOڨNT|r_POJ'3LZ`0ѱ2*xi:,iQ!}$iMm@5LPdi&>ZܰT@/XʑRQ&Guu*4֌(zҟ7MՎ6giX[@w>u >5+z#珰]O]Ȩۃ8DF%P^hS*ܓ \'*nK+tp_D~ TLK=亢<7b^+ ޳_,uI4+*76$P=Ē- n%T_=*a(Mrz4Z0;*(oş[yNHVgR!t%~Fg]bveH*SY\D79;P_N$y]ybTz'ޘ%UtEoCp)-˲S7$ տf_+c{_z{4~+%BWޘc[cM4 \*eWq(hNpj  Ɂ<<=@8iEE5}#2*$Tno r^oǕơ|E0 H+>jamѷg[ZD [yj%o&#KпeL?r5'QQ:s$* f(O\ MҴSIfAu%)79]yqV 2WKW)rCn~ĝsoKR%tyyVR1GV;R_OTMg[]QCFn%FV\w6 $wq(;RWB BYs1E+ sj@G3"آj̺XzLB~E?oiWӟRpѶ TWf TthR@sx 4,&wϖ{R&b@*wB=](F=vRecdWFO)yS̔ײ+rvIO5 vz=r\->b]l!Ңt.E]Ϲ#o&cUz ju18J9#ca.ݯ+l&8C a NN.^uy}ܗzPa݊la"PHnN-5X sYĚrDQt~!e*?GByzu"H;6ScP^9B9M TrK?jIH?H OC'qW?}ꍔW<[mc#Hur~FB 騭3RHHTVGBz|g kw$D1 ?2~FBB:EߑUi;~j '5jHHHeu;:`h#տiQjC4g #?"FN4t0폘\gaHZ*67 Uui }.6؈>[Ƭ%FD4', hD~уN?[? 97^8Dj/͙OcC#1]~uhUYhzLNfI%7Oug|$R$i:WX(3ep93>,4Dns)ȿz1"_yHȞ[Q<ZxNiTwjcN=de]GFpqo,JgMtWB)'\|I+ ?[ Tq+m:n5F+7C zϳꯇJuԃ:#۠u\~|]n.m_  PZõR޾:ݦ^7Z4 ׎uh׃<(SRtL7e210ɯF8ɯ}5M~E=mP`ɟR+TĠhmM&cSV&=JH ǼJTN1+Ռ <ʢkWC!77mox|LnPh)ה*1IŰPMѳQϼ=6~z7- X:$7X,h@̒Ig3e@EE.b;zLa$Pѐߴ}Wn TtjXӶU8BOͥC‡ ӵs^HG H6 7j> l!S~pn*GB @Es˝cHHtGem=YKl+Ko.zZN$޹9*5-+[TPAu)NWҗP@%,PՉڂ9խ3|^s3Ohf>*]AS_.l5'f-.ڠI#d=SP2-}*pM)%̣Qyi͹p0ekh);3H:szlLLl 3JTnkd)4X`]b]9`6e4 aDǓSU|[Tr9)͏qbNY`#JP.i!AK^a<_.)nEm,\,e(o=4svԌv HVfZ1ܬ/@$eӲ;?jUߎ:-GӵZ>G3XxXm|QQGEߩvw^Hwu~!6(?=X;q#w@Rmܵv82*7F.)9L.sKݖ,mصsaReQ+:]#܂UNV=Am^7ߌb1<Cc!ǓK 7$f3%@_&ŸȃFC6)wzw!)G4tY]bwV%OfUN?=l߉*E@O5gemRP~:kPYP`swNia$PT`r k4W\Hœn T0OƲEz5o6 B_i8?PpNDrH"-/dTBAzʻcX*{jTW?^{-ei*5“nnI*IWc+i]顊m=sDZ tzyI\TD*ߋ%FZ~' FJ 59/B"1kB#o$[r'c&lD*xqtW H;D7~q4R_ PJ Fw#-NS ՗+Q$WQ!5C jC4rS'N~HEN nĝdi;(3$ی;C-l~h7D (^Jh"u˸Ta]~iҰUIo&tUyf j}Ev,C:D?yܠJ+kxfSKkᚩպSr+A*g@S>䡣¬SiP 1x2Ȋj򇖝ͧ^ 0@bJ#W"G҈XBJ.G ׮ Tja4ʁ41*\.xk66/ Y <T6C@!`>!͟&V1ܒ LyΎ-h3称[m|(7"DMhTܖ;8bdvvm  NY0I'#m$W 6E~v'BX1l,Ļd+b&:JŠO I% wN.T&5`(iJdM>aLGK#ŗ4r{G(M/I$&ܡ>L- OF8?:"4Zay0GB!c'Xb+ `ER_.n!1 -&7" wz4D*~ztD*|L33f3:bP0\ p% e~z`S `|`r̫yDΚ1j0/?0G@DVgph3dTj)D gcR Jͩ}h54qd}qmC0g?HciɼDRǵK1UDfGԝ4!٣8Z"5\("#ƍ> Z'K\h^<Bw љf @SYZBȩ u"B2,7d,,_>`[/ԶCjHЌgmѷ..M]Z GT#wiH r%8a:L,ھ?hчq(ѧt/PND$r 4 xpڇYPnAJGD?Tw9QF@ QOӇJ>M"g8uDKaknvBA)IxW~8%3d 5x'>B 6Ƒgd#p RawF$1]Oq&۵!4xpԒ9M'aUGA=Id RAi$z;Y`f cSxq"HcNL'$)9$$H7bfZfT QHb$8>byH6=',\^0$D>M>" ~?(3a= A" +L%ID"wJ o 4D*)z@FE*^.z?aJ+X_ҘV7Ǹ}b1P- )I-T] _hR+lh?卉sĂ銚Q9Ɲp$&?GT&"4diW HNHcT|&I@Ӎ81R8Ls#R HH[*I^МJشaԉ2Ghe1}'l3LW쀌ɑ=B'R1sNa!H ܘFĕ8>1)X_(#(޷nQ6מ}1OSIIГE#!AKnV13 ,+ c8q[X@j~RIOpGdR^fEXv <[+Q/  Mfhf qE'Z 6f+W?'rc;15 ̐oy}C$jDÇV<`M F^sFzCsVvM;S> Җ PB75@F^ܸ7B.G92p&$##iEaɥ V;-hBa{&W&7bZ8@NC]ptA]Jݠھ#d0nd˓; G:?e LQC0ì5MkIJb0wJͱ cr?1*IAeib -6-,׮BYF85iӄR L0'mzOiQ2K`H@?q q'&aDcH0|4F;L(0wԌj\S #Ew >I(otԶ%\@J!$#oHi]\a!,7KՈ#h9l|%FZ~"IC/7r|4.F<dx1e (-3`}/@t[3D*JH<>ppX$+@#8%! e_8XBx|bҴ\=0DnV @q03w@ }X^c$Ý@#4<Tu `Bewf'qĝ 2& u)x7!hNrxpP58أf5a{8rOf#!RHpq0DCdj[3<*[Z4+5JDG5?- !yh<27F7%IaNϙ2EQ{3Ej9т"4q xoSK+`cdRec1^G^{CGa }0Z<=jGSlen mI./d(cF 2_p]m &3GH!PJC&mt43õ ŀF$R}*>; OWlmlԈإHnFE7HA{ EKW?Dj2 X^wE7<tVE-10y$t~wM>8ePbA`i_3$m8>F<@&"Yp' kL bE^vQ"e(F}?xb;C!5xbx@=)G*F܉T3(!@H qEv# qНjPr" dBŝ/OB-5 auP$CoL { 9 Dm?L8|Q<¥q;(Kׇjإd[t#$P?!7ۚwB %aj:Vm͞2m>dxEch$X"JA6%F8dtXd۪$~$^is(g2f4Xe^P;q@dFKf@qh1?xxCi~D=i2:.y$Z I9%d&,-SR2T}2 MQj*DB9O ΐ'm=3g f!+]!I.'2G+.'6/5J/r,@C"DN|DrE#HV#gR>2b&=0qA25h ˶?1|l؎B$CiLwiC 4BP $1jzI^\\ECB CS\hUDv cC=.If#{>A 8HN#6t4q 8*ASʗ9OM3h(f( .`CQʳU?YXcd.`'ia[ɫr_KHS;w0  i9`.# 5 5tj.@)$n\ 0LBDBq٠7 ˧ o- DTO2\fjD; 'ıM@" 6$RQ^8H!9ᎁH;1i!@b"R h{>d$RhA*;>@/|!2{wy&B5 $7p p'&-H D*܉I  &-H,D*܉I \bo.i ѹ4>ď .q%-Hpi#J7" *"5@qٴ!xAcX 9r%C%WV.pHKc:04?E/W| : kEv ?o0C#8H?h{ELb&Ht{Mfo-ۗHIF4y\ yGs8'c_R(uw(yy}D*ɦMEХ['q\ږ~T& 7-~6#H1=~\I Ƈ`cRI? Y#)o#!RhK1ج>$ܓiyЂ pÛ Lr5aG Z9oPq'47̓,JzGbR1zOiXаQ}O$6}H1wr34=x1wy԰P" v0wp^cx@B897ujE|s%$@F/X g=U Z7M$n\~?olZy\r4,+P[ mݹnSxʓ6;WQ_s*@G8뼄<%: gb/N cg&5ٝsQD/,lզx`PjɉBN`34mn逸4vKFj.>.>t d8HfK"w?a2MT̏|ݗ;H&< xYDa:8``(VZ± #МJDZؗ&.K@C'h&, +GD k+oh8TcoOۧ/ lHt]qCVӒ̰Zr;P HXTaӃ}f_3EMǿKT`auȿ/m8h0}eߧ>13dBE8.=P 8CͯϿStxlP=>?9-_6ڜ'`58LNWy9X%NQ8ˎ!N+%h#L]@8 -#J Jb90@(3'Bq|>((+4kʆ%\&:x^cg\{~o3E4wc Cw4Ac`kѯiiio3Beqk0@ D}[T<.-:(q> 9HҲ @E:,s^Ydu2UN Bp%r͑Rqб|)o]!6(&h/'{i3R^oJ)+`a@R-?Qo#7y.@Q6QmߓX` P@I=V@{Z9 AW#Zh( 5 )!X/'ӈgs-Qºzx"Lw_;فCnDKvTt`JM8P׾ GWf@5O|p7,/V:xyE(P=  Q&E4D*j}=~%X_D3E2PLՉDP@F@;("~5܉+)"RN4 w)&E4D*܉kE%"쯙zRDcp%fRN#?:ѹtq%vRFA+)"R3@,* _y SsC>9@RĨ.zNq/J,D*? W+% .]J/_% ? WI<[VG%/G"vLz:/^xD[yJG} T|F4.,@C TF!y(?徉>g\Nn,%J $x͖` `z "&"q_k.SDȃp ag $/\%R;\'` Uh4tn cH1z{uPR RVuNZ-PAdYILc!ev XëjRR4Gh]々)`{P GB8,*Ә6"wIG!~B=\ߊ&4yLQV) J9WAm0#% @0eC%6B\8?toRq@C2SY&X( *h6i/=fhPtFA1Vٯ/}NQ7$Q$P$*" :I܈T8qD-\O Fd7?L@od(a$p[%_ qd! RxC@DEח񆀈p H" %W^Txd2  3\Lܸ$7_ ܸP2Qpty+/)nB^hT2xnr&O%\%I" MߟI wa'ȿᇀHŋ$P ?$%ĉjp"<1\< 6]G!qb6Z\p#8Cr]p* f?/v13nܡtG ~`129NI.F1`)(?S:DC*IiN2·#Jԥ'N&@LAō(++_8rӃ!')gsnU &(O]U[Z_oZ %;3x,z8@8Yz %JKK"gRPmONVkj@Ȁ4?g  9 !XD8@4{e|G&MAZtbyV/V{-Z[=,ڜZJ (yVfhݑ* Tդ 1!J3;S֜)KK3A0Lx@dPݖ2#,KϟQfs.DZ A@M)1CijdTCXK`Z12!iSaO#ﯟs =M; +B9"<~? 귀>? USN-:߾fЁbP^i+\`;DQWD[IS@O%Dr!>0SY/Pp<*ol 3Iٸֿ!x5u\}s?"xh;muxay:R,͑Y˃˻l-DCoFNBVm=䖞)ǵ+D/ p@*Q+^u8۔<7мio{j]*h.jpQ^j JLSSIprb 圸SaQBl_uY$:^o-^Ԓ䆭7e˶nBo$ $7Z}s !=4\vK$ 7~^ lNl%0Utp= aco٥5ֹ {}q(xC4:#PߎrHp =SYGg_.Uq~=.G) cOo.YBE__*"o!)"g8pp4t(ץ5[8 "`"RaoBݵG~!0UĈeH 6 _]66دǥWTǛo Q Txt6A2`OrAކ3;p ;NmGE:%|}ƥrGïwj =* Ɖ.Ǜ女 N(یNG~o>ϟ-`O%*|%#A P3:0?.}i'~ g{ԦzcdW>>б_E\\\mLh@s.J@w<W #0 /OfGi] PqŌs%7D- ^:vL.]:\\\,>r9k7Hፔ$Ym?0s)& i=\\s.ȉT"h{h_/ժ@%J_x)RM-yTOPS++ 3p೹jhE:xMiJ,}m{C\ r؟:hA[#-ơZtK_*x|K^S@9GXY1hȡ~kڿחpye=ORjy{q ֤&0oB_D6E-?3_9tUvƸn}s>Ɔ`"Z2@(D2<}lG}8\R> +|4DxBOVp-rK| zJo+-,Կnpђ y?~"fB-Y}xD„`s wF {>D-9#Ro-qOڠ}A T9#a%5Rq8n QdpE"-81$f@<}ȧ&VZAP@/یćLD* ho܌6p}|Ic>йH>?tMWtZðǍ۫-1Ԥ -p@3a0L軕0NAH|I@H/d !·cH^0ї4UaM+"׷'>&wpJjlP2`?!Ʒqaά=Fml`N." A h +jD0TێpL3D2٢1IYn}usvcQat1<̣)"o$[, e?v#w@(]ϿSS;KBBbMa DÚ JcB-4.npl6cemkaYnW_;,SCIZ/${^N%8zEK{ɚ˗B`ҳfSYzIpuBp i5mijO{fAc:Ү0]hM`WS0ɉc|ʁvɧ)gm*d&uMҚjU,W hvU@]ob9͞F=a/Z]*G~\P%^݁6MYL%~ٽ&ŶSi'pWJE(v 6bAyy@\f?kzz ?ǝG~ COT& B@DuN, fDK LS0AO&{i7% i:Jp}K)^nAGDni8q t#o!F$LF6l.}h3-}9醙?LC>8bL#Ȱ`MAPHP^c%4i%b&8y8_k2+1]`bwrГ.un7\v`s'ʇ4FawOa:9$1wb "A'w><'.܈To wb@BGxA 72@0&""vW"v8=2 x-GR0]tgC+ZBhOI԰q ]5_La:x9CXQ 'Hw0?VpZnzX/s R/`jɧ!jĚ2 N(aT֝VS^3"= @)"&rR nЕN,ŅT.A[51^uHѰምpH K(]~jٜJp81&.$@^zM 108hZChàu(ĺuwPK^ ste$#hEу(AR®J,6 Tl +k;KsŖ?.N ڵd<ւL"h@Ӎ6 N$G_w*Mg2fjglVJ$!H /Z Iu*@Sk?mվr41h{_ wWލX ӋS/eg⧼/G2Z`H@"Z:{L;cdA4o_4ҟ9% cYnuQq||k/{;OϗHoEP G:Sq_.b>g iTѬU!-Fpkxiߡ6[rOfD";a{O$yE"A\'>rIrX/Ɍp꜄$Ng'p: 3Fx-W'aϾ'tD*ƃd0pهI='C'd0I {+M %QZGBii^F᯿a ?R\m?MMg  /-p +k Y>'\IF,Ǯṇ Ets!ޏehϨuEPBܟZW$(tP:`]%ePY[=}%P;ۏ֙ZHsSo39C)$ҲpigGMwN7H쾟ڂAFzF=qeNwTopߋwZ=9YtYzNOKo]l8vN;>/ێ~xՋƄechȲ\74/B`^Jsa[}{#(-w9 qlak<75-~!E=hIZzN-=Ja~7Rn)·4 E 31AەZ{?ڱ?T7~C )Cة9éLߟ*>P~eJԞ~ ~[ɏ 4D*`(Ƽ{C3t_hhiH_쟘i1n$:A2ý %9ہk@Ah/NTŷ w=jJWŏH?|pL^6ǟF`S^|9 I!c;%ہJNhpzڷti;Q Wmڂ fz8Gs?%Kp1e mȟsĴg1^TbI*Mۻxy!(ۍm2G[Rx r8xJӮE %$Vc 2p8;Q^[IhI>8S0aJ- R7շ2N`j)F,7*C ;kg*{ڀ$O}N_+:]dRAlF*;N2^JdCu`X1ǿQN9w4{GhovK.'/EVdcJ|5)yGÆ0H t1 ן=w|A2oW>KFҶDa:С+ sp뮐#hZ硦M,=#3%alV0Y̿f rYέFktUO, KT.ma~0nL,4_h Twﯙ_yjWJiI4I6q9Cٝ—@Ӆ/aԖ54=ůiZh& )FJI6KlJ薾/JۆQ~/z[~eHt+˴1XTʶ6-{ SRd8n]MCm`Acz.(x8=/O(b)w[EƆSD$yKrcoIxeHy4}QbvEB7AJ%a "u<:B:"tB )H3ᜃ4L" Skې3Gv5,+yq E6+W'x49q E$RQig&PC8"?h{ۦeP=?pc@> xV8M~i{ˬpK|^Zԏܘ1!tԑ\xlcƗ:xöf;`jIۍ y3 E;DJPl`%@/b+4G/=,TE?le思l& %V&JbL%k~;4퀾+\J DnwC bu.Ȃ@҃Mcp_ -v$=L"Bf$=jlXU#PB:U"I`ۼIfIN=묦4A 4"  V]:;6.K.t{h~L2TREEw4vx ~d gEM7>^@ G*y7ylm(D?{* }I'@(/z(a*2"xdJG/ҮnͪdFⅿnlbCE1%쨨j> lGC7`{ Q2ET8l8r`*Kt l-8SUE `=3oLgȆ-JȁgaBVlM9x"Qhr(!x㥄I`2T<)"P!D_fg ,8wAܝXCm7tb"R1 X\ @iU(!B.uY.ʢI1=lU=E9lp,l-1 S;(&6(%c\#xPDIt#-YԪX/`^>'>Ƭ]\(n %b%ߓ8'J-"K 3Q#١ItcnOkۭ++ Q+a,RU>18yt7d? "Q,\Y44>D՘rfqZ<"B3` ~^y\Գ$@ ~ND!C˚iTmdO?2`ִ}T>`lQj e;tT !ށ?~&1!?mX5]z)?. Ci$eR,hlHZm 7rڨrju;v)ҵI\ڥ%9iQ઩N7? `( 2+z =]fQA>O_> ;qC*W.X]va7)"(ԭdsSc5pD(2uU$ n){VX ic hB,7HO׾pϑ/hۂ[[|myv@ wfRih$8.}kFܰʘGHd9-9f"=?}ˠ3ykK@O[? R=MpIm ~T+ՁvA*rG8d䡹ӮyėHEZ(ۦd(sy5$xKQwtӼQWnD* %+ w(Z%)*W R~X!#r1YT+ Xƌg0Ie?ݡx>A6 Z -9~h ϒW=[^-!'5^)ZvеHgGp9Nz{lXMkrnm|lⓘWUmN#xaU}Q:9Yw*vΨSLZy{W[j5KClՇmk;o+̧!Cu3bx+jWm;GϢS{[cע#k -|g1ڜh1pD)?\NS+YD%[Ovͮ~+]n#O˵rt;tz棩֙uifܽiNMC>cFM׋%Pu_C74)r_?1X9J0y 骹Ɇܚ/;ru^ ~A{m%t]PSJS:#@~M@T'u{m%˛E]󦧶,uo[aQ/çMJ r~d%_)2M>ڍg8T]vD~ 9Nj,7~=RJ}HM@?SȼTmL-KgƪRJ<ŤBche_8*q=/$mAe*YtViGETv=*˩T+|99*oN3)Bn%XpW$'^э܋6V&3Iqp6c|Y a}CYpy ![9+}*dۜJaB.g#+Va3gBRՒ3^ J;83,Uj<sm ?4O鲔_Z!o .2J s{,THsC 6kVHoUn[|nCBS `*ܑE_5$P驮?"f~2 Y״:msj{[Q(ׁ:Kk@W5~\LZ&#,on~7:cMKfCfX0YJ_gMkWĿ͇O*GB>h* ?5poGwO?Pt U`߿nz G_ fztpo=Hxl֭½_ 5*?+U,PR5Q]]ܚT^sD+2 : g.E=KW^}Uٺ Iu wo gx-~%N핪M]J &*GcY )jJB5k?[ OGʏOt|rAcHY8Q *e$>}7q8_Z$=tٝ))G%r uUT./5SgVw騤eI!õ5_K3^B\G");qri P!"e7-`ݩ']Tt ԛ_un')]N0L](G`]Q 8%tg; e+~.=mΪ;ҦS!ggӰeM}2t(WZ-U OAQfͰ)%7l-*$]3\nS/+=6|zMuf6@b z /Lo^zhcA|IǓEJP0Pw•t5nNy $MݜW=]j_w_(Ìu;ʴŐ6ӓ_#%|qt(" os>^̙b =*(>aQsH5nWPj'WD7i~YA)ǑR ;_yih`qwEMP-wI6 (H^{Q vhAALD*r#j)cQ <#7~XVp uZ7Pd6d|R~PK8a)büh"S# L.jE{jLTY)WǑJ~B10YM(3ӽ21ƪUKG}% My0z(5ɨrnI9|/D*X 3R;ԃNL+~[2:|)?q|dr lР|CD*ܓb͓Ȣ< 5;Z "1+-Yg Rj#Y 72,_i?^v1fK6/@$O°b)TĒGkuQþMxeIH2FL$?fny`-sp|Œ雟nsƸx&3C/H^in;裛m ~OTć#?W؇ 7cB4maX>kf/\#ю}b!0ˆM:ѐg]ڧBfҏR%,&GG w`H"ד D[=}s@L$3h[Աff#|?kK9J\tgpҡe`Z@"IZ VqΉ u$ Wb": 33:#!8 UFJP+o 2 2*%waHp&"_YIAULA+$'k'/Tuz2^unfaNi'bT.Z4!w&tcJU|.y#wH'+ږc$Xsz.xeg4hKGӊLJ^^YC92 ( @oNď@)!nrJظ݅އRf+yEy-f&y W/ń)b1Lm@0!ueu T {9(14;M,gfT,OWSFh2J+8Dy/dot۰}P>2]|r2@1KL-&a 3=Vf#~l\*6–dg>cv~M$,23R281e~hxKRܒ\4Lej0/4!3:.&ģN4T핔4h u~(=`FȇQxiNMm³YT{*FrLX3} 9+(f?旍#Ӊc +A;M7*.n$a:I#a M̔୙P ߂I9Å6{~6` N9 M)q h.o\QYA%Ջ05f:X3Cb9 h$´3PӍ03eFx&c`4OԊX2ݰ{% ({t dN_柣9 @w<'.uD*|;& D*<"&g"RqWr &Hg$A5!g:3S 1~}WL7#i&^0JaeRJAfX'0pc,cR^J5}}P(xO C6#y#p}gX>t3|e~((9)E3, YCڇB<H䨎%Prg;C>~ѹZ3K>f:Զ}r|h9#a nIEQL6Ōd8uD7}i %C GA3ohzJ##=֦ ?@g~U|˰CT:b]<0(B (uzr;EcsU3ceGM6#~CJфG$! I^Hb#~p Zj.Y6ڣT4DTzeV~'f^ZL|oPQbkH9aCaeC!.QFl CJ)߆ OȉG5KE6ہǁF99rF({z<)i:$M=ŋe)Z׿BִOr9fj42@ +mkI ;o&ENBoKԲO* 6_A/EsPvW ͕hԄ!}@]fRrq#Ra>'!RM Ty@9шmQO~ʇPϴSyGm8QcZTxHɔP@vyeHE~ LfTH`"or̝k-n_YnⅣCKǰi3?(%>"\c}rΔJ:)+uƤc| 4EWn*%H'H+٬VB&#$-h ޴#-%YN~y"Ȧ9!5Ѵ>>J+Gn#!gJu@śAlrW=r8trC3PhD"w2!+OEҒg]^#YPm?`p{OF"V6OPL;'Dy2J6uQ>r CfR}'/(9u$$uNs =.u-H"k!*fR(+;MCuhh]+R&J/ڳ2( \UpJO]t4Ⱥ\rU Ru|Rqv8hfEc*!k(ho694?&uS.rhf[>fynIѕ4#/{iBk~%{馷%[ 3CRk|^hY^~Q2G.5uKtZOG"I9~qg/ T iX3ȟbYt!R1 A3> dɅT֔lD'Iݍڛ IBѝsvrL Rh>8 o0hE#'o193" dExIJk\!s;5P\C9iz6o7?1+WX#U<ނf ^`|^&b+)^3v@z `ʉԬLBb;rI6{mō9᩸b"=YE/4pf'bt[@Zsd7GIޏѡD+R$U?wR1ԥ"D*<~fViaF#t{u"/,'sxہbt9$C5|"?$x7zKWM\< IqIqQl!!N2C=gXY;^_BQhnD6^<Gv$ZS$R1$/U$W៝ܝ VWASs/V`~1%Vc5քZVSC93Xf;coP"#+ SD}"7L*P^uUrFfDvpSx-fMvځO Υ|`Ia9¿~A5ec \[uaj ՟iq I c^>ذ!*^ mbJ$}8 ~XBJs1VZ?˱rrմ84of~H(aӸR j:$u5(cJ^c`MA 4㐣 6rIE,ńE` 7ӲΏtp&JN\RQ#է<#E4Y7cyw#1`ФLI(B4pB˄i$>dHs _QELYf lXæ-*frxK0n_z1@H:A8SCTtC0n~d__bncI%ŨtJe/NkM$fnfYŭ)qUf LX\abO72 5zyOJdNjȎ+W 2,yyGiGԬJ*Zk쒠t\R&_FZHT8Hrpe/x0T64m*gQGsE]9TSiy  3pUTTN1 OG0MJd[\{c>C2NB̈|9x8%رLu|xM}oV5(PJnͰZI6b3&P'4d:0S_zK} zk=dKIT2x8QxWB:xsh'~ uAL5 21UoyrI2z|!jA. 74Hr1(Y>B~%-&9}g;l|R^Uo(g)i%bO%Ϫ7p )?Γ"v=|aNgɛQ把0Ɇ4կ 8Ps4GtժEZ;K-`h2{E8ZZ : vr2b%PJE BEP!Gȃ'P1dYRZBQiu_ Ä+hc~2\61˜fe=41?N8iUuc;02ѭwʊJNb"ኸ+y 31dXJf cCNpX>5VXӧWt͠'RwJ ASm5BH2E 4RW$L/?qX*ƟUaYN9!6SqyDNl;A/ @ .AWePBbQh$!1\GdP5(R-E!@s7||Xnv!fjVc*+phE]A^RRݘA#NLR4K oiq)A(OIp}P$DTnЈmn:Ƨ[Ҵ==99"D- J!3~)֖<[ۢ Mn>yzfRzןtw;q׍Vsu1G8!d݆ӽBYoLM_Vx!&?b>h"xo,Gi>W*!ԚD2D8d$O+E5c&]$>Z'4G} FV7zٰT05(@$])9ɍ(uBz7KM8ͧ & $2/ fʫY{ (Y6pzL>ۘPRSHzM٨,9q#C[)n7Rf@aW<ѩqA wD?]J*a7/x+mPosWb 4y E +t9E"kH!ɘ>+p!V99-`kfj:"쁍~ y=m /ռ Gld̚h4>nTէ6`D1D#reG5|Mu ;E;ghzK87g:"gB.#b}~=9X.A5w5/q7纸d$I0G()n>0O 9R+NSJK79yFZar>?r+:=IPHE9";mC:z7\Wt RϟaXga8,$'pӆ Aqa˘F6jL69*j|!|; &P%qF[ߧIZpH'te҉Wϟ܍->suꘌLRO) #`AiN'@r87J9$[(''JL!ZlU 3t>Q/Tf ȁu\N)5n.0ȓln|t!s:dGspkhVP?s˞뜾űn $SA,I4Gil|`Cl;ԬLife"")GJl}$PZlDR#5`vMՀ̢jFX/6OңNbدՑZ|3lǧܢwoԎ@ e:C6:Ie A"+B#ࠑyHµW ȇ)B1XH]6~ڗHq*zkiuW6zM >~܏#zj; j~0h3B(}*,? .*j |0o |m4B/&hnh`rWV"E7r BCvdD:iGݻk 0zJ<*'Ht*ZИw _4s8?r3E hf ExlfĉԩAчE'aD6G_*\TPj R y5$IABr-!71z#6 `tm. tT 0!}*GAX>ȝ gzH0$cr 0 H1GH{%Eq)ִmfz]< T{-SD*y1.gxpحܘ)7hwjDe4нqm#Fh<v`}ygzpYB8#"+~(M M h>W"ć.T4T_. 4OWtݳsTQ5ify0Ǝn _hAQdy^l80q9`QB_lǸ,_ =͹~>VzpF1>5/l8^ᔦ@ŠU ]i9P6 Xh^u'4ce[.z0,d]ߠ`ܾ0z/sÀ56pj'-WF.Ky`'v3{ V6;X$6gRt:ܽjtz P-3EEP#`4`ĖJ̏fxb (C VRsvK#P" /%JznN) 9PTW?ݿ{`@a_l]OC#:NR612Vo^h0F.4 H; 0{)\aԐ}! HMF3B!;-Sԏ|E-*LaA䧹 Lڗ5IW|bA 2C$8(݉ZH2C0{۬YO ?%W7` \Q:Xޭ0kg ߂'vө%P8)E:ރ8u Z)0K"(CN Pɋ-]@"X8ru";<ԡdEOQ!fpڈU5<bHC4OB>i# >Brڧ5%v0l#ˁ("a*:4 A>ޫ]tbsQAUHꦠah9qW䧪SF(YfC r+<L;jBfPܬ'IX30b7谺\V7,=n9Dq#oFAw3D P@ ?6D>560 |Aܫ#DbǴc*-@' >@QQD'F, NB,E2Lb,(ڎw9*޿+Z]6B|%i˧v*R>3D`@ӗ+I-dNPSw#M'>|z8b@9w: f{g |RgVǽoաHr59?yra~)mi۳V'b%N?JCSw(xm4z{zxmp`2@C#vEXIÖ1Ώq|qNO+?-# s ~%P{m ~:8D a?JıCii} wD*'xAsB)=y7ҼR%}# h9kX-0R{}?)L|^AzX;ڒ \y{y paH}KځUՎ?re;NO$!\y3p;ղq>`gMxv式ޯ?F]U$ş7O,wC cMeߦ !J`9O?p=PB}9OQOokp24 c!Ѓr|Aa>JDJb֤Jʤ<5y2PRk, JA WQr#˟ &} >}  ,\@7 8-Y7[/|43}A.vjD *D%4cs#=˺nZͻN)i]O>], ?Z1Xә6Ώ9 1B4h1p-h[0wjWqz5 3g)QjBrGT2JKu~К=*ؐ(1GK쫇=2&SJco"J?2.e$Jr)S=@b`*} +GIdeMZ~`y`@A|Zd,:%# O[.f(%&"QA(Q-UK?ƈɅ;Cs]GSbMί'zc +X+ L~nGIMnu0͵d7 iy_ю!pҝÙ1|3ډ4_=8,EB V_p3j&6Ԛp(h7QW/{W$7xx>zdvEFh Pda|&`, ԛ}XE]dz%xIeftr (GN<N" l?"~s۵2;`%){P30OB+7pDYݷAg+W / {h2FdT`(uH|0 i%$Zοj^PX>4xH.CnD38-ca`^^.E#hȎ}!_< FN8pۏ_$r;4Xwh~[_!f" kFBF-ˏQ;{G^i:;ayS3ƒ_):"eG7J,@#6|lEXၒPahtNWCkciaӏ"9ie^ dqg}|~^ \hA~p i ͎EѡlL|:Ӽ+t)OHa~}/̟U+g)IST20T`߿ID Z%½wAEaG<)+R6Inrm<? (ҩu8YM+QZ6kƮ"Z8{,/" t9\v#;L'_`BC?{AqnЙl/<ۨ5^/:".bSTROiQF>-_ Lvr%|3.{5xΟ o.\_YbTTӇKk$L4G9@k^qYg~[ $VZZ] %cІ}汮vڷF҂2-3Y`}Z~[.AS>bߥGiQ'lX5ϟZԒrMYH`)Chy}?A ҂nyq4Z G4XhgX r!Z /eȿS.%c,Y unNQSǣfRO[][=şc z@@-}f %v93^%80anG0$ ԜpT@KV_#K9fV{hM1[F p~ݵ@¡T19?yK=+!E}iVvE֟m[\<v@?0w0lm45{e P/l`@оZ26r;,ra%-JzX]idz^$Μ$k!f3ac_~*Je/%'mkjJ H]҂J%F`0T(u?jV0_ғ3/+#Tzd\)cӚO1#?~Gד !t.wXZcHb*o_ν6֭抑"WF=Tc6lwJ*!qc\-Ƿ-Ӿ3s4sxS'BXY" U%k`/_꼟y=0XErc|\(.ؙϐNgU4{ EgOCzTOc?FkG aS9Dr{:fp84sbc%ydVĤC,*\:jB/:ÉJnѓq<n}Z0da^rEc64Gi<+X u|<%ki;VOǁ? /nXvR(FvtGihͭ Ѱ3|'^vf%o?Iz~z{\|j$&;ٿlPI+0=tƊZWحnOӏJuyIP*\(c|!m 7ұ?vC/QG2g?7! gdۊbYRVʗ[q ʋ5%S4 F4 8npZψQM`(-b03}x J-̞cNcX$Ϳ"ayWg|G9zuqS1vʃ ]_jH CWX m}y\rs׿"xCy/~#7+9';_Ԣɒ(Ci3ʬg喝L)F-z>g{dWynM[boiZ?3WvËZNS{?|^v~3r=DcbyyWJaQ;)NkѺϼЬ O--r[wa3+s/,XƯE?>ۢ)Z~٪>te9|/% j?^p}3fsx~,Ѳ=_0xaIGހuh9l[>6z;{&Y7?V Xh)ܟSWe,` ͅ|[YfX?+>@zPcWmg),_m&Ykk 4GEh7;XgqBr7c0V_{G!pEtj]~D#DѴtXg*ᙇ=,Gs#nnIoIV ]!UȩaW<tjGY%)Pbɾ9;D!Dy|i9npo>xidkK#Ep;W@R_f8(4=P>exw*\wK r*ÝAh]1cJ+==pOs:»p/xE o-*.x7Eޚ "g?J&31>޷]chz \w|b/9ʫvtvoR2Hs4ʓ(BM̐{n(pӜs`{K%J)6uQB\픓BmWΆ?cng}*iV"ʩ]g򿝺-rm'BZ{W6OU=iHp1-\n;>8ؙZhv3u#/^W}x.|ΰ>3v팏c)%Zo% p{KyjeڰIj/e?"t"3oK'4,uZ %Ol?Ha$t'neF_EOzlkJPΩ-4UˡƗmGnzڡގ=Qi=v|uݖ?[ϟX$+kTjZIrtUr4!p>2 |;?(u5bzMpnӳ^_ʛïRW+Ds qS{]Fom~a.\,BVl]k/ 92=NjWMzrWnf%* O8TtNFHy*cȶXy0n^Kdy둶ٱnX~[\o7Wa$iOq[F0S4K#ͻOw%M4vԽGI'_|37{R-&q"\uindJ5F" c ӭNHa^$/u FcdlmEp8?fm2CۨEtV48^KuDSۓ3Ug{a)RTw ~ŽDBh[ug -ʓ<_cPJ5j5vǙSΰ풦|RiR=x5l%|aq+zYvV;_Ua K3:BKV.Iugwz>/f:M**Մn]6Quąߪ W }+1ub^#ul|b jÍYQ &\8_G &{"TnI3ok7:zmDJgݽB֝AWRXsA|}]_q얇Aqk޻LN>-NJA6uVöWGbkǎ2&w;cod<7?NΆft?mc?& пQ*:z}TtEe cs[yWuWdO{1P,q<҂?*-7/!Bb4'i=u2\K=i6s#DU+b}*\t)M({%2VBIEȻ['c@c!W% hihvFD#c\yFأD'Lg̽RK?RۦhN"c/QkftOy4&/a^G+?`J?N?M< J؋֐t'B| ą=o ˻["TJt>_J{ q׶m5b^t~;9ՓZ~nq*#NnnҫOd{Z*?BNdt-aCIW=.j%?V79xF=vmѺ]RmW@ n o27p]do.ZȂ5U5QsSǂJkE֐DCq U4S3Iv*贘aJJF@io;ͻ1P ݜ]5.;Q\moY7vɓGHJgYc n mvx<Ne8#ڨeVEEG <!O%z'V@EyOmGFv=< o'B`Es!C+ogNvcAzB)p1CC9Bd[hlLu7ovg L3IϱyVqCp PVG TTFѳB~++SVM&D9^֩FOg՛϶m [=a,Т۳'Q*'c+E ؚ}ɺ j4bݸ$=]KxZuIQa/VCyi{K Pm{z޼#ѬG+3b=o@D5lofXe:Oav3*?jyV8ٕ:nITN%֧6ӜO TxWE00 T 2fr%P=/avsOZwuJOCJN55Ahh=['a;[Ysh-FaݎHjwt17,nGR3eeJTWk)x)݉%jvƭ4 7mcʖ9! Y"@7|.Y  TWufP\)Fb8K?d`y4GqwW3*>,V"Eȝ`@2ܴpȰbg|)ax A,pa :,0"ta0o[C#T쁼M; ǁL"Q 9B&Hʕ2q~Ѵܷ g|]/jҰ8)ATj.:rXR݋2~}W3vw#~&z4B1?iq R-Z`AdWFVRI{e>u8) ԆU prwKG/gtw># #fF@u'pƞ N9~0"YEg!0"Rq'f`a;$0L +yDC:"8zÈAbЮ{Xg<'с3 e'&7 Ey2ɰzwB4B)C~#MsH7*ˁ^8"Q<"VLgBq LO4xIC"L1n:+-WFQ}?փ/ ˫`ahI'Z"$$wr{)1>/)z2K莌N4T3Gh"IÜ );W6{N t9"@ 3ndF1D*"5!F;N l<ǴN 8H stG8B ` a pqȰ|}"+o? q  ܿ' 2\Tݿ'1\ܒDZ "(JϸG ȡ"{6?>3-!撖1H;1A+ 10#I\2RnTD*IZ.iI#5cX i܁J~2O1F[Pp`a nd}H;m!FuQJ B)I0TTČytHaܿ$5T lK # Ys|=V.Hd> }([;>d;c8rXdtT\-UsGkKt>w NF"I V~gT&`FrG`om̯;G奈В&xi=́Y!"G n YZr:Y9#@$9f9;;!1쀏v ZaoSni-\5Gs|B'//m an9}v Cw[1&A+fRp{ lo}%!#ôV(K8@Hc{# $hkPA#= &gX^KJp4 Rȧ`Ă<2frAT2ma2׻>`3?!i@ӘY{(㍭8/P3N!-pĵO&7pɫ4qfNTe:`ޞ=iI|X3VBte&Ѱ\30DM~deKYh簐+dOTB7b)ܥ4b%*%#$w`t=E܀)Ӎ0JfG RpI,Z!N'p8y0ͼr%(᠕d?ܢNMpLOLZ،?ՓAdXTL?'rfo%qpˣdx-hNEr}'l cñ3[+Dq; М.EG>5\GYzJ0D^ =%h03, :4ŸKw%pj4Ta*"` ZJ0LCw]J0LGwUJ0@4=%]gVD XsdeIk?u2\܈T>xB~#{ _ʇH1tm9CZA~dZ*WMPJOP1;Gdi0U񡙗VlFRM+l\xMmP 1">$ an8HV#gJP,a.Y~,:i #KOQn+"I Qʭ2r : BQ=%aF ѣ¿L̋qxi&o~{NEIaygyJ07䂦 O\"ē HE; "bT|eptnOĄb!R={&\!/f7"#?'G$dE8%;)` g(&>oUe?ӴJ2bdtwL(Y4A8h%qdncQ?h BW_PBΘCtaJž=QA-ֹ%@d4؍JB}*d86@_pASg` S&L ݉kSþd?G[MG f " j@ZC+U"E$JrV\ؓF'0C쇴1rpq8˲ aSlHr-[pa![:zD$ "'"+; VA&A3L q!1EiaLvZXN arɔ]1!'DhCV`jcpb XTdFPh47 D%8,zK4AB,O9Dd 8ssvA' +B$A\n?&B) CY@T FE\`'\P%&+xBEE\2`K&LVddŋ=D/T@Ax1ㄧK2FX8!a\| t~D'N:LVL48 3z?j.3SV` 11d;bɾ(tK 0]Ȋ( >^EHb=B4Q)-QQP\hzX!¨ny08 .)Uc# pdɊlib >%r&#$H☁4I\**PCDW9/z+pw r3q [wjR#Ps_qCp" 9܉+ 0IM,`bpaĈNLVm%6bq1bXr,$"FB b*АHuYqH5ylb>1l(NUxgй,q?"4]ݩY2q[$Q$Sbq?ኡ~$B޷xLP Z\U%\b%H b`k\6!$1#;QJ}SK;GI% ̭bȎ , JYKw}(N"b=_f"{T,?;|i8.٤Po\ )EɊȨc / ^f{{\%(%Q%(z z.3(ddC(ǦK:49c+2􀖝aoVQmNah( V*i( h>+(f!i&mD^/ B#aw?+1p J0 Q%"3`KDf.4q%@΄ 4D{o)dtʣ&+n٤Gv4\:,7hܑ{.R#tDL9,:LV'L yM}f8X{`f4EѤqɍ#O/,1n;//?T V1"NS ¥qɍ vG/A{2dXAV8pct~(bc*sxΒ#o7]!mu';TydiE(j~^pY h.d`,GS+"S48 9ƐZD('t2hH@Æ1#0p~`,e{YD/;G]$αN`Z_/Da>xZy[bLK0@$X0bbe"<@&EweT!~gIN+l2Y!0>L0CEqNmeU|3mK2tx},2B]a['p#c" o$Z'wRW`6X1D! ԱMe ceWm\i:& 3fAOpfr(ؒ`25k/T\e1O庽%ACc( H6@K}&!F\4Av&6 /8pٸ3SF8T.eA#; )cqp1J.7@%#h&*?Ջߒ$)F6&ц2>8BKO#X ]L:͹MP\DqGK\#Yu\iy #Jn9+ 㜴ClD>V fbTTiC$@FJu$45{THF o1xlg+$9Ɋ؄%&lvrȪ;*C B%Oш&m(c$-POYI6B H;<MB)qot w`Cj$^̙>H!V`axf[Q~VOz_2ە hEy4-PK6R vBFSO#LBr50ݨB"la#?t&@)Qs>+x@Efц'Q!9T]䐇i)9-[/Fb]."@ LjM#8vE&h$~z /jт1զ %]fĈ-.[8M\uWrGT#_#8Q!2C,v}j;HЀ;/m6H a$oM]O gK66e&|A[_|#)&ɋl(78G'Kڃ) ^ ꈸ }%YQ+7)vb}&6~&32AT9P"셝fZw`HŁ/`5لWhh5b\i>qX` p(/ݰT ), _,]CTF&U}QbUJ K-yq1m2O.̞kZ V~u~ 5?^>bs#wm+|wEVc/t5_^-cㅐ=/U#<@(oӊqWL+Z:㩙$AW֢!髒ணF+J-A(f7ZpՕbL@!/oi(ҦcYQ"|uQU/U} M4"[J.I:=cKzL?_ύfŠ2U0CcMxv3*m7#r,W2iNɑ`@ qN0moCu94b=Vh` Kr G[QcC̗EGÍ2œ+Ɍ@@f=p혛ˆ `utԬ\{> яm!0_aXn =~j[{޽Gg )XNEA:Tn? &CuJ#;@%&\QLJxN?ӳԒPeWRXX3pR;!9&Ϋ9 wOM5Lq_4Y =W$"\gu'r.(4kСy^UZ&C24 2Ό-k59E~''Xƣm=H \ ]E؁(1J $Z-'}?*ѣɒ%% [ĤP 5M*́M@6oD_"&.L*r$6| }&dΓ iǴpTxH0lJ!H_:؛P >iGYdLæ> El tmKIZlChH^FPbCTPXCM"47(5HaPgEM"LpR"v#Fq,%SبWY|H;J]yuMh"S9qޘ5]Tq:RZVbIF2k9 G|qÝ oؤOf FRXgF;J׏}QT &T|n;p2ѦDIfQĒBMX Wa?G"M5_O$Li@%ˉ Rh::RJ)4x9YA:qVqd cJ2cǒTUq~iuMz\Γ T!x<=xY_Sdڤ5z.PѯS9Fj$RCj%]A番jΙ T虼NR40ʥv~=?Np#VM(_78nM%FÛj w@fkGOI$8 \CnGb^Gt]U>ss~6LY Rw g̓/6KFV4A9e4M|r9=<(8FT#7iYa"EL"[&o@Pgw2^z _"M,ZgBԛ79lF.udшKOV/ZSeeE_?p"uYE#G]-RߪYJ;I[e」͊6NW<|:Vhfu%=Zۥu9uc,.-4tɦUV8̬"œqtu^Ś%L[D#INtDD4LTrg='c P1(!p~T{섳^Þј?7זγ>8'{"\'dzD݅KQiG?TGb[VO2Հ@kFf^{_ Փ痴,Wgns/(j%ZXa]#3/ _Ѐ(]3֮[7a lڮ9nW:]h;->R}G.W j [~?.8לH.d pC;J} pՄ'Xa0{CA\`<]!sA[v:v9fU"KE5nn)jiwL㭜E؏e1S&I8m[4ʴBr[Y%--fy߼0;"ܶ$ `[H#֛ QAf;ẴfVڂPyv1veu晞8f](ix?axkIN :1L;3{u|%Tuse)זTh]%Y]A~\gi@^ly uyq,Aδ?*gq]Xp'+Ɠ l] m}!=:3*l^LCm"Oz +N+v 7#tc\BX-zU ^ȯFFΨk,!DRJDWО`^xVo~re}u.qל|ǁka(jȓ|ېBAFE\y&|6v`q;o82}O+쓿@B4QXs`oa !(GyRʘ j fR&"̮4ii:@Ǯ5WP6/K.z%zpZP5"pJLnc8c})d;5p~ԓ -m+M%A*+2 ESA7' Gr $C^^["MУTto)!+9p=y#dK<pRx9D9}y@&\JYaE-qXLj$(*E{#%[ v99{:HjIY&?^ 纪"7@fp> #;qdw5_2/:eG / )Ј  m_c^6hf}Vٻoɑq`cv6cq%q8$̜:67C;hymP1ag!J+nq.'˽nZ;"'qt:Rϋs?zbϖe>l©=mE-HZsD!C{8ׇߏaq$DJg58Ѝ39pdvZ)N|78i,z9(/i!^.?ΣjΨ_8N rr,X~@!(Á?2`ؐ&M=]G-ߐCdwVup vD.lr' >)Y+^q,8OXŔ3)Rr|mt'E+`#,@$IWO{?yB&ã|1j2Kn`ȯUmq"tll?Xؘ7;(8uz$-p2iGXB>o18"n|C 4=$A^'eO2O2āOq_O$I/8dqH$I/>Z8V 8qy^I Z_xr'vqI$I/4x&| J:IQVZb 8k"G^k"g'H^k"LNB]UƤX$n=/ i jx<=麀qy[D;Qy9[ 9>u՜eOI6;vn3H^gWՀ@dMފr%^oCTImzR8e:þcѿT b0ףˢ"̻nyADIpY4sۇ5E"~d6DkAn)'Bıƅ^P 3O1,C0җсQ-irYJ@ ;@gw5`rE: m"J:TTUhy0Ӻ0W Q&kRa>ZhkZi]ChFr[䛒~"fGET#!YMD 0ƒZS Ԣros$[cTɉT+ʻToiٺϪ!Ĩ)z:itWLT xnH^ "EC RFxM]Q9R:?@4Mh=j@C/no+R6~K8$nV?!M,F/s⧒X^xSM,F/SK,F/K}O=ء⧑X^kbOXl zMߥJ,F/5يvb1zA=ObGQ=*U^/N(j|zC {~V"X^kbLSmv?3TSA/5>7Y2-vλ1}%O'?!1xfP3PDW}3\87ճH^+p*>XK(^gE_r0V/FU^lVꊝxhxӃ2GL"}-2e"g-v 6vRJ~[,ӤNf=$.>uRdVjSyT y4b ;>#-Gﶢ{M@fɉДxnj",9q9)J~;Pk8\uDc֐KE2)E}RDrK \ޕ@8ڎ#Y8ҵ;؆D0: qƒ]m9sџ%0e߼K1ukwo3~]_ͣƟqf'5byA|ɼtECd7ք013{=' aM:*CXdi8nSK?mjg( \؜ixIFYËHm(wGC-Yg`r!3Mf9x5-Zd\’\VNdA[oh6>}׸ K(j৺R趈n>AVv$5<՝%Gbk?Fr/ ]^m唱 Dv!'Yh}|޴TSrrlGUm tG"Cw;[W*l4`SOY45fBIX˜5c0?ak)+75]V ޽Iv_p2ك7Z/Wz7-Pmq[JF%]o~CHcyD,Eh`]ʲy6m}캙81jK:Kx 5Zq$)IVPd\GBpWR=ge+l.fL 6Ϛ_n%S-E#ٛ"o@+7\eD9@ .Ͷgڶn Tnl Am;m[Ԥb6 ?,m!dװCvQQ O3qKV|9H+>_{c&0P8}m-6\ Pȫ3k JsE\,} >=jqN-1:)4uU4t ;ܣÉQc@4"[M@TfҾQpNaO9P`ͣ+(!."`O Gqt_ʏ/7;*2O:TZ.U[lR~ֺ}#zMꉟ)UH:§3Qyj)%2>R^]T;1h@ğn;EcbYdQaG[8ɋ@+@e͊4YkCA?G=Hk{>F~"uDJ=+14u|mU_,8:U*< ÜɋcL6n'i'Z,̈́?]^%ZȃSnmtR8SuAb.4毸S 3։Vjl$ūɞ߬ :w=86 iML;TNc/ qLY1`*ڷd$d'FD6:ĕh!L xd"W=v{38͍':rڬ@ӹ.?$zͶiC=^j}pD(:2̶pypo~09GAˆB\91KR \O0A-MCAQ μMDIGN:uI/k.!P5sy5 SF= f;4@`y0[ptpqGMEB@q.3 -2r@jd,DSI])097\:uHO?z1>XE#b\%^-piB,8HK'L1bƪ\Ś77;TTӐ X U>;ي>mC)f veq*L7ӂYmۜ k+[eS7ɬ, 6 -Xgtsf?;OG ^C8 8\KX%]jȉMܧ) u4`=~( 7گ)?gMzlrxes^"7%~ 79$YU7~vojI7e}σ/9,9B"2ewҶȩIZ-KSDD#֥ʫ׫{Y0ӕKv8)t> /;dNG~l2KAGėZ9#a ON).K -޴ԸYtiQ DZz+o) GOMV$k?prGmK:l$}DIܕG,''pkJ K,7Ya5b-,(EK.[=RĀ@unTxCZne`ۙVޱKw8R`fҌ#pohUH..Ad3SzvaKj)EV(f( _] D*Lڞވl=LG`&fduՔGᖤCGu-\ N?6r"@qhX;KPX .g\Y^?X<1 $^(qQ?[g`qTE"UGp鉢3HlH) '5 >n^FvVv}e<Zb &";}s}|l8*_|zZn4ycN| `8q ;Ε\3P83E|L/W)ds*/wU_PJ6pől$JX(Dvw3}ً??=[#jmh>}EmRhGt .M{z[[٥0mV/#] T~rekMSog٦|aQ4}@7q j/U2f ^ᚲUp|\gH1D8f:H0!|!OIXSO?:yy,Ify{>M`7O,$x1sHR#s2E\pzDH! \@F%hkiB'8'\3aН_A#g̣PQF? SƓ3nEQBu9$^t[Gы.hyizPU(㞮vNhA@L$"#ډJh<:H'FAmY?<(S eI\4®mkDH5\<8s+R(RB,TkFz&qm@H.u`+SךT7IZ!y !"E)eRw,bstnV3,s`BT9ظrIO"n~x'Af8´W|2tҌݶDE)6ת7n \ ry#]"ъ9 2:ȗ(r&}h2IJ`NɝRk<"iDvfpCָCD!LG p:up^+<tMzMD&gm]7!H` 6;f>692&.4p)FAT8j_yPc|b]W.(OwcXPski!Jc40 -CƨƢaWH@ f׬ '[-b !IXy'NTcyg`%^\Uۚ0Ś `xc?y[=$`?I1E86r6̪'`!zz Hid2V%ŌXH/ B#BX D<K8C=Cs,F.9\IăvLH3 7' ȍ9Mt܂G1Md"׏T9Uopa/F/Jܯ5 :,Œk*^.SW4xAej͇e/I nB;d7R1yX|DC-qa MB}ЋDlJPMEQu J*~ 2iBF'NI c6U8?cq""uEGsuXȜ aZt|;Aʒ6FC GpqBQ+t*塉f8B“"_N!%UN~94y2M֨CpH6)rCܙ ]jH7KѸ̃sPrq`rHrSD)%]y#HS_-ހܒ/T'GWc&v!) HľzƐ?>Z`JXEgQTtx;PJ! #ZY&0 B3Ci%N[S(l,NGKUUIEYC.# }CFÀƭB &#/װ8lu<VLQyH[ntGRLpxm,D/"BT$M o#EˆVo"CXA@ &5܈0K^py\y+8@o2`i dmAVQv/@)lűZMyc>;l,vnjPMwޮp[j%%4&9ћ)+Ckq_ ZZTa/kk\|Z6-+yN/6y@Dx`scotch-6.0.4.dfsg/grf/3elt.grf.gz0000644002563400244210000013624111631447171021651 0ustar trophimeutilisateurs du domaine[5U[:DOwМ׮1nNm)z؀}nm1~u5{~y?^wپKwߵmCq=#ngֿ_o0_?_n[vy 2ߥ zaz\o1n)pŽ7Fʧm_qmnڎ+!?_KAC1-T 0׿}EC~ o{FP>O:?wHHޡ}iFX-4 I(`+6rv+7*1xHuy#15 [t6qD۱Bƭqv_b5th"l__{#,}J9C_41lV^G'  X(a`'7^i#}c~~x_)͌>`>&m{R><¹G74xe">s}}ޠvܸC OeQV-Np*hsE}~ 9cg8ttw_^a$ϠOр,ntp;Jhy_-;UQgj_7_g=1x@F+^17m(yT; >3G;Dowа ;:;n|Gwv?O[C;#:;~] ןPiV3:' ™EY!i֫@ B){/.N;"cǍ 6ܑ/q_ =XaOYFBԌX _"EZac\侽VwRwߛ0ur + 1pZɭ/thԾNg3)PDmB jFƾS+J~l ǰEoQMeVik.|)kb\d}#"BOaSM*G wiP}`\(2vLj;(*1;o:?[CK90u?]ȿ2E&C߲VƏi"<8m&" x[8}ca] b1G5~9C:q-(#~#b,lcrB[3 ,m(9Ǐ3ѫEjŲWs@E~Qjv <\=Na# mkzZ+3|HDP3SLFJ ENbEElJX8B,m[(xuKwXcxv~\EXcD;lN^ kZA{s9n$ R =%gd!Rbv=7y 5TCX7hP+Sj"7vzy2Xԉ؊jƌ7S !sJ abA_Gm&: aP+[zWKGXIBDlw_,Č+ pD :O&1O㞸wd0C'K1U)ѩ iC% cٴkxd?}?_= ^…z׉E^Hbu1p 3PV6#:48D.VFO+m6 1{KʬXzr\i錱.Ǵ%:_u2ѝbt3%@X,,W킣=^{7/P8\97) b%7u{_GfoL{fIPe~vO)hMu$@z50ʽ-1F>d~AװH`B*#À,_KttYĤ:zFG{**+H3bV]jͦ{ӿv@HzkfOq屷I VU[[NQ#7BO~r{+˾B6C9,. #GyR|Q S}Ab@h =WJDz\!YvCK6gC`A]7[FBJlwHO6ĻAOl65*1-n:B++B⭽2pQ;0g ۑ(<زN ˄}J𥐢Ú^`]?\{Dö/Ⴍ=oݹ"Le&E] P? Gyi_0xL z_!Z<8P6zA-#10s ~6_Mĸ3(}xУi ,i0 ]}ѣ%%FiXM_wč7N^ϱ >6,FTya+tyD%2u<46 C|=l(RoH2hk;@zK0x17$`߀:ų A9e1nGz+mGX r~飷pf LPJN#DHZ5@\]I|z R>w\IL4{:Vz xbg#R.ϣ*ȪO!Y7y1'=Mqee zwvO߃}C Ԧgx# ^ >h>kƘ(4~.MF|~V̑">M>{!d}i_bIxզ-Hg+^zo6}Zn1":0hc ~=$^[#V57U-ajhoy9:=ϓxP˄|ӅWw[n=WYhQs`ľdBN2/#G e:˰X)(s,KE=^ zɿ>u rƂ?5 'yoZ<'>\ x)3KxŊק.xT?JjH^6Q%LwYel!UǓZ|6z%ј=DǸX+W»-.i PQ>~V9WU"Tdc{("~uv;ER=Q٨p7u¾Td1DlRA*&( ^ |S f D.^Iw8E=c5~ݏ}+]wM 9n`vzf ZǥWmA|W  oBY@)a085?[ЯgHū8\* ~H „-yeK~|+2*gl0:d S;C@G w [(&g`MeXH{5qVU)PE-2>@I`W07G| ngr06" q#9`|aa6t4+ bU->2NـbG~ EMTd,`))q;ZH* v}ShN: wPfE ).Ԍ@Qԛ6t n0 s3 B/"P72z.fw?y~V,ag=_fGXw2(sĒqlMm_NJ_Ps/ŗ {r1?} Mr,Zyx[k!12ފ-k8(jomy?;0,dno*l5T+44mB2 d@оGwOT۩eV"] AܡeEu]}[İQ̅bI$nc 2FLJWn@؁8~`bhoX ~Cqp]JԀaN\mَ.ŴixKMfC̰9\O'QN^h1* p%Fe JO^Yx_GCekq(xůlBre2WG]w]6X!9R3Nӑ!^mi/THKč|v`pc"<%TI`jS 0 >xz_c,M:2XeHkT+$^eIڤ\X6ݷ`WXŇ@|b;wŚԪUWWEDjEh᫋&TӼ `U*pb._WYa٦YюoD`/}çwJ a"t zA6j@ ;#]3"NJoBUxg b՘uֲ_3x )7 O.vbʌ DZ\ˉ /_x% Cb>lLIB,5qBiT] ØN+ZW 4T6ru8 8YkXKmC!Rdh8#X@q~Qfį`B~e H(2< 쑉]<ULDBS`auE O~"V|5Ic]j?>!+3P z;#IvЫئkLOTb,ۡvKϓ5?!x4>$DϱnޡOTV·f֠'|[ 򴖚xp!nDᩱ w|Z8ʻi3>31"kȇ-g(m9BdCGbƻ:zO*^-#Bxr]{7v#{{~W o^7-h`f͔c*"#-x؉LXYDbq@&Ũ#AҖC{AU琧{n^L=A:(J2$ i|ciѐ=>L' G "/V-V@NF3{#Giį18ѱM<OE.z^.pڑZbg+nj 4sԘ,Ethh /ht<Uih3:F<[#wϪ_< o:QI="Wǜ„r=Vk]O}[H;5zDj@&zMY7"\-`8|UdɏRxoegb&B,]Sq ^ AE6X=>Kb˺+FQ9*&YpZHr6*H'¯GqOYEqG~p$>@,O`a62J$X@D|J=(?`aW>'=tXeiĭLl1xJY_z /юk6tDd.?7kݫ] ]~_|;%"<x9Ȍ ?BKzE%}O?(\В+1zQG HfO7HG$qooH3]<1QÓ:|[/ R[Yqw{DC%HDts0}מDvq=W$nFB`xG~,vM/ƹCJKxhw~+[ߦP!w.tnнhi4uD ?B˛B^G3{ dDyb\HUt+\\1Y5AlriN4]",sBqcti(YT^e-s'ĈΓ(JJy! p5N!aH󯑠"=qU_'mָyh/0:$n:$ט 7Gn㨁+z]km&+3FY4Z_^BZA엘/ltѕl8ƱaEZYE |%0]<+wIױXiYKF8Q96 4Bx?n^TEE9r08hJx Rg|C)f!`dL{; RѦq9EEGO!zwW|󊳮?Vlҕa*k?m1SHb: XD-ɻ>~QB?=qW$x+Q&EEwGv9ۼ$jճU9b$42u .Db{S|ĻӱEO6!U 7d3/XǢt N'3ApϖaP hh3'_Q7W ႞~\Jx}ǣtY^/à N"KPG6,֢7D{b_w&|?k׭^R D,qVwae M(cot_\y?p` w\,^L|EnLz 4Q\"$RKzKX>'k{u77bUkB'Gˮ9 DwJaqo\}|>v3< e'3Nw]HڛQ^wZB2![X9ZG/!\>{76:.zICIT G@>s#ޥa>FI ilZ-4xx,Lrl<ƌ٠8E(Ð4O_=:teWI[7CgB?ȣY`;̌$A4 E)0c' H|vܐolce_eqН-@d||pɋ=%c$ax:@ K֯I.R#MX,2Α7W.{]5ϭ&ib=lu,r z{5zv`mL޿XZF*썹0 DA1Fk .}'䈾_Tw|uVh5=f'?2MW0cu#jɓa'! {[0cn#MY\E|*G9C, -âr  d))6zIxۥ.QKPƄ*IO<^ʏcd| kb;8(oA!`W=,KE/D=ݢu[e[Ǎycc 9,un_$䘈567lƮ?W$?dmޏ\ @wG0+sT"0a7$= P°{czJ\TaP-A{/yc1,mAs_RFGBР2.ˏ۽+HATuo Ŧ`E\iD 3xhi#x2jA_Ɔ`x Ox[@AܛD𼞞l9vo*ovŻUuH*]I.̝+~]SPB #ty6 8tD|p_BfO@OzC@5^ 8 V. cQ1lgaA-|$ #ރ^ _eÜI2m/-boHRњ؄PXF1P/!!]|j>a^BXGOCXﱕ0ƸM~ZKX2M/Zj JBG^+gIG׆|,w TUCNIxÁ.泌I{ݨ4,׷HFG;|&uiꮧO鼮=(c?*'4حnV8[?'/ qe?}xְO!{?*LQ%elVSi -SM'>3![^w4ܽoNŋx"_w~1e׮u+PN*&<썧OYLFS 3&n M{҄` ?۝ Xȏ&̔ϊJPy_.ah$zFp,IJ(I$S'֘~zCpVXd5i An4R ;Xs:W Ollt1F%?"V`䇈NjOe@`#6'X"?ɣ^%5Gf HʌC'jz># :N٠?;=MyUk;j!gBF(,u´D,^᫻x}%4xυ!Xn~Ԭb.cfYvhSAE+[Lp*=`A9 Rm.t4˘V t0 {iNSA|BlsbHE'ۿC3 RD xC=fQJ8$V$8LFН]$M$DjZ6&f)-*!)8U@2NSH5K͓,+H<[/+?%жvBLN7#R4ϺcVՀ3,ptH57ePrqдN,9EhdU7AV'V,8%-t "F`ᜒ_MjJVҨbAavYxTby*&0!)@#]WW2'hpNvΒsV@'oӌ<(9ӉOb zGy%>{:ޕ1tUu֩jW:,đ3aʷ-=,:]׶iZs ?4]£-:XH';xQn*.Y;N,BK|.|afVUN%Đ$/$DSC4`8lZVBpQK&g>eݫƟ,G"l3kI/AV<*}sեiRO%D;2+H,,TO$}c_K3rĮ}3݅0HbGTFc(Wtu@uRJkc(3HD{V2H_i<)/Ɓt]$Q ]B飌z[s\-!C"n5l'\9cmWBB<aIn/0sARd!\2Ũ-00+x]c5}尧E+ڂ{UYo3\O"^N}NQ>gUSԑ2ɼ5w 5 ͩq ǵIt9 R¦PrvR*^."!>!WaLQjYsڝ |jJ$:v;}{2n|#iQpdF Uo'bvN#lc@caaAZ )oj$R}ɵ u<(_O I:/N^UR|#zuCŷv߄ o?]y*!z7Gڡլ\SzXz7Jc ېƹ X0-JMw^:s(Y#aP`eK,yPT=ɳyL8ת-p YO0U ߋ&n/k`\s 3wux"X2e.KߛuLApt r(9^cÓ;2i|\=oN?i;&_{OaBh" e(&<5\H [I;)IxBf[Un$HپyMN.; wbqV I$㷎-ECExFEMZ Q>f,((j^ڸH T˾e |dSTy*V&Xֿ52Cc^h=]Z뇔)oG#_oI5w )3ﮙ[nM w|S.NW!+7:2qKCL  h/f+j #jE((wTywW" lf @`u 0##\x~Wѱj%\PBP%}ܝ`u$۱ʂT(!M=l:Ѓ舧Lp|WSn":MVZ$7 Y@W>a x8 6{918\q=RIzL| 'dOlg|,L@I1鬫tUsKO٣ۡn(>)`G1JEKgv;CL:ԍ7ҋy+iInj%@qQzEIϝƙX)gqB$gi8( I3ҧ4Do8[?:ϙ=|nmSYQdt&gF] ʜGu 3 TO~ ?`Y4a-xPHKt}VH~hI#D\wu"5x&`Y>V9 p^1hF`(q%G ;{i&~ 7ByqG A[pIB1yJ3 a瘣J*@ W T<\=+SJncȍV;k:of ,),f+!$źʪih)zE,#8=c1*i@-J M]4OH.o)ilT,M=9aJbJݛɝ ?)g,V4%ZVg'2Ժ\TȖD.f\ᗋ2H~!q[:xqZ݈2dm. :|I]j~H _ޝ*fA2bY{:NǹO R.9~5z:*j敯UH. bp@8[aV)UWr/2c‹|i{~t"2ROfʾ^CTJZUNTJߕÌwBxQh&}@<>(prmnPp 1 SݳT 憿$s# ܣҗXxp(NL.śiMD8թ+ 74jPd||gEs~{t%:K$[Q+R;V>UzeyFJj ^'iIML~@>?ʕ8جxWO?r=Tx ФC`GA ) ƮC _t\Ǚ a " 4{ϝzK:7pcaV9MYQL,O*"ש$7Za050:wt=J 49~DZA@oR=66FKA٠T]]5!!$L$g )J>%*/袯iif/%t(?00rPls}fj=5a!% Q 4UܩÎ?׍;4]4ݭVO" Cg!!8:1ap8P]̉,^fiV)Fr` ϨmO£[JH}RϫY Pu58+{XEנEC'ժ?Xk0-kBM3 CpCrȦF;uSU0V5 \ /c8}K5;.De}! )y>` UQ#) iJrNrz^IÑ|=]O3P*~|sv-!/ q\)+R3Ul) =w)[f$VFdpJ6Ѵn*CA2~:5yNw yB}f_H:+E߄iY+~}B(|'5I# `z1If-ɥ b<_4 W8$N,8sLq_Z FdPTQt?)z*&[܇n0R80B[@i%D\#icF ˖$ɪ,ođ&? I4|mk 5i#LِScgw'Méd sr1i~W$^.Sp|WdBHFHdv-J&hݟC"#uкf(k]Yp/AGWz пljӯ(ེhScN}Mtj%>WRG. j@1eoR򐴕$UwHУ:*K#; B]KU3B!QQ_S]y\Ґ*(.{LM{F1'xFޒ,z5uTM :q~@-8I~%uZhW/I~]u=t*Wp.Kګ\iW{#uWa "R KAUFuF )]AC22!4 c߾%-n<~BGV/ysƒ7YQc+E9ey}կDm9YB8~Ik-}!.(@tg!%R'[ Ib@:nr##V{v1X VYܰB䃢ӒEQ\!'SQa%:I;ƔuZ"I:uTlvF f=d)Neqpf| 9r^&V*NH ܾsm%,k: :ňqK.IBcH*3JPQ~s;m\\$xF}H-ai=~R9Np8t,Ck**u!h&F?6{[✻t]Cd)8 Kf/] Ro?-Z¥^Je8ws=&"yFGZ:$-Ov)ڜ QY& O|TS ;n,Nϼ5`-rUr a$m麿XEIwL]Jeߓ`؞TM2-A<4i4Fjjd,Q?&A&nwg;N KwH.+`r"?D0|'k(z("L-~pdWSrUM|68U@Y)P/ͫ4ANV“ Qo$"3t_80|- j:I3s&O6&`$ U[@_AU^Vk@4I8rO[jzWƻUבj iJx'Lgη.> 9~/7<}OҊHC@Ҭ:saD %.ОiN7zsݔ7 b*$Xտ4"m?( M82 G|4:=sdX9b  @Ų͂?Wr IÄV'-Z<Nx{!y.F},g/ +!SͯQd[M~'FK I lu'y9ū0L=:o>K*@IV-&/ys#Ϭ۔l wzIIXw <_BwEU \"S *|MyH_6M@z"T/!$`'/$8p .\j_X0K^5E 0Jd*ή%ZH7E*#bl=X$Sᤵ? ~IeHS GOv:H1 *2!Uyw ( *KKQug½a\b=8+v\Z}fiŒ9&u*Hdʆu M< DZ]o"`c>HtjpW!ۛ(ܥhک-8j瑒X À]$c<'t!/ZQBc4O!0ZKB4N/}q'r_h$ژ٬O.(e+$1/J5U C^OIrgTze1Bubuߞ?aplfl-+]0 FaڽT9pLby}jvwQ+K:0֤yfS9ZJ b_^]p&x45p25'EZ,LHإ\ ( !~>G!Aq Pmԥl^Ј tI9P >%8դŁridKV$O5!3&x}Ū-kg'tH$wT\;8蟬G3n{mq\2ѬYc ^Z55pp Wb8{kOZɯ-_߀qpYA1CלwDwE>~CBHR~~m7ZelJIμV3qk\{J߶G!t0X4NLhP BE' ۵ 8EB4N'*yUh0i8OBY0 WOB|}L 3E3CT16+@b30i[ >E[ǍaDhb];akOF. ]3`a',q OIWQ#sb C=3O/>ES5jIr} !wƮBwjqŋE>TR Vi^\iX{Nd\ }J|6})|\ih/M)!u+}h06 #d tLJH㯸1oJ,N|֥s,FT4Ky3\:iB3m41"7b"PT(Is\K5.9s^ribťQ]Bd\CF7M-X4J˪^QBV' TMf:l_Q[ADHJ""@:0ܢȊ/1 [AVw.-#M cɭD5w H}*FJ v/%CZh~hyO;7AaPX4\M1!0rEc/>I8#4]5Nnzz/84O;Lw]rwxi2\"-K$QEc%|RʭYXD@< &L h+݅Tg7S߲XTVYy޴ K#5i(Cx0b"YivF82HH^o)4HI3y=OGq^咁[h2HF@hAR*Gɕ:X:R:&U39l h0hm*մNl-ּph W(!%p(C>. !«5+}JY11-AA'V aVHz|(JTtGj>l:@P w)!~> \rB79pzT<62B Qx+6 #3.*aإ3ֻ G5z~ķUMwOǎ#c@sJױ +*_<6#)P+5iz8k^Lp—bG4gAÐsU65Hlz{ j(!mX79#Py_JR`2N(_o +Y,h&<w%Gvب_ l8m-h^_sښ͗@5ns5S)PlZ=.:D`|_KM:~z@1M=.񱦆ΰ~ 0)VZ%r)v8O|Kp L:jK)%=ߣMF-7Xig*q~Ua"g{L!r8Vi\dI\ZQ& %"qq"p^QoWbaI=%OyK[ͫLP5lDRa&>L.U\mOR$jD#q"\7I6mt֏YDlQ8cb@ hB̒O>^KԝZS]]&Wf,Ѿ%˷>tя$0%sEnd}U!iIʮ=$FtP57|8HmU<#cK+dCB#K~d vh^C^YFu1.f8oUOpғ0Ì 3T*M ~DV9$5GV2n&h@Jmj^>=ȳU<xz)Y)A$ ]3]RN?Ot=%@':Ұ'r9TI!a#6fޚ=\~'r@C6={dE&-%>\%F+` XhK:M~BhKպ!yMx>5$k@,~i0W**L[įBԋ>€Oݤ}Ԛ_IOgB^k^a:WVqRmo=+;ˀa!hMɂ> MԜ4HV9jڗ ESo,s+Q3c~rjO?b:KWޤhK %u&A8 oHԏzW֠K}ABF -5D C8{қ;9R1DX5K,Q݀+.WgH[$; BA , E5.1R)1Nk2`̲ ]ӉZMK5h1ԗ$ǚjUM9"Չ$ڰcuәM7Jo~>]'B`s:ȯןCXMhqd]@Y&]o`p2Xa)YR!,] _E bhO7X(C Xr.~ߔR2a(_.ifCn))|0~U 1pŔ5*\c$0*kP`\)-M}`Ab\A5Ia[~p}Ҵ3* DJesD zOM7$jFGAI1S &da)-?ҐjA bM2 f!tds*W6kH(.b'w7K$ b4sv'~}`YG%jqj@La-! 2S!j[wƒ=HJas85sZν#GBql$aCwƽ8l"F[?EA!2ҳDKlf'I) (&X]hZ5K= q xV"8k9,0`kGuAB.e{^ /߅abdX쑍ˇ$L4iZ홃aHI˧DjbjE&:ﳮ:Ҥˮ?uMVQ}wwW\L+QRR0GLo~[(iEdȘA7w[dnЭDa`C DO;<`EODֹp t.&[ j2f:<dS}3VLRRMR>pD瑤B\`1{$D]e&J,]Z5 /|CCܭ7T*y5J|p-+TWui5hAEt$8K Ӟɴ\0-YUQ,d~+ ԈЀ|CHx[4]38WY'[ 02nUyAjpHnvXͱό+w S8y7Ⱦy͈5CޡO}d./\EW q\cz!F%8MkDߥ$yn0MלכR^iyh$ICnzJGUA!fWR^& 1~JHID*^_稤DrWTF;4y.q'C*Z~8UH*mTI+aUnZd)mTy Xu} H9 g%X'¬$I)<+xsG-e) .s{RjY?[@8Do+o~c ,+[W9@Joٲ%\a{@qʒ xqCWׯXW:"58ĪG;W>WS\fW92*.usN5 bƂUa 4rO@zugA5%Ýw? h0V.DVB};Cӓ/"$58sbV'ͨWŊ&Z+>Vš[#ScMF}_[ ,B0C$Ow!1r". ,`J'LԦ01#|%SjDS>uI&ZI*kGK&B+^" i<`bTQ`&}#\VFZM%]z +H2)78R>i4ƗYMfUBJh}W'sfƏL~iLT F>-Ss]NęFJ@?0 +JʮKT8.jI2!ӔE0>y}0\"gq,%b9_8C\Cbd&&ۑ!:c ~)D=a"vnzR>vT'Pl -{M2;^XPSJCa?Hc$GױLKAF"MϥU7a3KNyMHK1Q>=cE4mǿjL[N{Jyv^::DE." >L@m5KEBAR\iFČyk@ՙc*]|N[p f F !4\oJ)y^Փqd\[@weW$ OJw&1dzR8t3$KC1Wj#UE~z͞Ʌ8ԛ")f6Lzv8BOVUܥd%)$I"l)dԈK2f.zk2ͤjO!߂-~Ɨ,eqo`_αzY̒9^A~|1#Sziϟ1(f==t)I0!#U]]ȉ^*xd# 3XuVWEXE.;Y9ŕfd5tC8C hNsҬ^>NKK⟻[OPS ϥfA}7IW5k|f c uc[Ak$V:Ayc]ӡ.٧ϖ4&'H"B~Ƽߡ>c1AN_E% SՀ3.P |ЍO-#9'jㄶ+1%N b7`g@_XC.$@ҩ3j56p;d9uf|<ͣk?6YwxfE]2SaØug:I>o &&#?L" 'ܓZ Ubd47Oo$3.Ԭg!XceWި xWz&3lW| 6zv_ (8]7 *ιJ*5 Eۙne)L:%*՜HR="[iGk`h4Ι`TGĥI8q~fRҼN AD =(FE(3P}0L/b;VK  f:“1e{3|mM J:8Bx76nY#/}VafmՈ'xf o%8uv̈́~f<ǀ%cZ0lqfӿDt)|<8 YA"?Cj*d x ~S+-@V5=Yob+@C`1140 B_,4M,EKHpE( a`?r1#FhPA˩FZ*]UR "wjk'ffaJ* ڿe71+J)*abƁ&X{Fk˛hWj.P6v( -ĄҺUc,;E[~?Չ%~Zz U\9. l,l|BĎY(@Eoju]eZ Y.ApW\ZuP&ιhqAfWlU'J#=.JɳY#u@rȐk~>!wB/P[L%dh(GʨC(7BJs]ǯY9V\hD82 ;3G&Qeן0]?* LPDwg23yjAv.nsh|ޝf9jW3>;xnaU\ iY~Ln*KC2ߍ*ݣWJʃ*YoZs4S^۟2F x,Զ1cuV!o]o=W7} L,ڭ6#S1"\^;ti0@Gfj$ߪ <[; 뵳қW K4#$%J4 (ɹԋKLJ)T~2K:4Bd][e#Tp-x7[niV]34'BcJ'!'M5myP}TM@MǾmo]BїѠRWxyj@#,ii7-{}XphyK!IZ RK4Fw1|%MuL7>k@.vLr -N zkSm)_mhZLvN=Le)䦹 κځeiN`~E5 ڴQ&/< 'DcY녫ˇn%0h :\<;qPE 0wR4<tYa|ht~ksYߜ'IHj /c)mI;T{&;Kl ߿X-!0Z##"|-AZUaʨK4Ы `ci#aj) ꬮxR+0Yç袊{w`_!8#L@QhuQ'Lu;1:n*k-w|Ktr-ZʧAN4␀>ui+ {;wE^ -M^v D.zQVNbpr8YyLֳ B䲀K( .W_mǁ0v^_Ϯ^r 4ȝ4xy:{Œt4C5J2tn:rԗ"rIG^z0>ۏ0ΛT>Hc(T}P.'3 |y0=k `41 WAw3=>k% ;|(bi{PNEҖ.V>R'8EƪUL\Zd9*)d@s/꺵c:KxpyUڟ/) ogsc*Źt!0inuӺNXui״ԓ pxQ 󰐛4hC%5J:jW5lߪC.ukR.4/D17|W7L$lizJ<$ĪjH(KIcɜ0ks_1}C8ЖtRo:w\^Zq]ӥUVc]!\1 a%|U[jY kDˍ)4[Fk~irq jX\uiJ'BP#hOXH:Z5op yk+[#;dMGu==5Fa]ӀKBo'xE/]bX&cʹhԝq==ZTX0 L_g?8͏nVB;5V).1Pf@}nj52i8{a4y3Q_ D7BSUڍ[59@s>%T !ŸVH@b t[ H\zQwXկ8B]OY#s9ɸ7&8#2jNƠD ,$u3q)Dٵ^`0WD $tF}):xi;E_ڲǁUiz+?Vr%Pm ߢ D=FL- ZB!BVjPj~wfpzUMԸ) ?y}jgM iAT4nL^na ڴ+z0_wNp'[I ^eȡha~9{q|\Ӭz)P]g&뜫'&꒨s,a{ s벐? 7idΦN5%ZBĝ[<>Hp/=A'6SM2-+wxe.RG(3yEcuՉga@:qeSU~Ke[2|16y`+wIlvg\/3ϾwMp|EMڇ( ,Hz?F:QbQQ#i/"o1R MCUh񾵎@^6fi$Tk]eS]TFb ykQbu;dP~zq.F_ y$1* k<Չf p߁ fNQaʒP:t(  B$L^֪U ]8DoT[*a:kMe`?hAn$[5ݽLό+=D;,%{[uja@ȧ\{a$|Oq9 (K_4鮛LZ ` C UV=0QIoYt 8A Iύ"yӿ\]nl)w}]LyBlNc{c ,+g ~H( (X"븄 [1M@:S&ӓemEfh3 Q$ZiVq^t bYx]zok}K,~YbYW6#,o'-g9t ֛ްNj34^'gMQ'֩w<[ԈϕG7aJыˌznijil?8߼HxKVfԲ=n2mckj X!:|LE n@VI8dG'`XpŎ8QRRE:#~+EmH4 DZpKB|:D΂ghĹ:eYBÉھS8RfB2&7Ҵ M&DM'=fzsIT0QOWQz2edI_ƨI:)9@j~LqJoohz`Q[sSs щm1YY,?aa0֝9jVt5AY"j]&C__% {֪9.D"f!h atU/7憙% fI|' S\R >۰r>6gt1^62UTQ8LVO8h3ښP,HEdiDl,}[QxQt:cոqH騖JVmZ]]So(qFjʇAG2b&˲wݣ7裰-xGszVdq vvd--)tP^.R., ɐVE`i=z@NWLڕ ;35҂O& T4AP8d; $S}X6^ ԍP~)UOVNl4n&3eQ8NM,w^ɖ8Ug,)S ]n2K_WAoM!'Ik)f)P<4vzڛ9?a,q&WUt* z܏gAԀjL$~a$gnd}Xk8P"^a&[s.2sǼ$ Lvl#,O7NIDF*٨IX2*XZ%GD역ip![s'8CwĞ8I<7'WT=(PZTV_m[-}5V}K!^e_ch<SXOH $Pgu)]o%u)#Rg~6wQ;'/R-LnȎ `I9!U6a~C"j.װ?ԙ54_exfډxٔW^Bk~M֡ Ojo" Shhw=Jӂ>IN'QaN ŗihLB<5eP\أ&OY`: i5Xcv')Ѿs@J܅ !fJCā)ZlR v޼LlOc^W`z=9RZ%G~q~dZk?+!œkR.4uB a Jpa7>5 ā˰熊0X ٫ p[efh[╣ iat-\Nj4 c>0ى`XR+s{Aad}N<4J4H/tC05q+u<3  f w41 i Y/ĩ=L|ɤ̚T9emc<$^gly**.4VS SIH')G\3Ώq< |a=%DGT3X@^N+K%=^us]oaJWȟ(7 o*e|z #+}XK-|k[wa=Fl87bOƵ;0Qx*yH aFui>J.]0`za1B IUa3o3XٽDN]!vمaSF>Rj%80y=\s8$ž.+r(xqX*1d ?73^qIw̲O@hd|qܛ@0T'q.fy% 񝺛O7d?r+D3 c' ۿ)B<#k0s.W3P(:z2|Vh$!px>AIGo9^?PQQ,"Ӂ9OA#nKy2a܁߾k"0 P~]w7NnuKJ5K6JAEm5w>NWVH!rtJ14]ˀ44Nޝae3މ _g4ZŸl4=y)v8&5Ij]@')pZ;Њ`uq]fv}:q$bg`C>2Py|y2>×+aPR5lCdP]aV!^:&6iV*?],A,E'&PA׬JHH%M;m(#۬FXN N07 G*A,$%ZwJ<`!dط#ڷR(Qe~s(ҸPxU.iP=A -+1谢12 ..[[ߧ_`:YLM0_aj\˾tW;E8~3ܥD ! `d;I&d:L߬Nm*CO tZm\ WP?^Fi:Y1/SQF"WNw3\578a0>y8 q쑪 _ޝH]NX|lJ ze= ^kefDEcDP .u7"0)pxxtV)𼎙)ռVID8B+mfiKz>S;7 {ZxVtVc @f"6F4Ҫ"dc&ZwxI0ԈJVbZD]רGf' 8G^9YDmQZ%"l]d{;wӛsx*;^rȿ㡚Eu:IԈ Ĩ;y@SS &=ѧ/X.=i8thu.jx>5.GDB&rzo&z3J( wi~K/I%iٗhtjJI\ՔW`B)r-%t%na"R8HLɐ%"ЛMzLK?L]W0D"w-(r EZ^ˀFjo +#W/\JDt66Av l9L|<I:Ng}Ǧs]&zi_#/u%uN$9ɩ<s!FPmed+)?E[IET5'qc:e0^wQcFHܦU,]H !MiJ" XnJZnjbe'iPi0Hןr7?N7L:ѫ_[z E [Z+TJ.оg~d^~sQL.>kXfԝUGcPgzVⳋx:Ko^I'W9?*J>&o/s|D`$2Q<%UdM|PMh3)Yygw|_EHvM}.Ĉ aPT3d<$[hjh9PU7бH"j|ߣ7Q#1m6\#$\^B&ŷ+lѵϯ{XE6 Vu8?wgW9B0,&I^)4PX!D|\Q+ R\\vq%$pw#4ª`fN0G|7[^ BZc|We:s>,K7J4"J̢$.3LBeݶSrm ~Y}|N#v0&jl3R2XnqV `,X927&gzCP0)PДqhO&'S`h!C=àSJVb%>]ՌQXmkЛ\WޤБOT ;K }e'U1]QaCtټOTHBHa@0.kQ4lJ7Q]y*=I8k2KI@-O*NI])]T$X~Fbۉ9_sq>`) IChExl]i` W@G;&uw'M1H@i'8/F7L^f^q}U z%Pܜ7jUix@!M&:B2VO9vk^&L7 V^^~!g8״Xx\RǗdz.Oլ&"xT#k>(_BshIͼ,g5wM7W$%ȳ*4?/Mw}^ՓG<' .h=g# ߪuxn54eьs]"L9v*aA.C] H@- [Kv.{m0:ȍ߃ɫ !'zS͌ .Bh]5$y:Vy:_ġ#^5xITwO9/|%<e\ =[͇>&*.ChrqT7HV7pDۭ)oa9hI>_P-E3?bc 84m9jQ6s]B R5BIY`V|4^KW Jh 1> &%ZCS`D!53|QM7ݶՀ0M WuHC̀hϱ4aowBҋ\e5qsQUng!2bqp2krM.%*˴-%F>%fA?K^&Rү|IuKؒwҜrt|\4JX D$C|q'SBK{Vk72m2JuLjƄnIiz@M\o)|OjU{*\>Ւdqfeiɀb%O e5`"iD{"zN T!~FI ΎڌO/GapqiIJ$#V_q1+C=²a<Llq`6_ȯF{K[b q wgMp[K¸A+{$s'G+5>\FD"_oB 59kUfj\0t',1obsfH|j.u^B&4|Vl naZt2_ah>lbrq%4CmDS1(Kq(sީyW׹[qAoQx7:*0DwA8(+[겤j|J!KW fxXcklF<Ǒ#ߎ@v2~0p%d`+*Bd*\UyN|`!n\3@kCZ5>f _"Iz7pdC wYFTw+#(FPw a~9=೏-" EJy ?P|.˸f4{13YTq7Uj8_4N,Gz8 1fqcdL[ 5đ!xjO,_`)_k03ܖ-fF8I7TH.%fk^> 1C+si.a՞Z"_.v0eaԃ|MAC|Cȑ\}ҹ905 Q?:Eyi Q=-z҃;$j1eъGFjM-qD(ܒ "&L, Nei_b:xIb99:z !g\\)C"g4`/]a4RuNIHӵ /j!IӼ0](/*C мPK&N-/ "~'*'ﮔ%.W".Q[įhE١0U }^$dV _EaX P&W|I=Ћʵ%nr@9˗2xzN5iTZ@'=L.mvK[9z'%iS/[߈T}WH@GC# `!=EQ  {9ޣKtz\KuF~f"VwJ&8'Ҋ^.2k\ib#C. *+pݥRGxC9VXuUw̼*{O=\ 3D{D}7͟>=9`0+Jj:/>hS+ř7-4\E ]ᐤ8p%3KK2 [l=w8ÐmZbP;!vPNW[`t{do5f$3S(ňi,\pK.%5VE/X#׻Gy#f$K32Y&VmY;fXEOH48oG$=BK_PD!:0ni[jEvzhk1xTohix 3fH #npn@B+ bx _Drbāt 搌0ю3LT>%5L,)2[72.o!xh̜iRk^)_2 6 q|E nB-@Ax[( isz.ݐFMÌ)&_@mpe5U; O_OVGeyJԾ%Ԉêb9ڍC$]iխQ  "n2{!(1ӎ1Zܟreᨯ1̸KI^&a])f9 >.6͞-#g(!)5\̫JE&d]&DdQcg*"Aʡ2z/6p9Gc&}JoPƹoGOJ} <$*+`lISSTKrʔZtbAZ<ےRBu3U'PW< 6,B=ɐ|TsTpN7O%2F匮IGE^))4q9`ܭo)uhV޶_iB3Kt9&UE?\ 4͔$hr3*I]7R&1nIهt&D6jEK,~Xj0  tYqˡu^m2pTrw;f2 qR~R(1׭AI&'Z!_:!ZE8)*'n%GEC_I4x/XmO ){~DqX(^&i3>)k)7ܺ .Sa(խԖ#+vko78Xt^:"^V?R-f1ؤ~CR|&=(魚an(л-W6ʏ`xdv]#L.:cf9K<݊Fv!.W9-)1 .㋽raWB&8t* yC8"/ĕ,vhGs^xMy< 8fb,]=pD~̈Z(5&RF+Bz$CS.8R[x] 鼊֮wT{^_PAmbnm~Wi5W)C &5Es$\'*ȯxR vM(ɵ)2و83*6)W[K6M%w&xhAod>Ma"5n0OphDӐi^vZv RftbG 1PwtAxAqWؼjК%n£4Qy:dFȂK#uK坸^ʉpĤx邷`&ȍV]$y:2'Û`JP 3!~Of@C" k;g|efŽAcE 7{S=  o JbȪ]w`E Rۏx)fw kJeaB1߽`nSQ/ ,nj8'G=]RFn9I_߰2׎Sbr?)Mu'oQEd@pYA#AN%fE d4'q&Q&W243 %lfeT}TlUۇH#/%tN _n)D}_OV2qlw8=egI^OX>j!r'D^bܫVH̊ш@*^&Od_a@43ޯt Vs?$ ]ÅVq|轜R(|A4a cRhjfm qBFΌfZbJN6]FbuGt_t'.Su0)fb4${ͼwIr 7q=6ݹ gYtOHNm%& *p BO5nTqyX It[{X!pb 8N}uEK&I)I~t! xBҿdž"*Ĩcpb$g8 qo3>U}jWX~JRÄ](oEpg(7WbC7ުg 'ɲe\eiSITVEki,pi@kVuAz1%)Rdq2M$n6.drfV$AugtK>жc~Is*t!䡄LD:䌗SYϯPj9-X ߖjTܤkk0⦘1tZ!h5AfK_.G":_j r3"st')`fi|N&izS4p4/DIKQ]Kºq I>H}\U7jf@MSO0kmYD'G/抨CAl)!!- `$sO?tbkx"<ַk8XPd$ZY"l2E pe_@u~E5FE~"!$~t =<:nXZTa/.^>?3S>1}$6XqhbR|УQ1N: ;&#KM%f|S8tiˋWlS>)hE+QjNީ q=߉t`ރG{7%ޮe xOn5{+_'>IYs$rDR0/_M$z$| d:1}\ANIhDtX -Bo s6zjkZ*T:ͥϓ1vrVZcu7W$G@3"3:++a"[՗NLwP"$MF!mh)V Y hJ7:oOڈ0$>7uP;_ti~ e ;/]oR9K}an`άVևNӵ]⮰u&xOyŌ.>; rJn`6Itxq78cxL|9ˇ{*NvZ!Uɧ8V! 984ڇBw՟ $ `n, $vdQ~5MU7Ɇm{'o` wF)A`$!Oz~䇕xǤ)fWt13&gEE8cu(?NjIQ'XO$Ob|4c4 s$kh}ȓ$V/i?Qs$uH.=n3 D##ooep'kgjB– /XNKtBh|2{4PKI\BHWI]v0D0&aN$CVBl2+5s6# ztl%3i_Iےw蓴"IR7USI^Ni:I H3 ᜌgeIY#~G&af$) \g^Wȓg楥Xu׈.{s 8MA9`$0#*aZ64FB57n14A-"pUrMֳ&uCxAm[ !Zvm-ܐIw9tY`++k*2w^}=_D].`00O? Qkv81KV`WRQtpiV S%`RCo_td M# Ԓuʎ\쓰ڟRеmw !?ӫ*Wa*tpKVY&ӝ.A?u.4VI fNUB;x.c雅I)s-&q2M5UR hUuPrhzAO9>kY)1E::c,ſ:$ӑ_տ:PQg;:yCcUOCjt=/FϟkZ6xËqtԈ]Ůw+e C&?S0k=}b}T͌)OiNwVoIO'RCtFRzk>J_vK+9sɴw<N45r|m`!R^\Jn'l甏{8O'< { Ajۘ`g9F6My;Nq"׈ZgOUx}Wܢc:6un/MR>4ZjUIS#M/oBIj}ΨOɂчIT5WΑf7Y7,U!]S-=MѴ/y3A)ӵW N[/Ѫj-.AL=}GEr%yk'S+$SǺBge$2]aˬx9Hٿ)a~a!mqG Ő6D(\gmup%2q863|Fi0O A3,z"{1sw??jVM ;rlNev+2˵뀄꾔pD>S?Bm9S.L @}D#@$S< u=3<$W(&43Fߥu0jG~@}*ŷs\Wc~gB ^-CCXqeL}x:@ p qT%ո|uD;zꔨ2Otd;'Ʈ/G]7r0yp81F CN(@ϲawB>xOsh^x`Ƕ.ǣ)#CED"xcΫ0t>AH,Y'4OunZ6scCߎV\b|Øũ& yici=9gzSXS8Q.M[rla ڮQu-v?&#I$14k8w~z*z̪AW bZ% w^ &oOua~ߋYt91MfGz=w5ew;#=zEGbVŧ. 8^o'~G+Di89N_؄ qYSA9Sgl(FbW \%TcUwM019V0ܤ~|SAG<6יbN=> 4QE %S*jҬxyږ%GmK,Լ8eU'IXR៷8Mz[P9H@S8$P+xCzzO֘Kl:2Ӵ{a@|WHcW/sߐX-jYv͏bI\C/Y4/}˧DZ[ ~2QDU <Q> ("f1Ոz+*5ta18! fifZż_ȍA"Ưn0ɺm-Nm6xqLX [8Q,-hbs3M<Uy H:odphjl/vmz~Vi&A|=c,uX1mQwֶr;#6ƕ۠A,S @^[|§7U}`_]/d]o^_97P#scotch-6.0.4.dfsg/grf/4elt.xyz.gz0000644002563400244210000072140111631447171021724 0ustar trophimeutilisateurs du domaine1ef_4elt.xyzt[&˪>WesXƝhe&˶j3s_o~?_Ӯ}O߿gu߷p|qkj׽g43~sY ^5 ' ׺\?˟~i}|i cxO?Geso~fwLb M2"H7?= ,|Kew4:6sMݲ?O>M_}q9sӒ4qoZ|%[__wzs_l^B;7GΥ?M_ӿ>v}!=A1moj![SjOfW:={.Gvu[zuy{v~aқ"sy=|M0n=J`O>N[N}>i9/b_<,3便/&okrӲugy q2~;|%wU2=GoQ-/-ǔvW_}6y4>ZXͮkGhT#.m>?Dqa'Zx&iIˡg$\u bcn,Z꒝x!]۷YΙt4-;}}_GdWֶ#cѨmw]Ov8{~+gs*}3IlIOׇYi>mHϐ9iV~$}~|~-"5N_l֎iҽv%<{1K=toz>g -QK{Nn,ub#gȷo\Y#zc.X63n]O#g8 E/Jkвk_ԏysMZvxSWQp GisxI|Q:~si?w{XLvW!GKh?HC'Q;7u#`qJ^sUŚ_Ou%?fhGNh7Zzg9 'ط,7g!zOg_~ZvS篏gn4K=>Օg8ݺB[u{w.V=D>Eu JκaGI|{!659Mwc"H7v2c>U\ߍV bckXMxۗ?.1]8boל=Ϡ?/4N_ɠ[W:,7}AgM.Φ֘rh5V퇖kze6r9ufdA~O=+]Zj>52št^*Y"\%,q/bwg괌ᝯ-[~QB]N=u7hZwtFРP|whR/VGS^j8?#&Bޛ0N%e6/IϵqNK-8ݡ[uwe@zsi {Nԋ{y}-՟"GPˍ0nZ tw3DR=tDF]SPZn]g@Ƀ¿%ܦyuz3'!:Yzz %]yiᖹ(i75 7dJtۍZ|槉b^/Q w^mSf |/UPn9x¥8$^| W'\z2ϜO- bP]kyKwn,k/=#4x5C,C[pa6MAV'jyS#CJ h歆[CWt0oP]=6"oM@utE u4omEQ 4GVe=*>AG0(6~MD\rg:boqUBk |nCкADPDoܱ}kAzb JӤ tSf,&2/`(CzO~n0H#"a7oxׇ'zk7o*Wq W7oSgg<Os`|^_p# ';]ykx;#R l({f]okp}wu(V|^nkxGj_YӼ;9:yhn2 iet"M71{ykJ<Ƨ~MwcɗF= ̎ExMVG?k$|@MĻ:R7vDr<{[ˡ>ŷw[ )P62oFƂr:]ymjàu|^-OV#~ZM0g0 DM{yK Ny `0u|6%`&E[8Hq,~~rtl;*4u\FD7ѫz{4_Ղ! y\6/d@:[. iUgjs`ñ %W:55\\v2}/`йSP7]8_ߕXPYns@pba90%o1\dSĂ=@hJֳLOdWѭTs?XC؆"^L38]&`!? tӭxPS$ H%^L@^YAWU` fhtkK*G5j QVjʺKs۱Jcs?ShW:oz.<XC3b =U؁D3EXNd*'"z LsX.`~\ښz4>*VH?k 4vѧ ϵqkiHb֋c|EG+K/#|/hӫ]5dscG7Ȱ8'L.:o+fFooM+j#UCtc^Uԅ/v-iA ܚljKc.oC|G:{Tqc<5Trro$ lw2o Z\{W CxWT5h3k歉rG-b󨘜r,Oa^.fz Ri!VDZ[m7^9NBM[q Hmjz+BAa6oAD13zJ :L%gGz[ Bt+D킽 A^z8Z}KAn&rbm-5NDO*?[W?5qkHֱp<]>"ԭɏZhcշpZ}:F g~DNjzf%G0ǫƺaP:$~<^6DN$g]M_jt0gx/w4 +Ǻ]6[ĂR75oa_+eXYǼ;7u_g݆ybxXlKvIV uj=xh+[;},%N diq׎/T_߆a{W AqsikKOxW%|D kǸqDg h%ڱPTR,1v_$^;{YQl14$SQ2Y4ߑ| pDG A퇓Ijڽ"+D#<~@;#C 62(՟zvJ."֌NgqO]n:¿b 6SMTaXJel"g{3-]m'Z,Ze e)8O#Dpdx{Kw9"fkTyN3W=.AD؝?wbvk罀24cWnNzԹo:/c]FDgrIwy0T+ft<\?!gႱ-2< 7|;yjtfӸ03{+7dkQyZt7'2\׵q;?)HYSQs}G2D!b`[0coYz6@  Ƞ{$clt̗8!Y9_.\Cm:%#"]ڨ놩70G4Dfqom"/# =FS{ 9Ucm鸷>B7.~Ǽ9뙿$6*]pZ2 !FB[g=ӏUnCLTSML`?SqgV$|(^"f>>!`& N.a*'\{R~k@O+6g?{{k;Ľ*vqx`<-ێ(C[vވ!W$bqo齅h+QDX6uw6:@O{ MH3t8[cŽEj: N<0v)3!tz}Wvʂ_-5v5{ G|֝aio[%6+뺷oso(G/ҭ&B,k{ ո療O,5REmԾ-z -$8E3oD|f߱ ~k~M7/!f6cz}:ˀ 3KQzt,C f'@3eAxZ/]?o91P!ɫv~WkOֱ c%;R _;x 퉊x<^oKIuaqX"*Odj!ކq,CMLp]`{=zu,CX~זPhӌX^0d6ޅl:os;10WYap6~:1係Ӱu,c3St/iva_ GĿ¢&@M ,gޚ.E&. ~N24/ͭ%?Mu' c(c:FxNL[zɳDDmϱ{ 18Rh-=K:N2F7 E+]噢 sKHk.p,@%F`50u,CMJh"t,cX)2'@ b M[#>-zL~x]}^I+Oq{;Eԓ]XUXDc =Zdpo5\'`(o81v@ԃ܎e 6Mfi͢߼:b(SNBO2G@mDǵ?c & ꝌWe (!`6^7@PbϡX䨰a B@od3cca$77N2H2X.zvc|*I# >M+H#T}Fm0Xa'Qq4|sc6}?cde Ԫ8"&CUdp,CMY|-:_SY޿%N9] DetٔrYP XF7cm⯏]?t-HIwN#TWc]/V8zCscjСdOo-2qfpsÇHMnBP<_i2Rr,CMWx+_uۭaarnwJ*Yw,Ƅ$սpA\Mlj=t,|Q? xOGКf-dv,CMDoE{e#%^-H#wIE}1 Lmx: FAK @Ր,Aa}ݸ{&RMhz馆H!4z+-24+3 ns]㙶JuKҜY} :ciEBׇ~#Le f'Iɰ2Նha&ϊ-~Otxs9Ӟ!W_`Xڎea>ݹ1ۆ.CXt$-';=\uqf,g-2Юsܼ@o9Qwo P{T}.6e?o}]Dv4qǎ/e&8Wkc$L7B >{ RjBÎj&XJgj~';4Dch쵋q?']˱ |mQs޻cL4Gc>o-2z*@AdJj`k< \C5onȹr,CM;ړCBLkYe@~SB#2!˱VFr,΋,SzK~9'r^Zpp,r%LUauZ-2\Q8PXچ?ur,CM[j% b"O9ȰRZ@d{ bmJ΍S(/d[L.x˒$ܟ+8BH&˱f<.]J^ˀxVGEXF#B cۣ.2ڤ 7^4z˱FzR{ձ H}K~c9r6&xryj0^$t,CMp:O}OSϴ) 9ZG;] x4yI5e|E53Nhs|20Icc)c: ci(m?u?SMr ;'?$K䄩B{| vh G D.z>Ω{ešXZ-}&.p,C@0{5R݁Ju|(DîgnQ@V[6*XW7%w-f;]@'j7OfM-1~VK n2>t}S#[o(v,`O=JjlޙXq}$Wܠp)k;a<|ٽdZmii:,q/~ oPSpoIC)Ļ)e<ӧ ‐nML % ET"fƛT֙NOsS0YN/tOsSVb inZfR3t>SxĦlIZY~/ގe|N,9%ͱ*Tm`\Vo2>Ң<7gz Xz}(&'#"M"'˃ -G2gL6ybtJO?ZBkxQbs;c6@sxgXLecߤN+Iuy0"Uۦ9Ï֯2sպ]O},|Bm!XԽq8ɫ'Zݐnc R3asˀi/HjԽTm=2>w['RS: -=AT JfmN.f~BMCTmӗ,ޠN9sokJܱ%{1qž< '~Ql$=ݗaDBr|*Pb>,Sz$psgՈJLMBG3SC ~գП~_tWh^yMۈcrV߂/?sSk7 P>eikGV|W^ߙ5[$>c0oS94]. DHOV W/z\+,u WH h*.o'وCay Lr&^wyKK9]+b (#M[Xtwذ^+™M'Ua؅}05ot<GX pM#xd\74oP q0r"3[z!Y.:>kA R64g5wmLt>GvIcb Sm|#6; FM.<"$1=YMA ' dz[|EXg@w\G"XnC ,+D>VkO Ľ@M[ sQu>6^MRY824R>"Be 6S\ݑ>C'SES9"%3H#3oz8>m7tdhOM^M) 21_ڼs !#}/|}Whh1?ϴi&7ޠiAkCwy|hPqSm8;4(+Lmfi\u/I[8H+)eLS+|}޵!sSXp6Fb`X\Bl:"\3K!gsb|73}PQ+ }-00 cM4yKﺱ\|־/`/;ɔ#YV,::yk9 fM) F" bR\Xu5$B#ȦAOI p;vR=@ $BRSQǑ7w5o-]KYmu^qL֚"f-ٟ'|>7y P1av}-@P `x)Mvn7{_\0 3m@kG.8݈)+t[ϗB6oJU ?r>7@OȸueEt[z@YhU{hj ӕӱ84oH!|&+PσH30CS֠o캥"ϪrS瞒1|Ct)λ`B -Metx%ijނZ>(zn7UH>įbmaL־MT6`I1Լ`X 4(x"ݴWJ6@u_;y i4놜{<y C֡XRO/ŵYMA$Sチ#xWV`ݧ]YUVļ<5HO)@ļ(^w uEPz[6 e R>:M!q] d48޺-BױP;=M׹%oM\Yy/mKDo L'׼AK+ad;3x%TN6_ևiB@GKBaH70.2pM׼<Z lư|^{?w|6%+;#+gjB$TzD0^y5u¡MIp:7=pӐX~歏فgqH)g==V\& gJ$Ґe,[L!6~-h7"] ydͩW0Xiwd'ႩM=$ぁMljөz7dPʑ/+6N}IkeXtjt!~bF{*ͦSe\1x"(mMIO=XMծ6˥['mKSNiLh҈t qM]Y"Mt[4uoVƬ0v}xGsȗ%FHןAS՝,2+ߧ~܀>t>SLY,DfVXn:Iku`y M k1,0oa ނgZźUH~fg[~fv:NR LVǦOЈL2노ӽծUz (:hӼ@O)$|S5ykoB_dv ) j4cg%Y-QMђ0o G =;~IJa˼EH=HWbV;[A'?kNw6һ*_@SjnJhpBμ˽eĊ],SUao45ofLLS )<:G9ehM\[W= 7f]M) %Y-p!S |U?O E#,c%hXq(֍&66o-t)'mZ@[Q m pZ{x}Bs0CKWۼ5yJOr} ~U[!9ۼEǪh&%׾)ttwͬ)F.%Ʋ0oiL .:9٣E Ka PI ap-cw9Px=~|qm?q5uoAb_F{[2۸=S%8 nx-ʨԘh9-|?RUK i"8sH,pI,,~WSkZ25c{SݡiwS^Y?1|TM[v^F3-]eƆYX4`9 rS?Krt_"(zż41g>y7=`Z{D.b hiK^Qbb3z J 77']8S2"(>^H^/%uf{2Q[8o^ŵ Y(䅺wb'lF>[TE"(z-kmМ{[}`VHtpmuHv1DVJb_;o#6}!ymG" F(qUKʽ\ں !972R5`Gk:3].%\mȁm5(x;;ak^k)TsTrPQPT=ئemu ,:΁6]` Jfy]@w> u`kz( :,BO0/些]8Q`oapUkiO5}Y>tgv-{|yw9FևF3)&7 xlO^ 8wxY&${$j+nKa3R0->j zy:3M Xnͦ p/77 !hZ@ͦߦM(f-1LMwXn~7=4oBy=M2CPs{~Po$o(ʳtsٞG&\qmS0Je~3qF--2I~".hg7lo 9]#˝8 A1͖ &4ԗ~k*=pI* 4nFv"Ob Z>fcOFvVZTE^f4v&K`B&wcY0B7w!q˗q5N?n 5 sp0 ,_Bo -R+( ND4jpc"7h nyپd-f(.@2fcn .2r>XP 5,%mx 7b H5Nb~[5+Thȇް3e.V ˲ov BFfP7&:V>G][#9S~o )g52g7>.[6lOg[mo5Q$ر Z@OF}w=[rqQx~o1șgFD-Ƙ_ejif+nEky/ sH$1h*Eu60m>|~(`-E\vϳD375^8/־ak~ J{SYo<=n9&-؛ CuP7ۆ)Q 6`=IuiLJ0/]Nq> dPЍ8軭\n[z Rfu%o34G鯓~,&5Zw:$/ޡ4ݨFc UdMfsۂ$sʼDWoXf?ZN%N~sf+!7Ʈ/Z;n U&"lɳЫ-NnEjKXcws g'$ގ/ɸu[}{^$1~[7AsZK4G}$09l9{=R!ηٞ˱ԫo$+xud;3ǎԣENy,f "|󛫈+d%돧7J[t%{:Ӎ 5bىlcyں:f[ͳXƔY "a·7淏SSc{>fim{霞X/(jh{?ɲos+O%e\2>c/Q[T*P ,y! qavR($^a"*ayGYcE37[\[`6C_'-|!7'd ^n~H$k KMo2N]Shokw)EG|붐~&5ڡf2azKћmljwm3mTX%;\jk~}ȡՅO k| T"{[~r|jyVIx̰ua-3 AD)7س(v7]m36=1p42pِhzAEBb~8a{D5bߐ;`R90Aa4)E[jMb G6ZZ>(}mqIWf6dPpZA#pEJ:+7\e@i,R/}_tSf}7Vקmi0~zQ>-uR"noAZS놴4L9k[44ܖ(HƗm5VAgx5 7q[K|8&.ק :)X&v_m琂P_"w671+Al!+ ߔm, -vr,YoQ_7LJÖ{w60VMCb1]motnNbt{ /[p)z'u}:&V(%gFݿ/[ûiZi~c]YgFgFmIǁ0FQAq>P }ī;d>oMG›&An_% g6Lg:DrD/li)٧x=%1Ϛh;5v<%.L}|:PQ[[퓕gx dԴ>tSK/;Q)´W2(淎N!eY]fwjԇQ:c,R85фom5\lADx N$Woq#ng,J\BdxBrsRvQt˾Ry ѱ/POAp m:zwĈ-ceBSV[_;.E-ecB)4tK'9K-[[;o j2w ;^0WEP3rxI#ۅ~^ya8^Q&z}Pb K@xb.3Umw3z&>&t'V]$ǻL 2'ד} fù6I>Et/)7lor|eJ:/A]E0&.|=c]fB]n{ Oj@9Jpdscں,:l7O\WSKUZ7 [ۧ 2d(mbKJԿm?Jt)cO;}S0Ȼ3CQ˞fe%&Y;K%Pc9 =HW9^CE3?lJIt8^B*-b /AxS|~Wwiq ^K[nXAsqCm'pAd؄d1YHf r8vPzl4vYH:u2ɽId>߈'VĹs5L(aj/A7oj %OE Hkm }^ącغ%,kN԰pM!qh) |r [0WJ_>bDn Gwu1Ei}<YU܃]ak~k}u?-Z)i_4fjF>A`+cvp:7 [`6 Y89V ^Ř77I)dKr[d?T]v[RTM=ؚD Ԅ f?rlm'xEzly M o"#o]Q0vہJ-iv0i7g0NX?ؒ9vo@}MD~6 5$߁͋':n۹efQ)S e#D9[!.8oʒYN!v6^hCmd pl!Dzc2GQmbX$ oPRښߎFn8vЗ8n j&^n)w]~Xn`Ͱb8_dEll(ܓ_P(ɻ)6m?ڢq>4hbinko>*&ߠ6802 Gjk~|&& |{4jV',ݜG/!q.]yhNN8mm_\,וf~ .YpXX ms%m[7 iDܼJV[8l op/j8vm~$C"*Z3qQFm quoQlO[97GBo|K3eIlQ%"voᑈ\lE͂}GŒn#߀bNa0/7؈Yosc]o3"7tu3hSZk~ =4Q;I'pڕX.]^e.J}1v85Jr[(}ᜟ>٥|ȃb^ښ&s{F_D>67gs|jAXL [\ln 6X,-ϾJಞ ŷ7Cm#kW>E %Zؚ߰)65Fv`Q(?6l7UvdzM`8J&zūm^Z?#MKS!rO=FZ@ټߚ[%6?ЃZ.Dn aכI/`fwr-;e?yLE;j_p[Գ6@IK0@:LfYE%XcX tOؚ4̏ xr~ԚuBQ}k *YMj?@:\J ktDcq.nAs!%hD74TFnA9^yorzIݙx{J[C-_Nںa^j_ؤloД~uE7_`%IH؈x`_>$yA::.LK4IeF0߄_ KatxV)/w%pxla۷_</!-F=ԐLK: GT8I{s;l嘄Y&LKb)JStDpH`8E;{6󛆩l~,ERb:^Dm(i+4 q//JOa&aQNf/TZF);j9]cRNK!M >a\yVo` }oy7 <1?f7Le-stmgbT8}x t "|h;8^P9N/*Z9/XAENt"6Jsyy%(2\%9^2':=9t+<ƴ~'1/AHڏkX뎗yz%٘G:^ hhol%@ vEniNKp,YrC'mRJ;EjFy:^ Gt߲X蟏x JA\{吓:sDp 3Ÿyo:^ߒG 1)q% jIQٶa9NK0&!9e9^\EGa/6VYY, Ytܶ 6gxɷ8+<5Z=غ*,=xJ̽hP뺌G_ZOKo$;0x dO%0YKD}og(W|dcг |/?Fҟ>+jcl`V/;kg /dgI;x /?cm!&'he-gi/AM1 Ndg/ -*Y~r">#^}%Sc]|5فg=Ԕ\M\Ԁ[`"'^ߠ h~\ތq̈K#ea~9kևjG>Q09**F-DEhX_[(:bϣ΃7 Š3 3$] a-z^эz Mcϝ>eEӲ1 Ļ#&X&LI[۲.ze5/c[VVnKy91A"ߠhovv`#ੱvۏwG%;> NLsV-WS"7z@;L 綝䁢Vb=t qEgmG|5O :"Quk~ߌ W= 98zsoCEMK+r=#w-7LpܶmwZk1v(poz 'S01puʻƽ;kߺ1ON`lʹu5ȨEc1E2x}b;ۛM7LD ź \ S)P]>ٳm`-ðދ|hs~qvru2>^(^lz(Bl\ﱡ4Qp&Tn4e1tqFGmfwA݋^Ɗ-i~ۓ$?Ql]*`A7ud{sߨn.۬%~3~aǡ' gP)_[V-zrq-Aǀ[ |ԆD5aKOV0ArlovBnmQoa]Ru~ H_}y$א~Fn3:1ї̈́}l$O/6Qw(y`AKێۢA@bb0J.gu0&$7%ak~m#_R>:7LַnڇY}oi,jL磆Nw[Ng?h=o-3` wsoBؠ.|o#Yn+6hCP; ~^::m!G]C&+ uo,x0Wrj\FS msp% 1M 7L m@ (Z=@EȜAofMv̛w`0ܶA*3&ۀvi }rfܖk=@_o&7k:C) -pNeHKo}AmMb &ܽEK_zf/"RT3K:m(12^=%(ӂ'z{'#%*>z;Lwfz~:.89Z/}=ZE7P ؚ1Pc|/m٢q+G@`= :+Xa|.FnKN9َPnKԶDQgΊ\z;^©ZUg9`@cKFgYr4&/CηFGr3z%ݛ٧xGn@uoL?Rd|[g,uMSg%Ovrs/x K8A>9xIzhBѴmn;W88u,e&^[ʺ+֏KY:z/f|x mLɇ:b<7AÑuMͤ'-&bH/g=MbQ jܛ]ҊP;{,Ik$stO1ɥ酘+|1o?t1b=oo%;gt[~Ѫqbߠr~Рvښն}I(č4 9R{]}måiA4 BcBn lms[.=[zxsJm\;6/n~*`Mslr L>e6YӅhE'戢al>J?N##ɽo`cp=3;9m 1/V~ PQ54v8ťg*tXGnogjrƸ07AlX}78qv`07k3s. W7Gw>f&JytN6Jo=Wg);g{&k 4̣<=\RxH;${|7(1$!3 ًx REή:krk1bpN3`bW-āӞf~SqZaiir|/BQ/ml ʩ}~S4X*INg7 zE3nR.g3f~ϋMj<{]]>5Fzn~weNoϖRG?j7pP WP6{=ԾY/9֩]4л~~ 5BT&6gn~"`-mo]zQ6j.-{ ܎}xIGtU7Fad4/`U妵9мw'%Dshm@ڋw%{[8 ófq|s]R8^0' KK͢yqY{-I͢x / {. VQ&w0!\Bcє҇x=x qyM3xNkSjjx;lo޹T& FeYp71˨K0k\x F(ZhBȶoRY|܎x RqrFZlPs 4ž?.8/i=4颴϶,=bs/ϙVw/srp[}#%ۓ$&wC:'djn^Lux#;x/́…QD?q䣐me^n@K3:Z}+>@ ~YW+;@FQs#k:}aԏ:Kic L3pC|p8?c9~#^(|h.f;9nެ\`)xIĈ8&<|ecSy!,%^QȎܩ2`u w8f{0q Gy/-.i\h%((hrs[ٸP>@m=lNW4.vXq\wMa侀t%^xtN ₯ߛd:ܐ-'f*m7lqOJ:u5o'>ٲ^8=iY@-OJyx .10ok%Z` mqK'/KHMZw(}]ܶ_/Z[B<% %?<֤y PجqSI/ѷhOK>&WjKG}H/H!!nPC`ܖ:)c8Q3@@02 jh9p|%,#qVYX~ TټEmx-v :H>&a;Npr3qOyخ?XL7ɝ N%^ӬGv`KΏo}g~3q[>(s?6`l=/8/9h`@k]/3/9m14oj^%}j\eԶ&O cPttQ2ow洕e4ꪤfm淎fCo5N&A9+4n3A=bMb=joMo\gHW-~u[L7}"GŚ$^1w7{т9%^ɥ\#(C"8ȗxF2 gBR}K0o[$|B/&s=avPy<1{M[ ou~_ж7-+q(I[jFL]]\#hB!m}wEB4>OX=Bm . Xom3ֈl 'r<>}*${ɮ>,ܛɳd}/ߗ?R1*1%rf}1yE|7OXlԏ0s{p}`iQ?1Gž>O#s}e=빇|,r}0-;>!Kqy„"9^װi-c Ѫ'q]Uzq|=z·ێ}{6{E Ŵ[k3_"Tºwgs)uxsm yIUغ^Pf_jm="=T7غa2<"~"d=v]#kw8cz`Kz#!`gC',) *o-ڀGٙ6V}ʚܯo[Hx/xG:̶s=LCq0 ERþB[e+gy_ iCޏ=\Ezh;8_w'D~ũޏ3M`k91_ޏcgߚ_ bΟ֙G(y?Ė}|&Ќzu# |؜EI\\`ePle=/M!/S~7lF1"_! M[L5"ew@^ȲIOs/!(0 z}~a DFm;a@K'8O;&gbpg 0'ƮavrX2ԵmopnC wF)?vErzȕ8fw%,2[M7\Ba6112F$T8L؞? |x3Ɖcwg mMxX]{oхmς֟:.wvݩ?o1F%pL@hUb>Dʢ :L~^CJ֐ K`;c_$&g=%N.R=YVkC61gma[^_%HD7 stGxcH^"M )?5}yp[)Ċy6 k7\%okwkīmcEku̥ {0[#d\9b_x fÆx[f9c:vN>ބҶ[sr8fw1[v<߻Ut[cQC45fkqwkķ(jt'6;/G0'Z)m@O' {v-=u kt̫2^=.YE IjPP03}QsX;l 8l6 ۡ^ҋ!S87iqh[M lWVL"8#PxGo0.ۆx Ƥ9vj̥;[#vPSA*3vdfAy?9Ǽ%]C|z}:CK`{mG;<&q!ۄAP /P~RbӽS)kվ0)ݒKaߠؼ*vu)O*{ Pz7̑0v6n`u۷;/`c `o]H#lT"{hBl7$[eN ^<v?Ӏ/gL!9/wxbh5/@?v^w7_ ]Kmfk%M=>%r&sQEHN7 90ubčur/ )!ӎx l7mYjBK$lm!V^ IQi3~ж/sF2#Bm-!<'jX#x l0Wb=ցv=wz1 )ya7wqF/Q[L%N;'b# )ob~q5$ߐ@zd {mCqe oU_ %QWy1ۍ )j{iaxȳD.7cO%EЄnq#}P^ [JB^|.1(y+ݔ$G-m(30"XqixE!i_ 'kyg5Ut^w8n}!PoQ[˻Z^<4I8:J\ngG+zz,jf[8P٢7e~n§Ͷ_s /l[Wf&Dã۲lF̢f\9թ r_ "84V-|Mm|[斨AB9dh8d2gs|=ܨ5)>'[ǹP)st!B/zz`3epݖ:.zbR[7bj!~vö-yApN ~[n`01KrlZ7eE+zQ&fk~謯/m5ĉQo7!"'u]ˆrϷɧl)$_&Xak~ӎ5wῢ%>A?,~a~R@;^M;r6o}"3_n叴nK9Z7 S/>Q-6ozYCgL ڈdl60Θ,D<نMW/t+fѲ!nk'hAcPw0N hAܯpp- ?T{>¿1~/ڙ^ -:{V#-Z[Qj,^ŋ# G~m.[4:omy#7(ۃڎoY[yՐIRzmiP4Ei~'Ŀ;c;~9k(4_VrY[w-a5ifI75qIφrǛm ߡwnq/BJf QYtYd-m~[hhQ43m72% F#0|2I5ԉx9͒e@ǘ ·m~ۈ|H!ݓk~Ӵ~˥'2g|m~sRs^R]M31-,m7/ߝ"qWj }E T7HmrD/fgDH1n=6yLrzgn;LidsA:v[FѽCpo^gSFuo.w4o4Q* [epsvD4BE/u6~vx1@CMoPMs"z杽 GL[ R Zo/kz;dytV5FRPؚx>|q[FRz:99-tVܖS~iȽx3}Zr]"2~HoԨ4(5yoZ~9 Ꞔ/  s \gC;;&ҳ=>5j }7,`k~^UuO_KD[3@&Kd&Z̭0zDuJOeL\jk~ js]R\Iniak~냢-T3o[m9_b+zfN~H%I XAe~H.eALޛ<[⻋"J bVyo&Hvx9ܢݯklr??qnքoO~C=F¹oں8tOץIP_m~Hn׌o&23g6 0pe.JG7k8۹%7 qI-n QHu(Z:XnknZ.ez|v~65gjF} *|C/}`Jpے3o͉#eښƢЍfe>v:,l >99 e~B##a~4rzmf~#hòCMq:)T5OH,kpoCi۞-ݷh?jgeqHrLb;ML[H2Ϻʃ߄e[Mawq]u?~rkVb9,|m~beftc8zq==VɳWv 붛8G[cm~_㬸/k~C-%\7HpKf=sSK{h_%1'Nqrʌ?}_Yɷʜ=L pD `ܥ60MƱ/ }#IKK[ю>5?a :fS( 2%Y[,@o~}Kr,H^pD x/qtD=lȭfvc_Po#x 2 az'ax~0'IqF9^`qYl/m=+Sћ< z:^–'$VKmOJL cAa~[O _+0OͦKcsmm*: ?k:^9X8t88lRu~^ l{:^NQ̵FϜO/3"%6s [rz\MKa-K(vc:GvjcGb=8^B;9moƓ[l[dj~΢  E/yAYϾmzMWb.#@8*/e T.7k_5fe:OkXetr[([ɻ{m&5Km qӉgP[qKA;G+Ͻ͌Fէ%;Z7:3u~\\)lW~3q sS~ g@n{;mr٘[ecZ~EmS6B[mj7ep*KmA>zl<D9ខ~C->R"_# m6sCXm~[T[uwRtsFmI\loSaU9ʕ)bgro6j feD~Kuu~;|nб[غߎ@e4$lvOIh̥&jk|o"ErqqNE~q:^ wغ4C["xVsa(QٖVsrpS_K$Ws]bm^pÆ0v^k~((wq-ð|rFO{s*Զ-`5h7N-~sWO(?9=pe,E3jrW$&}=$"Y&?vO%-{EǾ]pZ kEVk-xAkH%[bDm1Umo&V݋n7Olo\wN4(Z/9C:nj(P/|č (rY:]^\]jx+ll gZkĴA97a`:Jڙ7|Vxu> [p:5jvm@o漯X;Dy_otۈR]VC773^6*|EcVd=WX zζ٫^Eyu[XJ rZ3uTPrxr>w5.[إnOJlQHׇp[=R˸PtfRϣB\c=Ki~Q'K/Kִ 3wB4j/Au8F*/2[$@Z+;wG/QۃAJ6\dɖ%6VnK\*_] }'px d7*qIK9wJltyz}W?KF/k@ 5M%, 'C@%ϾwacΗ}dY--|ErdAWSv%Q#30⹎LmXZl1oٶgK~,?ї%jVkR&/PavM /K&!R 28>.K8C<'/"ۜ?Pwz٭\zfvQXA(}2;s\LwrM^A=&֙%?Ǒ1S/|~9^zȩ4z29ƴ/AB@fnGCP>w9-69V jx fLQp˞\EBL^1(K2ᄾ=%sc`iXOmԎa6_َ̦@zsIVnO[!.oO/~^,QGߎL%k=/AkРwaں..X./AlBL`IQ/kێ,@wd~)|u:C.w Ǣ~/Q۵yՔiZrYoif3\lo]{2IEcڎ-u%50ppd5+x :p­ G܎FQ)t`  %1ԏ7"LRMY>;ߠҮ:#RcK0'pqj||_/Y#^6ݡ/YpIVJ-u(E<5ͳz;^y|Ok:\&~)|۠->Ɣu khQA\D#;8./Px_ۤQg!e u/A ^klK4nRwjpCp%w YzF//Y2K}SIzuy*b~2mro5ddHT}+j/ڲ{;^q%DfBCmGu;^eRk/W󹎗,Bm/qYx y! osl7Wg!?>ގhӉᕸdQn;^fdl9 o>QYB7N[Gx"c=϶ ;gF^b{ ;e]a+ϖl Gc,kdBC,ޑŞ԰BTum]HM_r$m{,~W/X :8}MK7̵~͎%k}hR /ɢqw0 xpt(>^Ƶ\<HgrXlw%G83'ơET =9" *q=8[8*'{&5m/}Rx^E<-m۲>6)K@լnj%Z؎gN>)5ϝn^ĖZ^s*8.wso75/y ̀%)M/̆88^i8X G_ؚߤHUK(E3 x/AZʙ6|x}D5<(3KHҪx QbZ;fFEly53r/٥1x_zp e}5xf1?FL|m `mEZYIJձ&/ &@oSw_uA w'?^}/A_oaSY5[?M%`3$T>KwRR˳^p/(M x&[Y:]7mowV\ath$Kz-,u\z7g -/&KZ;ڏ%3 KGI3=Лl/8 KA"P4iZ>\d\OM[*hX!wڍb;,]˘ F]0e1(pxVoc? Z~3Kq!_J6!:\N(Uv 9^r'~LiqqNtЖGAo) ˢ[E}.}AW;8`R,{k/q/'yf~[o]ĈVkM9zX[{M=~}6R7{@$B߂Ct/aYuou:^i3=ܜGKfyς Xd|_1.U; qhy383lodL|㫷KeL%yV;^.7{Wǎ\ƫ8eڵY`NukMM=ʼ/ 'ͤ-{u=9^Zۭx*^7/A*Zcƈ߈|=>}BWul8K&=p{qC>)'jx l7b^,[qMނ:7W%0Z+1٢= x 4;[(.&ߗx A\;m୅N—Cj#7=Vτu<[[jO_qMɹ IJH\$}y@^^~  Q\:M3d"j7ݛ/`v|~q# K)N˘x Wp3Mu+|'soP`LbX|mɳV0!~ uH:f*8fLpozmMt_ın!FhCUpߎ$z 9F|ߠᆍ&i3v|Jᴻo- $>)x ?ђ&8ނf=i=o= 3<3$WBē`2ku]˳ OFgo{ΛKI,^Zs[Ov?xk&>̤r;i;ւUn?߽i#LB^gﰞ->Ҽ 6.m-uvA? +CJ=kfK_9Sˢ-uQ] | krft0Hrhڛ 6Ok?Au#6>b9Jelz7w /Cjͱ==mo I¯Ծ6UosFpጠ9Ewmr}df<)cdwpmPS_6IwAU\2Fђ=ۅA`'qԸ~;,}[a~;M^W!fC/B\k!pi@pY'k,vHh,q78D,p `v W?T*.C-QsQ~8u‡j#x2o6k7;{dn3-`t]vao};oP+am-)XŅ6gvr[ف2i~ׇ!WpA>ox%)n<^vȼn¶s9|>%U\X5 w96VqEN&VݺcSm#.Y9\D^ltGHqт3zwdߠBu!ݝk}35%e,:[Ki~[YE`(~*s$Z,ul<~;9hVxgoQQ+χ~u}א~;x=@e~ML99f~;Ӯ~됱&؜gnϳKLa"G va4<ı& CY:;7P|=v=u8فQ'(ro鬽g]m_}~&g߀ȡ.qa+Ls.FC7ځGg1{fg_8^G jߕ%C/ԕؽ!ִ69s= @^WB4͜򹎗ncꍒ"ATQ ̵ãJϖ5%ˡ5lLى:p% u fqdG?!QK: Z[a[H zqD/(ՙFZ;1y>yN2i~[%P̔qU"r}\Mx//Q*䢈%$g/ce~usg$N9hp-#ǹ .J0 ]Yf :^48W ^uAƑ2[-mo׊b=ؐ蟏p/3wyaRKuVs=xO c-%K{K>4Pő [y{(M<u|=׋x_\}/{Qb}~msF͢2#mT udn~"溎6+k:t[L o0&Ü]VYĶRtub^1u[YϚ#&LaFb46hܯ\ΧRB-I\KŘeNڝ1Zx&ClyL9r$ux'uy/zimp; qMrm⏔9bSlD~/Xg~~D2Ѹ2'O~Mdo+I\.9] Qcpf.ߢQ}/(,xUfDtza۞-녥'IYxغlYWC`1(%}rгRfC-px.PvZžh .}Fɞxnp ڕ; L7u=x1/C"M]v}{:4o~۸6[7F &x '>W(1 _셭j I 񾎗hjV:ڑ\K&32k=%X3^KKݟ3Hq71¸vud^*VIMx ԥGz`ix:^N5g<ot/[f_41m\Kt 1*K:^ !яNZq:^ح3wf>wmG8^rSsg`-iu{H)d`V%i\5O#z/@ QidMB+:^Rjue̯hβ Tb{K e^Rhx ²T C=x r1kCD.}/Yr"1sc9^NVoB:^ehVMVǎ,q-9<~xȻJ<&%K:wj?"b7qgXml9:^A]ތ5fesoz~k/ ^K؅(hx" B' fuda:G]u}\;Xė18 P*i#% uA/.$$uxIѢX+2+_KlpK%H/ĸ// K|嶆yt S_?9%Ԥm1 +3__KZ6SXͤJ7IWM:^^Zg9 YhzЯ'ܛ2[Trލ? P 727aso-L^f6Nwqxغ&X ~ڡyulAwN(&Xn-L8fPfqՒiݧGvg+BMmX/ :\!}K6B\{xH;ݖ ߞG)mmPx&EfE5WհUso8;Et=RN$vW-z [w_`;妡p0azgj{Sg;%ԝ=Gu1Egz}p^Z@[Zlq,t @; Hց{tdq\#7SZbM0KMIaj~iE#Rp݁Z/&磇~/ɖ"I9Ux|]﹎8=eؚ')p3@?26:Oz+h%hԁ3V#0J?.Z%E;ĤesM:^rL<@حxɁ8?y:Oj+nA݅3Ls^%R8I=[K(%yzAjk~zh]rю~ &Z>Ν%ena|!b%|2wrW|KdQx鿖~TDE#28/Q[j̢w6giAm! {ih"+|xəPgHX@ħ9HMK40Cvn<&ImQf41R-:h ~{clo-zm` {3]e7sa$Puuɣ`>z굡f/Q[|_%G?,kxJpAX@27Lq7a-U?*[psӸ ^MJDpνx%5P7(Kz'0FxVܖ|fO.̊S6 ܅ zc_8^)< Y}/QtK=}mmw[M<`?*|xڢdK3т?w-UM." fzkи75}x zV%\&1@γ~uj,Yxز6Kw[}os5ŕ.P\mP:.kM7%65࿧1:^"+z 1 ~(!v</:OYŕG򙱜%`#f٭;ze;f&}xz Cy$ܰuM4@v∗ZkzpF\k7sDyN6q$FhDh0 u-~vl;4X0־E 5W; ~(ꖙ!H{m]VJ`tg+lϳf}출ϐl\N]WloXP/Ih7!0oAm7~{ 6/loHPv{%Uzts;%zu:+@osD?m95VsvB-۩4N%=g{ 6(_mi`bF;lF^9l;q[6IZk`|_q[G#փ%y/`M κ)Gs梟)%9SheH܅tq4kw7s:vFf~ ]g)(lo(~K}&wsojJ2Ԗ=v̄RYN`+;wq:^BK/"W9^r7UCbυQlYYGyKs = /HmoP *Z2BjG7ۚO`L PZ;%ܢ:E/ADE{R/eQGeغ8sW}-7lo'5sdzEa2T)NA3[ᦝ\ ߁5KЊÁW/#̽~;o'GS c-uzf/y`+B?nA| m%c;< nK<5kTzw'$0<1FHoeV!?jԈv^L"_g5ؒʼc>V7eXnpv[ Yġ`CK`H?Y';;-VvSW;)Qn&Δ6Ә@dlXU.bۙ3&E "-ݟ-gzgv_Tz5OqlqD&oC-Ne5 _l[o80o:GZaB]qغfJTS,k}& Zjz~\vtz5B?Umot,x~C Y4>,Ƴy;`qtPH$q(Z#{[d$xSV_Qi<[6l^#M &2E8 qg&$JI_xj~<냒2F#w۵p|TqALu뮶k|عkpeڮg> -g%_fDo tKk^I=Y9wG/r|붜kԤ0aeEl-0-/@I3涸[Ğ(W3Զa=1;cyŹsb F8ۚt[4JJ}PH3+ﻞbYrμ [Aayуu9>uho=LN+XO=ИB Be~# $Έ _4s,qKpz'moroN >ں h Ѯ7'ǂ߂7Jk~9w0~Q>[0cd-ӓhY:|n-u%"oڶgk`,3'z߷X+X72Ș@/F@N`߮-['|MN|jYKkS 'K7Q(<]*ߺ-m:CeuI٘kpTz47~8:ȱ&/ t[ ,qo69|8*:oaٺԣUtꔬw2.Ls٧mOT\yZ%Β9-x"gJN}ť(dfO۲j*y7m_$I_&@{7Z.5bFں cysH~;{sir;P&~Cw,'Лvipo:^ =]5Ĺ/l;8^2g3Y, Ʃrow%e\p}2ud W-OZsKx:^2LLu` Ƹgu-op)+8i$4dw%\gq2q;^2cVPi%CnF: +%>싫8h>Lnh!0v8X+&Gr%rUs6uK#*Tp}.8ؘn ]L`g#KvԒ-qqc\] =[Kȏ5.h<#K 8Y_'\g-JlD\.|x!l<}qxLջֳdkq(#քܒ$-~~UHMGWa%w 3}7Vy;ΚEw&B 42\p] 0m{\}ޭ<~hLCV m 5%KULsuKՄBᮑpoHx )RC:cyl;^2;|l1i73fM [N4lWQK.0~|f_ }?7Mxɜ I;.'οY(^1'1)<^%̇H[Lx EہR?( ghFxɍ$ Xx d0Wft|K^2Me&.zz /;r' %~AY9? /)J>W}Rx vj\v{Ԑ^vvl /C#%P%V&I{~^r/m V%zԛK0{53$e /q [*DKG"Rb߲:Oc%W.dw_7VyCWHya@J~LpgPަ AHw>KЅ`/%/uܽaFp( _,fS]Dž]xɽS#{tXK`F17CAspW^-vsc8 /Y&0Wv%k5 [Ma *o|7WxgoсO;]x Ii6j{93(o{4|C' )S]xɢMIwb;Sގ͂q.dS$IzA觾g^ip 鹽vK6 K5_S^ l|lF#s׈5c7Ax6{j|gK`y @i >L^B^).w0N#dHG(£Ij.SkE`B= /ٍ]a<5> 37hq.dS|^p3>XSl!Go/,%.a-~k)>gمGv翫 ɠ1vO]m@.cMCn tK^r9 \(yWx ,I@,Yp7ʽLpv / ^su% z:_[>KЅܧ5xxf*=bNjOs(y]x](hv >9']m r4 3lp_,EԒ.g3(%J5$g5B' /:͙|83ZUޖqݿn K䇲+=U 'wOrȃ{^B|Cq'T%Qp /!Bi'OrME/Ғ/} r.LC;W毳 vXܫՇYOL&RWK0]>ϊLx f 2y=oKq] N_)JΠt^rqІ/h{]x 4C]IpVM{u7Hbr_5w%(OzHNs,^# |t%K %z`s^%]x ZT0~>bPG-f\>s.@H3zgߦX>&p&nGԁwgk}QM*$ԙ] /1c6vKiR3+^2"q&NБ^-5K5}=i&Uo&7y%wLx ㈏KeV6J7af!^b/ -5y%7Qi&_ZR^]'^fW'^x@@5Zl/AyG㟈-k tq373 p&m :Cl'`x5C%kEJ~70${ĮYYłW|ҾkU:gH=4rh{^,J37(o\2>PBoekLg 0__EyuФ)y;㫟C"X3g'i(o䙟t`WXm ,+ПKϫg$X쬝 c7C{&n~3;(ۢIjLA1Q7;$}ٝC55vwIF%lN덪Qw.+>%8D*ov6[\|oTt#F=A1XZ6,oAS KI ^ó'<N0 wbiP$ͷONg&y=,o< vJ/`덭]4~VgV>AG rvƋOۈzx)wDrAWo)oٯx0m[_jXfa.Z E͂ە7H&g ZlcGX2e%IkoW&jXp.]y>_|oe6g+otw<f;^,o%A)b0VyGD/~wXlFA]yc4?6s+ogh+ۙ+71hǗfW#i6gg|P&}g*o$i3 U2!j:X6>y/6I2~vos-G~ă;Ky0wFzcYpFskg{6d5͌5l&_$OZޠBMu삇8p [VXG([n2;ޛ{ms|.ZZ<.EW UU 7sc[08M4o+WyC q;4V':&+ĐaH&:18X䞻,{v7ϥImo϶6+NdPmyv}lmywq+v~CGyoY_Iv!5Gt7rޛC*opE=Q(*ohݵ0GF;$m늵G:GQ6%|_(^ c!ž9Cx Xxii:>^ҩM+gQ0hy(Ir+w\^#܎=K^=bM%\q8G^s%Z˜X \{)%Fs)DgfpHeE^r"ȩcf|۸Tb1'h>Rp >p!A$oG.64?ż>94@ 8:K`nKhc6%FUЇ]O~vKbCKϠ PZa{ʚL^! _qء=uz⼈}mg|%.Y+;vSxINR^?P`xSxI?t_^rF=W򥽱C_ue6ZIxSPܨ5o 9ϟ6rF?Ԩq`y$_;KCg:^2̊1j<L%hn3=KEb۷|*Sx @*jRޢyWŬ^rzb>ý<,3@x^ے=RÕ֡OdVlg8G}$O%wED[9/95>"ݎ7vay+Sx %~ 쩱޽օI ,=)d㯅֠=)(~w'{ w)V@K<^9W3Sx A?t_ 0쎽{ FkGx6I:ǐBJnXpz֙=P׳o%KQK6|r{(L%eq$ AؐAy|X)c|qziJ^4:_7,\K@qŐI:6rX_K6t;[ 5:ہ76#slN }%w_J ,%X 'W zۨ?R,;ޛAw?dHx{jm'Ehpv^,3AX;z-%G p:AX!v BaWoڂU<'!'+vfCV^re`#q878^A bI*o"gGk𼟵 Dݹhq=(o'zXXmR) 7;glt0?=-v^k4 / Enq{.L?lMx^matמxxjփϖOsu9i;zKx hj"9c =肻}r/A,VI?X0+q89cۋxɢEޢMl/a+.cǿM% ~,_/oK}@ /Ҽ6]Knlaٗc=/A,\*jJ6^/% +p=^gVW޸N~@%?R)=0pΝck|/ڂ ^mS[֝ny}gX0]7=4FSYAٽϻ孠o \#i-#d;CC Y3ukytp~k,R/swߌMyJcr=l{^msIC26SVk; \cMl̂2JM#g$~tI糓k*oXSy ĎKZSy5\?#|t/zuNb})o /i#~Mm5g.)ol6iׅ tTHJ|% ~ѪM%yms /T,G50x׺i"__;KF-T N/bHmx2=^2P#Z2"w76jp\mR:h /Άg&Q0q-db(?X@ cT~ /v~N [xɄ&= `@6%B%l}wo%30kyC) wXx]-"{gܹXgδwB>{%ī= /8(^{ /_5wɶYYקQQc^r_e8{N_{%m%xX#ØLvջ`wMဤR?"sLl /b5߫+u+b7uju\\G̃qk6ˑ[Xo| /=Nkb:^ML48޿(w{NAvKةH[o8[x pF+?I_ȱ s^"_XWmL<įXG^ H-VyΊ3+zy>/>M@Rky;3זI쩯|ܜ`j&M{y:K}1 s8/9@0Y7]%_<_K/if@e?# O ƈҽX%'i|L쁯|sa=Z^r_2p{/Ol4-s5G_;K()_+=qC_qb!^X+LzĒ^ F::K@6m4V[ ^%edEheݼt vSgZ0 ;K6.طgM[XC{(s$Rot qxF_oS爵C`$į1X=MyywEpdӔm36_롈K.ʛ9Y>wv *3m7qqc7hPXͱӋb= Y2<*vMg=5No%2rV`1-o }7W#v(b0ݿD_m/Dx[JﯟCpB paV,_|-6IەQ`j^P:8/ )g(o;eg zhGxCy[F`_p62 mSc̦ia[{B'Ǩ|Vfax; S@5$6oRqD/>Kʫϰ՛]v3|=–GǶݺ>7v5WL{F홖/, w 3-ok6|%4|V̦X|5=}O7T }Iߺ{Tfb}IgT&5ləۢQguٿ*oYmLPgZnHffFGb/;؀ ,/-ۭГsB\E?|||'نa7;,oBg@=^n"Ox71yNU,G\صotC`C6NE/O >ZZεb|K0Ï9%} /pQ< "ӿ7%9$8e%U/ۡoפ&4@'m̟AxXU%}p6RCſ %'^.}fsBxɍEǻ^2]ӈ{ sE|{0cn|P #W%C~B'o8G tc7Lׯr#[Cߐ3}.XKf5k]_KFs^蜼ۄԢtdbo^xbݱ/] %إ0N@j$B Z)>)V[A@ ^`H}oc7_gQwslU0;_Ύ$ObgYFMx '[w&NGI̒&dohz9ψpZ {v_K[=r%@nإX+oJMky۠6mi>|FX!lZ=6Hi慗lj% Io^E:J}-KG#k25^わ ,݈Wx PpɜHty ;i{U\4?/]wͲ'{U;]=o }̸B`&3XбO }@a}0$NljWx qϞXhS`Lxap?yARJqAx vC?b;^?5:x_gK IݙUx*ogP7;CgL.Kb,3 ˿ M:0i6f1?e$^r@&J ރxɍIEO؞wZQPH;h>u%",p38l%[c]9]Leխ7AK4QCދzu>;ycb73%q;gvsw _~vb/IQb-oQxL%J[6Ţ[Ip_Xۍa&7 zIc H xUօ~( RhZÃg}tUި:OOMb?uc)<ݪi:V=@&/MygXxtئv<1-6ON4^&M~k2ֿZ (> 7p]Զ(;t8m7f;]\_ :۬7ys6pډ4_Sl'zP^c*b00fy0Dm|t\Ţ MmǍePp k3b-o*x Ak.XhS}}M/fyPjζKn~-oWꤧyxCш?\).'H؞b78bɫg@W +XXmHϡ-*F2Q|ٕ7I|gmu-o ƢFR,SVړwOXDpoK2xqG <&&2,ow[M:DsQ;,oӯc8O} -;P7Hy1b9?%>y[qËlXۀ=UF5.Cy[wOZB9YCy?.vZ']}+׸Ͳrx1eXܶY}Ss`Zfݣh(~g}9G=?l 3&Ziy_%O y [.nHBNPT,tJOx_Vϙ'a)2_62-os6Ej.gϠ[掃ȩ|j}`r&Kyډ;l#~]ۡ.JO3m5`y#v?vbuɼ[=)_b-oـ7h[XۢZ%NM֋μFdc)eyO r,'Q,4+vb79+c-o0;E!rvCK>|i~rmb^!4;>d*oQ;{ȗq"~ %}ڻB9^.@&wI,o8qNQ`y,fajGTw_%H tz+z^ KG{^qU靕%>KI;s8 :󦹱M|E:aLhldV,ofBZou%hkRx (4S8\b^gWe]z =%&Yi浲O /9b"*LnanU:Vnp3!NK Uxi}}S )SFئX }ݼ-DU=􀤒6GigE33wb)PJʞbw~ }pKWn#KTy[V:y7VyP#iA>hvRp-t\][T%>;Jl3`PEK;yfǟx c &?;N^[{=vۖb9Of3<"V1Lwz~ӌi-HE|v>ڝIiʛſJ;'1kj}4F|:f_m}/73Q=DZgL bƏk.ZDu(ovy&}}mX{I|=VyC[C曾v'wK߱R*o`R}w[6=XOأ>Z̟w*o=S8iĖ˭d^RE:t ;v'h O[7AGOF;^,g(. 9_,;(;0bIcHciw dN=j_h3|y)EIǝv}K߼9 ^}Y/o^fbr-Sy/ox\*mKyP=kj:tzm_X8ՠ$?߶6~>R7#Vyw??by@ϼF]4>~2LQ0Cs VM9X/"#bfQ< .] ÿ~hw6:{rCU~pn`&]Peע(b7 _qWOyW8/:}k,@qg*7)oQ+P+c3z/L{Uv4s X|whP78g=Z!oPcal]OXm vX,5#5o{xɦ0~ߦy>tl=dlk.X|{x ^rY"Vy;sLOt]a^;9oo/>=jN^[q=Qԅq5%{cO5Y}K ,aA{P;SpU.[P*oc?\lr^s {`b&%l2;{\xoK07VyupYqX&Ʋnq.Jy[ T_TH \ /cҁ]{<]|KJ>L®7 ^RP z6x bq}oMe#ބJWUc_?Yn{^q^-zw'[:|yw+F+Mx|uGa j#Vyս'QX0RW@`rt^R6قfr^By'hpp6gUWw \pƼׅMZ]oN2_K8|5$5 ׌gPo(%{^s^ؓM. AxI4 k5Myх@ !}CwYvXT #EDZ.`.C`O+q>њy<.6 ̑ +hC5~axRH>&聾/<];`)&M%UP8<8-p$k.ڴ:r.{Obw]xI5?9 /n&)Ax 4 + nOK &U:"p$ 3Lbd6w׋n*p9rϐv%g $bϋ=%כ} 'r8 /od"v+v{G2@χ@N~@^r_N=ҷiG^[pGž.r}XAt,gpxjВ^u%^q/^&ȌYVH[?n+..?'AxI-GkS^4Nx=%ydf/oz&97wJ^n v̟K^~Ԧx[ًgP*c=oS..D^A{t37MyބTbawRc /u͝jkj /7E!رK܃ixgKxX ,<X / $i5Vݻ-t% > jm[#}oG&tV}x IօTyq^Rm-T7ӅT(_=Mx cR7{ڽ'܅TtHh܃*o8erb- }^R;O˗c ȫ7jw7_Ϳ8bЕp*qcN c_(Wx $M^XzUٿᄍ+B&?慗ܻGCjhH[Qހ^r؂. 'C:Nh?wI-v c=|ewܿ!%=5*owe[bwIX dU >{e#W6&%`GK1IDhu%'psũWxɍťi԰x?XPu!.wcEg6$\>+7@Q 1ctߒuԢB QH*o!py7o[_2@| IJA4(hX%/F&Ų_-[KAx VعICxɍ5-As,'jHdb f)-{M6*. F-ĆV ^yºm95d41~S,Kձ#h+wl{/iVGNZ'Cx ېO{_=^%!k;;K`!r=Fyޠ8#_%7X8#q0i/f5N̋P_[!fFq(GlCx zzSVK@ۈö)GucFf{M0cM};2;3ux%XRѵKCxI4֤֫<΄4Q幃 }>mp@bN;(8cv}/%$΋-|f /i:ȱft'v!#;9C {M6A~jqkN6]m̙{jգ\f/|L7t޹mdCx1(Fp~sU` TUlϖx3b6U Yg/>%@EcJwD#Vy4(;ϼH6%6%goN'^rcw Yl-&=%aGdfiI#G>31qS߫4; 7t%F_|]Wݰr);P:ղ2_#?jPx%ј;nxő߅Qyg+b#F(W^^mׅ[=F>h T5Ѱ~Yz/iV̑ƍұ!qrm/2 {ijRk6Wg*<@uk>64;4_;A'&sI;_:L섽\1'=(N`&;s;N0tfqKU'U qX*oݼf}hs, s!kqx_L%8@AN~|/Kez H51^˛G,< 8S;8a|wIN=co:v /1ƀ ξH[-x^}gc*I%&f v /k.( nWwy LSKD?2f"%ιSxɭC9RxmVpXmggl#9ɖ#Vy;.>t`}Gz<}NsISxI?HPt8Wy;Y/@̾h&^PE"jޏ}{v /̌;b닥Y~={>^Iv ICc/w[Ouj /3h-alߵzh3=&j K(Y֐6;?4Msvw PÛKas^2̟wx} |)] 1X;Kyy+s>keTԁ$^cs#J } ^=`ul#Kxߐfϫ!"eK=RKx <<aet / Y2e  %>% 1w gſ m%dED Ɂuj1N0%aɨ}JSwNד7L/<Ӷ zWy"_P<7+1lz0/RLğ9^Cu %dNj4UaƘ{_<}QC+*ob$>yuۄ TÉ*o7X%͖j ZK8~{{u6}?^r5~,&gZq\n /f<㍹/NN}IٻqDᰥ\—` /4JPns9?u /F`}O_Kn=bx$ш#6?߄LI$3֯;A|#k%Ƣ6#t8?d^&zkvM)wymsjk&.&=%:-no*Χ>΀`9s /ñzs_s!djvR@e *w d}{PL^5 ˿:خXj/KVϱ8Ji{-ynq뺀KxɍE48799Kxɽp~V7[Mx"u}X~3Ə)xq&6.%c\4~+nQ$'\{:^rcy>O-%y%\HU޷u^mjHLN^K/%me<} /Ÿ́]n3u%~/O>Xvk*A /AlO %k ,5yOm /Yps&i4֙ܣbи\Kx |~N"D }ι;~@YC pﻋyD*JNտ w,H'^={.%w_3傄 𒻯|*\~ c7ҾBT/ d {^r򹾘*вU-),%7ka gޤlyK֚&^l2#W /Yf> mZFs /Y^$LwA:ۮ☁ .o;-^㠟Źw֐,o%8FS캵]Cn /."i&ւv-dmU`uK=qܗI49F,h1& ,{_%dgvxl%7 GW.^@g&խF.bc#=᱊kXjH#K[i_j^|^]H/X^r]OTϻ|-dCD=&5޷Ҙ|8/n\8bս}g /#dFQ}n| /#T Bo\/مG/3xgKkdu!Uܿp /jL -@IbNo>Kv5NCŲx5Cn%Yz E >[^ݔfF\f /nW:0[c?` /oI %J_cyMXMM!Y^#r|wH3 N^DԱ(jOx>VǔC-dj<Uq w= 52Kn~Hsm%h? =hKBgFwdN^rUӼ^VIPx FH)GЌcx[x1kp /vY  Y{˧toKgC';ظ?^r0h%p.2ݪ[x |eԶ)-rjJLs^) v9ax^3jLzGx #(_4GL;>KBi~?#Gx WpV3*o?:􍜧>Gx ݴ)PI㯎%xT끑}=J˼wp'P8ݴ5#VyCNS?XjU4uq9K@yV7zc/I<һ˚uU1ʦ77td`2Qc<19p {29zĻB|Y?ʘ˟ǚu[}95BT3(P,idCk 1Zآ#}G=F^u6&gVQdk0^~?CyTOx%g(o淘璪A_=΋;Lʉog(o7j=9t1xfshSG9_ @v*o0fa)9}bXQsl7fT6K3;H=g*o[}xm &Lw{*J6\S u3ͳ04RTQ3Hcx _,10Q"=vu% MmB>Ky^Yw#{v8z!6Ϊ/T!A^9k0jzвa8bI~q!gl 4_M bb'Z⁀½/zHgmrs+f@p/}^74JN/ޯX*vLm-]s3{%˷OR/鯏͞DVJ\Gg^KHh~gVȳɃvz yZl 7i{[*oE7aӍa<[Viqd79O#_4V=AmA%\\5?{0b7?$ϳs#k9Ϡ g{)?  P`8]}=Y|uv7*38J䗷QJK>΅| I0R3BO 6+k,絮Ms3ǻV,zI|ۮ/}y3xb0{ۏ+bOU'O&MހNĸ:ǽYC֣zUxнQZ`3x3|/&a}?oQV\#8Z5}=b9f퀄/ocroJV_Ԥ=Ny=l:'<ҞfηFZ:0o𩢜b,*!AXɸ IϫI~H /ߗI_ Kù>l܂fܗӿc%p+.&u5Us5~zU`=3`-9N%:\G7KYH'j关rDM\=6 ?\K*rmoHxI&]쟵\,pF&}, /~=oKbD}1ӌ.|Giq0VUj.Y5Vi՝ ;3W9?x|7/k'ջ=xVٴ#ݸ_ /?{kS'_lE} /uKI #| +NE~K*d6cWXxI5ɓ$?kx^JmH$r!)k]X]䄍Kj^fhn| '+Z:N7Xb=Mׅ%aQ].T3{^B sn׺ؿz-s:^RMis|C)ovϤ7xO&Gzg"|-EH />bޢsoSxɍe3>a|Ϟ\7be}Y+ɟWxɽR< ^_l#),bML[1X=w -6m ?# Vy;e,K/Ǭ^Rm-Av(0GtZ`Pk=k/s /iB0bO^}tf;_,gwTj_% Q:\5;+&-;K0b-obv>$Q|/ia Ioly,KҎ. KF;AQupcB^f^N^ԗ#}*U*Gꡐ*o='f:7"vIݙb>7K0rdxALAxSs&vc:1} ^;Y([=KZuu9Fg /\^j3Li"m [ŜY !7D,\K!ѫ̏/Yp/|߃\^Qqe[Sfe/ԶEYY qQXfՖ䲺g$VΙyLzT줛^-7o[e>4,ox!PZRfȼ /hH88q /"jBu"nDlEx zWA=Jxɍ]}Ɔ)ֺ^ME]I=} Vyf M|n%s-qjR:[XJ VU-,b^rZf4&bۗZq$9Wty$6zބg""NPA~@^9 \.K0;bJr"'~Wy|sWHV\;c4sհTlO/*o phc^Fo bH1aFj%Ffj`NԒɻw&Ǎic] ۠nOwc5_;KТB!2o,+׎F-}n)K '}Cm[oK [#mImr/NzW,P<6gfnDO7;ΊMܳ$ԽEx b6/8՟ıMe wtȅK0Ҍ-s_,9S(ǘ _,k!^w%4dA33(["Vy3/}km6(K('}bZd~nVK /yCX׆"bbNJ| ۽&in~7/$CQP__/AjܵDHAo~F|pIRϝp^!v)LPhRI%>{A?%5xfQEY,OM3x8֩[ ^<]F8օEgN:%&dP;6z'y$c1!dTb€*}U7mbO]d 8/o$\WAzAp~q^ u-k<7c=N^:˺{'^0y^2:fKȳ*o4LܧJV4ƌǂd ;^Y{T;-{ƕ1+G̲:^fF{>XmgG£`{Fg$eP|MV%^=1֦K4!Vy(N ݙ1p̦ /䎒qi/S%HTY&hXm5)kGxXԇ>5o^BdY Vy{ꈳE&XH5߹P1L(a{T^2 $]k&U{Ww;+n-=ٟ_ό؍U6dB#lbֈWxɠhV驟@ YL*oGFAIU 11ʎ{^,FOO0%n a+ /ߏ q:uҝULgbTMbmu{I^2OrJ(M JGͻȔ5q;V7kĵ.f507~cbK1bOEV,owq>]ݼ:p=/4:GlyأZnZ^2 WO|F:]/1}'INY^2$߾a2=u%p Bg\+*o'k|gHԛUx j^FQV^2F-Mxɍe5 9C / gVttX1h8nI۽,A#ϱAx W$[@F5 "Ux RajIt/M\o{dF^2ex~ha׃i3WsgMΩƍ=/vU|Izr7Vx}tZR6%v* v&UL۽gi8WZ Wb|Uxɜ'i,'эU&MfˡAD61g =ބN[\K jCWr)on=7ZN}]x\oЮqOߣ@VKƋ2s3%7\M+ / >+q-EF~=XZׇ{Ux4 #>9 ڳ7.kw؅;D/%`%~u%{9v+dϷT_҉RL qŦ^2dVs / SyXUC7mqAyݩO{Z2ky[ _5'݊uxW|CK k1Kַ@4:von{sEOo=QU%T][^ro ބ 0UecȞ9O錽Dx=`)3۸ v?-8tJҪ4ТZZ1oLc{3lr< /Y g]h&x"1 k[|ZjɈKeUO+(A^5dS/tm_ԨXXxT^rFґ{%4%fʵ7&XE^XRjk&du6[-5%ѝg =5X9%mK\F\ɵӚ3F3ᓃjw['>*bAC^B!k!aO[24]Nse /ٔ/f=s#Kn&F' Z=m /tq7^y&l~^/_j{ffZP]ABXՑU /iCwlL(& /9脃BA)F͸|Az).LY&Jv /A7 I4MxɹvfOnd́BΜAmxk]x ,Dш?ߙ m+wgϦ /)?Lx m?vhQ| /PScTK\t%}=^O6aJcADl{x-q'ׇKpC0>* ʛ t` ˎU@t.Ny b b_H3*# H:auz[b{2(5!Kg4 mAԛIW~ʛy4; `3s,ezW%wEd^G_)OϨZr8E+7Uh^Yio%7R5p^/ġ:D]x 2?h}Ny$Y~t%~tr۹Tx c7}*ZT$հlONd^9G}wm*/& KX4#݊d\'~K/,- /1 :ϐ elfL?}>7m>'r YN}(ou8s}8}kr[FN$=㡼U3j] 卷K7UNVc^ͱ[cK83SFY.r{^,zһ<9AY^nl85NyITn\YTHg/YDz3)of<4\O{_3ON )Om3їFQi}~ط{XAJy:FwRvh@hq-;~tѸ,m|g&簽'ܗFJΩߥ6ϛ4ja.FKs\[bYmVx\rzL#ɡحmLG}f=mćtY[y {] 5Xn/Had&[ywC-uh~+omb6^@8g*o)Iߦ 4\⾗lЉ8孀<{>Śvw#)%h%nFDE?7Ծۦ [-)?e01~bѮڮ5Ee0vP,/g^_iŢ(ɣak>yǮ)0EiX;g+r{cZW6>孂hGpUGͤ[@^_X'~WySR-5)o$.Joy:Aٞ5;{[XSޠ!mX孙.Z d~,8Oy'^pQSIݢa 2Ӗwk |˰zpmPң&[, Ū)pISO (E/'!$4FQw^r.(Ζud);*oTo|γ;WQϣwd1*ogD_y78cein&XGbaQmєm=ݱ_\ۤtbb97͉+MDb*o&RWvt_d3(o~ڽb&}n~cП14FG;/ >cQ~ᇲ<K~V\O׆K*-\Bx57 =IzY@CxɍMcn3+h>߫B>+Ѐ[Kj|ld>kyLzewJK*'icO%8"ݱC?|{}!BP g׽7>JڳFXckCx f/k~'-Vye@%6r-{~KYޕi]`/6]Zƕ) ŷ)vQK3x 'CX~iઝt7ԵL969{ 9\h:p1?4pUJx5^R7 Ʋ7ڦ8^RM;'=99?Tw1]w&n77!bK*xi| /8~l&'g-QWcc Cx]xQoZ|K*ŋ3~^R23qZw.%pa׈Ex t O=!}/q?+~4}2³Zޚ e! /i5JK}{ If]9o- _gKDg(΄ʡu'957%Z;tiYq /+dd$6kGxIk$gqXDPmSx Yx΃KZ@XIK̘hǯ zX"VyC^))oj_Z'('3M% K3v9j=u /a_̀sR %fTX$+3,}RxI+;tN^<Z@u_K:·i־Z\mXj(|6j /~{ [w^"u ~#Kdžjb񼖷[y% ct|1/ 3L^ /wڑ=;ʗצSxIւs>J%Sxɍ}X3sc4lS_R3(okT50ڵ9ܻ9?Xm^rK 9#[z'HgKzNԊF$wX*o5ɚSxб O%${X s=TL%8{/cLSx LRqϞzzOm /,RS=$1G2Ih="',z=4 x^E5$=mʿ7%/S>[ڲSxݡVɚ/Ӿ^נkͳ-f3tA}keEU&5~h?P[wI%^(/2trrq^$A/(lkKny& ?),3w̍P@;>@'O763(ol&υB|TymKFL&ͦZ`Fmz)ol%~^3Fᄽ Pz9d}ӘcK`J2ywVp#wu"8l@bGwZi6-M%]Ijy+ǠV{,lZ( /rllVO /xr[: mk)q$K TwLa ;dh^0_<0Ay3Yޣw׎aDͻdX孃T]'Ƹ/% 7j-IR^FrK4t V~Xꁸu|zj3Yg]-%q^l/!Vy(dqt~~WyFْ4iqo-Vy8 [a;s%=xmZip /v9BZ_Kp<+?CfJbI TǕ2H}ch^|fan>>@& -F]${:{_.%1\a1s!dlꤻOl+-~Zbmb\1\n /z @v /&L{Q>^2mx ]Kb}vKx8RuFmgi[KV Ҳ.kBT,ìՎ1ރ-Kx, 5Fhπ{ʹKxɍ s47Vxɽ_jXhS 9 y/ϛ+L48Mqo/^2k\ ]wpWDVb'wZK& UK}Gu%d1i^G:o6 d:zfYKn,:$Sf !2hΡ_Kf&I ~*(^㽄L):|l0::v /Z] ;icyCפ@8G__%0 1g /^ 88}%T0-;%dBH /bPK@ҩGˊ9b71gy\l3 RF7)~(Kxɍf3sXK\ -vKxɼWϊr6^2'GlF̻ucQXK&g7\W_m~;.,&]9`TcbBh?Mxɭ;5ϲ 5[Q/3 <ė~Wyz I3nW ;ƿLR/TOܫ[DZe;;F炎c&ܓjSp)aۓ 睖M}6u /usj~͛2Vx 5;'Kd۵9fæj.'K̹/%a},mo)g,ǿcYWb /Y)RdX^lUȧOxک7~OY*o V_xr/%B#l ?X{`cшU Y{A4> f~} /t4^CI{S!%kPj  ~Xr\fE/𒅓7ڜOhn%7v 1O6gn#0N/aci8Q$\c /1Fbp8޷@dg@@[}Uf@$8-zYs#3'@{[@|bMy2{hsE\~3% ">ZtDk zY^m%]T ^h!f6ܳ^=]q1*o~gDg|9d)΋K6 1J+ K6PFO C(WWnϙgc#-dOcu=Hϳ0"N-dว&&[-d@s}g^^BYv0[]b98brf^aß1l.^b`F% kl%w}6ӯ S߶M{OYEnX { E,A\~`?b*@^y5uBc /g" S8,'aXYUcga'QK C2iN'kmjUvP^CG2W5 X{ dL=K.!@B,sU)ul% ]z^X6p o /t >T Qx==lXT%8] [. РQl,Cj;m%X{AwH KCU'a Fçx / \#|=/\.4eQm%W҇!-]#~/x,h&DbcI+ S(ΟK{oq(zTrҮw*u(RoKOG<{/zZvw|7xbU^bNLG*oCk%LkV&q\T*oٌG:3^k'j/W@䍱$̼Ej7龃!Y;;gGu.^2Fj#gRcQ%0Gw8Kkއ(z/a XK ' [;,a# 3ڎةgcCfK%gۡVZ_ l<ڐ4r^>bd=v:Uy֮H=@y&bˋ:ٟҎUS#eFͩ[[1^je_")鰚|lNU:4I~yi6Vm;.wz4%Y^y~fBu֩wq¯־z 5mPW3 ,i<KvS>3xpcֈwi"(:iiۢB+ cTxbYφr{F?+Ad'F hf:4m:{y޺\tݜx32]Xnl;z@ЕCt)}`yfW([ܯwO],Rh,둢!/zY; yz ;vߵ$%}otQ,?佲b-ߛ|cgłs>CJ7LɁ܂H o_y?zO +mbQ;}|yg RK/Ϙҗћ;~z`dN<7P*/,$O+q=fF g*oXܡ['utbA@ϺYOG;F ,T[ТܮuV+cLP}s1a{T3=l6g r5b1ӻI1zަ6xy 9qNmPds s?70 ^^=Yۄ{FA޻=Ky3ۉ7Sh)osZ uZ]o,mR ܱbk齎7^Iu/@wZ$Ve:kX ϝc(}}yzƜ䲑{^lZnП!c d0+vXlcډ-`;[y[?`7}.lnL{uX^QCnmӻj<;On /\NEI;oDp Gu\7HE&h\؊'fpm^=j'?}vsb ~w eVꔝfg4B.lr/[-\%yl/g(v+;7ʧ{,o_F;]KfOoLٽ]F=~ZC;/gN|#ٍmbc۷BU{uNKS]GrHG.ݫyYl7KrX(mkgPPnҠPϠK {%&J^,皓:ֺ^RG [%f)6nq5Ab.߳jUEv: 0`^rkw|0'8[2l cf1jSu%w3qi9^=tchOTdr&k4[L8Kks|gKC=u0$V~ߗg":7Vyl YoȿM% M -ItbN|![X*od닙W|}_)o952ss,N:j7w*o <&nI Ԥ<Pk]xI,r?[KYr3%<烞ڡE`4'H"S$i΄4[ݟa$|Oy/PqF7*2ٽ/w /ibF5Χ(&~]'FK$8(q /ȡ3׃[\P$-浈W/ϱ !ym /inǡL$-\Gnap=/NK8(WYXn1 ;5qW^M:o镐mnQ%Y7=Z׃?s*K`b =Uv~ہݔWFi /iQ;}O7W.&K3AsBI׻Kʼnq xGHO hޏu%%ؒ3KxI KWGo.E(6vUޥKakdovލ]fʹ%(2{bqqڍ//g,^,}{{VAi3(ok+&}yJc`{%X~a#So^rW:z_% (Rq.^z!Žoa ['~f>n^=16sSNʾ%x]/v?|0iq /AyP_s^"w4؛ܕ;IuI wt@%A΋"zG|/i3v>+uoGߩb9[2lJcNjņ?Zw6NmB默rVAXJ^~T\P֔ߕ7`A:gPf}HAjԎK[Qgi}!`t:Z7Vy4s_^mnj1gU{^AcMT$0יgWB']^Vii>d`qyExIG{ ^U[#ٗv+֎pu(oWWxI7Vr_kytJ|@w^&_;J5ߠmO{\ky_>x%5~wjB (KF~Ibw 3H|^ֶvAߐQq7ګ$leQw/)K0FVbE9:~|kВ[_,wa(3(o'nGzAwWc^k ߦX_~ ,օ9C-0~e>pΔ^(ؾ΄niw[W /!4f*J  K`ԋkGzи&Ƌ&Z)(%Ä kܕq}*o(oX3zݫ '8d8Nrʾo%Uu%~t q{ b7S~z3^)9ܕw֌Cm+[_["ifX #Y{r~@XQ3ܬ1"dгТ#Vy7>L1"dpɾAK&C1-L~G4"dx>0iMyA̋1g LP8ͅ % b Rh~,K@fZtzTy*oo7Xo%]mogPގA'Tj /{B_aةX~6Jzll2|\7v+oAN+Bx {SkJ=nlQ=e)eΎ%1Xk~Gئɢ!a > dV^Pk"W뵅r>*o̓*ħ"Vy&éiM1s5=(oXKkRyؠ;/>۷LK`3i v;K&pF_/4_%sU7s￴ݳ3VyTRWy#1d~5u}]x n%#HK6QzxLLC%D2Kn,If,Vy Wښmba$_p2/cM< uۂ5/j;K13Z~+M%@s\t+hR(<Dx wqN\aX~W'tF}!ḵb GS8q'? rz^ɌإXѾ^OQҴ&`kbgf ~-w\?v(HLNUx 6;G^6-B)zci0R)+b︥x^[P;d]ɹ(E{ Y rtz*otaϑ49k.C-4.\Ux aָ`f3?9/rw}>U*os1~b]*o3$=݆VBpmbنN5$FU:`J'ѿA^f, b9ˏ>mbAK:1q /YxcX 7@H;h$*j2ܒ{*/;zXx :o7Yu4NUxZt%xb-zb[")o.;{`zk=ޯy9t*dsO}e#UxɍEw- o{)dw7ܧťm/g_up|Xʛ1vF}nf%[&gU$_Bx=d5wүFvԛfס{Q{uTӭKGcMZ7(Y;ܒW%Qr{y)dV<˹7'\Uxہ4Ζ;^ 6~5p\k=.yV~ /9 qOccMT%B,'=K#ybKnLݹ\Ux]:{j냜'NJȲs&3ձwwXoSQ&~ئs佽b|O fUޠ5J'mKN̚%k&B+LhE) ڴՄܵJi(G?X-2ӫ#Hs քά&k4refWZz..H ?[wG.7Lf n/Mx Z;bu-|:ׄ|3zg^F -zX%g*ԴF T;^,I& ^LAy[h :㿫3$$. / Mx PIЯy /Ԛ- ׼PJU64*!{Mx ea!}i+^ bcf_᧭gޢŶpe } /a[Xko)-EFl}tBqc7:͋x/~s9pX{ B(SImm3%O;FuKw hԛYx bu_1׼r6/(%gMrE \Vq jBFtyiOFFय^sr<7jK oXm4+oBB%ތ{+o[%Wm]yg^ }7ߕ{=-/"d-wܕ7rבp9@Anߺ#4̷x/uTՉ=}Upvbw#Y\uOpV(4[ v}hv3zPpoiCy8@bYqLDw{P8Bvn6x^m+#I|XN6rw67TcX/vCt(dAICXzٿ5Cۚ7gWLߩI[:0>~6 ùƧAǜDnWU;5lSyz.z [6$N!ܣ! M%^|_XPw|q'/*oVk~ɓJ;M͌f;=5Imiy3?͵J[bg)*gc򼭪XjJܯH޷,oŊ}->+4c*q/ok(֬m J/IzXSv$!b9R-M]=\BU>(UXBK kXn3l孂V ,+l[y[l؈m孁ܙY5 Gϒ|\Kc7Vyp(-V0Z/wVޠ, ~Š7Zwnb7BP_*opwuSxu;۠8PI:.sy;f;9.F~,aǶQ&Ҿt »|9Şyѩ}޿] UjO *@B*osS*q;2qw{)QH">+su~ʹmw܃4OygMGzBiޗ 4dU޷ٿbyߤXmS˶;F#X2c>`7 Oyx 46 !U+k5T.3(o-͘WhZak82xYRVe˾SG'RsQ7L~lsenQޠC1`by/dVUCߨ;+M =QKWl^u7PǎOG䖼^mT1qe+̗?kޢ0^bX-V̳%Xj-eK̛k|X9?93[tc*o=^(-'UyC Ku7hP6:wV%f_OJXϫ5(&ߝ:|uo]~UyA;ՃDw{M& mQU"|m~k.Mhs1켱[.Ip>*0]x}Otzd{X孏ܑp_4TqM^RmFSۅT-b^Tgoϫukw3=߱ {J}U}^Rr">:%?q' 6̉_wݤ.{up"pv*ou{3-rS@jM#8Xm_\3vʉU&tYVg(9wIUpR+6mY}Fz FXm%yZʁ@ #~}ۄ`yQU5c /&z\lɂKS^R!;v]ڣ%w>=UмF|9([ )H)uP^C!ڏu~ /4;ߏTyבX0N*ˎ\}5bc}Sw oԅP|8c];w&:8i>ޅzfpP^Lve];KOO(޿M%%FEҹv}o6{-8i$'K5Tg7ڣ(/F<Zs~3(oPyw%;k7@?wK`8B^AgCxIGTKl|N)\,-GKn EN l}=Uޖi$$_pD!o%wjQ17KK%bX0k%BxA}Xf&s9Fhw>g|Jj!I5dyǜ^rS[GỞ><ܝY s,B21|']'<ܳA&73(oX O7y 2}JuS<ηKn"s%mzx;gGw6y_K` !4+%bB@K' X~ /k63֕A㝭}]~Wy[dJzwK*o5wӭ;;^r˽~401sCx ͼY/K[Iw!wvle8мe. Ե+ Q QC^br3v-fA{;YuXw_Ow܍\.uVتʋ|i ފX__ (zlW"4VԦXz#uH'5W{jSx D#ПZt3+ ~5;ۊ$%MZOb /{8VX%sTثp4yPU!gOR|^[ g5X-1Ə ۭ𽍨c|[Ni/1)Τz3鿫.:.1.=(o<'Jܨ_M#+K\Rg||GM L^wf51y^2Q*MzI%Neo޴9B{[b=ܝo;^bM$ZK!{%g/)Fp0 pLx N3YDxr /?umA3V<ܕ^pOB#wgfKVGG΄݌s;׼4'U?_ҋ/חKibK ]˖ WGyK_tK B^sI$zq)du9I:K HP2=(oy <|^L6L^#ΊsHxGt ._O%讂昅Qy78jUvIX稦a!'˦|e۔7:c=ARM%7BM wL*o 4~9Pn@K ';L. Sxbn';F@"Vyۇ$vDSK'> L ./fC#^񶸟 /A~0h)&`۱ޣK6=0L%.rK ]Yx}!ƵX%&gQl+d~˹Eδק]^IQ).ꔭwp튥!8t)Mǚǿ9uz~}NKao=o*}iHT3РO8c+Nܫ>˵_ilߊk.%҄eӢo~//ښܜb yOt` Kxܤ?P>\^ 8l9GQsk=u /A,?u{{8{^孓4Z|0h%d?,⿫u^ J\Kl0~^ GGr%dwj[49^rHx&dP%e!f{xOt~voh&yU%Q0ZmuB/s /}^QQIc x w-%w%@`yMBfWx _rXwG_K08}yҧxx l-?^/`_=Ry8 *d=R=Jx &^JtUڮ#SrH۽K3孁XqZK`m旵4@=,~ /"ߏ e\KNgd~ 8ث /9}ޓ*Jܫ0f-Qp 1]LQ.%H=:&!ԝ별`V4I{a /0ꡝq] s%Mi>s`莭,%|?aܟA.oJ<66`~}H/d=7Ddrɣ/›5b6_dgx b\/? ^A݃ȧ9%~)|uM^EnW,*_H3,%CCOsjw>_K^fֱc~͟a)Y5\&{G-MfBkl~7NS*|/@Zd[Lt2kr—8{.)o~-1IϠOy@xhUFӜ?cj]֛w_ߟvW+،ِܟ5z׻[L~›yފFv7t\]?%ѾnT I;e 5_zb1PrgP Ɖ\SMb_/cr8.4 E,Ey3I 0]7('*ģr^,5enrfW p;!Sa;F44lqήŢO6o-p ]7|6\Vo*o@<88_2Mo$=Ru* "~yN4(91 ߕݻ*o>6u-D08n}'dc8'}7~kq-["nmbͤ{/d)oxImyO%Q!pjLogPX֨["%8a7[-t\Y"w[%c)wۊ"_IJDlY ^>cMgrO4.;"Y쓽Xl0#i|/vODlS,J0y)vyP,&N3؋ޕ7p% Bռ8[?_ߒ,K:Uso HBVm=jV8AwA޼e!Nх,<˜-Sd1:u.ۖŢ b&eh]e7|Y 3E7O}tgK[`z< Rn0kIJP:m^ёgݼ&=ܛ7Хx<~4#TStnlbQ]ͥuLP{VJW,/,C){O6[xy ͞<4%HfǮfy͗VZ~Ԣ7;As%8{~ q{+nY-Z^qo$/LbvˌoyrA7I?ݳO]2`?=$9t9׃- ,v,>5Gosܼ ,յ/\gQKL@c!3GAGYWq6hu>&q6E?b%9sܼcQߴCp7oߋH:XU{0 {0ۤps%[2yv29yw3\kC%s޼BMwKkrLtΛ7tj7d6^#0x0dҚ+]r~cU|^ ְ҈~˝̬=C,捥L] ‘z9̋ 4?Kh/텹x /!̓^nx 9 ^gdlYgٹx &XbVs:bϨ}]P6Nf]'xɎeu|tq^ %Xϋ`17P%'@my[RpS|9c\i(Hʺ^|oyw^_XC~ߺx 4X[B;pϱuKGb_\aT5΢] boΟpұjT^bɻq, Xxɾc8}oF#0aαn "ѷ&s so`&{Yc6%7i˾.^Ot'xWٵNK@W"V;kuCoe<䱜%;"Cv^KJ{]$cIԔ,BϽy?t=u%y/3gbah ՟{Yr.CwCn-nr8s]ޛ49⽸x K(;L5.^R#BW`Gez 8齙zc1;Nn,P\f*6vXsxr8@"7>lvg.z켱(+X&-1.^X uRi~x.a$Q %ߋ@t!bov[Hܩ|.)͋Xh|& dx 50Qʞe)ky u݃cX/UrX“h{/)Fxco1C }Q }rwňurEɚ[ coX$KpЙKʎs&V !?'/^RXs&c}A1uR :~h]Juݼa a38|7Hvx ݵύxɮۀ?G*Kv,^Djr9.^R8R4sx *\LzY`K n>K0 u񒂩m"%-SݒcZ/)E,z%eγ@ܽ*RKʢҿw3]?aZ,9^#.Pa" h]O񯋗&ѵuKvx >C\,H-޳hRj:.^R`aՠ޼ItdYR7S4Т;ٺx E@k2orus̺xI MbwWqôأ )rNmTG%3޼;֩a0qcD[EkC?˩; U{`` p2ؚ]rg}gDlX +hR ro,j~*\ F[cly=H֡#X7K4,jĶ]k 76vk87qc3tWzֿrgYOvboAHYG?qZj'Ӯ}49ͻ ܍5+"nzyb7o4Hc S٭=j`X7Rᵹy{yx B } vw<8RyE?/ٱS[(aKj"2[{]|c%%پ,>L/FՈykP:Kq!OBn䍥D;d9[όHsvU>rmqb6hJDWbZV`p P -7,Ce =歓CKuyȪ-4G?/=, 6?.^RZÀ%E+pmx;C>KvM]F-.^RYYW#/ٯ7vH?ko. x%xqv˽b<[o,uݫ,硓7m7}yo`h$wV+K,'p5-ǟ 14z؛7 -_Nd /k(ke0{ˢ > /^\4UA)&eIh:Ϩ|f(Cgo7oLK/{:9q]SQ /Q${0\[vUN=gKv,Hln+f+EsqՇ?/''8n'F_}xI?\jn9yc3Kz%/i8.~q_߾&:ٔ8>yx iK4o]_7n:^^\.޵pʵǹ~Vi cv[rպgY]M?.^KOttt*^]5QGu,27??s%;Ffؘ];80o]dwT&̪WL;1xIg/Ï%t}T~/^K6nyC?zA5acۖiu_?K/WJRKw%4yazϒ[ '^ Њc2_K:⡈=YX~x..^X0ꩍ[ݳ*`_+L^ce #7C޼U$k27c!؛7ycY2i p&XmV{p|:g`&nw?7x b(Z8DiK Ore`Ờ,<\xeWyfs/u ;w|޼3'dK T˽5?GMϽy zzpޒK|7lU+\>+]B~=b ޭ38%T/Hw |@0o/xb}78E{61}7G%=SW?֞~_\mXyf(^\i\!XBoyܹ#>w5K}\a^`!pm\s/^i% %@i>x HvNʡ-(IYoI/Ap㾻A}Q\ DG b1~c3w jXx >3ppx,`E}{4} @F~(] بE g؋fO\}Qg%(԰+2nJ.^XKڊrcy_p`摼K?w.^KCW"SAg KwۿYS%Pwy$%@؛:&rx x/"m[ 3*}k#9x HPx7zNqa$tAܛ/a^]Vt/g/S̚k~|񉧷؛G5; XD:h]QI-_kk mz*a[;[lbUHꀆeŢN# [vvyyx|1(6RhB-`ptbB!Nl 5NK狗`Ų2w%(GZCu"K;+_ LG4> @5T};7ouHZ'O^}x q͢ co`P q> _d,s$@%@ҿq\s|K q"Iboް;hk&,K&Ĕ8=F[-5Q$9V/^]ea` `KGrϳ` ӉȚKߖ SYp Vg%@@W@!wKNĬ㏚%;|ᵊ%@cV?3%;gu8?X3R%~,Z˾:Px1;ܼA ϲ_:ga@Dr^ к-f0%pKvSPx$/W?x=bnGA=6[,s>iOcA%01C7CQ/q^ܨ0 /9ׇhsl޼M4CwS&V1=x WW.^'lp񅿳oЅif؛ݽ'm}\.^Z.r@ wܛmD;Z6h b{~ .Ux"q=WhXy lKGт&ۮ)vE0%ϭaVN4۱7oOKcogm7o (a 3ԋN-wN]ŏEnހ?H~IX؛7l,k8p㣰%:159xɢ9ҮU[~r.K(͢DҚ>7-/Aهb﷋P :. ,.^kɀwgκx ,|nfb_}p i*%%v'qaqrbv |^d $,x U^sCʍwx vS&ip6X.^)4 ܛT8Cvc?Ϭ\dkq_ğߋ!~9O/^d A=!of1`+>I89 rA=o#^J7{~%ASpFV % ^؁E1gPq/]u ^ؚPmNJi :1Ɏc.>)K;pL!qqr̛LovOUo/c_2qI\[iW? BgrJ8qVml'Rq-27EP[},vR0 ^70))߷. Nd7o&˘[(t^$u+aܼŮgNYCyVInv_bZ>-~ W̛Z9NoD>łYES&qq[%\T?{39TW,6oT`9-Ze޼a1'Z=@fw˃Y=l VCc l7V5|R[7öкyk[ٯ ;eݼ5 w7oYyLeŏٻbn!+jx򽈝'e7oBBuy]dž,>z>-{IeMJ}ni؛7  >l]B 7uY1&ʖg?w6h Syt +Cy7obQk/ Jsw6&}CYJmԯY,L ~9P o_~ɤML;؛vNs={|E2}lnܱ F,s1ECyovz>γ)[,v̗ޅg7oaPsUtwxv""Y,̺R~IM'od +Œg+XP捥)jhƄ",<~-s?hw l%r>o9vDTnplx0a Qs0_Fv*%iR(?X,)f8'cHGĐ|.qyK 8 znɨI;k|$FSn3w}2$.>;--zOW}Gqx׊YԷ8I;7z6z'j&U+\2g?ݼaAgB~7+a{>NeZ,2Mppkp;bkF7oho =.X[(,` }7oB.ZW'فylXrxM=޷zV5,ah[R^/P$;>+h^ds|؛7,7"؛{s&!j>oyCYv3γVʵ} р$XXq\dВ)I歞zy~Ϫ칇VĂL ʬzAݼDҴg>q޼BS .JRw;8x!{X̄|}oZe ^E9dݼXl@$ogK70SvP1g75J&^RxI:"Kj/z;SCʶ0ɋ ~ _+)T/^ϛ/]7x8RF/ٱ]5?/$ ׋\lSH{F݋P͋@# 3Fhc# 菥wAn>˯/I.LI (=o/IG 0Ip_2s ^dPzEv1wK@ƽNK \8K.^I(Ψg;W#ꒋPOVnv/u{D˵\c^$qIG\Ո=y" XYGx }$Z,43z}S9ZoK7y~37o6, 9.^^uKG:HЃNkCx T"}}^.^ACPL%;ﳈ7Ou)dJ|\n3R޼]f)uZ @b1'D[MW{VL \ zXmV|iѺFL{󖐖LxU2m6?k~toK7K-h=ߒkS(v;J$G j/4q3ԻꁴX6c nXHMSxɎH˹aϺj%;VM'.^G ab/^G1?~2~k/)M`TC{QcԵKBch5z"XW/9.^ 5ru/h z؛7Gv?/.^q0۾*Y0DKv,R\Ϸeu_}Zf7o,?TnxIY(}9$,Ӵ[}.^C=5͋좟E6޼"'[6~YyLxɾ(|n4\JGC/ٱxkޟC;ܼaHB^fؔX1;h/ٱ ̄xӆa8]$s/>vӄ6럵d*%ᚎ Ϙ?_ {%;[Dzs!4KrX`Tx.^SMi}Z&EfhRn:Z;W%s~5P] v?C4jpN~,Bo|M}Sd4c%'Y̓rCZ\o>v#zl  XcofY:[Frrhq&ʾXTRG/ҧ7z"1o/a_h0ڥ%;E^j?@^Vԩ%;O]ݿC7%R@|$)=xIa>9:5`%PB8(7o\Y`xSk޼ sy"NJKP^:N񾞧Vn޼5܃)"5AF</?WH/ٱ軧de~;ehˑ$bb@k/ٱ$݁􋗀 h?6-ݱ7o9ǎCx+۱qǻ޼uBWM+ffbaj[K`ߗm^d!4_a0嚨%qV2-4s vJf>/ 1S[tq7o`G>+{F%L H-(Px b{bwችy":c\sv28ufXlJ >@%Alq7xIhK3z6\|_Dg[j~3S9G7IKSR" d#`GDf?Kv,YE /ٱO?!)B8/^R&9#Fyq GxI%!/|-^aM$[]v˽[V%ɤlSw%؜ :?}AV`.[׻mԇ ~_}-o,>.`؀h؝adz~kL?޼-Lf[wKK0%.H</)Ѓ)T%(h#\JF/^Qkr3O _C&X<^dSl"T$u5TpV_ܟT8b̎ G%s8 }~oM5GlL]9~ߋ 6}R $'PNmNp6j"ex QwpY>bN/^̩0s9w.^O(hLAUARZc\fj+hΊF¸xɎEhzN[^e쇙l+­^F qx ! VQdz/BLwxɎ=QWfrf\dׯ7T^z\dW8dx E^EpK*CcJ!5/tFiGq[Gjm7ocY#9{9.^R?)ѹ#vX,7Yb7o4lMvSXOwY,to< K@_y,(K*pEl/ٱجl KHљMӽq=Gp#w5Z͑-o8SsW>A7X#[I~J;3.^k,^6h/viKP`Il8^>ݼ{ˮq}&̞z\\ޗkߌ"LbQ%ޘ jo/ # vy/*e坿x |9Q໶%uP`k,X1Т/ :+wKK!/:K*ԡu ˥%u{[> [K*#Ng=[\Wm\oe KߋTTk@>ʖ{A`ʌ $rl7z,Z^bW؛!2]|%h7)}*%_-*yШ;>%~7ȢPr d\,Rs1;%:Q3t6o7oG!B by]z)؟K ЯnW޼'ii}\& W \^k\. 9Wm\dbٗr*S/GR9.Pc/^RM%{q/ݔd17oA&N`%Ԏ0>Xs]q`\$SĨq\/ԡ%M_Cwq]{AcO. .:O>/b/iš(GKPx{D,Iqq .NiYbk& R?`Dވr_b{Oiſ} XwHXRF(Ö7o/u"}@8qh\ j x1/ٽ>=ۤNd%|L./ٱ,u] ͖hX[ kyRڔ*S?ggY%ǍpKeAO .zD-$uXTso46Züx o&[=m%Hg>OK"-C fU;Q&=%02ý:3co2$hS y7o(}7u^ہJhNpc;}5wyW+A܎ym I"Kv,]^0骭pXgqg;;5/^*^zDw^da $x T5"[6h, '}fۂFcIO{wyL7>cDzR2̋\$z_M:/h^=m\^%h IHDS7y~hEI΋4b6#4+/i8T/qbo ;3ycBp\XްKNzZyRrP2 f9sGJ{]M/i#ռx > ޱ䂣؛NVf+ɟqE647z/^ :߷Y,,9%x> {b%;vPV>ѿvӼxIԢSӸ:؋4jc/8_aMEfAx.ؾ5x m2ewg?my5/^ҠzիlsqBtE͍8WV=2 >9/^gIW6{%4IV% (.ScR./9~]2On]܅/MfWγD{-o;6U ߷[j%yt*9mVny[''7i^M"9aCإbhܡ0|as'7Ec?yĂo$|Q6:h^&`b~?̋%g 6D7o^P70kFy6[hw[X 'J/R٨)Y#{!\Oe{,R*x5OK:g\*<>s_i? zʖfvͳ/79Ζ~ww2ly!EBAo)ly[|. =u {ξ>^/9mM5mou񒳋Oncٺx~iz,І.^QP/@1}Vcd}xɎf]bمDrG^1{kn}SCj]gkO]`*7н3y*7gfYZ7!{|?uꪖ7Y'񅁸쫖0?vm[a˧ς몖EA06`y|wf:Py#А_ecGqLJ/! 8.^ >ˇ+]%?Y{]/ۦ>L/ٱ<ĥ׃*2;\d7}t? qܝ.^ұLKO ({bI)T=ky$4j7}^fyb[px jbi)}5j  ElfIIV9V卂J%ruNZp\7>di&T!g%35%ދ$h-F8'/^. p@ѫ޺x .&O:GG*C{]dba ",&ZfbK;N.^Q K6?3@Ǒ`\bj}ֺx~35Qu\ﰼ/`x& 6@xHJ2,oБ:wQ#ofytAFykL+ʿ7yk\{|8/^[GpN?/ٱ@I(KLWr%V7]/ #B8exhx7oRHz]̤ %6֏)BK:>dϽ{湸xI95txA[;CWşiy[)'#ILkey4h|N>QV/I֎Nw%%ru ͢^.K:pLJtcx TWuց;n,:4||+<*GkAvߥc-oKΝOfy[<@$7x0O=w:eqrQ5?e#w4 .QG UCAۤE=i_2.墎`L`͢~´\?̌”]ZPV ǘb1ro.R->@lub5Fg^m0J9:gno7?建ôXk'7˰cN1Ϻ_KiW0hҨqg`xɜ;(\8S]34nafp_݉YaC' MO:DhO]UAX_uC+^Rъ𒕨o$J9<]9 /Y+K9C0>:_KÃ"gW K K0Ձ*f; U(Ϧ]KS|}5y6`Y_(b-oh*^xv𒅩[EuŗBH6,*\kj~^ Ylด-sҐ}=y# w@b 9 aC#bp~c>jrVƙdzsqttc+=rը+Q"/@ t~Ɏ-=צY踈7/MAykyvP>'oMrU\j夞XcmP=ݳBN=8X˵8Ϻ:pEv2fIr%oxފ3%;`X9){Ʋ$%q,q {Uu1|GlV%hjPCkX,1qK+ϞwkZ:kܤ5K8bAZΊC/104m!rY9Βiy ~3"g/iy|bMcѻbWx7-o\L,r>mOޭuи{WCϨ۩{ĠK%Xf6 k&.av|8 {ߋ XuyRbd zV’޼_&etg%x6C&.^2@qĬ8VE P /^O^𳩗ù/Z7<~mAzU7l gi!ÅQYָ)f)RD q"Vr vtY,>7 eo,oGoṗײ&x {fUj/gy#SXߡ5f(c-o5MEXf*~yΌQWmڄg0sI97o&p˿òX l&eL{.^[ 27iq%yf{F*w؛6 bhK,7t4x +؛7ޢqa]8WxɎ&ԻV}K=5pOtCY}] VRxLXϵUQU Zq/R<z G@'okyxΆcm)[ި= ̞lype77-)?5c-om.v__7ECJO m|ZQ@0~Feۢ^`b@xXc_<t} 79?>.^a,!7o¥{juK/16CrVc>t>]w2U\XtG-{1;;8 7F|k|i{7!:zex w f?~ǦjyC%uwF)XIVM|NKFqw,FF=ʫK -t>{Kp$v2ۂaW?boް0ѷ/mP[/{pN3ixɸv"vGNmRN}uMZw( bVYGgd,P{zOtgv@PU)=6d@o)-[ܛp]eǴ8S /(~%煵,^C̏U;|{<ְU;/r >^dK䗋,lx 3,1c^c\(R?wڱ2^8?񹖷yZ)fIAƔCZnu~i8xp\:X{OqPCˆZ{6 7o ls[^2)rˬ@MvlX^L` ,slxn+QW 6 E\;Pg>@ A &^ s,4&Jz ;mAlP04wLG#w7XoSzQ@A}b-*g=r~̆`؆s]؃&\Տvþccov?C%8I1P&^B^_23/wdžԩoY}H!e?pĵzzfxj%{֗w0d5&e0ޙɊJnky4XӐ /om7c!sax 1KxQL:ϱ%)*'`F8nKH#BQJTlry' dU狗L!fS%Q?ܔ j *CwK@S!\Z4?cs5|T~$P[|_|2s~RXw=oqA wsKXlUB'acѤe5Gm ~w7d.סz .  F9x N:i~_޼%0Ske fEU ꨍ.^X`}Vx  KZ;\`o?=GQj2j\[@>7ǣ {>;?X{[m&/sp]u8占j|:.,oaV<-i*AGϙY"||!Y]/ANPma;&/^3G; G..^2c~up9n_> tZ:J7cp!jY`7+0s-o&}ҳ|7\8NMZ96wtǴ ]lkNla #Y?=6Ylᴣh >{xaMb jܥ1{eƆ~&y+hhgpIO}9dx d DL\ V1WKʈx* XPwVɖ7JMJN4˔qf}=p%F!(f%[Vm̈́5w卻]vvý֡ܚoAeϽA-V;<>byO,pkyaR`Vս i{t*F+}Xް?t`R`stc Mt0>WK"y3 CtOnYE8u? /TQ\W\3] /|6wE,oñ 2cFU /Ox;h.~޼шZiϊ%L j;95o-$'Ƕ%nyO)K:IcXX7AaXs2bxi'<t?ФvsQ1SHPoT /Wӏ+fk,o؝Osa[ pi"zixIG!4B~ʇ)t\oY^eepdw&(pVt?vҵ+] /(fʀ<0v /Ieh>Y1 ZCgT-KԧƏ7͐)ČNH><; ,$*zUK@GpSwl'^*I)7̧^1,`&֩І&s%% S-b fǒCu4s-oXT]a8WW`ۮ@>[w V a5pj'N2O{F/P TX S!aJ-}-o$d/%[E΁?@46aeϧ/-oJ@=^E햷yz]*cc׳v܄OyzyK0ǯ.?+pzKTK\G~"da]Kvl:b$x Hřzlfs$k4> Te}l+{6KW~ qx. /AgY282np-Ѭ_ 7o4I'zf3< %CAr9p{3e˰37.`{y0q /OC}o@t ro.}lx uvT7P~9t՚%xC3}Vt:kk@u΁1f0<ˊ{xuY|X̾Tl @+Ɇ-; a?Po7dP8#FcՒ 4Iky *auꆗ ogtKbO /솗gс3@c-o>M;^ VJTj(D{B"zxTY>5;~膗!!yK|膗L8pNN">xZ`yC4+ \%:u.ќ-3F /m\:c@f7^{[hHG'b-|V2zw / T= ]솗@*Fzu=KJ)3C|iDͧ'^AVł  E[\%'6g5b'^rbk%2c_rN?.KP:w%seرaԔG|vcC/(%Gu%lNV58wu\4[_ |7[qT#W/;+Ix_ػmPJ=20[ͯw| w"gVlrYax/"#yh ݎgf-hCR"zDXNgo8 4OV ?*iykgCQ_n5\jyٗ単nNW"F_ٸ܅F,oPK1.(rd_֩?.*^ +&7E},oXRX{tؗmҔX9ȋr 3Νeya7!.X9.=ByEǮ-aWR0O,gG蟿K /I@1{cN A^#[NbV]%_X}2ԣr|b'Mԏd8n2DE棩[0qW}rc?`|7obVWx~aY,@T'a&fFU&g;h Gh;o#Y[.H%.YjPG/$歠Bw X`#O..h/ qF^`hnc;kŢG,aUUY$GUׇnɵ%h6 sg%=YV !T0UYɽX[M?^ 4_'3axIˇw?4$BLƩ=%7‰"5mH`y+ĩ=F;4{iQ &̇%G6}@gkxI3axIі/fߛ4؞p%TL?[0@P>f#7;='%}Cʳ:~81m 83cK9A-No\HFgBh"{%I}qU皆42q'VMS_!x /4.YY4c+,~I+1ylXIwh:NJ -1ix 1y-s`^ce uwK%wL.'66[ka:74;>so;X0u=:pvixIV>۹SqixIjh:7/<6y,A9>`g0uKz'_YtZFzެF~y%cg;8D|Btb}tZ^҉ 1:>'t w4vZ@з,NK.F(}뀜;ߎBpz%ӷd[{dŮ/5jKWdRC]>sŲ8W-}Z{ ZW蟡]sŁsN%s˄E<XV ~4d`2?N%4d^߽/hBMKhՍ+ş/4eޕxGW>m eF V0c-o$H˕^/%>z'l]h=PghzKDݫKs10;3lj(o[ ~E / !9(Cbk,Reʋp=ڿ^2Y,4J5Q%˝ʫI 5d֞w_L-4dPgC0/g@ڟ:$I,Kg9Oc-o4S+"ǖ k|lPXX`g$4;%ؚ {sex ؜_O@[% } Y7yi\b^Dx(m/K(dC6oX * / b^#[^688g- qYǺZްޟt/mosz,M'I4(Z}OE}-o;2b-oY䚒o,9Cb/ >ťЪ iCZsNPkyAJ@b|Ƶ{]kyC5v`۞#{EcH᱃JR+ٴX?7BqcǂwK?g/z?{,Sg3<<wZjfz&}<ƝVbnCZd?zLC} ;J|XjlMHF ݬ<^$1_fy>W'ExXYy(a[oc^lf,3q573%Oify#Bҕ)7c-ors VE!mXIN8 Z&oFdT4hZNwm ;t^,Xl^Aw?UV#}>ԗ<^rxgy p|Sq^f?Z\\^m@DzT7vR N0 & /9:;E3@ wg&ZwP;r'y0GX]4j gPx^0Fǩ8<;=jDKjUIO#ŧJ^%=Ë{E BnZ/YojZ1h[>^B#̝(ʟK2 fpc /l~F=GlX?<094,BfP!O6ϛ%!%^rIѿ^ə.gQ^a,z҂n"& x Q{MK2Ȇ ~tU,Q#^H8bky57.,%7*Ϧ{T!m+@/Z 8GR\r҆d |: ͋;/ +b:a鱖Rׁۏr׾svBKyX(MVf EZ(g_԰}X=LrP?%Kc+xkyW3"vy,5Uˋ<0 fqT_ek|L鬍F| goHWZް#Tm7Rg>T=z,*pEVc+;{_m7Bk(X=y`= waΛ3<̶X<:~L^鱣^P~9wZ 䖔w8FkQ4 imE栖"{lѫ1Hd 8i]8A2$##p_]* Kr @e` c>-"kdxɾ5E%y8YtZf±%߷zlC>bŜu7 IwxLpX`YisX(O /LX,QR[,<, .Z^\: `"%yRU|\}5 8T3M%_QM[kyCߒRR.c-ogZ5|2$p6j#6X[%Źnx 4Eiꝲ&7,Q硵g_ܟ:*^VߣWANXHY=VaC֎gɪ.`Y!E\XZ9^1Zw /tԾ5ڛ /0ai'28-byoXK 5:I"6y}@Ug%qY$֢-^BGlX|r;;Y⎭h$Rc B]=CA(biW5%M"H2^3_dxI=ڃ~^jK 0G ƘړUŞ7ZS~u|3^Rh7͔ /g@LBc%t%^:M^^ ]?Z&A4❾՞cK kw|mY~/w3^Rfн }HoIY# saxI:(K0w#II6+ /倄* Ѫ5b=oj,hSkycb5uK*y۳*lE] /H(H>|fW/jBG /B3;bO-™K+;^RA }0XvNeE4 15O'0TT tQ(L5f8?+*z;ZfbN /1>Cn8 /7uu+=cyc-f\bD^/[tX[>Vzg,o _ <;^R gO /AoIC@h3lxI=v? %Ci8q BG,hϙO>p=XzѫSab챸K^$^R=@w /?ޥa{IXz*>I?OfK*8Zy<=i6ʑj! b-o MԽ"Z'氼ѫ)ga=(sfx~TPmoBK~f%(bw x3 Vz͕XqX= RFt]ϙ%vTL _K*vz.d"))^ u{9V /lt;G=ixI^f%;BrCWӌXt}݀rZ)$q^1to+=6k] XO<"eᩖ8R}<^R'\܍ fK?:%y?ԙIn.+tg2Veγ%7i $F;iM0fK*Q;p%enI6LW;D/cOj.GwO⅊I]kUbxIKgHsLB=%ƞz(N| gIkLYbxI.+jR{bx (.o>8ZkyK_;`Z[,vl [ /ifscOG/4:#X GaxIHuW`PĿ%ތg ϼu_1xL:߷EϽix u>נR*掵sgy3d퇳ȃMsܪH{#G zb9^] /iLFexp!h=vשӖ7k>;{&Ͼ4(8okKl}D獢87uJ]MC!;=I7C7eLA8 /idߤg_p%``^Bw*wzg3x.4i3w"ڱbxIǬn(7iu>d1N`_RMv]?jv~)i{-ðXx;AXn~1'j.GV;,"`N5'u5bU /` dݥsV:^.!-1V-;C<>P@q~3vT <G֓/NN7T᧢m{NQC}HۡxM[ 3M;޼G.@ѣ=5%z#=d7S6 0U-{^}~ c-o4M~5cK/jCV4 /v>ڣm>tXo^(3r<:;ɜ5wM6OVKP]^&q^!%St3+> ?wg~^ҹg;i*kyË8T?uzzK/;gI&AYst //zSz[5JWtSFy.m(UχqOԇ '2{6Pej^ ps^%h;=Ϝe%>֟o_'K+Ӽn=٣Y#g%!Cj Q?_Ki@F)i>>>Wo-qzvjh5d/-4zF /4\1Dx/ /9@1̉,! 8Dx"z,-:b}3d\wl82r%dFl{Vky#ܐMQ_3d4pb'c-oXqth4KB$Y1^28l{z]X4` x_3d Z9cٛ>w4.kyPpayá(~7VAwhú\_K&կ_^rPn35y0d~W-x߽>4?Ϻ%N9FjE$MU$}@LBO^2|O߲+><" /سUTJ=C|!\0Z^2M酾 /Pz;tK&x6_Qమ}-ocf\?c[$ ꆗ P;m۽놗Ll]A`E| &x{P uyH7 >y!ѵ9b5\Z bJhuK " ?; ( _,f <~̝f7ƣW?G~ajCHz6XP ky+^o68ӱ? /[]Bh / &0K a񽞚Y&n¬U Y'8:u^5wWc6ѓuK&v/=Ƀ^q^2w5Թy9 /U͗Ԟź]σ%Xzx>ꆗ̆zRwN<솗po X!vy2s#XuK&zTl^c1P.6)_r'L2-KUv\^KZWy$nx|jbgwK&Jh,>K"KėvZްϰpo7Zrjm4^|\a|T͌nxd? ~I7djԺZ{~'s-nx lP_?놗A=>8; ,o&܏3z dv4kp;AnN(Z.ņb^Ժ%séܻ%\lj%s ; 97o61o[uG 1F ji;?IZpH%!%GG,%sܩ ,YޓuK&c=~̠,os:/mQLjL5> /T>kMcG^r3%RdXb+w /OM+>醗bkz{lD?vP~ϱ^_}E@"_]o[G4w'3e=1C=ouIez`0U nxɢ#룩3R\7.sd?xfwK <kfkx ˓Z>`x Tm~)gr6j :>K B}n^=]C7wuLUg^=Ts`j܅@} )=*6Y*bAǛf^;YG} / t/ ǘ^ KZW7 273k2zױ'\G C"Z0=oGM!ؖX$妘7LrVϛD-5W%-}vtu=1PNͯ.:5#/gRxXhke [& Ʌ9-.Qz5ay,ڿͯ5b-oJs1,o6DѶ{,kg_qbXG'G!) <ѰKkB_6='wxWnN ;}qwO IR[#V,[\-

Uiy̱q ˜J#\!#X4ǴA[z 7h($ꪍiyWz4"_-;XQq]jcY\;LyLcYx)rEH Hv!J{7Gߡz,tr}^=jey Z{V7 Qg;Sj9a,[7{F SL7~CPjOsugyc3:]u~7H %ԏ{ϵA_y|jcˏVky]^=WZhΡu*zj?~ky8Tb Q|mg_XR_MWӁ@~*~vtsYL7U*uT=Uhdy"TrVH;`GS{s-o# z.5mBǰI0癋3 {Ie~>dy>/Fg\ LL}Q X\5hǒ*:tno?0+}l#Z9y,.Igvfub 3fu,? Pc-oAaB.w)<Yv '}fu1F7~rvC.?g/J3?z g͋ vzMl%+jvbjߛcG[/8S/^iɒZgZ%%I@Cp Jhbg(%bj/P{sq8SZ|3y&3Sby;} H֋X[ߟ^ƝLi1PY0kr0ϳS-oҒsRjy˩^<5FYW爵ezI.$?/51N:44ҤD%fx 5O6ȽXͶb3Kv9٧q|/s-oz!:p0v?<ȅBeT"Ն$g40#Vij{_-Q& /΃>ⱕRh:m^x  ixIj||Is_rMK $@,o0>x]7&Ogj3ixU]VE: /x@Y8 /9"KH&?%4(% ԓxL5zxX*yCoǣv7pԾ%\‡=uqjijnx \PC$X莪{ ]FˌMTxq͟KhA7T7G% R#$Z;LXV93$M P u Cu^H^geN4$A ?/^G'b-oD~ߞXs4.trz .\7.4>3C4Dk/f3ix ?!s` Azֿ,o.&KLKIKP?^$]5}Z>v%Rx^Y~.l{0+/)^AElL:wZdۣNwɖ%yt n%% lՋz>8<-p}k^Ǜdghl +{XIbW`>%d1蒃 /XSy[d4UioJW|ϝBB Zdӣ뇲 /ǻGS+e^Bf*?R PRnbBe*Rbez2' /)G' /)|M7[DG Z 6<] %%lR-y2p_5uu /a=2pGfxI![ؕ+% ;@?^R("u߀fg-K 8S;  /)䁞mzfxI9&%VϵBSwaNgRJEb^fwFXs鈵KwvϽۖ&Et^RȆyv^Z^~¢4I&2@;of*Z0\1|4F$e~^R(|?^NP"kykw?(,oE9m}-o4m]7'$Aσ%Et-6D=BLkN }h{m+@xl$w`=j&KpuVQ[8gW9h&5-쟪/1 w`K 0w{X$nOgwH+ "=Tb*y0-YJ  g$o*n06`,U"29p/-eVXl:/7 _aCNS .p)H#s 85X(5,hpj7I/pGXS.D4}0 %?.lgQړzJ[ .l~I1Z0|r`J<'(dp`>6)[ozYw +Ԑny0 d/^5ZsT(lpeg[B;O g:ıIU,w_8 Wgf U2,ȧH U=<6}'H`Pu+jTy&9]?R B.\H kJ=ce:Lx)`5``ᯕ%ʰ 5pv J9 ]\ӑ7i߹{0 \(TM\.5-4L_ܕ}0#2HgcUbVe=hbI``P}nL!Fw+`ܐzP PoX>2_ ~d LKtZtT.w_CZ*È"2H &({0eg1PQ/[)I"A#-A :(>-a8 Al4__uCnXC\*XRXD rqP3kXUQ9dolRo%Iep>)Ө5 v𾒸4-9 w.Ažـ;(&d=-l%uWmeK^Xt7؆?Y0я?r#fVBI"aO"+MQKL ܉e췿c؋}L ]f+c/{:}TqEp`ȑ ,\,3}pNB%0 + 3 Bүl}q Fz E5$"%9XY~8b5*Fe0cu0M/52$elDj[|gbt;ԕ#)ŀiz:Z:$J9Uu.Feв~lҊYZcvk_?F~ dv0  9C``=d8>6#xzp}GO0Fo!OT6q'd` QQL7"2lG B4 < %&_bpL4%.iғa2HĔ® 8m Mp65'[;MŇanU~5mpQw >VAwߡb RꝒ-`;uLI0L qs>'d(\D[M4x9O|w.#2ȩ7tɯ1<oFn`l oz!28)aφa2;x'0 NB₣8f#28'ן339a2~Ow/Q&dL2莓a2mQ[1Fΐb҂` \gr#"ep⤖.& HUxF Djt5&ӱ !OS 8-~RP&A.ܔ~L 0 Xf#%d`^cآLEw4bh[5LΧ<Ǘr0 W|` gQ^o1Bߩo:[SGMd͌G0qv4ݻ~li} rS>R*кTޛ&5XN>HSpT|x À6SgQT2Lf Yl 6fɐ6Tlĝ0*Ɍ%@U8#Tܼi@W8 ٪10J` }-'fe씥.4\Y d(\z.`அIA2Ls*ӸW2Lfخ󹒩4Lf-a;*FBy6Lx}ϋU6LfO,[>Na207ǖ*4:L3&3(U I˘a2_ij``c!Eep0O(/~gࠝR ڀLa[ U;O<RfepT!,~͆'cX$dh$A<~hQ1~l&3Z$ $,$&3`UR=?l̀h '[_0N'o\gdh{G` ʅ^5Ṟ9);/ 8 4̰Fa2[@`#73QM˒KpI?łCV0`H8|f<Ż+32H%hL3ڧ$>$(/a24z,  YḡRv`d&𕕮S9*a2=1LN3I/{ʌ_0:8l)N r ?@ʍGv!2Hj=V9d O't T.ʅ51&3?&w%<Jdfd&E޸ΆL\sB :VX0,j\K&Un6Lf90+c6Lfbiv>:lYv $5Lf܀C xx0Gg`n RX~ flppM}?7h hH9&0LԠV+0 .&@,k&>YBep|*pa2oK*sqq3b,T<-J1GCd5TF#8>0I?XT,R6nHߝ *Db4h7(x"N@p`j`#,+IDR/5OV w}YSڭ5R,@}Z>`I&gaĊ1{,2X`r~kkIɃWZ/%YuհvA7,G$l|R.'*MWϼ ֔^A~"2\ňx] & :UM)CeHлG"\%[ᚲ3M*9yTe|[ǝʧ<5,`#'1s9WƳ&P8dQe:3naK9-n^Oqldy4dp)0:.-28=+a,bUri g#>Xanh=J m{ B@lkZ `d^LY.m+),㝾 cr1Så3s@=?&ꫤCv- LNb2]_տ}S@Ǵ T:o\L2?Րm$dv0e糹O] _6^Onҹ&eGRTWl$~gJs~ w7V6xAԒZz+0IEjnTa .fAaJ>2 c /'_̷aur,eX'ngF`l=/` T#['ư .j?q`'[am03]AXa&9jА -eϰ aa1aD7xgJtQ0C*ZmpXCeXqiU.&'8UDdN ЌI%oHd +蔪\,`2@ _3zњ~fҔ o@ޔd~r1̣͕x/&# IJ xb0ײ,oT+ 8/nY qdT, SsJ)J,|ÿ,U1s"]U=gK,Xw}VieY+]y.g-wa2%+;"T&sO%۪[gYXAרdXΥSٮ(>[5Aha''[!km8*d]&k;3:'- nCIN Μ8 2HΗB$Rh :dh22HPLWQ"28oմT\5LT'J> ΆP/4?"28#tJe7Č#)6a2rxI/PFe+֤0pa2ʰ*:h^ 9C8#S"2Y{Yb` 6]u5=Ca29*Ìa2rR5G5A͏R~:7fo"Z0e LĪa2CTnt]# ]=a2%sU55y6L1ǐQ~R:.7:h&tH`?0RPd}5LUYR#l\<ȶt]HlΒ qWZjLE6I1L4Tm2 nd f-铊<R8Cwm&*_z΂lL:|t~滗zV{ 0BiUlCDv7`a{-LqfLZʼ~E4-&TS6dkgB/ݫa2&jng]iN/ |d:l&S3ߵngSgd*f)*'g Ƭ,H+|3X7i.[0&FI$oa28M \֡bkt꥖XT>23rx@&SI%j>]˥ȎUd*7llA9d -zM R?0J48RU F~Im5Ld1a (O7TN!]Aa2;PPQ>R>M~: ҕG &SM|J^0LQ*Ud*7q?iK[La2x-pu!Q\L/Md*PN`-Qd*uO;TdR{5`0LpMX&cC)^_cX0Z!ches?Eƴ`"?ݲ9N84LSU-Y 4aUF&a2-䥂 L#X0HYH2ЯɐivT6L8QX =Oxa2:jƪYE4a` &CYQPlj`pzWbR >R3L{`2H۪&Ӹ`>Dp`tBG%wd wCc >lv#f#- +y>E 'Q7d>S'5bJe'x. x?fL#P B&:/\AeA^]C0]BŨ"L -Tťƣ7d`{O T5V; AN-?'npa2)ha2j m+g$^'[Lj4j 0h 0IͮL(%tfLø [iq4.V 1kXO0gZ3L0gt@0/2ʲV`QʉtTDj&9#-&^T#! zgy6 1N0H0tLKJρzt1E+ł)NPuS4s _N&b e,`ҀC&:d:СbAXĭ,λǛa2lȓH@lh4k3LfwT Tzc3LfX42ڀ&a2glU|ΆɐTDbw=.lPU]|&ӱ4pova2Eb;qe%d:LSQ0a 5ΖyQV!}3L S ¡5O/tfm3LOn<3A!9 D!1o"h7qp@Y3L,$F)a2c*'?#0qMSWawCC~)Cx6 K㧒 $dnYg̀M\Yfi ˽z"qv,fRɌ\+wa2;GL>&C %68|\-j!1({m00]JeA$a2؍S1f voL?EFc%a21j"ʵT-{,,`i`Nx/Z0#"L ʯF_t:k&3h ʳ}f0Qa2ԒS$a2;8L:s12H9KËa:-% +D*dId 뤒vr zBGA0pa2i=4-f `\,'y h? |=IwȂ*f̠U +_2șfvJh3LfR02iy9h$ʥ0AGQp"݆f&y 1C`v1Nkvd0ɝq2'7a2ٿML!Xq9Q5Lff.O|)r}i&3H >2Ah`Vu%lmyij niN\`8XGPZ1aesRJqn̤+X!/Ka2DC^š1r)i20ɠpUa! z0HL#5̓aką`lwdC^;MJKT7LH)0d&3A2 0舁dNUva2IZud&uY,A0R.uF  ݞ ol gwe!U7Lc6 2Hk;RX_2h5 ;Rk=;s>Ӄ>=8a2*:A>f0E[#w}M1nc2Qt,פ䷈&hx#Z0pwJs0ERyUut|r`md6n2xHa2 p}V~&n̢uZ0c+# wdGla23=Xk~(l|rwd]44l1G- YKy v/?<8PU$8&Jȴ3k<<{+qTdNa2@%UAǼ--Ƴ^bqQ;3n XX W4,_`=D="2Mve!ωd Jz40#0$=Kb27M~6bn/&SAt03a0A<#D7&!s-f_n cFhh=Lf`Yʀp4yoqrɀ-1Ur*a2s_BK/-~ؚ2xGhuV†ɜ` J-5=G}7?tAP Mu;'K p%+4 1 җ{YXdpdN sb%ɐ '*A;̑Atke~v 0dc5Q.Ģy d0$82hd; <2AW_+ ޑAU'6\;2{EP,0: uTʒr-[a2U}m:{~ @{u>Ha2L7Ry/i٢:'l~A åE&3e!u+0.Z_]Nb0[5(/U&E\XU(R\=fGa[]j>C#2^G{ v䋕ȠA̗NҤVt!D*hM#2HfR*źANi-Eo[F`p>[m4=Yt~ :WE&sA dN0v9#~ʼn=L /C w#0A$Y`NQb{ `)YP&30w+W͉u{~Vn9G%k WѹiRL6 Gu/VdEo ДBX P=}Ҭ_02 \K<2,s"LX!!^IiA1ά̭E'S? 3&`dX[-B#ӥMi98) O?@ #AjKˏؽ?#+&wF_ B 1a2'x<̣ ~:Uؓ/g^:Nd1e_9ճʵɼq$Ng](0qj)qI7e01hLI.Q5{>!DA="E#6" "}~Lz%H/PAmlٙLJh #FsuZj |0MCEn?-%&s*kZx,4f10A}~T ca@BZ$axk$-0EXR&$ Z`24Y< ѡlH\Mm %E+ŒU`2VVu`1.j9|A{,0"0 ݄Kt:h3&w2`"00Ip*(&34_L|,0I}^쟉a`-YL2;tlY`2GD3!\u h9GoLUǽSXT2,0IЩ?&3!rNy 0opKpYuɜ`9 !G8/.zL_ o9qzFep)BB80o@ YX`2 RvӴd3\!77d0KUYc&'FWiyρɬ2Vfj,0CSK,],0#VpR L')72I[Y,L3[b d,Z PʜB Le]l%928,M}YUdZBp̚h tu9űY0C( |p282H.z_}݁ɜo'S1^FYuɜ9,wX Lf^HήJNdN> W,5[YΑ1g`z y@h:"nR1K ?bqd I:d2h$sr<&c$2 ]uw Ng B1dȧ[J"V _6Tzwm #>\1<4$u9&/P>>dm&C0Q 6To}y`2vzO)g/GFVd nu.9s`2L IHo@vY~92V_83td MH7H<<0/k 来3GqIJ.3G72hG }K3݁` N:?8)$L dz4 }8F<A.0mj:{L]bOcL$Tؘpfx`2T۪ĻT&%0 AlT?{`2)g%n$=y`2i` d380D)s7r3dZ2oz`2>}mjOI|DdN=0zE៴'q&TcayȠvfɣrqJ%c"0%7[rdP@K\N|VɸC" D>py}q` ܎!%-գi[{D/iQ S(Dldud ;R`2)|ݤeم ɠ{edvAUE~gKڕvVx}&;0mGDhȂ8:YEd\bPD L&{`2<=g۔Lj ;6 CAx&X cG6dâ?kl{`20A/k3 V#Hs+AL`| 4[Gq쵏" d L "UnXHx`2hQ“eZl?J&Co?LfpYf dpRim6x'6.d [2_:'&d{] 8J;>C5QQ%c!3G9z EYHl?RɣSlw[d}Eu}) A=7;Ș{d*U9TX$U=2H 1"ήu}|DXr\a2B۟aC a2T4ArOyHQu \u} ^U w% B@\Mm#X_0(582نZd]FNT3 gZ ;'%c e`K=Ao 昸HNf0u[v:::G|0v.?Xω0U᧺N}*cd3)dV!蝖.T >LfMN;Ʊ)smpf`4SmU:282ȡV26&enB4x,,7Mhc;,/ pZWqG0f۰/TsJ6 f)^j(3/V U6?o#`=SN|a2 xh{|̂OId Tڔ=ep{~ n^c+ G)Cx90E6qi*"%QҮ Rul<MI@{7YuC;~̂>JT=]mLf*T_7?1)a2F7 >L +IH*dN0TA]+g9UnF~[:@![Y)OMLj iAcrdYSXPuپ<2LTmS6&\ut2$2-R{dҦc 1T Dج; N::Bz̚d8J,_d֬~zt9$xE06zXM05IP1b_}`4_VHxܥT{̚{y7~~̚GH{~̚TTDh|6mѧ`š '*6)&sֵË;P[)MyG7(F:3-!& ͛U?g ֢"a2'd43[{ /ڳ*%>LJ(0; w/]ݷAZQ(_0}\Q5T, mߋ`J gi8UT2823V쟰E0jUQm/PHj+ gAZYa<+YFkw2e:tTeplNgâ+߸AbKS:t(LAMm]C{ ~Eu !a2pH g OY ^Pܫ#$*dAgaKceR14dSdpp6 MЖ&OU.;Dd :}2 aY%xF0$`& 4%Z,K2"A};#_A4D'\6s l I%d,x@50 yn8ġd&ɺRj`2N3`N=AWӡ}'82xe2\aa&8 (14$WA8ĸC(n50^Zm6Re!&$ZK @O1^7QL7o#0ԁl}/&qhTj"-'uW\DbA~B BYx;0 8 `Kz LVfz̝MK ..P`2>3uk*2H16J,K L` Q{^ep`2`X )gw`2D1rU?7$kU, 'a5_dh^!^\rߓhCg]Hz`i|VGYS@{d_k/̓Q96i;tK0.Sa2_ހÖE7P5d QDƸhLUK~(+wLA!UL HtZ0BYM6:(q}ѫ5Jڑ `\jL h: p!9ʜ\K +_dJ uBd&cjS>& 7JG n0Cu#^z?4XH .o@N=.5Ra4A 8P}q[ sZ~Yv9fO AI#na:"a2'S(-%dN0 .c郘B} xHDtW<#i+^Wz]e:AEdpR>eSta2'+KvQ 1Jw 6p} LXq T[tƠ2~wxcPA\U&!+֣^Ğtxd|C;.5y9Fe#EYrz̩&OYQ 8[;(q/8K~_E@:9G/<>=1Z Brd`9W382;@t<3O`{:끎q_ &E2i* )N242ݸ+Ř  jbAz}U\~#C: i<* $m9!1d!3bHĥ&/a2vŞfb"DȰucN‰)0j. PTî6.2R<'et+) ,yCYi?epRteS&lZ#H-E[dp´W-z4E*NLJ rmb GPhBIiA'YZf뵬z7"lC}uO)X DN?ep)dk=L%=/a2;)T$u=LʓḻVd@EN{,.<"x+-lEV~< ~\~.xfs=Lo i*s'~(i["T}Ӧ<oR2)R/.28T FPR78"e}=n:A[Ѿ)]> hPW8n=5[ԦGQƏ'k6"p HXJk#2h`+IA*u݂v6^d`lz;&a2 ݴdiz"/S: 1`YGO,{AؑAX| K$e[ƹ F鄬̐qLؑ 6:q&);2tȵ2*ʍ[jJqG1z ^.h<"92" WeL n&z:;0/Ļ*lUcSgMx`ɜtЮw!Mb`AIܳo&4踖b&-OpdwB|0Q{ ҥ&_wAলtNFi7R^Rd~Ty :͔ن^gI3Kx?Lơ؋ PUc#ɪ{z/NΥ}FJd?Luw9@ &sV:>%TI)j3xF7^ꔋa2Wm~VP`a2(a,,8  f2iF #||=pHĵ?L^TXW0]tZW8XAw/y9|5*N@*ɜ`,p\Evɀ4Կ\6o_~yE0m%0CdxT_0QBXN_&N3?*2SK&}DqWF3)#2?#'a2Pq!Mq~8)@Lj#N=Ƽϸ42ևH&_P@F)@6ŷ`hH %ĵkɜ`0x78Tx}a2NET+\&s5A&sKuZ^ `HVa (ueOؖ)>#T H\ѩrkį 9gq&ED]Pr]+2Ϲ;K[(/3 `;d^*walj&a2q8>9`9+5x(EqC~"VF:O9&&R 7PWepT}0 (zq5U%[K5CNp.N7y &yQ:s@6,28,4"'#7s ҭ[m[N`yfi]vQ !R/w<إ$vU@c96:LϏ@W~10shPJH?L6MOzwdè?L'J1<3epxNegA1 Z>UY UT1ĩs=&᥺=-4w &=uZp!.[LP J:__Z1WW]_`&Τd-oe)CpM.@(ꋙC,L4OM`yq8ġ_p`2(ReE`klSf1q L|&j4=N, W|&׏LɜsJ%gGtg2q~L!M < UP.΁nfpd"N)I.Ƞi.X́L݃P# > ~@Lơ໫#=6 n0cdiFIt0a62F`27i5p_>Wc7*pg GU?bwt.d6fB+wK{mg?FYr`20.0xn_\#rmU_~ɯ S)A TJ3=ĭ7RSmЎAYa2Z,wuvhUdp38u~& c?0Fe*ʖU>Lfb[Xp[*x& wI!u$0DA9zy4?c7 NεUJC`5p(9+Gd6U[,'Jb~Vy͇l oKḳ1ުt>LfS< ~_;Ի8=-@DifdO50fZܱ(CJtI,Ax1VV>>"lDF"pB N' ԧdikw7@? ^.1&s o}uHf @͇`8H}Pޢ 0S4K=dk>Lf {aNB3epJl&FPEh0h28'9FRRȯ`tߙA?rI0(RF\{c!ZiYP^Wr -"lAL*lF282hWmIB'Z4v2-Ad}zm %A -չW:_9ПLd_9_ ̇PQl,$&E:N%Za2'ȯ(b (o֧71r/w7ӽ$;EQd@RM3]1,.D9̠uP3aTM#0 ;iQ,?epϴ~ I"PAٝ L-R7+0~y;P L/-ɣP`(:W^7:v<"25! RN3eU>mX ZUp\d1" 謔+3 L9;d 7Y][e *z9hm :1 VdO:mԬ; L*m9gѬlG ݯ?l 01s1-LS?VB d&shd6M\:A x,J"=S YoFq6o>l&S3`}#0j"氐90?IaTVmA0RM +}/vRm0nLd+R >ɡ+!-e" ᯾$&I\QB87AMLNKA)31/ZR i = ap+ad@@'U1բ1?D݃R^YNu;2萤+S71]D{vȠs|c˼Zg#4]u;2qt VRekW5#uFnej8I繐 W(:Dgǻ LX`RZew{IsqIJ*,+X/^tqn ^u-ZP9< F]'y<\^]dR[j-y/j$82 d̪AR͋%`Bž@l"]_6B{QzIDV}q-n_#g7瀃j՗338< ~lt`&[ V`V2xG0y|^u7͢z4#G:4FˑE/8uZiY^ހ}x΁Igpdpŧx=#/4lq[w"ccD7;2B3IiA#a7Z*2HM'eڎ`(&71KS\ 'W }u^eœ)a{A1^O{YF9uf3)Mx)/ZL/u08V5GSSp%82ȹa= =_ np x1S,7E$ X:լX8Gk&sJGH$\GV`2. W#Wak,̂uc+ s4^.5PƓA` TG'H誡i)ɬ+/9Fb9?ZLc1%]aGb&[A٥̂h2KH&`i #!282 L;QJjSicd)s;^Z`26ȍQb L@9; 4{_LC[AA{n$i%1dd8אsoX;.hmd"jJ}1F LƜkf < L8THo8`}\~,誉H5YZ`2P`b3Ϸ 8!%)"՗ tT__.,*"l J,cal8܋rsd^⋷N JGns\)}_,0Lf182#W&,cD,Ung{D@O*l}-0 x㏑']&,0* mpjپ˛"fCD!,0oo&%&Fu&4~l{'U F`2)ۦPF꬛2820t27q(H8nm6Ąr]b{W,-0P}WychxnBQt T[d ܳŇ"-2/^l Ld"e<[d/(&L'TXˑAKW F9U:Nw-2rҳiKTy Ǫ(9E+/Qzc\μz b'=EgV#>MkA97֖R 9c*B2ߔA CWM O?e%397M DUuEnB&vQ9d P$e|> Ze&+MU@cC0'X ^OZÂmY9S_L,Xr{`2WǭK؆P-:_x!lhuo6RL Lf3rrLLnUyE0L[WgUd2?IߙP)_9Sw0|A <0j5[ꟲT,L`2JR W4ȩVD?{`2k;ZQs' . hH.60"nHcJ&30rJ#,)6A4ԣm=T ~t61"xwJ︓. ?ַA# wdH)cD=0T.: U[)ɌI `?[ Kɜs Dh;? "%D`2FHT L3G9>.O [k2J܀*90ERe4-t#oiEuPrfpdK ހ>=p=[IXcds:hASP%rcxE˰GMTL朂Cphr" ޿`|):#65&7@,tX)2VL*=AJov}l f1cR&3Oӱ:׺6rF7ay`2 gKsm&3!ZՅ]]$)qQ^5,դ`H<#c 8x%SLj Ϋ#DU BX@?#Pj4W`|d?02 ;>E2:#;0cI6kg(=;0ȴGRPoW(;0HbQIJ~]6w`2:N)q' a&3łm+͒eLRuSٛ؁آ\=pl);0cOs#̑AW2Pv.0股!e(;0rܽokLӐ oeիHɘsA: DF`6*cr`2Гў#zL !}`2 5ܟVL sWE ȡpfdqޗ1u\92| L٣߁`aXVw`2%bh~ρxrO :ec1M= O@C=_Tۦ6Ky7_p+"Jم=j2A`l2CAι 5f#NémDQ"*D':u/blj;W:fpdu(୳/Ӗ] ,YQŽ-ˑAl6̈ݮtw :+wQJJ>Fo—g+7Ɲ.0P Rbk\FyG)>̐vŔr!&s%\XꋼȇAN T*`h6`* uï,hEyIY6yρ8=i'9-׍;wKaGW*m0z /nN.`d.#g߾U;0s5ů:V&%0? _0c1Ia%1ܽE ae*s`2z]g49)֗$*n#&HE/5ddіm`7`̧lN,ؑ$82$ϵ7q^:WZBt0"2828p.춲v WPBos{9;.5|,P rLfCLt:̑Ab7xx QFdpBGY(eI ρP}$5|d~\;0>'B>F`2sMZ!P`2{ae˙rn$uG;K[N]m59Y>Ǝ vzKAujSLqϕ#WGz 2hpdpn{6RvdcUvYc?A0I- WMf_0 Avd lZBleC ^1"蕝/mJ+(w=srSM'4?8Un-AEb?282ȁ!ԿuFѯnJlN?* #֑MD2óJpdpqZJ5 E fpRV[fV@u \ _ծG[HFq"uK4Ux]kdM: `hS ?8"is/ ‡AV Wr H12ƈ_H/f")9`QћKab :ftlୃ{Xlۄƅmt"TxM\L`t@;CdݩQ#tZ1̑%LMZ/tdieAox ,8?5٭d҃ ~5r&OՀ  a2 מH>b3e&iޔrˏP^uTɀ* Bg-l9OC%(@50F)x=3ωd0bHRiR^byi-|M/p\p)g6}GNI ّi@PwY\{7Wg`D˩ Wi}I|)4BK4eO@&vrOr'\Hɜ_BʍnE t! Yur L?=U_(O`z4$0USNmTF:c4q=O[T/z:O#\%382Hu[M0 )0OK``j H fԅȑmƼs١}üU rVثt6q)n_0eNEeniYm9}湧i4ah9MН&.}QDJ$#C,8ΟL L}N-+ liصmx382yȢ%P <N${LN D x/>R! jy³-0wL(WtZ`2 /zPH&Ioi 9s?7eAF-0J!lk_e#t獾&Ib3Ekrap+*}H]̋X L7@6\,2 _ b%N ܃t!&;Y>Jb̧ cD#&B1  0}Q0~j!.A L~Gm/_Xb2{[`2sUX,q/-g*JƫdLSY" ]-`?&ٿrLα/yAT2eٱFJ &Cbm\z ^4ۮ-MJ LtGV܃GGedL_| ꢈ)`L`2eʕ?pYH iy_0w/&өe,b-A(Mڔ\=+LǤm394D HpdН"=ڕN ƙ" kHpdwf8 *؊rlok}Xrv&vS*28?k;xa L Nh+ U u{lΏ.K&30 ~Ѓie L b,D`21=$*U`20HĠΖBG ^D|: 8Oe=U!k#0aR96!`u8e=&3h[ѻ&(Ҋ_0e1w>*}=-0e2UHN#HEIɥ/Iw`2cNd LftXP"K%cGym!Θ)&3H=\ Ja2&/-0̳"&  ,Vd3LϯoX`d꿟^=G'卫 ^좁 BhMA0Y]2U45kNf\%h`2 &\ zH YrLf8R+PV<&3]WZj=R&}+*ࢲ#&3f&ޔ-kg@}TnpDqS- I[]L_ܧJ"̇jK7Ҫzo./MsklT/~$;H&3 ǥa&Ĺod&g4qG|ρPljKELfbLwof8Ydp)j#?.Iٿm!~Kd&pp (#'=0$ /%k$WsEl92pj f LY0(HK&/<\Յ-mMuIH5=0 ב5y! 6|cqKw%G1k,GK9=x1821 t䦹عDLf +'Ԁ́ɜ`鎜`l_L xUޖS`;D :(dHX8WA-ld(Q ;&#Qn(D.0@ U&&3!K @㾢!/Ga^hM 7<sc90t}/G)>uDSqq[A0va$(Bsq3GMY妉KNdu~;:j3H5#0UPr9oLyɬ7FwL%t& =@E -=dm&`BuJ`H?Yh l`2 ZnɫԭT' >q@ KHIM`%H0$>}^Ro&< J*L–10nge y q.y ,omP[Kף&@q`-P`CF3xMd U1:Lc-N;J.0|'_* KdH&-cNYW#U!D`2j]TƑ6Sd:6l&x|Crʕ(0sLe4ELd0ZlfS&s׮k65#lDP5%u&`olE9aqM!43ZPƫCuBg>s`2 ?]K' ĥ{o@v2@ M.%\m[S4aT$sۈ ұ*IbcuӤp Lf9D&d&svyeh#zj282H6⚯7 *k"1~6F`2ssE!As|3 B @H52}69%R1nbt cUF#,OK#0(oߘi25fE#QjőUx#0!Ք~ 5Np:Grv#T+%Y}/yZd "?>ɜ4M91>>7 ^ t]ߠ%7!@+T~92i e#0&I ^L1RѶO61bC:c&c4]Ǿog~` $@U71vZUoJj~&sPWZAE3 I?m7m\ݔ?0281GrU  9'lV AGوX*b<'L NS@5?90sZzI#0J*}F,#0sL)| i4?(#0z f?̹I|^l=e&qoF7B L\Ai2829KRB-.T*sC9R&%0'DzSdXZ`L@ˍjʟ!KdrW?zk[~92ifT H R+u~J{QWUOXxEΐLf&=5=h}$F`2N ZRF`2a}:5$/w&C?L5\Nd -!s¡+#iO: /# +<)hF{jK["n;R`2iOm tx EdŅL3Vя v;;"d6dο!G!,#06aIӱOGaGֆnAq``2Npqbu&s)U GUG9q4͓h`2Įi0;wLj R9gᖷ`ܻ%:nlugc_0e[gѝT/UwF#0UdUe.^FdLE$W\*#0tLFEr#DTȪkAL`M"ƃ\ɀ%@rtA) и8E9T|VF`2PN6Q}\& ^CfuekPV SLx8KvISnɀʈ yIɜRZC, 3#0sgڳ{rKNdhJ豱jӥD)ss-O%K:5SGoS糋= >yt*#0AFq~ZCmo feg6! {`s ?Ndxg3'v{mvcC(B~N@F0dJbT&O3/30]&gTِ .1p!\d CAol'%1\,l|k?U h} < 80\NUCr"x@8o lOLj Xԅ27b)%5(ӁG!B>ީ?$82DSA)]҉`y[ DH{&sWP˗턳f`2b.JmMol-NԠ#2416i2ԡG''.(mQ4F`2EZ,_#69OA Lfi:ɅPL# $IjQyϑA] (qt&#WӴK0m 80Эz[Jw#DdUx] B1ǥ9>a3gqyQ1/ؾRiPF_F/g`2e2ئ}Tf`2P[!e0d!#K40P|'^d6g*] raO:>u*g&4m61BEGAk[-ie F4qe&,\մ. [#NU:F? @E k0NMd?X|L'teC+0R& vﮔje| PLjiٌRmX@E2gaa% >gdг{/g Zj9B132:8]A,^Q<]jU+o8wtі#sEe\Aاz /mYCGsE54tGղ ^rgZAH͘+ks? G'aU& E0&Hœд ےd)O R$ΤTRO ^.e—]x IˢE`]g-24/zhUǴ࢘|Vpi%'E],.$-1N ”T zpߢFB#_v\=<2Z:1=2\ia# 1eN̑Mꢶ>T0'rw!X3O|zd6u35\#3 ([I۹/[fYk/߲TxݑABre /_k"l ~-<-0^᭚N˩b$d:R/?\'7,2~Ϸ`C#0NY* A&);J<>k /H,d:%O`d YLzL'"p&y-Pdku`%]4\<$82HfK)Q&WU"Qcн(-=D9ѣrdbS~,U#tk*7LJ ֆK&mW u@ޭVO3``G%eq6Bblv׶jdpJ]&3G'IS\ȒIj߱Xgpd' ZP6Zdp3u9 ~sc.b Y(Z5rGZ-2syRm&#" YH:cK92fU*YAMeȠյ_ Uv )A,j~FW }ݛh@[ȠSwGq; eNaK:G\ԗ CtVZ^AșA7omP(jZ&nA&<#*{YDYV H}pBR#ph4_a6xJ3U#bC乨` WgjL e+N&_d3eJ Ŕd:q E hnpc,W/gT0d C_53!;рP a2ejKWrQ@r Lz@\# krbI tZvgp~ LL`)dRX@c]XiyLrUjH LCX=(%F`2j\H Lm>OAԅTM$\an rZ>;- f`@wN:/ݾL]55@W`2! [ɀ(~~T'i&j,<_*O+QL•}p;a և痢]Hu)iiKS/hr]4 !Lk^G>h*.:+0j qMs`2jG LTQ:G舥,i )Φ~gV`2 u;U*SM^ (;A4&L7dΞ61N4MkTɀw*^ L [JbL B|t\JV`2 M2<#+ÓYɠJd3 SXXod.6vi~)Öa)(UxjDhofM&d:vNM^]kSi~lHHg&ë0+DRE9^Y*8rQڴ_ V'7?==#DAJx T"0reqLs"sh(K@P rل@ l[`2i9 ;(epd0Y082ءYFS#,\-0N!7 .v2nC||j,0N!7F MX`2`ENL)Ie~vE,0f08cR}-ϐ&өT0juLb9)/C Uu fv[-04k1G >ZmD!*C&,3rdD#J ù@ L,0_h"h.#[K [=: LK WP$/c_Px#bt}-g0_̑AS1(p-0/AG-ҬLw(Nq g.d:#R,d/nJl)W-0XJ`])*LAQބ&I#! L7j+*_$TM]Ĭd0 4Q LD3l=L"wWƈ&S`W7dE0X2AcB-0Qε@8(:KU_l[`2M*d I'%60uZCdXU=@ϻĔc"0AD3#lWg~S/%82ṡ4&[E-0Q}Jr-0Lc&s9)N0^A>s`2&]6sPyW_ '4``,@g.*AR2>4?$d0|{ՖD L&0 EA7 qM@f00xNd2)`q  kI`2 E{oF /Ȁaɐ]>gJ#X`20t} ӏ^ن8 TDCp.M[JT {\=e>3Wr`k@G,,0S?Emx˶&3XMvQ ztK̄q3}e6"ӗuR&3Eٳ̩( LfRŦdң{ Rl&,*ơnX`ƇH앂ي:K-_&3;xɥd&ȥťc}d<0Sj\BG&s^TGkrdʬ&N9-/xz`2N4w<2p<09OLİP=0H.E?#0o=/ :D|'L #YV`\=#6HF{dLi+S>(W]`2}]h~V]# _Ƀ ޿`I:Lfi@p_SLfOQB@p wcjM<0hSJ |ρ@Y;Pu IpdЀrͥ2Mpv1Xd&ri``2؆x~"rG Lf:7Tyud&MN,a@ j7&Uw6=0fOuiFsd&qP z`2+Z%82\Ƨpb[ {`2s/!tİe{B̴B٤&3!QUxgPITsg,!V7BȼA&0rʅriQu=XV V h+4D'3ArшPO/xC_`I["{`2 =:^:k#0s_A,;$t67`HYZ"˨k#0S D2& rɠǡ{󈝠cD/I*۰W<Lfם5KQ=0s+Zɿx:T(զGqv{O+]ȠSqSE``2r[!eLfA*bNYs?|c|3LfmnlwYu,,_Wx)p]1".jCe!a!QI@-e{LةF[D=0JVa;' L gu@.*}ԤiJd [YaB<NhLTWsiʶ1 ~DU#TCLo1/+MfIXDžYW?{L0VfSsgLWTjC-d Pb4᎐FɍCU͍10ikľ<07W#P`\u,!>Qsq&cDǕE ϒh({61jGaU^ 4382+2]58OMJ, {{ˑ ?% QR*Ef⦩AXpT"Ey4+FqͤdƝ~\!-yϑA֖JH$Lpw%! te&! ϴNLd΍oc>L܁ZU^YSv`2hzO߱#IVeVkim6"ݕ۳/HLA{G'mD1\>6>C;0CSUe؁mr `L Lz}6|d {7Aռn&܄L 7d݁OyYr@> 0Z݁xBEjM&0Ч [dv`2Ѥeܿ`S%v=PD !v&t/D?;b&ل*U[@g ^dm%c7r.TF)ii g1nj``*`rFL7ظzaK=`]ÚP?pF0ޔuQ$ |yr_l7 테McibCӧ|T;3G6uܳI4K0~о,G\x{nI01>-SxQz\-2Hڼ 뾑o{tF0j&JƃC0 y`)=',wD+ `ng #_0T5/˪A}*5ڵ{fG n$CCD j]q:q/x KEsȠSvl)vp`jTr1"Aݙr/ ( r]H(d$4KN`fl_32Q-dl;J̌ vH$lc ƌ Sd`l32vs'xY@WY Rw*5Z ( A vewHtP0aWT@H8+2fn(MiTl_(z'CA9,;dj xI4(ZoXSE!5}}<ǻ͗a2p_hdPlKp`IyKa2l$A!,K7N |`.n_及>- f^>n^FWIa&k#X՗8eޑEݞ% L r2),s2%;2hTTV;2}k?nb;Ҏ V(4trcܑAԳґ@xw2]MRG R#xt*gS?02kM,&ܻwd)uV?bw^~?ʌ. HB:LG@""sڴ$ V8(ʦdƵlv9d>]Z,^%eXj%}]r]Þ`B2~ wŽ{I  KV2Wdхk/z_k#0N!WSo F\r/OpdswgA:Y( FAP=HeS~92.ީdѵ-.2H&TѨPcjY>T$!2xrJWkx Ek]ی`awE6)_RS9eݾDd b?,ߚo#0=r.z 2 wzݞ:G‰T:K!``2h"KT250Α)Q;@cfUuP=&s>(m[.sVdpD_Ip^ge^VY;,93xJz8ǀ"daPO_5& ~[FXIbY$);F[' 0eLշ|)ɌI %!LP[.50nrVuD̩U`%̩G}؞[n`2;}ϞLfk450A xBV 382ֺ, 5C6d&Xs^MQ̼ĉLw`2,h\l7ȣe޴ȔǝR>r&32o?p)ճɜ~'чU:Q̤jhDqA4AjHGޕ!"/qg{{LPp܆9@zLGkh.d&59T <ӅJQV50)byk=A5Յ LΔdpb?A g<줛ŎT`{eCytȝG[Je!@,uJ0 d! LfRӪo*dYj`2rӋn6('Ssd2.,EqE,0e]o@\50)6a VoZun_,4 &r&?42U_ kg+VVs00 Y=}\PMe+%k#0+u04%);:3/(\X/ŭ9fS~Ӕ|JFK B RNh -0 z-ƹd/Ɣ^+*ZUJdlXK!L~eP>)ˠ+%k̹zˋ B:DDZ`2FroL,6ˁ*s۲?hr[`2x_ *90`{IQE/GZ6:/GlwShE_\yC<##w(N D`D{r+hɠ\tK<ж`kpQ=&㤢U+FU[[ L {;RM^]`2Na&oLmIh8=m .qބWsirSoh :g~ 6,AM^]dp@@ 8#e.z#ϛox( Rhv HoM! EzZ=($Ri'82Px6y϶\`^92H퐊"puhO6#|̬)-"+P&sQxHn$/?LTz K6r`GX.%U]||Fn 녴J7ؑA6IjA\Vwq}q6icw5 NMCք/œ>o|2.2FS d=LTeRU` .(C%1 oHp`TZAA1-@+,@!#YYo ~$.jʫt ԑ?3Kdp Ue )^" ml/ F*zG.o#2W#-tz ¹( MxdpdGRK4EFm`mN^{ ?[r d诃`4v81$L_M"A2J~L^Y,109Ik`*CrQ"}j`9 Y%^gK/+@Nnk|ݻBjD&s17TC3{~ 65 aߩk"ϼ"8tdi6zg 309i: +R9&=1 E`.r?A>nH_MdRDdmNy Ȣʎ0I K *z&/kTuYFa2h*xMA``vMgpB̤KR.7T}0oGFa.&@0t*G! +W-vY},םY>Fd Vf<ƈ }-7 {#.}XԢ0IWUb2E#20_] bةIo\ ލ +#2l2ԉ}D7VupE#0h3T8E 2X5.v =ma2Z$a_Rr9tlI!N@]=$T)]7%epB:/.Bl$lq9 &s1(: v)E?CL4#)V<Hd_9,zj9⒏1kcDץ1eJ!?d&td = @$7)E\sЩ&Cl)y FA?epALxkky%L`2RH}1x]LfggUd @Xn2ђj,TUKeep`)"& <]Щ LfQu^ST,\ݥY(J}&PFk~ HRY"њ(\іh y ]p8y Խ@GRCe &h%9L,̚q7p W'`TДLV 7Qt&/Y:aY''haK ը\*;L9QRT__0xN7/N3bIso|ntuLc{ ɀ|V~s1QG`2S9Y|dm&3Zڵw1"$hf=e{0@fLF@G`2v Su#"2N%+\`Hf;/Zl?qLI9<[70umO7d ҁBS,W)N{gLfqċ?I_JD2p;hd0 IЪjb4&s4$Tfh-llDoep6ZHAu ƭ3+Myu94•_ ·ɜ` hOmNɜQǖkʽ2 T N4I|*P]L| FC~&#!TFkd64D gɫ :n,GFRֲ欑A<J %-2Hw#U<k7f n!,emhAHH!;+c\dYni|BU:7t@r>Lf5\21&Euwî%oep-lSML$)/9!`LhP?a2eF|)22&V`汉8Hp>LW]޳G0.5Sj:\9&DOo %P_#yoGÏ Lyvş}]sLw`2Ρ%5Ph+F`2N)w,'l`2L{@B'g`2J 6"5NMC̡@!ؑ %,~ ˟#-NGT| :@esȹ`k&g`֮L1&.JzBzL&da(f>KU0kݯ'묇` &Q>(G 68bI>`C(m v ]dG' , ߥf=L ت7X10S{& La23 U#A- Dd h(7Eds̈́ċ?M04"H4/ʃjγV&^TKY2C8N%:#s/ 4XDE V2t=dm"əez 9Q"~ &q2o 2uo]Y 6wukD3ց5" gAjd!׈ b1WGd?2zïi~V#2oȨ%>}0[ulS,lXz-NdljMJ^buQ_-8~'jVXPK+j=LƀgafHg~ ՗qc p=L%Z~ *x3?Lπ˨+*X&s$ niTɜ`KNe-/[j-E0ͮep &7ZjRrW`2{鱦 xiCPFƟW`2z)٣~r+0 n( `"+0j"ۣ B`2mXԇPtMS*n81ъ6e`{CU_T$dN0ڒUq͕[vjd Ncb_ٱl vd1fĄ 9l-1,,|3%x\IG d3xyt.u0+TgC@Ԇɘ: Χ,{a2-\ĭ_E*{S-3ZᵇeQ+ Adq 4"/kKVdVبqs;b52H&:0zu'Q5!bShLG (V!0J ]t{AK+ <"8{I%=0rdpt耓SQ0SsdR)AoID&JXJ1*a2f\gs.*=LyB;<=p̸\&8-(quu *jd|Qsi>2WM?1^A3ԠHଔ ̙GR\976@hSg`"+; (\j J &+p ~]Ys!y`28 7zB-lL/pCDZa}UKr=0A-S+gp&h* /"[ Ͷ0ucd9I[Q. le nd6 M شP 92ל5 G#N} @I)\d64#DR_qJ|N@T0{6Ki) qEBW?L>}nLf>M'A!dcCpf۾/ W\&O f 0SI:Hį-0,e):dஇ.0Fq"[dg2sh{$ٷ?L$&s*=Kx/)}X3bE20ݛv;uze*&aB~B'g~0 M1ڊ"ۘ(2"CuOXDl./iraT|A23/& a2pW !7 dzICdl)Sg  P3id mas"ļdN06la/XE_Fs7)6[?epIL+뾁*8?LFKsy{^a2ĂBՖu[\>{ 'I]_dNg Ba2f6'ScAfPP}0=ONrϏ%u~YYd,yu+2H"}+t F2Zj8G= ޗN/ *8?ɜ`TJ w}xa2f"ۄd&sA0.5^U&a3vf^d0\sҁ `94npdP@a2u| ߄n#."0}Ԣ21,I\ya2(pʔYlI 0CP,7o0DSJX?L2C-c0j=qP΂b{^0M%Jdx+ba!5dn4e)ݗ, $NWwX&!YKIos/ B%, 4)AΥmžsKq%23"^[Gw }/Gw\v[R}.A\%^Jl%}?L[*\ɹf/ brdDir_2x6FIuw`2<+1h3 ⊒dW:9';0jV z~V;0VЉHj21Gz鷈㪃&󞲉``ݕHyd " ]}Jp}mb2 EcjFLd~ LfGdh x/Iua0D p:jbH J\εܠԓdn0j濷a=:nV(=/i282wC+~Wz ^*{ Kt y:'ro!2'~<"0w y/~o@B~xq%njrdUӐ_v:ɭm &}Eo#W]_0jtv_0um@N&ulIܾ *h2"e-%_݈ 6:PU.:~ Gxf6~_qh}7="r; n1!옿Nϩ|s. Rh#N/Cu2#wrKYurf,8ASN+l8מAv`%EJe{Foy2F"=/;O9 2{_0*_ TY$ +kY uwLXtU7#g7Ճ|))WW1Zi7[WdpP\eyBDҽ/o Fd\ Q΃q@2/{2a!Yi@i׼ _TίTei VP>"{E'x.(.8oG1#NrG<꫋ ^ߤKGx[dD|u i`ȶ @zp^9V-2HTy/OͶBg PEzInU^spnj^69bRiIX382%mp[__]{vzAx)amfqlS~92))iE|#3"Qxq<' `ZJ;1dpdpO2}M4w9UGiR9<4'+n ƫ˛N`.7=ث^ܥ90J T=qt:%xuݭ92xF0'e=; zd 3EО?p\re_o1J. )0J+ʝ:f`,Q'=N^"v~cun'Ac'w+N b2:in r6 ^Ssm&AmR1NhᲓLruq epdmSK.94u?M92XYk,!&!} )0PrJ;y H.b380M/RJTNp녝U@C?i$'82xў9Iޓt&S!1f)N&lYHVI ^W2NpdYJV/KpdHe>HBS92^|v_s \v &"%ɬ6LJbM\)ˤAB)!3zrM_X Bk/N5'lngˑN2\K-Opd޺ZнPo_^̿_W 9+!.[n`2Tv>@ I L"LN.'Ź6!yA'\~x@?>oaoQ9' p僝 r󠇝N/1 ʯ;0gߐҹAoy&S'ZU>+*ipdp\'\ugUD }"Y*gic^]d Sଅa`Av|VXlNA! 95;b9tGmsh!Ag⨗*0JS ' S ~r Ey[A`2dQmd,{dO70wGQp+GX &́``2["#崲_qo00qV]<49 R^b)Xg&u&S/Rq0g[0xǥq 8q 9|,ל-2~Vɀ ap0W>F`2nJ[>F`2*S>*u Lϊ4||feGp?ؙ*0s;j Un`29HmR&SAN;/n. x-F%Jg!ץdNa".s'7&s,!uo#0J|8$)Puį|uoLJ`2'7c/H/(md&8ݿ  TK|VrL&S t 3ȭ 3 RhEMDXs00?_f&SZHC\cg?UO_+^P#m%a PLcVQ^Z^j`2 #y84t:Ap4G`t&Wvms+Ԑr&C&ZU9f+o@50Fg%UQ@  $`hrG*%ڲ3XˑAj&I %DdGt6N9: `[\KN&Ө[)%4\,^ړU`2>O7(,h`22FJ o;g+Gby,ࢸ8 g Or99}v<4稚LVɜ`*MLT-Nige,dN0 sV^ L掚Y/er,a$TCNpdwb7 `F"s!:.&)WX I5|J]vˁPבPjV[`2Wut͞oa(\Npdz-2i\G:3xF0.bkIy ^ 9*V#7$fEQP6Q_0d[Sd:ADmX”L\E"UnɰN{_OF:enB}ip )!6gn~ ›r/E5 r+¬)Zǹ69 706mDܮҴ=-mnd&InM~Q%-q`2!F :&7 %82T/[zRRadL|PN#Nol_$Y׵~$B X$ ;cid϶d: :BUi/r/xs23X+ S\4A-CWBl EN w8 |0/xM'0>Nod:oSI T;|}^z`2>7G۹Iѭ \=08r@=0K-gȩ("pa ۈ?1QOx #T 4U0/x{H#mEF`2ByrtK2# _Ȣs(]EO/3&d/GIȡ!rp4JG5\)`pjdIw`2947ٗC~92X;2㨒XPRQ'3/=0.W(Cud^9S =2/rh6"IA LfnY&3x]2Xx7"<[ǾXAsm&:LǾ&}j0 λ}ad}Fz`2{'4tz|@_oX#}VqOH=0AjFXƟ v}׳[dF@\>dD{[V̠eW71&382x易' 28288_w'.]wtK?U0z`2'ؾg6 H~U#yN2&3u4d˪;s!&3w;eGTGW\݀-= qw σeo&3thލVC^]dKJSdpd9B!gIw"Uu 4-tH`Lfp#_+wh/ YԐ`} %㎯4w1L#rI`.̀U69nT 0TC[%u֣ӓ&s!m ȤВ}#0:goI ^yJ· ` ^{`29eyt(RN!)Yl282x2=\DdR&TY&3HW0/x\P6y<愑ӓKF`2]NmpKdƥC~&mA)}Kp`g!xWɌMZe |ɜK0 W\ \uɰ*35eLf~{- wf!df!exD9jVa]"_J`2Fh 54>s`2'"c7 W];"&)|R\-S$^6ld ppy_LfVhMH+u|&3)܊*{يɜ`ۜ77)̀mLʜpA҃"=#law[mLfvhRm&sn0M'УgٴFSڪzg3݁Lvu\NvLfiv9I\Gy79e]=.r'Ki"nΌ}`WoTHkRXh`2$v`7U9ұIU0:߷q02+%3 &3pǡ Ц'~)/80'Nv0!A$Suk )9b1G ;[Q=0zC(( T.$j z`2H .՗ RJ7Ο&|L6ǧC'eE;2rR&3D c䅷1 RDv=~ғْ,]D|&`nt JY=0YxvgB7b Lfr+D%&3]),*UZ6z`2#}k _q+L^*"o#0t-/R3|B1ʳ0$A*08h?ouy+eiLSES(eyjwd& ޵JCVLfzz/FG`2h{] d&s~hYךzwkn!f\?мj@ƫEMd&~C6aCdpu sp[#dt]%.0If;V#0]l0᝞+E$.^0}f)$ciS&F`2S>Hd#[%Dd009(-ZrdpoĘ G05d/?$ [}=΍Ȗ0LfU\4L%e{Lfr0Ez%;9`YHe>ZŶ"̐ >_KPLyI \̑AgF?iͳS]o-G\tfGyysq-d&BGhR&̤]yGL\4Xgٳ ój&B5 ș29]|[q[{Upԛ QjwxAE eGl_pd(9_g)A/G`2'\1$?7.``2})g ͇^p{8&j|&\ļW282HBع\KLj n_WU'8\ӴGMe6S_]dp Y" :Zʺ?1gVZt&3eKgTaGqۧ|3HKuX` `aiA& ơW$Mr&cTxmW+,ג)0("zH+1>#0}"Zg>8N+A\Ye|&cG iTXqL or?1%;*.TnLh\!l`2:YSb2/5#0+m)ѐ-zY3R=82H:mU@VLyꋢ\/E ~ߊ#dRMnД~oAb-wCͩF`28 gR1^jLL![yi&seVRᠺ8L ?xm/*cHڌdSu:L5M[C k&s))B[տd)d/j$d<̉فL1&nXاYjE+d}Tb" PIç{#0b*{dF`2FzBg7LJ`2 Gb P!.0l x_w w&sjt+ˑAC *Lf`2F=UCґRa|v'R}&cmG(Qɐ>B /WL7\:&S30<1 mAs׍x/Ǯ8Q 1A:U)\'@H>[[ H\Jwi&cF+ UBhtF8ɘQBxr3Ma3I[ȠYQs %19 mlPV2)4Xr/VY {yBepdp *5NC6ː#:EQg`2?+ LJ`2 V+  L] ΍O30Ü(8&$?30<#Da&sts1$ĞK:& -x G]EۗSf`2~5B `}2^7Y h wq&8{Hs"<M b7KQx7d LfkK|.&C 6Q nLP`2+ 1 ^6me&Ab ^x 6ɜGs0!`GGe͒S@30WMӷ 62>9S6#`eJm 0eVADLW܄~$jY՛Gp`2 ^Vg~:30E,v{rK%6 AU o&8ݫX~? 30:~*Ռ6%30::S3*Eg`2?[Js)OHb305֧8 > ^/N<@wS)0j"<:1h;.o00E*&bZ.0S4M LZ|̚G lEj&Yr;~g`2:']*@,)_w`2 KlXGdm&B6"6~ԃAznɠR1!FݻR&s2M]s`2gmHT1ɐQ'b Eaf`2'X@msY۬ LfQ1Šq"1x4:g`2kaT =ښɬ"N4P yᝁ,6\,̧$,V30jcA:m\P%$7.?>@6\P${lZ>j%xd6\:orO L\ @&ϼ#x/rGyN98r'9= ⒮Wd6)}2& $ͯ];md঍:)'2dc LfsE9T'(-j30];)M&q꜁ɀO9B2J&0\I';'T oI}Nb[V9;h+IWu׵d6GNm4WG@ } ^}CX=kɀꉽNn艺e 6RԽOF{,0S5"]?s2q$aɀ2xo= &M)J`o?lr%)F&*jgl|S{k :I%n2C{GYN, 6v%Im&!^#a/R`2JWL|HSs`25?")pŃ%{d6y2] $v61"ߪ*Oo*0M)8?tj8o#0 &cWRE `N|F?U1"DyʎБ̞܌r` u/W LI%J_ Nw&V/?6fݲps&%0;p&-ӔW_Vp$ Y`2_\[:gfkD>=pP2&gDu/1E_ .QRԯ͕ L6,Z)Q1), LfDdBՎi,0}&b~U_ LjH?ԏfpdU,DU6_ n i^p`22eCip`H lGATšj q$N,>օ&CZ뺊hM@ c$"MdQ3DEN^0'M}j&aGu9IUϯP]LIؑ9 Љ|1BdɐKKq1`tYi( 9 ^'{ /GWې[犝ocD 'ٰu6G6"M441z!W}!I>Ҧq$؅gfdq+ =Edte`vuv4d!%IfdJ!*)ی ҿ{-iC?Co,}cF3@ٌ gYX328o'?}/BMN.mo"[AS"$3 )4 B3qQ ɯ]J"BfZrdm~,~ &JΔ o#2h981"ۆ@ )?[3G/> f+2h1%jv좺DWyS%n+2JFq[M{*"-? L"gkԕ#^$ˑAM{ $ q.lpL6b(锶"T xASFdTa%#$W[B~{Ǡy"8t%.&S6W@ċ.&S aGyev1Rx9R%s fJdT -|1,x@QAy[et#`Lpb2ѩ{u1L෫:If_d]MՁ/Y# ]E& ʔ3G 4!;.; VDs:ln- :M) y R1/cmuMs}Z)U;&NNx>F UzOg R+:Ren]Szmc4`: mrA?]U"M3?V/0!W),W ~|?pȠ_4N[uV #2B1U"79v#NC~/zE k$ݵ`s3jdprx6~ "al"W]m/ kT2̑Az htu+3GVY /T$Xn#qO\}ȠgjOٺrdrEj^[d) Ee=_LT 4p2~5QnL$@6ɜK2Hԅ|~ LSz ʍ\ S?C4 o(D&dy h ?㢤;dSwWC EJz p=L*)ʐܴJh&ST14S51L}(Nhx~V`2: ub8 d"Yɴo3lEx&)ziWU=G_lT/~ps6UW`2 ywqsR-0@ŲO7m3imW0z-R&: 5kZ4 y }*4s=&X$Ι-+06|zL,`\928Ӳׁ5d?+063<\80FQ5trW*908q0~W`2R'@?izLԨ]=^ H|ɸOS /$gp}Cfj`ByV`2"!CcSiXH 9@0TLpLG6 \X03 wa cvo{!|bIjы x;V+_LbjguK9r?쾘LE/ i2b2 KqwsZ\C.ao3b;;K`%5m8-JLdKMt/d.&S)^D;Ŀ˙ɜ`j@ MXx|3jZo7RdNp>Fq1t&mnϏY.wûٝd)8>Mm/dN0G/Bg?"`_L{UR^AH|LC+28*F5n 4h|8ob2Ӥq01Ւ]ncT=3x1c OTpGK/9KVל)7AZSlS45b27b2nkg}x?8TmCP po]ξ tc#TM~fp'vD/&;YBpH q1:YY̳a}%>%BE?:7]+:nQdU1Ճo٦4HIjn0[vJ]7αXe`5: p,=A4p)@}$wTyu#L>5:/ n(da9ogJrE0Y:aT7; sBx4%\ ߷@: ^z3d&2|Vrz (^EL=WkB~974Ij g8ϩ|38(YW^LMQٷXm@W-dNqkR+  rzywY,5 'fp%7+uoQC*q3, Ys+̢ Ks  :e+h?b2XjEp,@_y`iNq b2gqk+yDSI{d:c=O #3x1Js܄16.?؋@  <򄽘 :TC7QOt1x!` '6Edspfy\Ls8 !bM~s{1sbND?ފ|1(BBZ_LS\/e {1̍v)% ry<_7ݮId/&659+}6I:ڲ.&3;|qSNY>X$ozr.QGiT9)/gU.b2@y#co|3'ۻY|3^llbdy*qnu1(@uɠF5d3 #r,^\| P1 ُ+j$6}?7x`*7s6ȊATPf: Gb2 ;E{ ֔1V\>1\01=X\Cyq'3h_wW |3 ݥ⺮fo!Ո~hH:g .4p`)\d뙈rK` %ƅdt*DdN"VPh#^q\.&58423R|m2˅ @9 3K+, <{KHW<`YÂ'5?1 әtHdQ?|QN"w+b2Nnb2 j@k{&fA0U@H&1v>- R40$9_=C0 d|T2dNJUr<]!A13&tB棶?l.W0E]Wbi&{=0-bă޵y1Wg Pe0kΞM!z^oc`::*=MFb_gpBuq\338xO9;-&RtoNnpC8f`c m%53hF!ץ [0 _{1`l:}pvsN3™3G 03*0e ~Ę1J^A%&Y:0V-&gT*1Rj~;\ʫt%&Cv'4_–}r?z d2*~}gChF&`94mLs"l.t&zYCO'(Aƙ/ ] \//𯗺db<R3x.#%zy2QɌ6 {O \ϧ{ @? \,'_+|)+N6V1qx1x2{o.0$_, 0PB"A ޏ{n(NRbT/OfA",=)0pQ L.p}[lZf䣾T`2deB ]UJ 6>Ts{,RW^xx0М$n ɐ{3f/C IyɠIE"_=S >D'0Yf 1MmzP.†d7keF%JwN$yJT[D n : qI9Ӊ#C3d8Cqfcn햿 6T2ǯwհgìEɰY7M^@  Vx .w}> U ֿh AE3'x濼:0B`Y``d.,sIKo\uZeP熟wl{}?8] 7Rg{} Gݶs<uhkɜ!3Y;}=cGL{ 6VUCTK`pu/U;"4mREWWU;.%=_KZetj\&z>|j\+2s\TnjW=+ϩ!_JY\t_Xuk|Qs{yʿr17x1 PlFR;rm\LnToJ#Wd ZP| vLWaȑ-ILC8ݍqB dAΊg\">c2;},$r/MM% HؑF[ TD[3xV x鈙y rd(,A<؟yqKLd[p=sl|tBW&,,(Z~%3c26ƉjrNd`=Î^m`lsCcgK}ipT QH+;c GΡ;a܉v K>]pwu \*1 W4}1{K:&S)oDؾ2)d 06k8] 8!W`힟A57V/Ǒ+=WWo*y_1U-WW4qxنW'26ah^gդʽ<x{~1/_ӹ29,yTd6e4+N{chEU6F290V`!7eqfm9 10 "]ޛqzW؞WDl3{o@o{ NPy`[˿M`;)o)14pNE3ʞB7hwI''tOyo bO [0 Ģ6 Z5U嗽7hH7/y]ޛ8 Se3OzԄ,spV,yfh qOAL=@_?o 76ۃڒy{)H+?yA)8/x&xGN(ߙS~sU'^w9 ZЀ`?ſF*9H-e&aK4p:16[ ,vҷ<Ƹ6@ϕ.]cg7v%ٙ9)?.ᫀh}< YZLV2@[GFFL3,$K5 >ّ9 n7OT w 7iIq*qjDӊ M:.zg޾i,eZ_)!z|$}ZS#类H9 uR^1 93d06dǵ4dƾ7>H5^o+. BٽD|{?lJU04<`+TyU"|Fls_|3>[C") ns3fSX˪>^d`HqeOo7|o5ݾ>↹D1Lp lB67xR| 4UgM$rѥ U"P}yd 7:l/v31 s_d X&U u7mX, 2FٮkHַ3d=AB8ᔛy\& ?#`Mv7g\P,W7%o'l} q1n'n|&*I,%u]3#x|{AR5W(\䫳JC/o˫;_;-? nl84WC;G:rT7p㪺*|nɌ E.L3r6"Jo=AH񘖗:I&c)#.^3fU V|55>9 hJUp1B43`KM7ͩE>G2~ S `:mt!o;r]fSy}=q_MMCa^D~yGP=+E ϞSmXNkKUqm|3Y9[Pn7 t:u^ɩܭOwٟmF.)믎di7f&VR N7K6 :{Þs:w)jnMR`i/ ك\o0w-9aUg..sd:}џ|)`V&E L_A/ ="ئ ^0 }ljA $}u F| V8 B9m̅ ޶ 8oֿI!c KnyAҝy2MƾzɴQC 4`ȷ1! MǸ\K_Nfp `#B}3 +Ro֋q1<(&Wz@Ƀ 6fw׌49=_)zPoNP cZIfhgq¾ygK%q1,xb2>{_gI_Zlq]6<f3oqhhR3r xi=s=UL6Fl>lt*oԿd"23A'*Ӆ\^gam_t-kQGO˵r4Zp/3{ 3 SP97MIAM/{Z4J=s!΢%$Nz&plrlJ5Qu`z2\̼`lhd{g<Ys^E'ϣz."-:B`3?SQ}Hyp-e1^0P|٩d6PI +ul_D ïDeGlV79Yl="̘![[>s 0 ?ͤ4`-`=ڐtÓ`=yk yeD^V$? [{+e=l7ڔI{+TfXmxo0V\98Y퓳 Fs _1AKb ̎7Z.9sLwy7pA^䗝'Cu8xq=*/pf;Nr(Lʝ]~eݧ=ڪ竕>pWE~ރ|N E{ gK_grz @eog>N^`X7P8Ɲ]BFT(0 HK_XhC\ nrwvs9Ҁ9\䶜)wv}9Q=s Li6 !!؜K8ɺ˅AȋH2VHWk{ZWzu)Gʶ6U8[fK!tR/ʗ60-b\_(?#'R#]_ЎjLݵz?th&r5~R՗WM[rZ]".hT|3m|8D Ja{z^̫ du ;/gGM5J9,oY]S`K̢Wqφ_ɏkn HnqZ#3G?@b&ݸᣐ%3|7r΃ͰOTH&r,|r!Iq17wL9HmCc) ~Wd9mv~"ݼ/oEKi>M{zюIlcDijܴxH>ES1{ߠ#)TQgC? \Y;ږxߟQ4(+۟hL9c폶 U!^L;2;&]$Ƶsw82f_ \ef̄N*o6Bz*s6oSV]c.ZK#:cY$u< 9`h.r^?, !vu5nd V5}V A_k z׉.?o&ܴeӦQm%[!v#6j)]Fm6jZNmZ0vY1#@OLG^iX]z^ u{{t *^b؊ %>KVt޲PF~:_yiP8]Y_#g>[D !_g]8:7Pe n^o][fg[5\'٭lD\A4̉,)DTP L܁șh7ôzaYNƵoxl"ù^svtmVh$F B^<9+wy- جy=\(eFr.)([^湐ւ18F.AauY>vUos6cl-Dl+("^"VcS>f(av}QMF: Jd.H_^l])eHeAho}:W8 UeSz}֒E?>!FڤC9^T!\Gc ^P[{ϲ>lpv@kL&1BX(OBy~%Xu]2&s?Zl ak<\;7JTwRΓ =nI9OԴQ7|crb/T^ g/#4x^hc6k9OfH/S*?kص[;Tw&!gɾХ-G/P$ƜܡepZzY~tZ~+7kīVn 6_DZV5[d[zυ/T?q>oEMmʂuKo%f0jtط1y" Ӏ'=RRaB @IŅЧ:}h*Vy@o.&HldL[El4Wr%QKFel3D}vʅ[:A҄qxH~1ٽbuc [`¹NuoL֚mYJ4$V E,kVQwFĹt1p.}o99?}s g9?z(l"Z`{a9^Z/45sQZ7)r>D^F:R~+#>s2N߉q@t;DeA"MP5$CE^FZ7АC,O}3ʸ`+6q9!4?YVun OE \8kcS u+s~ 0((uXTpHȋ-8Z,ErwTDe]6~@dQ?Gru2JM:LqxOe#k&M)V*I@XjO)!ZQ JQ[˟.M=7e$t.uԄ gqz_'zv2iȰPmn%2d221c9_:0\R1U|dQa8[Zlm#kBN.Tyx;bb+>1uUZlV~+%v[!4!Є؊NT溎X⢒(Hf2꣕ ^F̘RÝ^F>OG1L/#5&q azifBr^FBlEΚT44[NSpu٪ߊ1"k[" Zl{u[k-,C6!.:=x |I  %$lM/,G/s[!4W#8%Mmb++.vv`)B}ޘ< >7k[twq.bH2:+2#&eT[-gm.4$ hN#A/c-iQwAfFAhS/u>^F>h\]aE P՚r| 7T',9VLOA>s<J-+4pqP߳em ڋ-2,iV4~&*JZ ^lƠ(/T}-UƼ-P@e2[ 8@("!m'PlEɷKVP ">n'W.؊pS@-*-ez^%[_"Qg" IjHAF ]28$ hXډ@ m]h!dڅ>*e \f}XW⨗-]ek˖/j$tي>34 #7C ]p2EV1'BŖ惸v.Wf־Ŗ">?wq5AdѾPvL*r 5-z ^pN{Y:-l.[ic (<4Ӓ%vڲa PւS؊FBG?Pg-B͚ -,S`gKBWW!}b+!+Fʅc+ 1 -]w}PC'eP(lE qk;QDC[/[!u1,lmFtC&{_؛$[HU,D7 95[zmh^lmw%E{C\C]t9'[~owUoaz  ufkx^|R*v5t >4%; AfxlhײggÖY4gMPg,pĴy}WkAĻ``DZ6(`練l-8E9]37[: j͖A )ARZ+XfKA9y &loO$@9^P)>iwfk©\6٪Uz+fˌ7^FlzWӅ͖PQ)h)\ZP2*@k~4QPe#exNea&exEmN ߿c wlkx3Zk[Z(@X)zڦ>ۄcIZFi,ɹ M2bһȁ2v ZˈC_@Z&91d. N;;?V1g?XDZFx%0 T8޴Xqr~fkavm'ELB^gmt}vDhuNw+iCӿ>jkۿg9ilO^ L &ZFdpxت%0{i"l-#YLYm m-cC/7f7LkR#l~,K@P2zK8Jt64ݱ»Qμue\͖L~}MY͖zTc.6[J6ٲlDlfQV>Q][HHqC-W/szm-c/dan22\77-2*ɎK[F"'fPhkyDk-99`Ne>]قˁnhɎ-bNFN n-j$m`Ǻv=EpZFT]@[ˈY8D{Y:>5q#M/o-#8/VFeDY #[(WHzk5>ު,kₜ`rҽe͖_u(j14_is[>& W"يMq2f+ Z tklzf+rqHf+}PMeK@YߗOUPzS h8P*}A0uCmS;k++=Q?~ՙKdePtjUɏ}KUf+\&''DeAU݆>lh,a64Y }ؚ_O MN ! %YL,lh({{kHCƆ6[?1dk4[t6j mUB',l%omxhS# 4[96@l4[O+pefk0cSlq lDXVۄ8E8Vea W Ն'b͇5;vzCxs3iז@9Q˰u59v:\г0*"f˯P8ֻṷX&4[`@Q6i؅'Bl>^ӰЏ Ӈ-#5nh(&aWu[2S娐Xk%Vj]fN{ W%2D^Mqk"휂aex6 fKO?Ɓ!.$$Z^Ml'Z( 6[hK2ZЋr!P2ϡy lrM?ÖVR/k-CeqCAx]Fֵ9Q@bDeR^ǭeThZZfˌӥqwm|ڮe[|?,2 kkZ-19&Z] 21,92%7Ġ/` O^`ǶQqjD};8@(.m-cғ_@0+Z˰w}Zط TA;2LX2 ͖ ~wb }:t#T&k.~_8/8Z0{;ߵ0 eX@pi`yk.dZ-`[ج5+"WzÖWtA7o-cZ>0H*cb,XZF}l=?+ꜟ!Nj-ʑq~ZЇ>g z ri-蒯d:hY չkk]:o-="e~4䬵 ]Ķ=Jd6a+kͼ`;ںމZF\ɧvEf SOl |ׇe×B[˨`:xk!X# ' G~ykx$fxkauAh[r 2dka lxpɩ\ }ykbsd@F)$Pow} IזIY ͆Vmk@5BY$2r~]k2rb6鼵a(BZF 3bJ herfyk*xA@9o-#c}&⼵:9v|aI-$o-#E[ʏAƾZFV" M[(pkruC-n-jymxkY뷖FF*)[˨y 2 Nn]elh [ V5[xJAϭJ'LnV2 hֶVRW*GqIMݼ6')n[cX]wNEp{ ]EV?lu QS Ӈ }G5ClC^)|&OzLuE6[sT߻7[om j v]n70+5WCעpFQaP*O3mxŢ (xgbwGlC[ 3,<x\)뢃h .=~}.NsY͖DRbSٲɇ6ϳd4 fe+rŦDdDlQo'lN%Vu+.COoh|r!akag W̆w<.Zllh(لH zتUjòr\[+d-N~*ĶUV q5[uL m_Fud ŒܧvNY[6Cׁ*csa*caKtXvbdUj`Kj ]\*7&5B41&YU"Vڧ(K1aLO;@[:Y [;CԍUSB֯\c G%6t~rdR%k5Føȧ-!)[?ݸ*:ܾ@׎2.P|<s㸶X[/T1^XagNjC# >Ї-P>e j92xl5;K>l퟇U,2 }V^lash-| A)d cFwm,MJ2M0e侌X^(EkwexӽB*6ˬ4 N=\T?P{ B@yTtЅ{N 4xVۯ>J[lyFׁ⼸PAw[0zj5. յ73zn4)kh>4pQ_fOS7z>OՑxd7btjG5 b(~hX 8fkN!|7 2"@朖lAxC)NCt>#Q>zOxzߟ ؞crϠ}4sL%FGƸ.4zɵ aV,?\+x<U?(N֛(E147~crLܒ-nC@a= 8Фadf%8rs ;y5[bvAmlXr@fKAS lY ll.6WbYpC-}=I{a;˼w۞qi>l8wŒʼ-0dF, /hl ZY{ڎ!c(\F=a5:r4[nC㗼Hɞs GcZ1gŁzPjƷ}lVl=lr\tƥ]:hl!jOVؒ  m ~f+]G`v}·#ρ}Ł3:/ZF>uF v`Зá)IfCEJw]>iH6U&ׄ W҆&. Y 5}`_oPff-""v5[#aiߓ10#kcr:*P(֜LiK Lep%;Go4[3nM9M}e$"c@ֆ6[kN4 @:PGhܱA6[++`j%ڄZ'B-lNpϺ S-t{FImx76[O-Fʝ/lm2QOm-cC;o2jD;k{kZgEhtkPPCdZp ^+piQqjڱQkяs wAkJ]c LOhF=i-1* kjE&Yk-\<@ m⣒-/2F'.Zu; Lhu-dkVtچkFyVD3Gl-cٱ0kmCmng ]$>ae1҂(fk#Ciio) {@6[˘S{Mҙevͽ]SLel(U5M$\5C;K{DnEkZhF ۼVhQEu6|ߖ96Xe!qsVMF)V5bqԱ] oֱxTW#x{m݋*KՎ lI͛@~鴇ZJ]) c~7yS;x>ncOR2C.ZؖsgAAa`Y* whcu^qx贱͛`G=-],?-|LJ~߬t/+q.k+nEc\*[>Q߯ P4P2[mhU7G%6o86o6o19f+l d5[TySz{csp2ƾ'a샲wBҶȖk-FLݺyndzlȱTۻ1s!}xeZkarq؃d+") ϒDº0Rok\|o+a,kp*NNu\;sŒH}x['qخnefǵ~sc`ݛ[k#fyS#[YSQ4< ll6M&IیE >;b 76Q#QHllO"$%mY 5oq{hzh4wJoּ NrZ&Dmڕ|NR '+J(z:o+%=Li%6oJYm5|=Zɶv"![,? #׌b͛&ۥ;u&BN%un$%WͣxzIS п, -xy{_;ml!wys1&vmQ6P,-w;KۼYi [({ .G.`փ/lU ]ӂ߷nMm%ImRۼe:ʩ8׳+j{ N X̸,W5Z/y̓{f?8Z/)7t]&bޤqZgYߍ!AY5 wcWc.؈gchWW>ihm= ۼMሑ;y"|znww8Z/ݴzNi,J{v6K K_0.a^tc7ʚ2|,۴>FTly5z(8?]hM)W \KDԻ8jd֠&>^Bm;yr-d6o~=4<͛k_~k9:Kąu=q^RM>:x^"1&q\Cm[(CvzIڕ3{ we^"A1>PlGIIvZ/wYw'!\J6A%srF֢w3n1mo۪w(jYiF8u9kga]r uzCmGxa5:q/F%:ϾlKt _ϓdK8}ۼOl{"lwV1Z/g{+kPIcy^cۼgN%ۀY#㛣}eqnc޷y`}rFwV%vI5c5zskˤ3Fv4G%5zԵ@s4>XОoD pZ/dJ\V*5^1ZhqJm܍jJۼy.Vh^ ?~BWaXC)]#N%n;I>hϷ^!Q=^R&g;HIۼE$yQhDs=YYhb&]ۼ%/CʢJK~cUo6l,ϒK?o$d+b͡{Kjvi5h!y MAmbn wc[/ Ts.!l*l$*lf\l,ƒX~U^؇ Y"YcrvsjEB [/q[]}CFaKj#W|n%>>vԵ@f(<$ު =w5V3'|^փV0ZgH3nl6f8rjcw'ܤzI+\bf.:K&K dۏl槑oZQ>.jx& D=9[/w1͛3͛WKj*|mOM`Ia7[h{m&zɶmIP%n3"Z/qV͏K$^ o;Hۼ;=߬=}X[ܙzuu}l6KtJc፵F¼zIc qzr & g%5PcۀzI l pNId%1l[ξKbt;y:XsV>k$f}zI, ~V /a7};4o"x>T+6o:Y\~z^򋽾rhƎsrm$T4_^JZb0t^T>XIs7LNP%՜1Ĝz.jt$_[(?O<'[/ Ď%u=Xixi|[͛|NԣV%5ɹm<>[$5xgWMnXNmޒr˥#}ĸ j$duc.) _vq՗B;j?q} ůKr^ߋFn8ixָ V%9eQ8xNՍucfŚzIiޤ]ficcuc7!|Xj$Epo>j$Ō8y9H~s7?/Jcm]m!wJ1zr{.H-EɺrZ/ l+;zIzr]P\TvIbr^>+ z%ȇzIٷ]QyW%hyזR Ȧ)}6(g[/),;Wu%'t\*YŰrzɬ.rNv%76Aӹ~%b5on=Eχ[/),F)i4}ܸdycY͛4m͛ /ySѽ|͆N66oFٴKmEs,)Xa`ʴ}͛a[ >/n65oq}1Fo֭y}&-hY-IyKS;޷yKj%1|5oKxZ69c\CYּ/ck:7Mv/>Z`ξ}Ea>J%iX+|tU cxY?6.;vQwD~6b_/tl氱X)^(k Ð7o亨8dc`1ͪttW4o\7.\kyΧlV4ov]}`ǰVV4oC"N ys̭XҤ:͛c-@ߟ6oqVS^ۊγ^[$ zAl޶=H>1lޒyilR'\/ԱzSW kՠ᭎M3ۜ$BB"rqu<Fc8r=͕۞-=wo^#V69n:n ~-ۼ4h7[GʠmLؔ)WM{WA027Ruysa d=mbLF1݃|ѼŜToZۼ%6 z$}-O]f!{xx|ks :8ռs¼ۼ49 7y ݹ;7:yjYef`-ns`_^>Cni7*]"Kq+idw<]AIv%TM݅ MiD~=b۾> 8oswƪp=\Nύu3 Zy[vj8 :Z/k) 7zN z{S yiD4L{N޳͛ˤxv[8qEf8].l,!EKJP7[/pgykdЃcA=I|pr}.'Ûrcw2Kʴ knRZ/ѩL_Mwۦ8뭗{$ɞq+5zI%PY{n%{GGt7( 5>'5KJP^M!d^׵RlDY#KQ UK Ad%+6Vϝ{KZV/Z/bur}Lpϻ(p;;K ˱6}x s;Gc^b}jH':w SŒKsP/K0~!T_f!]#AZ/1^:}"^e,Tkf+tZ<[/:HKL1]wuўo7t;^ۚ7O[9F{*'#<梳I#K̃c3'4h%վr\@6oAf][dPZT箭 jmԧyqI Oo,{Ҡ#?Auz>d zIusg6j%N5k6K\}zka|9;i%)%j%#9?(md[%+x`\Z[/VF(QzWϧ&,md 0?J[/?xsaC[/41CB[/}0rSj=WE=FX~qA >-cMIzc{%~^kҶbzI ׅT(DŽ1GK[/ ~jϴ{nk'Ğ|Qc1J[/v3 3l?)`J[/+xe};empAS5S ]gTzn%{$ZIo%5.;-7Kr ̌j׵ern\Jy[Cwh޿ᤗ;O6o`&a7\}tl}cƏ#7yscB[/9?9&mK4k(Kgҙz",mʰΪ~q%HSD.]N߬x[񩕶5hzɺNŒŽRoO5ԫKjFc*/n!v?/ﭗ`>9)?Jodce ,5:qHɭe!7{uAK f ys,WPRVUBmz95כ77ΉGcyK͝N~ o%A3K\c#MF{ҽC7գq[%qcŽQ5IߘMJ8JJ-7]<,U>tUj}y.-gѼ9O [ jѼ8fc|t.7ץ0*՘ [&ͱ0aޥ`[Zc}R/k6'-P|xIAF\Zo4BAt46>TkR͂:Q4]}nч &L/aXap-` Sks/kP,~ݸ^y#X>D5>ÛM+css\amk@n]r3M{^<k 5:Z[/ٿ?XZ%}yzI}|P^ۼHQelUГlKjn^ m7MDZ/[HSY%mO/e܇7fo>'ԝ7>n><Ո_oճb]>nv:&[/X)l}ajf#>њ^RyfkiTA>o%aW nTlU&h$g?cA^|aQ;msr/ +~}z%۷ :of3Sq[s[/yl]Ts^"Ju:|s3/K[/fbM!&j~%5Xv?{^wOoϭzH%w8>+2B/>}G;ۼ}h29cBzsܩ;v>UȷV3uөχJJBχ88׸28ا6xftBۨtY=mL T;3k!oS$u5V9&վFccn_[|=MrޅwXog zx|aYc8-?Ҫ'5ռ)/m]·H~\M=0m tm! m{c4t gGЬ"j>/.Û\ ?[%rKlLݜuIׇmz&o*qÛpLq}x^!Pa\Wc!u;&!UzkbΓ6xŕnm׫Pat\%0P؇7MOO0ڛN}Fcǰkam6VxŃ38r٥Be 8^>މcI=muo6gjsMͰ];o&ʶOV<4Sm98o~:(meXc%Û姏7omz5Û/FNEccozLV؇}LWc}rmonX3xߛIwKƒnT o7.)o>y'gQ̈́㪘!$mio@8>io[$ ->2+96?ud#[^pl>s5zW)}j: |xۗ'=/c᭦ќ+q }xۦ92Fc״O>o%|ظ 2&מmۼjW7r%K^t K`|]x[/ڈ ǭԐL |_[ [z91:v7u X}j,1&XṘ;%6iҝii];EZPE`\/YU%F{f;#Tm!3C mXo5d}CK1j,Ոg y>0&[pu9۲O`=VlR>bmWSOGU ۼQM'3irsKj ![Zʧ7,݅H*i]t:X*86Np\X/7WcvRMM[uy6VÛcNhl|am;\g;+ՇAbsCvT+ !\V9D>)熚s4w u5Jwְ-|w khyt[PO?j,5QIcK&᭴ D}=܇wxx$AW s ͜Uϗ²9 W^دf|dÛq=Û7ʝx+co~6dž?YPEo.ujvM?m"U#12<KS^;dc}E<լM P+xx۾\L»ļ٧i#ު'ݱ醺r66Io1'/~]sEJy5Gp6\X ryKog¾v{(rPJgTzcQ33%!ҋ|xNyy]>BϝFcS}xFn_v Փ]+QV*\ZۼKK2J䭗6?3&筗T3yy%U/I lTy3n_o#ysePM|-u5{|x4pxL m}moc|sweMlxgbݶFV?t`qqRQ^C@![5ZˆϝzEk o[[by6:ԗ*,LJurf%EyxXSq s=/DS /E1V#(ߨzzsgc%?2z46k&!Myxo{͋?wT S:ԇsg*ycq`kk }x[f;U.ZgV f\gWcgWUEC6KP:E5o.: ۼmf=zQiÛ`QisCX^_& k^vX0{Wc1bj`Jl;KEc7'{ț7hxƳMoA[^3n!}x+M~o6y6;ȿ0ƾjw0ޒ1N~ ۶5ϊjN4JciMV8!z1 k/r)]exc?Hy359y͛۠\k*Yټ9C'Ι[М*s0vټ}Qe"o:wgJc?f>̇7URÛ-eV%|N7JmA|FcӃ8/m\<`BBwFdcު̝udj,r8A;`}6Xߛ7Twh޶I38B7ygK6ooo᭦Yr,I0}c`PsZc?@ׅbc|Lޛ^ǻ·K雵^3z͛g^9 Q<Z/D=\Щni3gZyǍmByH [r-d. [/LΑ8o5 W)=\߭zzcm{2FccrΩNn^N}Y+w쭗x5VY[/)o~^[/),i4,<ndc gU~j*ּYɦh?Xfj}޴͒{:,1ּUtr;4oPJ9yVYw'vJ/{z̺\q[ ^),[?UE?yqMX+Qkg 5N<K »`{XJ> wX5W/-1k,y{'>{D~[4o6.!oFƽ)l3L.y۴QM6>y Wm[^Kgټb*Kf2yrC΃MfYox*NU6A>!<ޗ_hk[WGSXo?5bo_V(T'1zc`r+{s\ogrWٓzxws>R' =6L]mB;oy-,IU[Cyl3=[Nk # ۼ%v޶ۆyp1~0cڭ8ΰHG.f ySUN;7Ts, 0c6oNjL??:X>Hmޜ~ywcu>@񶋰[\;j)9f,dzyN$5r-]Wcig{MoVXЅ~XwXZљ}xTdNM\PX+w3ÛpPwZ|@MR>}ySe]c;ui4Xk;HfǍ]eZ͔k5t`l|c7K^gC7g^?laRܛҼq ׎4oitÛ^cRz{v,Mz5λ=(6M) |`{+M>5Dz%:.XOW_zc^66V/`;L}פ}zI;ۼ>^捝soDž^mqz9kIgI%Z?zzI>vޡys]uBf%sb KCgh$ߛuc\[ӧ/[/&] KgVb|hĮתPǵz:t덥9m1_,Kaio4fؤjKBs߷2hoNh^b30GzU$u\ۼ-x߱d^?Ϥ>9Q!bn[a`${W?uKLhF]7ŃmD{cq!y`Ҷ^=t6|h^vz6a>Ƕot|T̫Ϭ}j zzq|YkpKLm 6[/1w=΃>p2x%OO>!`^b5Q5]nۼ9k)tc`4]N%2~,4>lr+;˚0g%iƟ_Oz^:`qazrzGe+0[/z(}8KsJ5ǵzI\yMKulť}W E,bBa^쿕t?޻&'jPû[NAvQwߡrf%um*VPO C;Z m.oql}L:Z/q!ݨFʾjlm{J^P/͛魱HZ/ql0̴mԹS,BZ/X^{'CgF CYq2[/qMG -Elfc}z,ų²^=.m|1t5Z/qSc{srXY~[/qO=|=>=ֻ҃m*\xmFyald4TciDk͛jm?̠#J/a`r'̘qʹz &K668f~[%N{0<'[/X\56UZuzT[/{ǺwhªX;XimzG ;"lK<H̝l,11Wx^)>0vcNϲmÀֶZ/X:K* 뒪wOcm; zI\7nz:^) K =UC6K$hꟀzI| :VvghF_d^ԙs6V풌WvXšjCX`+*)Bp^5kt[kuƼzI [Φ_MoKb^\~[?ȻV&W%Asn=1ΰZ/` ׶ۤ*n.Z/ 6Kb'pQj$NJ2oֹ?ׅj$֜4r/5ok)x=m.1'r^rqzI{I߷y[siml,߅2ava|w[m&5%IyoV:ۼLM gll&g6Y7]PlyAkP\uu}9j^g/C߷]2yˋ}H:E9{ -ȫXW7Sy좾3o%UtBaߤ}[/_Sɿؗ*խԋfkV%(4z<3j\;V&gۺGm$/uzIuAQhd_OQK^=6o}: i$ v P#6cv%>y|R>^>֎^3׫DlXp·W[ۼf5(%lD$먤jiFwV+;b2yށ`iR-bPZ/9dmۚ795mz;NRKZ/IErrρB蹭ԄJ"(wFZ/I]^3nhmfqw/KRO?*P:ʥq%wfa[/I9QԶ4{d/dz-S߷+*6&[/Iܷjg?sS5&|K 3ΒK]_m$=Yh\dONQ ^1^LNKxS\Tʉ^?6w,֓I%n;j=/lrZZ/I)[w \[igJ}7_q I"l`R^:hK%_W2zgζaidFgz ֘@K>>y_zɍܙI\zIaVoP*@Q\^rc^4k`ʭĝLYV4sor%j_˭T K=\7yXWwwYZmP߯ʕ辰mlYm6|4_No7o c$⼤+7o3t;x6WRnآxVV<fUzm_<<)ofr :Sy[d_`sqEޏO>lX4zcm&lEYimxE&C>1AVy{'嶆wv%Ѽ YeXhB}M" ږC,TyӋ{lޔk=%7Ջy_/ټ}fI^"ټ F듵̅kwlX+.ۚ7L%~K6o<z?N j|p:k-Ďd%z5oNF53D0ƪWƵ%_tռGk[j^jޜkts>|W&loM:okZ?e?hނfW1y,j9:HWEhK"0oE'L7u:\u4oq;4oos6o7owȃz^};?\M4a<;~1/ԹV tJcBաP NmlrxR|v\6>'k6WmXTBV6H%^WVQQZ76o{!y4ˇļx]6F{t9ե}ԃBW6crI6vkWy;r=Nmp Qy[4 u8sG>Ƽ,ǻ\4o Shk* Am޸̼geosbl\y:%lh&sV/Bw!E/T7ΝgvV=6os`2mdHr\Kf |_͛~z)ưIyxKjVÖwz rwV%C?DۼFC[/XRM-K~l{i% (z0[]Lpo^GPjmdاu>ξKS{%N%zv0~T,뿥;!v,f6A%2ò6֠ՃU1*KFM7֯>6LՌRV؟͛ۡSGT[/>'>K~#_zv9o};b]SAvI%5{ i%OpTćkd7mߛa[?nF8oγS, dvf8oJ|@S[/ٮU1K-}-i^\sU_^0[/<_3[|fQ9^CهMkd_qsް_o8Cnfqso{Q/緱}ogpN] Q]B_-9j7mKl#klY3OznSN[%5ttSP[KF~r%7O~T$=y}8DZΖ~vTf3vΉvl ʔ`G/DBv֘ |;zI,j;zIRόh.$Ûs%9^Ugu>KjHXZ/[zy35#"践^R8s :8Kj My,xv&oZ%5ȹ`kݝTc }ɠw؛ݎÛ$_u&7ʌ+~S9Q}wVxLou9'J(GΘB>->}-XzxOʠ~6|>z[WqzeOo(F~Ğkz'p/$Z%?>o6j@ε$jNgyj9#6ocVhN[kY%pkbo'-F9Dхa"o4Û(~x9𦓵IpxwN:'fSGu7S57 )^+y\w8ڠ -qxOLϲ8Y]qY/TcnqxK̫}$,'HoAVOH~sFĭ9^߱K&MٳKפ8d(&߈l#^N\%Cyjr\$-om,m:?m~jJ/Њ-oՀq^o5l=M 5_=}gm t}=g6@¯Û\Fpx1Vx_7K: AzÛr:>żÛM~،Û-ΝY蹇O~߶0w͒:J#xa?9t_85Ģ0oiSqxsu*%>+S'cZ}A5b>otoV-8<P>ol:|86>:8<%j=ζLgKhSW^G/YoF5K0>utNd ]U/QG/Yc.,^ןc[a td9*}^&0ei@K|k~EoVE=Qo}_K^G/YÌmqNF=}jأ,aw] ?z_I} %K|"xd ɶO/њ|񣗬O?hEԏ^y&xŇ=zɊNjzKV|Gm_ KV~mpA?ˏ^R9OwVXYtdQܳh #G/'(3>;~ro'2`1KQl{[D̏^"޻פt~޷y $ٞ a`YG,KTKG/oIy~u\gG/+DžaK~>^"c=~ިiQo?z%=xDD5G?zgޭPmD$?u sd%pߤ=D}%cG/fKuT,Ԃ{xSO0saFD>=06G/+Q i%ByWIqz8W"òf. k%KpoKr9qq9o~G/cjqҩou6%q7=G/osb8z|kT%#a?=ތScNqs,gӾvD m8z/]Z8z܎I6?g@?6^a̓mOdD~TP ;^\ԃ-^{x[ dp߭*Ȼg\G/Q1/dG/QfɣN1p_Dq6}_G/Q3:?fUW|ߣެ/r|5m,(Νr{xc'ÛsEso!\hr}{K4uF:zwf8z]B9DU\\.>%v}wymN÷mDuqe+XG/Գ5qҕJİvqͫ@"^bJ\fKi8wKLzT>~(5^bŪbovpX^bq9KL?=&>^b >?Rq{%7)_9^bTGP%t|%[K쓋׾L|[$`oއk%~O}RG/2 %'>^VB=*^>s8z/7|8ݾׯ/r\gG/q"z0F>zI{ħ_s%b bIy\gy-)KbXpKbqs~mނb(U6a)s-}yM7刜Û'ۛbo;xK¹R>#yAg3`oqG/G/_m yF!^>{m^R9 u;Dcs*`Ÿed%2莭"햭K->=K;p^K66)6IިKkmUTGw~gcNldc?>Q7[/Ybq^g@rH^Y:U 6x^8߾P}^+3ۼ/` j:'H=%5{xoUx[~x7AQU[ׄjl,=[=CBZŊac7Z~Ve7=ߡg6o=w.p^HOjmj:} ۼyȧWιfcK4Р7y;=6o13oh^o urIKڿ ߡUD}zɊͯ\`}ry7ӳH;^ag8_[ΉV֩/Z/Y1Sb1xc`z?^Btڮ޷Cu.q%urUxK9{"a.6of+p^"1Y#ۼ  i[[/K<Ep^RhW WoTo zx\ּlÛZ{,{xs!hrXow=o 7=Tߟۼ5q^"sZ/JXYZ/ZӷK*)w=~6ogz{:<֬6o[ds^<ƮAF%Bs {mlX1 E.Z/E>6r'a笶ozlWr]/鹱9O}zIy@˺>HT?aKu=%1_K{bd۳}okZ]~۞ |q}>ndsgElz֐L|Оodc!NO:q^ˡw^ς,oԷy{Y8:D/t6I3*}<ݛyxKzkd^WI/' ϨK[/ؠJzIIxcI3͛m%X[1ƢP{(~z+ /sc7ٸ`W8}mHzM}o1}ߡy3JgT(`Y{ /j;ŝz@Xǿ͛$|KE:bv,+}zή}sc`Tz;X'ߴJ8Ynsb@|~cwŜ] KN&=yK|߅F$?t@dao>\WKҝϗwK2&^bs d_X%wÛҜYtg^5XJ@6b(Շ2l"Q%[}7px[yи[/w$@/֢5z*٩{kҙzvք(ᬩǍ͋sǫޒ{W6<6Xߙ)Kt|uĹk< /[/),ŝt Y%:>$Ҥwh/`g+;>ZzhDzƲݷ=AJ%:Ka9=SпÛ_=ukŊwVނ{:rdMa[hsKtRݟ`{&ol61{zI5ēߡyscس[wЃ5 )6o;W! ~ߵy{'9I+X_(_c^ ٢fZ/х=cxK6vq/KtQ=^nQzag^RFaS uIk; b5Ϡۼ`s ?l,yQ՜4i]^EW_L|w&b ЮE5З;[/Q|2wh޶!e%"Qų+>7vKU{n좵#kV`YHٛN>w"5zIaYzTK |;[/Q]A1ۼ)nS@C]:Z/X7c_G7oW66o'1kl,cc;po^}=[/Qqq;4ooǶye^X56o4D ֕I6KrLǜy$ۨVpNO5knw{\38n:n9zIڠ\QMۼغ;$1wĹudX&N-Z/5sf%闹rz]6k*pjcv[݃mNk z߇7cmJx;dc)fjBj*+kaLK*cLm^RL{T=q%6T b"KzQ}ldc9$z%(X8q,`+;JsW%5X·aKl]z}-|m/[bōmdMl(GU#:W%^cu[9ԍmF\p=Kl; (66X?^J5Bըqx}qu6o2/SY%PiC5oԁٸ\I7yz^UX<׷gVKk*\|2q%U}A9zrN}mjxk~mdc=f~]0y3 6yZļz%F={4)Kr|^R%P/lf?lK6vQ߯E߬3zXM5ZX褻pZ/X#m;rAbjdckjaޜeS~f9-;'掺0Zmļz6&a_VV%+ls]*ۚ`HAb^w&roKuq|`jĶNz^Hj2^Zu=K7SZлeya!iX'p=f=`}nTZ/XԣKj%yM؏3{JXj8}W3-l%~QrKP{]6VK6gmKp=)e^8 D[]Hۼm_M̝Y8)dգcjV`-jkkīi'V%(O^ ͧV},}d]("|ȍmޖq/m ]-==WXhwUۼ Fmۇ( 5i['/:#l,1ߞ-zIaɨ^Rj5H%NܱzpiLSؗc\;X[UE%UɵpƒmgԹo2}TƢ#l{id;4rJ)l,wN]hFC%Nz޷'m?B,k >)]nΨyx58&=𖜳7αö^|Z/)}E^ܺ_7 ·q=zvy^ 9 zg^Դ6o\k$:QWK0G|u>=)ϬtF^})6^RIwqI\^N}rt>+/Rpc sg .ԟ@Z/AuIzS[ř񬻽K6+w3=+W lt^1t_gmbNo}3Yzm[zI&܃ծy-\;/C\^W^H%9-߬M& d|%T#>^RX%\66oܿ5r0[(l{rzrO6|-?:^;I%;I+x^{~=g#gK2Y_ߎ-jz$լ C%;9/r?K65:%q^Sh~9J%\E}:sMK*M:I?/ӎzI\hal\nU^`o{փcRW/;I%۪`mzKbMKMڠ^g:gml6ٌA651GVZ/wxzo'H,w֢px96Iuzިrփ?,甝zPWz^x^:`;J[/J j%U9DO[/),MyyޡyC_gU.k̓ S^;X߭kmmMä:o>)qxel\wH{^ ktO[/uqNoD]C[/GwE߬y gשw^ 5zdbJ[/tZ/8li%cM[/tQꏨDEHaLKb,^p¯$g~~Ûs!+֡n=f^^Û~e=)lpLTo3nQ 7Ŷ=^zxO}pxs ͝jS;l_`;>=2:zr_*YzIdz/h%8[zI ^/fqU\tϷ^$K 6AmS&y;).]x-|YH}^B3G/QwV޽pD?%Ju8^Xu{lK'p9zɻKŎ\j^+܌lu+9y[ףاgFu?Y\=Xs\mLmp< ͛ S0V^b(iJ=%F^+OAb^bT?d5X9zw=^]ӧ׎^mƺ:;zɳ}8M>=Ž^؇]8ǎ^Þ[(KW6(wfث}19lq%yM!(g6VͻнZ/ۂgZi{n%yYZ$Ə)'*S^m#0܇Js=@,I ǭdes>,6oc-5zI IDM`|s:̩Z/vg1wkdZ(`lcL8:{`b_Z/ONeTX^~Mc\uzIlXՃ mK&=zI.]t\s-fTg uiv H\KK*Va}sKwiAuf7%sƚtV^{ǘ_bTK[=u}r\iwZ/^oڶ^bKLndAg}z6&JAlXP mzgN_k$ê'Ѧmd;Wu ۼ֪kE'o{*K'20K {s_K c1whQZ͌^ԟ>'#AK66?S^Rh%of18Bes`'K6j-IPB)l_6K҅ul?^Nڙ sʬU1Kk$=4DֱZ%fS^m$.Z/e RLkdk2o$̛AM[/>#ׇ}᭗d**uB\m/j y۬1eୗd&nO>w]^/kr\ĸzIai[P~uv[/)-61goxAJZa׃hӖvro͚i\=ؠxSDŽ_=>Vw-m`sMy[8jټQHF7ڝ{"ټ-z&[ȉ ò^Umצ$ا,{~[Vʘt|M>}N36VAjdqНzj3saV&>;LS\yAc+:C=3uN'l󦘟zOK|5oJ6qM3w'͛ {y4oxk"4oZJfu{u<|ci,9.͛Pw]ci`YtaJf鎕WY[%fI6o\5w֖k,׎Uu7ڼ%>ya,όTw<6]Q-ڒ:On M|n6v}9ݮ<6olO;Gm56XSFwE} Ǻ&ojO u9m`N=[Pqk=_-+=7Sï%poަ|tedy6?1څmުR:XS&Ue!y[T{Vm}<-l>[KV=2[y>C`F&v5G&ѼG)`?XtwGgn+Smۺ:׵ۼO?ľ>͛&϶I"~XεWﱛhތfeų0ټUټeg{6oϼWqCcU9r6o̿(м9_U#vὙ͛!6oAqQiyBsw|˸^gCwx y)72whgr"19.9Xy 2za`ӓ/F\v3*ѭ,l󖟻 uT8ؠ"L{&~jwK;gI^W׋\£?'g`Nz^R{TRa+uQz]ixD%jĞYfkyqmv0̉}zo[ٰ/v^2'S~ 5hdcU^OOϝ}ʂI6oB5uE 3ai?⺰G^S78S>Z/?5hds6hG5o²ntش6o{fhdr &UK t^}P^2-'`9ֱ:[/65fc~KaHhd:c[[[#Z/XTvlw^N؟+Z/<|[D%ӝEjsv22;4oX7e%aw3Ϯ/};t^29WC%Ț6&YTLj/g죚}L, i&@1ĵzɺhd]qMwƚ~z.[u9 s;E%m^d?^\;Y}x\zx3a|>Z/)# Zy a&R*lFyq%LzO5F%+}LPaKV:r -S65giwK1mVc|3[/KƼX}}wV#oz`a~ 7KʚB3X%^3wKJS$(zƮgxof%{8W ǔ60y[C P_K~;ے ۼ-M)g%FB43:[/[}gmD9N6Omބzod%VK6Vh.KGpY蘆e%c{}zpyϞp|nf,1mzÔlSsYulD>9+[/Xc-5lD,S>#zF`|3[/ٷ^t0{=[/<#xBz65gKz;t^"}Js5:?\H}s3m+ud%҉98G7[/\-6o/hC槧KOvSc ^\St^%]zI5N_Kt(grMʵzI]ŽYC%:҂B35"܃lD'.mc:k׳哙c.`^Rkk/!,u,?kL_/>[/х=TϜbzlDerµz :1I=>ǟ.ˬvZ/X/G?N8L̲Uc-fb)[/%{0zrv=KOy{zR='"[5 p>Y^\Q=g6oL]3.[/]hr^N{j`7uȦmDc& K4֧vǡݎS`|k:jzIl50%[/Q\h^R0;[/IΦa Gg㻰ɳn^bDK6V(vplAI y}[/˸ΧJ2K6cC1[/y/Z/aIlļl3{4mQ|NK[rۼͅ}*U{hol6H/Zh歼*' ol_|u~m'tDּO9o,U٧m8þ7^UaX^caWU&l~f i o=Q/m\η?q1hwQMcr7ySe ykdc9dk'~c?5Wa`llm6oK"s`+={lڃmޜz/Z/K&PPia>6o- 4 ۼdbpnl6>s &Co46c\C%.fZsM}$Kx>KZE%?<7mjS^7j5yM}hlzO6˺s|{<'[/A5b^`ol,i6x^ԧ2o%d|soh77y[{_#Z/)}6o"Z>/o%5pc7IWQm>nı0ARa7\/]9Z/ӛPKq&]n-{Aa{gj%eVK3f ~ncBTSZ@9zvyECx^!/|h=_-l{(zʹ߬ 4Zx>^Vmb\Oڻ-gP:'[/٦ǖSq^RX]Jۼx^:~ ۼ%sh^gf.5mXm|QN(nҿFcfL.؇}|C.=[/WxZ/ ӿzBwagcIB{®&Rm1'Ĝ.OUgluw?,TQf`TLoyx:wK]*HI=;Tu yx*z鹇7IMqy}3w8O~ؕ4<餽YpW['zÛSMEXuVyۼ_ߞu6 wcK{sR=4; my~ X[[yv /uxw];yZ7mQ*90o9iZk^~Νmœ*ai.<8f{9fot6XZg ׃~Aw{x̿5遚;{5,[>\gޜϨ}o;b>Ev~s(3ߏ݅+-F1n-d\a-V>SѮvxI7 $~qНed-m]N=eo!*LkwKgqAm|9hd@yd?^KuvWyw̭G/k/mÎov9|K1'rd~|m#bb6݆5Lp;%ݱ#^2V.Ɏ^WznLEÛEK:ه ^2~6L{߶3ws|={x%KuuCΣ_?]';zgMuG/&qqy棿{YG/kWzM'0#oG/Vo,ovx%c7;k_^2[\}KfOiKf!= fT}>{xK>m-o_X^_ƐmzM^.#-SL޷ykwǠmy|RN:z{-K֊ZŪ;mG/kC8`gvò&6.YG/Y:+rK kD{lR=Zwތχ>^G/ fERlfdGh7TÛOK֏^R]Lͼo6_KVי'rcoE^YՓ;=gc_oD}bKf6];*,u&Kݲ^"^zĸ:zL*s7}=tly.]G/vQ_G/{߽Q0'gD}up>ŶYG/_AyEk%bPE}1㸩bԍ=e8:zش^"P\˶ZW:kb"쯻>1K$X%yKuvY?%zb;J&8z`gh`~{_u}u9:ƝKԅbW%_D\@cKghr|so|͛]B쇣:yo?أj6-ޒߣLZgml}_󏷣*i\9g}دO/Aϵ5fsoat_(B{xc.K@%OׅK4oQoWb:z%kmi؏tco~ݾK|}h:W_b͟m0"yIͦAQ^wQKo?-r%΅7yse bT|%M:^K>n=/G/q 3}o=JgnlJKt)'G/ 5W?֘%!xV+ y;zI(r|׷@mJ{S/EWu ~w_ c9zI"G^g*}-H(w84qK"M.5>礽[%IoP G/1s쉼$礼5o`}`QS}'9zIm G/I9-ߚ7gKY߉A$I?j8jr i[ ~ddriUH+ mirj&rc X?X>KfK\fص)~kdc4݌z(׺zɸ>Z[!Z/f1LmdL߳$P% GRZ/9oҋ z2YK*M|4K6HK6}Ț +OJ%4ʚ+_ۗm?'K ZzKS|%%"MKƚ0[Z/+!h$!kRmdO4YzK0ӫΝKkW6El%ØD;zI 5K66<*766o&sPgm|d؃B[/>~jJ\L܃,3ztLlPw{h%%r)%FOcY99zLgxT'E!/6\20F+dnmˌ^O6Z/]k%?8pczI͋pޛk}$I[/Xc; Sz ۼu%dOj%>}X^R#w7!jzI fEKjX +EӘ sE\&S԰zy~ViWD~h_~=P-Pq^"vp^R=틚I^RՋqm.[^l cixs[/ϪP>w6sk>TKj/eTyUK/)@L[/s`-gllzʹW}[/wq[/)E,Smc,zߵ^T&KJ|c>}_~kĖϻ~[/z_ixÛ9EjOҕ W@+grzn%~Qܬi%j>^~qi}v4Cv%M!+m924)EeKnC>/|;}gHKjYR3a'!6KbsS{[T` kmqM>/oX|v !j~7ű?ĵcul<_q+q}fgԶc_)dXwpMsNC[n6o _"Czi^4 kv%= 캱cS|s5[/ӂ{2s־:J5y%5psoIbYr%źgK[/Y5$)pF-I&%pVۭJsZsZ_{y雋oT()[\ [;\1[/-ѿy7*1ds{5 [/2nrY*~[/#a{=l^"5ەnKs/s׍'?}==q=z~j?(/Mɧ_ vc# 'nDb7vYlWg(٭܃.5tA[}'FwMp%7md9;c>S&d]76/esȫ^b O: UحT8aO;؃.ݬ~c۶_szIۭx54T[/{V'0+=%QFRJA{KpaJٓdzI3>~[/@g=lK{U*u->)JQ{{ʟLÙۇy}_sOIzfe,8}gsyvK>5/կ@υz~nLA|?kFB.[e¿E綮|jHTcýzLY%}Zo9z=Լ9x-}yzI5%.jo$̉,`?`gf5 m?+ޗdKEo9q\q<~73ϧ:~\wڙ>9|53๷dcTO(Vo>vI2w,>E;حxK/"ڭxs,76z7sU`` O?GX:zF3z_mV!sI*o߶NyLmmBB^~=:hgfkv^E\[/)l/zBĝ+~8/o]ܨ |{$͵H\{֙8̇zv8,Ϟ:I P/>..O|<&scotch-6.0.4.dfsg/grf/4elt2.xyz.gz0000644002563400244210000034407211631447171022013 0ustar trophimeutilisateurs du domaine1ef_4elt2.xyzdM-- ]:,F!ѣϗGgI3 w~g:Ht_L0Z#i2 4m*Hb0 aؠo^ 8dgr+@׬%HK/j?HX.bb<4:߯!?96K@C/#q2.23"X!i_6} ^Cی+i\ 4?&YxrHA5b!_7'hi 2ULZ$f?|:K"!~Sq(]8$ q!dCg;~&\~L@ @o;D8!e{($\x'!YgsC@=Jde= 󳐶D'CN)5KmS}pH!$)$XC!}ꯣ]tHK?s9!W͈ŧy}'Eb&|{bgkMyc"TRL& }D㐈Xg /rS׸c@*ѶE`^O6C'qF*bōvGˍI7!Ò^Bh>tMry#.sTx'~Ctqovb#}o\F*^$*;FN;ܤ%y`J*e#vmUɣXӮtHIwe>$@dOInrRȿQ!,tgTa4/2l4LhCzZXSAŞq罞k?皇\XW"ᐲt^υml_gQxr݉5#Ⱥg!]B:WV~C䚏ƥ'7I\J8U|9n!&[\˯8RS6yH[tG&!tD8IxF,hd%zZ_n%6G%؎u+O?}eGfutzН֩2 m}A^e,_ j@ybPSdˠ|B>y+y ⭢VBϝSK.oϚȃŬ/L:waǐ(bm)txBue]+|hgzKz[>5]s~w3I(sߞ|w+lΒBɅQf*jCIr6RW\OeB􉖐IGn\.p']2]^X|k,wF9Ȱz]Jiaԙ^r,߅$q=Ϊk (GE<]qlFx( }jQGԊ,;p#<yYn]]G!AճկrOGe+muW|$<J2'U;ԊFsWJɜA+c\{5nצR^q4aw ⊺ );<:Ae? ;4wSZ%mpa)]]W~1G#I-srtb]sS\z][0 Ey{G|+"HL bՎ'ylvu\`$}Z ky|n- .U3oo{eMCZTk[ŵ|445vd>Ѱ{FՄd a]Ҵ 2ԕ]`#lbE|J8e\ ﺞX }h%=h]u4fXZ8Otm\"Ɓ.4h(V厂̰vtj]1EZw},:7(fu6s+yh2ibV7J5oD!lݨוհxi6y&E:qvP+wt ]sbE oujؼJ!2 @^% QJ(9(|QJ4;EE]MD 젩5du I[*ЈO{7T^FmKͰyknl(Ŧ/yk :rY x.VX`qC#o Xc0e̷H}hCZFg_}Zm-;2,DžJ5As6gu 7_t)JUꚔ:jM^WPfk&zFc]s̽Z0YzT djhͥ&'YPMugCgЄ$[ WjBܦB(*VhB~n\(ԝQb$О$%]MkKXˋ9;vԲWֲgeyWL {pY6[SP-f20c2+tRTFByƪYZmZuH@CeaWׄmJCAWs͔\{Ѱ20A5p Z0<ahڦey6 >]mFi_Mj#yM]ZReIVY K߆뎵PۊIT*-[ נQ<j?ZFyfT;OʪIEZO  ks%S6iܧ `e[fk"y5tRխGXˤy09R93NL6j y}cR526* s17V;qS[_{<a- +>FD `Yư־V]X| "Iެ}mĕOҤ/G[_QMZMr+w5ʷ}Mz+Bx i>oJ=mk$|G\~x]`sya^4yu*E$yPZo!E$ ûT KI(U2fӼ-a[oA}^R^Ճ {eAʵ>V4 ~{kE1X+ekK6^+rR[@Mr^x؁26|V/BmZFu}Z 1e,0W{^ޮ61a^~[NKu{RNTXAKcRm: =v3gf;3|2ڴ˄?_m[Z: ~X־{k6kq+QroyB-oI-¾2@5biwB'@[zd$[L U i> !@sB'5֤~}%󢙷<5ݣ l([f9ZKjP}Fmjl=6Tآ kZ Orj͞R[oY B>&I~=hjB76ԄJGvjx4!^45t,5J[<4Rf٧ ~Z)(ˠ,OdU4<)4W4_Qúah_\BWG}I-LVC٤@[I0X-K3Y+qPY |^hhVHؿyB ձ,\;1osG긗C91؅Wy_G35{q:Gy-hVNjO%whZk htO+aa1A +m&&' ~yEO!2VԄ6i&āͳޫd/P ,6ԄQ&<n0;ٚhXFF=xY>!Y@ U_ u%V4(=Ya-/EZ=oLHgOԬ C1LXP2]sbbճ#6=^#y^.aCk m˘;W~Ѵ싕ޥ| Mki}.vWF3Kq*.2£+w>+5=ƀP(":Bk:?VZ^xe EV-c|oq2rBN3\eZ;Δ9 Bűֹ@ |܂XzGZ֞6&ج@C#Ǹ .-Ǽ|@aC+Ue&0[ ʈuP"}O=-3 'oȨ ~|st|KFe?Z ~Vϰ< o/Q.O=2x[Z_ 'f<3(ǿ7ԣ2ՌgEU W^^iL̋#(_Ve(}nF;}qPs )j7f71P&l:|J =evȇ 4uh 2 J3R:Ayc8cEKBIqr7ZzȑP~=-k<2K#, 2G3c M,z lǽP)zta R%[zJJ- <žo.VʣY%<#& L1ugjGS>.#k`ȣ響`(Ocqb\ƽ-BO}*qː#vfKcؙ-^-٢ٳH.bg;O3[cG l~eJګgmi/ mr>#G3 <6g|١ &%1Bu Zi:qi;DYP)eg ql+n:Vo`s  O]%!K:Kg5ɷ'aY7LhhB."Ʊ"YGMr_0}PZN({1J0UG>ڟISK|kdCԇue }?_mV궡[!x1`-)ԙ{3rk1tHiiތp̖u&}`#^ʵ<<կT,*Xu[ uɤgOб&E-}BF5;-M^>74s0KxYZr=$yj zu:vQnGzj7B>C@Jz]L~qS1?i'qSOHeٲ߫_:Z&9"0֣EZ>[Ek>~Qr~ {aӳ)R,7O(X]C6RSҀ'ҧ߅YO_r-O'P>xx d)A/YtZe "U? ޮ^ %p+ }J,R1uBWh X6J9+6I02+e$ -WX]?yM,لUڟɑ[˚gm 2= 7He 5̯z֖~CrxgmXNjWJ g8{A׳$l]6@oV*r޻U[q/v[1Qȏ -]|·UBMmc1yl-h:pP]7UB2,;շ7/Aժ1g} =1A5I˸6K?=BoqW8 q.| 82 um$MS2,sEPޗaT3 ۆ=ltȞZFY_bÕ׸T{IQlufcNHh|֌Y[ZJ4"ge '(\Šsn*e~V*oo@JpuLڡO8P#N*7I]ڒ'h c'\쑡ꎮ½hR#e3F*, 穳g&O8c(=LǕ*?U>Z8 dž>cĆ:yȴ`@')?B][K[sNǚb2/FOVDc!1 ]4QS;N(1T1%<$] lD7Z:@3੃amϭdžZ>&Н.*#C@ D<ŃN1A!߯RF[jP0ZaT>&i+DiT 1 ]51 &>^$lv ^լQ׬Nxj੫G=%zkVh} 8;t] ?8&3Fԗ5 @8&3: [|z{huVOB$^O1 [k:46{qL6`MUHܫP_$3[QS5MeF/ɥX/J '뿥H$ztV+d?MO};+ZZ k,]ʿ Gɭ,V@1ЪY[O+W_[>K_C Թ~qun䘺ϸHbx՗6]tƫ/hk>(}{O ^ .P6`gi]NNH5O9!0Ah %3ء9ĂctDV?a|L%Kl/yp 협Hx`Tc#2cڅ`W &'uf&l>&lqww߻!C(Cӹ;e(Fv/c =}V!&Y} >ƫd[1Z- `ZFS,$`(x2+*~zf+}ݭ.D0c\Zg!, pgS˰C~A*ER^p"Az<Af( ڥVLr#6GRۗAW-# CHܫ:#Ck'lQOU>&{"Kcc2{g(*e{e̮c|.'~G# Xk ChLBO!Yʾ_SԚm.&~2G;]@'uSݥ?>ξXSϹ%>V}ܛF_x-v@NoK:i ByɚPhq~Bpź8֣ t$"n;lT'b8jF8tZ&q68կ;AR=@ZYt5v:*I!Kvf %ӵhe}Gd@~\UA-"f B/kՒ# rd2{|䲤8&lsK_[rAk6a+Oh}צk˺jC 8 c[joj< ڟ̬Up?e Kcq?u:0P2ZnPo A> #RpePL~M J yqw(5-E4ZA^Rj+<}D<82Wspv(ϡ<OW 0 kem T_F~<,BgqNG _^&A(1.՗as1@6;3/C&k[T!=j'dMD2؄}2(T``T_OaӬ})Z]4oO z)/#a qe8Wۛ(O}&tVv?5x=Y¬ߎj0A ~qU qf+3j <, VZ*KoGP‚܏<ʝz<Ιg"y[fΒ@P|]oNS;3 -^VI0C;YڶŞI9HS/jLc[jxO` cK $OΓA,&SX )l>;10C۱n9;+-P¼UFLGm2f_H$e"T N=ڱUE8ϭB Ҥ[ )GZ S(,\ej@ڱ׷# L;+Y8)u4hJK։:B`^QrIIco+iЗT=:PPY:ch!(? a,]GmMٜ#8.@-۱RG T@1#Rp †{֛\Gd ou݃gN+;jDt [[|(I z8^ N2Q̗6(gsWo!+H2j ͧ0IR(>Wusb_2vD&w9:2q9~V|O RmAl@<})ĿgĔ j H;6>l) \=mT?v[vlp%0ܱ=e3;!:;נ(];o;wdx8oZr0l$5֗bA$ÑdѬg2\ܲfK*}.TWf"MZ-Eo_rwVǺy-0- G]x(|;禟|2q=(cNgޜy0^??*?gS \ǎ븈+{[&^̕R2>gVQWvr`tyU@?gVu|_nbmr-'BA,# ҙ-V"1$z;ԵT >xoj_e%c>{h1$:-kNXmX0Q9)}Q㷐*Ys\/?g1Yv# 0ޱ%ݻxM;^e1%(cد€MKXy@`g/naN]-?ia]΂VSb[#`J9`4dwly!9I52N! .N{^?-}fr?=[z[6R']ڱ#%c+so0꓁s\KUAg\`Sd0oÀ5$Xe;# wu;|eġ[5s|cBz>.7(Bۯj,[{g5$$PRg@ŏ8 u?u8[رuI'X`4X>5p,ö{C' ?BKَ -Vƞy#jKH3X/xt1H(~Z!qhNIKYwЬ.1?x^k+֐YL %&q [U4MpW{lCs {2L 0^/@W}QwC؝I{@ewscƮ[wUg6S֌Mc7+u?687ь{73wVn/[+/; ύq.ܱU/Pδ5aflK^z̯%DfǞy9N^ő^L\}GO`> YbKS ][ G]"ÈuVlk>IFBdzμxp=mL٪!6>܇fu( zv[M[0 M;-# c6em`gMY]zݟ8N.%sςPN;~,">uǖ.DYǁ%)(Ȏ>N$m*Oz N3xsUAq}lXrCb0fm3Į5ǒUw2'84>EL-_srX,3)D|6*÷Ve=~iǡɈý䩗/ X8emz;IH5A mէ0mB}gծ=lϟ>zl o^"HRܪLfؒYdzigl,ꩋg\ jB>{[I" e 2..?ɃjxK>ssv -kx)y`cKJx}O'Ŗ"l\BjЫ86;F)G!K!;xA\h6y1EV:8܂|]͒8%]ͲNI>cl b¼6˕Q&L\wqЈq[8@k:֋@Oj'Q3tٱŏNy0p|> ^X]cǞyK.|?gޘ<;kٙ#@\VP?#,y3s.àçsp+-&b_x+(T)BwE Vw싿 PN&bvp|m:? ;VWb{וF13/3߱^= [x_$Ld/1E\3;Dx\$=j9Ar /GG>c> ~U%ҚpVVA2BaUzFyEޫN RvC uOFL:FETfWX [XK c[VQٮ=(:%=0Ś= L‡0ۇ} 1[hǷ^O7do ciM'ƶ HQaޒQowj dkmo[^XJ,lՀ~{UXh+ M}}9M;cOGqM[X dK&u[_ܿÎOS1a*>3d:c5c8KLFxB=u.أhtB֩OބyS۾FT%3$%60\{6b rzTeLc#'* 0E []x™EtpSY`l'{nbKDM%moBm\=Oe~7qN9T{QuQ{FLe+Q >&%D?G;h^덱o.c栎c l}C ߜ0c˫oyh=_'9z05c9o <ə'{%e(%ׇW70%9/BmT_̇W8:ܥI[|(T^\}tUsXK<ùr[W6QzsfCeuOj qKvɀ% 6 ,QXWej{y6Of~'Ui[b݂0 {yn~AV}ACФn."+ LmeloQh/ٟ#&fbru!oLIEߙ_jbR^&>w >*gJ{U'{(}e6-M3lq2V[df >cK] sQs"c{%l>/?coxFx~s @܊T%;_Arn9宵W#RְϷ. wx>KGo6?I^"s}4¬q%Y@lg`c% ߜ-wλ}V!ڱf%{\y%d CRޓfG=֯j@nUڣ_>p*38ǟ:8K{%>'Tvloa:\)gLP,yjR?'_T{|^^ ,.wlT/ @V; jm,[[&y~#([[H^ gy3Ph6;kw+0WGzy5*7c 3EB ]1_!pwZ ҙQ1gRau鳧t j}bT♯|)hp忍y\${Ʒv-K œ1/٩Dl}{?#/IswX: rF^flo2V\?xXqK2؍ 䓭 -m!kK34`?{b #qϭ{@"qkr1Cok;峻8`[콡sMOlkoN@o xbV{![oW[?^U/5qvz0sqKvksdz LU/Muߓiy1!#?)>t֐ppʟ>~t1dk0C q=~m/{SF`akꊱ;ǂ1Tp _2`3t)8[^"yy9CQJ5x6Qs lk:||{כ`Iz4x"fyTKR\Y_̇xT6r-,0/Arld#9dkd1} 231|.=`R7x o@1W0+ĞyɄ{XZoy7Ώw@2nq8^{r}siX}X{w ?5py} xRV:KUڰ}R6{_B*hU?.t? bsez~p'\YᖴT;c&1VVח:[NSWK:~vx;#tM{'O$RestA[[Na Ww"BkW9L/<r똚_>߰̓;Fʰ73:}jޫufB)WO_<-P=MIBXI' nxm8?;۱_B cNR%p;p'/{ sE_JDgE9<<ҝqj0qƖm^ƖNgzɾw7cXC^~uR!fow0_bLc"^㐢eƊl 7|*b}H\ LVK/pT [:>ܾ. U{*f`_ cز$14A}R~X5;'JHqrC6k?V^G]>Nכ\>\;՗o|rZӭK:R|^:|MK8lKmh RgߋeJqdAMD@^\+eJKv~{Tdd}WFW:#&eu)Ol$ b=_ C[[ @=s7#)|QF:Z=y!m,QM}qnJPW7︓i{_Zz=(^> -׵vvSpx7Εюn=/h闤sՀMErSKK1\KmKo&KzVJ1,m7W_>_-p[J ZĨgmcK[t-=K@z-\#dS٨c(Z8|2fǻҲV7ij^V rDU/aX3: C6[؈uug:a _/0o:'!6]0:tܮ4K[vP^˪t޹~'~뗏.XS/2MƀWp|$&:{DP(٧ޏO$M?ƇBJ{\eI=zS/b2#wΪ^2^οXc}!':7LA[~WcG?Y(1ՉXUI6O Uu#o\U=׀-*&>zp=}um^h^N{W{Kb_YK+s|Io*c ]fo7hty2'S@ϊC^g6 0Lǡi -v84^b !blq"M dV|}U^ ++>ξPRNo C8YAl8S{+h_9TX)xn\>@/_z~s RXخ:+^>FFm' xu&g"Pr-ޢI͛rlLj޸o{,bkfy'giRѪL.\cz&FE߃]Lã^@uF)? v^E_RzCϴz48J5ApR1Y齎W SNV%I&auKsi$x6Y C_bsΖ:e_)p/8ivNTzlUQ/y!wS+􇜟=EPȣL6PKqo]cO8 *?ڣ́ 疟GsoV~"SCf62^~b`K '\=%}{wLJ_?~z{Ͻ{_~&αdQ3 oֹ`p,>N ~g&0*<ˑgB\Zs^cESԶ#=:{<Onslv߯~ !({Cis vVc|@>V9ԫa3՟,)ϷSW&jaƿؔpxT9mƠs{Foa./>vQG3{pGE JCŻu|N´9؋#ڇE.ϱfGU/>'&&ug;yq2E4 A/>> ,IxqLU#6'-gϒ5Eqvz5DFqޒx׀>(>N,.mm{-&~%vRT ۙEMOx_^߿ؚ7.'>ּM ixi0v^Rwҟ|I_|hL1S[l@Ɍ{幐3m0ǩzN&'yO8uV#>DgQzCs:p}>ju^sTHiGجձ^~7r*vVD}9Mke6PUF}AHFxnz叓I3,qel>Ǯ³貮{> 0@}(?ak(:lu Gp聋&L"f Me>w1Ox;%x)t +Nqc~}zzO\~I0xe,(O8d6Ew0^)o0ן{&rJwYGޝLx^"8>=<@"<MxQ@=!G)S&CJWl&jS̵ ϭ{o :.q%F8?_G~ے- 8,E x8sGEA_>΂ '!{Iq9L>Cb#,F*`_k]<| VpA4Е;~V~b׶yX|zI6uc W3o<5߃yCnjjg s>_&UbnȣXR}Q~=ݦL ׊?gFB?;口Чp(:>ccgs~qur ߏ2xY{7%q*{H>H Ơm'jr[|j&'\{u?diszly!i0mR15gS}HxɣNj,M뿭ݺ T-Cl2t ]߃/V:A^NZpxr&뿩45)>T[zjW}KVP9ܺw/VsK%w6F^f0^-< Nu[K NCKejʌ˥5l{z|=Ҝ{w~Cy^">dҽvlE{Q7 j3̕p٤Z3t-?W-Utݙ L{qr?}Z>_`_2vR_oqDDʱ&YCO@go^>?V{qX;6.yώ|$Vh)*w`Ǟys5G1v.2_Wqs4811|_]?䀵yƞy'zה|Rv۱Q CCԵv'Sf)>%ݺ{5oѽfhwޚF^MPzq g#F.6䠁ckFxÎܰ>mSUziBD/E齲:tt4coD^ͮc>7cp_ [f3z; 'klϡ/wThZ/y0[oy=2 y%>lRw y_=߰ͯ́xY^>b%+8t w)~u *m.P: !W.?/q KĤ>mMqi; ݓ獽aI;v]"bޯc,8arǖߖyz5cMm_yMA9zcSWZރK NMR5c`b}i;8+Q|v>Svʎ/3Vڎ=7]/[[pG1̋rpMi{x87Jrq<&K!{ '6ǯ.8{>w׎3i㬅Vp@?;3%+q2SHw @J;zI~f8sg&싍1~Kz.s@]<\9juL-~S Ro3̔ h>S`g^U _Fs {f:G0V8kY,U 3A^k~fӒs6o:L x~j]qn1~[se%=|Ĉ͊'c?Oxߓb:-1i˕p'6 ͸-Tٯ-eы0W.ZiO,_;~ɾ^9oT3oKl5q./_DKdo]Hsd.M.xU/I{~0GG|3%B6 P:q l VЗL^X~)^^cQu.Q\nsϜCgaqE|p(>dxg VU|p=}|u@s^6=6=xTeϋ5^^WnyL0K"u39юo]#wY3pY 3JĂ\2=8N "p]XCr pvl8 vL vl8X v>Ύ-g_S{Oӯp&cNo.m7xg_2v;֭/y59L]Ǟ-aWVENDws/&rҷg\}>r' .6wc3O륷 JhB|'[{*?-ZU~™\D&Ox^w>-ʲf r5s%𭗟pq I0Aq#VJ0!LjojK=cZ0=ۤ/-o;轷K e+KتR~L ჿIjk,[Y+Jp#Y~sKX>M?׮t?8$Q@͸ܚ7/@boP38Nޗy أϥCSeǏ]2~eר% =u9i}xu̗ۯՅ9>ΰ^;V|>WW>Σ>r2'6+}] z{%n8'HT3q⟠}ljl^zGD,Rybz~Wf:Vqh%Vw]3#+qGo¾+S?(h(=a?c=D'~Ҁ{aKQ hgF= Wi0n(V'Ğ>gA셟jh'=D4zwlɜ( V[g`_8i8CObKr>o 1̊$e챫F]6]/G GS/}oN>J~}ޖns1cXa[2 Bto{\OXP#,c潦B's!LAlra͊6NT%CzOC6Kdvۉտ/C_}+ {y# %y[tDWolvܔ^A.^$͎QKM_e=Ԛ\c:^s"^7x#<ГX2$_:uO^8!g0` c 1}8-:g1rڜ&/k ^(*FC3|_8_?VG^*߷>Y8сc1yDZg܃ YN)>zB ã݇t%vX]DرQ:Ӱfk4>F-nzd8u_^*-'TlR%9EրYsr=vHqd_V;cBAS`w=3oy@&_(̛U+:~&U1G _w3ϼHo+_왷$u9=+zajּ)rH-wfCYO7֦z$ /">z8EU{I=LJ 2vg]c}E?_TIG.E:# w/b&T%~o_M_\CÀOF_2I$XPRf[O//i RAg>?I:W^^-=WQ[7yRbm{(1wvɬTUmoOe ߙO5ɲK{-Q+` |5>^ϳo_>~Ool+;X-MV?c0xnocMVygnܻy繯/[>bu\]#]svWMæc\)WY:~2AK19KߢUаڱΫ[3=xRI\=:1?\4=C72=]5_/X;tx6?{Y4>Z;k:Dq,*xã8o }qq~:g>x5` /:pgVr/ØLs>-|8@9O[ob.%b98NF5@|&9U8ٿ[1^Xʏ%\83o VyK;cϼkݞ/cb?A &^Y_D3p8:*zYu( o =K=y c҉m w(.|gBF %9dԺ3"[:<؂X*/ѿz ӉߺM-ND=k(b˯!y֦uT$bk3zI nt([,3xL={__R%&]W 3rR8;\+cr;y,VsfJǐ qȽWg?#0!)_+@[=1 WΛ=gG_Bb q ٠%I1#1T:Bj R|2l?rά0 0zq;_=wU8΢ghc-b q3o: ?o_ >ЙI.df1nِZ׼DJ 8={GXЙgwS}OSoJq̛ǚ^ftgsԌggֱw>~bkQϑK}Ǟyۗʜ akϾG}Fu#-Z+T9FG (»GQ&^Hy8}H'5'b_ͫJ [o%^*&3/s=,1'#ӸsKxjC*xV'۱o>< 3Q.D¼{X23h0@VtzHc[oq;r_?=]:X|v>g3ӻp7^7_0'(>'Alߤ=k1m;d hqH &b?--@'(Yu\}a97 ߎ_p.t[zIۜTV]{}9{BDZ;vyŒX]$HcϽcR1B<+Q>{ucɒGŪ&<|T}^^7!68WX>N;iO=z4?ښ JpN@Lԕ#MsX}8;_M78W]w=GQ< fAJ)c!SHXu<`ߜ>S{+܃ppc8;g+7vgLrpYp9+5N= r{>X1oE k&Ù7~5/Xؐr-)Jdߴ^׀:9*ݧ-= 9֘BcϼabAϩFiCO]wtz :jc^ӾĞyGr#] x.GgZoM\:}m!oY =Z޵ 8{ũ?j\s56:G4ʹK(JQ9wLq ZZC?+u)F{Քr|5cϼWQa_.F{лO>1`.O8dxuYq|8&ƜraU$M@vOۂ|m{̵R>ש:-NPz|zr& ~=GI1ܥUV/}b*8=i=7{3vn~XŸ3k(%%p; oߺx/37^|@fֽׅ{L7L|.yP-mR=ZZZs1mڬzI3~'ͮY^_Yo PK ~ 9ժd⛨Ǥz}V@_옏~LMhdަ|hP7;V~@]qz$~c_[q|`XO?NS|tYAJ?p v3G5'{Q z/*EI=\'o8#8Y#;\ٹd gG[p=->1&$-G<8|]-><> xTg"~g` 5μe`u5a9#jT^2owz.,ow/|0*yZexJ6v}05㵧$/9 Àyu:(=?3a0!H=Gwfs{ U_j7lϲQ6cfql}1 %+}Y` rD+׽06czxi-ϲ{%!)X).'x藵Óf4rF=% ڥC$R 0*箫mn_b89^NV2N[\ݯ|oь+?aF-[R%8|{q=` u{+?>;K~#๥?9.]4*m>"e>)p^-tKVhʎ^]ň;*&f\F^> .ܻ6u7W=RʒeϕgajaΦ,xw?m{pB^ N8wǯc&TvH9c8/Z07Ol`r Wc<.>Kq!?gI>NbIiT?L͕>&ESA npM8~!sNpeJ/3Bъ^ߊЃa8;W$\'amƀНsYw8~%G=% v5_K&h?RMhOI1}xrd_8mv`XAG-[%k).82V5 (@'LJ\]|N1^s+<Ǽ'V.Odʼ>> [1u#,ͺϱV}6>o^0`I|uXt.xaO8;i4|g_\37Vޙb,}>fw^ƧŽ'KuW:ߔ{3q2_[$7瞾C ]orz-?oU/QƠl~Y'|;U/X~Okc |;Y?qP %];ٯ1b?{0? ~ Ы8Kgw(!UۋQ''8$wS0Բ+zqD9)wܟ[|lRA\o8DZtЄηlp]W{*G[3p|L<7xgG/hf, :ʾ\}1H8ur)G_S u B xpw*t=8NA<39:ŇK;<]μ~Ar)'cN^R>+YɭyKT$ ;{}2eRGG|sϼe{O3oꀷw63=d xױy9!'} \ϼbf?.9vV Zkm  ^za{-^| c JUR=(׷\}DwJeZynpwej3՘|2tZ1\^nЬ8{gr_%_߾&_Ssz;s)@'~O/dkp0޽3W7 J/?aF=0MAϛA9b OkX7J^>^:;u*-a9Isa~ 8M_2A4\S/cwt1ljGocύbf"P,=Q[ϝ|^C9vY8=~zy"FU/1Х+'N8jBL7nIjUWž q>;+>]MW<a8; xQ|#b~/vV8Fi.up}2|t'Q1q2DL8^ItrTA/>n]+2؃ewNA1ʿ./et7YC 0(=@tM֘g;깟z>|,S }X\<'>ƮQ=3gr¾b X|-MPh:\Mv=Hpq\)in4z-3Juêg/G.sK@yI*hP)OF5zWcKkm>N2دL nԶSb$==%ee'xIHO{{=0*[ =y$W&K)߯}buF#z'c)t0@Q~T,b W3c԰9k.1z(4QƮ¨}m flq5niSPXThs(|4j;woc ybT} [b ;)Yf{FןL0.V8@ ~۱'/uܣg}8mΞK,_+w;OrR=<%y /nݱ>9t~|ςa3o{o=ܿu-e7_I~6me}]M˵3bX묷lpGR~lX?Wju^ǎ-<`:4O]}Oq߃s-+Ym؃_6wPy=}}mL ԩ{֛4x6v8y^,μE',Ҿ6[ot-ܝM]w}h Nug?3;k!%|gmkw޳B+Q0uVc0͟p'G1} >N<2pںfНq{5o qvo|,=0YoΠ%eibVx)=7$^2dYokE<8Ci37[u.gĥ3\=t !V=0^ag7 TVoQ;wrǞ /IbKW-G6^rًGy\=aQyOUs {f|G^>/^Z[qZ|BX|`ENLb:jUTggrڝǙ{zu;8N*Wng2p<һ;'~1Ebpy ү7O9WybDLOjr?QM܁c\oڙ/og gRla=7L-:-UXMt4 xƞys#?~͌QK1O[3o3$_/[` gD>ZK3oi kW? :'MUT?18j s,$yǗgn8w -A6!+oquݬ#36JWm_?uΞ9bXU<5co1x63Ƅ}Kt0N]KI;X}=zԀsK|Rw8/ 8xG*` 'TW|gPYWw7yt\$kW^w_B0\ѣrs<9nbua{νKSxM~{ A+8e!Vvxk%D C^ m/|b=wZ7R6kss說YUأJj:8<쓯_l@_W7\KYhO+_Sm`^^G׏ʵ=<b,|qtsҩs>w'[88O9K`/U]W-*~ǹng-CgVSˌ.-ܳd{0n莵{aN;u-[<pt!ۊ#:7S| or~V|}B}U|}WCS<-vq1G{gDϱ@YoOPY|p=tF}}~K>=zb&ǡWƳю=R(8eT{Nbϼo}@;Ğym p%O?x[b\Cm!5^ bmgd炃zlX_}'AB$XC{u?{MBN^gv}03oYls4XZ>>+)|cϼ%$P!]gdiᦾnKbj;x6܏WOmA*ם"D])cOA ?+lZC 6odvInUIi:[:{^${Y8cAl8o ڡ~y+txL鵶Uz J8ާĒ:Q 6Gx.?ً&_c=QʱoPjƞ>GJdOoWKJ$Z'N?DB +(muRJ̈́4%IFohPwhF\gl4x.Yڱ\ݛ&c_Q7X*QoFT|>w{X-1v-U7{?[} "룑K}_Yzxc-4`(nIzWsu0} Sq:ϖ="vl8k70h=VS r%6t|>`?t{=4uߧ9}Tיi@l8ҵoc Pq_ocϼM$ryסϥ{-K OVǛ%ZB-6]OAg#Hd;%=%R/L'xƞ8 ݷ͞_b_:-Wϕ~8wlS3}Ox_֧o(b/?ڏ 7]i]B2.fk12 czYo^Jg >gB&{\BoAi^5s)p|f-oNOVDNLԓ+bpj%b>kĖoߟgӋId3J-^~7{$X!yZYCzIqGyN>Lᷕy"0&Ԋ/߬- xuN|ƾMolo5yc <*c{_&YoefQ/ c?Îùܾ_9>ulQzM^נ"jgf ?ّ;og> :%ÃAOO$x{~|VO-ױ9qX ?ΔX /o+d\.=/'gzyIaž0U[ZrQdz(1q?)Gܼ@v=y3g`>zǨ:{}2 5@ԠX o;8rcחس-=6{-ԥ,xw΄:9c47?|,ch~;^sh5x⼮}ӎ}ɆnR+b{捽NY4?k Yoi1ok;ПlƞyK5cBg7Mƞy@;=6d%\%) w{ԊbLߌ QS'2pOtI0}2& t qjuB+o:y(Á/PLޫ f8c^-{'y4B`|~!T`)utx\5u92r̳wT;T IOt|fw_"ϷK:)a+)Wݖ_.pnX(('6\[L2w~%\K=!c_ߜ ꕱ?ً/cr/%elOcl+MPN7|:&r݃J&z)}6bg5hsﶀ~; 6;/cOdQl䪗H78mU/1 =<1A쾙2_/>` X-1rZ>:eϻ`B^fЇf~T|530ҀJo.E0JU}2 {0OxGe![zx ξ'O^=+ C+Px_>>-Ǻc~ѓ2ˆŽ=x@oA|;F~1;j/MԬg[K[Q8΄}[P7(gxql`8ǝ{w8󶷳^2iA;h fgř|Ϩ{}X# 8Au|bVxZ#R '/TlY^3$ҏuMA.aa=D7Oߝ|2yK"_LsSF>+=q>`D-xg9-AXt-*ܴO>{[Ч\Yi>g${MfݡG) Ѽg xgÛ/\` v?yg^Ň73z_TIDgZJ𷽽OdHbSۺ][( gt}Y~Ǚ=K5F-cXEݴ)3~o,V]K1@+BuHד{<7_׶1{?*cASGKdocXpgY䎡X;)[W> ˠݯ_r`w]fJ{ sQ%ЧЊ%WϱyùzX )b-M;!6!Kwp܂:OзU?ph9`Z8ٔ {J0^Éٰ{uEsZ|}@!o+v oON}kf$H{Tq^;֋Q 0TΊ2ގ:Їafa~gZ[8Λ%5 8a~&c p)<`o]^|Nc8x@}t8mBqS,?Z>>xG=z/IOJ_r7h>DZzw'3o{CP3]T9f{` Vznz;ߴqFP;vdZ8dQ^> ? Hթ}ss~ֿIoDܼys|=\DbO>r\s6J0ރ%c=v`Z~EnrX'Gxdj+&B`7EsEo<j.f$w3T%#`"sV=བ8sae c#<l Qe8b_r~bs{|Ԟ)S=y^bX987 _cS~~6uk$b9bP˴YDfag#pKz7SE{I2H;˚d؝j{Udgu=/i{6RȽZoЈKv~t\ʉ5?4;bϼ9by'PGLx1۾Д0 ;6La3o"97 yWoμ*z{Lszcϼ1،M(uI>N_^5.R4C˸,Y&P{5YC<&O!!y-s1ӧ=9Bse˄جo+WB;q/KغD֕a5Mզ巸xBpol+Wo7[j߳ )cjK;MZښ_{sZsC1vyhĒo='yu׳P؄nx^JĦK-l ޓYOxA=8Kd˿ؽ$>ހiS{}a{޻bpY;vއgN׿`5˿>zU$MQ[iݪ^0ּ%λW~tRTduQ%YQ:2Wghܥ(} #ãҘ>8ޫ'CBOg͹[ѱ|+>L{gȁw x8I F'&f/ȋ#٥|-^|}m}^|]~|w|~#![ p=ZXBo%mJcsp7BUR%g8;b6q|8#-g' L-6{?,mtͫd_qʁbTZ^%#n~mOObWr=5o!դ8>]$芕LG bb⋿C?NsuMg'qV1Էm]^(ӐxKRxnXYk+μBm0?CU掩}y__N;Oح3oi(հEN?3>[z\?޳4񷕟pa(h9iؼV~Tsy <}RK8?J4Bwg\Ͻ;gЩ(4;+*fz(;|_%`T{8Y~|CM$D;Lw2\9-lE9·_}"u{sbwsGn)ƞ|2 cs?1~.vOd16;֡!yem c/IkdI2iҟ[{I{>\oK;YZ7^gE^{NOI70v +v?wHWZ'S/I+UoK~yjKvVՙj4ta_t~坛sozw^j-j2`YcJН^j;[溈χ<''7;VIՉP8 xTlaA/>Ρz->Nz8j$}O->wck޶y0q%[ᷕ?ξ't̹t,I;ɦ4챇o%S䐎R{'Vt08uOqrc>{?ggph^}'XAs-.cK~ wI85@M^{{8;kEp ~b<8&|=8Cz;5LIԝ[ܾ0vc>i}SqUXQ[bzK-$\~Yo7kM_xYoKu C1!qpS*} vs<'j;N̳O.>0b$b2bVT0j?~,abjqt~o5ĝ=IƖNf.UnX_[\])ؓ,(j?ƺDȏ5;:|1v/?5qZu-wٻ=\Av翦9ƕRΫ4^jOW{4{%gvtpU"AcΝj==(~?W+2bһ)Kc([*ڼ2^c76JSz;2 ۹\[(c'{;%U޽gWc>^ݸvBkG/hͬb \ұzç^ {|V(lswԱVQ8s:iPz{ͣΔ{3gb2;U?B9" |ug}''p B~éOf=)^}xF-.4oP/Ihq8/>$[kq8b'l83Wb=(>N)/>:.gfIZ,/ys\|'F (z:Z8θFW/Y8y+ /aaM_{M \/o,Cg_Bq:Q%]7Ik?id~Q8COfܪO}8HȠ28NС)u7NkW+w ib-F緄yKȬd#cϼ%yevr޷.Sڼ=|2|ϼYbSO8uٹc_z 7k}?=:?y,.p"z!EXdG&D =ÿ8z<ŚJFn Co-^{JO'\$y.xu9MW[$Ē7Raˠ^=8v8Op[o;vɕ/.c|LTo-ݗ5c/=٩LOƞ|Ҙ7Ş|r'ٚ{@v9{`D7;=N_9s`Yǻ0 PobO,maN(Ylm_N?op>erZp: z;"?䌍ҫ{/O>d[K2X o쪚c{=fWKHv*8W}S7;zɔ㽀 uH~g{O-7tHSvb< Vqg'Z{,=ZR6cm#{xT5`oKh#)x0*>m h;;-'r$ٱ3b0yaÌ)sSVࣧ˂sGa>,/祿Sa3ܽp=8ξ'!o| gرI Ӱ28F۬3>8Nْtk>ɳw{Mh$}~[d }VSرĦ .luϼC9جٱgA{|k[MݱOavUja[}>R6X=ec왷=v왷0]j_μЁ60̛|voRϼLBmٵV|gKP3b[%|:DkjT%p Z'ؽ}tS|7^9:=iFᱭpI;;jfFؓho|8WqlIOO Wc} Rd^h)fƞzqN_)%Ǜ, x/Y}P(~:[O-髃lJ70^ ܢF^Aא{xMcVvw*?}*<{ɬ`o'c(M9xo܍NỎ}R.u~.Fk!Wܳʱʗ<"Sb2VbwV%HcvtĪ?P7o~~c8{7ܻ9oKzw'ŀ?Ez_ޒ< p:oƮۼc ո0O >䩳8):g wlys[xB<#?ޱo'yf \.gŃ,dH`88N+eX7\2[on\"mh{vaoƺr]zbboSJ*-g?鍍ѺfoKz?rte&Ƴb/٣[ [4sq&bQHSO=$f]5U{][3i,Cϼk`杌 ~[Օ^ 3oIJrnzl>oc_;w)~8I^o'Ldx'M7)wO#Fy-[XYP}#I-'(>Σy=V%ryۃ%nE-_,O/c_Q0ؓdb?É=yI }wX[P՟:≕!]a6"3=ޛr>Ժc| bi5kމr؃,<j,?;`T?@[,LYNM̒=Ɛp76B\s[nyg(qo߈4[JM=o_/=Xwݙ'v(M3ў[819Jf)1P9~~ӯL86>od|0oxYI b}^:O*kh\Ù7/{{cOyX_O۪^ZwǞy;?PF ƹZa80>&K=qycgezos\|l~PP? f1}z^ε \#ԥ|>K p {ckgYo#oFecֱ:ug׶j|mW{pr*_JG+ϵp;?y?9e-LFȆTGzCy kEG/SGsLĦh2`>Z?1Oxr#'晷E3}HS?ߝ,^"kl~o;nlXILxs'ޝd{mRffo_]ޯO3K g7oSXC:>5Qw왷^qcϼ휮*)=Ecϼe![:WCq/pb;}^>ΏR!?Kh=:3o{_M̹ln u Mybn= c=M^>N>bojY펳t ;i)-[1q+{cKugЈe{j[< /d}jwŧ/Ha}}/hrO_P%I,a^ƻwNN1Gի9`oCN-)^ڰť8wJ՟{֛}CzmNm#h1,k [Ox(clKxc[o>a[7'}bI[ҟ!;` WfpޥRc=9wp%;C<6J} Gpwl|N_RƖw2Qg_Rae:8cD@nh^}._-N8)LVk ]vuBH?^>^/0A?& ۪z~z+) C,a{%jvPo7_qV4}ħV 9mq\~8Yj|2{sGO^R=pɽ책 heLm c cwݱU|nmw\o'yߔ->ΞzÉ;puL,;pE3z{lqҜ^Cyե]_ Cjt0Xݐrk7{e{-Kfiӎɺh4C- Ͳt-{-عgo'_왷9oZv왷!KuԎ=z qj@[}Ao1{:Jij u2MigT|gg,;+kWޫxhZoY~{ {7ޫӌh}\JUR@ҟl'iߞzK8Kg폲/h^4QjS;PG:{g-WU$dz;ohrK-o?AƦSo} ڶI-VJ; h1&77s\8yԾI6:zAeG?x+wրϡ>w' $)hܥmgrxT x7iiK={{틁s88fp~jWyq7p$>=#M/hryJ3b3&&YX=Z-6{!pڥ]gd<`g K]wfOpJ'Jv-q2NS[S>/g8GG,ICg\%y@l7̇O~pl2kj\%o+O,7ܻ*>iYXI ޯ%9?jeYy7Fp|ד XRܞL c{ݶ,>7[Ko{%o:ǯ# ~' .,_b?)ݾut ǘ ރ}/Yc>a4y0k֋4x?Nvy٢[u)RԾ3<˱dnF3k_iV_otuզPg=V.yIOqrdr;KQU/Z"G1${lgEr{8'6Hq) Ё{o!:s~D.>rv\/ͼǞyy|zGl"ZO@].KT>;_kkۂv-)kv N 6 qz$g2Y=J8NH C8U~uϥ u\9.>^_q o&g{'SGĞ7wWm^p7+sxĦF9e?K]o߬{㏓hn&/|Y]a tbudC|bӅU]ԕ'[lX<% ԱfC-Hfk3osy8Rpmd#}e$ Kw`_q~8W3Z]ov'bb/n\oWg@nZ}|K/R5ShYoF~vWnyoSڣc|SSzz>54Vl zكYR 3\.~Ѣmd,|3oM#d[ߣvFǫOȻ9x'Lpso_D7͜^GO!}he'l8z{c>=%Ċz*^8::ҡoO_E+Z,Vz+5( G;ƣ/ƐjCqV Bn:sr &{% yNqL]k5d}ŏ.KQ&ETZ1ص7Yk_ysSWz=y%QZ-q = 2ph<-Kg*7 Pqt P_v/ylojd1ďŽ[d^0cz@ʬdciJqbij$x->N;X] 82 s㭺K0R|Ӌ2g[q=0[GvgwyXi^7k:4!cϼeqOkHq4a6@0h$Hq,o4#!ROlumA7EsڬBl1Y3gToq)ڿG_ZMLa?7-_)t?sA1BZH0^Vz;Wu|KV&4n\NԊmP% uџ[%*&/Y5])WU_3 ^ǃ4boMO_ gӰZ~K&pcC{jG7tZt) |iƐZ}*-OR/Q9Օ/ɦf\]OIwiG? xn@sk@?̨k`>!Y闌:;Gן!SYOݩUԹbKyX|ҢCiKk~ҮGE|V,"\(~L Ia.]LMɤ6?zA]/^#w_V3J,>ξQMޏ{y{u:jvVlMgjL^X|bψ%~[\ЂBpX,[,_.ANn=vSqgw8x@*itn07YAui"X*,}HנɅQ XZ+Ws+4X]DU,`3H@lT~tyiTf 5J㙚lu.)>h&י7 dμٔ΍W3]g{f:22|aty[,zZ-μ%zI'HיC/U[Vי7N 3:Sr=- iy) 8YxQj P7GxYSIa {zGV>/T\ĈaoɗjC5 ){jd+LH_D({lb_VɾԮRKRպ~RZ%dJ6_ғb4MRV{@r¼Ғ^'r\qϛTm*G|_}wJvާ&\˫UV*/=߯1>8Y S=i>f_oRj)0V;'{>|b&!7ҷ^BdSNܻ7]_Ch ߙTLMC6{w/0>ߙo=>+y@\$ÝgSn}yWiG, Qm>{7M|''Y!t->̴Q3fT<*_K%z%iߑ%'Gw\%Z|䖀n6joq9m>c㭺i;#noq$ 0c/Pqb!x>o:.>NApj}7M x?S>7MIēEύ7ט;k5]뷨דۏJ{RZ~VbuuU:~dv=\9X8ps)&']Wb_cNƩOԫއ'<-8BڴiP+6^;V'fZ'(_#ijP]p' ص4TD^5-^2.4~cmԼq0Ԯ_l ᮓC-d6μ#Y瓑k[Z $,ly[0 {l.'^'myۇCl֠9d|bϼ=jxl'[喝;gg\K'{K|^fmKD^3}v[Vϼvӝߚ.`TV%&>u飏Yz -ڻ^ ͔j{ Grz ~[ ynZ4%(Kx/?MK=9cn({3={=)y )+ E&͗[;:^G\yMm{=%āX'a/}2/ }2F]t:[J _l}q FdzI R#5:lU=$0T>w=-`Ge<#>sh| `O$Mb;:.ǯ;aU/٭oPn=}/IMI_C?@{lά ߑ/ ϝW捭>aqIŰGFcتs9 fn_ɞ5}fc(~@T69NoF_XKRQ1ˮjWXgo^gdӁ}Yi"-f}c{/3qH 7bpvYXqb!x+G:G6iЛ]ي7Oa e9Aq`vV|ki]dV|K7{h,c BUi'Ҋp}ӬpK;uuqbNQX**- q3o{YQTu^qV8>(/Cl0_][>WNQ}KRzu\$-F$5f׵~ZubU:'(%.^~P?h~a/μxxȢpӔ)I(4vKB.*wZb ])HYo@RGVǙuB8m~cKznbf=6[_Ws+/I^^z։Knb/h%^p^Q|n:m>ޓO7B?{ۧJ(בEgN[7ɟlCutooOlb鹋uoDcTV]'^ػ޸i<,Ku_1}^Ku<8&)wuom/ǹGH|{آs]9 vh{ӯ%;Ы^PR_aK*"x?YвaI!{[~C]le#tZmЋ#dzIx3@"=Թ}kۄ۫u:{bSeVMw ^"N|]RbK[*(x-^86g0m!_w9S!K;f¥A =VY~-f_d/b;\AgY$t)]MciC L:(⿙>XE¹FkNw>|=xnɝܳ]K3oA~v3o_-lzKP%kBkMbg'=Mm]ϼiҠΕpV[J*]ۋʀg.U$2o6+sfm7 d[ol)di{N#m8[oۊoCa sA{dm{}EzK_Ǜ!]m.Jumi9^Gz<{_ !]2E9lc}:}OԜk}K8ƛ+8Jށ{(HvF8}x^؝ Rk<8{uՔ?Yt:>O~=oݟtߔM>wo1{+wik>Ƽz6 mZd:ܳP߶3~lj$ĀclYTdO[y͚hS%g3=[lK]3.YCPT=X=[rg3iӻ'7.OxtG:ugpp:xđ3BHc:x2w=-4[׳AkpJ[-Ǽ!ӊg`q8mu8-5bImcb9&zvxKtRr=J,Pǥ{Z~J5"d7]cN2ޟ|M+@Sg>F='Su-_/ ,ᅞXi3o{{C >mtb5[Z{;r.[M9M!g{YYo {l7mW (?a ϕzl᦯r_3KX{ٰА3oQ%G 5L^%mo]W"$-MC{l1e_y֟KJ.;W\K~b"0__0i%Z{2V^нt+5U>cڇzۡ`c,X+=yź>oo2.ɥ|c}cOP<+,Ncז\W_.Λz<%Ex;os*YWcy;:x7,vԎI{kzbͽ-9}̱|zv0߱Nn-Վ}Խ|hW{b{fZ! }@1߱ShW|\_"j@L}Ns=g7]u\v;w3# 6xU;ג󹱿V'uAUxBS u3{[_pbbfw>oh^~﵎1P } pd|}]{Sox/y5;go;[_̝8uR|ho3c5^O>d;Sg?|} 0XONI X}޸~c50u"u?/џ/{vs|^-^pSKӰcמkvbGZץvA֯!;=_K>{suqмT%2kYݩx,z;uź>O>LS~i3֒㴽"vjx,^s.z屴cs}yžl4쾿z=W[a8^N&үwqVokb3im~so׳8o;RǻFpS2z=ιѨ޹ȥݱΕ~c?x᜷O>x=trKF9z;sZM9 -6?8 ]iXġc{M} 3<v~v=933" {oz>ٱ~Zr2[f^^;=y;}O]bg*&;󍝷O䣗r煏Ċ 3ˆĪǶc?ʣS۱s'u휚R_Ruwg\ze~toy4bv4bگ?h2;R֘_o֍GXmVnn;[j_+bm]qj32?viEoe 5ρV?7mM6q~:k[>ľ齞w _c9kFxc}4x~yx3?˷1M}ÜOw;yk#b}ʘJ?cmY >ki}[W#g חz{z cur =G\_ zxOO%ȼu<3ח#q@>/Q+wBbuR{S:Cƾh(\K\_"߷6b~x0]<'W\wS9>mb QդcMk[6u VٟpVWV:9B&M᝷koi y숮^^?'cOۉySX~igr~t -}cgA(V(ߖ~s ;SNOq GXWVL^Wacח<4[Ik{^L_93m sDd];/6\W:/9V8C{0Oƺ^ygg~Ab9/:60o/9x/>BG ;4}x:y }p}Ic Kos}IQoYZ[V}x)kV</9yzbM<q/ع*K͔{5U'Wb]û|Vj<@}%KE8ptݱ]7<;>j|[u2ٻlN6SyN [+B0ָǙķu_5Yiz8={{N * -6~ycX6}  ݫ&Di3^f{ߦaVA}V]u~7dNvCDU[>b}cWYKy;zXط@C[u_:3~Fog|/Ka󺋼=vcj[t7֞X:Tߗl%IrKZwNcgZx=qx]?k4:n3GQãʇ~cpAϯjbZ禣5xzk;ǾKta5 ȥ?xgS˹+zz߼EVyjCL1\}IY%}iU:/9%2yam5y@/R曮/)Ҭl9K]5 jKV[9Ϛy@aO,P3?bW~/:y>Kc]w#8oɱ~椏!Yfsg3-E؞'.\w|˔l8=wFygm'/s6"/z:r^<Ӟ؁o/q` %XKUo}pR8oj`; yؚd2j!vy>؂\??{ 󒮋lL<`?(dmXy=gKmuN=Pg:;4ӏ!3%,j#c/]`]_RKn'+{4y 0%':(]z?akq . >vlG)Dsbo[=Ƃ<球o?eJcUOqvy} mZuǾ:\ZǺA+K޳㷝3~Ǿ֦N[ZR{ǫU}+r}vL+=V:urwvbw;Ay;{s홸͎\_b!7חDrxb}Wǿzއw zZm{u=|믽e)j'!#4Z~|rzޖ1Lc6N??VQylf(^Y9E>^c[FKthgq4cgY}`\O^7>œq@+|p,sǑu><x=-Sq^#"c79I߱pWE y{O`.F)[ևQyAmeM~gyK N6ۺ^d8boXKFy7j1o&T__Vu}l53ozd6蠇ht}^=qڑQAIO㨮gU 9 ~gx=5Qv1*gd>{)73K^ %g@ z}=& Y7;?g麽1NvӞGGOە}ɀن Dz}P3K?z8Zj5gjɽQ~}tp}?y70':sy,IZx {P Js>?|{=GOX&jV,כy3b;<Rq]lP:#89]x5<ks1Cp]o ܴ dg'&vV'9 ۗj8/9Rz1=ɼ+ol N9U>wb}kS1^7mJP.̉yNÿ]) o`jXv#/W_=49d:%}1o{5=/eq.zoί.vsZf uRUQ1\a?cKJI[u2G~߷eC/5i/.cy/iN-rKN5pR_/1X^2͍[%{[{| ķۂ^Lb;ц7W#xI{ֳe}^R[^Cb컟_ߑt]%2:Mς엟u؍{%{ygSD+g#x>`L#xI3퓟^R'9L7hdK=>t #x\y&K欬? tjG#[Kس`8 m%*sޅ\d/ra ^R:^%tQw *Xތ l/n&ܚ#mKYq trVF69߆ E;?^W|K:}0ϏT^W;%'}3xɴ$p9?^2+9}K׏Z\ t3x2Ucp^z?AQo3x^VSh}I|}a]K&T c}_Q_d෰ ^R{CKGc<h۟Rzp;߿sӂ.b=vzp/1g ^r7y yIഇ%m4Į5lKF_8N+;D yM :ɝD/N0(|;NN& ^x7O7sD2דYMgjϛZKZwb\Z|>oVj;6x֭/I DKى%%1цܱc \%OlwS%q=:+irTzBR+bcl_NZ0KJM d#N%<VۂT67xI{jdA:vg㼤-r%qqJ ^d8 ߋ%Uon_ôzek'nT/и3 %u_Klag_|O'%3GxD+?{5y@aK xIgt^"jZ}U[\PמbPtJu*MfObΰnQLNF?lw6%r~jKtUzR._=N_d'B݊/c [(K쳗IeN&m}\dh%>Gc}~s<>5s@\巰J=6xɬ XX%xB8!bCR\ZNq^Қ6L/i_=W/QS#KV@rׂ^R9^%S@%/Z;Iu2xɜ /<~/ƧSv/ЃJ*W3ϻWaiwddd)H%}7/Yt+&b%defm͉ _Ƽ!|KHkkub- Epq^_} S~dRp۾jQl ^2y1;c?^ ^b9{#Dk=urOR523_' 9/9z~h^53Go ^2')W?߷ /#oRV$xNQ%V0 '6t2qi9N򨽮[76xJ{/ЉPA=/i/so@aiEX% %QU ,xI;: ^2bvo/)gy~3'o ^"؃m~[WWt F5[ڭ\YБ NKvIJKE4xK%9쟳|xhjl%S;u(i C1W%'SXhV/)^doLXCxLǞy1y~p]cM~9Mo=nsm\Z|^y>^BmRdjOuTu^!>g=xISK ^oou;Xp?^WSřtW ^9da+|߂LIMgj ^W9,cA"F A3è󒣩AΠϤQbI*ܩ}yɨ485bGrK;` CKζߖVr^b2@~L u|&w<PZfh;nN+ǣsLX%uN^25%^t},xָ%b "?XC %[@9/Ewp?iKv~ U%A=zO߬%y:X'tpuRxtKbwgK~KZho-[c%?ł5Wsi ^4*e]vbcޒΦ~Xv%6sXՓNa'%k&-NVhQߊ],sv'nY%? q$irewb/h&^jb̺ J'6rI~+{ wl𒑼Nt5A%#ebK%}X "xIϚ_ ^u[k4^TkTo/mr-v> ^-\wz-LzK:/aE1 ^2zҭL5)F_}By zbHI[ z\K[ T/Мc%R݃zp ^ғ7KcoѤ6Ub#ÞV9/ՠ1%]KKP*%v(s[QQng䰊3Kς(jǣC0/ %F%cVPcK4g;ga +xIWրHG.m/FRu0Mҙ2| b%YPKuuǂ ^Je,lW:8~+xɨv*KmN $Nmb3C+xujYx`3y//djcl'k ^bF֨XKV@5.z𒡌ݏ%{~=ڃ弤6!#{ndQMWW۸0V&bur1\@'y7[K\,cF弤Ǧ`~ [Kk oRkyp^R}wr^RFK8{SJpWWP0қ]-u_lqV/IK󒝛 tK{nqXSبZ[K*rGwyɾ -% kS{cCgR=hc<鏎}EKOv:kw-u(u\z/gIMcd26|0jzAVu^GZSh V^4Ti9%-xIXϻ{ψ ^rpKdo34%Ur[Yg1brg?53ގXnfvTIq.~nxbio'b}ˬ դu߱o <5;F~ u \رNM6%n{b]7FŎu^"8X;"xB/rzIԷ l$7Q\2~(K&8x;=-·7^}xvpNJC%wFtz&8 -n6y^|X V%S0%{oOVQTpN*}Y=vݖtЫs= ^)Z~;ׇ%{k"xJgԆ^\wkuKUMkec}җCmyue?Ǿm2Ϫݱ>oo۫bǶxY^)Rc}I0,%b ;筦o_䒑%3]_LjTcG/) %|\uQ(K'/W}@/94=s^c%>ѿ[~9/)|SaK {}P~T0oKz=esj+.;їv% \kxUV/QرgeuR7>+࿧vb]w^P֙J!x BO?K|j9/^N~oht~=b^>&n/8>{8i39/9B^"8/9q/"%%,%JY]T̝^]oݬ!'MxyK3(ox,jSzXXĚǎ}s^2ğ ׭K{&?E[m\ g§ V PٱKZO-%߷;6o|Q7/T9n_k[}8] {7ImOln{pKdi#ͪԆ;6xpc^;>/52&h/Kz:xIFK;Z.XwjY+T߱K ߈sד5 $`-Ak/1U2:%by(%"xtr%\TzΒuRu\xLz6&}SK)D}N*K8oK,0dm.B%{AmWmlj}s^56ޱcA94ƾ7gԗXwu2d6x=ggqؚz9fWwTgK.9- ns_nwlpk:JnfSwOTMaY9nXxwźo%1^!xQ7%7}}ﻬ9OlЯgsi0{1Or08Y2/i)=s^rZ %1y7tbUYG ^/ gK*j^u^?^š"sç̎ޒW;ԃB;C+AgKH=')hvk/a/NPЯ)ļ9/9:kw Ju^tyκwކ,Q<8/Ǘ/Pcw%ҴZW#VRSw`rJ^doKD>Ԝԟ69/9^vt-xIU;`K:xjqryԩwF] ^|~c?oX7sQ/uR%1<=8_^#5/SBЗc*dzp.j'Ku|+&r:/Y#ḟ%?73D'[a38"zޥ/ZK[0%+]l?a'6𔱋ߖVIdFJPzW3\f~>Ө[:d,δڨ%ªI7xD>?|J}Is^2+swc L9/A̹{XJ}^2Eኾr;y =Ix|O -x,r {DK]ԗ/5wۿԫ%y+{k%3Z>ؘߴ0xa)/ryɤ ۃ$u{t d#W;drrX!"/1h_"r3*=Hof~q ƻ3VcdždҋWyI%~؟fq1zZӓ#SEO2}:/i+ź'%W[mZ;e tbԤ7wߝD`MDݼ/ƞ{K䷱_ϗ ^`zoJ֧/):ҺsdX%/wӣ~&TBϐ*tT#͒X:%}Lhʾrȏ{)o c%jϬQKeu^&{}c? ~76^|z%#6xި;٬B7s#K5ufkxUߏFΙb[_4^ߗTo ^YuxbFmG^5d^UݱS1|~cq?fExA֝{{>%qóFS&dž OԎ ?ZX k_$%˨軾cGhR硇NA2u%Ѳ6^W#З6ϻd*y™oS:ٝ0}MڱQ݁~;/9B X#ԗ,wtJ.ם-H8wDw^"E*yޱ>oko*=>okҌ\Wl;7)w;ysԁ}Swl .8:ڹZb oKRr:DS/DwNq/jdx_W=\ ^RY?o(r0bkx00dk ^Pu+z0뎝fםz*;q]ߗsĶ%5i;z-wM[Uw ~&tKlE+eYzu%&a}^f5F\'еu%u#cwĆoh]ߨE.qb-<Y]o7KjҤFgyVw^2PdZ&u+Ƽ0xIQr.#Xy }Kv MЇz;*N5+=xI/{9ϻkM#z]u=T^ g_y"YcV&ܱu{UKs+%җSߝt]ϻK\'?~np.bj+%u[8cx-KsEN0&1436i jUƆ:)Jsr4/x/; c7󎵖b[=s^rzN2dG4Ws.Kj`7^7%d|e_i =ܜ7%d'[Og(Kǃg#xɪ UM1o\wl{Ո>Fߋ\aXmadVWJdw^Sh/)߷4Nd K@m=nZTw:am8/9Yw;o2ϸŹXK5L#xUYc=^"𯶧<-5ӼgKN(fҳd»^كOdI"^k'(W:ub}jwEt:n^bRtTeζ=T1Ì%%IvN'6xIjo !c~zȳF|ro ^q!KRmByKk}8ȽF/љ+X^~'VJN7K҃T^,xIzEi|~OKrzkѿEZ7sKziYvyi"g/C-8K5AMh %*ʺ632^[iwp^"ֳg67| 3{mw(xIz0%KN#N"r>= ^R'k2?{aSr"~[KFJ%|q w/З Q6 N0/1w8/ڦ1xwmy-%A;GzX% 0-b@>#x 5zK~, x]ξF1 b9 ^2&{OatKkӟ/4:E`Ć~[3wsx~^yu*֯76xͣnn7}Zel~;V`l<ة%>bvզc?UxqQZc赗fu^N#aaW%رa/?g^29$%'fօz#ߙK~/xl󒽦jwyI_xlo(s2yl!*<˟MXk5f/X#6: H;ϻ':Da5~>{O`;y4ẫ"Kt[ =gKü9/OdE}Myz&ccEwyvc B=LM%{ޕ>{MK-U9` Fd'i{d~{}/?m=^H K%ߎ։ 5aFqr{N%XLo{0X:n*w9̕˅OlKzLx:/{5!%ɳs|}S[oo%f۷Ӟ[1s!WYȉ]˚|T)GLX>-xIM}1MzT7߷[+1ԑ[28=lYô?y!J%}N۠tԱgy#'eIcxv4B-~zD[b6oKdM%g#=}9/9_=ryf)ToV<#hW ?C77:Ǟ= + >yIWv<-t^v¼ z|׍uVԛN%m T|7 ˠ 0KЃUk44f ༤M~x18/i:sol1 pJalfnKŸso伤z}5B ^R/c޳%+ ,4>gM%xW%kȧ/םzelK^[c~7vD&J+_?o#bh@ߨ%Ž[;yڵ:/Y+tmݗ cp^]ϻAכV}i]kgRWw(赵cx؊__`F>)>c7tp92&g>, "-|CjXヘ:/ٟy rOic8n@Z|s' 3 Iz:H:/@'-ZUz΂S2 7%By?Qyõ|/yɟyw[T%:;c=2#*ΛDX ^BM18/wQ{ dq^b~ -x*% }#K ް믌/b}t񬹴~{)JIr*XSmw]8/.̇· ו`6ɣqHΰh"7< %xhEGӋ;דm!Wu^2&ϰqdžL'5cç& Ղ/I[ycUXtq,̉˴0^׽jc>+|N%xIKvmї9H%xI ;󮱑%Ieݹ8/mY2nN+KZM=d~Tn2q^2[/l*M9ѯ#qVQdZ}wy`YKv.vmoX^v;/ٗH8ʡ4:}yecGTc1 {г>R;oraއwn@+,KaHNu^^^y1Fi z# ^Ro[Uo~7Wre-|&,wwKv=NK֯TQ#zv4 %_l#S~wO| 1'Qȥ.8Εۭ3ϩY!/Q%hIk_]K]oyw%Q% vlKN+z64xɺssKk~9^#]>d1uWkT-kĺo(>'gV%;!h 4D1:=N)yպOF:K87EJ쭤-:๥KN‹ow׬m~Vf(ǠqOKƺNa0DS3ub@u^b3 |yMb=s^bCٛ7=y{zy!=*9Ws2W=v7ͤFV(y/mq^b=:g3mKv.ĆT>I쿎9+VS*d՚z@PS?0 =L#]>W%{K4K˜o:R =C4xIvfE?^9ٯ0'2^٩Qӓ_VD\CT&T>bΩ=z/:/9Z˙p;?W3)}Yw^rn/S%Ү]{cTuWM'4y] Ir!R͆,+ kѷ%]8DJ3UL H5uZwjO읭KNCM>H/79̾ݷ?jĕݾ(Src:ޗb,h0yMĹ:/9KJ5+/KlQZ`dwb%Uh%ols㧐r*ѵݳ m$̢pϻw(` ^w_}W`C^2dc0 s^1|b-|+{>vdC5%cyPXuq^b5ܾWSK=s^rB漤SoBs^r !?_:s^2QpG}2k֜lFv^uAdU'@ 9/9Gmo7d}s=0x:w=u>X,wөwx`wB;=55l)c%[V9^`,e|s^NC;֛]9/Yq>%;A9dC ^T ^ҒnW-޷mKN3_ր@o:8z܇s-{X)m{ٕ}d>/atͷ'يغ_Xv1p]ieݢ~X}c ܇.4%Һgfb漤z~ǜvz&_T7=\3%/kaIbK161xxүXw=6TKN[wh%'N c{x1/Un ONK*ߎ#si%'J 9/)csyS{|y@odOs~g5epV\$ȿK}xpO \CX9/䛕HK=ߨǹ?"]/Նb/9'hw(麮/ѻwQd͍F$QXK&ƻjezk88Oܼ?Kf0 Vv%u>^RbcfJ>^iެ3ylŶVI?ڱ.%Z;Ћz/[{nMs{m/Ѷ!Z5M6z/_㟧ؽ,%g/GTRCjvy>x-YKylGKc=VׅگdgsR{M~}:^"4~X/9;9-i@ߎyQ%j=§AOލ{9M֢F3B" ^^";O?Ҧ`W%#W}ysu&/5מv/r^r<R߇!uuw~@[N0ԯ[5;䔿,x|%폸B_2kMgSq\UOs>/{GxueD5cdžJ+xI[-9nsd$M=ԗi ^Rsas \W-PVYK.Ӟ~v L:FTsdYϰΥ&u^R;yggeϙ܌i9/:aN,D=zҸ~vQ٣xE]M.h9/9^=K(ԡYKZ-3yg`+Zdc]JWkk2vEY*KSW{ZKJ\u^2o־5eì%vsA>Uz)V ,wp,0v޹Pu VX%%wDTo;y=dܽ{?b-^{{}iݯ8뼤vM㵎11\W,x޵o)#C л~A_7ܱWnVmFbVuwnc_,Ёu;M}~tWMcc&Ț`.Z)Nׅ9nQA\ָX?溎^E;()0b}XGu=];n-3la.ڛwE\Ys7>MG4<K(Zu^r>` C %u P~> >r"ƾ)8`;Vi$۱jkއwގ.d\S@jKݱ>o}0еW>nsJV1 \1ιFM6/?뜫$mX1cp>{p Ắ粤ɑvXseϢGw7 ֫4F[O>bh7I}g-NoTi!xJޥ_m`^zmiB_"xv$[Y O_/W9or jrb,j U/ʜwx"'&zb\x ;W.|~kI S:Ęz^ϳm3z.>;dZ@Oꤗps켤j:gK)d|Q%{դ=#uL}\` n3Pp]ϻwCJwy~Z>o޽5zJhq^w(KkJ{p%&ktVim\ %fN3{27"K쪧݃+ع0ޱ5P[;ov&ܱι뛱Y]cXIgMモq^re#VJpρs19/9z>0oKN38QgY7XfmKK"K;Zc w N`yr꼤>Jpw:޳7{Io[xvt ?E0꼤ei|Μᩝm[+}YKZQo&K}=>-wNz;ocWɭy[¼V'vו<>>GDƎ`ykڃ{K&0N;;KgLu>i}f̊ӡv빬jPu^_3mzfjx}˂/)fsϤ#6$K 뎍ݕ~x56;ֿo{FgK ǁ_.zܛ` /tl,NK; u^bc&MXﳲ.[n뼤gjכ%}c :ɘ:/9VMfy]$oo=QG ;5̱jz`r^i8O쵃Tuhɯ_mNu}ϜIbMys^|dO[{-q^ru1lwOS^;Y_%{ gyi6 etNÙĩadއl2's^2W00K ް^p^2xk g/q^2y|NSl'KxcJI_H:Y*#TE}X\S{%O|MoX=jgzK \~{4 yɼ6yɼgЗkѭB>^21kV+k k *:Ξ76tد޴]go䅨۱qsHK+& C%}}Aس!yɾѬc]Z[tǺ^*8nKNkF?n9.Xs)NۡXK6%Vκ8🴻6ak>ޱ3پM[s>m;yw{:qkus^2#17;u7_%sx\:/kTg_no,zɘt^7,s?GPxk|A8w$Z|ãf}us^r~FN?ԁ,5%gC%bs|<>cp^kKut"y_?c}k7t1z+x*}0N/Q:s>/-NDNz:/[vv|Հ3og%A{(>[W~7^I&ӼKzؗ<$J+Q~^Róuz,V^=l ZWW_!VAXsȽ|HUo{獺^;oLs,MVۢt2Y=KٟY,=<%'?^ d%;V~(m8mqOv Zp%-}{xI;Pvx\%(Y{Qp^Ҏ;ߋΛN[ۚgOYZk/}(#Fw ^yI_lTƾyw5FKz}dKF>Kv^#yUr//Ssd,DjĪX/b-x҉Э>8/ѯ~[ž!}9xIco0X%¼;xI{\5'$AkiJ{\8/90yߜ Mk|g5yww^r t9% zb[vؕ^Gs֑p[/QGukzwl+Qg)0W};~<;w<.29py@/:%zVkH 9t>㝷AW~@OxWEY<6ao7cg>Uu';YvhC}ۢAg C=9',=>+>K{>7t0<\_2үXtx%Sr_Nd[x]?羿urS$%5φyz[jʸD=IcpӤld f×jdžk7+xIw}r~kp*kVbz>[pI(ѿv9֚bw5gWiooVή+lzWMִ %pt4wq3]itԡ[ڙ_m@w|~=h'TT:^a'6|n6 )6?̼>Kz9ǭFO --w>i ޷o"П|7v^^7؎ukiLÃ/ۼ@|r4N!6y@Sh跸&3[F<$]7Gz-< 6>"a]Gc3r'Iu(؟}w\<ӑr8:mUzLr1';cxݳg ywᔊ1<9?N ɽc瓾Ks.(whruκ6kZMKM'}%KZ7óvQU/쇢}ct݊;6xIm|փh q%]KDKz1oKr_# ^cd%I/7u>/MF?KSM}qMjKo}wKr_I;>^Dsµ%K-#xIoc@Ol!ݏ^jQ??>^Z/I^~:>^2[wF`/?j%ҳ]xIZ[bC2>^zMKrOn~yIO~b-xIM\ 0%߀oG/w /}$q돳(ޥ{n) ^W9d^S35Kl4kF𒡽'!5x 3xD籤쌭V6x菭5?Yk8y '{*of&hi{"o/I5%y^ /a[q K*jO//wްG K&G!xIK>{'S/<g%ٗur.>^|F&=K$ ^O %g穥FlH|Ǯ;uy |g"=_e/i{@0%I=%ʼ8̥ER ^b #A32?}I%/}l/Ix",k}VW6~Fȥ/Ig ^c&=}MuN%O_R'Qy]+ȣ(ǻB+4Z?k%=1jC4{{%}$b͏ýK=u4׃tY{0gx rSԎϏyx[]hN%u?^rtݏ(5ޥ06޷*D>^yk?xgn5Sxm/Jcurғ}I[֞%9C_)6xRO+ ӗ-K$4ЗT2~9>|zf|vx/5ȣyMXKn>.'8_}*h%6_K3ug z㦺/q^ gVCM7/isq8K_},)%=G"Kg丈;>^ʅudT3߬o^b%׍ykr+݇HϽSۂ@ȧ/i麳1ӗp_>|S8?z԰?jI>}Iɖq}%3"zP%I&X|%J8ǿmQ#|7s9xlE>}IO~WKz}KzU/ѤUy%S՟DK$݇%'wZNS!/ĨO_Yx"$/qUއO_R?%3:t ;[2%ӿD>^(*~ Mۖ;|S9*%=zw%A n/KވF%MH !%x ԕ,%xyҙ/iUp2Lz8KQٳ)}Z>]Ф!s= ^2';8OϛtրL>hmRyZoy[Cb+1sF7zdHA ^2WK h\X_'&$)ӗ㴖b?}l|RlKFG-K sKƆdX#/53ņdd6K4rdK]/I ~d,/E͈~$yE8sAS[/YVXw%%si㏗`/l[yɽOdK ^,xRm_^58/ ^2{> ^2S_Oa%:EDɘ$_WT/0%?3B?^yi_^R[K2'PL)Ĥ/Y%e{A3%SpPc9g+~4=W_$6ClKt^WTeʾK]lu&nFK?} ދKN+3 ]'IFD&=lӗt֓}ʦ/6xI>/iLL7dl)ԳZ@ ^be$fKa4x$7%Cfz烗B=XcX5]^#x^S=l/I [TIKb?9/} |ς(KO_g%vsy^Qw4 ^2ZY?Tjӗa)d.WO_cPg~;y4Z0[Ƶ$xɯǕɣ,xOcW7\/1ϴt]<;R'fK/:͂Ƴ2PcKzlo >}I!/ic/Y^b`=xIq}ծKo"װ?Ƹ'xIG5>/hz?^uH|փdm,N}I%5u'xI|dQkdKjO^hKvƋz%{αoKXO~X5JSO6_'aB>>}`$KzmbC_ 9/irKnio } xI^/Am }}>O!/sA~^ 8LgOy^YxyO/)< ]96xt_K/7}^2StzeIM ^]imõ%6XĵzZ/i0:뗗Xe ߡG@~5%8 ՟RlywOOKRQ>^/u|}VNa~r}XS}Wx}${|~/{{>^3@xUL%oD u3TuUfV-ctKNHM2y\&V=%kc;yM^%aY;ߡO_^`lKZix`㻈9%ІUq֧/L/eO_2o[Kdu!=/rCᅴ>}Lf뼤*18/{Z7(]x~Vf_lf/oJm3M^t2G}%2Sl~)tܾZSVp%R]]Kw:`۱>oGqC/$0[}w Q?{lOjϛ T|>o6R ?jw[KaKTYK/MR}ּcsy^2CU F4pI̽>4FwlԿsD j[ٱ/1ú>{p:In$0^/'/Q2A؎'}d1ߔp~%lej~~g~;V}bdlK=uam@cӗ4|*>7%F1/121)\?} <}O;xu,^w΁yqގc 덹0/?;KJujA>Uq5~/4cdFޝ{ՉoKe/)i_2%r_p̅󒲔ކ=vfCX];9/) 5b>%}l1xI'?->+뛷T3Ka?5xIj cç5@jq{RSƎQV8 oōȱ>oKEaSc#3_'=bЗ\yD5ǖhr^?}I3IJjdž?׭~˹%`kK33Ky%7϶*|1|d26g oK垚W<|g/C۱K*k>wݏ7 ^LL:/9Tay9)%GJXX|;ݬ ^"8oY?̦~d3%:F[ϝvl|]ȻkE#b/0׈OE͔CRy[7qb5@vm>o{K 6SA}KN4[noDޞ{WN5x;9KjV<;/{.hwZ"i&VÿBe:`̅5xIZn% ~U/)m~Ά# L s꼤xt<KdXtevKJ쪛`ޜTrݒ >IF ^J~L\5xIComuݾ=n/);yIȻ5ZZZ0dOLlyD]cp^R%%Kuja>*x 51xA*GJ%` |cL֡,I }I绩)7%-zRW#1Ͽ %'w O_*~6<_g %Y"&1v|ylYi3z`b\4kvC?#yt3;Vg+ja. ?'R=V\wX?Tͱ_Bl%z%9/Yw]ݎ-%]w_2q;Z/8?3ޱ~#y7Z"Zm-Y^:/{ ^2-YPu%sy9co˺[/iK$L 87sDlwEnzYiY='3db17/\W2OmKM/;6t t麞wۜ8gPKM#Gge'hKVaOϭ76n9'VK: /ى-xJX;uyΠdQ}cyZEY]įjKޏ U&[K};ڨoKF ^Rn7F'WF),Gί];_go쌚 ˷ k|/֏߷s^;/9MEnڜ])dTᾺys^k)TxKpyOZ8Ss^ҿ7ﳃy ^R Q>g5>}VQ4?;^  9ϙ~1|>ԢFt|iuHQQ+eS=y%5k0*-Kʤ費1BtzH"N}iكyǶ_>.yIGWnm<8/ُ[nJ{% _aX.0R`𵜬h//ol"Oմ_%g3Ip܃%}$݇OT`)?^2 `L]|KS;Vu%)"\my}iK=(Ǩ'K"#]#8>;=xk?맒<)-oSk</Mu</YwBMYoNp.c]~))XU^)dorPRMs~ O@I=x{!V󒝛Vԅyi`So/y15{{Џ7D`a1x Gkw^4 gymXuom&c뿏hKhIی;bް:ux yaIsv6ϻ=i쉵*cC`:6N<8/Gd c ;- >y֗_q4fBo`k&U;K[ xTw^RT2:鼤H׬>x}%ys^Rѣ|T%KL[GME^2;E/`LRۃLN!K&lvFKlʖb(V>^S|:1F I Sl+ܕ,sSPR>?P;^$olݨ덝 F _5˼zȻ+~rhSyJND[ D{Kzm'*n,xIѿ>oK=*>oxnZWx}7z|p>?=})J߀a]ЗTu{G3WGy}wl􁶅w~d-03%sTډ8+c`^RT}3ouS@E0;Cr;CWޘSh̻Sh>{{zl~"eȘQoȍD7q3fZ2_G`+cއн?>oKyIJ:^Rtxy9g,띆|y뾆!d禽U{cj'"݇00$E _lwʳἤȠzc#V~;Kʰ^$o eME]]ö7޳%>m]%}[*s%]S ^ϝ؏uO)#bż:g/h%^>=KnK'w|"2H{֮}p3oIG򥅿OoŜl|s/Qow𒥓{켤U jKZ@4VԿž%u'xyskr~pL3c-}qS(V1g  Y:XϦ\kt^q}~-~~0o=vlO,YOA?/·fOa+-dSF^Y+q2GugbZ0bC7ۢ>k5+ ^'c=^i wW'I2#\>D %ucp^j:ZyᴨkKCl:ߜKМ:Kf9ٳ=Vw~=(cyJհKv2-ޢ>`/|'!nJyz|f|f\oHx}t_\9QGeԺkd:/ gt3GK#t D[)Tdy39B`]d6s|:zx)$Q1GMz0Kw)F2Gbw2ձ7Kn]t/9'}0Yٱ³ώuQM"YPho%Ckek:/9gbuCUT^|vfy ;%| +=rY.YZ<%7jzAodO0};zLȻ+N%% 6o.j>'Xϻk#3oƹ^R ^Rag!xIŹ3ڭ9&5eu3xIk/Nd=ߒ&7Y ug/9/d 3K݃3/F_uV ɖJg] ^\/x}IY8SSwW ki&Kx~;6K*X;}$Ky%^\,4 ^bŸ8/90a ?^kKX̻׀׵Xn]̛NAuq 廏؉-8Ǒ:Pe~ru(푎!6t =C.3Ŋ}Vٶp+Q@r=5ۍ,|~e<gi7]1l|7+{j-o" ^DP5葫%{g'`lw l'fy֧jCݭ^fh{lԴel؊l4xɺ 3vD,׊ZOu^r,ԡ٢& ^7껅u;Y*kV\=Q?t8b=BY𺞿L ȻOTC3Y·tzeÿnyJ;1xލ>{OnQ%O[KN~!%1ʳ{`Ӈ% oEA͐803핝RYKFdzO]q#Zbߵ=c~dQ6GWxG&XONYʺ|? rEާ+| *y:Yzۢ>s>`2'p^Z%}yFތnФJkĬDޝd?Q QSr +w/-6 9/=(w 59/9xg yws#z!ǜJc=-妚1|xcK{YXYA+ ^2Z!Sן9/9rGC9B_ԐCx~< %6l x>W=:W^ufELq8w_*bCp״XZQmKNsm)ܬ\w cC0kx+OaNw`h=㽋뼤Cz2qLu [k%'H5漤܍;NXl6`1%RA}𡟚5l|ZOwϛ%y._-y|t!J{Y2 $w> µdFm_ӵyTzP>w^wbKw/5}*,xXS:* ^Ob̴/ ^s?,x łƞg3gvk;T}TyM/ %2HԨ)cVւsq1|>kKDx~ur T3_ 9kYylȝ,^Q s 9nr{}2 /?*+Qy>+F"_k ",AXW>D;Uhnq:^6o3g]x#7]--,%;j 弤܎5h-W S~2YKz.jWw3o|hSh 0U{;)VNFoC0Yr^s@!keۧ96bdۓۈ&p.6;qMa`t򺞿Jo>p}߳}{Wk;<.S86ͻF-yt^r^Eb6%'u{9/9@q$;ɧy979"^KNLFܗ8/4zN֛.%g'>me[xg!dt{lK90:%6?K)>xs83V5¿dܜ- +xboa9{b-+ kwrkO,5pK<*GSab}ei*>{;ky4 z. ?0\zi)({(6z- NcC-|}Y[E1/~8noUdAFeWc3 5.^>l ?IO>P+ak󒽪*=ӰgyiKXo[%mGFk9/9+-\Kuj9c=^^||9/S+9]<=TZ?*b鱽zz9m~;vж;b 8ٱٜ9َ}H=)mtԺ8^YccS*blou;P!׫;;g s>;K)knQc[L:x_ب[!p!62Us Ӌ^S׍~FN,^os^ua CKoE8/UoK(m߱^ױwB`;f.}E3:6ga~>џA5T<;6t HųCܨq}qѷS_rF}w@ǿc=(kBdc9zT^B#(UqFXϻQqG%Uu=F*u%\\o{4z`gyi"~IӀZ i\׃j ^{OCEv^2qkwjyQ@1,jݗƼU2Eَrdg7V]Q3-9% gKf&dLn.NV rX?ޱ'"Z߱_s^F/;c}1^'V?9쓿-|zޭ':_E/P}㋍y9 ưu ^{켤+P5\qu^3ir MԨ723~W =KẮGF}=œy>>eW%ݪU_KNZG9/⢈mޱ-,kn:6}%K5IxvwoԢMU[iU%\\zw7{lQر5| Bf3ԭqW@-JMȝXekjλ; 92jByz-Xϻ/ɟ> |7є:gK5~[}*lj:/ٱ{;==NtwT_h{bկ{x6uǚ߇J/JP'/@y[o?it9^"xJ^^WSWKQmh䘭\y's:%;og Ka [jjyp^Hx-t wycYR˗A68~E}@c CK|JK3]wpߧw7K}%/Str 11~΄s ~*};|~_B ɇp^g>dMurD=<'k܇lpU۽j#quur3sQxj[okOo<7z{P~}XdN}aȸRֻ/ǯfpv;osuO*o  (=g_\/ᇷ;{el o,F?-}r=lzyX[6߱OKƾ7E~z^޼MΞf=oG#ư$JjW ~x'^r n{~x!2cbbcsl^r:MXyb'ro/9̥Λ9wLw-zsK_89ީ̉OVo5^vx~-0<^rHf6s~xr>KN|P9}ߺƊKόZ~xyGc_/y8%^@;?LAq~/ynPc|s1~xɁS%gUU΅z~xӞ3v=kTkeZrxc⣌~x#iXx'3V%ĢxLKFc>Kyx#k7'Vy&}m?;ntۘ~uwކ[ r>ygD7ݱpڅMy7߀Vp}Dk"~/y&󋅽}?L8|<< ~ws͚FBzq}\0y3-M̾ye-z^o]z:<RlWw=Ac>/+]w|l=MkIAx?^be=bgta⿱~)c~1;Dk>߱-j@FIzӚ(Scg]x!+߷ ח| /GևΏ`!/YFywz]{V~7-qF]Ũᄂr-9k5gɵxxjK}yIgzK5=.:yݗmnڱ//4 Qy:x]{ #xI5Vr }wxz:/f-xI.}-ww[qt^b29JMp^b),rlU$M=wެ^:9/=9/n/}m%yk?;oId[+-Wy@b _Kt{|*xϜLip^Ǔzc+#Iq^㍷fNyM޳7jiZm//uGY4j:Km軟,<89xp^ϴ2%S[-;KϞ9ΝE*u/}񷽼d@9/i|~OO,0aoP'c%6&}!=̝ =3Ƶwy@{#3/Y?f,]W_k!;s={%V'ckciֵWy;ok&@XMK\c}|6:<)/cn$1W=c_^/iKK_M%33Y:Zfd27ٱ;3A>=e Z ^3sLsL,wIQ,%_ Kҳ~d8[">p0kw ƾb}5kQZ=Fь]u}֗+k戍鼤3N2یy֩KH{ þd:/ѡf9t^bpx~11j;t&Ku3O*{|_;يb3sNؗjd $}X#%"̳+X%}ROP tA3xI^CK?:/Y³A ^IΫXחEI{VVG5E/hdvj;>/6%/AO[\e-q^nt^u٧bǺN籲IytK֠Kt&v%:Sdby yґQ 9t^VIO%j%u5~AK*I_9wެ1ԉi:/ё4pyP4o:/- Km\KXҭ4?I7X kk˚1hcW~7 IPS<$ױ2V @X_'KK ܾe{%&=ձr= ^ܩFa/׭K4Ƃ&r:/4&0۝zX%sG!x$](D%r gTI3]Pf-r= ^2\bd zuW~طnquKx=Zb+]cR%#Fo+/c滞ռF#WNo*b;=F8)49⼤9{Dq^251ތkϝvF;oK yIJR%t`,Kf4ޅu&%$X%uQG*K%JP\kK"u~7Hq^[IO;UKZr^ߖ#]3yE?1q^өG8/Q1t%CV{%8{8z5S}D>D4Iq^2%n/u­$B 8/Y:8J}8/QjCw``dǖs=q^kրۚI c= zt%kIL5m)s^Ҩ }u,Aߜ!wI׵w]g 9L} _&ƺ#Ջtj%Y~^b?u&$YƎܟgR;#G;Xd6~%ȠˊYKzj%ȝ.({~­\7fս%@ة9;PFT+X WMb̪ݹGrHI}%c%>Yyfz LҁFRvۜt)I8yhK\?Y{oiWZ<yI;d@{kKn&݇L9g$mH}%k4M!84%uwrs^g/dJu3cxj#iؿۜ>?}yIVr } =]!%ug9ES{8U,qE!-xI/т[Im|GcQ\t,x$FnoKZw*%"٣Fy` 漤eQ5yIg-:@s^;&r^s^gEoƜ>k^ɿ=ayI"Y/{612z6}H 99/Y8n:/1&VD N!|y*dh6X_hKzք{#Q?Գw%GTE^>DK.m148,gНc(:/YØZ$y&?{O6%c!{"m&fS9kK`t֙38/{yI/>V L-J/XM:dҟ:cJq[x>oK,koSkK`\8/w'WIkm﹩!w:&-]6P*XicnŜ,J<֜7ח <8/)ȇճբ4=zꇱ//8s^^2Kb+=//%qeA^:a%vC8?0v=dgm=dLI9Пv/Ǧҗuy?RJ{;]j%+CXyesl=Zb N`r{f [k47oJtJ2 35V>VV^ͻe͓,6rЌjk `6%i6ޏ u{a8\KZ/χgMk,%)l`7 ":ݛ:g#nKI&"|ԑXם?/PM1O iϷh!Z'5(5rK`CE#TVp9)+()HK$0n-OpPh㤄e )O#Jw4!KlUr o'8$i?hkx E>L,_ƻUsQe֔9@'XnENo3!:/dMͱ)hRLt:/f 1:gf%PUb?]/ɱW j[(tEёUCbj"?)&)bW cj@{;ؘ8†*h0ɡftN/p`n6&hɽvޔdZ*JtʸKc1팯c) -)^m:΄T|1@%fsQИ-I>M(iSE]z1X1b2T qSѯ_qc*Nqc2wx Lґqp#:M:7&3Hw)[n1 Tw3}1/ۦeDIܘHSڥ|gd:2ZS|Ϋu x(#b^S5SeHf=ndĕs]'!T2A*sc?̓78ntc1uj}ooG_Ps\@\4"b2Z-&M\dVc2b2s9sZ'EqL IdibbA"РjLW ¯v5&C  jLdш>k6}ڶx ;'5?L㥛AZkdC_E| u tWٷQ]kAdg{J,tA.:!o;eKhPlh8ŀx&i91AES{#Lf5&C[0tɈPc՘)䏊ƻx"DWc2J|b'Kitbq8w<+,_#t:ɬ\I(y2N?P7Tl}CNqc2SfQ7֋ɠ<0kFc2Q*d+ z1''0d⯟ޑecKFc2H5df\dʅc_ٴ@,wl7%#Jw۝u@.]NUjL&5t:zD!Vc2홼iLft#8ZLvqlbX6'ɨ:@LX Հv_͓E0͓"G y2tq{=2 e1Y$Y2XZ A<>mug8?ZvLf*zEfH5~f^|? Gn$VvKc2;;KҘL%$V#_ߐ'D}d*HV0b2OV2#'R_4qK,ɐwf\71L,{ wAiL&}l4?emiLFפQ7Ihek97&-42gXMaD:.XLPA4&+p_'%T{,$xS p,¤=ʢz> C2ӐZ ,^IRc2fizgtèjlNzS^"֐<Ns]ío˓YS$ ɬa )?f0K1MgAXAitܐa.Ic2մ^Âb"D')O$BR4&(IůW]!&つG?Hl(ɸ$a2}4&S0pί)ĺTy >uv7&Bp.Ldb2 N0ˢs.Z ]<=r0 Q, 1qeDN1#=dO/lc21H[!tֹH7&||K?b2k$} /ݽZ!)DN1B2AU$W J4&hII|"b2c#L*֗_L&q/:lnŷGb2wɤáٱTl1.G)@ iL+?;Y|9ܹ{Ӵ Hc2s}|5i`8)F8dsPM˓a|C{jnN. t{4&ݍǂ1OtZ1G3ddёV)bdkxa}~ Q%ՉrD:eR77t`2Eʺh}@ClԵpIy^ľƢGZu@="DHZ U#W#'YaLf!ԗA3=A/IqO&id= !#lb(:_7Ao%ژ,!b+/&ǭ;tlh˱A`sl$E&mմ1oVZI2s˓!$`AL&uFD<.EGnV&*{¨viiu|HBu:O&@yl8k'C0cצʋhG&[5m?QRI˛-k4k~y;+Iʠ`ɚT轹Yj w'`et|#/$ *ȝN׿cR 7]LϳtVG,<ÍPdᕁ/ *YhH >u8$T^ k2AV$~pVK#v˲0|a+Hގ^eQiћ $i$bC#ic2^Yގ>%(i1dB8~L t1d\DBd<MQ֊N`&zڗoz1rPBwqv]t{G`|} 3>'C6&cFsc2O7@6ARc2#I6z:*-˝D, mLFDM(]~2>>>/FmBV 6&3!rT I+6&3!5ഥ+I͡cëk:nR8Oqp.tz3hEk(s&2$|'HgcQ>PbXAK )vdL+:2ѬڄX*M45VAмoT,;$1~5;Ȥx'VY8o,=bjKu0c{Jŷ ̐ tE]H} _[.t-h=̑}5qю`20G! =̶Vb Xc2o$Zc2ZL/W{15&))ў-gBztz^7%7ľL/Wm.iV&,a>9#;2L|p!+K[^@ˣE[d*C3~`A3 L.nL&|! dM߰'ZC, kLF:]!>ϯv V۶Ldju g'(l[1;NiRӡM2ցJg "DoNTZV *^̾g"2$!~Pn 5 >h)7~NGԯe-C.Lww[ŒV| ;z˲viF ! L߰xt>ӓxȂh,|w'M#;ƽ4¶,1-9#x1 Yga۝d`I۞=]%se{Y氖\Ū($x[ގ~q=e]gw&|%uu;tE4[dǢOn`D.ڥ씮⽑K,#Yc2;ƝWKXAc2ա[AJGnLSG֘JFXc2kL}) %4S:|AGnTYK7w K;ڌHhbY`Z=0{y?~:6 N팇I1G[$'v{La}^dTQޘ̊vA˲_ܤMߠACKg;zugБ 7O&W-.­f9 | 1Xf8@OtH ࢬ(_M oe7jĤG4?n?)68I-,ǿh1a3赒/Nt9ȷ\̷.W4#݋R7W]E&ٜ5L-:sN.0 7q vi4&cXpj1e`H11$Y:{c2KH o19َ!͓)zsd ɨżoLFdp^1M5*nQw<(㗦WOg༴iY+K.nXETXsy,ǛW#IQɃQا; : M/1lvgkeZ"&29A nD?];8'(w{)h02IS(fV 92eOp1N+`?~`KFfor4N^i8|dWt{3&d|ykؘ̙7&3m7Nuc 4`;%G@ůnb,"pq!"pϑ9Z@ #5 뉒XFN#3\771ʂl8 2y6" '5IN F©s:rkDHNЗḌdlʏ蛅< o#^k ݡdNS/.3_&9q_JnK [8HM N(tdL k݄)/_fW' vg&ZYtJLʊ |ѩ[24*xpZϕH94ظJ . 􈺴"xgO7 l3םRBM sN|a p=!7ŻυpMzS +AF~ЕPAL$q;z̲[8#nG_R$ E`2;tW%)= 1LF vLX hFBLj{LfÕV-/~ Jdݷ#;hchunLfrg D}jLAyA od',Fb(D}[)`f.MWl;d {4y2Yl"=- 7}xL#?'fOOYa+D[ݞ&HοoqߗvQoq6P|m?oMTwNF%c`,nXt?HouB{s\|qw/w[:!PX!aq584n|3@txr| $ 9noF01屢'1Qy2dV͓QfYhMzӸP#4o]0hlB!rу~2n~"5_?>E l?9H&=~}QNb^D*>LǮhnzu9/P {Z^f[CGIP ,8KkwʀVe>W7!M٭ Yxw0nm=]j7E'@ΟdtgNYܘ62\Qձ:OA@WJ8ҠΛP'ߎ^2;, (}YHH!Hȯ vkxF莞VIn$=eʜ9)V7_bWG/KW"(θSЅ͓(e+:rVRҽ@;ņ-:}c2d_'L+8XOlL3N|ь˲ (;v->7O&ЦiED)0:}TjvIhZj0MD)6Ty]Apؖfr*z+TәOWSh޽A5(,1(miFS~>?ū͢i"6Eq-n'{b،b b|QG:~)('Ɲ.e5^T*v ({ą0~*lb3(}"\pj>,0p?N5zF?=JviSGb>rHKW]URb8.=;ZMTkSԷDtEHTS{̾|'d<>)OY7 u?)K$|dvO$ٮd;OG2jLYcel4&3MA?Rr[َp64^m.Aq) IA$˺ 6iإ҂x6 DvBb *>@~]Ux@҂|ĠStGp #2m6:a$ámlPvƋ?†e/;ew;9oGI*t8Ν|η|Ng2qoG?45U7#b췣'rQْj+^Ujqn1d*_耮?.2~dp=H[ZJ9I :~ጴQT|Qҥ,سdPqY c\DDFKnI]Ɍ$+Û(`{@#V]*tۦVZ|vu hK^®?Ka[v7qǯryžC)tlGNJlaw-1Pw:{λӾXA ̟~Tۤ`;nq[ፅ$4}}%T/AyOQl;XQ\~t/Ofv]LY zhҟ]r(KMaU4+(;ІKvRQi7L,F3G[E"ns #>&ӠP:AF.)Ⱦv!vvb$ʦw*i(*@?8֪ ϯ;(T=tw844y0>MѢ%WG7 נ묷 S|u w)z烕'v&HOoϳ6g{\tv!KŷO h1|& ϿKwAgi,/,-_+lѾ˜t5v6 DKE^Kv1ŋuĮ͑=̱ +‡`2;|aۧdٰ/s17X@n5{$TռY {?p-(]lLhh3my|Q̚}PbO\d_Vzkj>Sܘ&+ax,tisɄ~#Gk<9 ᜚Q-,uϧ%?d:^E&o JS\!40]@}{tD{m 6=~16C7o",1RӜ&wa;|ن@ywpBQǑ{'p8ŗ:+80m3Bd{JE={ٞڱmaQ]ne`Rŷ[7&ħ؁ϳ|  [ lý|iБ;Ay!xvcOP)aCpϳ odh˺_ŷ| ZN]{scotch-6.0.4.dfsg/grf/bump.grf.gz0000644002563400244210000030276711631447171021755 0ustar trophimeutilisateurs du domaine]d5\]wf):][||Gx1<Owh3*?xX()߻SX:a_UMYI=+'6{/\ƼS7`@k%#?(uy(n?(?>SPmRg{=:u4ϚrH}U_YG곪yӪs9TU~s=P]W?C}ۇMpz\á2>:~.ӈ^Ht7͇2:"tq|ȁqpq\|\CC \6C<p:с8ܖԀA xr< 88Եin\{6P<ҵ@88Ե@88Ե@88Ե@88Ե@88@sC][ CC CC C9 :lPPPPPPAmqpL7'/PW[aim5wC9tkrrj˂'"NUzH':W9I=|b}R# }<(5PP7P쥯g[% i,r 6W>DGs?Grќ4qh~'Gs*0Gr쏾9C}tϑ\G̞=K#M4>ϑ\|k}4h~\ŷGs$Z]%濳g3:}$lFGwlFG̞&|k}4Z>k5f |k})Z>kGϚ5=[g-^t4Z>kGs$7ZHn>}#H99+gH9_uugYe 8g?_Of?_-觎k}ƗGF#S'SG꧖ʜgjјqHj5:i1(ќ jeŷGscB En,wZ1u7bSk}4_M3Gϗ9ef/3GZgBhy9ڛ4?=9ڛ/)E>Z?gfo3GZ2E D| }45_Bi}hYkd>ҿZgfho=|4\DGZ7{߄~h_>s4kGZ6p~}hY h}VBbJg9}i\j4||vhh4V>o >磹*hh[yo}M7>>ϻxvfOhY ||gOhyśof]hY;;||݉S}Dm >ϻx=fOhyɛof]HΞ hY||-S}>}i:߉:ͷGlsoΞ+ёJfO_hy)>>kofGڑy >MO[of3GC D1hyh;>st4ϻXhn}T󼋅5{wG.>}w\ӑ=;y Ailf],|}4j>h~h1}hywG.>}w3}v5(VGc;{wGϟvN A7tc;of)%:翳|}TGwf],|}4Ms>}UK9}wh7H|}4mY>&>%:}ԣDGWzy Ae1ضgy)!l g>֩+GޭFʑv^gHך})Gw{ڳv_u4oor4=o>8?im+}H;||4s4\N9)?>kl~>}6gOhY {>}kWO{J&6g sS/#4ʦr.[ }hY||4g>}-z)面'sDYbҢw&?oz쳮G+H }fI6B{Z䠷ޙ^פ~C^q4T7߿u-dk?veK`MU~߽Α Bk? ӺO>jaɏXyՇW h6T߿.sfk;ƭ'pTZ aN R9XmZl5zTdl=z HNJY0TT~Q*[1WZ\6[m?=?6quG_.Ms55O[t6a>6Pζ!L|CA}Ayk!ּzt5n*h+?E(Z?yi`y K^dd' {u5d/zP4㝁J:AMx c}sGxR(:NB4ʉ2̎B ([Yw_0G90C Jz흆4{\0;G?{\0;)hoՃks57,} O1u];ٟB={?`AS݌.\?5~Z~vGT>vs*Q(mzNDնt0u ѹs_ݔG=nm-n\}+^ju۸hT j!YuCQ*l )fϳ3w}Vuoi߇ejׁ_bfmZvp/dkֽdy1$Z)VWs.D+O[䕁2cK6HuY\ؾ s ҰTsoÍHduɑU-DH\P1v›3.i^n4vP`G=o<>_1KnljwRU| {]Ihd!OZ|txU}s1h1UNq)|A|n.Ʈy%im׹'q_ȓRtO3WEq?NWxY? ;px:̌uA:o;6RӊZ9dPz̓ؓu{kiPiq _Nkݫc`v.QȮS|&!)p.i/kRsvɆg)*z˹g<&^th gZu8[=2 K>RmwW4Үy*"N_;[pW[{<MpӦwa*lUsP5ۜ7jjr:0{5TKnf GtZU*pVJ:05ծv ut^e}T:Ёٯ_&t`l2 l8Cfņ*cy-*,p_J:0[6ئ̚ tgÉ*I mJebMkdXyjÕ:@pf:0lǑFڥ H:4`vX#J̞m6]wT36ZЩ.37Z" VZP=gnn¬z70oo?Lꆁ+עY}pvĕcFnS px* .oC SQ p{i,e0w5{Az& ts앛s𕏕s*0~J:0G8G+l𥱨:0g8L`EЁak,rbq7f@'IP,"L,]R,*L1q3* C!ʨô㐉(Њ%P& (ŤPQ!34Ur7Ŕ P+4搓5 Bsh}cCؤ9b gI̅IЙKx|PCl(`|&Cڌ_Mx^ՆU$8ײ ҢX^M6S,^j4\襚6`"~IiiыX$T,^4-Cϼ&?!:W&K0xEDhRP( HTP)@/PnZAX4SM,K(7`P,^&ډ@/o)T'zͣ8%ЋHҩyM*<4L?uM2)@/"zH ETAXѮP 襛mAX!B7Knz E*`:jw D PzC:`@/ݔN!K?Sb ]LAX"B?hKaj b =N  X SLBx(@/PSTrzxh\CExpFFBSb "Jt !R,^D N$4%cI b "bt -aP,^LLx(@/N& :WQ,^DN(@/HpFDS( O#Ћ6rSH b }QBXț)@/"HP55db "ˆt ]HxB*c"SRm,I@ҋUI 7ܴ\ PnBXoBXb5M_K<`+P,3mA0 &:W0Mչ*U 7Edm;Ce(Kd\*΀=\)@/WܔAzLa0X\rP\Cl \CmdJ :W&7K X$*E Łr۝$ ЋQ)4AzMk0Xl"Bu@%[u!;hB@yU9tM]p1oչ*7Xt"By(KNSbC=PHsY*2T&ڊ f3<K6qP hPX(R gbŁ@mH=ML[X"k(K6Q b t#>Q,T`vCX"o 'j>"[tǁasz-_)u7"3(@OP)@c4\\d.ҋx'oj=1(@l 'BA5 F@RFs麚/&Л"hɊ8$.Ox EjyN^ S& EfP`ws <5 @Ϭ0!mmftC8ȓOso+lڟl<|G4[Li/H`KΒ[9c]7.hWYԩ{u˦s6ۮmWmi}jn,EDeiuKEzx<8 1eU.>ZC: ]_O,LSKs )Y%R@#T2=مM b 3(dTkW m kH`{^izc,.s)L0[3כدmEq|@>7ؿ O[z!~S,A''!|taXu9/JٿH(tAǡ~x_$<K*Е"z@? x@A/qԱ8Ýb RTAz)6DP,^ HL7! Ca&&UC8bQu:TL7D6 :^C\L7!:W67%Ku";:pƃb Rm$XT3nC|t1:^a<t4:n!dAKs#:[_FFzid3rX4G!yP,^ 6%?KI6& Iyl:^(aP}zd2ݠC;tK6+ u r1ѹ*iS,^0ٸ<(@/d%KwP&qKwx&L.|\n21&d@\ۈLtA ğ6#?K6$ӜŽU94O.cL~iNsUns2i li\۠LsDJD/mR9^^ۨLs .Y4;:W6,QaKCܦe/j r.q44tB? {:YZ DaSL .$ffpt!14(zF/e!16(%F<$9]H ԰t!19Ө͏Ӆ#IJ,8]<,e$gհuuQ?F>1L*O:4-_4=i{]YWz@:=>1P*ͺSg?uf]驳/|J>fj]YzC|+~1U*ͺcvf]驱| 0:=>1X7*ݺTߗjć0֏y;a+O<ܔn]ajto>k][Wz;|Ʈҭ+=5Z~cW֕ǀ-߱tJOc–UuU[>dWTӠu8k]abqյ0N5 zXWzj_sî2+=5A[~bW֕Ǥ] JO}c.Lu1k@ua0 z+L}ĩA?F8#Ǻ¬,T豮00N5B[Wzjwa:XWzj#waBXWzj3waJXWzjCwaRXWzjSwaZZW/ ׺ߗjk]a1829z+LOL1|&Iu~1}Iuƾ1~&J'.;2pz|c+՟u/9g]a1_0?1 _ ˀN5ŃYWM_Lb_g]iʾ1}՟u-8>SXW %s9 ?&q0 ]eN}YWF /4˺ĤRM+H2SM+1?qEºҎc@XESXWLvȉ=T/J[ǎ#9 W03׮z[Wo_1b(L1+$G\.{Arz\.)Q]viО \nStM1/ fs43 se5V܀語\? s])w ]$)+2SM^'@I8eXlZ> ZW{5pA"Vv)?4egAt{" :n[ ay^$=/u+n{msֿ@ºy%:=bq Jϋ#ľø]T-*m]\)L5sFMĀUlC|,6NV;2a߅c,*|)຾ Yy:+@ ϫ rw9? Vv/ewM=Rqݻn_NuA[2~AB e2l ǔp%0F_pj:KL XQ ]yl$DU.EgzP{"ʧaXvưz'0-t?+Յ?QrsHRكʴs'49Ht-by4gÎh C*Y9nݷ͍ndF($H@?Ľ9Xq嵲C/xzY_<~RpZN!̃ ^HIFHAGTn8*˦D? 4oKK(s$lF+T7(IBo ]k3?pZ?q?^*)P8]+ ')7T\& >y%/ja%ճ#Bb,gz`=/QRd%t)xa2o&`f%l@+Y¼TZɏ{ZIE}ke=@gZon,ZD}a)x, 1[)@k>|Nɵrl1?OKrmk*r[nNص2pi0ňsq>Fg"{lOzBOMMg‡|a]Ę0Z>Fƫs5<^"ۨ^❐,ɓ[BKRlI"&=$ ' [hTo'eF[=ȝ` NjI#`وQY@ǕAZn4G$c+k 9V>;$V$')$nՈu iV1uקFq٨kRrt2HYȆx_#GFwՀId2_>e9F<;VV$|l-k~ble0S\f@ux- CcgKŕH_'K#Ӡ ji$)ЊAYyЪsdh @:vHXΧ ؙBn:v: >)lhi:Vn f߽u1ڠVpB"{w_-@Ѐu%ޓ$tmapu ٻ8\@ºjflfdmpBFI4@w\Dpe`%\.[Jr$uHXWpsB xq:E5ąr`pĆrpćr:z_A>nkq* XWԸ"Q" ؈#L-: fGH[kJ( _kJ ) ckJ) gkj $+xR{1Tq0TQzI'8H[uE $-: p֕8Sp֕XSp֕&pWА0N]Pi"@Pi"HG ej 6MD$.: $NfG\ kJv kJSv kû8adG+H] XW ccQ8=AFVc''GZ#2zqE$( &n +[$Ѳ%@+"[$Ѷ%@+2H(\# :Vt5}Vиs=K"v' G_@ X$ am!saz 5$.\Oe뷨`@ㅴu-2A8e+Hh]عšE$.\c$jv.D ;Ysz"ޅ!9=QE֜"!xarhkN_E>E S\Š2.Ǻvi$wE0 ceŠb +Ix^x:J+h&!ta6slWXM6l|KJ%?ӵ&δ-XCu:kh$}tWMTXQN„xڮ"Q]aE; 3ckŠx4Gv$/Li +I_mV009+(aPsmWXQPÝQ]aEB A^QaEC  5VDp09V+(a=(b:osgB׵dH3|$a~yѿ]aEJ / #}ŠfHM%{D5%0tITXSர!;}Š +JXbV$İ=^1O40Ű9:+*=(٫(m1͈Pn*׌8(+'**aa܋9 +J8cX +JXcJۜ32ksg׵YgD1$ԯ{u%%{UL{j8sg/I^KGK9ՃŠكŠكŠ&ك*6d vm&y93\4bAr%#?S棡NQA^_GU ̼%{E%̲%{E%ܲ%{Um x73ITDn A^iUĮN#%'uDp A^m_?Q\2{PI{v9jΑWb1'~ 3.ku 돩Wm&/)?^\i%Kgrԝ3ej H3iڌ$a6voD9Աyk?GhiveGukik[WX_@׮"V^G59l H3,$aJvo~„d?dusP 'YBZU'yA%&%{A)&%{A-&46_?6IXrmf[LAwB h'Kd^T6ڷe6p~&FElNZMH; $avxi0x=^ zIN/zTk?!_ìc350'?UӞoS~J?܏zYLN'b O P†Pk O* I.Evse1%(m6c|WD{~E<H\ d?X͉L@X1wK ϳPϣaHyy4 IóPϣaHg>a/vTB_,|RhgG÷?T *Ͻ>0$nȥRק~Sŭdžy ڇ֙pX _cjI0H~$Lt ǔJ'(EO{OX^E$Zb S%uH\/3>Uw Vv))} rdsY׭O6>7dk8\ w_l\&sٔ†.ˡnuKy/ɡ}f]kUaJ^6Eza.b X$7vZJI=ae "'yЭr#AVGS8 [8y8\6rz5r5< 4_\\TBaJk_bdw<g6*(V"H *mWJ F̥U]tջo6^V)Ƨ5_}rM_OksgcU]k2]7'S ׉9KIؽg6ny #a{O8^'['(F"W}恾H.h7N*C $}r.RUo +Kb㽃߮e"׍_%yO>9ZF|juR3^߃vǞ7[.tnJ%o 3Z79пQ`9ȟ:GHXʜ6axmE?.EzWLiSGY/Wqkl+|2{ ?No\z3 ّxwi Ɓ(Au"3`ȩzjqBrEEBNꍷ_OrkZҎHu'ld]qlH7VU6VOk{^Ud ڱ6?8wUJVrZe7{HoFt:v Ul[Vq{:+AN2lhG^o?mͬZݻgC]D6W'iuUVϦA˻UX{ab)VRi+B"_xB/my+B,Pv)I4D6)}X:9<>1~Kj_8!N+1lz\4x߸Byn݉NřDvTȲrKiO-p$(ccԿRNNjE\vvRku am.Q%>Lގ;d=;zu~](Ք\LUmd/P Naw ɥM Mg{DI؟55󳽒Nyd]8E3,%,vz9\M#-_@oq^W| ԯolWc_|ƽ~7H"[]-~ R'^׆nMUu~?Lkr˵$P^+;QI/UIk𺝵DM?a/ e$?i[S/a-'q_j>uYď]'s%r{_P';TձBw7Majt =2Y}y_oJP<½o6)uRK$ϰ}$?vCCT7=Il~ڝd:ɮcCI$ $xk oC׮@߆M"pN6$al(^HwC~$ sp!nT6A8ɋo ŃIXw6/$am(~ܤS$oC@߆IX77$oC~PN2olJts'cC龁$ ūdm(~HP<vw oC&)='Y$am(ި E5:ɋ!{yy@߆]$ ׻IXw6o$c&v|/ߗ -WlA)Kgh׵9?v:'M8+ݕI\Ư˂$nIiaeAx9i-,H'ݖIy nv]$1NsaeA示 {]؁YR^؅YN̂$?Tb$ad %IX.)0,HIa/fAK {1 P]a؋Ygս CW#a؋v{^0,HCuIa/fAKJ {1 P]bUYX<TF?Tve$a9xdYuU:V XuɁaW_'IX.)0,Hsîʂ$TWa ?uchH>N2 {1 ^̂$]^ ]#ܞWJ {1Dub؋Vs:}b؋xoc؋YDד^̂$|P]c؋YO'=oh1d؋Y"^̂$_]^~Q]d؋Y(^̂$|ʰ)<y%˰ )&Y9p{^2Ŭ-o'aF ḧk]?NҌx1sfċ/Hߓ8#^yΈ3!`^ϟgċ 0TX3Lg*b&A3V x1> +F %zLF#^đy=J/f"ɼ?Sa҈3d^ϟ]^ШFGTX4L|RFL}=*.b80oWޥKJ^DDn$o/嗡i"@R ~+qpSMx7|(lgWJɸ YP)1eŨhN՘'{mpy(HIo|>xRI%NOHȠ;mU5>~62V\T*Nz`\+(zmOf~R K/o9+NR? kY$̴DLuYܱ2; u{q7X\̌rʋ3A~;;FO=x⎮I뺳kWugq׀$py]wwHugq7$O*/IX^ם]S'}^ktst{;;F'?⎮I뺳kWugq׀$?IX^ם~Wyq&H,:u^ܽtNZnw/]֟ugqGuY5:iy]wwtM ,uYu 뺳@O*/IX^ם]S'|΋NZnŝgŝWeqVuWeqV}Weq,Tѫ8ӂvF*UYix;S#v,δ` ;zUgZ0H*3(PaG⬺{WeqVI뺳kt,;;N^֟ugq׀$?IX^ם~WeqVey]wwtM?ktstùݝ;;F'?⎮I뺳kmy]ww H,:uY 'zUgN֟ugqGn/ ]֟[]kt,;;F'?⎮,u]!FWYT'pTT1޽$W_3緖d^i|E (*QYRUAtǒpJp8(K1KºeH_/ ^qiZn?qxۥR ZIAY䵔W@'^WvT+guOuyݱB=d~xȺ}zQ׺3>zb:6C&N'_fխuˬPTB~>UuEtYN-Y?̪,.tX?&=> $g%؟tx[?2k}uti>=+Sӡ,L=7c6ƂPK_ ^u%M}-kH·~*3E J1&=)-0%lލ%0R(#cVe>`2g] +hpQGߎP uR7mj䃿cwU~]Z`H޼N`.]D/Wyow6QYKk?krX~r]Қl!`ݦzꖅ7)Grd>y3Cs|#5T5 @+F ~qRl@@eV ׂV$!WX*oT\BZCDFN#)^\ťPZܵ.5 -fuRm`VoqAK3oqAKk^\jHwqAmIRa'0A][5.Ax r-Zj7 w-Kk^\j\AXj\AXj\AXj\ZZܵEP@-wm oqAKk^\Z ⮅V5ȵkƥk&Uff0 ;bi,T86K\+ `ָH7N2k?4!5p-*Ard5hkVV#_ܵEPC"wm~AfmZjA5[ŭ;T3?K]*,2_rlL45 n3T>x|/ǮxVn>|ʧm-pX5ÜkVe^4]MO\(fU-H w@Jy}_2s{AvtO4#f^ZuAM44.8FlyUEN MU')3iwn%r9)Guڦ-L&hV` Ms~ưuM_eA֬f)| 6q[xmYc0%c箽 )43[ ݊P4YSgYMhui߭)_nC[KR"&zU]EW \x8|I߹V5tφ.J45R5/qwqq϶J`;!6M۵^r;LΙu+cmՠ/MqHu!h5]WT? UCN{Yr;n2)c($?  $rݺN=q{z*8 +@oC \G)y"37t)xؽ^+ÎcDBK^ŷ=Ǎ *]TqG؏kt\E_7Xrv/Nn$t<.~K5b >.'YoY%P~2*ܣv xTIx|GuՐzTR ܿ}WƇ٢0ߐko?pEozJmtLpxLT?+`6Q B _u|Siw<їZN˓Iy\N˓I$;OC,cj:$d< o9/OrEdOrX<$ghd< ̗'y$o@r2'y<?R .q5I}%mH`|J~!x|tJv5\d޶!qT/:U[l c*e'ux=N1(x;N1(x?N1(8N1(=//ːி=N1kmn ]ېP$<~wmlCBݵg﮽ېЁ$<~!aIx|W?N1("8N1(~~_!C??Z]]xR]ܵ 7mH(@֟6!IXڳ HsmH@֟ې0$'m(x>إik1d`o^N\Q{n$.A6r ڽ((uHFu HHϏ@_g{>:F 4=ۯlSD?ٞn.!`Ueo@֟kpJtWu7x9N{}K;YnjCE u >{{yķ/|qg'pl"  ?{w $a7 ??H'q@_'w =qGfmwxT;֟=;<Ϟq_viT#T?HCqh@֟<3E`LL1$ޏ|!v/*l'8C(TNqP 8SX?q$ǙIXq@֟/})Kg$aǙbIX'8C(֟3"a;Saۙսϗ>7Kg$aǙIXqh@֟/}):Kg$a=8ΓCg[W~ۙBѾ֟/)tm~-q$?_8S ϗ>H3E|Lс$?_8S >զ8Shw'8C}L3DcKg LCZDz]}LAZDzǙ4ۥǙ4ۥǙ5H/})e'8C.~Ǚ5H3/Y՗MkW_8Sд}3MkW_8S4|LA 3MkW_8S >Μqi j?Lќy~_}Lќ شǙ5H/})hAZqiiǙ1Xq@ݏ|!y;+,'8C(-֟3F@'rfK/gn|?GCJޙ"*-IXhţZI-vH}ZzzS_~oH{|OGg]qRݵgǜt6^6w_w=/TvIWjURKxgARxk o? $8ۭBWGW2!/{LT_DIxmWEFz1!Hwxm8cBD7=&Id|'tMy .◐.vP$2 ᅴ#I%m;SHI?N#34G*.n~|'x0MԑP7h,h?4X6Ϟ_A2HWJYsΑ^ZvGU[%%徕4v5H81S`"?=ɢCnJV"%ܼkIؼwj㻥G͙H^v)@˕n+ m¥E"?1w 4m>N> sF,˝p! Ij|j7JQ Olfc Wk&6 IBW4v5NrBzz'O'ʪ.J(M^oir.%9O᧖^J[9KID%Wҏ=5gqV%r vVm"-5׿3"^ƚ\i\OL(uxÂ^Ocu:6L[wlE5냿 `lPîZPopb+}VbbNur2$#Z>@4a0RagHp;YBq_WXYw}Ýֺqg8 wV@tNVne Br2.Z >A'mv'edX>A'r2p+g8 P  (Ywcttcw,2r2p E C<;o/#;'v tkQ*,w,;an}ÝXA>NX,nB^FmTXk`*,w,oW2SΜ,Y.KU^❟G)*f3_*iNdm GvI>Mrn]UB~~k~ZGs7ڃ@YG}ËJ?; ,*Nc Y?!*UYֲ`=,hB eAB քF}V͉?t$J%R )~'N~'Sm"'j;isRG{I=b}hHU *ևր$?X>Zb}hH{IZ>p#Tӈg*ap#֟zl>j9@TIXP>| $aAG@>~O6܈i3k 7b|Gi~h7e:IKB{x'i^v)>Q_k9wyo[ݞf]Uߩߏ;zbF*,O39\7KZT3]h%v/K2RN{+jvIXfM5+@֏YbmS*D1^;zb>uM5l|!?;}q9^j?4؏O{f;{f8.wPx~븳jqgՌ@w;];{fTyUzC5#J"wP͠?lwP͂㸳j39\aj39\aj39\aj39\aj39\aj39\aj39\aO39\ao*}"WN-V] s+|41w?4ˍ~kݡpWX̡pWX̡pWX̡pWX̡pWX̡pWX̡pWX̡pWX̡pWXpW8>lpW(} ƮE֏rj0/c2T61 xtR 9T5!ZyQ~.p&zE0I]LU$aB%LRSIZa~4 +]Z)E~tH{-&G6U͸#۶B&H" l ?T5A~ "/X` l ?f6խIf]V$Խ7խI[6խI T5A~`%$j$|KH`SՊ3OH`SՌ/,6UMѯY`Mu+@֯Y`צU !uMuk@֯CMu@/,6UMT5A/,6UMzB&Hcj @pVH`SM0 췩n2Il>!MU3'涭 h l n m6UM;05j椌9!}Mpx+>ml~$ql~$Q-{" H>7IXׇf l~$a]$CpAs}n6?6 g6A! H?7IXf l~$a$CpAwn6?A! h o! H+$! H+$! H+$!y[W>mx>إh֟YZ_Fgz^2Z\ե7Z?lgCK% Jᅱ )Z.]--1QN]I׾R 6sqn]?Ff+^$szO xjd,O7~J>5|7$G/tC.&BOw zjnWtCAצy{'`B\Ӈ\;qii jOZv+}e>4G W{J6 jIX?Tir+=[' wkIH 4 p-&4n(VJ4n(VJ 4n(VJ 4n(VoCzPUJȧqCz<@߆b4Ol`׃|7dӸX=*%ӸX=*%ӸX=*%ӸX=*%ӸX= AU)! IXՃRB>Ճ]iܐl}ObObObO߆b۱X= AU)! IXՃRMcC J 4n`AU)TgCzPB8oFvǪ@fC9&]B +N.Hq)YWR(Ip+1I\O̹R }pN27* ͷfUpcn|uVVru df;hq(mv.mg]q$fl*{#b诊ZZ nB>Wfb譄h}~#lZ}|8WUU*qKd|ƻ$L/W_ӫSq\~mHgNz)DeQ߲v >:2M7g"/RXzDPج3.%WsP?\x bBrjRu*3ZuAXl-O@v+g9Vߵh3_7{F.gU,6N-k2XWļ}_R1U*O?" =z~SKpRx(&kCE r-7E Ac.(:"uˏcҮoŇ S:!2Ofާ$ote<ՋR POž -B\ )mB`Dw|}i:6ĥ/N! ''i Mo'dRCN |dgRNictf*)z`J\6~V4EUϊ͚*qY>O.J\r)WEl>NX l,bq ƪU`g[S0V%?}*qYVU"z`J6~8cU|eYVTag[SXWEl>NX_6~8cU|eYVUag[S0VWEl>NX_6~8cUxl,bq ƪYVUag[S0VWEl>NX_6~8cU|eYVUag[S0VWEl>NX_6~8cU|eYVUag[S0VWEl>NX_6~8cU|eYV/v `g[Պl_V^YY <6qԋՂ VjX.WF {+Vw$X.$Iaz*H[CՊhdu^ Зz"e ?|Dv}b-DgȥS/Y1:7kI'yf%y hYfT~ 4 ԐjIHI^8Vq-JH h2h)Lx!G*Hωh =#$oN4DHI׉h o'y$QN4DDIXhgf 9J%$ ; IXٌB?}e&hw&]ohcкIWCRDh_ܫkT6N =ivj˵6vYQƙ]殽Vw~K\hDKs2 ^ѶV44ch[ U]!hm<#oB%YFp\+n W?IK&H";<UVܲmj0[ª=MWȴ3}O+?CcpXuVּ4?]$[bm :!j{=v1/8-:SP<n,I2e &M.楘aTyH IzONlP!4n,T!IkP~ny.3- w;"kЉxq9%߸K˽K榤:(C̏B4ct>&zAѭ}ij΋ʲZ8agT\h]$ \xPσF+OjIHcUq'f!DS\?xK Ѫ|Yf VʵǿvZ;E ::d*WaZ_g3»M ѵq)j袪K-RfiVo w߮ cIȊ0 tkCoȦ >& hZaCvq|VHAs-M0,L}3ּ~V|Ŀ'Z7r%|)Pf |Z$ͩ2j$F&uz3NM4z%")|Zw|v]x[~Ƕ3~Wa,-j=mZ0WQ8҄'aVР#~ut\2P[L 36 _U!l@\} &}>UUEƧU 5\RCa|bA{&5! Bww%9= pJ3=pr߹ -Ԉ q9t˪w[uAVb=\k{}Weh/';<ߨ/f‰G}&IABmL!dlT"V 2YLͪZ4ڐq30b:MV+Vu7^<5~b.y]l(ͷNNپߣL*RZk; ӡVK5ヷ[5%'YI "dzN܉xeM@!әZ^iy1@ ~~az)T8~f)uqi*,Q*A#x=~aU>>| St VyrYL1.M@6.N#wW\dᦞ-:/$4d匭Vlũ]L[t[Ws&z'NHwt?\_6bȾRqۊ3 \nRkg]$JW- 5Ԕhq-tUd]8\wkպ I+PV.Hr"peU_VxUWɪ\c}Z+djwRkZZ dm +%Hx] Tϝ CUe/Nh>Nuzyj -=vq9khE,no?0=5qྫ4S~b.7("KМ2[LA\.ZS& l- ;\a;lQQhP*~A n΋F ohx| "x1ԅzmrQmҴ jC>2yh0RMnR- w[2>'~]AzuO?B{Wxbu! Fj dWOD}T.hؙ$mcL4gD]L$g*ۉ?gr}G? aT IGo|Ԡ{&RR͛{aZn ?ViI L+RViI L+R]AV$0HK ´"-:mar L$88vI:8FޔJpda mIXo9BQ{:f3$J|Klaf@"\{+ә)J߇sI׉rPӇC@b>$э_)K *>$'R9C-v#6XV|cԸ={ SM=ǔSF {CzoyӋ J{ \7~<4/w)4 x;Zx9 e*MVUU_2tN@zN]뷇COaj S|G^ri|tR-Y|}J7HqtM>U? at2๪8g@ Zd]뷠qVUW>プ@#GѪURKLES^-Hk@ Ⱥ:yH>ESΒC?]9bXܠI5Ovpe [,Fl=uW_|,.YwF_qIQYk}swjo#Jc"Fq,`O'|a8kFqO=E>zYk$ =} XR\_!:0K;Df1K/u'-ʺGt[YYwqcbRIl鞟YRnB/b_UuSeR*wsG! ?{(ӐK%Jvn'.xvU1V㓸oE?;0D7v3Hhu!q s0 ^aQ8k8}sܘ/Y׭uL %ݽ5pFH{Z}S-iyl*΄wki$ / Rw4ŭqjQFOQk]¯f=jC+W+&uCS+}=CNjqj1Yu>LJ&Hs$O8;Lb7l 2U? C`ճW*=aSpRQZ+dOd +dOd +dOdS=Ճ U\aS`$aj=5pfL}Ly@?#f!T9-܄@WAleދpXf85E7:''~xoGUï!C' CkD> ʣd{㝗O9_wR]߿%CdUR>-Ov^d</) * · :IX#)0)/Q*1{ӂ$z$;IkAֿŝR I-)~I$Qʜ4Ax=I$эʜ4A"XT& xjsRv:qO,*sIX?N $qN,*s*;>װ6- $am[8m Htp%Iߦ6$Mw dl[8mcQ&H Mw3$Mw 6-$am[8mHtpnlMw mIXN8tpP 'YfN[A5:[X}ic}›߾n@ߦV$Mw;QDL;x٥Qa:UĶ\kjڜ.}(J?Eam,FכTq衖 +Q"%*VJUDnz"Zɮw-}5P! Xi~tj:P?܂p1FDp'!Y,8r0@!4S>ش'p@R Ni3&Lk{O$CR ?ߦpKJ^M5Ph-¡e(^g#S> (ЬIC9ƇU#KijB"K?a:LP_n+lTᆹ%:AʫE?3?O@7gV<&n xq2 py2>[;Qtq*B }bb}OS}F0m/.q_3Fyx!27i!6G*CHpE섣]*\TavŷowwcJU&jkHkP?X,7^[*)baղxm$ƎbJk^217ʑ"׺\FH ޿JzS*!%mxE_(NP8';hR? ٛSC\ǧ&%ԬI@|[BIw-QqWvФ~+;hR?Bz~KTܕ4p!{}&.dD]A[I D?I -QqWvФ~+;hR?Bz~KTܕ4Oz~KTܕ4.}=%*씾weMvJ_>&;D]A׿?IN,QqWvФ~`+;hR?S ETܕ4)}#*lޟ&*섾}weMS}weMꇗMl: duA$ԩIXԩIXt(H$u ճɞ֔ ]KM{FJawlAV =i -HCw=i{hv۝5>o}wmlwn㨷lwnHMڻݹiZ6N܁^i$;.UOߍ/Aל≝R.Aڴ8|A>ׂ$?jlwm.O2p> O6+̓ݭWU? _]{J`wkAtM8^%IiݛAhno)g`mpI1UXV.pܐC}<8 DAVxr# |/f(.^bɥW}Cktɾps6J7~MεkTQ b@c2Rx$|`J4 w3f0.H"$^~i.~1W&F"} +״I~3~dIORc@V|-|Ux\$]j "1Gne ׂ .M/qi뗡+Sk78hPd7W'N,oF8(cb|qZѝ_ U~Xp;b2w׆Jay_OJ- v3o@C烷 ^w`:'oޚ J*Oϡlc|oJ!?b8ϭ9֬*\y㧔^<=<VOȨήj1xCzQz$Q/3)T}W^EЬ{,.=,.fRgUTXY!=p2+P`MX qU$|gMxJ)=6Rk%w\Iβ NT9w%g\?[?w;]=\sS6R+W/ [_}j5@7\LOɃ)p"w0\_&|0!yiĹVZճC4R {_L9'y2S>ɋ̕$O"?Um.M$eί.no?[ Ə J6~I0lWm|z7CQOJO0t֣/yaN$aFe4o}n4M!o!*?g>4yRkp̕!G`KC$&&/hn~V|g{<L8}^!{? tݷSmåQɹy,gZy,\V Q`w-*NJ<.hO ׽!FABt pw3܆slr;p tfyMoj| ؽcHcȥ4/]վmd4_}}sW\zS*ܰs|m $J7<Ð]5R {y+SS3?fɫ[[|KZ;.xvU91It$uAs# H.HySe?57="% ȣJ"֨Trye4"|xz dp]J^y84|RBၟwnIMj &[4V| miz?H.-ViMBzgpЮ jJpҾ:;x;5* Q$!~rp2ttVhU}ѵ/Bg n[OϬ_g9GQ8_A?N3T5eg 1ZJskxxEG #+kؚ)q'+K4 toN.,w^mY\zG^<Hh rHTBS?o WIX MdI!,$cM\$&04.ǯ/C3i" M8D ܁B@}c&~&Ҁ$ MIX.Z&2$'Ey$?tLah\yиGt/иG.04]$OLtL)@VL+h[^&҂|M4$-Ph"H !dD ^͘NLZϫ\Z3nr0H[?.AL3HB퇅_MIoC&RMEk"!X?x!:c|R*acVU N$9U_S~_0PS+!,V 'i|>͹;ip7'"NMjB8q7C/B@&^_ o ?po $ OF˥uq+iK>x=H6!1+$7dAxYZ}qI 4$?7aKreؙBkj!D\ ~SUo13t^xPIi}V OZMVK%HCI ^eB4m&*sQ݌JB/ ȸK%574wc]wCl$us*VS$yv!(qR;^科! )N\_ IX>O &!-|U-igZ]I&NBA2DJ]uJW~$~ɶXI"V7MzEt$gx$|^(Pb7o2\1# 'yk̐ڇ kZ,h_$"Nk'l|b+9)<>_;)n KÙ{JdD&DMINW:I,-ɲ?W~.p 1btfj>B~H^3/Gĭ3)P'C;\|kg> Sk|ÇWsjVO/Qj÷:4|zm ouh=6oz>\[ O7fVSU~4/!?ؼ_/CKO4Hߧp&㬅|D?v)>$vVCCӴOaIS']JЪqbk ׽_ɭ8RULDiޥ*!ȿWZŵTJ\枨(Bv) 0*jwZ=SZs=VM~05W*{Vu4Q' O7Qӝ{$vzj>$>x9$ +O@pݾwU(~~bQ`K$UwU"U?uW8߬Sp%:a/nBXz-y| X Kbz/5V!riKCZuJN;8UKou8Y|y:QOTqQƉe+94U$]wh߷iUk)s ӮUsy}]64bH}]jLݰH] U=07 5c@*+}Ak&W* qrj q-u?})O+*֏\"=+?_C 5{pRNקhm(4:)f|Ҿu~YanHG5cVT$hMIX5cVT$XMIx5cVT$[eEy$9e㻴1*E|AKDu,V,Q]nx\+Y܄Ny0VDuQ$)Ib.3>IE`'Y(_$1KTEi$fH0S>IE`'YB(_$1Q_~J]ONDu#?IE`'Y(_$1KTE$f ݢH0SXlG}y?.Wr}.b$fH0SX?,Q]nKk|%1KTE$fRxIzGB,Q] f o|%"LaODu)1Y,Q] f g|%"Lo|%"LaODuQ$),Q] |ODu)L7K,Q] f $1KTBLODuQ$),Q] f $1KTL-,Q] f $1KTy"U{"Qa'1KTE{?IE`j,Q[ f $1Q__IIX:\{ۉH]P*EwX0~$˛lMvy? = Ğ]QSٳ4~w=.iڴ~$ J WXrY +In'*v7'Tf'3jᮮ|5M-E `NȐ%0՜ OZe;=+O|C׌ {mM,R7sLYl%t͖8L2vwXiDFB=  Ӳw5vjR$sZvZ:k'56aP T#F߶7i?[7U%6.% >?k##\Z1n7 /'`$rCuZÆ 7NSBs?H5lxZwjai*H}CodDKh 9HN4+ $?bQֳ?pIu:H/bQֳ?P^N@X̉-6V@X/{ vTB8a$=' $ɄqnH;w[Xa$7[3T _fh@SؒĆ  f@O@ج$n|Y , \mݥ I8简Y+P}3fk.=$?f}a5 fk$a57+]*A ckM7's:sD1O@ج |5N`kt[3ؚy5+__O#|)[f +NqR.Jw;NJ{?>x?NF{}|q;Hg;y}W+I;,>x>#ݑtiwVG~]&!֊~kwNu|8m$,&R YvĿmlHh?Qs;$V]4(T. ~\.h ?G »w_~ՃSkJ3O\1Hz;VXBpW+vW0I`&?$,R X©ua(ҍH#TCO$}^P!c[WUJDOwq)ڃ ɤ87QFm8Z!2NrЊ!LJbƼ3 ujIVaH?TC$H:$hո4L-}߫jIԵ]KSaerqMouC&Kt(${ǒ6~HNrL akTץArz͝=(Lv}&LL{dcH.Ji7X& e?I$RppiC1jJ ) G6@+ |3k2NL;R#c@h?8)A+x'}0{;Wl51ډyC:mCAhI AW4'1ޑp!H2 9q/MiW~}1$84٦V D"qjʛ1ZUzRUlf떭uo9JqHߖXj-޿މc'_?SVH۪MfG;.-Jh' W4$agEqynMIHvmeNIyc7z<3ތLݟ̯43%jO̯4k'u&pVT8=$fQ!:<} NU.-p~6S_f¥$IX$s|7"$Q'?)?!iUM)]S'iSLguC=PMv;|x~AWܑ;O?I8^,m'-rRT)πJ%8r}uEϭހ$?'tMmg+C'x>L;$mYpnA߻R YTPq?~mXFt_U_Qv'*+PTF?XZa#:|`E޶}}C`U!tOU$>SߪA !dh9CG u$ߺ(R*~ #?o=.V>4_J%d?1?$ P3 ЮֻaI|͡skLDnY<]v !>OڰqGnan?ZYהfӂo!dQ^>yUךZwCX-Y++ݩ߼(t-@%l |[Ecj]؊=,n.Z#7V[C+wxf$,}IƯc9'^yVKY9Z]*lá}| dq~8IJ#xqbE ) A\$ϼbE2 ) A\$Pa9IJ?cfT ȱ|) 1GbES@,y ~Dz hx͹ }8lup,.y]NCʏy>b?XgE}R񱍿?R.V ,2qJp_ρ0Z) U>H_7@1gP)(؀$9|ֵ;og{qIzϦ ';V<ـ L̟Ƕ׳_u*~k~kǨn3{*Rjf?Y*l{2[Np?Fw͇U!TVe⮍mQKBfR <~Zş](n}AT1-C !( mo c]hɆl7Rwf^ml%BO8\@zӉ]K-ݪnޔxW ~Sڵ:ɖ4x‘ o炝ZSHj29w5CS8!o?Ar|v?D4H-:|(<"XOC{ZoeJvOlYNj(xuUk?O~tfT .<'q4溈/[ws;U6$<d/=Mz_ 3bNV}F.or#l;F5A=eT=3yl5<誙:+T~ͦ2-x [5)1"q{z*¬oMF׍sߍnp.alZlE 1#/o"4b2 c_;bա%C'@1>ʼn OꗄO>xM1;io w9^gAb= µ6./窘Zv03˓oL`+-Z$Oh MOh MOh '-Z$O'[_~YK47,^$|YÛoVe { l/ڗwcQ &Ͽ"1L?`Aq{ e?v4[vmJ`o?4IX ǘ>`gZƴ{p,@D?T+s &s&F^'8oG9,I:K6+9'@w$aɬS*Nd|zӜɝ>>xߥꉹ7: A*1Iw\O2x?QU%dLwk( ɘxׂ2?Z/vtǻ$qdLwF2;5i1I'c] 'c] Z͘xׂ$Z0ɘxD'cz] "2'޵Ow5P1=_V'cz1 ^_1}þ?K j$S CDmo3D^ۉh3$+ YćgTXQ3q!tf2#D [2&*>xyTN=Ⱦk{__l΁j5NU2'vV`wCd7oox͛@+^'rf+WXK7ox/@+^9+ZiC /XVx4 /XVغ{^_ޥR ))o2{߶4Cf DSX1;3rLa= lE5 w6f04٘^9veL)3L)~6>̅1qkq `rsa–&wvɞ>ol4._lMU)3{,~mZǂG~: Vu5xm2^qn3\kÌ^n, 'T8;l/aӉZ3A wtZnۖv͏A|lN-߶F {TX|[Jc<;|I4-PliHvL̆XkTK<ߍ_JϷ.RlqOrҿԺ]KZNz) ׁ$~;ی766FNK龈omyi9 *UO|Ab1Ka5dp GAn(hvZνwUjjPNkRn[ V_Wٱ r炩Mg6i8|mlG: TAMĖqm_lwUлZ@Q"u*(ʌ;,ƫ(W%K?t^UUsZ*Q^n$#ZƯ5(ஊVN}:DߟvJ|U]0>xu*W^"fQNeʼڪ}a}RՒ`|HBz)]| XmʕJk ݴ{Y]}j| ?b@bĴ?jU zmIXnn3vG7sҲj?yRĻq@3 6Ah:@K@G/1/׺]]ٴuN*[?xsDa%j?~S'HZʖQɖg?PWsAR\eHqHn>Rrl悦b Qf*@a7'f~8tLmo*=paUj|j ?/vӔ>wNz3Zƥ fspW-ԒP"L\rG3Hq*;*&KqnјeP#mWmVPɁARS3?3t}^h0~:,7~u/X$-L˵{eUJ~.HJk)mDKio<ů`O 39YC~ HUNL$F Znu^$zl/Ck%9j-Z z;ZN{J q^7AO|_N(o}KH#x;OO0O(~$^p xz$|$ "ŜP'HAۻ?+@?D5T)$HyP_l"MBA6D& ϛ$?,MBA_yN>o "iMBAD& =D& ?l' wIXQoo"^wiTÈ7 IX7 IXu7 IX94|o *.7 IXwh$$aI(Hk{'MʡM.J[7|w3wZZmJpckJMboIjz($7dlQK4q:_M.* 檜qZaL BB7Mwh@x]$?}[ue8D,JDjK|لW!Vzo} m.f>]> 2Q׵k m:ssZH'^u%~ph{)~4@m#2mkUp7q$ЊV:^viTBh~kwPeHG~JWw) X?D?âizGϵƮE7N(|ݗORr]k\k'k;>vu񶣬Y J!+_W`~%%)HdK(|s%uf@,~ _IJ KAeO<+C~JX~J;Ϯ4绡]EP|7T+PMUĽB[φW&RafOR'k 27񬩰Zx,w^o9!yKWH$d!}C柴EiL/U֥<̲ھPK$7D^3I9ᛰ!CpAJפTRM$n "I\If4s.V}ߟzYfb}qw~7H R LJa3R!Oqf :bRa8Mݸ?) QA:cCo2̏(IϦNtN ?.|ՒѾWRIwlf( ա~@8 !W;|<75DIaU,HO uQ% w mae(hnSzCQPK 1ujoYxE\jj\WӴI:UCWi/wkzW|/{U;pSV]K+_RS7BBq5E蟟WꡋEBY_u}X_ *eɉZ_G?"׺R!g._ ^~b0DC3?..g.gćK8+PJ>8'I|I_;)8#DK';V; ME ⢎c0 ]IXڷie6J%pM$w<>?.v m{Wsm ]LdlI7Jr]Id;T]Jh9Ɗ?;vcUv?zqv?*?|1hO;9=C{R?UI!Dr7 s{\doFm$;͚$>DU\l&g,Q§pIs"k|nKUe6J%}X3(yϘ|~|>cJ'?$%-gMX=?$ܖmbw|K68 O2$DvD_HUdɌB'[p' ;Ty/(&WS[TA'^yB0(Vs-*xàp;Ds5Т‚hU, 5^N¡ouz;vf3r( ,SwrHw/<kYE_J oJܺlSUw[mAUi"nS;6έ_Wב ; C׿Oc/HPydQ@|Zv _G'NmEI²a'g6c'g5q N.%z4iIu3lZO^>5-f\>ZؔҵJj$$!N$Fs_xMVE\1(l[/1}Oh2 eZZkHdǜze 5u4#wK9o ;(}6D.%U+.+ K^->&[zXMIMm=[/y=!NX_DH a*xdp%eet?-n!ʡ D7bJ}ݰ5YDp A4DM»!r8^J˅kvaI+\a:+X5"DK/%EʮsAT {u? k:n{o{hW5`?0* .|+x̘&Zj}V~K-% _:8T35kB U2Smq11uS~GOB-bUȼe*Ga ߆:H$*"kW©'ڣY+&arQS "1kl.NhG-tO@WVkFM&]itR%nRB>#75ԸPC^C,+lUZ-:=~g]gv%,wr.GեYt7!pquw8pY{j-(/ e!jV\KpUQSe|j\WQ/15f_Fqq2x8dzFGӗ%ōhVyDq<:&AT _vN7O z(^EP@3EGw9Go+JT#dxէE!H!HvSMn/@//Ǖ*y1r_vD W0+38TH#L9甝 QɅR$QuA9Nu48 El KjXa HP:=t@Z`ՒD fv VWs8A"{P y$:AKk?_|@H\4ԨP5u`GVx޵ nwxV0>A󯷾PL4$TͿPŮԉ o+*$WZ]zxs+tZڋW<R'/|ݷ*nx;/nQRzm;wRGB[qTb;)!˹x:v'WTHթJ̸x:q'WTH­wMf>u3s q߻&SSBczY=$<|Vd$$HuYenZ8d5)6-|0 Q`Eќ:&Y4 ϹuRTY0C3^ыaĂB!i9AP"x V:&*^P_UcK Vs/M( $zjCi?RBVR@ JjHH ׁqܽ kŷ{*~~kw/y;©K-TR;=U !R! ̔ϮΖ5%?v;w!G>|jٲqƾDǹe 1BΖ5ăΝ-kL˻Ζ5CV_Ζ5CE>w!Ϲe 1BHwfS/ Vjo!2NBH 5t-qO]Lx :us\|b,י,Fv~(SI9:SM ~GJ#K)fj"(ƒ-cxNN& fݯ;D/N,u7ZZR!{kh_R!$\$))UEB-: e^*G͜J٨e.BM%=ȑTkRu^4ApneZ0SUaW $qc*9'6>]kW'̲GaM;1eR-P(Ҿf9?Z?ZkibpKLg.ɣ~ڪG|^2̙K;I|K:vWrB HofYeO:!$uA_GI4pH4HQ5Q! 'Ϧ-Kx'h>NAow☉7yP!Ҽ#nyW ZG_?QQ! f&ĒG@uS@QM- _uʡ#_ٓB$?EzWb]/E³CZ,>?uIDZ&}KbTf$vi)=*(rPtß{֟ ֊P[J8E_8+NhAEq>=?‹!F9a:brFY:U"e$.G><@bS-Xjg՜Y є()Iɔ} OwV$hN="nH";$ݒ[]ݿя0H%ƃ2m=>rc7A~#Pvg HF×2jTmWAc&s?*(qoh"E Do :/y~,:дz( ]OuZ-φCZ8WTSJv҃'p`B =P䖠z g286w*J?ʈ%g_O},s}P3#/R YqE(*y;=?^*4N"#dNQJf[9$pQq#~Q;AǬGB)3u!˪q7|EKl{r;rƑhHpU WXς-L؉EERsUA& N&d;y5q,<. U:3qRϿ*VrK*HR.;Z[!E_) c1M,GrH;(JX\Ư z׵O=< _iX%Nn^Kf lZ#U8ڎ89޹'\z׫YRx\;;T z?.  /Tx8 L`MZ dڅ~N0{2k "sV"' kk%/qU6hI>++C4eKo uIz۩5~֏J!6? 2F?)Ibu"֏J/emj^Kq4f u9a1t:O٦19V  Z~׊ 1['T (w*{|FxcՕnyjI5we-IWDnf[~P123FYUPuABxPߙ=qBi{E[!!N՞M?Dz{%>tb>s&&x)''վg}F2÷GMIAӡxwIPzR_U/pԲ:~OUBz-P(J Sy-+Bi#*<~/>= {MS_`S/aVm + #3&.l,$K-]LEKBc8jn&n*0$}KR ӯ>؜U,ͮ_5 ]4'YTeĩPIu%uZIj"exK|dՠաAyO.4y?M!IY^Oz8ѬV Gq$>) pKН/dd oP+o'>o{{+t(IVNG<La=uA/TO?T /i>ʈU fC+T%7>>9s%٩+UJz[HՔ;ICG5{)k:HPHEtFȍlzJR YiIta]LC]˺**%pA ,׿ RIPa.wpB򃗄Ղ&+©7 itנjAi>~_P— )#.aʦi uzGzMRUx=B2OD[! McsTZܿR!Նb@gbC@ BMxhIa'd3Ejk%KxewjVKjƛ!F)_WTT8H?$`4 |&NN _ ӄ9>tGK>`jHQoftT*TH+]H.TLX/#xU!Gkw l|'ŗ&AR^Lq;s),Ytzd56͊I z)S7J!'jS~x~H!CVu 9煏Ki!%τvB$PQ 1'<^ ]1b8r|z^}I+QI" M*\"-Bg&(̛ޏ3e]B‘RMm QHYΦSG' # njVyRћ T#Q'E(‹KT%Fm.oBկ<&;$)+"d'g|LПZ_-ƨ^"R /E_+Jo1 X?%PZi"9 _UPH4 Oqj*,iGӛaV*IO$i!.")+/{:鱀bnbAw : ?se?*CIJĩ5mί =sǡ_%9ׄ"M욊ipr"e$NTuuTN:WxM[_2~FC<ͤ$Vǜ|% 'ېf#KN]ÓRF`1:{xg!LjzxPABփ>jjz:~NKTXq8v3!{SgTk;I[طPi&=lWKM g#2y.RMV"%N!ŭX_ރ 痂aj8% *3!֨䍫A=pQ= sj4'K c&V›!BhErT_6CIABMH4^P!)KM<]k%D\ToRuB_+| !@SiT軘^[TaQ7AH4jE'4}}Y;p\e\K?0A/ʈWT򻔹R}=_C$=OD7R.'>-cBu>2VNJԔ~SdHM Kr^B /MzsCMͤKu?ݗs._yB]oI)SdV#ih$Hbe1RN)iM' SR˜is!NTlU-qˎ%)/vN-.-苾tP=e^,)|NB'Q D%Z UubˋzP= D]+8CWM_a>V%*^Y0.'ې_04HzOC2Kܿ8*>aj=j)8&)/~K\U͞ dƕ}iM@┇8oJ嶲Wr qVDt!zpg;D3:NԟBZ94|A3*LLȎӵ#w[Ov:CER,P`9Uܙ;W&.V'0#nSLRd4KћT]QW>\̹:Ox~fƒ,9S_RcPx<~(ǣa " b883ZQNBГ~΂wP%AE/"1Uq l8^"ZD[B=Hp.b5hjOAH4SG>Ί@υ)wY ۤG:HK4 ՓT_> #R1 i[꟨ish|j?i[x$M^?V 'o1^b蚤BKҳ̛}K|vI^T*Ns<^ x1Q Sހǻx"**_~yIJ Лzk!CVC/hG{s' jzRjA}TQmvS;{| , aQPM*^Kz>;{ASPSO6MkgרO-EUwJRh|Pt ~֗ !$~i1+>RUT<1SdG灥2H]kbѹChjDruʼnE-3F%DU4Vg@4xPMf AOqW0X7cre4#ƪg4^xI=!C!B *z_Tb(G% u}_E? wvC v5HGTIpJO%H' c*D4RK)*$z !{Pj3>Usͤ}.Be?e#GwvI!zu0j8W8I_Q+Y 쩉{~/[;^\%͉ꅇMp=`(d@lmV=5A\v2hTmJ \/Өq[1~ uݿcK-.H[7yuG[-O 팸hug+DMܷnM woR'vT鿨=3յ~rO]BF?ze,kyRK[ZݗG:Uxn5=O6ZCyNyWrBsI>z1LqK^xK9?UO)W:e1yN,Jտ:ETbqm ipX zL:2}YI5+cn q*Dbj]ud'+N$L(wSEǑj'ڧ>&Q >T.|uIz:+!NFYILJM=jZ2Ijt% %^jIIod5l)ujzi|꟧Wڿs1GNnnu+ԖBw/9 rup-G(W!xica Q64C0K]Ȍn*jYU[ !PST*$Z]|VvC V/ux7oE%pa 5hjKuSJMޤ-a :%@lr)dN\MԉBlKH݃IwѰfSdBUg5đpp_AݠmWd7tTH>XSR^%O7&!э#pWMuW 8xtYMT{5?[~ԤH O2qod}]x\ qJqFe"߄_Q?=0^?:CYHxMumT`&Gлz@xtJ.|0lg _9=AʰkE+zUVT=17!bOaCP/U AkQɅ,^W쿞4nf Ayȅ/Cr:=VF_-*ƏP_Ca}h%B)D}`J }[x_\7AEmA>uͪ u]"`tP3v_V"/qz*ENߦ&sw&E.oc"a'FBq*X<M`ƹ$УR}%?PQ0xb#)w "J};&HX:z_ &-xnC0pD 3?Wm#cv BxlsmaC32x'Թ5rq>l)gdI=!.d ~ STCTqdADhw^|:a7Nf R&8CWk>nd\DI;)Ѭk%Y΅\R39tN^U8G3!ȓ@gT(8ңU\pOQw{TfyEY}ɿyL`[RB8f) #X^7 D0#K~Yi 'TГzd^M J'!;0# %HOjVIURuե#tlJuUQnYRkQfip?UQUcNGLZ b SɀA-%(9S]1>Bڃ4FLSUQ͇7$WE’$. /cyoA -_["AA(9`.)\ɵ LKq%*A¡o;t=q)<0$hhܲHp$?G%,yGVͩcOX xtu?8>?*hǤ[RlqB#'SER՚ЅЀ-VN@b:*^r$[G¢L8{,(b ad!Dhar.+*IHz6JT^C(AcЩk|r<>EQ+YG2sfPumCvU|ߵCz:,JѼ-%GCf̝)pKtڃY8<>PI=יM򢕼o V:+^3N<C*E#)%4 pi04яsh9VA5f#U}bn!:NR0{yX0g#^'44B$jB (}WN>2t,$6¹SQ+.{ L0 ^N7ڠ>!˪@}IfP܎!=ZֱCU/PSԵ ո%?lS(! /UEB\j]; پWuH;A1Vc, {]2-nS(%+!$lSsь#IgԔŽ*΀'7{B:;oAYY;VTCTE=+ &N[d˫ 8u)(7\vFeapK ;; Y57.wX.$d 25e $)駨lڞlF州t ]VU7Z qG1Bs_E5 oaiצj?EDgQ A”łrh?R G R0z5qq;]㿘 lBXa3;/\TF  c>k%5r8pGTO hWw[=Y$_I (BzTسUv=ف?y')G=$JVb_SA \+r`J?@HܿЫ5 B?8OcyoLbmCs%w"o^ Zl,- VEhI|(0d!9xKh>xacl0r"a*"E.=ԛf`.;nu܅ZdF R5҅;!`9 $Cxy!&T yλzy]P5vw!8"WU$PkvUǿu^Cr@H-^59Nbi_iG {B+EP:ĢD+UP: d o:!5 $u\4PA@vk ʞp.xӢ k@%)Ə29>댯f-f.I1~phK wD:xUnIa&M1*%!|}T`}F~B ~m+pIpy(d]f%&54f`} m .,_6gEMϾDOTETE’ BN_:ti-VO0m!e]C $S8ъp9l# q8DS坞]O,[zoRp"ї>\L #h xA ) !#Փ&QM\WȅAB_Z yrtx0I7"};i q{0YZnD^*w*/"8RnF^RdhF{ںA3 g>gOwQN[*LNzpGVk\Ƨ珺Bip|hH}RP[Ov[B7G/ovIJe.h09B @IBTSTEχFTn\i|Vf(̓/_JREUKOtד8&GBY}KuET8~u_go>|ȷES ch8onjSIS4Ur0s}iV8 ӥ+ |~:oJ(? |f.Bg]:ѝKO6gmASǏZ=."<ڕ  <5,p{19hJ*?{)lo'Zϗ{Wr#wBS5O͚ j9*T"F]<}I~x]sπInE*D)S?Q g5UѽPHьzT<;|/BSmڡ T%_f||6@S9}ą"Y+%4|} O?"Py> :#a'yH~M"O jC6ˡ4q?bXs{"Vxpͪوַ^Su/3`"yw[9 x?'|7]OH6 ٪~$و WďdI>l5oh%Vs! Q.Se}/2ͧ?s q֤A8Mktݢ =39S2{yk<ߩuicJ\$\D]C rh_xIfW8qpbþP"cLTbϗw pknv.BoIBfW;pO0T‹=/c `/w} /n&ѳbfW'ƨ`}b&p펗H-⏀Mw +qZ ޴q  DYX}㢯V F̋&)Ewi As6\B)p1pV'*^oR**?|d<^BxFUKb|J́DYL$?xK'xf$ #NG}rfhE v]TIš /KJ8_ЫjRuVDG^yDOTH<~Q5SXE/N a~ZУvf-x1tSu;%g>R'ļW*9X]1^Uz̮&NvqZУB7' x&mT/q#!PC0Nx,Xڜ}KPCTF߉~%'&YG˽'*dW%W?l٦ j4/dGk[Bpo/\&*'N*B*$-47.;݄7~PU4몗:AK,=N= U)Z?Ļ Zx9\5!hҪH2B"xLrTTp 17bu MB(d|ܢ!wb$0Yl=Ԑu"N&V)FMb‰Üo1\$U ɚYkkINGk+Q=\ LxH?xEG24[]Ǒ:|h]_< QAK+F̥G=H,W/~&#x\K2I¡Ҙ5,$ϭQaK $Z_GBld!Ad 0S~gEpD3$NCf6!$ sY?OdžOոU01~roY&Woz{2͟z^x4ƞ%vhe-DPHhkf$B|o"/]O#i۰$Jb$4Vd_BJ͇LGc!ViI<!qC\8Woe_\$wo M|+FSH4~ЈSF4&TeK^TTHK#ÝQaD7ÈxBaD!ѩ$Èυ}1tYҌ˪Fi0\Ry%q7s+s`_(K6aD.f`_lÈx\x\Q!a˲i3gݿ/pr+cm"m:%o[4\F2e,S>P?.ߵmUdL\-M%\iHxEl/D ׽ƭccrR4xR*ǦVsH`3aյI`7n[S rמ4A+jZ/T#KKj2w1 G^¡C/|EneIvK8tP߃_I +A;%aIWvUၣB)M5Ƹp熇I o56udiVC5_[ Fco;[eI͟gr6;7a$M;ᠧpwQE7KP8xcxOګ^xj@Pk :-=]F PCHj+NW٫Ŭ>.)?9ёk^?^XI?{ntxWoRO*tcF H S A &!+!!$ۺn5.EG[va}E~/_^)Eby+fz&?6\F(0\S*,JzИ cs !k'nM-|fKZWV֨ ix7ma%U+Ȯ=xI1\wgGAVѵF.%'!$z~ ~d++T#ҡ;Wscj5}2"A C >( 9+?֗ LULx_bp4jğ˵Gf$EK1yW8a%^9 ߗCJQFPnxh^qȑ.D ?57O-~I L}î%n2!GKgf$ez~Ea W yWR/12B%L* e$h/ ˒*K~R-$KFЀ( " dY4(krpSa &ߢȉS6q^X*=߷ ʪMC1\$Ke /ǗEʪۅEN?eٔeK%C,3ZoxPUR!a$GxIN5f#{DL]+hE]M8;k27Z ԯ-:M h2^JXu Paj%}Z!ؔAM+Z"@䡉 60ZKp[U#=s %Yy-DCW= m?YHx/ y8 D-aj4şaߞ _)=O?8%F8I\|K̚fz-s ekVr-B\d_6~?tT/&yKΩ-1?=H `'RTO['Zs}˂ŅW瞫O`} ]:8LugX.%94[8u؉P\k`.ʼWۅ*r. RF\^r[M`%|*I\zd`~.+uN@gL8-=P=f,_FDcDcFv5e^UHܤ^-0Լ kjUΒEHI=Us $sc7~1TYBGuo u٠ZAcIy` O Zr'"^R%ͨAߓf^ jhg~D?VKQYx| !2Ws4 sU~ @WF쬃 14gӫk)wݻ2Hꈪj"[ԻfSMUإ#D}ƫ QE{--~9Ȭ$wZ i"aI׿o/_F.9_ BBH4%h!;xI}L-azKIގ[}[*Ԃ>ZedJ*֯S~^ _>O]?o  !Bc  qLz5:HR/MӒdtHU^EB6M# $UjvbBMC?a'2D!K)))*jBoo)DJx*`2Tӗ[O)zpںf$djƏk=,SheM,Y*~ W7v׊\$r%d] I}i`\n*T3^0?t Ԓ= #\4J1|j`n =!dxuU׈n'`)}ըYRxH=k1=jSU'mEHIdUyq'jTI|XhҀ?3`yh9!;}}h/Yx gc* b 3!ԏCxy5pS ߉c: 4*9HKV$E HtBj*^F[fT֗n[*W "*iA5B*e'~܎)E~UכTHMIʌV<:~)*b|e~5~z~$^ԵEs?CK3=RFeIT*T `nHWP$VtQS(/ \?r|ƫʙKެ\bb@n>,I/xy[ڿ\ש/1NτvB8q "A!oV_Vs@ـ s tuyՒW8sm !n_߄W exO+5M߄AoI\Hr`txdٞw jk4r?L(K4W5m*BFrG>aA@ $҄NWo% ̄w& 㓃Uc\L|)k9U\5yi3pEAElc>_7r5VoE_N zxSn+p^d(-%E__:诡c$ETnI n|4iC ^ $ChPj97 y33q6Ȕa^xQnΩ_^ ju;].Y1Թ3Fΰfϟ# Wֽ6WUoPE&GB:72 >r09b&eؿyȐ|΁wrO@H0J9}B : a!S)rε6I:F"#8^F+tBt:""dLߙ˪1R)tA:yGȘL/B>i G%ts$zSF5d#l:YR!;hR7/$D;Ѱ{9Su3s*tJ8ItadINGT=8{+UCpHyMs?^:D#v*.f.0qzSq=s's2Z3\󈝊 εS6܂DQ !-⢗3?/tt" )߷?$ CSKɮkĉbd _hO=IB᧍=mqRSk կ=3oӍ=m45t(WK^}1D%F@H45tΛBXu+r'*!$߾O# $Zz"0 3bur%F%sY oZxz*4Q4pMxOFܖ}Ұmu [h]6;ȥD髡N'zN Ӧg61I Õ}`B;:E=Dgg* _ !AƂNn;*Z4M :+^މؖ\eƯV++Qoa.@{3cZlz zb)v;zEv=T'kSGu h~ '.pL`w_J7]_?"A'_`sTk}j.B ![D5]l=힟SHN=8[nNj$Jꥳ6Ϝxt⤫zj&b'/=ZmvCG\b?iۜte'揞X6']Stbu9Nj}SfSR:mqU=IC{SCvpە?yЉ]"O"ua煏ET?:95~VW'/|]:gqU^X瓔k~x:9’9TV:LJksK-O`CN&=s&)tCy#ss>н:RѲkKA)#KRɚN%@e_2I5v]O`i= hxn2 bh8䔢NE4/w:׾DSK`u*-~!Aw:aDSo;X0_:S܈)=RZ/d.[8-֙"*:1WwHu𞹓H0o+;Xgj_R!խWW @lwHu{pJV1k~(h4rh:)d joK':DN '5oGBQ5nd"&"58A`%)q,ENcٌ`M).^,' %*-'A@EIч#rC*YۅyJRHDS_ډ`%)KI$K8)o2WT_Sщ3A(Q_V %#"'¯&K+{RB¥ߏ2 StO'Rwohk_ES\S$[yy2ȭL"Ie+܁\~VSD9m%!'\$dz;;(<tAyr Jr!gD>9-h 3e~$Ng[3XÐ'E5g|ʓғ`N#(w[Υ//{ȓқ$7]xkΧw-t oQcُ~?{BH!?'խ< !tk(Q=nK׺GC^tR׶vG Cn3^2Ͻ5~^llΒ[tF¯|V?Z]$FevTE7󖘟 }=~? Nհ#=n^fV6/|\&xh~Jq\ѯ1{#ǐ㜿g~_Ti3t3a8m&B;dݫ/zCm`hTP1+N־]x\$xg6{f$eU͡W?4UXJɮd AXJ^e9uTէeH5}F\6N=8e 4=F+?=[GNI'k.f.`S]eH:Yq=s'sAˆtmLDK_s;s*l>0l˅>1" }/M;ml&DO4R&AK~D`T:)! ¾9y'?n6ˆ}c/?ضO6 __f]tNcLن$0D*OOoN dY 'A[3 AEߏir2$L0 -"] `|\ä6=hJI5tK4$F/ۘS#"ˆr72w0 P˲ap$_Ǹ?ãjr`: 엃uV;sE ˆrEx71% hXf_IV.L䃤:FdRj'<ҟ'c%I?/I{uQm5EBNÛ$2XCO,alǏ#PUaXpP|T&s` y`HׅLT, K=RqdK=8鸑 e&׵4ɦR.̄T$*/~Iu?lܺ$!ZjkWj4YCz7.tW4 _ؾ:)B#q]2-9*/+7mVz:qwb»sEMHOtO~r݉3}+g6ڍ[3Ӽv5 |bn4Ulx&b.{Bpi^q U4H1Kk΋td.M ߚԞ,|ؓ |\㷧S)yg&3T^72gP=4.eb'thPTsdQYeUKv2 ݙHq#3%!p&QΦS׿}ӜVݑTm! }rp,;ʒKWxD $GU,K(̘R'OiDYH!GK/sgնpJY/-xGT6cHR 2eДj6֊uYH?#/[XaKd#]Sɢh""dމ)AEt>E=R2C<_٠ȢG*YDtHVE2RSǢ O /ۘhv=VE2q 1[|r&pd.ǠE.j HE)Y $!Ǡ(E[wQQ8,E)^n ۅE$lq\x?V;Rtٰڱ1]!Euw(_t ^l--=86S'[{Lw,?G15I Nc#^鎅m8)'zY M"a#wӟ? }Ec2YetC>_.cC!"|換LPRkh;&L{c!!\l/G F Z~'%["AKİl$q^\$Acc!v(#SR}%>Ν8wA-EA|K6"-:NP094v$u.or1)1DSGBUX:hcHySLhDՋ%M7~d~Jb^}L?4&ޒȦḬXR+ԙ#Av)%$vK9 SG-82pv^u~&ōtx`!w$Ln!GG䑒gJqgX ]x9A)8zLRHG-I5-b,DՉq֞͝:qJetN"&X ,O؄K=ḡW؂3$ _w)_7KsJډ<.Ev.2#4G}2\4ȅ$sz> +ق#N3bh:n\CX+_Gd.q )O-FkQXL}=tEnrھ]L?T5$X.KGT3\ư1qoGɭAM\m)T-\E]E/%}`ώR.n- r?2WW@ ?{|88[  *yynVcJK@?'ipV%HIT%s_"UB`! <z@4 ]@(^]2.*8p3\xra0jt,+L!kRDr¸>%03az4窶w\ڢ\Cxv?0>ӌ8g_x4u >c,d7xܗxIX^g#8ffhPAߦj4\\a*<1ie'A$·IAI X23W!+s;~sLH$!x\$d(ibٰ?Io猕TCǴݠl~%e#MO/SS+:&OYꑗ;Y75i 3 d^\\2x? Y'ĮM=E'm'!mA Dۓ+5f#KYU?.ӏʅ*FR-5kX$laaDg\u H&h2n+#WS^ab+đ-nN\|OSFN<BHCզ|έ: qHDZN['XVۓgQթu bA!͑>Z+y܁ũO& %OMC9NytO-Ey䁩]xIĞrpQiQ$ ӫ k|0<a7RHIN|-Ny4VdݵFz6A0XO%S(R}HѤ@?K!T2%9Hh(x9+@CwQUC[o|V9'5?*zn:U !QPc.ƅ;Pn%nI*$SA8*F:oBпz|WjUNSͮx52pQ5;'vS̝H koE`^x54:.:TTG+hL?/ڢᒮHc/jE#w $I%Un @Ip!Q?hfKD D҂WJl!̥ _Uk"& D)6gIL=לaP7s9kISO & H_&˚lf0s9uh5  &HP i~kx!%Hq´iF;i%H8MLH $+ |9W",^e8".\XPDOK R.Mt&A]x=|h*{ˊ}PADp4-|$/v^>i-Zb-Hz~g\$$l| '[V_҅Go.&8j)Rl(-0B_I#S8C\3 o| гEYC"QE= lH:ߥB 3楗t\&9v5s;s^O#w1DƭrKl:7)J(kkD#keO꿋v* Mp]d}?rOkr5erK=1^I Kn+VagR~=:n^y ĕy]6) 6e&%/ɦ9Z$0m&t?+$"& ϶O6nFێtg.]ffM_g̤~x\$lD/喬&D[o,͵+¡ ,͵5Ta!mօAZTB\ nq$0Ԙa\}BAnR"x$3 !ѣO'kO-5Ԕ0kBװ w*0N=8-Qi4"R:ffMv׮+'&hX7'҉#.&2!3zBHؾWX0 I|dM_VLUVo}!$A?'v6^6A galփ^Talփ^gSalA^Tǂhc.||~b9Yu/`-r.y«|Ȳ%'A/I0^6A3-rdIօ]g4/ޛ a=+OZZ_Lh48ń™LDݳxh&tߙ^a|/N\5i~.* شyZfIOMC_㨼5l{yTpבa6MRzme"qj]7\$zم͕$^o8yVQ5\$ޏ6=yyh͋l.-iX36 bhQ8GGEBeC~k3㐲.$ޘ3zTfSh77K7ٜ!hl(ʓ){8۰6 [uä֯|k8aP$~"X/E{T~U/ђkھ<Fhn`C0?H8W\$] Y^GwC<\ I!-5AbH?SYk% 9 BAGAH4Il_rp&ҨfKz@_"g}B/ADR!%*$Zd=5"$xatMeTN5JhjԫuA%sE _?TNEE o15|ȁ_]T!hO5Qbbm\0׭.i?X7j a:StX5BW`FU^)\ 8xMR쇓xKh$AhNZQ<~-a3/']ay%GZMR8,aNF§C y4SPK\;q&PrxI>O>⬰~zx7*|!DaN%V'LOrB_%$H^Mޏp\P}CcnR&!$E8q?O\(:D]'.|g>qDQJN!Q{B $)wp(BD/ǍJg.qrŕJ_)G."+Q"@?FF$/$5WncK: r,$5'}3\/[ȓ-W70If^FB']/[#!ѓD뀐h%Hu@HڏDISk!bv*TL.ak$yy[ IV#G*$IZ/BH^?QIRwA L R.o M?~ ?'%zHAH0]RRC)_v@~E™rƱJc#8/Տ【x~|?~$$DS?BSԘ#%a5oGq@H4|t|mc!GBp@_"ױqfy:+E^"0ݑL4a#!N'HH0 PELI۱I!M3w2 &/t'7>3S_B>߁-2>?I{/\!q4r&-B>[^xɌ_vJ!DOB`.6͑8}ָs &4-vNI4Biɘ9iSYD*t(~ w<&xB\_˱Iq5qy %zjjC>2A G)6\$Z_{}KJ=)D/)y0͑LܗH0S X6 z,~ k?NA5MrzJRQ#|n~>#M[O7K*cb˷aJH+Oz=.IEgf.[I4h|eԐ2h|=8Qܥ@IT3k$k_|aXHRUõ b3T!-FU?Q S|֖BI-.~LѾn}t]蘧;-FT0@AE4BH8fb3o^-q )DC~J?g{.|獀=[|j {6lڍ 7U,/%]K1j P^54 u ۩DhQVl4Ӛs% Ij"J܉qTOq+ S ᩩKCl*xBZWlud=ũT-6.xLŝN-3ujGH?ueGԴLKK)'$$~N'/I<N]y~A59_ڨİ|Xc=_v=̒VhUF^V|#tU%8ANlfJZur ֯OMGHb%΄]xT!)HѓGRZD_BrvmI'nxj Lmq'Z;/ Wu,GK*+݇ R]Buj|RFHjyt4Rqm-~8_`2A_Gcy,.">:^g,m!2=u-I&$8%dۭ$[4Z(u H-kHj;SIP1jږ:|M+r'{ţ#pBү*m-NxUR[*[i˲iFmHAg0@/)1T/й-5>̺YJ\S›R[>5V⡭ ZB,C]̌lDSj Ywr@:5@xcL f ?9L)3j hYji~-rM1j'DoeKBZxZd&sK돯m-ۤJ[ᔠ _T³) g'5#|Š5NjD'qUxj(PAO^^Ŗq,}Zj8|\SӍcpR^|Iḙ)l§ˆD?zThg'(5 e榬76 5#K+&eqTOΠBF oO\+'q\ TIU{YղȶfOҙIhZ8דUG j݋T#+u!En JsMģǂز"6i8eĬJw=u26C@T ̐-TN[jssnB_\z2VqūWi_"2L*W41H.zf')ՖRU3ck @Ѫd ?f%~dH0.[Vϴ鏘ZTDhk`]a0hR%! `P˽]apqi ]1AXYh*$K99t$<o#VT?gª9$IV{- %P00Gx3V}8 UMH4@Hذ!_~DlzRTP%LJtC1UYs/HsL,5Mp!A֥TsBi鲖mWo&K_Ȋ, K$U%B#HB#U|_RτHKIXG e! b}^')*jMCluA%cg!R݄#%!l t"L Pf-IXhm "!%lImǪ|ϫןcuLOlNHnv1vzSVUfa%dn͔ BHɞd.DqIqBVC4yت<=LT7PD3)q=JL`@cw4Ӓ) Z DqLhRUoǴʌ=LPD+]ℕI&qcZev_L[U%:HPDK4)iU qE2j&!DOB^OܦWdK4t,:}gqmED#w"]'?DZ2v_?籪2vHzPLJUېΏE[Ǭ{[E70;u>D #J0AmDƼtuX{/+Īs9W_Y% 4љVp?ӌ e%m)B+a?bf,+C? T:s>bQZ0̛bMIqؒ8OOr—!x闼Ne.$#f>Iw1㼃< f ]!Qq9v}d?L 6} ?r1;wMA܍|%JrO/;y{B]fqʅje.ͭj 6}&Qhi|gQ]6GORAmxM }Lkv"󕦘eCk<Ӹ𞹓H [uOkh3ftYWfK:Ti%TWItd%Pc!~:I{s: 'ڛA/ѣjM&iB⮏uO&h]a6stjUZv+$3e.ңIxa. ]/RjL0|-L&Ժ-DEOP?j<2`HC5n&ETVۚV_yԿuɊ]sRk-9)DM9Rٶ ۙQLˆ&ל"E|6M&l^\$l_[+Ng`?-i5kѾ:LRBN vGĚ 4Z o;beCjk!A(Y0!jV< %&DZR2pi B MkUum= b?Jdꅗd5ÄyId5}IgGPaB}"8T1L_$%*kf 4m܇Mc.2DzlFPVWM2jRʷ܅7y9Iҥ1չPK4?r1x7QAz8L0?[[ /4fY V$ MFb{Q!CRNڬ}7U%{4&\]\$'Ca%6v98JkPXݾ\I$CDq5LY/2 $uꬵjb8nuURVn/snwuNC~r,R%IaGd^'uTNfsPKтMZhkfaI9 1+QjB5Ԙ$ Ds}n=f]Ȧt4%#o2ѹF71-Yi$8v.B/,ِΕ&^T2/ѹK TRɦx\$$M*|jf(Q.T۹!lR98h/<gR<ʩ_.,r*jp:5S5'5aҋyq dnc.Դ`ԼhU(H;~Zu 0*N_8 Su / 1S"7Qqy4єium o SϟsxMÇLbϩЎN=$Q)ϟ95I'3HGuI~ќD8fj\uZ= nBz 7]ۉVLϷ$9J|M=Gk !RVZE"&s?jw)e+BHC u3O=>"F"5%<i!Cr'gƞx#f!KD׊yl^oY8 AHXHc1pgUTGC"Y6ɺpgz\?+<ghq}X'\:-E_x_II7pw%ډ~, ϓd𖹃HhqX֝'yX;>Q<' IkS]F}qU)dlDϗ: 4V/_t:Ԭht>hsU Tsa ?珵co\hI8`##I:U$GE0i>@Qq`0bh# u" ?JցR??q}G/H|灀 ?tHbGSO G\$:h.>!AHlTsYT2|B04K @-~Gu3sw~J~5YV>_ȥL :QSG>snQ=mX?G rGT/N|UGTV'ˆ@'>K>DWH>D#-I>DC5GM A\/N~pG**!E`|0I}?ؐgK͝GK[Hu݇փj|ǟVn O~˅[ozVˆ'?뗉,R'#O$r|>gu>Cpz &O%3khs0Ú_ .$= geר]_C{U2~Ii?el\'*> kkVF%kRA?kG+_\=I2K=w{NpIaɃD;C_~ؓ=޳3I,{=uNsPa=p-ܤ[rMi_?$"rbDP9?ԣjZ,gh' 8GM،ׁcfW=`@d3 *yMC'WIvP޾_$~[RU^ZG geRB7Aзr I+סuPRd>J 2-u㓭iƴ ln/¦ЀlgKtD ؂Q6}^B/߷O.Guo7s;/d;d`=Vo:EՍoxuu(ˌhUBj/w 6Px{U| ^(.2 C/ n(*Ld U7l'3P73!~t=USB}I |#L AYByuCHHJ HY*D[8ߩ]j5گ,쌂_UN|\WP½Nӯ5~4J s/{7WU@ʌU}Vm/%ƾ\(E=1_~_(eR(I$\7>8jcp.!>1TpܹɛtNoE(I>ޛ(F_AI >m&(K|BנgnHktC  8 8hlv@qVni::wF*wI * p}S E9a[ͭ 󰺵M}|r>{s':|ToO ya99$!ڐ7qf˄xzBQ>Rf q; Zq\`@(4 }w3wzXktn8r[UDx=B ^WF 6e Ȁ- ݄0xlmC48hu*8 |rQ[E}=h>R8'Ճ#P{քW0 <kERġv;q$L*|4&Щ/K6lW;{k~#do0kU!bjttJ< 1xKxքKAb t#~&8pz]j(pҙ Ex'N$scotch-6.0.4.dfsg/grf/bump.xyz.gz0000644002563400244210000025215411631447171022023 0ustar trophimeutilisateurs du domainep0ef_bump.xyzK찭,Vg ķA]xL\tɟH A o??jk??f~8+mq?yYe鿲1^W=&{&]nmmD64}nsNPm3R32.$=I&#/ڤ I/<6Bʋ6BmsEv!E~!69hBmsEBml/q!_#g݋}{xukfs?;NH=. 9 x۴WX 6 R/5@Fc}}^{~!DZٹ{\cm]+E{ܐBrHVَ!9:NoVQ/$y_$YpGܐ_`pͻڅ4 A өfS9:pwxZVj! {S:Fﴖ59. 1a=!e^3}kONhfwzO<#luy==6Èq!=m9#m9b}nsΑ6xl3==\m9R~nsΑss?99Gv9GbΑ?s8cUy#Ǽ5huNSċV罡ыVšVeBEy/Z h/(Ƅ>~sgẹh5/y9[^:gVl1huVlI-ْ{l鋽Esޢ9[boќ-{hΖ[4g^-/{lŋEss:e[g ℾ[c[ۋ5fĵ[c5#[g4|ڽ[g8ℾ[g<ℾ[g@|9[s؞[s[sh5o9[chuh/ZE9[4^:gNjVlu}ꜭNϭҜϭRE:XFV3(/Z/ZXh5c/V2X[˰{kȓ[##O/l5l鋽5lɋ5lɋ5l5l5lsƋ}8/٢{lыsZ{3boboboɜboɜboIfL^-xdޒ{Kfr_--{dޒ߲{Kboif!_-4䋽s9[bo-y4/f9[bo霭boٜboٜboY&_-E/٢{+JF^쭤`{+9޺bqD_/742oZߴʓUMoZ&~$57ž^ ھI>/ゎ7ɽiU.iU'MoZ-}o=BGlx홑~䐼wMyiUmx̖.B'@IɎ®o]x$H_p}:AMrxӪNV⼷7ǿi5.h* ᳌/(i5K޴:ߴʳ8MrAM4iuֆțVgqi5*zUbgA3_xjiu\7{*W{W{*W{kz^[g >C#/[Bޞ[J/Z]eq/Z'!rhuVh5kVzQ^UPi? Z_l~B:~A=U UlU~B [_P l~B[PVTZ*Ъ-B>П%-bV3sa?gkҟ5pol-9[{~Vǽe?g޲qojl5[s-1[!~Ae ^Z\Z_^Z1[J ʥUm[ ڰ1[uH(QZ_P-/(VUҪRi- [/h/< $so9_鯕EjF@ t ;4*{r|Ab=o*O-ݡY쭟r&w蜭c @Meñ췉:cW$c3aaQ:|oų>F` [yA3 :yهzM>V""t^JZY>48q/BWZ3#Ǧ˾Ψ6N}'Rkf7um +yLW9]{klyBRN:[]oG{rqѵ?: 4{_@ ޴:Vg_z2g hƵi.iuΖiukћVʛVƛVqқV}ߴ:Ubz*=C7ҵ ڛVfG[;ޡr=PvCIx,^5B=Vle,ylՓ"}XF4X+1L+>X4gkXUh5#O)>+ƘЌeD/9οKBW,õa94]lEH T@WX ֊<ݕ} yb,c:v]gJjt_YcET1OX'رg X8Xz?ƚ->c͖Ӏ:>}3[%Mr0~q5[L9r_KˠO\y<aX~B;V'/C``uB'OoB@oHm} el3[[VsJ2 "@G;4g.}=jﭦx׾ V,#M+yV)8Z:zJw:~jIC}^ Bt`~2~(v~8cʿn*:TWZS6mfتJW"Hp QM=~V}~A$/cӁk淨ϒ_i;ǥ *} Wժ⑑c\ށ迠]nR3[\ӡيgw_7>!Z\BW|F`{+8wՉUAZ}@Z-C5JzCǂ: eP5X@_SE`NTC_}V:09[oEg?~}#51PnU3qkm~V2(>3[Pޡjv_}-qmb$ҁIXG >'a/eb"u}\? k@}s`2z9 :5>-*P?NOMqV/\2:>yzO,C* V֊eGa^ a- @W,zeP!]Ajnk_'aY:VZ,d,kK?EZ8z~ˠ [F30Uc#pVN=ko)K޺j]9b : 1ȩ5q7hX 'NbR"z龴4M>[KS` we_P'ϬYB'sЪ z0\.{i"4ExDPsGg!г3ҥ$TA{V't`jjRVBLJ}'՟u.z=iѷ՟P!Oc߱ر$ZݡKSDݿ$s',9 Knjw?'!Fu5hIuKl}bsJ蚭rZ>5[9-9u@luE.OwAB?{0U:BcI\ 6i{2PSkaj򠧄^:gk&!gEKIlYjRVzQ%sб;2Gߡߩi`a ,?ؐ : ՀZ09{:R7,1ME^B)-$T>&Mii[Xx:XnijZshEXhL1Qٵ iNl?ǖ>&R_Z4k>Yc"]#M_vg+?UM}:4-?gEϮU@zY'VSڋV)vg+?tt5ڟMWVj6zѪQՋV=v5&4jЬ1q\19TPJSXNGRh|RhG.g-g/gh,Gh֘gh_ PZ S@BcO՟ j? *4hThDhj Th,PXBcRh|\Cm)4>C})4>Cc)4>BS_z2 J? tTh,PXs/Rh|RhGBc8tF*4U-/Th;B~q*4F=hYvfH}ѬjAͼ@_-G=T*kf;4yĻڝ{AXYAM˨?\ak>!"9jLLXX4^(F0?؟grX4n 6̪1I+y*0thJrEdfK@̖ޣ6tVM? \@l*xƤ0(F`V)tb2 $av)@iO9J=?]UcBlCPNZ3_5&Hfhu@mk@|O_۰C>ֵ9W}fUt-:~6A dS\uFЁ-+5Cuqua\A7ngzJC`FIz֘l(nWxȳhZ<4}u:} 3[Z5&Ǖ hUTK_WM* w>ߧ]d2z1 Y&g+kL(ߡE;ݳƤRi?+>ť ΁1ٴ^ࡿJrzؾZ=>UK,ECR/MAlR/OE֘47^;/䀖R/o(-Yc҄AϒՁB?{Sdfߡk&]QraD_P#Ucv.wScRCxc{_WJq퟊UԘȨ|/qد0{݂:گKjry"ꀺϓV+>O|4.jq~X=#ž|.p+'$*:ƂB]0xA Ъ*/h}!}_P X.#wA{ _pۏc,q߆-^ |/ V|졧vɃV'/\] ͚a$ BSɃؤɃg}C3H Dر|>^`y}rxսk{-f[l>v,F!ynV-[;~l,?"+R,Ii][/l?D-63 \/}9Ҳx ,X]6 wDm/XZ& /cy֖ /+X^ 򈵶@^`rye; ,!}϶|ijiwѿzd]& [,-c繸3 ,/kXY /A^`my(A l_!/,B^`ye+{ݷ%to'de{H`{kiiWȦ XJQΡ?#Bٝ}`9B oR I,tVp`BE>Q,js4V0Z]Ԃh0"qkqZ_M(Aw)=]2պXq-Q*됯ЪsbpϏe!P04-K{#Aʸ~]N~4H]k^X݋^0z!}aG?U*i9;9bXV~M`=|HkB{Ze\J??ޕo`m{a8ʟNzt2_X$Ȥ?k1ՂiK(W~i_]XYRtʯ}- `UTMlU~S35Yz zp/-n5'6Q".A 㙂،+#c| /,ε|PٯkR,u}M= N$;?[ v?~av)F>WA<v&G/kV>aM2PX6?Qb!χ Xi#+=PIjGRln֗lDy4]y" Nt?ljfe1}8 9G!>wVVC3bQE 7m;7J;+}Hϐ}aCRôdd޴7-d k2%?"$b`ĜV{(R k'Bwu|H~IvM+N,%ym6y _ҥK6y ^(wZ7_BiW@iW%R1ME{6i%Ǧ݀M~ ݀& 8%2j8%bmyK~]8sގ`kn>doڅFkji<%o*Iq$ɦ]Rj wJqӢ+yaaRݴUX<R޴`XC3yb/*fbc1< ^MYJ7߷틏Z؇h;=[x YӐQco:M qoSd&oo~lm,kj1߲k۪\+pGUV#EqV-F;VAĮ5ʞ/M_oqVyu`i@{"8G +k]o]%Ұ }wY+},Fq|_ zP~ @njW߱6]{߱!Km6킴ى{b_(8%:t/ [zk }1oYNc/ [F'P YEStaaK sǜ˿hs`'vv'J 9b|sI ;:!圃Xׁ{y 2qo{NV -iχ395oS\'sN"A^b[Įy+x?Xp|.sbs<-VW1[~/|\ {; /|Yؑ/^9󆲇'#m_yƉw@T?a]}Ha Mo8#F\_tUoo1l}=j6Ҭ&8:2^VoapĈ滻:ok/qEȝ/Au:7%QqX`2^R-:ŊTJxv3^k]GKTv5L0/Qڴ ]0/uT#%w\ {fHCf`qblpF%̰Mi'MY2gX6_^68 C1LMqކem_;ccz//ÜXZ9/KSnjSU,ӜX]9/ls^`}2ኽ2bۗu ,-رs^`yʲyÏ{\:sq{`co^8-/tѱVرltF2`yl;+i㛹t҉:3g[jW,חN5l,3u_n4+;P+YQ8d=Ng}0C{X f}@VdJYei)`V=N3{LU N)V=[i3ߖ8[(!o^x8ǫET VYm[1 P8q6c&e󚷢u"j5׼8";MYB֥]Vȋpl"_ Mk>6۲q!}y%9 r_qF9ƀWz=¹R8I,W֢V,;kK2>-+ Ue<ӖMmgIҐhy8jw'Cs8 ˚J+c7hS`=,sQ J6[+ߋeOzSOSCL]5yt^5Zt e'qqb5é|a^b3eŷφ)`9gP?ĶC*za+ȷַ̽`#cQׁYsuTpd=BRGpd=0¥ ߬^tGknƕG`XgY({ c-%}/9+}XF]颌},Gmv<eKwQi{/o'׋?)GΛ7?|߸E]ekPԩ20oc gP&[\X;K/9tmޱݯL턵nv[Yq6)8ul~Q7O}oR 5 x9a-1}8wJ=)hi'΅Le@[忰¦.6rϲK4%8Њye.Ջ b|o:`m[qO"/0w'_m'%~Gt}ϸkqV:1욷mgvޏM.kaeJRp}:Z`2yo[(na/k?Y54q:΅r 6:pn_X8=J ë5PcCpp?qv3 eW!*wO7B?'6y߉͸2{z68T[3nb5[x+q&)~?NRdǽ8JR8܊(#6'^g?D wkTie=Tr.u3ʘ͖&_7"8Gk n.8bUC8ǽgqg>ݢYZk 8Z:RG36[}x_'1ih許 lΛ5qe yX Ѭ1}X]ow5оQ]o%nUʸPjjx</{C=ΝVCkԬ1^83NJ߬q=;qDMwXW ®'䗄;Woӥ)Z21GM~ITS jɒFΈG`џen:-N٨,|,NYq8:/]˲&dz^<,{ܲS{Wvߴ޶MѼMQ+M_jY/K&7cخ.N+5Ӧ0oRY2bc6>'3Z3nd𖶥*Zj[zQVS'Mʛ7^_`^PJ8Q^P[z zOM* ^^g!^I^zq9N=,l99oC@Ruvމ-WҺv oOvrolt]:m齎/Amy[zG|p[zT0umVa.p5;k#*ҙ,=},=91]Vr3j1Y:F޷1,؏$ CiRx-Wqnj[.WmxFCϖ+z(/-WwL0K0+ *$Hlb=!ϼջoyǓ0^qmVAϖޫ-І^7X//lҮJiWbkDPGeK﵎iCl^خ9K^@SҜkL=ΞدEx6,5-W)PkKU_(/W*:EՖޫpɡ/-ך؇ M}|v/ZuzC+MP|X/~M=6o[{Kw dOc;?ixKy#nkQ ،W]}xɈ lKNϱ6\,!\c_8<%Y}'?yKv0//pzKl2 vŕnŦΓGhGxq&na3^E=fszgR k'^(9@]O]~XPf"uC۝;uCGt{G͸o_ m|/l eM`nŨEz 0V, : FjUF4qZ%^h~I.ج[!_ҵ>t@Y/3-C0;c5~-29N+C/8K=p.RDWx/!.>f"ÚL!*Kyg)h{%Z{JN@3~ UH%&nwWOV/"HrA_rJKX/)lX9> m6^GC_'vΔz'kO ?uZj u״ØI_GCwҭ3-O}w7 )ēQGCBla!v`?gE(5>_LGnWHKt~P-P KBKY}ZX]^:m835vK+KVr"=K]No1m/i6j {ʉwߥ Olƛw7 ^FxbWOn*zww6{텃a lT.YQr‰-\5mx)ў!M]w j*Ʈ`Mfsܼ=p2Υ,nƹFCj=Kk[b^rbÊ X&/)k\aV6|߶tzkkxiVQ_[^:^p|ckyŘ`Wk:~%\cL.F۝ɯ|i.,'0t`%$[~KqX]Ekkt1uq;>vƍ}?;Fةu׽lw;1?%?׀j׺38^q ?){E] S^+X{,"ּ~fFEgg;5y+c6f8XpK{j@'oX;A;ɆU9X<)NpT7Dεvkz] szV%bv_nf=՜0|{[5Y3Bj=ν~ҪG/S_ؑu,W+V{ج:ui8: YG%}vל;{:*؇uT{جy v`z5+fMj!mja:7|S qKePߖuT}.f=i\YGLk`FQm~߱YGHw|tJ|.GvbmKU,7먬ԓU,U%جځyz`jh#.Ώs+PpjfW<չz5%Fڳ'FkzhcXY/=Z 18!j^{9rIOh GOKWbf94/6c7^K,c]ZOW]vRf_zԆ/s?cc"o[z3VxJw;YT,gn.@NEMlꪅUi1C̦~I?}̿Q@~/^]|)`x/2wZEā#∨1z`JU&هi "9fޔ pagT*_CZ`}(H+Gk ;J c[ |l5+Cyk^r_ ;5.s>W izX8LqfƦ~9a)gIdy#*:ʚ fm jsPl.GoQ tNϔ ׎?Á󗚤gPiڝLkڵl=mVD0=y a|{>:;?N90fp`9SO)vKuf`y V5GlgBvE Gr s'/c[Ƭ+{F/ ڽ%8zx X\#Ve`Rk]jP0 k6s3}{k|aϧ~rWvCKK!؇P#6Un ck@xIvK񆬾qr`'i g2[v+x {]sA 酪oڰ.b齪dw,We{5^o)sbsg-ca36j&op-W {5^{jRuObCKu;*#!LKuYm|[i-욷~u_]o?v+qZx@Kut|o.l_Xc:J< {%˿v'vv'JQ^`'6sq/c~aGFEl;-=NJPҲ}񒡭sQ9p/&-: y162^B;k+oKzOuH~Ii,OB~nW^䗴VFnXXcQ{3^ ]0//ci>GK̻>cSO7~:K[6X_㹿K+nOyvg,xM9oVҷ_`qnwۛv?/^&F{V,-x\g/hnK#w_`F4r7X%VW$}/XZ/ci//\ygFnunݸ%Fnoo/R#w_nzOXJݘ!v,\yg,XM7}X>+o~[ڛ1KXZK#מ4r⊗\ 4r7X ˭`/ F.?cX^/4rK#֖Fn}ۗF ,-ر4r[祑+K#y._oY_;ė~ɥH\OcK.M}inI,-ܲ7Lcir `Fc4rbK#k4r]YyVy挿-Fnmⓜ%]-7Xl76w^0hq~IXz U_#p=~Ij(X ^zUoPksޤԡH@LޫK/QrKFb;9oJMA~I+a间2lk/iVG~ 샯v;yy间/940oKUZ ^%4vsz3{Oyc.в`eaKl.퐍-ᣧ@O$,=IzIe yMO]>~zXJva$EPRK` /nh{X=}];} /lkeʩI<~t\a[X?#7l°ݙ؎SN Affaإ Z|% ee|AQƷƊ[N/{K/3(`ϸr/aS^\cKZ:j4.$V3N=XKtOYqlq0wa=Dq*xK꽪ռ4jI[uO,e=Yo|7i#kڨ JfPSqk?s/uP+'W:=OLq.Ա ^xP(/Q#Z xI?>3^2J͕v*۹U*+^P',xOMߊեX[Kӗ4}#m؞XJM7ؑXNM7XIM7XMM7XKM7XOM7Ky.F[aY X[#5}mX^>t-c|4}b 5\>YY4}{6\qxI/N}xI,N#/pPcTVABxߌGyb-pD}v?["6\k lj/v-(ښpOɺŏw ؙ7ox^b+S4^ 7%-։!6%T(+^"vPZ>z{kR~[ƹpd uD>:E9FA4֙.}McinuwwzV8C]zVrIf~b(t*OvW:zȪǩس^kHK+TnϒCA']V=NuI $+=t[ -y -Y3'0~[>8%slEsz(zAqpC z(Muk(Z^{-~&&uWΎkT,x>9oCk.Ighɋ\gPѬ9k{%fUlwY^nuĦZ#>k'_ 6b9%%w SZzcgS._'o:*5A81zy:fYSs:Qy լDZzF]Ҳ8V!8@ YG%9KϜ3v}F+*;>klڅaڴM~gU*>Kj R 8mXB-~շb_Ru0 c6qĠ/)weØ-~I/~jiU3 6y T"S~US5D۪*zXZӏr7E=nmMa0]ySGe|?yS%X5]yS\Ї{= 8 %銿mK4P{lw,,KVx+~+kuߐ'{%mk5U*s 0ߖa%Wt-%%d-zvv'J=]sE=]sۏ不 w1o.| =Ӆ;A:;tAb[zPnA}qg.JgfJ֓A,2%y x7Z|y=_-6`}KîyywD_Iϓ_Ҹh/oR#/?᪡-Owcl\Zޗ[So8Q fڭg 02U/cX@{샦bɹs0ak,ֳ]COF!)}2rjpуiOBO{{M,0l\SN]ymsoK|sqevʸrhvֵsyasqɍ;G:zHywʏ29Yc CPsf%KZ%pC(6|{&^sx vpRo=%|\G^;~G-x3g~>82 v` S oO=N 28׳Ew azIAxVKx>Fw71;ͱj:nxb^/py"N}61+/2 9&sY&箰/4A6gޫ7Ms-MXS/ԫ ;LKk)G~K~ s`šԥt0UG W)x>zK5}O,})>}xAŧ)ޣ_"!~>eѓ_®`ԓ_r> ?l,-X_"!x_%xbsޢx}$v6U,/]lkQ<\om8{?`ܻQ֙Q 1'~[|~z(1&a\Go}q;zC1o'^Rxa}x(Y:/[x jBŊ0ԋ\9،!Va'h+&fvտuXEU&kgfZN4_8x6)]T,}MvŹ}Xps>J+FX-5}Z8= ?e~ .5[Ψ~kTj^![R؇Rj^+VK|ԼƊlX/GԼFK6햚 Śx(51گ1#݉sQN,c~mSX{beO8V8%]HSχM8fkI1V -}}cNCmj<~uCɪAL+>Yk5 j#Ծ(H ɺ/넃3>6Z u7d|rH9D:ˆusƿ!Kj^#Kk -MX%~I>m~zZOUcelyojKJmbh{fYo:J| ؒgZw^X֛jWòtW 0^^|vr`޴M}ڱUoZ4`Yo:8r%Vi20ȍovCYoJ\8Ӌ'x'%cE O߾Z?osz=iWW,y{Sdī/̛68^zFNX!z|Y[TK?E꽊=`\z?* H3u~Iџ/ɞ⡾z%?c#N9u>v/}?=uY`)uYK];~ntY3V.kjVvb-uY*򌍥:Yczn}g,-]K. ,]եb,uY/8^:z.'/]zPRf|#uY}ӇXN]،o,]V-X/]Vϛ߀{u.6!fgU#k^}`gs]Okr8U=Kzq{XI1G}h̉e3I\C89o^=_ Y5v0Ӫvv޴F_]mKW}9GX^cVP6+\}X~\[]8Ry89oZB@)Unqo^zxӾt 9oՃXenX&s9oV<Ҏ8+|+&̅.?rWD7uQr2XP~aڸw- b?Gu`׼8os4S=?nKصߪ]zQmNA:QX(,Unaty/1`}_Y%.R+G7JEs=K\ƜXYc\;/iQCrS9^ܙnyak]1'E!%za1jRs+E7qO?c1`͌W]3氵}l,ϳp:'!~vlfnp̨y윷㇠W}/M7)D7{w@/rNk4FElX ؞XzNbhh`V{ y/i\%r%9Y qyNFy_7l7}ZѸs7<'OcnlZx;-ZJ=,3}_,?cq GHs|!p`Y6FozC*"f^H=Βt%-؛щM[mo}1={Ik frؼ ؼ S{?@!]X 8^w`W[Rױ3۟W*yc]햺m+^O}ow%6bI[Q|v%};!v@l~{d~ j'SU'v'ob?(Ix`9k,\ج[y^Cd|7{K}QP·᪛Pp`3-:O0\d=u3_8ݨ7qP|xnֿυ1z^])86pS#0OxRq,*FO~qz2}n֩1 e8[l؜7u[0 (!}K%q8JN^_x>&ט.7Sǭ/њv_;}?Nr Vtռa3oweMy'\ a|bgH#(uI}X8k٪!Z}X89^MxP +Kr}̥,`~ ŧ]ؙ a:)OJg|Fia%ؽ$K:-_cJʋ.lOj'`.HNdt3CF?5ǻ%#JIU8ׅWFM8-hWRWg6 9oE'{~bEfEw ٧RSL}B[O*v7ƺE#K `cy~+qk5oQ5 KYs%+z`Gzm|DYs<',!6ug_0(q-|jA'j%NZ[&UXc&GwD8 $gUr8{anҎgw`ӗU-l7:4N˔'8wK8gjCHTo8"ZNz{*Ħ׺8\k' (8kC|]J {3qڇ$MM=:z3Rz6+A|j}D.1Z k2qUl b?>b_8vr>qɧ^PT;uDI7;㓮:v'A8v'7}=,'{عߎؾSMzlT=Y6X^)O5 8>nXK]&#f>Hbwi `7X坲ҟ)͟)1.zNiYqys}^+~κ;vLu/bg]G1%wJZz;YNzF-SKRϨ5#%L4Ju7 y0}<30UcFgq(r}|VV)Oe]u8߄a..{LazwS s /Ӏ/7x)J֐;Ӵ!YB s]7raـd q;`gzܖNB\9w0iwSbYGRtYC^od=N#Etݎǎ\za2 #_X}[ `=I3C<' >,r,rxIr/~Tns|bU99dv|u/2GK;L\u/n r#%.> VY^~b#9g] ,HMG+~C1ءnѱ N؛:Ũ rC9z v~c/dF~3+߷Vj`h^Mۭ^bRj1|-ZdSNl-RxQQcyVj ioQ~ۜM 6mXԽ uj9y7qym{vj{X/p)Ubs㜚z9q>TΨsrNz6!GyVx;RF{ #%_/,UvK65lqʁRs/i-.M *~CKxrKEgUUc_9*x /-5rTZ\N~ nſzxFVxAf/A8-1 KP48%cp3^+Q8cד۝-68; '$ pQS+H9υ._;;aqx&LݢEׁ+VZ]g9r"/%j"#o=Pwp`3ƆN>*.8}s=56*!mpY~G|o.-\;cXǜ7 = ajr/׫x@(N>_!/{}o ަ{8ѤW=WON8D̴z6XsQcN6s sSSQj1p8%Ӣ΁JCL3|^&˜ޠG߀_r![>%v!`1w3%V/^ -%>:[zRc^Gɍ{CV,yAEFI~I|, y>&7_ȽoK/pX&'$p<%QuB@KA 9x[~7^~ˌ7Y{TUXYCx7{Ywqs1K?aB}*6X[Bw>o`C9 L[A0q0\OXrC]~u1佶R%ݻW2o-4~Z/c|/)X:}6A-wP[1j}y^!^NĎ {<0ސrKN8䊗*5M&wߕ劗2z'%,%[wG}ʟ>Мç+pKN(rK $I V5W7/79*wCWrcQj>Yoڤx(g( Ѳ73?j} v'A <Gֈ <:x/!gœ5(_v ;筷RK+5b2QjEX%}I^gP%_ŵĵ%JmO8~Iv|g/͠~&]gK*8pKJHNwU[pDzjlڅ!9oƛu@'yySY:zlPg2ftsrK4*튝I_>y|a_`ЛU,U_ZMVka6~-^٬mm||QQ_zKmS7߀_'9ٞja$f qaKq%򯍢ù:*uY336u3D_C_CK\띴W'ج7Жnboj'y.gE?>;\Ul~FG/  ]8ݏ?N(8 ǩb?8go]8`?8ܞg3vT]8c`M~q`?ή]8֨b?Λ]8b̖?N=zǑǵ珳;q d8%>_IR[{`5^ _ `-볼p|S_يb.P˥uxǩo' P||N)\5. AZCMqY].869b38<*61ɫ]Fz9k gKUE;#v[3 *5 ́{2yK *TEX؇9oZja:ET漍3ogyZCsކꃋC^DuBN:U[yӜ7IIm!՜76Խ5>WycaasK`cgƅ/V( |7zP ~jBmu s6MUK1~9oQ ?6h l7>8BD~ӰsdAADZ]?s9o X1T7==%JyM~ i.~ M.t O5z0|FST0r4KGp %_BR4Q]ksĊVeFFΛ6&9rr4^I yA] 9o4<`"\ʧ'C$Kr7)qӱ9o 9E::vfdXgiKj)W -~ 厫j{Ew=Mǧ'mbY5{Kbg:K ȳk |QAljRca٪ipw.ȵU7^ћ<Ƴ-^4ڸرfh~`yaKN{XXՇn]@b.ޢyܞ ;t?vr\.ߨÙ^oo8l=a47-[~;Pt>\oHlw7+oHmߵjd(o% my+yS捫w+xX66|+WG]7 }Tr 95m`-\c㑺jp_A؛#.t1{ԫFcN㞵Rz`Rֱ3V"qxeO(ͺ东Xᷬq4-qY8US7^z5zǙ]u" f꽪o3ج@ϾQ9asf[۱YhVAֲGWbnqłe=V,-7֍C)FTmq.K?aQ="[gt+oawA-vƕcƇ|q`ԏRxKFzAG;"/99hPdo;I9/lq,x{,.aRjHۧkL-`.R:v| k-"~;A=yK-Pu8W[ E-5sF+>ZsIRN4Ϻ|m.cS_|.̱/}VcbiT{՛;SuD/50k-F˫֮9Yk]>Х |偾%4`q Ey:/ƟlڅX'Din`׽d˫^ ֤7Y5ZOxb w.^:+G}Uc}Hr 'SU^|e̸ ɟpoXOD=K۩V?6'?_OkݞxޓWl,r;A~+KA̧/irÚL]g_X*| z^cmMV ZXk*6B8Ī;x>$]>Q2odyKu< `^8d= Y#op>d=^s|`ag>@\ٗޫ'ץ<Џ[SՑF4=G|zv̅꯳Db8b5b.? l{}.|SGX;YãWL3[zVv[Ze|$O?~g7 q~Q{j zq?C?4S{ }7*<=u=usS[:A}+or!y{#y+zEf2^9Fݓ_ZXGx'.,cޫZj_za5Z> /j6C^MPiu&/hPGl -u/zױx3`%kKM9MT 6m6&]~% Гg^ѓg^h+z6tؾ@Qђ8FR="w2{j o I^pkU>i!w{u3#-J--ǘVE\1(kK0=cdkK8/b6R5[pHߴKخ,M %\޹_m.cKĂ2`3^|]].%,;.X%n1CuC!:Gbq_h~p0x]YpF*pUSSjkZx_W_%W:Kcα$,'|;lO=/ɣ]IB^ l^M: ǟ+!/>^A,N,׊=^{ZAY,WΞ}6ց^c WQeڀBz@{ f=5o UĪDZr_/;q*1ƪoΈ_K[q̿lW"z+oHR+g I19>#W.z9ƪǩM^k>|1pcXU>.lC'v͛^}O욷y>v[]ĮyA!욷ӥyvX[#AkN?w|<YKm8OoKJ|]mz`}!ChM8N{ĉMn`Ǥɀ`sxӮ?&Go(=oV X8Xآ?oGly9Sa){7`P=2%'6msQY'7xFe=EluhQ~[^i}8hCYR@ujgԊʗ+GY>M <l6AfedlxxPK>1tÝQĮPǁK윷.gs7aopF먵}ɟ^}x?NouX>zmIX<Dl'˽Z¡]'rF`d䫨ð2^ҽwxIg:[Kz//}K_dU~rXU&OFkk= /ϳ FϕgY5||d=?yإů\W֊k/佒am {VIO,zž6C;ǝ Eluf}/>~%Fj̉Mr^j*[`1H*~G`@4а:ЭjGkw/M"n"dPĂyYcTjw>?zHY;:c-r`e_x>6sl8f̧;޵luv_G]=ǷKq8_?c^ot~|aeyպu8_wOͫ)6K-qȅװ6qu/^؛FJvBz?4#6qP?qqG?Z_'o4}υ"vt=q1'h(}Aӗ,C2`P~:M?)m,U C=e ˭oM=}U;[GMI>)'x7H]sL8/X>yf?{ON9os46C>n6WN}M=sc=P/ߡиډY8PfT "=&s o1yxP8pzN^D/YpEOY6uFNa>F!GKTy@M9W7+ꨍb ƌ'ǻ3Nq6]'v{ qJ~)rQ&_2v3}nM[`55jmbSWmJ~ _rjD+oZAW)%uG/~= 'A/ps"%zT*ԡ؜7G< 9VJ~ Zځ"Kv>=SpZ'a0f ܙr[Xq:CaK sIq ?FBe~T !%ޗ'3?m1>؊ۗ2E 4lj mq 'W?}Ղ?՘X&+vZjӥ/!w7Zڭ-Kv8T}6 : LYؾ@Z,=hرA//m6x;.W]ܫli2+] |w乾uN^3^51{~L^:^o- ;FZ)HК!S7{J.UUݭut+c(.]:O`/9qON?aw)̫X}Xϼ|pSj[j|0/}..=%؛qUA/́ZczAKx;Spg HwB ', /q$qu%urD5IX^W-$/y~hߖ>Ul٫n]FYmT=K>N?a ߈OXdǟ}~26ne46mvgUKfYmg^ϼ!0x=$j0_2zMޫԳDq/?᪡">|zMz,}HVMyHN?h&Wa[K/?=񒍟8/%TϨI-ZYyVu=K^~DFY~Ga=HPǻ~Iת5aJKs5d cN4@d S_1sIoiB.m1~Y%-@|G0ub!'YcO,CXxmB߬ok-qԬ@GW|/'tyL~pG? Жة_b8Ou8任v@l6,?lp,-')[Y#kq xTmvhƹr}" #4\<;Y{Uc|ֱ8~~)^0o_$W.2&_Fqo=O:O2E?/'Wn18ȡc)vg|u ߑ|e䲎Lw$_9g*_Rk Wur@Jx]܄vyƕ)M劗( a]{Ď1V,Z=sގ{Ipuԇ&WB FMl'JXwV'>uM!}<yC^8i8zb#۠@{^{{ڮ6vI>-[N9h{Ij쬣ab+y):*{<8|Js:- O윷ncf o=qN&DXBY&T<%M41k9UjCȝsz/sFqvtaȭ1O$;1x3! Xlv7:ݹߚ0p1[kފyN\`99EW1 l ۝V5SPX8ʳ>@'bg}@7a'kTO,Ar k-@ r6$e] kKz9@n\S1w+;\AaIiX?7StCTqMޫ:1RM=*fm:0f2yAä~!N2yAkڎkwm6_7G>m5{qAMuD*AӷOᙪghM>W+u|rKR8 ƶcL3>YOjbRCn}bk?:k4.| A=M֬J3\ A3:D-k8<:7̛Fs2%&D8f7%*M=/Q/nPS/Ѫy(|KK!6yAQ ?/^P`ݢY7H^' OZSlM+)r݇ b::r@Lp+)[%VVa'<13ξ'&Xb#}AcTj>0_9?b0%0@+C};=R*m=p꾿UWJOϼ4bc+_OxG<-?a6+澬y1ܣHy+>mM k ߳Үj3|߬ǯF FkJ-ia~_t ?˷po).4xaq*u,m6筗; #7h?uՌ?vF[Z1lOC6T_}w@уfj./l/5 F-zywbhb 8߬éCjZ4FR5߬{{k{ 8za]H^Z75z_zp"샮>qFTp/cr;"YJ7e=NC<ʲa]'lhG72̛vi/mSϋg_4ZzVkeycf8foZ~]hPiYӼuz&z:6|{8m8 uza巩~W.MSk]G`-=z߅Eb uxC5~ض%߹*g囸:ֺ|@1j06My|beg.~ w=V,qzf$؋_r=l,q+?c)}wĞi%w++yn^99e2-sUv;يSUq _ri8X^ Zpso~/_֣[i'l7yARt8#"VEm A[U5KqFUxb? m1ho&sJy>f7}F^CF[f% >SڥN{rֺ ^E_օM!rS>׃sܧaDBOW".z oVjT4㨗N>W8ĐuW1u<8`(yQ7{4\2V%M>rNBĦa~I.lZvemFϑMZv󁒯p:K'Os v'|쁁}P/b],|xI֛zK^O[Yzs㠐;(sqF`Hd._j߬jShVFۥmR4u;0:8%~6:~?8 tb(eΉ]IGE. ԬM ͑E aȝWQr߱ş,ᐓK"nP#ʳşO UΛeىOW-fƽ8#ro!KuXzp7x1҇ L{Z=㙺^uI0o=*GCZZ{-l'ꥎ x^i6 I?^.ee{Q똟{I]HI$PjvVj6uC+G7j& {=lTXY\&[XK(T8'օ='|`#QV`|zH=;+ΝK>.?z-i|yN~?lq]jb٧b-[;&ry<9o~+-o(ʪe\;cZ '6F oԝ~`ӏ*78Գ~[KD#0Ys<@[S 8wx~|aݩn1}؇v㜅Բ˜e=M vߔ& NP=t;* 6:6m}8y/Qglܮ~;K3ͻ.;:V [ξ/iZyJ-jj,)vaқj z֖ojdmጲjK⁓~`468oFKU,K]Y[BA1Gm%C%2/i;,7}r%^Mg-!~R֖>admɋ朵%c3|\'3ܨϘ`-խqո2CuPfY8X1qüQcňs<5+fKnag}tKXKZkgKOHl7Q8 VUt`Usg2_x~<#E۸˝O{`9Ye|OVsj56o4j;bg^sn ɟe}(C߷ϧ_ؙ7(wX6ye'v5jm lw^r0J6y<ݓ;UOװW^5}{'-[>0V"Pzq;!:ε{3;y4 Tt/>zqT~S}vֿ}i$,lϛ;] g:6'vΛt/SsؑI{nFxɸNعߺ~ԧ;ͣҝvxb>NA=+CJ+ܯq%)fȋ?j l~߼q (U׉Kx}Y/o2_Y-g>j0|$̻ !q~uN|[8kq7w8wUE*֊. ~[c>~/;h^%dN s`2z o!n\siv`#"\ ~^#1K~I#إZ3誡^ UC=k7sg:KvmQ8|k{`!ϒh!v:}`/[{/^Pɓ}RI-M3_ -<&U>4T|F%o:\ :pک??lQ=z-jf6-9K!XqEW޼d/{y%$o}zKv_:WTmv%eÁ55}ʹ.7k{[QA{$']..rFȀ]sQ5ybDë Fe=ɨuXYC >x6yxUzi9DK0*4Wy6G/iQ%VEK女>%' zL?`JN^x`ХƫZ cL&KNIw_Q`kPKܫ/KKgyHJ~ɱ l g6\lՁcHcTyŠ3rj%Ol 8->l|*-"QjHߚ wZZ%Ż,3:oኗY0*!K C,~I>߷_<:׳36R.bΝ4}Ě36'6M * 6}Ul <)%RyuARk Njțk]gTis3oV~,}2$G#e7:%G`"H_9wl7ߴ óIJMW`GQ 7.>W6᚟'yN=^FXg/1-9ցySZeKnN%K4oعߤzݬj)wWԹؙ8-fƷ$,1V"J.|`#!$SoQsy?>~bHEdJՉɴH]m0az qxꉕvjx -^6 7Z|l9{h3-|7 lwMA&5 3oz.om8{ qv lkQr8LW -r}`9/)_rza>ٽh7bh7^G.>Wz2'vK{|6{'OqkhW+^d=G+~ؠcx`-KjJ::>诵6uC |l~ߌ Gv-\t688‹=fkیsYo#80V>#+߽R>:9;!nQ<݆Bm5^,5 9ld]q[} l-jproiN?V9.'6\Rr kubiaAOmUO -*g߇5׼$œ5o< gd]g5o%o:@-lYgN?!uSﵵRoci؇{S?䗜JU ·nUsc9ojMa$'$c/䑾Z5:AGrH |,nv\gcΛW?l\'{]6漙i]M1%_ySy/V5r yS|Z;-RBbx5WobsEN86,I?aikN~IGP䗴K[ E5__\*_/V,_*CJ?Աn4$XSW=U|,YΛf|cq %j]؞_R۝v|6Usf`&i5>yUw8sބ WBm}n_ºz30,&z3(9%gY̦yHm>lSwFmty!G:M'y^yRQm<5y:LRp .cz(1/'`>?Ɠy]wCOrc]/߂]܅?@?@;HroUt8Γ>r-9S`El|kJ70caqf}{;6uS*a p"v'{ܰ?y+ vgO }Z~uqKɟt:+ $j Irq_U)oK TP7.4ZP,'ܢHA7$UX:PFn4P<'}AVot?YSeK/j!_N_biȈ+&ī&q&O Ϝ-/Vu9cɟx7] OM&AF.a>[9UjEV>|vd$x_$K{_oxNk4E'W$N^vj/9:iE,H1I?Nv,hj}0.U(*$qL:r"u OFz%=lƕ:X}7o;/12Ģ;8fqckWi$qkh2 q.KSk+^&%'RM}eN vg"=J'6u՚`T_Ba9$}4䆶xN<lyn:f]“>rWO`X;uT g! _M(|o$>yAֳf9yz;̅Kַ0IR<ߋjqې؜gq <UӆϾ8lW $%ٰiY%R>+>?,/G)MOk.gK%<ד_r0#}'_r݁|eKNG}2z9ŵ~|( [wmԁm~( {6挿 hiK}zTce}/C0ɴ^xMI9ekO2o"JpKNqnykhKz";(F_܈8\~ TuqH;}`ɭsGS;NSkH%ܕүco1hNJ^$8C&c%M}` Pk&/5bV;oޙ ۘc6z vTCsOqZMOIxhOqZxڳW֌x/qOy/Ѫ?J[:sB2WrO}x#v^))O ۀضrֿr_zK3؇3,)/iK\jɀJ[iSPMh9ԝ)pT9Kqnu|!q"lM\Oqsz>cϥX]>5oZ>`R9oU觪烦U1-թԫRRnn|bNR>ɟ-,-4V~.zjӯCVsӌ|'vŕC9qO[4][Mg*̛yywJ}lvg_C}qh>aCQ@_SĤj`G}~ߚSmP-w7O^N.n gFuHO7 *4K)yHȅjl|76Kܰv~(yu7*[CdnA:f4,䗌Q4(^5ϕ?džĹPۂjXK: b6M[Y~ ^P'ajP:YKESu\vY,_r_?`'{+!sOE| K튗TrI vKsgPǶ/ӲvZRq߮؇ԝ!8S }aعTsF"6j~ߢ`H;b/v|#NQ52/6hJ9n/Z8@_s1{MZ9j'l> }ǑS̅ƌOpo s1f}׼?-^)Qo |sOKsqq\zjc5ó{K:Ė0Qs{U.V8 Qza>z Wە.~|SuX&5xkUkJ89oVc/X'gW6Y>u=eda;h,YK:zךyzM y8CXA?쏇|7Epl7uz]JKeY#:P[H 4,qχch r8s~'N>sؼ1nW.Xaߴ(ַ?\ef1Ԯ[K:<<'G +^bVr;J.~ɩ \*?)l![M!gDb#p;:r\2:A=@,^J{4&3ހbg *"(y٬d\Ǿ߱K$؇oY:&O^o%w'\qOsg]i{bsLPKNoD+|OQsEGMc=`-k.;ɣբԁaW=Zso 8eyZK~_R8rM<'c' r~oԝQ[daP 9u;y s?zqXw۪ECЛ2^q~it8=%EJ 3oʍqXlz ta3\gޫQѝi.؇Q:KjQƗkeY̍p.}M>W1)my^.0$}=, x 5==8\s cxU]d Zؼ&f>ƣ2uxw@>fUSN&mm/-%K`Gy Oli}KQ,~g<_!G5t ac# Ӌ^[gT]~5lzÄتHDqf{TQI/[ɠ&,~Thq=g/gdz{* ,}etycS0o?zi_غh<ge۱pd]zsWK;Lst o&)> v(RӝyU!?;񨙇*`8w^=^Y>bNqmk"޷!Vxd;z 9ƺ^$֞eK%}'\mNH-1Q'Š!U,o΁so{mNQҀ7x^;EZXOu #@|'K|<~A\0GƘCd~ c`0Ҽ%g5nc;WX|K7;Ė۠z8%iЃcrS'׼B2%EԿM=c׍cO![5nLj×ȍ] ՘{pe:/b`܊_:x_z^;RFmbNmR֨b[Fk(^rŰ7a{6'|ڝIpH9֕ڰrT{QwS?OO=p>[lo%u璉kha'?koݳm@ ts=n8Ƴឪ޴q} vX?*7^dUzm_6k`"a6>}67. ;$Q:{6(zȤy+~w4Y!gdӪޔ ;傜OV=N(* 自!Oض0׽5q}KQ{QJ0W/yxFq_SGd)~->:\WclJؑ8:􁼶}\ qR='8ݞAS֬ѽO@%%78u{iqj&Ml)UWG\,Q*;YzkHc'Cc o,A0ǎs^Ggw{S3w|+~Iۀ1.sސyܿ{=quttX4O>@+dV~F؆{􎥻r<Ug9.gՓYuȉ=[oޟ{ؙ;>xpYt/{-<Y5nF8?wl|Spo^GXwU;ZH+bNxBϊ0<VF[src ؠ=KHvlwɹ'bb^ m/őu>`Kd07_3gbĕhO6FpnQc+ 0F*ӪvǞ|@K6 L| تºН0Ϫ8ק_݊ۆ%6.ՠ)~Izȱފ_U@-Xc\%֡>`[#w܀S~N<+ocQ@,lC6y&L_Ymh8 FWcO5m2vsmQzMɯY3jin~z T ر'oCĞ[6{/1l:l߭)ʶAfuyNmtNЏZ|ϡq|ηgJn^]l߶g[q,&%vg ,<ǏR{o2&K`b+<1(ox^xGwGZ{TVQ?̉W]'3UcOgWƏ$;_zk~ؓFMжت)N=yVwo̯yFwqc:vV>Q^,{XЏQq;a{ǿ-lo|];:=M j'0||s{h| cϸE q߼F':ͱNo7ҲmQ9n{_S{Ku(~b{ϽDPz{9^Bg9uC]J#OYv9ݱ[ a6͌vtCR8K; _%:T@G!6#8ۀ] ؆9s^ Pc+X?WLho {{Fz~W ag*ǿ3KF齊x{\/qmf`NZ+O?Zu[o+~ ھ\/~ s({m4K(ʒnAdLHW7}-n{6'п)5a㤀XEPsr>|>k*grx M@kգ%w%^ŐSo:'ViþzMUJ>Ac+3;i}8צ 碼] y]Q~= wŞEXqZ鸐V{(ZzAZlYotoۊl(ױ~xAďxKk5';q!A3qbM@{y / ^\7X8vm$ؿ âb~[3xANvxA| oՆ(?a7‹pW.տ:ϼƭ$``Hu<\:軂}!s`ˎ-|Dx{h0c3k|C] }%X7K{\qwV}X%ʇq^g^''6'F:`>3ߗ0.Jm['X3nϷ}}ꌬ"ṃчP, j`MŦ>z;Q?ST3ݨoqTzf'6!}O|SX_ n♕AʼnGk(kCf"v5=~4TQZ ݡGwĬ|!>bVot%|9ij5&3H;|4'4'玴cٟww½Zv\kCN}CfT< k'u[oOIz Қm1m] 4lү$K4أ|6#b%.Sk^ D~+v_pһ 1.5 \ǣxx_xK@~+8eޫ`;gJxc_E+:qک:er3cNF &rʔ9YxI8r]o*|QO;_ҝ/< #_"k|kA{[3BwępnJ4;,ñ0)wDM{Pk*/Nc''-p?/I'ck __^{ lC퓖쳳Of|NسON[W}mwlv |@CpŖB92͠q]񫋝N;q{<_b߷1JK7T叓FCx Q[noaV۸ndOkTO'O/[}{vlCmY:OJxuw~ 1ᷕ?Ĝ/'wKlQ$?=-VlqzoY鍵K 3o\3Au]?9X翥a?Ϝ@⽾̇C_Ys]S{oyg)NCv͂CQ{ WtNlѡɱ2^;2e9G̅b;GDi ao*q@?3dz5{-ѫh7gܲqr'3/;;co=>/]:߾9Hpw}ƞ5 (8>{6a68sg Hq03nÍP`θ %n~8c/8޳2[Exm֍;&r\2pZ״ۯ5=ЋyQ9-:׋4ܣ!I<[~{IZ{II >3nHs[gDn}RȏtW9HYiQ@n!_nnÄS~4j?FW:tVlakqi9P3n=F^|sjx> QQ?46m΂5n0-[|$ኽ|.7z[O_N! ꇃs$ݲuӋ[JvKFrz;)$B PxI?9 +369j>ntxk>|Zے ;o |ֳG^ 7=s ߾ nX?i*c9QG[سO09?CM,@Sr__=Шȥ(gvބO&b U33_Ho1.a4yt,r(PtC|Z8(NRl'B0Ύ=F-[:-61'%C ԙ|k8fMqUC͵Q3Y<O$HiY+q'n[jSs>RNV(]5!}d܌Q8ȁBr{.?50V8zzi%γώ{x  אƬvl×o-ޤ<#'Yst\oCܯ,e br^o;0<:X?|ײqb{g%|kMdCInWƞ<t;hY<g/]9P5_z=Pz3nSoqMK$3n1YЁ#`Qi0[9*γfb4h<6sG# {[v۫q{wzXX{fIݴo̓O:ԶYJzLa~ <rKC{ts3@;oz+c仭S0s˓o^55+V%&/K:zmm5i-gq0j>{94xoz;z82OACy'/~I"(cϸMOX+)֮{KcҝqSd6 xʅXI3ɿ#K6D1':&q^GYK''*[ mc0އww'{' Z V͸ѝvCvǎ+U_cgܬMǁ}'J UڌVuª|h'6' ꢝ?;"䄣U-I{LP/z G-!ʝW7r?eOT<աLiJ['o*c='or rGi+5w)u!IF6Q g z9ǎ| b a֛SvOڤzް$lFT@WѱϲXM[8 C60(L~[1 /Y?!@-&WXK MYմ lzFX<Յ}r9ֲc>@5%kޣ_C df =@m?Nj4«c!'F[8X|=ኸQ(8ȃ5xi՛"p:ƖoaLF'{R{ &7C% y3n>qDL,֛f6Xbq3n݈9z=㖝Lu;#Ig%-Hkk?c_xDKֱ? }8Enu[oZovٹb;+Y (#U,{ܱط;/nDUg]w@ܺ|G(?*c}їK#2oqoO$]5l"*IsEQI6b WN#8~8GbCk'3'l;fyvd•=a\YKwnru1KӾ3/glguv-_#%/(Н^}|pcaczN:.SXj:ܿ篔Sm8jtom,)0sLpѣcsw_8cq U)B6~T-0jb{ϸɱ0z͛+ł[23n6i_a{͢jO;㶖1כqwmŞqө3n_⣿kq0w̪ {*=qS{^mg4x?vME2u?ߖgm|wϼe=g7׸ ^-E5n|fojwqm!5nՉj^cwh>fWw9s^[·9x3n_fYw0ϸ { s^wۋ-/(\C'<9Ao23\?_OWp,5Fg ߆Yrl5nX OIУ6 =b3n}'E^w_~7vb1lgzewci:I{ƭ͗1 gܚ:J3n/o=n?~(ש'Vilg^E >/I$ľχdn.+:~Ww=/^E{x S qKk_Hopb_B| |g({Izƭ[ ЭljDZA/ʚJj8cVm ě\7dR,姴-I1gKJq_baIq4 mKl>$m+jXឬ/'W|_c WN)$XNÉ+q^+ Y8tָFtnyI-gܺ1/SϸshOkerc+w𴪣b}pW- YgMvh~Ü,hO(jլmnc|>OzҚ聆OV=x.Lܫ''DlCV."[81:vm~xA# (~}˄ T=vڣ_|f @>?2հy&0ВYzAJ:N9"\9jl5m$k3_mӿI.6߆>X#1 ^%cl/_c޼vsYOs>e}vyw+"a~#a>T=g:޳ޤ{}W[zx)a=;cV,_Ql\-H)Ѵbg? vlut'|cnS-\ӕe۱ZzڬzՎְfe yDBL`gDMsG="~6B\zmBzL PbX=טtp?Nmr+.)Ɩ1-|RGAن ti1m(p__Fn3b)kKg`?^paߵ;|p)DZ6 ^2biߝͪh\??c\%s/;غZE(3bϻ¹Yh𻥇7魇y&'z^E˜>cos~a-$mw7븁9vZ9$(^ۢtCG0O\RVwl݃4ry}v%.cclݨf,WoĹ>; V쨻'blw`dLƸѓvc;F2;pOyvy{q0xN}};` -;`],4<:;̝/(Dܿc,E̦%sPk0^uBz+KݝOI{%2a+~:AW=9'lME/+<5i9cϸu4{D]7$IXF؊=m(ŪWkp/)$CH?K8ۦ`^UK>_Opa+Aп豜,~ 1V)mjqxhߌQpŞqA +M% }4yw@i[z[M-B؎sz 7" +D4}m Vy3 3++E*9vdNm{tFpO'3=>m}FʿAaO / VPI3Dڱ7fW{m]y>>apx'{KñXq^[.q}twĞdޫ/=ļKXoU:yA %UC3Pc737nvӊ=̓@{jwzm}-_qbjt[:zK|?U0s%C㬽 b̦!OPlh IF=^wHg(E8;U3 oYzzX[К82A' :[pz鍾wl-s_qkȯn*Av|V=Η|'Ήݣqj o߱UFF Q82h7_Um9R)O{0[ F mz+8R4}Vօѫ*i焷5nX߽`?Ik ;~֛&I>=;qvcg:YWM'u8S;d;`r zc̺s%̷ WZ} ʹO~T߹$9ض=ɵgcR{ t#PYWؿ1{p3oO{-;HƞqK5_6q˗Ъ[fq3n䇽q{_ =r-;9T["7㦸6[d3bǞ[:8z_ǥ_a. gqA |W76hM/θQql7|4P`*`G䎭掸S/sY/xv^bMԉm(r8(IJx+D#V6qK%W:毟q|߄ug|ا銭qK5tXo~/5loYH\ {ʪY_![~Z[cٌk!>_nS_M/+|V!Wb WT'a#Pclzۄ@J50s)ה=թ Lsޣ\J5- Z+̝!WJ5 o'))}W\Icp*~\*R))~l/x*~IL]? ◄ 벂6$ho+~7dKܒ|+~kѧq+~76]Ʊ={gKK>bKͫgNwZ\C/1xVǻgKl/~x./7RR|G(~u6Ě^Ұ Y:鬋=a]hKT DGcmn8%xGiK *mCTI!cBP_^mWw;;v0%$ՂkK:B=DD /yH}*z%áp.lCK {Om~q|f xq/vuۋ=ټ\*۝@G^tKP IgxɊ'qQ'}^$Ӱ zo=-udwqNh;ӟNo+I&侴qɱic:q@rŎ;Z|DY; qK|ѓa]׵xAEX- < 5o]3ׅ'-:%XUcT>A+㬻ᮬUGaM'T\51~(nu^?\ Xt\N:.1&{]j9^.6_k GwL=ՏLDM=*?OkSQBuթ yƹqgqI`]ϡ 'NzjTms-K˚ɂ: Z~"Z~n:x/)?tʹgܺ sN;zЍ90n_2 (CKY'<*WYo͙q-~Il5OcAG/Ȃ59? TgZk۩7#ٵ-wgզ [zxzπl~3,>W?Ucu{m5'`zF$> ޕ/({Ig([nCKbN /ŏG<~b׸+[ R/]oo=Ժr I7)yڱ àV٪oZ/67 i]ptgz#MTE 3O6|in3nbc\8[cԼV}lm1xbtHe4:7Gy[:= :#Va2'Ԃ[4qҝi [z O\ nzNNf}IsGfЪg첿gp]T=P~zfsSժkgӠҪ'Q|O~cϸ 뭀ǎq6y;֐>IvlQۼ%8MG5nL3nKq v 5V8Sj}2w5ʊ_Ҟ#o;`N Ynhg~%ߚ$xG,~ɗ 'NPf/i9PP`Ll>e1wlqx@+1CK:4|A7+!g/阏ݥ4XG3O d/]m^_Zgp?+~ Jy◈jE|~cwc}Vne7;Ix_/~XFnI4)bl%'`4; z%6c0W; v%?h6.dK߁đ/5u[AFW{%4]/oaLOˋ_+VI◄p뀣/ J`>ˋ_\؆c0M c8pWƺ/~s}r>^x -[-F8ƅk q^xAbPx+lD◸p%ckfX\Kܩψ/qᚊ/~%wK>Ă8 ߭qCzKl cO6n 0c {KT'׬7AcuQ51qϷ4]_o\dP//Q#yKt0 %h9S\/~q{:ã216.Wk6_"{/w&yKF?<\}2:^Axxm r-v'3@5yzZZY3W j{闀 m01V:Juث%̙z;pjZ|z9imwsŭMㅿsj:VgKq0y[Wwƽݑ)Cޕ{qsV\NqFb{t}o4p ^Wz+WιqK`+{wlx u[dE-/wKW-׆S/95ώz2O ;2"mk <[(='m'Nz6'lNCK9KHË[G^o8yǍޱ',ɴA%yت;%/^8?Vg2쓒>7؛K<4h3otx%~8F0~[nҳiQ8<1+_U{y t=5'^xx (5}u>cQx q0~jlm6&~%T~ ݫw/!}/ ݍXWW/w:_vD?MC٣QK%hDK M嗰ZQwԉ$QA,QΞXXAod1nj>U? /0o/p6'^*-Mtc /I5l Z˛VxOώ5n0? ($w_Qxρ7 y#ԲKd@4 /9)% XzD%5!cN%՚g ױ[aC?^2ۋpN9<.vm*y.ޫA8'_]u>+ gߞ7K+_ \%bJS\STlw'j7ZC/ym-Wd Weͯ KcKw&zDCK2$4w j91^PA^luD/YzAA^_[ƍ- n _DcSǜ0<l/F齂@ws&T*"뻣Q9~7hp͗h2;#ϸ X:0{2m0Juпǖ>WҜq۰5nF7ocm팛 ʓYss^gEz`ly>ٮ;:/k]mwbm/D87I⵭X^zx}ݣ[iO&}~  |ϸY{.}=㶦60R(Ɩ CRAԆY) 9Zi?Q,sq48 (Am}WQshikқlo;6QFo'qC Em]߾9}wpw1irm:yL'g-qm3~K>z ˸Ϯkt)nqnF-^|x>wu}Ryw9C|cK_ξ#bj+;BV>PʈȮ~Wy6<1MQ'g{M-]l~}iSK[wq{Զp9j^3n_X157ð Vs|Jw>4Ӯ9Ǿ!쳫ggX8(ֱb3WnULzp,jw~{M'k] qYx ie.μxQK9iqK W{fK2qHSP8_G nCY>{_s>_2m(w+k8'EߗU3[g/dㄳNz/ǧ/wqfy != / [4 /nrYx+侲^7.gkO%:K:c8 /iO};yuKzr[W#*o=Q-mC,~Icfxn%:(/ _{K#[ =tE^ģ\!OW$}7ma\ָa2 4=OvYfKZ(87zwZlCݱ1,AlAA~I나~Ŗ~ISɜzG+K? ol-wJ7l 6K־!VQ0D{buĠmr>jJ[ޗUВ4t2|Xu wJcu,3cFXPN}@{g][Ӷ#qw߹:9w>9{Gͧ:NzWsg^=j^ɻ<)z->yAgʼn#0>>+n6\$M6 𒑝Z3O|[u*JmпQ?)̳:OV}@#riPK|[%E⊽>b(_h0nWd'f`l闠}ث_w{пWd66X2vurr. XQ<O6Dر 3ZsCW~V8Y{lj1pd( Ud >@quK\{K:jl_rl]Vxkqc/ﵓyB2ocrNs /8n;ufΜce H16w'i?jLW: b?\?a5g'']?ant /Y[5a(Dl*?a7 oŖ4jm ׄ5T~5bSƢ\yO%>g'lB{={wlMW෕9Yvڣw?mDv4 , OU:]`nAxfy7z3}2>tG~Ix߉q܆M<x +ޣ.Ik3p,/qqOiI?h1ؼN3op{/3wč⚟jJ}6\1ȀsuwY|7pf񹔰qߙ?I{Ȋb )xvæ.dj#< zyyx CI,/guaf#R?Ը 2Sgָ!fn)gXoyyx9f+w8[z<؜vyxq'l5tKũ[<<'y]_ĕO:Aei|oƲSs$MgziǎO~Ɋ$A0w*VXcη|.1z: Ƣq*cXYkqbr{o|m_ݪ9l ʹs`SgdV=eCxg=1UG5i]늭:*eV<[_k%^ل~(~|0.D7/kӱ ^._2}RJ;MG\xI2[%&I\A2vlwС /íFU=HS@CpV]q闤^2b.+xxymƖ‹۱Ƽ‽K], ٱ8/aB}KesKg[:CW -X/}K8~7yr(~r]ھ /Qg-:%:vYco[Ǡ؁d\=s;{'{q&[*C^ꇧ?F-618^Qy^GzKtN[0l)~Iw9؆va_RyuBq]?zwҾ-Kv7dF5W*GǏo,+Vy8=/$3$.cq,I剑:?/D}PSo>c_| ;%m=5FK3(g%37yٱzϺ_u+6.alR|#Zʜ^9n‚`(^2)'<7b /) lr#b D-lp'8#)m(|[dwt?Wl=ӝJ}vIhCl:Ď'[''pW6z z['L\ C-|r&tcLl'?7nᓩj '}6.>k{ޜԩ! 5+Mi;Aj܄qO >I%73S|HK^갇o# ls7(dgV]F: /O[zA|@Ϧ]])csbo=3c+/v6T/{u0&_b!/X i?k{*~N0nHcVlupV]]@رOdϱ{i~W}ˋ&`xRxIgm3ؐ# Ghc}t|RE8[]|/4t! ָ5g wܔ%g{Ԥq.'-fيIȼ߽uNz5_t`V=N?MVySNyrʤqfԃ[;oc͊T=Nhw.7IՇvsob>c{I_B]0-u8߱P /iTkÓ4ԝ9:w@ʊի-"k5`0T.ib2踬zrq&pq ɭ\6A:lCi [%`~Mī`qz!N:֬ȧXgzm9Sh4[һ! tlC)Y0vqKt67[\K؏^t8 /1A^ /2ثDc}Rxwʷ^hs3Pw ~oC_|ܷN>~8aJ/(29 2nIQ-q {̹Nx2#5nS6XWzfT/8 YW gU0g&i,i=')Ӯ07Y?CJ5ʿEy?+ s B|x}R=R;6yS-lxjVO5OxΪ!MQmk\w-gk"/ prq,:amU'<Ab>ɺC m V8ڰ0_Ҫ܌B~S}BNV=xiómǎ6X6\}eW,qA[n o+$y3xr ֦/ =%gK287S~9 ET.js},Jd*qhO-MBNB~ɤ3ka{+!Uyް6JOعiUKJ]}OXӘr({鎎{jڨ\ z cnoUN~5pzpWkyׁV8\[ /!7ժQ֙ڎcNѪ!?OXUŏ'wo}7jT>֪ǁM'A/Hg(ri㌗V=˙O[7: }V8s orPKɫ;♧rfKB-~I7t\qǍ9YZ ݿbq^Zu c㎱90vd^~7-sr z5 *Sq_WHXͫH۠7Ƹr^P:*꽾̎5njݹ__\u@g˙BGo=z|gָ!vܯAǡ]73.Zo Pj[$jl p{-~ɧoo P!]M'.4,olXf~I" 8]~Ioob}l}O[uT7cR{/OP an==^=Ĝ5л4`|}@l؆1 oj_/CM3LS>H.z끎flj-.8_cQX90D9ڄVN9@LܢؾB{_i'CKz.l\}e.~톿펛ޕ)W?+a ɭ&TԍwzmY /X;i4o%}@uj/KF6^"rvn G[+7~cŦ\!%qm^2w'hƙq#_VxIrhKr06XvK>c:>x "fxI+vw=/ Z6=w[lS^vjĂ^BoS ʿ9((I®%6>6ONKH O !8Zo8A -G>Ƹ6:[Z wwaC&k #O7yI7< ^wkuz5 a{ / Bkpqp?o[ _ Ϯ?N ខkKXsޯ?Nn+(|?k8}wKGYտrX^2HVZW#tེkЏU.ﺩ``{xG..7噛&0<ך<>3O|pz8pO5>@7{OxN$ ;ձw^;rݮ^P'^8)\Uۿh?zW`Bl)kq&sQW=N` ('ت3۠o$/|Z]DZV>^8V8ƣ>Uy+ * W=uqdp[uG\ ʝ9#qM98 "1_/|Vp 3Yu| | WfkW׽^mw˷5{~ј6,oy'.Yy alyNVxIZ׿^=o9O^x|Z/d:$&[%SH;ʬg);;^~YtD:ga^wvoHoK|Pw0'=Vj] :+ bmKyn6KPS(%m|5E b^P\ޕ 6w}q;%I8~p ^:_h#40ŕ;f>.Ww(#mdL@\Wo;+4TK| N&`Qx 㻔ָa^wY67p7D6 /IF%މ߽%aW8 /YONy\(z(Dٯ0(D-! N0oγ/n!Pg7zx\[x_&hm8.^Xۜދz{Abذ /1npK8N1ծG闬؉{I\.J禩CJ$hnxhCtgi~INzLqx ֡/ˎ-@D7.^20/3KbN\Ek'ïQxɋsG]ָxIL~o]Ʊp*d&ԂKjWkL>̀ԋ[zQx ~wlww!%~\# /1ھ:(Xϱ#K>WmU&K K H= /îzB]_t.? /9` /Iq4^\B\DHsS4;X_IYG\\^K^YKun/q#"n/ao>/ijqlg^w_ƍ䭾WڹK纂q\$KGf%{_P8 /ylSzt憺Bl廹{crd{,״xL͋$i4>wI4:)k9 /nJuכ/9g_5?A +3BwMy%t)7wUp뻻 a޼xI8E^2Cn[ksKDۤ # Yx = /IzoX^p)WOz^bMSu(ӊAm,Ğ&?>>B׵xAxbjNPA|K:%:o=N'o0;Ǩv7?a#S7nf]pH 1y1{>~¨%5[U31"ln||-OlzY8c!O[89;~,_%7bҤƚ7oIKz}Z;޽id׬,40#Vm^~IUdKf2A Hdf=i>>МAd:P rTYtI/YH-gf8}@w{}8v}]aTxe@s+Kd~&jwcpkү4 ?IoBN-QMwC0@oQFm^Yx qd<* /a?6V#/^uIC%m2'ulC_rآzwpq%sMPgtυ/|{gq},Cl(dl}nC'tc Wh5 Y%1 _&/fmW#尿i<΋ g/~Tu^.&_b3tQ{ѧE-,~{[F/{rXfDQ#\/քp*~ļ4\VC;ݞ[ m|7YsSw u'.b+m\wO<iuz[廃Z>kWlnFo8ico=N#4[V%yc?%؆/ [S O|rV}wخwSпWNq.M؉m}lB_̫0ׯ~ zw7BY/{OuQ! /Y[ihuQ؆[ /<+~ iUAø]i._x5}%iwb?FJ;Wu{=Jckܐ[ oKC}1Wmjs$LʹoָD^ECQ.VD>lqhC%>ks%뭃Ox^~5ye}K1,wkB1h^Ss{}Y!bkܐcBqڳF5n/^{%V|(w/Ǯ ^sxofu՚\~ bsq΃@츺oPySz-k^{qiѵ0'o=Q#0Sz ׿ q-|[[`tWlM^-TzK<&FV~}/~+~ItӮ' ~Թx|(~I /(7oXo/I؆◄ӝϋ׍K*=k=Wy"4ڇ[6is%=e^]ܱ =GlVl6'쿽%h5Zm N/~IO^{ N~)pS{q\K?uʛ qu<Ү>u_7'bXqš)f'YKrJ}w/_l{ixָ5lϺ]^sl;[͢{~=;V.suOl{V}w赭'Ke>)uPyd=&B]Ws bv }ثǹޡ R|AǘYWy黥gjS=} zxa#%n:.tV[AA'}V[^k7qu di߽![Como+~:.~a' c\ z;eP떀6_bw|Ώؠ{K,רXBR~3ڼF/}w.^!N,~ E^6L)[u$oXPc|cۍ @͛vk>)-[Q]o>|.G3_ IIY b^"p. zd"o{S 18ŇQ?;o0&\u1n蟼)|$N?[޺E x^{s(/ֿOb+3I#i`l^{R F%hƆG Hw=M1Qx}W1n {m9K9:p /Qu^og79⸍!!AKl(8{/كnRhC%C[~[%>{&*`Уǽ/wOU%IKr83ΕgњVxI$w6 /vl^{ʀتO}vq^bP έy^akW9k9[\Wd+v^%H A26yu h0'пgpʳjn=P ՗b5Q碚+ ۱5'<̇K^EH[#/8/cyQxI'D(GIwK%(3z)؆Zom8 V/ם8rw&DL /Nدx#j7W&s^dqWW{u^ Έ\DH$SS&`RxIc /[yIWS@awϱJcQ\_;>C{넍061ƜHљS8w /b]GjgVlj5fo)8aБҡO%%,ՙc6KԘ ^̭~¶'bWRxu34SwR/ .%CKW ryAF90nr %x*C- AY%aJ: /I͡O /Ǵ\DKC%<>%-$i4n6?N\s WűTXDžlA alb#kiiEn` /Xß{Sxɋ.-+iKϾyW2bk` I%,H /q}m|/H%/Fi(灻(X/ 8e, /Qۻ[ /d?N8A~>M黕gLv^9p'kc꾣V܅G= 8qqA{Fy{{ų%wy W5H+ 'ĹW_FF抽3ok;|%o߽uO6 /I'^m>^Bջ #``Rxtƣ$$/Oa £2 R X5nb \XWO+6@f^0GK^=~qFwp\H1\]j^_0X_=v\[?m:¾ í˟ĥB~LL~GD-u Eފ뻞쿩¹iɠ_芽ݤc ZxIzu }K z w|GJm( |S@ yƩ>q#V4t5}Dث͞șK4 ŦKq)&a?ĭ"Z /!-]oj; Ua1ŷtnŁ3zq.a¹{^ܙ ؠ^b0~SkZ헄g/(Śm-Qys&|G1UxkO Em7N7 P^b׌j91KzS@ݺܖ9[<f_Y/^9Ǐ :7s6ӹ p=]~[3c~@ã\"w /Y:^:Ӧc_Ҙo԰J!V<7c7>o:ps{~IK/yۯgp5&A?q}p 8J\6k~j[rvq8[ӓY}VNsg}[{ס~ i|]~ɠ{}.ĩ2]hIo=/i] \(c [qb`\W!K.Dzb^"ī^"N>`_ؠ\7Ů~I0p% 1=zb?ܼaW_~ l 8Ov%XGR/m_2m5v%Gqd䷞㺸F5滶b-ԿVxI4K:i7 /!}umQnFwH"y>bFwkhtOXk/;-K8x dVxNy+Ld0ƅ ~lx٭[\h /Q:*G^r{Z%25/D8sݯn(/,1հ uEs:}abp^2:2p,kP?ض]Whݼ9 mojп4a͸ [+LWa_;~V%7ŧ.NV8-[̅CQ{+WGOl]z$)'zDܞ+I^+)?/Bcl߂֛m87xaňX%=~/?7p>U#^'C:\ͷ{IۉS+?a:.xͿѸooV焳 l=߂3˛18^zގ gio^z6'iv;ҰBs/ą0r^xGg j̽]_Z%o%5T38o^BZ>+YL0sjFY%;6Ś+ ӹ+̝~ᅗX'U1녗K^xb4C%%/gW$W5g)~K$a ^+^_g󋗠Ю5t%IgoW[bñ (78\.>I o}x>[~bqhm8>q%b۾(76* ?x6p{Ǣ?xlp%u pU㍗7K N%` `K1>{kvj.߽Tbcb+vۿ{/i8OS\xɿ;U@Q`/w~?1v.xɿq  /o<5,u>πNC=n}ڞn T (muyё/YxͲ纈]+|5:-Z۴ڜ c'>m=H!|Kwq>}&ےcxɿۨ16(6^+v:0]#Q;xa.)Fڞ+.~RC!}?xmvn{@ac6>Կ[viD(?ay^|L!~椟=J6G^s;W.'<\q6ƍKFs<1K;m${`Zw<_⸟5I=盘[f%6^cѿe^/wڛPKN,2#_mp3lo*5n ͝ /Ox'Cƞ{I<K8L.qkHU^9 vII2`^VNO{%pfmOc%ݙkKvvUwc`lW9ߚosܣo> qv%pݜ2;KȟD3ܔ?-q?KubߦQ8/^P^qj?]@O!ap?N'orGH5? 6Ի[J~A͎͟kO3Û,6^s;` ܕ7^ 㷞~׿uNYoûft_Ono=77ep8#Ī!6⼻ǓD[7&:/niomO=ӟ ;3'7qOYXQxW,WX?x!Θ`Qx J?٨_0>ِO!g;Ba% _8};@euq/}=#>م"_7Vj^ޛs~Vx=C ~[zS{:7Ms%m[?scotch-6.0.4.dfsg/LISEZ-MOI.txt0000644002563400244210000000056011653315761021153 0ustar trophimeutilisateurs du domaineLes clauses selon lesquelles cette copie de la distribution logicielle Scotch 6.0 est mise votre disposition sont dfinies dans le fichier "LICENCE_fr.txt", situ dans le mme rpertoire que le prsent fichier. Si vous les acceptez, veuillez vous rfrer au fichier "INSTALL.txt", galement situ dans ce rpertoire, pour consulter les instructions d'installation.