apply_patch_slepc.py
1 #!/usr/bin/env python
2 
3 import os
4 
5 # - we add matsolve in include/slepc/private/stimpl.h in the structure _p_ST :
6  # PetscErrorCode (*matsolve)(Mat A, Vec b, Vec x);
7 # PetscErrorCode (*matsolve_trans)(Mat A, Vec b, Vec x);
8 
9 try:
10  fid = open("include/slepc/private/stimpl.h")
11  lignes = fid.readlines(); fid.close();
12  test_struct = False;
13  for i in range(len(lignes)):
14  if (lignes[i].startswith('struct _p_ST')):
15  test_struct = True;
16 
17  if (test_struct):
18  # pour detecter si le patch a deja ete applique
19  if (lignes[i].find("matsolve") >= 0):
20  test_struct = False;
21 
22  if (lignes[i].startswith('};')):
23  lignes.insert(i, " PetscErrorCode (*matsolve_trans)(Mat A, Vec b, Vec x);\n");
24  lignes.insert(i, " PetscErrorCode (*matsolve)(Mat A, Vec b, Vec x);\n");
25  break;
26 
27  fid = open("include/slepc/private/stimpl.h", 'w')
28  fid.writelines(lignes); fid.close();
29 except:
30  print("Unable to modify include/slepc/private/stimpl.h")
31 
32 
33 # - we modify STMatSolve in src/sys/classes/st/interface/stsles.c to put
34 # if (st->matsolve != NULL)
35 # return (*st->matsolve)(st->A[0], b, x);
36 
37 # et in STMatSolveTranspose
38 # if (st->matsolve_trans != NULL)
39 # return (*st->matsolve_trans)(st->A[0], b, x);
40 try:
41  fid = open("src/sys/classes/st/interface/stsles.c")
42  lignes = fid.readlines(); fid.close();
43  test_func = False; i = 0;
44  while (i < len(lignes)):
45  if (lignes[i].startswith("PetscErrorCode STMatSolve(ST st")):
46  if (lignes[i+2].find("matsolve") == -1):
47  lignes.insert(i+2, " return (*st->matsolve)(st->A[0], b, x);\n");
48  lignes.insert(i+2, " if (st->matsolve != NULL)\n");
49 
50  if (lignes[i].startswith("PetscErrorCode STMatSolveTranspose(ST st")):
51  if (lignes[i+2].find("matsolve") == -1):
52  lignes.insert(i+2, " return (*st->matsolve_trans)(st->A[0], b, x);\n");
53  lignes.insert(i+2, " if (st->matsolve_trans != NULL)\n");
54 
55  i += 1
56 
57  fid = open("src/sys/classes/st/interface/stsles.c", 'w')
58  fid.writelines(lignes); fid.close();
59 except:
60  print("Unable to modify src/sys/classes/st/interface/stsles.c")
61 
62 # - we initialize matsolve in STCreate (stfunc.c)
63 # st->matsolve = NULL;
64 # st->matsolve_trans = NULL;
65 try:
66  fid = open("src/sys/classes/st/interface/stfunc.c")
67  lignes = fid.readlines(); fid.close();
68  i = 0;
69  while (i < len(lignes)):
70  if (lignes[i].startswith("PetscErrorCode STCreate")):
71  j = i; test_solve = False; pos_solve = i+4;
72  while (j < len(lignes)):
73  if (lignes[j].startswith('}')):
74  break;
75 
76  if (lignes[j].find("st->data") >= 0):
77  pos_solve = j+1;
78 
79  if (lignes[j].find("matsolve") >= 0):
80  test_solve = True
81 
82  j += 1
83 
84  if (not test_solve):
85  lignes.insert(pos_solve, " st->matsolve_trans = NULL;\n");
86  lignes.insert(pos_solve, " st->matsolve = NULL;\n");
87 
88  break;
89 
90  i += 1
91 
92  fid = open("src/sys/classes/st/interface/stfunc.c", 'w')
93  fid.writelines(lignes); fid.close();
94 except:
95  print("Unable to modify src/sys/classes/st/interface/stfunc.c")
96 
97 # we modify nleigs.c (corrections for matrix-shell implementation)
98 try:
99  fid = open("src/nep/impls/nleigs/nleigs.c")
100  lignes = fid.readlines(); fid.close()
101  i = 0;
102  while (i < len(lignes)):
103  if (lignes[i].startswith("static PetscErrorCode NEPNLEIGSDividedDifferences_callback")):
104  j = i; pos_bv_create = -1
105  pres_ligne_rand_ctx = False
106  while (j < len(lignes)):
107  if (lignes[j].startswith('}')):
108  break;
109 
110  if (lignes[j].find("BVGetRandomContext") >= 0):
111  pres_ligne_rand_ctx = True
112  ligne_rand_ctx = lignes[j]
113  del lignes[j]
114  j -= 1
115 
116  if (lignes[j].find("MatCreateVecs(D[0]") >= 0):
117  pos_bv_create = j;
118  break;
119 
120  j += 1
121 
122  if (pos_bv_create >= 0):
123  if (lignes[pos_bv_create].find("BVCreate") < 0):
124  lignes.insert(pos_bv_create, " ierr = BVCreate(PetscObjectComm((PetscObject)nep), &nep->V);CHKERRQ(ierr);\n");
125  if (pres_ligne_rand_ctx):
126  lignes.insert(pos_bv_create+1, ligne_rand_ctx)
127 
128  break;
129 
130  i += 1;
131 
132  i = 0
133  while (i < len(lignes)):
134  if (lignes[i].find("MatCreateShell") >= 0):
135  mots = lignes[i].split(',')
136  if (mots[1] == 'n'):
137  chaine = "PetscObject)";
138  pos = lignes[i].find(chaine)
139  name_matrix = lignes[i][pos+len(chaine)];
140  lignes.insert(i, "PetscInt nloc; ierr = MatGetLocalSize("+name_matrix+",&nloc,NULL);CHKERRQ(ierr);\n");
141  lignes[i+1] = mots[0] +", nloc, nloc";
142  for j in range(3, len(mots)):
143  lignes[i+1] += "," + mots[j]
144 
145  i += 1
146  i += 1
147 
148  fid = open("src/nep/impls/nleigs/nleigs.c", "w")
149  fid.writelines(lignes); fid.close();
150 except:
151  print("Unable to modify src/nep/impls/nleigs/nleigs.c")
152 
153 # we add a symbolic link to petsc sources
154 chemin = os.environ.get("PETSC_DIR")
155 presence_src = False
156 for rep in os.listdir(chemin + "/include/petsc"):
157  if (rep == "src"):
158  presence_src = True
159 
160 if (not presence_src):
161  commande_ln = "ln -s " + chemin +"/src " + chemin + "/include/petsc/src"
162  os.system(commande_ln)