Instructions to use cahlen/ramanujan-machine-cuda with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Kernels
How to use cahlen/ramanujan-machine-cuda with Kernels:
# !pip install kernels from kernels import get_kernel kernel = get_kernel("cahlen/ramanujan-machine-cuda") - Notebooks
- Google Colab
- Kaggle
Add torch library bindings (guard main, add torch wrapper functions)
Browse files- ramanujan/ramanujan_v2.cu +69 -0
- torch-ext/torch_binding.cpp +2 -0
- torch-ext/torch_binding.h +4 -1
ramanujan/ramanujan_v2.cu
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
/*
|
| 2 |
* Ramanujan Machine v2: ASYMMETRIC-DEGREE polynomial CF search
|
| 3 |
*
|
|
@@ -332,6 +336,8 @@ __global__ void search_kernel(
|
|
| 332 |
|
| 333 |
/* ββ Main ββββββββββββββββββββββββββββββββββββββββββββββββββββ */
|
| 334 |
|
|
|
|
|
|
|
| 335 |
int main(int argc, char **argv) {
|
| 336 |
if (argc < 5) {
|
| 337 |
printf("Usage: %s <deg_a> <deg_b> <range_a> <range_b> [cf_depth] [gpu_id]\n", argv[0]);
|
|
@@ -534,3 +540,66 @@ int main(int argc, char **argv) {
|
|
| 534 |
cudaFree(d_hit_count); cudaFree(d_unmatched_count);
|
| 535 |
return 0;
|
| 536 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifdef TORCH_EXTENSION_NAME
|
| 2 |
+
#include <torch/torch.h>
|
| 3 |
+
#endif
|
| 4 |
+
|
| 5 |
/*
|
| 6 |
* Ramanujan Machine v2: ASYMMETRIC-DEGREE polynomial CF search
|
| 7 |
*
|
|
|
|
| 336 |
|
| 337 |
/* ββ Main ββββββββββββββββββββββββββββββββββββββββββββββββββββ */
|
| 338 |
|
| 339 |
+
#ifndef TORCH_EXTENSION_NAME
|
| 340 |
+
|
| 341 |
int main(int argc, char **argv) {
|
| 342 |
if (argc < 5) {
|
| 343 |
printf("Usage: %s <deg_a> <deg_b> <range_a> <range_b> [cf_depth] [gpu_id]\n", argv[0]);
|
|
|
|
| 540 |
cudaFree(d_hit_count); cudaFree(d_unmatched_count);
|
| 541 |
return 0;
|
| 542 |
}
|
| 543 |
+
#endif
|
| 544 |
+
|
| 545 |
+
|
| 546 |
+
#ifdef TORCH_EXTENSION_NAME
|
| 547 |
+
std::vector<torch::Tensor> search(int64_t deg_a, int64_t deg_b,
|
| 548 |
+
int64_t range_a, int64_t range_b,
|
| 549 |
+
int64_t cf_depth) {
|
| 550 |
+
int max_hits = 500000, max_unmatched = 1000000;
|
| 551 |
+
Hit *d_hits, *d_unmatched;
|
| 552 |
+
int *d_hit_count, *d_unmatched_count;
|
| 553 |
+
cudaMalloc(&d_hits, max_hits * sizeof(Hit));
|
| 554 |
+
cudaMalloc(&d_unmatched, max_unmatched * sizeof(Hit));
|
| 555 |
+
cudaMalloc(&d_hit_count, sizeof(int));
|
| 556 |
+
cudaMalloc(&d_unmatched_count, sizeof(int));
|
| 557 |
+
cudaMemset(d_hit_count, 0, sizeof(int));
|
| 558 |
+
cudaMemset(d_unmatched_count, 0, sizeof(int));
|
| 559 |
+
|
| 560 |
+
long long width_a = 2 * range_a + 1;
|
| 561 |
+
long long width_b = 2 * range_b + 1;
|
| 562 |
+
long long total_a = 1, total_b = 1;
|
| 563 |
+
for (int i = 0; i <= deg_a; i++) total_a *= width_a;
|
| 564 |
+
for (int i = 0; i <= deg_b; i++) total_b *= width_b;
|
| 565 |
+
long long total = total_a * total_b;
|
| 566 |
+
|
| 567 |
+
long long chunk = 1000000;
|
| 568 |
+
for (long long start = 0; start < total; start += chunk) {
|
| 569 |
+
long long count = std::min(chunk, total - start);
|
| 570 |
+
int blocks = ((int)count + 255) / 256;
|
| 571 |
+
search_kernel<<<blocks, 256>>>(start, count,
|
| 572 |
+
(int)deg_a, (int)deg_b, (int)range_a, (int)range_b, (int)cf_depth,
|
| 573 |
+
d_hits, d_hit_count, max_hits,
|
| 574 |
+
d_unmatched, d_unmatched_count, max_unmatched);
|
| 575 |
+
cudaDeviceSynchronize();
|
| 576 |
+
}
|
| 577 |
+
|
| 578 |
+
int h_hc, h_uc;
|
| 579 |
+
cudaMemcpy(&h_hc, d_hit_count, sizeof(int), cudaMemcpyDeviceToHost);
|
| 580 |
+
cudaMemcpy(&h_uc, d_unmatched_count, sizeof(int), cudaMemcpyDeviceToHost);
|
| 581 |
+
h_hc = std::min(h_hc, max_hits);
|
| 582 |
+
h_uc = std::min(h_uc, max_unmatched);
|
| 583 |
+
|
| 584 |
+
auto hit_vals = torch::zeros({h_hc}, torch::kFloat64);
|
| 585 |
+
auto hit_match = torch::zeros({h_hc}, torch::kInt32);
|
| 586 |
+
if (h_hc > 0) {
|
| 587 |
+
std::vector<Hit> hh(h_hc);
|
| 588 |
+
cudaMemcpy(hh.data(), d_hits, h_hc * sizeof(Hit), cudaMemcpyDeviceToHost);
|
| 589 |
+
for (int i = 0; i < h_hc; i++) {
|
| 590 |
+
hit_vals.data_ptr<double>()[i] = hh[i].value;
|
| 591 |
+
hit_match.data_ptr<int>()[i] = hh[i].match_const;
|
| 592 |
+
}
|
| 593 |
+
}
|
| 594 |
+
auto um_vals = torch::zeros({h_uc}, torch::kFloat64);
|
| 595 |
+
if (h_uc > 0) {
|
| 596 |
+
std::vector<Hit> uh(h_uc);
|
| 597 |
+
cudaMemcpy(uh.data(), d_unmatched, h_uc * sizeof(Hit), cudaMemcpyDeviceToHost);
|
| 598 |
+
for (int i = 0; i < h_uc; i++) um_vals.data_ptr<double>()[i] = uh[i].value;
|
| 599 |
+
}
|
| 600 |
+
|
| 601 |
+
cudaFree(d_hits); cudaFree(d_unmatched);
|
| 602 |
+
cudaFree(d_hit_count); cudaFree(d_unmatched_count);
|
| 603 |
+
return {hit_vals, hit_match, um_vals};
|
| 604 |
+
}
|
| 605 |
+
#endif
|
torch-ext/torch_binding.cpp
CHANGED
|
@@ -3,4 +3,6 @@
|
|
| 3 |
|
| 4 |
PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {
|
| 5 |
m.doc() = "Ramanujan Machine v2 (Asymmetric-Degree CF Search) CUDA kernel";
|
|
|
|
|
|
|
| 6 |
}
|
|
|
|
| 3 |
|
| 4 |
PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {
|
| 5 |
m.doc() = "Ramanujan Machine v2 (Asymmetric-Degree CF Search) CUDA kernel";
|
| 6 |
+
m.def("search", &search, py::arg("deg_a"), py::arg("deg_b"),
|
| 7 |
+
py::arg("range_a"), py::arg("range_b"), py::arg("cf_depth") = 300);
|
| 8 |
}
|
torch-ext/torch_binding.h
CHANGED
|
@@ -1,3 +1,6 @@
|
|
| 1 |
#pragma once
|
| 2 |
#include <torch/torch.h>
|
| 3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
#pragma once
|
| 2 |
#include <torch/torch.h>
|
| 3 |
+
|
| 4 |
+
std::vector<torch::Tensor> search(int64_t deg_a, int64_t deg_b,
|
| 5 |
+
int64_t range_a, int64_t range_b,
|
| 6 |
+
int64_t cf_depth);
|