#include "cpusolver.h" #include "csflocref.h" static inline void stateaddpow(uint wcnt, uint* state, uint pow) { uint corpow = pow & 0b11111U; uint startind = pow >> 5U; uint tr = 1U << corpow; uint tval = state[startind] + tr; bool carry = tval < state[startind]; state[startind] = tval; if (carry) { uint i = startind + 1; for ( ; i < wcnt; ++i) { state[i]++; if (state[i]) break; } } } #define DEBUGSAT #define ADD (0) #define CMP (1) #define BCT (2) #define CHK (3) void ctrthings3(cnf* c, u32* state, u32* ctr, const u32* max) { u32 varcnt = c->cnts[0]; u32 clausecnt = c->cnts[1]; u32 wcnt = 1U + (varcnt >> 5U); u32* mode = state; u32* index = state + 1; u32* addval = state + 2; // printf("> %u %u %u %u %u\n", *mode, *index, *addval, *ctr, *max); u8 addmode = (*mode == ADD); u8 cmpmode = (*mode == CMP); u8 bctmode = (*mode == BCT); u8 submode = (*mode == CHK); // 1 mask for if in subcheck mode, 1 for if not u32 submask = 0xFFFFFFFFU * submode; u32 nsubmask = ~submask; u32 addmask = 0xFFFFFFFFU * addmode; u32 naddmask = ~addmask; /* subcheck */ // used to find correct ctr index u32 varcor = varcnt - 1; // Mask to prevent oob accesses for when (varcnt / 32) > clausecnt (or smth like that) u32 currclause = *index & submask; // clausedat records are 3 words long, multiply index by 3 u32 currclauseshifted = currclause * 3U; // Retrieve beginning index of clause, add current var index u32 currvarind = c->clausedat[currclauseshifted] + (*addval & submask); // Retrieve current var & parity u32 currvar = c->variables[currvarind]; u8 corrpar = c->parities[currvarind]; // Calculate index in ctr u32 currvarcorr = (varcor - currvar); u32 currvarword = currvarcorr >> 5U; u32 currvarbit = currvarcorr & 0b11111U; /* Can we make there be 1 ctr read per iteration? */ // If in sub mode, retrieve current var's bit, else return ctr[*index] u32 ctrind = (currvarword & submask) | (*index & nsubmask); u32 ctrval = ctr[ctrind]; u32 maxval = max[*index & nsubmask]; // Extract parity bit from ctr u32 currpar = (ctrval >> currvarbit) & 1U; // Check if assignment parity matches clause parity u8 subvalid = currpar == corrpar; // Don't mask addval because it's not being used for a lookup u8 islvar = c->clausedat[currclauseshifted + 1U] == (*addval + 1); u32 jval = c->clausedat[currclauseshifted + 2U]; u32 jword = jval >> 5U; u32 jbit = 1U << (jval & 0b11111U); u8 islclause = (clausecnt - 1) <= *index; u8 endOfCtr = (ctrind == (wcnt - 1)); u8 begOfCtr = (ctrind == 0); /* add */ u32 nctr = ctrval + *addval; u8 addoverflow = (nctr < ctrval); /* cmp */ u8 cmpresult = -(ctrval < maxval); cmpresult += (ctrval > maxval); u8 cmpnores = cmpresult == 0; u8 cmpisless = cmpresult == 255U; /* bitcnt */ u32 bitcntval = (ctrval & -ctrval); u32 bitcnt = ((bitcntval & 0x0000FFFFU) != 0) << 4U; bitcnt |= ((bitcntval & 0x00FF00FF) != 0) << 3U; bitcnt |= ((bitcntval & 0x0F0F0F0F) != 0) << 2U; bitcnt |= ((bitcntval & 0x33333333) != 0) << 1U; bitcnt |= (bitcntval & 0x55555555) != 0; bitcnt += bitcntval != 0; bitcntval = 32 - bitcnt; u8 ctrWordIsZero = ctrval == 0; // Set current ctr word // If in add mode, update ctr val, otherwise leave unchanged ctr[ctrind] = (nctr & addmask) | (ctr[ctrind] & naddmask); // Set current index /* * jword : (subcheck & valid & lastvar) * index : (subcheck & valid & !lastvar) | (add & (!addoverflow | endOfCtr)) * index + 1 : (subcheck & !valid) | (add & (addoverflow & !endOfCtr)) | (bitcnt & ctrWordIsZero & !endOfCtr) * index - 1 : (cmp & cmpnores & !begOfCtr) * 0 : (cmp & (!cmpnores | begOfCtr)) * index[addoverflow + bitcntval] : (bitcnt & (!ctrWordIsZero | endOfCtr) */ u32 tempA = submode & (subvalid & islvar); // if (submode & (subvalid & islvar)) fprintf(iofile, "j: %u\n", jval); u32 tempB = (submode & (subvalid & !islvar)); u32 tempC = (submode & !subvalid) | (addmode & (addoverflow & !endOfCtr)) | (bctmode & (ctrWordIsZero & !endOfCtr)); u32 tempD = (cmpmode & (cmpnores & !begOfCtr)); u32 tempE = (addmode & (!addoverflow | endOfCtr)); u32 tempF = (bctmode & (!ctrWordIsZero | endOfCtr)); tempA *= jword; tempB *= *index; tempC *= (*index + 1); tempD *= (*index - 1); tempE *= (wcnt - 1); u32 indexval = (*addval + bitcntval); u8 indexcmp = indexval < varcnt; indexval = indexval * indexcmp + (varcnt - 1) * (!indexcmp); tempF *= c->index[((indexval) * bctmode)]; // if (bctmode & (!ctrWordIsZero | endOfCtr)) fprintf(iofile,"z: %u %u\n", (indexval), c->index[((indexval) * bctmode)]); *index = tempA | tempB | tempC | tempD | tempE | tempF; tempA = submode & (subvalid & islvar); tempB = (submode & (subvalid & !islvar)); tempC = (addmode & (addoverflow & !endOfCtr)); tempD = (bctmode & (ctrWordIsZero & !endOfCtr)); tempA *= (jbit); tempB *= (*addval + 1); tempC *= (addoverflow); tempD *= (*addval + 32); *addval = tempA | tempB | tempC | tempD; /* * 1 << jbit : (subcheck & valid & lastvar) * addval + 1 : (subcheck & valid & !lastvar) * 0 : (subcheck & !valid) | (add & (!addoverflow | endOfCtr)) | (cmp) | (bitcnt & (!ctrWordIsZero | endOfCtr) * addoverflow : (add & (addoverflow & !endOfCtr)) * addoverflow + 32 : (bitcnt & ctrWordIsZero & !endOfCtr) * */ /* * SAT : (subcheck & !valid & lastclause) * UNSAT : (cmp & (!cmpnores | begOfCtr)) & !cmpisless */ u8 issat = (submode & ((!subvalid) & islclause)); u8 isusat = (cmpmode & ((!cmpnores) | begOfCtr)) & (!cmpisless); u8 isdone = issat | isusat; *mode += isdone << 2U; *index ^= (*index * isdone); *index += issat; /* if (isdone) { *mode = 9; *index = issat; // printf("%u\n", issat); } */ /* * ADD : (add & (!addoverflow | endOfCtr)) * CMP : (cmp & (!cmpnores | begOfCtr)) * BCT : (bitcnt & (!ctrWordIsZero | endOfCtr)) * CHK : (subcheck & valid & lastvar) */ tempA = (addmode & (!addoverflow | endOfCtr)); tempB = (cmpmode & (!cmpnores | begOfCtr)); tempC = (bctmode & (!ctrWordIsZero | endOfCtr)); tempD = (submode & (subvalid & islvar)); *mode += tempA | tempB | tempC; *mode -= (tempD * 3); } void ctrthings4(cnf* c, u32* state, u32* ctr, const u32* max, FILE* iofile) { u32 varcnt = c->cnts[0]; u32 clausecnt = c->cnts[1]; u32 wcnt = 1U + (varcnt >> 5U); u32* mode = state; u32* index = state + 1; u32* addval = state + 2; // printf("> %u %u %u %u %u\n", *mode, *index, *addval, *ctr, *max); u8 addmode = (*mode == ADD); u8 cmpmode = (*mode == CMP); u8 bctmode = (*mode == BCT); u8 submode = (*mode == CHK); // 1 mask for if in subcheck mode, 1 for if not u32 submask = -submode; u32 nsubmask = ~submask; u32 addmask = -addmode; u32 naddmask = ~addmask; /* subcheck */ // used to find correct ctr index u32 varcor = varcnt - 1; // Mask to prevent oob accesses for when (varcnt / 32) > clausecnt (or smth like that) u32 currclause = *index & submask; // clausedat records are 3 words long, multiply index by 3 u32 currclauseshifted = currclause * 3U; // Retrieve beginning index of clause, add current var index u32 currvarind = c->clausedat[currclauseshifted] + (*addval & submask); // Retrieve current var & parity u32 currvar = c->variables[currvarind]; u8 corrpar = c->parities[currvarind]; // Calculate index in ctr u32 currvarcorr = (varcor - currvar); u32 currvarword = currvarcorr >> 5U; u32 currvarbit = currvarcorr & 0b11111U; /* Can we make there be 1 ctr read per iteration? */ // If in sub mode, retrieve current var's bit, else return ctr[*index] u32 ctrind = (currvarword & submask) | (*index & nsubmask); u32 ctrval = ctr[ctrind]; u32 maxval = max[*index & nsubmask]; // Extract parity bit from ctr u32 currpar = (ctrval >> currvarbit) & 1U; // Check if assignment parity matches clause parity u8 subvalid = currpar == corrpar; // Don't mask addval because it's not being used for a lookup u8 islvar = c->clausedat[currclauseshifted + 1U] == (*addval + 1); u32 jval = c->clausedat[currclauseshifted + 2U]; u32 jword = jval >> 5U; u32 jbit = 1U << (jval & 0b11111U); u8 islclause = (clausecnt - 1) <= *index; u8 endOfCtr = (ctrind == (wcnt - 1)); u8 begOfCtr = (ctrind == 0); /* add */ u32 nctr = ctrval + *addval; u8 addoverflow = (nctr < ctrval); /* cmp */ u8 cmpresult = -(ctrval < maxval); cmpresult += (ctrval > maxval); u8 cmpnores = cmpresult == 0; u8 cmpisless = cmpresult == 255U; /* bitcnt */ u32 bitcntval = (ctrval & -ctrval); u32 bitcnt = ((bitcntval & 0x0000FFFFU) != 0) << 4U; bitcnt |= ((bitcntval & 0x00FF00FF) != 0) << 3U; bitcnt |= ((bitcntval & 0x0F0F0F0F) != 0) << 2U; bitcnt |= ((bitcntval & 0x33333333) != 0) << 1U; bitcnt |= (bitcntval & 0x55555555) != 0; bitcnt += bitcntval != 0; bitcntval = 32 - bitcnt; u8 ctrWordIsZero = ctrval == 0; // Set current ctr word // If in add mode, update ctr val, otherwise leave unchanged ctr[ctrind] = (nctr & addmask) | (ctr[ctrind] & naddmask); // Set current index /* * jword : (subcheck & valid & lastvar) * index : (subcheck & valid & !lastvar) | (add & (!addoverflow | endOfCtr)) * index + 1 : (subcheck & !valid) | (add & (addoverflow & !endOfCtr)) | (bitcnt & ctrWordIsZero & !endOfCtr) * index - 1 : (cmp & cmpnores & !begOfCtr) * 0 : (cmp & (!cmpnores | begOfCtr)) * index[addoverflow + bitcntval] : (bitcnt & (!ctrWordIsZero | endOfCtr) */ u32 tempA = -(submode & (subvalid & islvar)); if (submode & (subvalid & islvar)) fprintf(iofile, "j: %u\n", jval); u32 tempB = -(submode & (subvalid & !islvar)); u32 tempC = -((submode & !subvalid) | (addmode & (addoverflow & !endOfCtr)) | (bctmode & (ctrWordIsZero & !endOfCtr))); u32 tempD = -(cmpmode & (cmpnores & !begOfCtr)); u32 tempE = -(addmode & (!addoverflow | endOfCtr)); u32 tempF = -(bctmode & (!ctrWordIsZero | endOfCtr)); tempA &= jword; tempB &= *index; tempC &= (*index + 1); tempD &= (*index - 1); tempE &= (wcnt - 1); u32 indexval = (*addval + bitcntval); u32 indexcmp = -(indexval < varcnt); indexval = (indexval & indexcmp) | ((varcnt - 1) & (~indexcmp)); tempF &= c->index[((indexval) * bctmode)]; if (bctmode & (!ctrWordIsZero | endOfCtr)) fprintf(iofile,"z: %u %u\n", (indexval), c->index[((indexval) * bctmode)]); *index = tempA | tempB | tempC | tempD | tempE | tempF; tempA = -(submode & (subvalid & islvar)); tempB = -(submode & (subvalid & !islvar)); tempC = -(addmode & (addoverflow & !endOfCtr)); tempD = -(bctmode & (ctrWordIsZero & !endOfCtr)); tempA &= (jbit); tempB &= (*addval + 1); tempC &= (addoverflow); tempD &= (*addval + 32); *addval = tempA | tempB | tempC | tempD; /* * 1 << jbit : (subcheck & valid & lastvar) * addval + 1 : (subcheck & valid & !lastvar) * 0 : (subcheck & !valid) | (add & (!addoverflow | endOfCtr)) | (cmp) | (bitcnt & (!ctrWordIsZero | endOfCtr) * addoverflow : (add & (addoverflow & !endOfCtr)) * addoverflow + 32 : (bitcnt & ctrWordIsZero & !endOfCtr) * */ /* * SAT : (subcheck & !valid & lastclause) * UNSAT : (cmp & (!cmpnores | begOfCtr)) & !cmpisless */ u8 issat = (submode & ((!subvalid) & islclause)); u8 isusat = (cmpmode & ((!cmpnores) | begOfCtr)) & (!cmpisless); u32 isdone = -(issat | isusat); *mode |= isdone; *index ^= (*index & isdone); *index += issat; /* if (isdone) { *mode = 9; *index = issat; // printf("%u\n", issat); } */ /* * ADD : (add & (!addoverflow | endOfCtr)) * CMP : (cmp & (!cmpnores | begOfCtr)) * BCT : (bitcnt & (!ctrWordIsZero | endOfCtr)) * CHK : (subcheck & valid & lastvar) */ tempA = (addmode & (!addoverflow | endOfCtr)); tempB = (cmpmode & (!cmpnores | begOfCtr)); tempC = (bctmode & (!ctrWordIsZero | endOfCtr)); tempD = (submode & (subvalid & islvar)); *mode += tempA | tempB | tempC; *mode -= (tempD * 3); } void ctrthings5(cnf* c, u32* state, u32* ctr, const u32* max) { u32 varcnt = c->cnts[0]; u32 clausecnt = c->cnts[1]; u32 wcnt = 1U + (varcnt >> 5U); u32* mode = state; u32* index = state + 1; u32* addval = state + 2; // printf("> %u %u %u %u %u\n", *mode, *index, *addval, *ctr, *max); u8 addmode = (*mode == ADD); u8 cmpmode = (*mode == CMP); u8 bctmode = (*mode == BCT); u8 submode = (*mode == CHK); // 1 mask for if in subcheck mode, 1 for if not u32 submask = -submode; u32 nsubmask = ~submask; u32 addmask = -addmode; u32 naddmask = ~addmask; /* subcheck */ // used to find correct ctr index u32 varcor = varcnt - 1; // Mask to prevent oob accesses for when (varcnt / 32) > clausecnt (or smth like that) u32 currclause = *index & submask; // clausedat records are 3 words long, multiply index by 3 u32 currclauseshifted = currclause * 3U; // Retrieve beginning index of clause, add current var index u32 currvarind = c->clausedat[currclauseshifted] + (*addval & submask); // Retrieve current var & parity u32 currvar = c->variables[currvarind]; u8 corrpar = c->parities[currvarind]; // Calculate index in ctr u32 currvarcorr = (varcor - currvar); u32 currvarword = currvarcorr >> 5U; u32 currvarbit = currvarcorr & 0b11111U; /* Can we make there be 1 ctr read per iteration? */ // If in sub mode, retrieve current var's bit, else return ctr[*index] u32 ctrind = (currvarword & submask) | (*index & nsubmask); u32 ctrval = ctr[ctrind]; u32 maxval = max[*index & nsubmask]; // Extract parity bit from ctr u32 currpar = (ctrval >> currvarbit) & 1U; // Check if assignment parity matches clause parity u8 subvalid = currpar == corrpar; // Don't mask addval because it's not being used for a lookup u8 islvar = c->clausedat[currclauseshifted + 1U] == (*addval + 1); u32 jval = c->clausedat[currclauseshifted + 2U]; u32 jword = jval >> 5U; u32 jbit = 1U << (jval & 0b11111U); u8 islclause = (clausecnt - 1) <= *index; u8 endOfCtr = (ctrind == (wcnt - 1)); u8 begOfCtr = (ctrind == 0); /* add */ u32 nctr = ctrval + *addval; u8 addoverflow = (nctr < ctrval); /* cmp */ u8 cmpresult = -(ctrval < maxval); cmpresult += (ctrval > maxval); u8 cmpnores = cmpresult == 0; u8 cmpisless = cmpresult == 255U; /* bitcnt */ u32 bitcntval = (ctrval & -ctrval); u32 bitcnt = ((bitcntval & 0x0000FFFFU) != 0) << 4U; bitcnt |= ((bitcntval & 0x00FF00FF) != 0) << 3U; bitcnt |= ((bitcntval & 0x0F0F0F0F) != 0) << 2U; bitcnt |= ((bitcntval & 0x33333333) != 0) << 1U; bitcnt |= (bitcntval & 0x55555555) != 0; bitcnt += bitcntval != 0; bitcntval = 32 - bitcnt; u8 ctrWordIsZero = ctrval == 0; // Set current ctr word // If in add mode, update ctr val, otherwise leave unchanged ctr[ctrind] = (nctr & addmask) | (ctr[ctrind] & naddmask); // Set current index u32 tempA = -(submode & (subvalid & islvar)); u32 tempB = -(submode & (subvalid & !islvar)); u32 tempC = -((submode & !subvalid) | (addmode & (addoverflow & !endOfCtr)) | (bctmode & (ctrWordIsZero & !endOfCtr))); u32 tempD = -(cmpmode & (cmpnores & !begOfCtr)); u32 tempE = -(addmode & (!addoverflow | endOfCtr)); u32 tempF = -(bctmode & (!ctrWordIsZero | endOfCtr)); tempA &= jword; tempB &= *index; tempC &= (*index + 1); tempD &= (*index - 1); tempE &= (wcnt - 1); u32 indexval = (*addval + bitcntval); u32 indexcmp = -(indexval < varcnt); indexval = (indexval & indexcmp) | ((varcnt - 1) & (~indexcmp)); tempF &= c->index[((indexval) * bctmode)]; *index = tempA | tempB | tempC | tempD | tempE | tempF; tempA = -(submode & (subvalid & islvar)); tempB = -(submode & (subvalid & !islvar)); tempC = -(addmode & (addoverflow & !endOfCtr)); tempD = -(bctmode & (ctrWordIsZero & !endOfCtr)); tempA &= (jbit); tempB &= (*addval + 1); tempC &= (addoverflow); tempD &= (*addval + 32); *addval = tempA | tempB | tempC | tempD; /* completion detection */ u8 issat = (submode & ((!subvalid) & islclause)); u8 isusat = (cmpmode & ((!cmpnores) | begOfCtr)) & (!cmpisless); u32 isdone = -(issat | isusat); /* exit */ *mode |= isdone; *index ^= (*index & isdone); *index += issat; tempA = (addmode & (!addoverflow | endOfCtr)); tempB = (cmpmode & (!cmpnores | begOfCtr)); tempC = (bctmode & (!ctrWordIsZero | endOfCtr)); tempD = (submode & (subvalid & islvar)); *mode += tempA | tempB | tempC; *mode -= (tempD * 3); } /** NOTES: * First thing's first is indexing, let's get started with that. * * * * * */ void ctrthings2(cnf* c, u32* state, u32* ctr, const u32* max, FILE* iofile) { // Pre-actual work setup stuff u32 wcnt = 1U + (c->cnts[0] >> 5U); // number of words we need (bitcnt + 1 ceiling divided by 32) u32* mode = state; // Make pointers to array values for convenience so I don't need to refer to everything via array indices u32* index = state + 1; // tbh the names aren't much better u32* addval = state + 2; u32 varcnt = c->cnts[0] - 1; // (varcnt - 1) - v gives us the bit index of variable v in the ctr u32 chkmsk = 0xFFFFFFFFU * (*mode == (2)); // Create a mask that zeros anything if we aren't in subsumption-check mode, to prevent out of bounds accesses u32 chkcls = *index & chkmsk; // Use said mask to zero the index if we're not in check mode u32 chkind = c->clausedat[3 * chkcls] + (*addval & chkmsk); // potentially zeroed index to lookup clause start, add potentially zeroed variable index in that clause u32 var = c->variables[chkind]; // Retrieve variable at that index u8 par = c->parities[chkind]; // Retrieve the variable's CNF parity u32 vword = (varcnt - var) >> 5U; // As mentioned in the varcnt line, compute word index of var in ctr u32 vbit = (varcnt - var) & 0b11111U; // Compute bit index of var in above ctr word u8 corpar = (ctr[vword] >> vbit) & 1U; // Extract correct parity u8 isvalid = (par == corpar); // Check if CNF parity equals assignment parity from ctr u8 islvar = ((*addval + 1) == c->clausedat[3 * chkcls + 1]); // Check if this is the last variable of the clause u8 isbchk0 = (*mode == (2)); // If in check mode u8 isbchk1 = isbchk0 & isvalid; // If in check mode & valid u8 isbchk2 = isbchk1 & islvar; // If in check mode, valid, and on the last var u32 j = c->clausedat[3 * chkcls + 2]; // retrieve j val for current clause *mode -= 2 * isbchk2; // If isbchk2, move to add mode #ifdef DEBUGSAT if (isbchk2) fprintf(iofile,"j: %u\n", j); #endif *index = (j >> 5U) * isbchk2 + *index * (!isbchk2); // if isbchk2, set index for the jval to be added *addval = (1U << (j & 0b11111U)) * isbchk2 + *addval * (!isbchk2); // if isbchk, set addval for the jval to be added; *addval += ((isbchk1) & (!islvar)); // If in check mode, valid, and not on the last var, move to the next var u8 isbchk3 = (isbchk0 & (!isvalid)); // if in check mode and not valid, move to the next clause *addval *= (!isbchk3); // if moving to next clause, go to 0th var of that clause *index += (isbchk3); // actually moving to the next clause u8 issat = (*index == c->cnts[1]) * (isbchk3); // if we just passed the last clause, none were valid, so our assignment is SAT u32 cmpaddind = *index * (*mode != (2)); // Zero index into ctr if in check mode, to prevent out of bounds accesses u32 nval = ctr[cmpaddind] + *addval; // Find the result of the current step if it was addition *addval = (nval < ctr[cmpaddind]) * (*mode == (0)) + (*addval) * (*mode == (2)); // 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 == (0)) & !issat) + ctr[cmpaddind] * ((*mode != (0)) | issat); // If in add mode, set new ctr val, otherwise leave unchanged *addval -= (ctr[cmpaddind] < max[cmpaddind]) * (*mode == (1)); // If in comparison mode, decrement addval if less than *addval += (ctr[cmpaddind] > max[cmpaddind]) * (*mode == (1)); // 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 == (1)) & cmpcond & (*addval != -1); exittime |= issat; if (exittime) { // If in cmpmode and the comparison result is not less than, unsat printf("%u\n", issat); *mode = 3; return; } u8 cmpdone = cmpcond & (*mode == (1)); // if comparison completion conditions are satisfied and in CMP mode u32 addindex = (cmpaddind + 1) * !addcond + (cmpaddind) * addcond; // if add completion is satisfied, set index to most significant word, else increment by 1 *index = addindex * (*mode == (0)) + (*index - (*mode == (1))) * (*mode != (0)); // If in add mode, use addindex; if in cmp mode, decrement index by 1 *index *= !cmpdone; *addval *= !(((addcond) & (*mode == (0))) | cmpdone); // If add is complete, or cmp is complete, zero. Else leave unchanged. *mode += addcond * (*mode == (0)) + cmpdone; // If in add mode and add completion is reached, increment mode. If in cmp mode and cmp completion reached, increment mode. } i32 cpusolve(cnf* c) { u32 state[3]; u32 wcnt = 1 + (c->cnts[0] >> 5U); u32* ctr = calloc((wcnt), sizeof(u32)); if (ctr == NULL) { printf("Failed to allocate solution buffer\n"); exit(1); } u32* max = calloc((wcnt), sizeof(u32)); if (max == NULL) { printf("Failed to allocate solution buffer\n"); exit(1); } stateaddpow(wcnt, max, c->cnts[0]); state[0] = 2; state[1] = state[2] = 0; while (state[0] < 4) { ctrthings5(c, state, ctr, max); } free(ctr); free(max); return state[1]; } i32 compareFiles(FILE *file1, FILE *file2){ char ch1 = getc(file1); char ch2 = getc(file2); int error = 0, pos = 0, line = 1; while (ch1 != EOF && ch2 != EOF){ pos++; if (ch1 == '\n' && ch2 == '\n'){ line++; pos = 0; } if (ch1 != ch2){ error++; printf("Line Number : %d \tError" " Position : %d \n", line, pos); } ch1 = getc(file1); ch2 = getc(file2); } if (ch1 != EOF || ch2 != EOF) error += 1; printf("Total Errors : %d\t\n", error); return error; } void debugsolve(char* path) { FILE* reffile = fopen("temp.txt", "w"); FILE* cmpfile = fopen("temp2.txt", "w"); runcsfloc(path, reffile); cnf* c = readDIMACS(path); sortlastnum(c); u32* state = malloc(sizeof(u32) * 3); u32 wcnt = 1 + (c->cnts[0] >> 5U); u32* ctr = calloc((wcnt), sizeof(u32)); if (ctr == NULL) { printf("Failed to allocate solution buffer\n"); exit(1); } u32* max = calloc((wcnt), sizeof(u32)); if (max == NULL) { printf("Failed to allocate solution buffer\n"); exit(1); } stateaddpow(wcnt, max, c->cnts[0]); state[0] = 2; state[1] = state[2] = 0; while (state[0] < 4) { ctrthings4(c, state, ctr, max, cmpfile); } free(ctr); free(max); freecnf(c); fclose(reffile); fclose(cmpfile); reffile = fopen("temp.txt", "r"); cmpfile = fopen("temp2.txt", "r"); i32 res = compareFiles(reffile, cmpfile); if (res != 0) { printf("%s\n", path); exit(1); } fclose(reffile); fclose(cmpfile); free(state); }