source: git/kernel/GBEngine/kChinese.cc @ 7090a8b

spielwiese
Last change on this file since 7090a8b was 7090a8b, checked in by Hans Schoenemann <hannes@…>, 3 years ago
add: id_Farey_0: farey in Q[x] parallel version
  • Property mode set to 100644
File size: 8.7 KB
Line 
1#include "misc/auxiliary.h"
2
3#include "misc/intvec.h"
4#include "misc/options.h"
5#include "polys/monomials/p_polys.h"
6#include "polys/matpol.h"
7#include "polys/simpleideals.h"
8#include "coeffs/longrat.h"
9#include "Singular/feOpt.h"
10#include "kernel/polys.h"
11
12#define mpz_isNeg(A) ((A)->_mp_size<0)
13number nlRInit (long i);
14
15#include "kernel/oswrapper/vspace.h"
16#include "kernel/ideals.h"
17#include <sys/types.h>
18#include <sys/wait.h>
19
20// send a number via a string s
21static char *send_number(char *s, number n)
22{
23  long *d=(long*)s;
24  if (SR_HDL(n) & SR_INT)
25  {
26    *d=(long)n;
27    s+=SIZEOF_LONG;
28  }
29  else
30  {
31    *d=n->s*2;/* n->s in 0..3: 0..6, use +8 for neg. numbers */
32    s+=SIZEOF_LONG;
33    if (mpz_isNeg(n->z)) { *d+=8; mpz_neg(n->z,n->z); }
34    size_t l;
35    d=(long*)s;
36    s+=SIZEOF_LONG;
37    mpz_export(s,&l,-1,sizeof(mp_limb_t),0,0,n->z);
38    *d=l;
39    s+=l*sizeof(mp_limb_t);
40    if (n->s!=3)
41    {
42      d=(long*)s;
43      s+=SIZEOF_LONG;
44      mpz_export(s,&l,-1,sizeof(mp_limb_t),0,0,n->n);
45      *d=l;
46      s+=l*sizeof(mp_limb_t);
47    }
48  }
49  return s;
50}
51
52static char * get_number(char *s, number *n)
53{
54  // format: last bit 1: imm. number (long)
55  //         otherwise: 0,2: size(long) mpz, size(long) mpz
56  //                    6: size(long) mpz
57  //                    8,10: size(long) -mpz, size(long) mpz
58  //                    14: size(long) -mpz
59  long *d=(long*)s;
60  s+=SIZEOF_LONG;
61  if (((*d)&1)==1) // immidiate number
62  {
63    *n=(number)(*d); 
64  }
65  else
66  {
67    *n=nlRInit(0);
68    BOOLEAN neg=(*d>=8);
69    if (neg) *d-=8;
70    (*n)->s=(*d)/2;
71    d=(long*)s;
72    s+=SIZEOF_LONG;
73    size_t l=*d;
74    mpz_realloc2((*n)->z,l*sizeof(mp_limb_t)*8);
75    mpz_import((*n)->z,l,-1,sizeof(mp_limb_t),0,0,s);
76    if (neg) mpz_neg((*n)->z,(*n)->z);
77    s+=l*sizeof(mp_limb_t);
78    if ((*n)->s!=3)
79    {
80      d=(long*)s;
81      s+=SIZEOF_LONG;
82      l=*d;
83      mpz_init2((*n)->n,l*sizeof(mp_limb_t)*8);
84      mpz_import((*n)->n,l,-1,sizeof(mp_limb_t),0,0,s);
85      s+=l*sizeof(mp_limb_t);
86    }
87  }
88  return s;
89}
90
91static long size_number(number n)
92{
93  long ll=SIZEOF_LONG;
94  if (SR_HDL(n) & SR_INT)
95  {
96    return SIZEOF_LONG;
97  }
98  else
99  {
100    if (n->s==3) 
101    {
102      ll+=SIZEOF_LONG*2; /* n->s, mpz size */
103      long l=mpz_size1(n->z);
104      ll+=l*sizeof(mp_limb_t);
105    }
106    else
107    {
108      ll+=SIZEOF_LONG*3; /* n->s, mpz size(n->z) mpz size(n->n)*/
109      size_t l=mpz_size1(n->z);
110      ll+=l*sizeof(mp_limb_t);
111      l=mpz_size1(n->n);
112      ll+=l*sizeof(mp_limb_t);
113    }
114  }
115  return ll;
116}
117
118static char* send_mon(char *s, poly m, const ring r)
119{
120  // format: number exp[0..r->ExpL_Size]
121  s=send_number(s,p_GetCoeff(m,r));
122  memcpy(s,m->exp,r->ExpL_Size*sizeof(long));
123  s+=r->ExpL_Size*sizeof(long);
124  return s;
125}
126
127static char* get_mon(char *s, poly *m, const ring r)
128{
129  (*m)=p_Init(r);
130  s=get_number(s,&p_GetCoeff(*m,r));
131  memcpy((*m)->exp,s,r->ExpL_Size*sizeof(long));
132  s+=r->ExpL_Size*sizeof(long);
133  return s;
134}
135
136static long size_mon(poly m, const ring r)
137{
138  long ll=size_number(p_GetCoeff(m,r));
139  ll+=r->ExpL_Size*sizeof(long);
140  return ll;
141}
142
143static char* send_poly(char *s, int ind, poly p, const ring r)
144{
145  // format: index(long) length(long) mon...
146  //p_Write(p,r);PrintLn();
147  long *d=(long*)s;
148  *d=ind;
149  s+=SIZEOF_LONG;
150  long l=pLength(p);
151  d=(long*)s;
152  *d=l;
153  s+=SIZEOF_LONG;
154  while(p!=NULL)
155  {
156    s=send_mon(s,p,r);
157    pIter(p);
158  }
159  return s;
160}
161
162static char* get_poly(char *s,int &ind, poly *p,const ring r)
163{
164  long *d=(long*)s;
165  ind=*d;
166  s+=SIZEOF_LONG;
167  d=(long*)s;
168  long l=*d;
169  s+=SIZEOF_LONG;
170  for(long i=0;i<l;i++)
171  {
172    poly m;
173    s=get_mon(s,&m,r);
174    pNext(m)=*p;
175    *p=m;
176  }
177  *p=pReverse(*p);
178  return s;
179}
180
181static long size_poly(poly p, const ring r)
182{
183  long l=SIZEOF_LONG*2;
184  while(p!=NULL)
185  {
186    l+=size_mon(p,r);
187    pIter(p);
188  }
189  return l;
190}
191
192ideal id_ChineseRemainder_0(ideal *xx, number *q, int rl, const ring r)
193{
194  int cnt=0;int rw=0; int cl=0;
195  // find max. size of xx[.]:
196  for(int j=rl-1;j>=0;j--)
197  {
198    int i=IDELEMS(xx[j])*xx[j]->nrows;
199    if (i>cnt) cnt=i;
200    if (xx[j]->nrows >rw) rw=xx[j]->nrows; // for lifting matrices
201    if (xx[j]->ncols >cl) cl=xx[j]->ncols; // for lifting matrices
202  }
203  if (rw*cl !=cnt)
204  {
205    WerrorS("format mismatch in CRT");
206    return NULL;
207  }
208  int cpus=(int)(long)feOptValue(FE_OPT_CPUS);
209  if (2*cpus>=cnt) /* at least 2 polys for each process,
210                     or switch to seriell version */
211    return id_ChineseRemainder(xx,q,rl,r);
212  ideal result=idInit(cnt,xx[0]->rank);
213  result->nrows=rw; // for lifting matrices
214  result->ncols=cl; // for lifting matrices
215  int parent_pid=getpid();
216  using namespace vspace;
217  vmem_init();
218  // Create a queue of int
219  VRef<Queue<int> > queue = vnew<Queue<int> >();
220  for(int i=cnt-1;i>=0; i--)
221  {
222    queue->enqueue(i); // the tasks: construct poly p[i]
223  }
224  for(int i=cpus;i>=0;i--)
225  {
226    queue->enqueue(-1); // stop sign, one for each child
227  }
228  // Create a queue of polys
229  VRef<Queue<VRef<VString> > > rqueue = vnew<Queue<VRef<VString> > >();
230  for (int i=0;i<cpus;i++)
231  {
232    int pid = fork_process();
233    if (pid==0) break; //child
234  }
235  if (parent_pid!=getpid()) // child ------------------------------------------
236  {
237    number *x=(number *)omAlloc(rl*sizeof(number));
238    poly *p=(poly *)omAlloc(rl*sizeof(poly));
239    CFArray inv_cache(rl);
240    EXTERN_VAR int n_SwitchChinRem;
241    n_SwitchChinRem=1;
242    loop
243    {
244      int ind=queue->dequeue();
245      if (ind== -1)
246      {
247        exit(0);
248      }
249
250      for(int j=rl-1;j>=0;j--)
251      {
252        if(ind>=IDELEMS(xx[j])*xx[j]->nrows) // out of range of this ideal
253          p[j]=NULL;
254        else
255          p[j]=xx[j]->m[ind];
256      }
257      poly res=p_ChineseRemainder(p,x,q,rl,inv_cache,r);
258      long l=size_poly(res,r);
259      //printf("size: %ld kB\n",(l+1023)/1024);
260      VRef<VString> msg = vstring(l+1);
261      char *s=(char*)msg->str();
262      send_poly(s,ind,res,r);
263      rqueue->enqueue(msg);
264      if (TEST_OPT_PROT) printf(".");
265    }
266  }
267  else // parent ---------------------------------------------------
268  {
269    if (TEST_OPT_PROT) printf("%d childs created\n",cpus);
270    VRef<VString> msg;
271    while(cnt>0)
272    {
273      msg=rqueue->dequeue();
274      char *s=(char*)msg->str();
275      int ind;
276      poly p=NULL;
277      get_poly(s,ind,&p,r);
278      //printf("got res[%d]\n",ind);
279      result->m[ind]=p;
280      msg.free();
281      cnt--;
282    }
283    // removes queues
284    queue.free();
285    rqueue.free();
286    vmem_deinit();
287  }
288  return result;
289}
290
291ideal id_Farey_0(ideal x, number N, const ring r)
292{
293  int cnt=IDELEMS(x)*x->nrows;
294  int cpus=(int)(long)feOptValue(FE_OPT_CPUS);
295  if (2*cpus>=cnt) /* at least 2 polys for each process,
296                     or switch to seriell version */
297    return id_Farey(x,N,r);
298  ideal result=idInit(cnt,x->rank);
299  result->nrows=x->nrows; // for lifting matrices
300  result->ncols=x->ncols; // for lifting matrices
301
302  int parent_pid=getpid();
303  using namespace vspace;
304  vmem_init();
305  // Create a queue of int
306  VRef<Queue<int> > queue = vnew<Queue<int> >();
307  for(int i=cnt-1;i>=0; i--)
308  {
309    queue->enqueue(i); // the tasks: construct poly p[i]
310  }
311  for(int i=cpus;i>=0;i--)
312  {
313    queue->enqueue(-1); // stop sign, one for each child
314  }
315  // Create a queue of polys
316  VRef<Queue<VRef<VString> > > rqueue = vnew<Queue<VRef<VString> > >();
317  for (int i=0;i<cpus;i++)
318  {
319    int pid = fork_process();
320    if (pid==0) break; //child
321  }
322  if (parent_pid!=getpid()) // child ------------------------------------------
323  {
324    loop
325    {
326      int ind=queue->dequeue();
327      if (ind== -1)
328      {
329        exit(0);
330      }
331
332      poly res=p_Farey(x->m[ind],N,r);
333      long l=size_poly(res,r);
334      VRef<VString> msg = vstring(l+1);
335      char *s=(char*)msg->str();
336      send_poly(s,ind,res,r);
337      rqueue->enqueue(msg);
338      if (TEST_OPT_PROT) printf(".");
339    }
340  }
341  else // parent ---------------------------------------------------
342  {
343    if (TEST_OPT_PROT) printf("%d childs created\n",cpus);
344    VRef<VString> msg;
345    while(cnt>0)
346    {
347      msg=rqueue->dequeue();
348      char *s=(char*)msg->str();
349      int ind;
350      poly p=NULL;
351      get_poly(s,ind,&p,r);
352      //printf("got res[%d]\n",ind);
353      result->m[ind]=p;
354      msg.free();
355      cnt--;
356    }
357    // removes queues
358    queue.free();
359    rqueue.free();
360    vmem_deinit();
361  }
362  return result;
363}
364
365void test_n(poly n)
366{
367  p_Write(n,currRing);
368  char *buf=(char*)omAlloc0(2048*1000);
369  int ll=size_poly(n,currRing);
370  printf("size: %d\n",ll);
371  char *s=send_poly(buf,12345,n,currRing);
372  printf("send len: %d\n",(int)(s-buf));
373  long *d=(long*)buf;
374  for(int i=0;i<=ll/SIZEOF_LONG;i++) printf("%ld ",d[i]);
375  printf("\n");
376  n=NULL;
377  s=get_poly(buf,ll,&n,currRing);
378  printf("read len: %d\n",(int)(s-buf));
379  Print(":index: %d\n",ll);
380  p_Write(n,currRing);
381  PrintLn();
382  omFree(buf);
383}
Note: See TracBrowser for help on using the repository browser.