-
Notifications
You must be signed in to change notification settings - Fork 1
Mps backend #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Mps backend #1
Changes from all commits
b68724c
a5ad326
e28ea7d
e3e647e
cca96ce
7df7d01
9b81352
64a368d
c11f815
24045c8
751f9f4
ce980cc
343d969
39468d9
deba942
abe8da6
8c881ac
3a2c607
7f0db08
74b9d33
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,7 +22,8 @@ class DeviceType { | |
| public: | ||
| enum { | ||
| CUDA = 0, | ||
| OpenCL | ||
| OpenCL, | ||
| Metal | ||
| }; | ||
| }; | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| # Makefile for building the Metal backend on macOS | ||
|
|
||
| # Compiler | ||
| CXX=clang++ | ||
|
|
||
| # Directories | ||
| CUR_DIR=$(shell pwd) | ||
| LIBDIR=$(CUR_DIR)/lib | ||
| BINDIR=$(CUR_DIR)/bin | ||
|
|
||
| # Source directories | ||
| DIRS=util AddressUtil CmdParse CryptoUtil KeyFinderLib MetalKeySearchDevice secp256k1lib Logger | ||
|
|
||
| # Include paths | ||
| INCLUDE = $(foreach d, $(DIRS), -I$(CUR_DIR)/$d) | ||
| INCLUDE += -I/opt/homebrew/opt/openssl/include | ||
|
|
||
| # C++ flags | ||
| CXXFLAGS=-O2 -std=c++17 -Wno-unused-parameter -DBUILD_METAL | ||
|
|
||
| # Linker flags | ||
| LDFLAGS=-L/opt/homebrew/opt/openssl/lib -L${LIBDIR} -framework Metal -framework Foundation | ||
|
|
||
| # Libraries | ||
| LIBS=-lkeyfinder -laddressutil -lsecp256k1 -lcryptoutil -lMetalKeySearchDevice -llogger -lutil -lcmdparse -lcrypto | ||
|
|
||
| # Source files | ||
| SRCS = $(wildcard util/*.cpp) \ | ||
| $(wildcard AddressUtil/*.cpp) \ | ||
| $(wildcard CmdParse/*.cpp) \ | ||
| $(wildcard CryptoUtil/*.cpp) \ | ||
| $(wildcard KeyFinderLib/*.cpp) \ | ||
| $(wildcard MetalKeySearchDevice/*.cpp) \ | ||
| $(wildcard secp256k1lib/*.cpp) \ | ||
| $(wildcard Logger/*.cpp) \ | ||
| KeyFinder/main.cpp \ | ||
| KeyFinder/ConfigFile.cpp \ | ||
| KeyFinder/DeviceManager.cpp | ||
|
|
||
| # Target | ||
| all: metalBitCrack | ||
|
|
||
| metalBitCrack: | ||
| mkdir -p ${BINDIR} | ||
| ${CXX} -o ${BINDIR}/metalBitCrack ${SRCS} ${INCLUDE} ${CXXFLAGS} ${LDFLAGS} ${LIBS} | ||
|
|
||
| clean: | ||
| rm -rf ${BINDIR} | ||
|
|
||
| .PHONY: all clean |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| .PHONY: all clean | ||
|
|
||
| SRC=$(wildcard *.cpp) | ||
| OBJS=$(SRC:.cpp=.o) | ||
|
|
||
| all: ${OBJS} | ||
|
|
||
| %.o: %.cpp | ||
| ${CXX} -c $< -o $@ ${INCLUDE} ${CXXFLAGS} | ||
|
|
||
| clean: | ||
| rm -rf *.o |
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,127 @@ | ||||||||||||||
| #include "MetalKeySearchDevice.h" | ||||||||||||||
| #include "Logger.h" | ||||||||||||||
| #include "util.h" | ||||||||||||||
| #include <fstream> | ||||||||||||||
| #include <iostream> | ||||||||||||||
|
|
||||||||||||||
| MetalKeySearchDevice::MetalKeySearchDevice(int deviceId, uint64_t keysPerStep) { | ||||||||||||||
| _device = MTL::CreateSystemDefaultDevice(); | ||||||||||||||
| if(!_device) { | ||||||||||||||
| throw KeySearchException("Failed to create Metal device"); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| _commandQueue = _device->newCommandQueue(); | ||||||||||||||
| if(!_commandQueue) { | ||||||||||||||
| throw KeySearchException("Failed to create Metal command queue"); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| std::string source = util::readTextFile("MetalKeySearchDevice/keysearch.metal"); | ||||||||||||||
| if(source.empty()) { | ||||||||||||||
| throw KeySearchException("Failed to read metal kernel file"); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| NS::Error* error = nullptr; | ||||||||||||||
| _library = _device->newLibrary(NS::String::string(source.c_str(), NS::UTF8StringEncoding), nullptr, &error); | ||||||||||||||
| if(!_library) { | ||||||||||||||
| throw KeySearchException("Failed to create Metal library: " + std::string(error->localizedDescription()->utf8String())); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| _function = _library->newFunction(NS::String::string("generate_public_key", NS::UTF8StringEncoding)); | ||||||||||||||
| if(!_function) { | ||||||||||||||
| throw KeySearchException("Failed to create Metal function"); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| _pipelineState = _device->newComputePipelineState(_function, &error); | ||||||||||||||
| if(!_pipelineState) { | ||||||||||||||
| throw KeySearchException("Failed to create Metal pipeline state: " + std::string(error->localizedDescription()->utf8String())); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| this->_keysPerStep = keysPerStep; | ||||||||||||||
| Logger::log(LogLevel::Info, "MetalKeySearchDevice created"); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| MetalKeySearchDevice::~MetalKeySearchDevice() { | ||||||||||||||
| _pipelineState->release(); | ||||||||||||||
| _function->release(); | ||||||||||||||
| _library->release(); | ||||||||||||||
| _commandQueue->release(); | ||||||||||||||
| _device->release(); | ||||||||||||||
| Logger::log(LogLevel::Info, "MetalKeySearchDevice destroyed"); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| void MetalKeySearchDevice::init(const secp256k1::uint256 &start, int compression, const secp256k1::uint256 &stride) { | ||||||||||||||
| this->_startKey = start; | ||||||||||||||
| this->_compression = compression; | ||||||||||||||
| this->_stride = stride; | ||||||||||||||
| Logger::log(LogLevel::Info, "MetalKeySearchDevice initialized"); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| void MetalKeySearchDevice::doStep() { | ||||||||||||||
| // Create buffers | ||||||||||||||
| MTL::Buffer* privateKeysBuffer = _device->newBuffer(_keysPerStep * sizeof(uint256_t), MTL::ResourceStorageModeShared); | ||||||||||||||
| MTL::Buffer* publicKeysXBuffer = _device->newBuffer(_keysPerStep * sizeof(uint256_t), MTL::ResourceStorageModeShared); | ||||||||||||||
| MTL::Buffer* publicKeysYBuffer = _device->newBuffer(_keysPerStep * sizeof(uint256_t), MTL::ResourceStorageModeShared); | ||||||||||||||
|
|
||||||||||||||
| // Generate private keys | ||||||||||||||
| uint256_t* privateKeys = (uint256_t*)privateKeysBuffer->contents(); | ||||||||||||||
| for (uint64_t i = 0; i < _keysPerStep; i++) { | ||||||||||||||
| privateKeys[i] = _startKey + _stride * i; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| // Create a command buffer | ||||||||||||||
| MTL::CommandBuffer* commandBuffer = _commandQueue->commandBuffer(); | ||||||||||||||
| MTL::ComputeCommandEncoder*- commandEncoder = commandBuffer->computeCommandEncoder(); | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix syntax error in variable declaration There's a syntax error with an errant dash character in the variable name. - MTL::ComputeCommandEncoder*- commandEncoder = commandBuffer->computeCommandEncoder();
+ MTL::ComputeCommandEncoder* commandEncoder = commandBuffer->computeCommandEncoder();📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
|
|
||||||||||||||
| // Set pipeline state and buffers | ||||||||||||||
| commandEncoder->setComputePipelineState(_pipelineState); | ||||||||||||||
| commandEncoder->setBuffer(privateKeysBuffer, 0, 0); | ||||||||||||||
| commandEncoder->setBuffer(publicKeysXBuffer, 0, 1); | ||||||||||||||
| commandEncoder->setBuffer(publicKeysYBuffer, 0, 2); | ||||||||||||||
|
|
||||||||||||||
| // Dispatch the kernel | ||||||||||||||
| MTL::Size gridSize = MTL::Size(_keysPerStep, 1, 1); | ||||||||||||||
| NS::UInteger threadGroupSize = _pipelineState->maxTotalThreadsPerThreadgroup(); | ||||||||||||||
| if (threadGroupSize > _keysPerStep) { | ||||||||||||||
| threadGroupSize = _keysPerStep; | ||||||||||||||
| } | ||||||||||||||
| MTL::Size threadgroupSize = MTL::Size(threadGroupSize, 1, 1); | ||||||||||||||
| commandEncoder->dispatchThreads(gridSize, threadgroupSize); | ||||||||||||||
|
|
||||||||||||||
| // End encoding and commit the command buffer | ||||||||||||||
| commandEncoder->endEncoding(); | ||||||||||||||
| commandBuffer->commit(); | ||||||||||||||
| commandBuffer->waitUntilCompleted(); | ||||||||||||||
|
|
||||||||||||||
| // TODO: Read results and check for matches | ||||||||||||||
|
|
||||||||||||||
| // Clean up | ||||||||||||||
| privateKeysBuffer->release(); | ||||||||||||||
| publicKeysXBuffer->release(); | ||||||||||||||
| publicKeysYBuffer->release(); | ||||||||||||||
|
|
||||||||||||||
| _startKey = _startKey + _stride * _keysPerStep; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| void MetalKeySearchDevice::setTargets(const std::set<KeySearchTarget> &targets) { | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| size_t MetalKeySearchDevice::getResults(std::vector<KeySearchResult> &results) { | ||||||||||||||
| return 0; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| uint64_t MetalKeySearchDevice::keysPerStep() { | ||||||||||||||
| return 0; | ||||||||||||||
| } | ||||||||||||||
|
Comment on lines
+112
to
+114
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Return actual keys per step value The method returns 0 instead of the stored uint64_t MetalKeySearchDevice::keysPerStep() {
- return 0;
+ return _keysPerStep;
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
|
|
||||||||||||||
| std::string MetalKeySearchDevice::getDeviceName() { | ||||||||||||||
| return "Metal Key Search Device"; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| void MetalKeySearchDevice::getMemoryInfo(uint64_t &freeMem, uint64_t &totalMem) { | ||||||||||||||
| freeMem = 0; | ||||||||||||||
| totalMem = 0; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| secp256k1::uint256 MetalKeySearchDevice::getNextKey() { | ||||||||||||||
| return secp256k1::uint256(0); | ||||||||||||||
| } | ||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| #ifndef _METAL_KEY_SEARCH_DEVICE_H | ||
| #define _METAL_KEY_SEARCH_DEVICE_H | ||
|
|
||
| #include "KeySearchDevice.h" | ||
| #include <Metal/Metal.hpp> | ||
|
|
||
| class MetalKeySearchDevice : public KeySearchDevice { | ||
| private: | ||
| MTL::Device* _device; | ||
| MTL::CommandQueue* _commandQueue; | ||
| MTL::Library* _library; | ||
| MTL::Function* _function; | ||
| MTL::ComputePipelineState* _pipelineState; | ||
|
|
||
| secp256k1::uint256 _startKey; | ||
| secp256k1::uint256 _stride; | ||
| int _compression; | ||
| std::vector<KeySearchTarget> _targets; | ||
| uint64_t _keysPerStep; | ||
|
|
||
| public: | ||
| MetalKeySearchDevice(int deviceId, uint64_t keysPerStep); | ||
| virtual ~MetalKeySearchDevice(); | ||
|
|
||
| virtual void init(const secp256k1::uint256 &start, int compression, const secp256k1::uint256 &stride); | ||
| virtual void doStep(); | ||
| virtual void setTargets(const std::set<KeySearchTarget> &targets); | ||
| virtual size_t getResults(std::vector<KeySearchResult> &results); | ||
| virtual uint64_t keysPerStep(); | ||
| virtual std::string getDeviceName(); | ||
| virtual void getMemoryInfo(uint64_t &freeMem, uint64_t &totalMem); | ||
| virtual secp256k1::uint256 getNextKey(); | ||
| }; | ||
|
|
||
| #endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Type mismatch: use secp256k1::uint256 instead of uint256_t
The code uses
uint256_twhich doesn't match the Metal shader's struct definition. The private key arithmetic should usesecp256k1::uint256and properly handle the conversion to the shader's format.The buffer allocation and private key generation need to be rewritten to:
uint256_tsecp256k1::uint256to the shader format📝 Committable suggestion
🤖 Prompt for AI Agents