#include #include "gpusolver.h" #include "time.h" #include "tests/masterTest.h" #include "gmp.h" #include "rng.h" #include "ncnf.h" #define ADD (0) #define CMP (1) #define CHK (2) void ctrthings2(cnf* c, u32* state, u32* ctr, u32* max) { u32 wcnt = 1U + (c->cnts[0] >> 5U); u32* mode = state; u32* index = state + 1; u32* addval = state + 2; u32 varcnt = c->cnts[0] - 1; u32 chkmsk = 0xFFFFFFFFU * (*mode == CHK); u32 chkcls = *index & chkmsk; u32 chkind = c->clausedat[3 * chkcls] + (*addval & chkmsk); u32 var = c->variables[chkind]; u8 par = c->parities[chkind]; u32 vword = (varcnt - var) >> 5U; u32 vbit = (varcnt - var) & 0b11111U; u8 corpar = (ctr[vword] >> vbit) & 1U; u8 isvalid = (par == corpar); u8 islvar = ((*addval + 1) == c->clausedat[3 * chkcls + 1]); u8 isbchk0 = (*mode == CHK); u8 isbchk1 = isbchk0 & isvalid; u8 isbchk2 = isbchk1 & islvar; u32 j = c->clausedat[3 * chkcls + 2]; *mode -= 2 * isbchk2; *index = (j >> 5U) * isbchk2 + *index * (!isbchk2); *addval = (1U << (j & 0b11111U)) * isbchk2 + *addval * (!isbchk2); *addval += ((isbchk1) & (!islvar)); u8 isbchk3 = (isbchk0 & (!isvalid)); *addval *= (!isbchk3); *index += (isbchk3); u8 issat = (*index == c->cnts[1]) * (isbchk3); u32 cmpaddind = *index * (*mode != CHK); u32 nval = ctr[cmpaddind] + *addval; // Find the result of the current step if it was addition *addval = (nval < ctr[cmpaddind]) * (*mode == ADD) + (*addval) * (*mode == CHK); // If in add mode, set addval to carry. If in cmp mode, set to 0. If in check mode, leave alone. ctr[cmpaddind] = nval * ((*mode == ADD) & !issat) + ctr[cmpaddind] * ((*mode != ADD) | issat); // If in add mode, set new ctr val, otherwise leave unchanged *addval -= (ctr[cmpaddind] < max[cmpaddind]) * (*mode == CMP); // If in comparison mode, decrement addval if less than *addval += (ctr[cmpaddind] > max[cmpaddind]) * (*mode == CMP); // If in comparison mode, increment addval if greater than u8 addcond = (*addval == 0) | (cmpaddind == (wcnt - 1)); // Exit condition for the ADD state: If addval is zero (no carry) or we're at the last word u8 cmpcond = (*addval != 0) | (cmpaddind == 0); // Exit condition for the CMP state: if addval is nonzero (lt or gt) or we're at the least significant word u8 exittime = (*mode == CMP) & cmpcond & (*addval != -1); exittime |= issat; if (exittime) { // If in cmpmode and the comparison result is not less than, unsat printf("Result: %u\n", issat); *mode = 4; return; } u8 cmpdone = cmpcond & (*mode == CMP); // if comparison completion conditions are satisfied and in CMP mode u32 addindex = (cmpaddind + 1) * !addcond + (wcnt - 1) * addcond; // if add completion is satisfied, set index to most significant word, else increment by 1 *index = addindex * (*mode == ADD) + (*index - (*mode == CMP)) * (*mode != ADD); // If in add mode, use addindex; if in cmp mode, decrement index by 1 *index *= !cmpdone; *addval *= !(((addcond) & (*mode == ADD)) | cmpdone); // If add is complete, or cmp is complete, zero. Else leave unchanged. *mode += addcond * (*mode == ADD) + cmpdone; // If in add mode and add completion is reached, increment mode. If in cmp mode and cmp completion reached, increment mode. } void printbits(unsigned a) { for (unsigned i = 0; i < 32; ++i) { unsigned ind = 31 - i; printf("%u", (a >> ind) & 1U); } } #define TESTS (274877906944LU >> 10U) #define CSZE (83LU) #define eqprob (0.01f) void mul(u32* c, u32 len, u32* a, u32 b) { u32 carry = 0; for (u32 i = 0; i < len; ++i) { u32 ncarry; u32 blo = a[i] & 0xFFFFU; u32 bhi = a[i] >> 16U; u32 ilo = b & 0xFFFFU; u32 ihi = b >> 16U; *(c + i) = ilo * blo; u32 b1 = ilo * bhi; u32 c1 = ihi * blo; ncarry = ihi * bhi; b1 += c1; ncarry += (b1 < c1) << 16U; u32 bblo = b1 & 0xFFFFU; u32 bbhi = b1 >> 16U; bblo <<= 16U; *(c + i) += bblo; u8 acarry = *(c + i) < bblo; ncarry += bbhi + acarry; c[i] += carry; ncarry += c[i] < carry; carry = ncarry; } } int main() { /* printf("Tests: %lu\n", TESTS); rngstate rng; u64 rseed = utime(); seed(&rng, rseed); printf("Seed: %lu\n", rseed); mpz_t a, b, c, d, e; mpz_inits(a, b, c, d, e, NULL); u32 ctrp[CSZE]; u32 maxp[CSZE]; u32* ctr = ctrp; u32* max = maxp; u32 state[3]; u32 hdr[2]; char buf[4096]; for (u64 i = 0; i < TESTS; ++i) { memset(ctr, 0, sizeof(u32) * CSZE); memset(max, 0, sizeof(u32) * CSZE); //u32 lenval = ru32(&rng) % CSZE; u32 lenval = CSZE; if (lenval < 2) lenval = 2; u32 jval = ru32(&rng) % ((lenval - 1) * 32); for (u32 j = 0; j < lenval - 2; ++j) { ctr[j] = ru32(&rng); max[j] = ru32(&rng); } mpz_import(a, lenval, -1, sizeof(u32), 0, 0, ctr); mpz_import(b, lenval, -1, sizeof(u32), 0, 0, max); state[1] = jval >> 5U; state[2] = jval & 0b11111U; state[2] = 1U << state[2]; mpz_ui_pow_ui(c, 2, jval); if (rf32(&rng) < eqprob && mpz_cmp) { mpz_sub(a, b, c); if (mpz_sgn(a) != -1) { mpz_export(ctr, NULL, -1, sizeof(u32), 0, 0, a); } else { mpz_import(a, lenval, -1, sizeof(u32), 0, 0, ctr); } } mpz_add(d, a, c); state[0] = 0; while (state[0] < 2U) { ctrthings2(hdr, lenval, state, ctr, max); } mpz_import(c, lenval, -1, sizeof(u32), 0, 0, ctr); i32 res = mpz_cmp(d, b); if (res == -1) { if (state[2] != -1) { printf("Fuck2 %lu\n", i); printf("d: "); mpz_out_str(stdout, 10, d); printf("\nb: "); mpz_out_str(stdout, 10, b); printf("\n"); printf("mode: %u\n", state[2]); exit(0); } } else { if (state[2] != 2) { printf("Fuck3 %lu\n", i); printf("d: "); mpz_out_str(stdout, 10, d); printf("\nc: "); mpz_out_str(stdout, 10, c); printf("\nb: "); mpz_out_str(stdout, 10, b); printf("\n"); printf("mode: %u\n", state[2]); exit(0); } } res = mpz_cmp(d, c); if (res != 0) { printf("Fuck %lu\na: ", i); mpz_out_str(stdout, 10, a); printf("\nd: "); mpz_out_str(stdout, 10, d); printf("\nc: "); mpz_out_str(stdout, 10, c); printf("\n%u %u\n", lenval, jval); exit(0); } } mpz_clears(a, b, c, d, e, NULL); */ /* srand( utime()); u32 cnt = 4096; printf("p cnf %u %u\n", cnt, cnt); for (u32 i = 0; i < cnt; ++i) { printf("%s%u 0\n", (rand() & 1U) ? ("") : ("-"), i + 1); if ((i & 0xFF) == 0) { srand(utime() ^ rand()); } } return 0; */ /* for (uint i = 0; i < 1000; ++i) { char buf[128]; i32 len = sprintf(buf, "/home/lev/Downloads/uf50/uf50-0%u.cnf", i + 1); } */ /* Expects a path to a DIMACS file */ /* cnf* c = readDIMACS("/home/lev/Downloads/uf20/uf20-03.cnf"); sortlastnum(c); // gpusolve(c); gpusolver* gs = initSolver(); if (gs == NULL) return -1; i32 res = gpusolve2(gs, c); freeSolver(gs); freecnf(c); return 0; */ runTests(); return 0; /* // printf("%u\n", c->litcnt); // for (u32 i = 0; i < c->clausecnt; ++i) printf("%u ", c->lastvars[i]); //printf("\ntomato\n"); sortlastnum(c, c->litcnt); // printf("%u\n", c->lastvars[c->clauses[0]]); //printf("%u %u %u\n\n", c->litcnt, c->varcnt, c->clausecnt); u64 start = utime(); i32 res = gpusolve(c); u64 stop = utime(); // printf("%s : %d\n", buf, res); printf("Took %f seconds\n", ((f64) (stop - start)) / 1000000.0); // printf("please don't\n"); // if (res == 1) break; freecnf(c); return 0;*/ }