Line data Source code
1 : /*
2 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3 : SLEPc - Scalable Library for Eigenvalue Problem Computations
4 : Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain
5 :
6 : This file is part of SLEPc.
7 : SLEPc is distributed under a 2-clause BSD license (see LICENSE).
8 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9 : */
10 :
11 : #include "network.h"
12 :
13 : const char *GraphTypes[] = {"sym","asym","bip",NULL};
14 : const char *GraphWeights[] = {"unweighted","positive","posweighted","signed","multisigned","weighted","multiweighted","dynamic","multiposweighted",NULL};
15 :
16 1 : PetscErrorCode GraphCreate(MPI_Comm comm,Graph *graph)
17 : {
18 1 : PetscFunctionBeginUser;
19 1 : PetscCall(PetscNew(graph));
20 1 : (*graph)->comm = comm;
21 1 : PetscFunctionReturn(PETSC_SUCCESS);
22 : }
23 :
24 1 : PetscErrorCode GraphDestroy(Graph *graph)
25 : {
26 1 : PetscFunctionBeginUser;
27 1 : if (!*graph) PetscFunctionReturn(PETSC_SUCCESS);
28 1 : PetscCall(MatDestroy(&((*graph)->adjacency)));
29 1 : PetscCall(PetscFree(*graph));
30 1 : PetscFunctionReturn(PETSC_SUCCESS);
31 : }
32 :
33 1 : PetscErrorCode GraphPreload(Graph graph,char *filename)
34 : {
35 1 : PetscInt i,nval,src,dst;
36 1 : PetscBool flg;
37 1 : PetscMPIInt rank;
38 1 : FILE *file;
39 1 : char gtype[64],gweight[64],line[PETSC_MAX_PATH_LEN];
40 :
41 1 : PetscFunctionBeginUser;
42 1 : PetscCallMPI(MPI_Comm_rank(graph->comm,&rank));
43 1 : if (rank==0) {
44 1 : PetscCall(PetscFOpen(PETSC_COMM_SELF,filename,"r",&file));
45 : /* process first line of the file */
46 1 : nval = fscanf(file,"%%%s%s\n",gtype,gweight);
47 1 : PetscCheck(nval==2,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Badly formatted input file");
48 2 : for (i=0;i<(int)sizeof(GraphTypes);i++) {
49 2 : PetscCheck(GraphTypes[i],PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Unknown graph type %s",gtype);
50 2 : PetscCall(PetscStrcmp(gtype,GraphTypes[i],&flg));
51 2 : if (flg) { graph->type = (GraphType)i; break; }
52 : }
53 1 : for (i=0;i<(int)sizeof(GraphWeights);i++) {
54 1 : PetscCheck(GraphWeights[i],PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Unknown graph weight %s",gweight);
55 1 : PetscCall(PetscStrcmp(gweight,GraphWeights[i],&flg));
56 1 : if (flg) { graph->weight = (GraphWeight)i; break; }
57 : }
58 : /* skip second line of the file if it is a comment */
59 1 : if (!fgets(line,PETSC_MAX_PATH_LEN,file)) line[0] = 0;
60 1 : if (line[0]=='%') {
61 1 : if (!fgets(line,PETSC_MAX_PATH_LEN,file)) line[0] = 0;
62 : }
63 1 : graph->nedges = 1;
64 1 : nval = sscanf(line,"%" PetscInt_FMT "%" PetscInt_FMT,&src,&dst);
65 1 : PetscCheck(nval==2,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Badly formatted input file");
66 1 : graph->nvertices = PetscMax(src,dst);
67 : /* read rest of file to count lines */
68 78 : while (fgets(line,PETSC_MAX_PATH_LEN,file)) {
69 77 : nval = sscanf(line,"%" PetscInt_FMT "%" PetscInt_FMT,&src,&dst);
70 77 : PetscCheck(nval==2,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Badly formatted input file");
71 77 : graph->nedges++;
72 77 : graph->nvertices = PetscMax(graph->nvertices,PetscMax(src,dst));
73 : }
74 1 : PetscCall(PetscFClose(PETSC_COMM_SELF,file));
75 : }
76 2 : PetscCallMPI(MPI_Bcast(&graph->type,1,MPIU_INT,0,PETSC_COMM_WORLD));
77 2 : PetscCallMPI(MPI_Bcast(&graph->weight,1,MPIU_INT,0,PETSC_COMM_WORLD));
78 2 : PetscCallMPI(MPI_Bcast(&graph->nvertices,1,MPIU_INT,0,PETSC_COMM_WORLD));
79 2 : PetscCallMPI(MPI_Bcast(&graph->nedges,1,MPIU_INT,0,PETSC_COMM_WORLD));
80 1 : PetscFunctionReturn(PETSC_SUCCESS);
81 : }
82 :
83 1 : PetscErrorCode GraphPreallocate(Graph graph,char *filename)
84 : {
85 1 : PetscInt i,nval,src,dst,Istart,Iend,*d_nnz,*o_nnz;
86 1 : FILE *file;
87 1 : char line[PETSC_MAX_PATH_LEN];
88 :
89 1 : PetscFunctionBeginUser;
90 1 : PetscCheck(graph->nvertices,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call GraphPreload() first");
91 1 : PetscCall(MatDestroy(&graph->adjacency));
92 1 : PetscCall(MatCreate(graph->comm,&graph->adjacency));
93 1 : PetscCall(MatSetSizes(graph->adjacency,PETSC_DECIDE,PETSC_DECIDE,graph->nvertices,graph->nvertices));
94 1 : PetscCall(MatSetType(graph->adjacency,MATAIJ));
95 1 : PetscCall(MatGetOwnershipRange(graph->adjacency,&Istart,&Iend));
96 1 : PetscCall(PetscCalloc2(Iend-Istart,&d_nnz,Iend-Istart,&o_nnz));
97 :
98 : /* all process read the file */
99 1 : PetscCall(PetscFOpen(PETSC_COMM_SELF,filename,"r",&file));
100 1 : nval = fscanf(file,"%%%*s%*s\n"); /* first line of the file */
101 1 : if (!fgets(line,PETSC_MAX_PATH_LEN,file)) line[0] = 0;
102 1 : if (line[0]=='%') { /* skip second line of the file if it is a comment */
103 1 : if (!fgets(line,PETSC_MAX_PATH_LEN,file)) line[0] = 0;
104 : }
105 1 : nval = sscanf(line,"%" PetscInt_FMT "%" PetscInt_FMT,&src,&dst);
106 1 : PetscCheck(nval==2,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Badly formatted input file");
107 1 : src--; dst--; /* adjust from 1-based to 0-based */
108 1 : if (src>=Istart && src<Iend) {
109 1 : if (dst>=Istart && dst<Iend) d_nnz[src-Istart]++;
110 0 : else o_nnz[src-Istart]++;
111 : }
112 : /* read rest of file */
113 78 : while (fgets(line,PETSC_MAX_PATH_LEN,file)) {
114 77 : nval = sscanf(line,"%" PetscInt_FMT "%" PetscInt_FMT,&src,&dst);
115 77 : PetscCheck(nval==2,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Badly formatted input file");
116 77 : src--; dst--; /* adjust from 1-based to 0-based */
117 77 : if (src>=Istart && src<Iend) {
118 77 : if (dst>=Istart && dst<Iend) d_nnz[src-Istart]++;
119 0 : else o_nnz[src-Istart]++;
120 : }
121 : }
122 1 : PetscCall(PetscFClose(PETSC_COMM_SELF,file));
123 :
124 23 : for (i=Istart;i<Iend;i++) d_nnz[i-Istart]++; /* diagonal entries */
125 1 : PetscCall(MatSeqAIJSetPreallocation(graph->adjacency,0,d_nnz));
126 1 : PetscCall(MatMPIAIJSetPreallocation(graph->adjacency,0,d_nnz,0,o_nnz));
127 1 : PetscCall(PetscFree2(d_nnz,o_nnz));
128 1 : PetscFunctionReturn(PETSC_SUCCESS);
129 : }
130 :
131 1 : PetscErrorCode GraphLoadUnweighted(Graph graph,char *filename)
132 : {
133 1 : PetscInt i,nval,src,dst,Istart,Iend;
134 1 : FILE *file;
135 1 : char line[PETSC_MAX_PATH_LEN];
136 :
137 1 : PetscFunctionBeginUser;
138 1 : PetscCheck(graph->adjacency,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call GraphPreallocate() first");
139 1 : PetscCall(MatGetOwnershipRange(graph->adjacency,&Istart,&Iend));
140 : /* all process read the file */
141 1 : PetscCall(PetscFOpen(PETSC_COMM_SELF,filename,"r",&file));
142 1 : nval = fscanf(file,"%%%*s%*s\n"); /* first line of the file */
143 1 : if (!fgets(line,PETSC_MAX_PATH_LEN,file)) line[0] = 0;
144 1 : if (line[0]=='%') { /* skip second line of the file if it is a comment */
145 1 : if (!fgets(line,PETSC_MAX_PATH_LEN,file)) line[0] = 0;
146 : }
147 1 : nval = sscanf(line,"%" PetscInt_FMT "%" PetscInt_FMT,&src,&dst);
148 1 : PetscCheck(nval==2,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Badly formatted input file");
149 1 : src--; dst--; /* adjust from 1-based to 0-based */
150 1 : if (src>=Istart && src<Iend) PetscCall(MatSetValue(graph->adjacency,src,dst,1.0,INSERT_VALUES));
151 : /* read rest of file */
152 78 : while (fgets(line,PETSC_MAX_PATH_LEN,file)) {
153 77 : nval = sscanf(line,"%" PetscInt_FMT "%" PetscInt_FMT,&src,&dst);
154 77 : PetscCheck(nval==2,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Badly formatted input file");
155 77 : src--; dst--; /* adjust from 1-based to 0-based */
156 155 : if (src>=Istart && src<Iend) PetscCall(MatSetValue(graph->adjacency,src,dst,1.0,INSERT_VALUES));
157 : }
158 1 : PetscCall(PetscFClose(PETSC_COMM_SELF,file));
159 23 : for (i=Istart;i<Iend;i++) PetscCall(MatSetValue(graph->adjacency,i,i,0.0,INSERT_VALUES)); /* diagonal entries */
160 1 : PetscCall(MatAssemblyBegin(graph->adjacency,MAT_FINAL_ASSEMBLY));
161 1 : PetscCall(MatAssemblyEnd(graph->adjacency,MAT_FINAL_ASSEMBLY));
162 1 : PetscFunctionReturn(PETSC_SUCCESS);
163 : }
|