From 8eb057f7ae2c9c384a337f376277f555c8bafab0 Mon Sep 17 00:00:00 2001 From: krypdkat Date: Fri, 15 Mar 2024 14:15:35 +0700 Subject: [PATCH 1/6] improve score function --- src/score.h | 171 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 116 insertions(+), 55 deletions(-) diff --git a/src/score.h b/src/score.h index 0800fd9d..7c0a13df 100644 --- a/src/score.h +++ b/src/score.h @@ -119,6 +119,106 @@ struct ScoreFunction } } + static inline void merge(const unsigned short* A, const unsigned short* B, unsigned short* C, const unsigned short lenA, const unsigned short lenB) + { + unsigned short lA = 0, lB = 0; + int count = 0; + while (lA < lenA && lB < lenB) { + if (A[lA] < B[lB]) { + C[count++] = A[lA++]; + } + else { //guarantee unique + C[count++] = B[lB++]; + } + } + while (lA < lenA) C[count++] = A[lA++]; + while (lB < lenB) C[count++] = B[lB++]; + } + + static inline int mergeSortBucket(unsigned short* indices, const int* bucket, const int* modNum, unsigned short* output, unsigned short* buffer, const int totalModNum) + { + if (totalModNum == 1) { + int mod = modNum[0]; + int start = bucket[mod]; + int len = bucket[mod + 1] - start; + copyMem(output, indices + start, len * sizeof(unsigned short)); + return len; + } + if (totalModNum == 2) { + int mod = modNum[0]; + int start = bucket[mod]; + unsigned short* seg0 = indices + start; + unsigned short len0 = bucket[mod + 1] - start; + + mod = modNum[1]; + start = bucket[mod]; + unsigned short* seg1 = indices + start; + unsigned short len1 = bucket[mod + 1] - start; + + merge(seg0, seg1, output, len0, len1); + return len0 + len1; + } + // max depth = 5 + // it is guaranteed that there is no more than 32 segments if tick <= 256 + static_assert(MAX_INPUT_DURATION <= 256 && MAX_OUTPUT_DURATION <= 256, "Need to increase seg count"); + unsigned short* seg0_buffer[32]; + unsigned short* seg1_buffer[32]; + unsigned short len0_buffer[32]; + unsigned short len1_buffer[32]; + setMem(seg0_buffer, sizeof(seg0_buffer), 0); + setMem(seg1_buffer, sizeof(seg1_buffer), 0); + setMem(len0_buffer, sizeof(len0_buffer), 0); + setMem(len1_buffer, sizeof(len1_buffer), 0); + + unsigned short** seg0 = seg0_buffer; + unsigned short** seg1 = seg1_buffer; + unsigned short* len0 = len0_buffer; + unsigned short* len1 = len1_buffer; + for (int i = 0; i < totalModNum; i++) { + int mod = modNum[i]; + int start = bucket[mod]; + seg0[i] = indices + start; + len0[i] = bucket[mod + 1] - start; + } + + int nSegment = totalModNum; + for (int depth = 0; depth < 5; depth++) { + int newSegCount = 0; + for (int i = 0; i < nSegment; i += 2) { + if (i + 1 == nSegment) { + seg1[newSegCount] = seg0[i]; + len1[newSegCount] = len0[i]; + newSegCount++; + continue; + } + seg1[newSegCount] = buffer; + merge(seg0[i], seg0[i + 1], seg1[newSegCount], len0[i], len0[i + 1]); + len1[newSegCount] = len0[i] + len0[i + 1]; + buffer += len1[newSegCount]; + newSegCount++; + } + { + //swap ptr + unsigned short ** tmp = seg0; + seg0 = seg1; + seg1 = tmp; + } + { + unsigned short * tmp = len0; + len0 = len1; + len1 = tmp; + } + nSegment = newSegCount; + if (newSegCount <= 1) { // guaranteed will end up here + if (len0[0]) { + copyMem(output, seg0[0], len0[0] * sizeof(output[0])); + } + return len0[0]; + } + } + return -1; + } + void generateSynapse(int solutionBufIdx, const m256i& publicKey, const m256i& nonce) { auto& synapses = _synapses[solutionBufIdx]; @@ -209,44 +309,23 @@ struct ScoreFunction int totalIndice; for (int tick = 1; tick <= maxInputDuration; tick++) { for (unsigned int inputNeuronIndex = 0; inputNeuronIndex < numberOfInputNeurons + infoLength; inputNeuronIndex++) { - { - totalIndice = 0; - for (int i = 0; i < _totalModNum[tick]; i++) { - int mod = _modNum[tick][i]; - int start = bucketPosInput[inputNeuronIndex][mod]; - int end = bucketPosInput[inputNeuronIndex][mod + 1]; - if (end - start > 0) { - copyMem(indices + totalIndice, indicePosInput[inputNeuronIndex] + start, sizeof(unsigned short) * (end - start)); - totalIndice += end - start; - } - } - - for (int i = 1; i < totalIndice; i++) { - unsigned short key = indices[i]; - int j = i - 1; - while (j >= 0 && indices[j] > key) { - indices[j + 1] = indices[j]; - j = j - 1; - } - indices[j + 1] = key; + totalIndice = mergeSortBucket(indicePosInput[inputNeuronIndex], bucketPosInput[inputNeuronIndex], _modNum[tick], indices, (unsigned short*)sumBuffer, _totalModNum[tick]); + if (totalIndice == 0) continue; + for (int i = 0; i < totalIndice; i++) { + unsigned int anotherInputNeuronIndex = indices[i]; + const unsigned int offset = inputNeuronIndex * (dataLength + numberOfInputNeurons + infoLength) + anotherInputNeuronIndex; + if (synapses.inputLength[offset] > 0) { + sumBuffer[i] = neurons.input[anotherInputNeuronIndex]; } - - for (int i = 0; i < totalIndice; i++) { - unsigned int anotherInputNeuronIndex = indices[i]; - const unsigned int offset = inputNeuronIndex * (dataLength + numberOfInputNeurons + infoLength) + anotherInputNeuronIndex; - if (synapses.inputLength[offset] > 0) { - sumBuffer[i] = neurons.input[anotherInputNeuronIndex]; - } - else { - sumBuffer[i] = -neurons.input[anotherInputNeuronIndex]; - } - } - for (int i = 0; i < totalIndice; i++) - { - neurons.input[dataLength + inputNeuronIndex] += sumBuffer[i]; - clampNeuron(neurons.input[dataLength + inputNeuronIndex]); + else { + sumBuffer[i] = -neurons.input[anotherInputNeuronIndex]; } } + for (int i = 0; i < totalIndice; i++) + { + neurons.input[dataLength + inputNeuronIndex] += sumBuffer[i]; + clampNeuron(neurons.input[dataLength + inputNeuronIndex]); + } } } } @@ -304,26 +383,8 @@ struct ScoreFunction for (int tick = 1; tick <= maxOutputDuration; tick++) { for (unsigned int outputNeuronIndex = 0; outputNeuronIndex < numberOfOutputNeurons + dataLength; outputNeuronIndex++) { { - totalIndice = 0; - for (int i = 0; i < _totalModNum[tick]; i++) { - int mod = _modNum[tick][i]; - int start = bucketPosOutput[outputNeuronIndex][mod]; - int end = bucketPosOutput[outputNeuronIndex][mod + 1]; - if (end - start > 0) { - copyMem(indices + totalIndice, indicePosOutput[outputNeuronIndex] + start, sizeof(unsigned short) * (end - start)); - totalIndice += end - start; - } - } - - for (int i = 1; i < totalIndice; i++) { - unsigned short key = indices[i]; - int j = i - 1; - while (j >= 0 && indices[j] > key) { - indices[j + 1] = indices[j]; - j = j - 1; - } - indices[j + 1] = key; - } + totalIndice = mergeSortBucket(indicePosOutput[outputNeuronIndex], bucketPosOutput[outputNeuronIndex], _modNum[tick], indices, (unsigned short*)sumBuffer, _totalModNum[tick]); + if (totalIndice == 0) continue; for (int i = 0; i < totalIndice; i++) { unsigned int anotherOutputNeuronIndex = indices[i]; From 6b31b0cc842fdcd93753a329c6e6520100715366 Mon Sep 17 00:00:00 2001 From: CFB-QUBIC Date: Mon, 18 Mar 2024 12:38:14 +0300 Subject: [PATCH 2/6] Added QX::EntityAskOrders(), and similar stubs. --- src/smart_contracts/Qx.h | 44 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/smart_contracts/Qx.h b/src/smart_contracts/Qx.h index 3ac3e603..02b4434e 100644 --- a/src/smart_contracts/Qx.h +++ b/src/smart_contracts/Qx.h @@ -53,6 +53,42 @@ struct QX array orders; }; + struct EntityAskOrders_input + { + id entity; + uint64 offset; + }; + struct EntityAskOrders_output + { + struct Order + { + id issuer; + uint64 assetName; + sint64 price; + sint64 numberOfShares; + }; + + array orders; + }; + + struct EntityBidOrders_input + { + id entity; + uint64 offset; + }; + struct EntityBidOrders_output + { + struct Order + { + id issuer; + uint64 assetName; + sint64 price; + sint64 numberOfShares; + }; + + array orders; + }; + struct IssueAsset_input { uint64 assetName; @@ -147,6 +183,12 @@ struct QX PUBLIC(AssetBidOrders) _ + PUBLIC(EntityAskOrders) + _ + + PUBLIC(EntityBidOrders) + _ + PUBLIC(IssueAsset) if (invocationReward() < state._assetIssuanceFee) @@ -238,6 +280,8 @@ struct QX REGISTER_USER_FUNCTION(Fees, 1); REGISTER_USER_FUNCTION(AssetAskOrders, 2); REGISTER_USER_FUNCTION(AssetBidOrders, 3); + REGISTER_USER_FUNCTION(EntityAskOrders, 4); + REGISTER_USER_FUNCTION(EntityBidOrders, 5); _ REGISTER_USER_PROCEDURES From 59d5be7f23dbc5fd56ed0227e4a7dec32a823c5d Mon Sep 17 00:00:00 2001 From: krypdkat Date: Tue, 19 Mar 2024 22:08:34 +0700 Subject: [PATCH 3/6] update new neuron limit --- src/public_settings.h | 2 +- src/score.h | 4 ++-- test/score_reference.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/public_settings.h b/src/public_settings.h index 0903f86a..f5ee302f 100644 --- a/src/public_settings.h +++ b/src/public_settings.h @@ -30,7 +30,7 @@ static unsigned short CONTRACT_FILE_NAME[] = L"contract????.???"; #define NUMBER_OF_OUTPUT_NEURONS 1024 #define MAX_INPUT_DURATION 256 #define MAX_OUTPUT_DURATION 256 -#define NEURON_VALUE_LIMIT 1099511627776LL +#define NEURON_VALUE_LIMIT 1LL #define SOLUTION_THRESHOLD_DEFAULT 44 #define USE_SCORE_CACHE 1 #define SCORE_CACHE_SIZE 1000000 // the larger the better diff --git a/src/score.h b/src/score.h index 7c0a13df..4357f0fe 100644 --- a/src/score.h +++ b/src/score.h @@ -111,8 +111,8 @@ struct ScoreFunction static inline void clampNeuron(long long& val) { - if (val >= NEURON_VALUE_LIMIT) { - val = NEURON_VALUE_LIMIT - 1; + if (val > NEURON_VALUE_LIMIT) { + val = NEURON_VALUE_LIMIT; } else if (val < -NEURON_VALUE_LIMIT) { val = -NEURON_VALUE_LIMIT; diff --git a/test/score_reference.h b/test/score_reference.h index 9ccd18d8..b0de3f4e 100644 --- a/test/score_reference.h +++ b/test/score_reference.h @@ -42,8 +42,8 @@ struct ScoreReferenceImplementation static inline void clampNeuron(long long& val) { - if (val >= NEURON_VALUE_LIMIT) { - val = NEURON_VALUE_LIMIT - 1; + if (val > NEURON_VALUE_LIMIT) { + val = NEURON_VALUE_LIMIT; } else if (val < -NEURON_VALUE_LIMIT) { val = -NEURON_VALUE_LIMIT; From e9059bf391d3e922495f94e2b4c0c39c80979b32 Mon Sep 17 00:00:00 2001 From: krypdkat Date: Tue, 19 Mar 2024 22:09:14 +0700 Subject: [PATCH 4/6] increase neuron lengths --- src/public_settings.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/public_settings.h b/src/public_settings.h index f5ee302f..5c468fa4 100644 --- a/src/public_settings.h +++ b/src/public_settings.h @@ -26,8 +26,8 @@ static unsigned short CONTRACT_FILE_NAME[] = L"contract????.???"; #define DATA_LENGTH 256 #define INFO_LENGTH 128 -#define NUMBER_OF_INPUT_NEURONS 1024 -#define NUMBER_OF_OUTPUT_NEURONS 1024 +#define NUMBER_OF_INPUT_NEURONS 2048 +#define NUMBER_OF_OUTPUT_NEURONS 2048 #define MAX_INPUT_DURATION 256 #define MAX_OUTPUT_DURATION 256 #define NEURON_VALUE_LIMIT 1LL From 8975d97ac253a561f2280d0c3ec6b0834f36678e Mon Sep 17 00:00:00 2001 From: Philipp Werner <22914157+philippwerner@users.noreply.github.com> Date: Tue, 19 Mar 2024 16:34:41 +0100 Subject: [PATCH 5/6] Fix bug, enable F3 key, add comments --- src/qubic.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/qubic.cpp b/src/qubic.cpp index 0b8b6db3..32b45659 100644 --- a/src/qubic.cpp +++ b/src/qubic.cpp @@ -2180,11 +2180,12 @@ static void processTick(unsigned long long processorNumber) minerScores[minerIndex] = tmpScore; } + // combine 225 worst current computors with 225 best candidates for (unsigned int i = 0; i < NUMBER_OF_COMPUTORS - QUORUM; i++) { competitorPublicKeys[i] = minerPublicKeys[QUORUM + i]; competitorScores[i] = minerScores[QUORUM + i]; - competitorComputorStatuses[QUORUM + i] = true; + competitorComputorStatuses[i] = true; if (NUMBER_OF_COMPUTORS + i < numberOfMiners) { @@ -2197,6 +2198,8 @@ static void processTick(unsigned long long processorNumber) } competitorComputorStatuses[i + (NUMBER_OF_COMPUTORS - QUORUM)] = false; } + + // bubble sorting -> top 225 from competitorPublicKeys have computors and candidates which are the best from that subset for (unsigned int i = NUMBER_OF_COMPUTORS - QUORUM; i < (NUMBER_OF_COMPUTORS - QUORUM) * 2; i++) { int j = i; @@ -2208,8 +2211,10 @@ static void processTick(unsigned long long processorNumber) { competitorPublicKeys[j] = competitorPublicKeys[j - 1]; competitorScores[j] = competitorScores[j - 1]; + competitorComputorStatuses[j] = competitorComputorStatuses[j - 1]; competitorPublicKeys[--j] = tmpPublicKey; competitorScores[j] = tmpScore; + competitorComputorStatuses[j] = tmpComputorStatus; } } @@ -4283,7 +4288,7 @@ static void processKeyPresses() * F3 Key * By Pressing the F3 Key the node will display the current state of the mining race * You can see which of your ID's is at which position. - * + */ case 0x0D: { unsigned int numberOfSolutions = 0; @@ -4301,7 +4306,7 @@ static void processKeyPresses() appendText(message, L")."); logToConsole(message); } - break;*/ + break; /* * F4 Key From 6211348b774e06b459aa133cec7144402c6af686 Mon Sep 17 00:00:00 2001 From: Philipp Werner <22914157+philippwerner@users.noreply.github.com> Date: Wed, 20 Mar 2024 11:37:38 +0100 Subject: [PATCH 6/6] Update params for version 1.197.0 / epoch 101 --- src/public_settings.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/public_settings.h b/src/public_settings.h index 5c468fa4..f5f3392a 100644 --- a/src/public_settings.h +++ b/src/public_settings.h @@ -8,11 +8,11 @@ #define NUMBER_OF_SOLUTION_PROCESSORS 6 // do not increase this for this epoch, because there may be issues due too fast ticking #define VERSION_A 1 -#define VERSION_B 196 +#define VERSION_B 197 #define VERSION_C 0 -#define EPOCH 100 -#define TICK 12950000 +#define EPOCH 101 +#define TICK 13060000 // random seed is now obtained from spectrumDigests @@ -31,7 +31,7 @@ static unsigned short CONTRACT_FILE_NAME[] = L"contract????.???"; #define MAX_INPUT_DURATION 256 #define MAX_OUTPUT_DURATION 256 #define NEURON_VALUE_LIMIT 1LL -#define SOLUTION_THRESHOLD_DEFAULT 44 +#define SOLUTION_THRESHOLD_DEFAULT 42 #define USE_SCORE_CACHE 1 #define SCORE_CACHE_SIZE 1000000 // the larger the better #define SCORE_CACHE_COLLISION_RETRIES 20 // number of retries to find entry in cache in case of hash collision