// TODO: Can use dynamic scheduling here int BuildNeigh( void* arg, int id ) { double rd, cutoffSquare; int i,j; cutoffSquare = (cutoffRadius * TOLERANCE)*(cutoffRadius * TOLERANCE); for (i = (numMoles / NTHREADS) * id; i < (numMoles / NTHREADS) * (id + 1); ++i) { for (j = i+1; j<numMoles; j++ ) { rd = Foo ( (double)x[IND(0,i)], (double)x[IND(1,i)], (double)x[IND(2,i)], (double)x[IND(0,j)], (double)x[IND(1,j)], (double)x[IND(2,j)]); if (rd > cutoffSquare) { continue; } BEGIN_TRANSACTION(); //printf("APP: writing i: %x (%x), with value: %d\n", &inter[INDX(ninter,0)], &(inter[INDX(ninter,0)]._value), i); inter[INDX(ninter,0)] = i; //printf("APP: writing j: %x (%x), with value: %d\n", &inter[INDX(ninter,1)], &(inter[INDX(ninter,1)]._value), j); inter[INDX(ninter,1)] = j; ++ninter; COMMIT_TRANSACTION(); if ( ninter >= MAXINTERACT) { perror("MAXINTERACT limit"); } } } return 0; }
void trialswap(int *m, int *nr, int *nc, int *thin) { int i, a, b, c, d, row[2], col[2]; GetRNGstate(); for (i=0; i < *thin; i++) { i2rand(row, (*nr) - 1); i2rand(col, (*nc) - 1); a = INDX(row[0], col[0], *nr); b = INDX(row[0], col[1], *nr); c = INDX(row[1], col[0], *nr); d = INDX(row[1], col[1], *nr); if (m[a] == 1 && m[d] == 1 && m[b] == 0 && m[c] == 0) { m[a] = 0; m[d] = 0; m[b] = 1; m[c] = 1; } else if (m[c] == 1 && m[b] == 1 && m[d] == 0 && m[a] == 0) { m[a] = 1; m[d] = 1; m[b] = 0; m[c] = 0; } } PutRNGstate(); }
void PrintInteractionList(INPARAMS int ninter) { int i; printf("%d\n", ninter); for (i=0;i<ninter;i++) { printf("%d %d\n", (int)inter[INDX(i,0)], (int)inter[INDX(i,1)]); } }
//we should use dynamic scheduling here int BuildNeigh( void* arg, int id ) { double rd, cutoffSquare; int i,j; //double Foo(); cutoffSquare = (cutoffRadius * TOLERANCE)*(cutoffRadius * TOLERANCE); for (i = id; i < numMoles; i += NTHREADS) { num_neighbours [i] = 0; //resetting these two as well counter_f [i] = 0; counter_x [i] = 0; } //for ( i=0; i<numMoles; i++) //single-threaded version for ( i=id; i<numMoles; i+=NTHREADS) { //BEGIN_TRANSACTION(); //if (id == 0) { for ( j = i+1; j<numMoles; j++ ) { //x is global var, would need exclusive access unless this method is surrounded //by barriers, because while x is only read here (and not written), other methods //do write to x. rd = Foo ( (double)x[IND(0,i)], (double)x[IND(1,i)], (double)x[IND(2,i)], (double)x[IND(0,j)], (double)x[IND(1,j)], (double)x[IND(2,j)]); if ( rd <= cutoffSquare) { //inter[] and ninter are global vars, need exclusive access //do this more efficiently? atomic read pthread_mutex_lock (&mutex_ninter); inter[INDX(ninter,0)] = i; inter[INDX(ninter,1)] = j; //make sure atomic_inc works properly, try pthread_mutex_lock to double-check //atomic_inc (&ninter); ninter ++; num_neighbours [i] ++; num_neighbours [j] ++; pthread_mutex_unlock (&mutex_ninter); //this is a useless statement if ( ninter >= MAXINTERACT) perror("MAXINTERACT limit"); } } //COMMIT_TRANSACTION(); //} } return 0; }
void rswapcount(double *m, int *nr, int *nc, int *mfill) { int row[2], col[2], i, k, ij[4], n, change, cfill, pm[4] = {1, -1, -1, 1} ; double sm[4], ev; /* Get the current fill 'cfill' */ n = (*nr) * (*nc); for (i = 0, cfill=0; i < n; i++) { if (m[i] > 0) cfill++; } GetRNGstate(); /* Loop while fills differ */ while (cfill != *mfill) { /* Select a random 2x2 matrix*/ i2rand(row, *nr - 1); i2rand(col, *nc - 1); ij[0] = INDX(row[0], col[0], *nr); ij[1] = INDX(row[1], col[0], *nr); ij[2] = INDX(row[0], col[1], *nr); ij[3] = INDX(row[1], col[1], *nr); for (k = 0; k < 4; k ++) sm[k] = m[ij[k]]; /* The largest value that can be swapped */ ev = isDiag(sm); if (ev != 0) { /* Check the change in fills */ for (k = 0, change=0; k < 4; k++) { if(sm[k] > 0) change--; if (sm[k] + pm[k]*ev > 0) change++; } /* Fill does not change, but swap to bail out from * non-swappable configurations */ if (change == 0) { for (k = 0; k < 4; k++) m[ij[k]] += pm[k]*ev; } else if ((change < 0 && *mfill < cfill) || (change > 0 && *mfill > cfill)) { for (k = 0; k < 4; k++) m[ij[k]] += pm[k]*ev; cfill += change; } } } PutRNGstate(); }
static void swap(int *m, int *nr, int *nc, int *thin) { int i, a, b, c, d, row[2], col[2], nr1 = (*nr) - 1, nc1 = (*nc) -1, n1 = (*nr) * (*nc) - 1; size_t intcheck; /* Get and Put RNG in calling C function */ /* GetRNGstate(); */ for (i=0, intcheck=0; i < *thin; i++) { for(;;) { if (intcheck % 10000 == 9999) R_CheckUserInterrupt(); intcheck++; /* see trialswap & quasiswap for the logic */ a = IRAND(n1); row[0] = a % (*nr); col[0] = a / (*nr); do {row[1] = IRAND(nr1);} while (row[1] == row[0]); c = INDX(row[1], col[0], *nr); /* bail out before next row if non-swappable */ if (m[a] == m[c]) continue; do {col[1] = IRAND(nc1);} while (col[1] == col[0]); b = INDX(row[0], col[1], *nr); d = INDX(row[1], col[1], *nr); /* if we are here m[a] != m[c], and only three elements need be tested for the unique matrix -- start from tests that fail most likely */ if (m[d] == 1 && m[a] == 1 && m[b] == 0) { m[a] = 0; m[d] = 0; m[b] = 1; m[c] = 1; break; } if (m[b] == 1 && m[c] == 1 && m[d] == 0) { m[a] = 1; m[d] = 1; m[b] = 0; m[c] = 0; break; } } } /* PutRNGstate(); */ }
void quasiswap(int *m, int *nr, int *nc) { int i, n, mtot, ss, row[2], col[2], nr1, nc1, a, b, c, d; nr1 = (*nr) - 1; nc1 = (*nc) - 1; /* Get matrix total 'mtot' and sum-of-squares 'ss' */ n = (*nr) * (*nc); for (i = 0, mtot = 0, ss = 0; i < n; i++) { mtot += m[i]; ss += m[i] * m[i]; } /* Get R RNG */ GetRNGstate(); /* Quasiswap while there are entries > 1 */ while (ss > mtot) { i2rand(row, nr1); i2rand(col, nc1); /* a,b,c,d notation for a 2x2 table */ a = INDX(row[0], col[0], *nr); b = INDX(row[0], col[1], *nr); c = INDX(row[1], col[0], *nr); d = INDX(row[1], col[1], *nr); if (m[a] > 0 && m[d] > 0 && m[a] + m[d] - m[b] - m[c] >= 2) { ss -= 2 * (m[a] + m[d] - m[b] - m[c] - 2); m[a]--; m[d]--; m[b]++; m[c]++; } else if (m[b] > 0 && m[c] > 0 && m[b] + m[c] - m[a] - m[d] >= 2) { ss -= 2 * (m[b] + m[c] - m[a] - m[d] - 2); m[a]++; m[d]++; m[b]--; m[c]--; } } /* Set R RNG */ PutRNGstate(); }
static void trialswap(int *m, int *nr, int *nc, int *thin) { int i, a, b, c, d, row[2], col[2]; /* Get and Set RNG in calling C function */ /* GetRNGstate(); */ for (i=0; i < *thin; i++) { /* get corner item m[a] and its row and column index */ a = IRAND((*nr) * (*nc) - 1); row[0] = a % (*nr); col[0] = a / (*nr); /* get its side-by-side neighbour in a different row */ do {row[1] = IRAND((*nr) - 1);} while (row[1] == row[0]); c = INDX(row[1], col[0], *nr); /* not swappable if neighbours are identical: bail out at probability (1-f)^2 + f^2 where f is the relative column fill */ if (m[a] == m[c]) continue; /* get second col and its items */ do {col[1] = IRAND((*nc) - 1);} while (col[1] == col[0]); b = INDX(row[0], col[1], *nr); d = INDX(row[1], col[1], *nr); /* there are 16 possible matrices, but only two can be * swapped. Find signature of each matrix with bitwise shift * and OR. */ switch(m[a] | m[b] << 1 | m[c] << 2 | m[d] << 3) { case 6: /* 0110 -> 1001 */ m[a] = 1; m[b] = 0; m[c] = 0; m[d] = 1; break; case 9: /* 1001 -> 0110 */ m[a] = 0; m[b] = 1; m[c] = 1; m[d] = 0; break; default: break; } } /* PutRNGstate(); */ }
static void curveball(int *m, int *nr, int *nc, int *thin, int *uniq) { int row[2], i, j, jind, ind, nsp1, nsp2, itmp, tmp; /* Set RNG in calling C code */ /* GetRNGstate(); */ for (i = 0; i < *thin; i++) { /* Random sites */ I2RAND(row, (*nr)-1); /* uniq is a vector of unique species for a random pair of rows, It need not be zeroed between thin loops because ind keeps track of used elements. */ for (j = 0, ind = -1, nsp1 = 0, nsp2 = 0; j < (*nc); j++) { jind = j * (*nr); if (m[row[0] + jind] > 0 && m[row[1] + jind] == 0) { uniq[++ind] = j; nsp1++; } if (m[row[1] + jind] > 0 && m[row[0] + jind] == 0) { uniq[++ind] = j; nsp2++; } } /* uniq contains indices of unique species: shuffle these and * allocate nsp1 first to row[0] and the rest to row[1] */ if (nsp1 > 0 && nsp2 > 0) { /* something to swap? */ for (j = ind; j >= nsp1; j--) { itmp = IRAND(j); tmp = uniq[j]; uniq[j] = uniq[itmp]; uniq[itmp] = tmp; } for (j = 0; j < nsp1; j++) { m[INDX(row[0], uniq[j], *nr)] = 1; m[INDX(row[1], uniq[j], *nr)] = 0; } for (j = nsp1; j <= ind; j++) { m[INDX(row[0], uniq[j], *nr)] = 0; m[INDX(row[1], uniq[j], *nr)] = 1; } } } /* PutRNGstate(); */ }
T Selector::sub_select(const T &x, const Selector &rhs) const { assert(rhs.nvars() <= this->nvars()); assert(this->covers(rhs)); Selector tmp(nvars(), false); for (uint i = 0; i < rhs.nvars(); ++i) { tmp.add(INDX(rhs.indx(i))); } return tmp.select(x); }
void abuswap(double *m, int *nr, int *nc, int *thin, int *direct) { int row[2], col[2], k, ij[4], changed, ev ; double sm[4]; GetRNGstate(); changed = 0; while (changed < *thin) { /* Select a random 2x2 matrix*/ i2rand(row, *nr - 1); i2rand(col, *nc - 1); ij[0] = INDX(row[0], col[0], *nr); ij[1] = INDX(row[1], col[0], *nr); ij[2] = INDX(row[0], col[1], *nr); ij[3] = INDX(row[1], col[1], *nr); for (k = 0; k < 4; k ++) sm[k] = m[ij[k]]; ev = isDiagSimple(sm); /* Swap */ if (ev == 1) { /* fixed column sums */ if (*direct == 0) { m[ij[0]] = sm[1]; m[ij[1]] = sm[0]; m[ij[2]] = sm[3]; m[ij[3]] = sm[2]; } /* fixed row sums */ else { m[ij[0]] = sm[2]; m[ij[1]] = sm[3]; m[ij[2]] = sm[0]; m[ij[3]] = sm[1]; } changed++; } } PutRNGstate(); }
void PrintConnectivity() { int ii, i; int min, max; float sum, sumsq, stdev, avg; bzero((char *)connect, sizeof(int) * NUM_PARTICLES); for (ii=0; ii<ninter; ii++) { assert(inter[INDX(ii,0)] < NUM_PARTICLES); assert(inter[INDX(ii,1)] < NUM_PARTICLES); connect[inter[INDX(ii,0)]]++; connect[inter[INDX(ii,1)]]++; } sum = 0.0; sumsq = 0.0; sum = connect[0]; sumsq = SQR(connect[0]); min = connect[0]; max = connect[0]; for (i=1; i<NUM_PARTICLES; i++) { sum += connect[i]; sumsq += SQR(connect[i]); if (min > connect[i]) min = connect[i]; if (max < connect[i]) max = connect[i]; } avg = sum / NUM_PARTICLES; stdev = sqrt((sumsq / NUM_PARTICLES) - SQR(avg)); printf("avg = %4.1lf, dev = %4.1lf, min = %d, max = %d\n", avg, stdev, min, max); }
void swapcount(double *m, int *nr, int *nc, int *thin) { int row[2], col[2], k, ij[4], changed, oldn, newn, pm[4] = {1, -1, -1, 1} ; double sm[4], ev; GetRNGstate(); changed = 0; while (changed < *thin) { /* Select a random 2x2 matrix*/ i2rand(row, *nr - 1); i2rand(col, *nc - 1); ij[0] = INDX(row[0], col[0], *nr); ij[1] = INDX(row[1], col[0], *nr); ij[2] = INDX(row[0], col[1], *nr); ij[3] = INDX(row[1], col[1], *nr); for (k = 0; k < 4; k ++) sm[k] = m[ij[k]]; /* The largest value that can be swapped */ ev = isDiag(sm); if (ev != 0) { /* Check that the fill doesn't change*/ for (k = 0, oldn = 0, newn = 0; k < 4; k++) { if(sm[k] > 0) oldn++; if (sm[k] + pm[k]*ev > 0) newn++; } /* Swap */ if (oldn == newn) { for (k = 0; k < 4; k++) m[ij[k]] += pm[k]*ev; changed++; } } } PutRNGstate(); }
//we should use dynamic scheduling here int ComputeForces( void* arg, int id ) { double cutoffSquare; double xx, yy, zz, rd, rrd, rrd2, rrd3, rrd4, rrd5, rrd6, rrd7, r148; double forcex, forcey, forcez; int i,j,ii; double vir_tmp = 0; double epot_tmp = 0; cutoffSquare = cutoffRadius*cutoffRadius ; //ninter is global var, needs exclusive access unless this method is protected //by barriers from methods that modify ninter. //Similarly, x and inter are global vars, and need exclusive access; they are also //a reason why this method needs to be protected by barriers from methods that //modify x and inter; specifically, you do not want some threads executing some //other method that modifies x or inter or ninter, and some threads executing this //method, where these variables are read. //keep in mind you need to protect the shared variables accessed in here not only //from threads executing THIS function (parallel region), but also from threads //executing OTHER parallel regions, which may modify these shared variables; //for(ii=0; ii<ninter; ii++) { //single-threaded version for(ii=id; ii<ninter; ii+=NTHREADS) { //BEGIN_TRANSACTION(); //if (id == 0) { i = inter[INDX(ii,0)]; j = inter[INDX(ii,1)]; //we're waiting on x[] to be updated for _both_ molecules (i and j) //by UpdateCoordinates in the previous timestep. //spin until coords for molecules i and j are updated (by UpdateCoordinates). //while ((counter_x[i] != 1) && (counter_x[j] != 1)); //reset the counters for x for molecules i and j; //must be atomic writes //should this be at the end of the transaction?... //set_mb (&counter_x[i], 0); //set_mb (&counter_x[j], 0); xx = x[IND(0,i)] - x[IND(0,j)]; yy = x[IND(1,i)] - x[IND(1,j)]; zz = x[IND(2,i)] - x[IND(2,j)]; if (xx < -sideHalf) xx += side; if (yy < -sideHalf) yy += side; if (zz < -sideHalf) zz += side; if (xx > sideHalf) xx -= side; if (yy > sideHalf) yy -= side; if (zz > sideHalf) zz -= side; rd = (xx*xx + yy*yy + zz*zz); if ( rd < cutoffSquare ) { rrd = 1.0/rd; rrd2 = rrd*rrd ; rrd3 = rrd2*rrd ; rrd4 = rrd2*rrd2 ; rrd6 = rrd2*rrd4; rrd7 = rrd6*rrd ; r148 = rrd7 - 0.5 * rrd4 ; forcex = xx*r148; forcey = yy*r148; forcez = zz*r148; f[IND(0,i)] += forcex ; f[IND(1,i)] += forcey ; f[IND(2,i)] += forcez ; f[IND(0,j)] -= forcex ; f[IND(1,j)] -= forcey ; f[IND(2,j)] -= forcez ; //global vars, need exclusive access vir_tmp += rd*r148 ; epot_tmp += (rrd6 - rrd3); /* pthread_mutex_lock (&global_mutex1); vir -= rd*r148 ; epot += (rrd6 - rrd3); pthread_mutex_unlock (&global_mutex1); */ //atomically increment the counter_f for both molecules i and j; //these _must_ be the last thing in this "transaction"; //assumes we'll only have 2 txns, one in ComputeForces, one in UpdateCoordinates; //if we have more, then you may need to put these under the previous mutex as well. //atomic_inc(&counter_f[i]); //atomic_inc(&counter_f[j]); } //COMMIT_TRANSACTION(); //} } pthread_mutex_lock (&global_mutex1); vir -= vir_tmp; epot += epot_tmp; pthread_mutex_unlock (&global_mutex1); return 0; }
static inline long long handle_lxrt_request (unsigned int lxsrq, long *arg, RT_TASK *task) { #define larg ((struct arg *)arg) union {unsigned long name; RT_TASK *rt_task; SEM *sem; MBX *mbx; RWL *rwl; SPL *spl; int i; void *p; long long ll; } arg0; int srq; if (likely((srq = SRQ(lxsrq)) < MAX_LXRT_FUN)) { unsigned long type; struct rt_fun_entry *funcm; /* * The next two lines of code do a lot. It makes possible to extend the use of * USP to any other real time module service in user space, both for soft and * hard real time. Concept contributed and copyrighted by: Giuseppe Renoldi * ([email protected]). */ if (unlikely(!(funcm = rt_fun_ext[INDX(lxsrq)]))) { rt_printk("BAD: null rt_fun_ext, no module for extension %d?\n", INDX(lxsrq)); return -ENOSYS; } if (!(type = funcm[srq].type)) { return ((RTAI_SYSCALL_MODE long long (*)(unsigned long, ...))funcm[srq].fun)(RTAI_FUN_ARGS); } if (unlikely(NEED_TO_RW(type))) { lxrt_fun_call_wbuf(task, funcm[srq].fun, NARG(lxsrq), arg, type); } else { lxrt_fun_call(task, funcm[srq].fun, NARG(lxsrq), arg); } return task->retval; } arg0.name = arg[0]; switch (srq) { case LXRT_GET_ADR: { arg0.p = rt_get_adr(arg0.name); return arg0.ll; } case LXRT_GET_NAME: { arg0.name = rt_get_name(arg0.p); return arg0.ll; } case LXRT_TASK_INIT: { struct arg { unsigned long name; long prio, stack_size, max_msg_size, cpus_allowed; }; arg0.rt_task = __task_init(arg0.name, larg->prio, larg->stack_size, larg->max_msg_size, larg->cpus_allowed); return arg0.ll; } case LXRT_TASK_DELETE: { arg0.i = __task_delete(arg0.rt_task ? arg0.rt_task : task); return arg0.ll; } case LXRT_SEM_INIT: { if (rt_get_adr(arg0.name)) { return 0; } if ((arg0.sem = rt_malloc(sizeof(SEM)))) { struct arg { unsigned long name; long cnt; long typ; }; lxrt_typed_sem_init(arg0.sem, larg->cnt, larg->typ); if (rt_register(larg->name, arg0.sem, IS_SEM, current)) { return arg0.ll; } else { rt_free(arg0.sem); } } return 0; } case LXRT_SEM_DELETE: { if (lxrt_sem_delete(arg0.sem)) { arg0.i = -EFAULT; return arg0.ll; } rt_free(arg0.sem); arg0.i = rt_drg_on_adr(arg0.sem); return arg0.ll; } case LXRT_MBX_INIT: { if (rt_get_adr(arg0.name)) { return 0; } if ((arg0.mbx = rt_malloc(sizeof(MBX)))) { struct arg { unsigned long name; long size; int qtype; }; if (lxrt_typed_mbx_init(arg0.mbx, larg->size, larg->qtype) < 0) { rt_free(arg0.mbx); return 0; } if (rt_register(larg->name, arg0.mbx, IS_MBX, current)) { return arg0.ll; } else { rt_free(arg0.mbx); } } return 0; } case LXRT_MBX_DELETE: { if (lxrt_mbx_delete(arg0.mbx)) { arg0.i = -EFAULT; return arg0.ll; } rt_free(arg0.mbx); arg0.i = rt_drg_on_adr(arg0.mbx); return arg0.ll; } case LXRT_RWL_INIT: { if (rt_get_adr(arg0.name)) { return 0; } if ((arg0.rwl = rt_malloc(sizeof(RWL)))) { struct arg { unsigned long name; long type; }; lxrt_typed_rwl_init(arg0.rwl, larg->type); if (rt_register(larg->name, arg0.rwl, IS_SEM, current)) { return arg0.ll; } else { rt_free(arg0.rwl); } } return 0; } case LXRT_RWL_DELETE: { if (lxrt_rwl_delete(arg0.rwl)) { arg0.i = -EFAULT; return arg0.ll; } rt_free(arg0.rwl); arg0.i = rt_drg_on_adr(arg0.rwl); return arg0.ll; } case LXRT_SPL_INIT: { if (rt_get_adr(arg0.name)) { return 0; } if ((arg0.spl = rt_malloc(sizeof(SPL)))) { struct arg { unsigned long name; }; lxrt_spl_init(arg0.spl); if (rt_register(larg->name, arg0.spl, IS_SEM, current)) { return arg0.ll; } else { rt_free(arg0.spl); } } return 0; } case LXRT_SPL_DELETE: { if (lxrt_spl_delete(arg0.spl)) { arg0.i = -EFAULT; return arg0.ll; } rt_free(arg0.spl); arg0.i = rt_drg_on_adr(arg0.spl); return arg0.ll; } case MAKE_HARD_RT: { rt_make_hard_real_time(task); return 0; if (!task || task->is_hard) { return 0; } steal_from_linux(task); return 0; } case MAKE_SOFT_RT: { rt_make_soft_real_time(task); return 0; if (!task || !task->is_hard) { return 0; } if (task->is_hard < 0) { task->is_hard = 0; } else { give_back_to_linux(task, 0); } return 0; } case PRINT_TO_SCREEN: { struct arg { char *display; long nch; }; arg0.i = rtai_print_to_screen("%s", larg->display); return arg0.ll; } case PRINTK: { struct arg { char *display; long nch; }; arg0.i = rt_printk("%s", larg->display); return arg0.ll; } case NONROOT_HRT: { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) current->cap_effective |= ((1 << CAP_IPC_LOCK) | (1 << CAP_SYS_RAWIO) | (1 << CAP_SYS_NICE)); #else set_lxrt_perm(CAP_IPC_LOCK); set_lxrt_perm(CAP_SYS_RAWIO); set_lxrt_perm(CAP_SYS_NICE); #endif return 0; } case RT_BUDDY: { arg0.rt_task = task && current->rtai_tskext(TSKEXT1) == current ? task : NULL; return arg0.ll; } case HRT_USE_FPU: { struct arg { RT_TASK *task; long use_fpu; }; if(!larg->use_fpu) { clear_lnxtsk_uses_fpu((larg->task)->lnxtsk); } else { init_fpu((larg->task)->lnxtsk); } return 0; } case GET_USP_FLAGS: { arg0.name = arg0.rt_task->usp_flags; return arg0.ll; } case SET_USP_FLAGS: { struct arg { RT_TASK *task; unsigned long flags; }; arg0.rt_task->usp_flags = larg->flags; arg0.rt_task->force_soft = (arg0.rt_task->is_hard > 0) && (larg->flags & arg0.rt_task->usp_flags_mask & FORCE_SOFT); return 0; } case GET_USP_FLG_MSK: { arg0.name = arg0.rt_task->usp_flags_mask; return arg0.ll; } case SET_USP_FLG_MSK: { task->usp_flags_mask = arg0.name; task->force_soft = (task->is_hard > 0) && (task->usp_flags & arg0.name & FORCE_SOFT); return 0; } case FORCE_TASK_SOFT: { extern void rt_do_force_soft(RT_TASK *rt_task); struct task_struct *ltsk; if ((ltsk = find_task_by_pid(arg0.name))) { if ((arg0.rt_task = ltsk->rtai_tskext(TSKEXT0))) { if ((arg0.rt_task->force_soft = (arg0.rt_task->is_hard != 0) && FORCE_SOFT)) { rt_do_force_soft(arg0.rt_task); } return arg0.ll; } } return 0; } case IS_HARD: { arg0.i = arg0.rt_task || (arg0.rt_task = current->rtai_tskext(TSKEXT0)) ? arg0.rt_task->is_hard : 0; return arg0.ll; } case GET_EXECTIME: { struct arg { RT_TASK *task; RTIME *exectime; }; if ((larg->task)->exectime[0] && (larg->task)->exectime[1]) { larg->exectime[0] = (larg->task)->exectime[0]; larg->exectime[1] = (larg->task)->exectime[1]; larg->exectime[2] = rtai_rdtsc(); } return 0; } case GET_TIMEORIG: { struct arg { RTIME *time_orig; }; if (larg->time_orig) { RTIME time_orig[2]; rt_gettimeorig(time_orig); rt_copy_to_user(larg->time_orig, time_orig, sizeof(time_orig)); } else { rt_gettimeorig(NULL); } return 0; } case LINUX_SERVER: { struct arg { struct linux_syscalls_list syscalls; }; if (larg->syscalls.nr) { if (larg->syscalls.task->linux_syscall_server) { RT_TASK *serv; rt_get_user(serv, &larg->syscalls.serv); rt_task_masked_unblock(serv, ~RT_SCHED_READY); } larg->syscalls.task->linux_syscall_server = larg->syscalls.serv; rtai_set_linux_task_priority(current, (larg->syscalls.task)->lnxtsk->policy, (larg->syscalls.task)->lnxtsk->rt_priority); arg0.rt_task = __task_init((unsigned long)larg->syscalls.task, larg->syscalls.task->base_priority >= BASE_SOFT_PRIORITY ? larg->syscalls.task->base_priority - BASE_SOFT_PRIORITY : larg->syscalls.task->base_priority, 0, 0, 1 << larg->syscalls.task->runnable_on_cpus); larg->syscalls.task->linux_syscall_server = arg0.rt_task; arg0.rt_task->linux_syscall_server = larg->syscalls.serv; return arg0.ll; } else { if (!larg->syscalls.task) { larg->syscalls.task = RT_CURRENT; } if ((arg0.rt_task = larg->syscalls.task->linux_syscall_server)) { larg->syscalls.task->linux_syscall_server = NULL; arg0.rt_task->suspdepth = -RTE_HIGERR; rt_task_masked_unblock(arg0.rt_task, ~RT_SCHED_READY); } } return 0; } default: { rt_printk("RTAI/LXRT: Unknown srq #%d\n", srq); arg0.i = -ENOSYS; return arg0.ll; } } return 0; }
int EvalNormal::Evaluate() { const Side side = board_->SideToMove(); MoveArray move_array; movegen_->GenerateMoves(&move_array); if (move_array.size() == 0) { const U64 attack_map = ComputeAttackMap(*board_, OppositeSide(side)); if (attack_map & board_->BitBoard(PieceOfSide(KING, side))) { return -WIN; } else { return DRAW; // stalemate } } int score = MATERIAL_FACTOR * PieceValDifference(); for (size_t i = 0; i < move_array.size(); ++i) { const Move& move = move_array.get(i); board_->MakeMove(move); U64 attack_map = ComputeAttackMap(*board_, side); if (attack_map & board_->BitBoard(PieceOfSide(KING, OppositeSide(side)))) { MoveArray opp_move_array; movegen_->GenerateMoves(&opp_move_array); if (opp_move_array.size() == 0) { score = WIN; } } board_->UnmakeLastMove(); } if (score == WIN) { return score; } U64 self_pawns = board_->BitBoard(PieceOfSide(PAWN, side)); int self_pawns_strength = 0; while (self_pawns) { const int lsb_index = Lsb1(self_pawns); self_pawns_strength += sq_strength[lsb_index]; self_pawns ^= (1ULL << lsb_index); } U64 opp_pawns = board_->BitBoard(PieceOfSide(PAWN, OppositeSide(side))); int opp_pawns_strength = 0; while (opp_pawns) { const int lsb_index = Lsb1(opp_pawns); opp_pawns_strength += sq_strength[lsb_index]; opp_pawns ^= (1ULL << lsb_index); } const int pawns_strength = (self_pawns_strength - opp_pawns_strength) * ((board_->Ply() <= 10) ? OPENING_PAWNS_STRENGTH_FACTOR : MIDDLE_PAWNS_STRENGTH_FACTOR); if (board_->Ply() > 8) { const int main_row = ((side == Side::WHITE) ? 0 : 7); // Better to move the bishop. if ((board_->BitBoard(PieceOfSide(BISHOP, side)) & ((1ULL << INDX(main_row, 2)) | (1ULL << INDX(main_row, 5))))) { score -= 5; } // Better to move the knight. if ((board_->BitBoard(PieceOfSide(KNIGHT, side)) & ((1ULL << INDX(main_row, 1)) | (1ULL << INDX(main_row, 6))))) { score -= 5; } } return score + pawns_strength + (move_array.size() / 15); }
int ComputeForces( void* arg, int id ) { double cutoffSquare; double xx, yy, zz, rd, rrd, rrd2, rrd3, rrd4, rrd6, rrd7, r148; // rrd5 never used, removed double forcex, forcey, forcez; int i, k; double vir_tmp, epot_tmp; cutoffSquare = cutoffRadius*cutoffRadius ; vir_tmp = 0.0; epot_tmp = 0.0; int finish_outer; if (id == NTHREADS - 1) { finish_outer = ninter; } else { finish_outer = (ninter / NTHREADS) * (id + 1); } for(int ii = (ninter / NTHREADS) * id; ii < finish_outer; ++ii) { i = inter[INDX(ii,0)]; k = inter[INDX(ii,1)]; xx = x[IND(0,i)] - x[IND(0,k)]; yy = x[IND(1,i)] - x[IND(1,k)]; zz = x[IND(2,i)] - x[IND(2,k)]; if (xx < -sideHalf) xx += side; if (yy < -sideHalf) yy += side; if (zz < -sideHalf) zz += side; if (xx > sideHalf) xx -= side; if (yy > sideHalf) yy -= side; if (zz > sideHalf) zz -= side; rd = (xx*xx + yy*yy + zz*zz); if ( rd < cutoffSquare ) { rrd = 1.0/rd; rrd2 = rrd*rrd ; rrd3 = rrd2*rrd ; rrd4 = rrd2*rrd2 ; rrd6 = rrd2*rrd4; rrd7 = rrd6*rrd ; r148 = rrd7 - 0.5 * rrd4 ; forcex = xx*r148; forcey = yy*r148; forcez = zz*r148; BEGIN_TRANSACTION(); f[IND(0,i)] += forcex ; f[IND(1,i)] += forcey ; f[IND(2,i)] += forcez ; f[IND(0,k)] -= forcex ; f[IND(1,k)] -= forcey ; f[IND(2,k)] -= forcez ; COMMIT_TRANSACTION(); vir_tmp += rd*r148 ; epot_tmp += (rrd6 - rrd3); } } BEGIN_TRANSACTION(); vir -= vir_tmp ; epot += epot_tmp; COMMIT_TRANSACTION(); return 0; }
static void quasiswap(int *m, int *nr, int *nc, int *thin) { int i, n, mtot, ss, row[2], col[2], n1, nr1, nc1, a, b, c, d; size_t intcheck; nr1 = (*nr) - 1; nc1 = (*nc) - 1; /* Get matrix total 'mtot' and sum-of-squares 'ss' */ n = (*nr) * (*nc); for (i = 0, mtot = 0, ss = 0; i < n; i++) { mtot += m[i]; ss += m[i] * m[i]; } n1 = n - 1; /* Get R RNG in the calling C function */ /* GetRNGstate(); */ /* Quasiswap while there are entries > 1 */ intcheck = 0; /* check interrupts */ while (ss > mtot) { for (i = 0; i < *thin; i++) { /* first item and its row & column indices */ a = IRAND(n1); row[0] = a % (*nr); col[0] = a / (*nr); /* neighbour from the same col but different row */ do {row[1] = IRAND(nr1);} while (row[1] == row[0]); c = INDX(row[1], col[0], *nr); /* if neighbours are both zero, cannot be quasiswapped (probability (1-f)^2 with relative col fill f) */ if (m[c] == 0 && m[a] == 0) continue; /* second col */ do {col[1] = IRAND(nc1);} while (col[1] == col[0]); b = INDX(row[0], col[1], *nr); d = INDX(row[1], col[1], *nr); /* m[a] has 50% chance of being > 0, m[d] less, so have it first */ if (m[d] > 0 && m[a] > 0 && m[a] + m[d] - m[b] - m[c] >= 2) { ss -= 2 * (m[a] + m[d] - m[b] - m[c] - 2); m[a]--; m[d]--; m[b]++; m[c]++; } else if (m[c] > 0 && m[b] > 0 && m[b] + m[c] - m[a] - m[d] >= 2) { ss -= 2 * (m[b] + m[c] - m[a] - m[d] - 2); m[a]++; m[d]++; m[b]--; m[c]--; } } /* interrupt? */ if (intcheck % 10000 == 9999) R_CheckUserInterrupt(); intcheck++; } /* Set R RNG in the calling function */ /* PutRNGstate(); */ }
static void greedyqswap(int *m, int nr, int nc, int thin, int *big) { int i, j, n, biglen, pick, row[2], col[2], nr1, nc1, a, b, c, d; size_t intcheck; nr1 = nr - 1; nc1 = nc - 1; /* big contains indices of cells > 1 */ n = nr * nc; for (i = 0, biglen = -1; i < n; i++) { if (m[i] > 1) big[++biglen] = i; } intcheck = 0; /* check interrupts */ while (biglen > -1) { for (i = 0; i < thin; i++) { /* pick one item to the m[a] corner */ if (i == 0) { /* greedy! */ pick = IRAND(biglen); a = big[pick]; } else { /* thin! */ a = IRAND(n-1); } row[0] = a % nr; col[0] = a / nr; /* get the second item in the first column */ do {row[1] = IRAND(nr1);} while (row[1] == row[0]); c = INDX(row[1], col[0], nr); /* unswappable if the first row is all zeros */ if (m[a] == 0 && m[c] == 0) continue; /* second column, third and fourth items */ do {col[1] = IRAND(nc1);} while (col[1] == col[0]); b = INDX(row[0], col[1], nr); d = INDX(row[1], col[1], nr); if (m[d] > 0 && m[a] > 0 && m[a] + m[d] - m[b] - m[c] >= 2) { m[a]--; m[d]--; m[b]++; m[c]++; /* Update big & biglen. a & d were decremented, and if * they now are 1, they are removed from big. We know * pick for a, but the location of d must be searched * in big. b & c were incremented and if they now are * 2, they must be added to big. */ if (m[a] == 1) { if (i == 0) { /* not thinning: know the pick */ big[pick] = big[biglen--]; } else { /* thinning: must search in big */ for (j = 0; j <= biglen; j++) { if (a == big[j]) { big[j] = big[biglen--]; break; } } } } if (m[d] == 1) { for (j = 0; j <= biglen; j++) { if (d == big[j]) { big[j] = big[biglen--]; break; } } } if (m[b] == 2) big[++biglen] = b; if (m[c] == 2) big[++biglen] = c; } else if (m[c] > 0 && m[b] > 0 && m[b] + m[c] - m[a] - m[d] >= 2) { m[a]++; m[d]++; m[b]--; m[c]--; /* update is mirror operation of the one above */ if (m[b] == 1) { for (j = 0; j <= biglen; j++) { if (b == big[j]) { big[j] = big[biglen--]; break; } } } if (m[c] == 1) { for (j = 0; j <= biglen; j++) { if (c == big[j]) { big[j] = big[biglen--]; break; } } } if (m[a] == 2) big[++biglen] = a; if (m[d] == 2) big[++biglen] = d; } } /* interrupt? */ if (intcheck % 10000 == 9999) R_CheckUserInterrupt(); intcheck++; } }