Changeset 562d8f in git


Ignore:
Timestamp:
Jul 10, 2019, 7:46:35 PM (5 years ago)
Author:
tthsqe12 <tthsqe12@…>
Branches:
(u'spielwiese', '17f1d200f27c5bd38f5dfc6e8a0879242279d1d8')
Children:
2fb52dfda50207f5e8f1be93c4aed7752b7af4a1
Parents:
c36a59349478e81a9b576d5483791fd3ec54e789
Message:
opt: calculate bits in parallel conversion
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libpolys/polys/flint_mpoly.cc

    rc36a59 r562d8f  
    6464
    6565#if 1
    66 // malloc is not thread safe; singular polynomials must be constructed in serial
     66// memory allocation is not thread safe; singular polynomials must be constructed in serial
    6767
    6868void convSingPFlintMP(fmpq_mpoly_t res, fmpq_mpoly_ctx_t ctx, poly p, int lp, const ring r)
     
    165165
    166166#else
    167 // malloc is thread safe; singular polynomials may be constructed in serial
     167// memory allocator is thread safe; singular polynomials may be constructed in parallel
    168168
    169169// like convSingNFlintN_QQ but it takes an initialized fmpq_t f
     
    199199
    200200    convert_sing_to_fmpq_mpoly_base(slong num_threads_, fmpq_mpoly_struct * res_,
    201                              const fmpq_mpoly_ctx_struct * ctx_, const ring r_)
     201                             const fmpq_mpoly_ctx_struct * ctx_, const ring r_, poly p)
    202202      : num_threads(num_threads_),
    203203        res(res_),
     
    205205        r(r_)
    206206    {
    207     }
    208 
    209     void init_poly(poly p)
    210     {
    211207        length = 0;
    212         while (p != NULL)
     208        while (1)
    213209        {
    214             markers.push_back(p);
    215             for (int i = 4096; i > 0; i--)
    216             {
    217                 pIter(p);
    218                 length++;
    219                 if (p == NULL)
    220                     break;
    221             }
     210            if ((length % 4096) == 0)
     211                markers.push_back(p);
     212            if (p == NULL)
     213                return;
     214            length++;
     215            pIter(p);
    222216        }
    223 
    224         fmpq_mpoly_init3(res, length, SI_LOG2(r->bitmask), ctx);
    225217    }
    226218};
     
    232224    slong start_idx, end_idx;
    233225    convert_sing_to_fmpq_mpoly_base* base;
     226    flint_bitcnt_t required_bits;
    234227
    235228    convert_sing_to_fmpq_mpoly_arg() {fmpq_init(content);}
     
    237230};
    238231
    239 static void convert_sing_to_fmpq_mpoly_content_worker(void * varg)
     232static void convert_sing_to_fmpq_mpoly_content_bits(void * varg)
    240233{
    241234    convert_sing_to_fmpq_mpoly_arg* arg = (convert_sing_to_fmpq_mpoly_arg*) varg;
     235    convert_sing_to_fmpq_mpoly_base * base = arg->base;
     236    ulong * exp = (ulong*) flint_malloc((base->r->N + 1)*sizeof(ulong));
    242237    fmpq_t c;
    243238    fmpq_init(c);
     
    252247    }
    253248
    254     /* first find gcd of coeffs */
     249    flint_bitcnt_t required_bits = MPOLY_MIN_BITS;
    255250    fmpq_zero(arg->content);
     251
    256252    while (idx < arg->end_idx)
    257253    {
    258254        my_convSingNFlintN_QQ(c, number(pGetCoeff(p)));
    259255        fmpq_gcd(arg->content, arg->content, c);
     256
     257        #if SIZEOF_LONG==8
     258        p_GetExpVL(p, (int64*)exp, base->r);
     259        flint_bitcnt_t exp_bits = mpoly_exp_bits_required_ui(exp, base->ctx->zctx->minfo);
     260        #else
     261        p_GetExpV(p, (int*)exp, base->r);
     262        flint_bitcnt_t exp_bits = mpoly_exp_bits_required_ui(&(exp[1]), base->ctx->zctx->minfo);
     263        #endif
     264
     265        required_bits = FLINT_MAX(required_bits, exp_bits);
     266
    260267        pIter(p);
    261268        idx++;
    262269    }
    263270
     271    arg->required_bits = required_bits;
     272
    264273    fmpq_clear(c);
     274    flint_free(exp);
    265275}
    266276
     
    330340    }
    331341
    332     convert_sing_to_fmpq_mpoly_base base(num_handles + 1, res, ctx, r);
    333     base.init_poly(p);
    334 
     342    convert_sing_to_fmpq_mpoly_base base(num_handles + 1, res, ctx, r, p);
     343
     344    /* fill in thread division points */
    335345    convert_sing_to_fmpq_mpoly_arg * args = new convert_sing_to_fmpq_mpoly_arg[base.num_threads];
    336346    slong cur_idx = 0;
     
    346356    }
    347357
    348     /* get content */
    349     for (slong i = 0; i < num_handles; i++)
    350         thread_pool_wake(global_thread_pool, handles[i], convert_sing_to_fmpq_mpoly_content_worker, args + i);
    351     convert_sing_to_fmpq_mpoly_content_worker(args + num_handles);
    352     for (slong i = 0; i < num_handles; i++)
    353     {
     358    /* get content and bits */
     359    for (slong i = 0; i < num_handles; i++)
     360        thread_pool_wake(global_thread_pool, handles[i], convert_sing_to_fmpq_mpoly_content_bits, args + i);
     361    convert_sing_to_fmpq_mpoly_content_bits(args + num_handles);
     362    for (slong i = 0; i < num_handles; i++)
    354363        thread_pool_wait(global_thread_pool, handles[i]);
    355     }
     364
     365    flint_bitcnt_t required_bits = MPOLY_MIN_BITS;
     366    for (slong i = 0; i <= num_handles; i++)
     367        required_bits = FLINT_MAX(required_bits, args[i].required_bits);
     368
     369    /* initialize res with optimal bits */
     370    fmpq_mpoly_init3(res, base.length, mpoly_fix_bits(required_bits, ctx->zctx->minfo), ctx);
    356371
    357372    /* sign of content should match sign of first coeff */
     
    418433    convert_fmpq_mpoly_to_sing_arg * arg = (convert_fmpq_mpoly_to_sing_arg *) varg;
    419434    convert_fmpq_mpoly_to_sing_base * base = arg->base;
    420     ulong* exp = (ulong*) flint_calloc(base->r->N + 1, sizeof(ulong));
     435    ulong* exp = (ulong*) flint_malloc((base->r->N + 1)*sizeof(ulong));
    421436    fmpq_t c;
    422437    fmpq_init(c);
     
    528543
    529544    convert_sing_to_nmod_mpoly_base(slong num_threads_, nmod_mpoly_struct * res_,
    530                             const nmod_mpoly_ctx_struct * ctx_, const ring r_)
     545                            const nmod_mpoly_ctx_struct * ctx_, const ring r_, poly p)
    531546      : num_threads(num_threads_),
    532547        res(res_),
     
    534549        r(r_)
    535550    {
    536     }
    537 
    538     void init_poly(poly p)
    539     {
    540551        length = 0;
    541         while (p != NULL)
     552        while (1)
    542553        {
    543             markers.push_back(p);
    544             for (int i = 4096; i > 0; i--)
    545             {
    546                 pIter(p);
    547                 length++;
    548                 if (p == NULL)
    549                     break;
    550             }
     554            if ((length % 4096) == 0)
     555                markers.push_back(p);
     556            if (p == NULL)
     557                return;
     558            length++;
     559            pIter(p);
    551560        }
    552 
    553         nmod_mpoly_init3(res, length, SI_LOG2(r->bitmask), ctx);
    554561    }
    555562};
     
    560567    slong start_idx, end_idx;
    561568    convert_sing_to_nmod_mpoly_base* base;
     569    flint_bitcnt_t required_bits;
    562570};
     571
     572static void convert_sing_to_nmod_mpoly_bits(void * varg)
     573{
     574    convert_sing_to_nmod_mpoly_arg * arg = (convert_sing_to_nmod_mpoly_arg *) varg;
     575    convert_sing_to_nmod_mpoly_base * base = arg->base;
     576    ulong * exp = (ulong*) flint_malloc((base->r->N + 1)*sizeof(ulong));
     577
     578    slong idx = arg->start_idx/4096;
     579    poly p = base->markers[idx];
     580    idx *= 4096;
     581    while (idx < arg->start_idx)
     582    {
     583        pIter(p);
     584        idx++;
     585    }
     586
     587    flint_bitcnt_t required_bits = MPOLY_MIN_BITS;
     588
     589    while (idx < arg->end_idx)
     590    {
     591        #if SIZEOF_LONG==8
     592        p_GetExpVL(p, (int64*)exp, base->r);
     593        flint_bitcnt_t exp_bits = mpoly_exp_bits_required_ui(exp, base->ctx->minfo);
     594        #else
     595        p_GetExpV(p, (int*)exp, base->r);
     596        flint_bitcnt_t exp_bits = mpoly_exp_bits_required_ui(&(exp[1]), base->ctx->minfo);
     597        #endif
     598
     599        required_bits = FLINT_MAX(required_bits, exp_bits);
     600
     601        pIter(p);
     602        idx++;
     603    }
     604
     605    arg->required_bits = required_bits;
     606
     607    flint_free(exp);
     608}
     609
    563610
    564611static void convert_sing_to_nmod_mpoly_worker(void * varg)
     
    618665    }
    619666
    620     convert_sing_to_nmod_mpoly_base base(num_handles + 1, res, ctx, r);
    621     base.init_poly(p);
    622 
     667    convert_sing_to_nmod_mpoly_base base(num_handles + 1, res, ctx, r, p);
     668
     669    /* fill in thread division points */
    623670    convert_sing_to_nmod_mpoly_arg * args = new convert_sing_to_nmod_mpoly_arg[base.num_threads];
    624671    slong cur_idx = 0;
     
    635682    }
    636683
     684    /* find required bits */
     685    for (slong i = 0; i < num_handles; i++)
     686        thread_pool_wake(global_thread_pool, handles[i], convert_sing_to_nmod_mpoly_bits, args + i);
     687    convert_sing_to_nmod_mpoly_bits(args + num_handles);
     688    for (slong i = 0; i < num_handles; i++)
     689        thread_pool_wait(global_thread_pool, handles[i]);
     690
     691    flint_bitcnt_t required_bits = MPOLY_MIN_BITS;
     692    for (slong i = 0; i <= num_handles; i++)
     693        required_bits = FLINT_MAX(required_bits, args[i].required_bits);
     694
     695    /* initialize res with optimal bits */
     696    nmod_mpoly_init3(res, base.length, mpoly_fix_bits(required_bits, ctx->minfo), ctx);
     697
    637698    /* fill in res */
    638699    for (slong i = 0; i < num_handles; i++)
     
    685746    convert_nmod_mpoly_to_sing_arg * arg = (convert_nmod_mpoly_to_sing_arg *) varg;
    686747    convert_nmod_mpoly_to_sing_base * base = arg->base;
    687     ulong* exp = (ulong*) flint_calloc(base->r->N + 1, sizeof(ulong));
     748    ulong* exp = (ulong*) flint_malloc((base->r->N + 1)*sizeof(ulong));
    688749
    689750    for (slong idx = arg->end_idx - 1; idx >= arg->start_idx; idx--)
Note: See TracChangeset for help on using the changeset viewer.