Showing preview only (2,608K chars total). Download the full file or copy to clipboard to get everything.
Repository: gorse-io/gorse
Branch: master
Commit: 64847a36c966
Files: 274
Total size: 2.4 MB
Directory structure:
gitextract_2md3h71u/
├── .devcontainer/
│ ├── Dockerfile
│ └── devcontainer.json
├── .dockerignore
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ ├── custom.md
│ │ └── feature_request.md
│ └── workflows/
│ ├── assign_issue.yml
│ ├── backport.yml
│ ├── build_docker.yml
│ ├── build_release.yml
│ ├── build_test.yml
│ ├── dockerhub-description.yml
│ └── translate_issues.yml
├── .gitignore
├── .golangci.yml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── client/
│ ├── README.md
│ ├── client_test.go
│ ├── config.go
│ ├── config.toml
│ ├── docker-compose.yml.j2
│ └── setup-test.sh
├── cmd/
│ ├── goat/
│ │ └── README.md
│ ├── gorse-cli/
│ │ └── main.go
│ ├── gorse-in-one/
│ │ ├── Dockerfile
│ │ ├── Dockerfile.cuda
│ │ ├── Dockerfile.mkl
│ │ ├── Dockerfile.openblas
│ │ ├── Dockerfile.windows
│ │ └── main.go
│ ├── gorse-master/
│ │ ├── Dockerfile
│ │ ├── Dockerfile.cuda
│ │ ├── Dockerfile.mkl
│ │ ├── Dockerfile.openblas
│ │ ├── Dockerfile.windows
│ │ └── main.go
│ ├── gorse-server/
│ │ ├── Dockerfile
│ │ ├── Dockerfile.cuda
│ │ ├── Dockerfile.mkl
│ │ ├── Dockerfile.openblas
│ │ ├── Dockerfile.windows
│ │ └── main.go
│ ├── gorse-worker/
│ │ ├── Dockerfile
│ │ ├── Dockerfile.cuda
│ │ ├── Dockerfile.mkl
│ │ ├── Dockerfile.openblas
│ │ ├── Dockerfile.windows
│ │ └── main.go
│ └── version/
│ └── version.go
├── codecov.yml
├── common/
│ ├── ann/
│ │ ├── ann.go
│ │ ├── ann_test.go
│ │ ├── bruteforce.go
│ │ └── hnsw.go
│ ├── blas/
│ │ ├── blas.go
│ │ ├── blas_darwin_arm64.go
│ │ ├── blas_mkl.go
│ │ └── blas_openblas.go
│ ├── copier/
│ │ ├── copier.go
│ │ └── copier_test.go
│ ├── datautil/
│ │ ├── datautil.go
│ │ └── datautil_test.go
│ ├── encoding/
│ │ ├── encoding.go
│ │ └── encoding_test.go
│ ├── expression/
│ │ ├── expression.go
│ │ └── expression_test.go
│ ├── floats/
│ │ ├── floats.go
│ │ ├── floats_amd64.go
│ │ ├── floats_amd64_test.go
│ │ ├── floats_arm64.go
│ │ ├── floats_arm64_test.go
│ │ ├── floats_avx.go
│ │ ├── floats_avx.s
│ │ ├── floats_avx512.go
│ │ ├── floats_avx512.s
│ │ ├── floats_neon.go
│ │ ├── floats_neon.s
│ │ ├── floats_noasm.go
│ │ ├── floats_riscv64.go
│ │ ├── floats_riscv64_test.go
│ │ ├── floats_rvv.go
│ │ ├── floats_rvv.s
│ │ ├── floats_test.go
│ │ ├── mm.go
│ │ ├── mm_darwin_arm64.go
│ │ ├── mm_mkl.go
│ │ ├── mm_openblas.go
│ │ └── src/
│ │ ├── .gitignore
│ │ ├── Makefile
│ │ ├── floats_avx.c
│ │ ├── floats_avx512.c
│ │ ├── floats_neon.c
│ │ ├── floats_rvv.c
│ │ ├── floats_sve2.c
│ │ ├── floats_test.c
│ │ ├── munit.c
│ │ └── munit.h
│ ├── heap/
│ │ ├── filter.go
│ │ ├── filter_test.go
│ │ ├── pq.go
│ │ └── pq_test.go
│ ├── jsonutil/
│ │ ├── json.go
│ │ └── json_test.go
│ ├── log/
│ │ ├── log.go
│ │ └── log_test.go
│ ├── mock/
│ │ ├── openai.go
│ │ └── openai_test.go
│ ├── monitor/
│ │ ├── progress.go
│ │ └── progress_test.go
│ ├── nn/
│ │ ├── functions.go
│ │ ├── layers.go
│ │ ├── nn_test.go
│ │ ├── op.go
│ │ ├── op_test.go
│ │ ├── optimizers.go
│ │ ├── tensor.go
│ │ └── tensor_test.go
│ ├── parallel/
│ │ ├── parallel.go
│ │ ├── parallel_test.go
│ │ ├── ratelimit.go
│ │ └── ratelimit_test.go
│ ├── rc/
│ │ ├── rc.go
│ │ └── rc_test.go
│ ├── reranker/
│ │ ├── client.go
│ │ └── client_test.go
│ ├── sizeof/
│ │ ├── size.go
│ │ └── size_test.go
│ └── util/
│ ├── random.go
│ ├── random_test.go
│ ├── strconv.go
│ ├── tls.go
│ ├── util.go
│ └── util_test.go
├── config/
│ ├── config.go
│ ├── config.toml
│ └── config_test.go
├── dataset/
│ ├── dataset.go
│ ├── dataset_test.go
│ ├── dict.go
│ ├── dict_test.go
│ ├── index.go
│ ├── index_test.go
│ ├── unified_index.go
│ └── unified_index_test.go
├── docker-bake.hcl
├── docker-compose.yml
├── go.mod
├── go.sum
├── logics/
│ ├── cf.go
│ ├── cf_test.go
│ ├── chat.go
│ ├── chat_test.go
│ ├── external.go
│ ├── external_test.go
│ ├── item_to_item.go
│ ├── item_to_item_test.go
│ ├── non_personalized.go
│ ├── non_personalized_test.go
│ ├── recommend.go
│ ├── recommend_test.go
│ ├── user_to_user.go
│ └── user_to_user_test.go
├── master/
│ ├── master.go
│ ├── master_test.go
│ ├── metrics.go
│ ├── metrics_test.go
│ ├── rest.go
│ ├── rest_test.go
│ ├── rpc.go
│ ├── rpc_test.go
│ ├── tasks.go
│ └── tasks_test.go
├── model/
│ ├── built_in.go
│ ├── built_in_test.go
│ ├── cf/
│ │ ├── evaluator.go
│ │ ├── evaluator_test.go
│ │ ├── model.go
│ │ ├── model_test.go
│ │ ├── optimize.go
│ │ └── optimize_test.go
│ ├── ctr/
│ │ ├── data.go
│ │ ├── data_test.go
│ │ ├── evaluator.go
│ │ ├── evaluator_test.go
│ │ ├── fm.go
│ │ ├── fm_xla.go
│ │ ├── model.go
│ │ ├── model.py
│ │ ├── model_test.go
│ │ ├── optimize.go
│ │ └── optimize_test.go
│ ├── model.go
│ ├── params.go
│ └── params_test.go
├── protocol/
│ ├── cache_store.pb.go
│ ├── cache_store.proto
│ ├── cache_store_grpc.pb.go
│ ├── data_store.pb.go
│ ├── data_store.proto
│ ├── data_store_grpc.pb.go
│ ├── encoding.pb.go
│ ├── encoding.proto
│ ├── generate.go
│ ├── protocol.pb.go
│ ├── protocol.proto
│ ├── protocol_grpc.pb.go
│ ├── vector_store.pb.go
│ ├── vector_store.proto
│ └── vector_store_grpc.pb.go
├── server/
│ ├── metrics.go
│ ├── rest.go
│ ├── rest_test.go
│ ├── server.go
│ └── server_test.go
├── storage/
│ ├── blob/
│ │ ├── azure.go
│ │ ├── azure_test.go
│ │ ├── blob.go
│ │ ├── blob_test.go
│ │ ├── gcs.go
│ │ ├── gcs_test.go
│ │ ├── posix.go
│ │ ├── posix_test.go
│ │ ├── s3.go
│ │ └── s3_test.go
│ ├── cache/
│ │ ├── database.go
│ │ ├── database_test.go
│ │ ├── mongodb.go
│ │ ├── mongodb_test.go
│ │ ├── no_database.go
│ │ ├── no_database_test.go
│ │ ├── proxy.go
│ │ ├── proxy_test.go
│ │ ├── redis.go
│ │ ├── redis_test.go
│ │ ├── sql.go
│ │ └── sql_test.go
│ ├── data/
│ │ ├── database.go
│ │ ├── database_test.go
│ │ ├── mongodb.go
│ │ ├── mongodb_test.go
│ │ ├── no_database.go
│ │ ├── no_database_test.go
│ │ ├── proxy.go
│ │ ├── proxy_test.go
│ │ ├── sql.go
│ │ └── sql_test.go
│ ├── docker-compose.yml
│ ├── meta/
│ │ ├── database.go
│ │ ├── database_test.go
│ │ ├── sqlite.go
│ │ └── sqlite_test.go
│ ├── options.go
│ ├── schema_test.go
│ ├── scheme.go
│ └── vectors/
│ ├── database.go
│ ├── database_test.go
│ ├── milvus.go
│ ├── milvus_test.go
│ ├── proxy.go
│ ├── proxy_test.go
│ ├── qdrant.go
│ ├── qdrant_test.go
│ ├── sqlite.go
│ ├── sqlite_test.go
│ ├── weaviate.go
│ └── weaviate_test.go
└── worker/
├── metrics.go
├── pipeline.go
├── pipeline_test.go
├── worker.go
└── worker_test.go
================================================
FILE CONTENTS
================================================
================================================
FILE: .devcontainer/Dockerfile
================================================
FROM mcr.microsoft.com/devcontainers/base:ubuntu-24.04
# use this Dockerfile to install additional tools you might need, e.g.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# && apt-get -y install --no-install-recommends <your-package-list-here>
================================================
FILE: .devcontainer/devcontainer.json
================================================
// The Dev Container format allows you to configure your environment. At the heart of it
// is a Docker image or Dockerfile which controls the tools available in your environment.
//
// See https://aka.ms/devcontainer.json for more information.
{
"name": "Gorse",
// Use "image": "mcr.microsoft.com/devcontainers/base:ubuntu-24.04",
// instead of the build to use a pre-built image.
"build": {
"context": ".",
"dockerfile": "Dockerfile"
},
// Features add additional features to your environment. See https://containers.dev/features
// Beware: features are not supported on all platforms and may have unintended side-effects.
"features": {
"ghcr.io/devcontainers/features/docker-in-docker": {
"moby": false
},
"ghcr.io/devcontainers/features/go": {},
"ghcr.io/devcontainers/features/python": {},
"ghcr.io/devcontainers-extra/features/protoc": {}
},
"postCreateCommand": [
"go install google.golang.org/protobuf/cmd/protoc-gen-go@latest",
"go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest"
]
}
================================================
FILE: .dockerignore
================================================
.github
assets
LICENSE
*.yml
*.md
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
Please answer these questions before submitting your issue. Thanks!
**Gorse version**
Print build info by the `--version` option.
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior.
**Expected behavior**
A clear and concise description of what you expected to happen.
**Additional context**
Add any other context about the problem here.
================================================
FILE: .github/ISSUE_TEMPLATE/custom.md
================================================
---
name: Custom issue template
about: Describe this issue template's purpose here.
title: ''
labels: ''
assignees: ''
---
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
================================================
FILE: .github/workflows/assign_issue.yml
================================================
name: 'assign issues'
on:
issue_comment:
types: [created, edited]
jobs:
assign_issues:
name: assign issues
if: ${{ !github.event.issue.pull_request && github.event.comment.body == '/assign' }}
runs-on: ubuntu-latest
steps:
- name: 'Assign issue'
uses: pozil/auto-assign-issue@v1.4.0
with:
assignees: ${{ github.event.comment.user.login }}
================================================
FILE: .github/workflows/backport.yml
================================================
name: backport merged pull request
on:
pull_request_target:
types: [closed]
issue_comment:
types: [created]
permissions:
contents: write # so it can comment
pull-requests: write # so it can create pull requests
jobs:
backport:
name: backport pull request
runs-on: ubuntu-latest
# Only run when pull request is merged
# or when a comment containing `/backport` is created by someone other than the
# https://github.com/backport-action bot user (user id: 97796249). Note that if you use your
# own PAT as `github_token`, that you should replace this id with yours.
if: >
(
github.event_name == 'pull_request' &&
github.event.pull_request.merged
) || (
github.event_name == 'issue_comment' &&
github.event.issue.pull_request &&
github.event.comment.user.id != 97796249 &&
contains(github.event.comment.body, '/backport')
)
steps:
- uses: actions/checkout@v3
- name: Create backport pull requests
uses: korthout/backport-action@v1
================================================
FILE: .github/workflows/build_docker.yml
================================================
name: build
on:
push:
branches:
- master
jobs:
windows_images:
name: docker images (windows)
runs-on: windows-latest
steps:
- name: Pull source
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build docker image
run: |
foreach ($image in "gorse-master", "gorse-server", "gorse-worker", "gorse-in-one") {
docker build -f cmd/$image/Dockerfile.windows `
-t zhenghaoz/${image}:nightly-windowsservercore .
docker image push --all-tags zhenghaoz/$image
}
docker_images:
name: docker images
runs-on: ubuntu-latest
strategy:
matrix:
targets: [default]
steps:
- name: Pull source
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
buildkitd-config-inline: |
[worker.oci]
max-parallelism = 1
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build docker image
uses: docker/bake-action@v6
with:
source: .
targets: ${{ matrix.targets }}
push: true
env:
AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
================================================
FILE: .github/workflows/build_release.yml
================================================
name: release
on:
release:
types: [published]
jobs:
binaries:
name: binaries
runs-on: macos-latest
steps:
- name: Pull source
uses: actions/checkout@v5
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: ./go.mod
- name: Install gox
run: go install github.com/mitchellh/gox@master
- name: Build release (windows and linux)
run: >
gox -output="{{.OS}}/{{.Arch}}/{{.Dir}}" \
-osarch='windows/arm64 windows/amd64 linux/arm64 linux/amd64 linux/riscv64' -ldflags="
-X 'github.com/gorse-io/gorse/cmd/version.Version=$(git describe --tags $(git rev-parse HEAD))'
-X 'github.com/gorse-io/gorse/cmd/version.GitCommit=$(git rev-parse HEAD)'
-X 'github.com/gorse-io/gorse/cmd/version.BuildTime=$(date)'" ./...
env:
CGO_ENABLED: 0
- name: Build release (darwin)
run: >
gox -output="{{.OS}}/{{.Arch}}/{{.Dir}}" \
-osarch='darwin/arm64' -ldflags="
-X 'github.com/gorse-io/gorse/cmd/version.Version=$(git describe --tags $(git rev-parse HEAD))'
-X 'github.com/gorse-io/gorse/cmd/version.GitCommit=$(git rev-parse HEAD)'
-X 'github.com/gorse-io/gorse/cmd/version.BuildTime=$(date)'" ./...
- name: Install zip
run: brew install zip
- name: Zip binaries
run: |
zip -j gorse_linux_amd64.zip linux/amd64/gorse-*
zip -j gorse_linux_arm64.zip linux/arm64/gorse-*
zip -j gorse_linux_riscv64.zip linux/riscv64/gorse-*
zip -j gorse_windows_amd64.zip windows/amd64/gorse-*
zip -j gorse_windows_arm64.zip windows/arm64/gorse-*
zip -j gorse_darwin_arm64.zip darwin/arm64/gorse-*
- name: Upload release
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: gorse_*_*.zip
tag: ${{ github.ref }}
overwrite: true
file_glob: true
docker_images:
name: docker images
runs-on: ubuntu-latest
steps:
- name: Pull source
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
buildkitd-config-inline: |
[worker.oci]
max-parallelism = 1
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- id: get_version
uses: battila7/get-version-action@v2
- if: github.event.release.prerelease == false
name: Build Docker image
uses: docker/bake-action@v6
with:
source: .
targets: default
push: true
env:
VERSIONS: latest,${{ steps.get_version.outputs.major }}.${{ steps.get_version.outputs.minor }},${{ steps.get_version.outputs.version-without-v }}
- if: github.event.release.prerelease == true
name: Build prerelease Docker image
uses: docker/bake-action@v6
with:
source: .
targets: default
push: true
env:
VERSIONS: ${{ steps.get_version.outputs.version-without-v }}
windows_images:
name: docker images (windows)
runs-on: windows-latest
steps:
- name: Pull source
uses: actions/checkout@v5
with:
fetch-depth: 0
- id: get_version
uses: battila7/get-version-action@v2
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build docker image
if: github.event.release.prerelease == false
run: |
foreach ($image in "gorse-master", "gorse-server", "gorse-worker", "gorse-in-one") {
docker build -f cmd/${image}/Dockerfile.windows `
-t zhenghaoz/${image}:windowsservercore `
-t zhenghaoz/${image}:${{ steps.get_version.outputs.major }}.${{ steps.get_version.outputs.minor }}-windowsservercore `
-t zhenghaoz/${image}:${{ steps.get_version.outputs.version-without-v }}-windowsservercore .
docker image push --all-tags zhenghaoz/$image
}
- name: Build prerelease docker image
if: github.event.release.prerelease == true
run: |
foreach ($image in "gorse-master", "gorse-server", "gorse-worker", "gorse-in-one") {
docker build -f cmd/${image}/Dockerfile.windows `
-t zhenghaoz/${image}:${{ steps.get_version.outputs.version-without-v }}-windowsservercore .
docker image push --all-tags zhenghaoz/$image
}
================================================
FILE: .github/workflows/build_test.yml
================================================
name: test
on:
push:
branches:
- master
- 'release-**'
pull_request:
branches:
- master
- 'release-**'
jobs:
unit_test:
strategy:
matrix:
os: [ubuntu-latest, ubuntu-24.04-arm]
name: unit tests
runs-on: ${{ matrix.os }}
services:
mysql:
image: mysql:8.0
ports:
- 3306
env:
MYSQL_ROOT_PASSWORD: password
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
postgres:
image: postgres:10.0
ports:
- 5432
env:
POSTGRES_USER: gorse
POSTGRES_PASSWORD: gorse_pass
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
mongo:
image: mongo:4.0
ports:
- 27017
env:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: password
options: >-
--health-cmd mongo
--health-interval 10s
--health-timeout 5s
--health-retries 5
clickhouse:
image: clickhouse/clickhouse-server:23
ports:
- 8123
options: >-
--health-cmd="clickhouse-client --query 'SELECT 1'"
--health-interval=10s
--health-timeout=5s
--health-retries=5
redis:
image: redis/redis-stack:6.2.6-v9
ports:
- 6379
rustfs:
image: rustfs/rustfs:alpha
ports:
- 9000
env:
RUSTFS_ACCESS_KEY: rustfsadmin
RUSTFS_SECRET_KEY: rustfsadmin
qdrant:
image: qdrant/qdrant:latest
ports:
- 6334
weaviate:
image: cr.weaviate.io/semitechnologies/weaviate:1.35.7
ports:
- 8080
steps:
- name: Set up dataset
run: |
mkdir -p ~/.gorse/dataset
mkdir -p ~/.gorse/download
wget https://cdn.gorse.io/datasets/ml-100k.zip -P ~/.gorse/download
wget https://cdn.gorse.io/datasets/ml-1m.zip -P ~/.gorse/download
wget https://cdn.gorse.io/datasets/pinterest-20.zip -P ~/.gorse/download
wget https://cdn.gorse.io/datasets/frappe.zip -P ~/.gorse/download
wget https://cdn.gorse.io/datasets/ml-tag.zip -P ~/.gorse/download
wget https://cdn.gorse.io/datasets/criteo.zip -P ~/.gorse/download
wget https://cdn.gorse.io/datasets/mnist.zip -P ~/.gorse/download
unzip ~/.gorse/download/ml-100k.zip -d ~/.gorse/dataset
unzip ~/.gorse/download/ml-1m.zip -d ~/.gorse/dataset
unzip ~/.gorse/download/pinterest-20.zip -d ~/.gorse/dataset
unzip ~/.gorse/download/frappe.zip -d ~/.gorse/dataset
unzip ~/.gorse/download/ml-tag.zip -d ~/.gorse/dataset
unzip ~/.gorse/download/criteo.zip -d ~/.gorse/dataset
unzip ~/.gorse/download/mnist.zip -d ~/.gorse/dataset
- uses: actions/checkout@v2
- uses: actions/setup-go@v5
with:
go-version-file: ./go.mod
- name: Install and start Azurite
uses: potatoqualitee/azuright@v1
- name: Setup Milvus
run: |
curl -sfL https://raw.githubusercontent.com/milvus-io/milvus/master/scripts/standalone_embed.sh -o standalone_embed.sh
bash standalone_embed.sh start
working-directory: ${{ runner.temp }}
- name: Test
run: go test -timeout 30m -v ./... -coverprofile=coverage.txt -covermode=atomic -coverpkg=./...
env:
# MySQL
MYSQL_URI: mysql://root:password@tcp(localhost:${{ job.services.mysql.ports[3306] }})/
# Postgres
POSTGRES_URI: postgres://gorse:gorse_pass@localhost:${{ job.services.postgres.ports[5432] }}/
# MongoDB
MONGO_URI: mongodb://root:password@localhost:${{ job.services.mongo.ports[27017] }}/
# ClickHouse
CLICKHOUSE_URI: clickhouse://localhost:${{ job.services.clickhouse.ports[8123] }}/
# Redis
REDIS_URI: redis://localhost:${{ job.services.redis.ports[6379] }}/
# S3
S3_ENDPOINT: localhost:${{ job.services.rustfs.ports[9000] }}
S3_ACCESS_KEY_ID: rustfsadmin
S3_SECRET_ACCESS_KEY: rustfsadmin
# Azure Blob (Azurite)
AZURE_STORAGE_CONNECTION_STRING: DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;
# Qdrant
QDRANT_URI: qdrant://localhost:${{ job.services.qdrant.ports[6334] }}/
# Weaviate
WEAVIATE_URI: weaviate://localhost:${{ job.services.weaviate.ports[8080] }}/
- name: Upload coverage to Codecov
if: matrix.os == 'ubuntu-latest'
uses: codecov/codecov-action@v5
with:
files: ./coverage.txt
fail_ci_if_error: false
token: ${{ secrets.CODECOV_TOKEN }}
unit_test_macos:
name: unit tests (macos-latest)
runs-on: macos-latest
steps:
- name: Set up dataset
run: |
mkdir -p ~/.gorse/dataset
mkdir -p ~/.gorse/download
wget https://cdn.gorse.io/datasets/ml-100k.zip -P ~/.gorse/download
wget https://cdn.gorse.io/datasets/ml-1m.zip -P ~/.gorse/download
wget https://cdn.gorse.io/datasets/pinterest-20.zip -P ~/.gorse/download
wget https://cdn.gorse.io/datasets/frappe.zip -P ~/.gorse/download
wget https://cdn.gorse.io/datasets/ml-tag.zip -P ~/.gorse/download
wget https://cdn.gorse.io/datasets/criteo.zip -P ~/.gorse/download
wget https://cdn.gorse.io/datasets/mnist.zip -P ~/.gorse/download
unzip ~/.gorse/download/ml-100k.zip -d ~/.gorse/dataset
unzip ~/.gorse/download/ml-1m.zip -d ~/.gorse/dataset
unzip ~/.gorse/download/pinterest-20.zip -d ~/.gorse/dataset
unzip ~/.gorse/download/frappe.zip -d ~/.gorse/dataset
unzip ~/.gorse/download/ml-tag.zip -d ~/.gorse/dataset
unzip ~/.gorse/download/criteo.zip -d ~/.gorse/dataset
unzip ~/.gorse/download/mnist.zip -d ~/.gorse/dataset
- uses: actions/checkout@v2
- uses: actions/setup-go@v5
with:
go-version-file: ./go.mod
- name: Test
run: go test -timeout 20m -v ./... -skip "TestPostgres|TestMySQL|TestMongo|TestRedis|TestClickHouse|TestMilvus|TestQdrant|TestWeaviate"
unit_test_windows:
strategy:
matrix:
os: [windows-latest, windows-11-arm]
name: unit tests
runs-on: ${{ matrix.os }}
steps:
- name: Set up dataset
run: |
New-Item -Type Directory -Path ~/.gorse/dataset
New-Item -Type Directory -Path ~/.gorse/download
Invoke-WebRequest https://cdn.gorse.io/datasets/ml-100k.zip -OutFile ~/.gorse/download/ml-100k.zip
Invoke-WebRequest https://cdn.gorse.io/datasets/ml-1m.zip -OutFile ~/.gorse/download/ml-1m.zip
Invoke-WebRequest https://cdn.gorse.io/datasets/pinterest-20.zip -OutFile ~/.gorse/download/pinterest-20.zip
Invoke-WebRequest https://cdn.gorse.io/datasets/frappe.zip -OutFile ~/.gorse/download/frappe.zip
Invoke-WebRequest https://cdn.gorse.io/datasets/ml-tag.zip -OutFile ~/.gorse/download/ml-tag.zip
Invoke-WebRequest https://cdn.gorse.io/datasets/criteo.zip -OutFile ~/.gorse/download/criteo.zip
Invoke-WebRequest https://cdn.gorse.io/datasets/mnist.zip -OutFile ~/.gorse/download/mnist.zip
Expand-Archive ~/.gorse/download/ml-100k.zip -DestinationPath ~/.gorse/dataset
Expand-Archive ~/.gorse/download/ml-1m.zip -DestinationPath ~/.gorse/dataset
Expand-Archive ~/.gorse/download/pinterest-20.zip -DestinationPath ~/.gorse/dataset
Expand-Archive ~/.gorse/download/frappe.zip -DestinationPath ~/.gorse/dataset
Expand-Archive ~/.gorse/download/ml-tag.zip -DestinationPath ~/.gorse/dataset
Expand-Archive ~/.gorse/download/criteo.zip -DestinationPath ~/.gorse/dataset
Expand-Archive ~/.gorse/download/mnist.zip -DestinationPath ~/.gorse/dataset
- uses: actions/checkout@v2
- uses: actions/setup-go@v5
with:
go-version-file: ./go.mod
- name: Test
run: go test -timeout 20m -v ./... -skip "TestPostgres|TestMySQL|TestMongo|TestRedis|TestClickHouse|TestMilvus|TestQdrant|TestWeaviate"
integrate_test:
name: integrate tests
runs-on: ubuntu-latest
strategy:
matrix:
database: [mysql, postgres, mongo, sqlite]
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- uses: actions/setup-go@v5
with:
go-version-file: ./go.mod
- uses: cuchi/jinja2-action@v1.2.0
with:
template: client/docker-compose.yml.j2
output_file: docker-compose.yml
strict: true
variables: |
database=${{ matrix.database }}
- name: Setup test
run: ./client/setup-test.sh
env:
DOCKER_BUILDKIT: 1
- name: Test
run: go test ./client/
env:
GORSE_SERVER_ENDPOINT: http://localhost:8087
GORSE_DASHBOARD_ENDPOINT: http://localhost:8088
compat_test:
name: compatibility tests
runs-on: ubuntu-latest
services:
mariadb:
image: mariadb:10.2
ports:
- 3306
env:
MYSQL_ROOT_PASSWORD: password
kvrocks:
image: apache/kvrocks:nightly
ports:
- 6666
steps:
- name: Install pre-requisites
uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: redis-tools
- uses: actions/checkout@v5
with:
repository: gorse-cloud/redis-stack
path: redis-stack
- name: Setup Redis cluster
run: |
docker compose -f redis-stack/docker-compose.yml --project-directory redis-stack up -d
for i in {1..5}; do
redis-cli -p 7005 ping | grep PONG && break
sleep 10
done
- uses: actions/checkout@v2
- uses: actions/setup-go@v5
with:
go-version-file: ./go.mod
- name: Test MariaDB
run: go test ./storage/data -run TestMySQL
env:
MYSQL_URI: mysql://root:password@tcp(localhost:${{ job.services.mariadb.ports[3306] }})/
- name: Test Kvrocks
run: go test ./storage/cache -run ^TestRedis
env:
REDIS_URI: redis://localhost:${{ job.services.kvrocks.ports[6666] }}/
- name: Test Redis cluster (1 address)
run: go test ./storage/cache -run ^TestRedis
env:
REDIS_URI: redis+cluster://localhost:7000
- name: Test Redis cluster (6 addresses)
run: go test ./storage/cache -run ^TestRedis
env:
REDIS_URI: redis+cluster://localhost:7000?addr=localhost:7001&addr=localhost:7002&addr=localhost:7003&addr=localhost:7004&addr=localhost:7005
playground:
name: playground
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build Docker image
run: docker build -t zhenghaoz/gorse-in-one -f ./cmd/gorse-in-one/Dockerfile .
- name: Run playground
run: docker run -d -p 8088:8088 --name playground zhenghaoz/gorse-in-one --playground
- name: Check dashboard URL
run: |
for i in {1..10}; do
curl -sSf http://localhost:8088 && break
docker logs playground
sleep 10
done
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-go@v5
with:
go-version-file: ./go.mod
- name: golangci-lint
uses: golangci/golangci-lint-action@v9
with:
args: --timeout 20m
================================================
FILE: .github/workflows/dockerhub-description.yml
================================================
name: update
on:
push:
branches:
- master
paths:
- 'README.md'
jobs:
dockerhub_description:
name: dockerHub description
runs-on: ubuntu-latest
strategy:
matrix:
image: [gorse-master, gorse-server, gorse-worker, gorse-in-one]
steps:
- uses: actions/checkout@v5
- name: Resolve Images on Description
run: |
sed -i -E "s/src=\"assets\//src=\"https:\/\/github.com\/gorse-io\/gorse\/raw\/master\/assets\//" README.md
- name: Update DockerHub Description
uses: peter-evans/dockerhub-description@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
repository: zhenghaoz/${{ matrix.image }}
================================================
FILE: .github/workflows/translate_issues.yml
================================================
name: 'translate issues'
on:
issue_comment:
types: [created]
issues:
types: [opened]
jobs:
translate-isssues:
name: translate issues
runs-on: ubuntu-latest
steps:
- name: Issues Translator
uses: tomsun28/issues-translate-action@v2.5
================================================
FILE: .gitignore
================================================
# Created by https://www.gitignore.io/api/go,windows,jetbrains
### Go ###
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, build with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
### Go Patch ###
/vendor/
/Godeps/
### JetBrains ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
### JetBrains Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
# *.iml
# modules.xml
# .idea/misc.xml
# *.ipr
# Sonarlint plugin
.idea/sonarlint
### Windows ###
# Windows thumbnail cache files
Thumbs.db
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
.vscode
# End of https://www.gitignore.io/api/go,windows,jetbrains
================================================
FILE: .golangci.yml
================================================
version: "2"
linters:
settings:
govet:
disable:
- composites
staticcheck:
checks:
- all
- -QF1004
- -QF1008
- -SA1019
- -ST1003
exclusions:
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
coc@gorse.io.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
================================================
FILE: CONTRIBUTING.md
================================================
# Contribution Guide
Welcome and thank you for considering contributing to Gorse!
Reading and following these guidelines will help us make the contribution process easy and effective for everyone involved. It also communicates that you agree to respect the time of the developers managing and developing these open source projects. In return, we will reciprocate that respect by addressing your issue, assessing changes, and helping you finalize your pull requests.
* [Getting Started](#getting-started)
* [Setup Develop Environment](#setup-develop-environment)
* [Option 1: Run an All-in-one Node](#option-1-run-an-all-in-one-node)
* [Option 2: Run Nodes](#option-2-run-nodes)
* [Run Unit Tests](#run-unit-tests)
* [Your First Contribution](#your-first-contribution)
* [Contribution Workflow](#contribution-workflow)
* [Getting Help](#getting-help)
## Getting Started
### Setup Develop Environment
These following installations are required:
- **Go** (>= 1.18): Since Go features from 1.18 are used in Gorse, the version of the compiler must be greater than 1.18. GoLand or Visual Studio Code is highly recommended as the IDE to develop Gorse.
- **Docker Compose**: Multiple databases are required for unit tests. It's convenient to manage databases on Docker Compose.
```bash
cd storage
docker compose up -d
```
If you need import sample data, download the SQL file github.sql and import to the MySQL instance.
```bash
# Download sample data.
wget https://cdn.gorse.io/example/github.sql
# Import sample data.
mysql -h 127.0.0.1 -u gorse -pgorse_pass gorse < github.sql
```
### Option 1: Run an All-in-one Node
```bash
go run cmd/gorse-in-one/main.go --config config/config.toml
```
### Option 2: Run Nodes
- Start the master node with the configuration file.
```bash
go run cmd/gorse-master/main.go --config config/config.toml
```
- Start the worker node.
```bash
go run cmd/gorse-worker/main.go
```
- Start the server node.
```bash
go run cmd/gorse-server/main.go
```
### Run Unit Tests
Most logics in Gorse are covered by unit tests. Run unit tests by the following command:
```bash
go test -v ./...
```
The default database URLs are directed to these databases in `storage/docker-compose.yml`. Test databases could be overrode by setting following environment variables:
| Environment Value | Default Value |
|-------------------|----------------------------------------------|
| `MYSQL_URI` | `mysql://root:password@tcp(127.0.0.1:3306)/` |
| `POSTGRES_URI` | `postgres://gorse:gorse_pass@127.0.0.1/` |
| `MONGO_URI` | `mongodb://root:password@127.0.0.1:27017/` |
| `CLICKHOUSE_URI` | `clickhouse://127.0.0.1:8123/` |
| `REDIS_URI` | `redis://127.0.0.1:6379/` |
For example, use TiDB as a test database by:
```bash
MYSQL_URI=mysql://root:password@tcp(127.0.0.1:4000)/ go test -v ./...
```
## Your First Contribution
You can start by finding an existing issue with the [help wanted](https://github.com/gorse-io/gorse/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) label in the Gorse repository. These issues are well suited for new contributors. Issues can be claimed by publishing an `/assign` comment.
### Contribution Workflow
To contribute to the Gorse code base, please follow the workflow as defined in this section.
- Fork the repository to your own Github account
- Make commits and add test case if the change fixes a bug or adds new functionality.
- Run tests and make sure all the tests are passed.
- Push your changes to a topic branch in your fork of the repository.
- Submit a pull request.
This is a rough outline of what a contributor's workflow looks like. Thanks for your contributions!
## Getting Help
Join us in the [Discord](https://discord.gg/x6gAtNNkAE) and post your question in the `#developers` channel.
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
# Gorse Open-source Recommender System Engine
<img width=160 src="assets/gorse.png"/>

[](https://github.com/gorse-io/gorse/actions/workflows/build_test.yml)
[](https://codecov.io/gh/gorse-io/gorse)
[](https://discord.gg/x6gAtNNkAE)
[](https://twitter.com/gorse_io)
[](https://gurubase.io/g/gorse)
Gorse is an AI powered open-source recommender system written in Go. Gorse aims to be a universal open-source recommender system that can be quickly integrated into a wide variety of online services. By importing items, users, and interaction data into Gorse, the system will automatically train models to generate recommendations for each user. Project features are as follows.

- **Multi-source:** Recommend items from latest, user-to-user, item-to-item, collaborative filtering and etc.
- **Multimodal:** Support multimodal content (text, image, videos, etc.) via embedding.
- **AI-powered:** Support both classical recommenders and LLM-based recommenders.
- **GUI Dashboard:** Provide GUI dashboard for recommendation pipeline editing, system monitoring, and data management.
- **RESTful APIs:** Expose RESTful APIs for data CRUD and recommendation requests.
## Quick Start
The playground mode has been prepared for beginners. Just set up a recommender system for GitHub repositories by the following commands.
```bash
docker run -p 8088:8088 zhenghaoz/gorse-in-one --playground
```
The playground mode will download data from [GitRec](https://gitrec.gorse.io/) and import it into Gorse. The dashboard is available at `http://localhost:8088`.

After the "Generate item-to-item recommendation" task is completed on the "Tasks" page, try to insert several feedbacks into Gorse. Suppose Bob is a developer who interested in LLM related repositories. We insert his star feedback to Gorse.
```bash
read -d '' JSON << EOF
[
{ \"FeedbackType\": \"star\", \"UserId\": \"bob\", \"ItemId\": \"ollama:ollama\", \"Value\": 1.0, \"Timestamp\": \"2022-02-24\" },
{ \"FeedbackType\": \"star\", \"UserId\": \"bob\", \"ItemId\": \"huggingface:transformers\", \"Value\": 1.0, \"Timestamp\": \"2022-02-25\" },
{ \"FeedbackType\": \"star\", \"UserId\": \"bob\", \"ItemId\": \"rasbt:llms-from-scratch\", \"Value\": 1.0, \"Timestamp\": \"2022-02-26\" },
{ \"FeedbackType\": \"star\", \"UserId\": \"bob\", \"ItemId\": \"vllm-project:vllm\", \"Value\": 1.0, \"Timestamp\": \"2022-02-27\" },
{ \"FeedbackType\": \"star\", \"UserId\": \"bob\", \"ItemId\": \"hiyouga:llama-factory\", \"Value\": 1.0, \"Timestamp\": \"2022-02-28\" }
]
EOF
curl -X POST http://127.0.0.1:8088/api/feedback \
-H 'Content-Type: application/json' \
-d "$JSON"
```
Then, fetch 10 recommended items from Gorse. We can find that LLM-related repositories are recommended for Bob.
```bash
curl http://127.0.0.1:8088/api/recommend/bob?n=10
```
For more information:
- Read [official documents](https://gorse.io/docs/)
- Visit [playground](https://play.gorse.io/) of Gorse dashboard
- Explore [live demo](https://gitrec.gorse.io/), a recommender system for GitHub repositories
- Discuss on [Discord](https://discord.gg/x6gAtNNkAE) or [GitHub Discussion](https://github.com/gorse-io/gorse/discussions)
## Architecture
Gorse is a single-node training and distributed prediction recommender system. Gorse stores data in MySQL, MongoDB, Postgres, or ClickHouse, with intermediate results cached in Redis, MySQL, MongoDB and Postgres.
1. The cluster consists of a master node, multiple worker nodes, and server nodes.
1. The master node is responsible for model training, non-personalized recommendation, configuration management, and membership management.
1. The server node is responsible for exposing the RESTful APIs and online real-time recommendations.
1. Worker nodes are responsible for offline recommendations for each user.
In addition, the administrator can perform system monitoring, data import and export, and system status checking via the dashboard on the master node.
<img width=520 src="https://github.com/gorse-io/docs/blob/main/src/img/cluster.drawio.svg?raw=true"/>
## Contributors
<a href="https://github.com/gorse-io/gorse/graphs/contributors">
<img src="https://contrib.rocks/image?repo=zhenghaoz/gorse" />
</a>
Any contribution is appreciated: report a bug, give advice or create a pull request. Read [CONTRIBUTING.md](CONTRIBUTING.md) for more information.
## Acknowledgments
`gorse` is inspired by the following projects:
- [Guibing Guo's librec](https://github.com/guoguibing/librec)
- [Nicolas Hug's Surprise](https://github.com/NicolasHug/Surprise)
- [Golang Samples's gopher-vector](https://github.com/golang-samples/gopher-vector)
================================================
FILE: client/README.md
================================================
Go SDK has been moved to https://github.com/gorse-io/gorse-go
================================================
FILE: client/client_test.go
================================================
// Copyright 2022 gorse Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package client
import (
"os"
"testing"
"time"
client "github.com/gorse-io/gorse-go"
"github.com/stretchr/testify/suite"
)
var (
serverEndpoint string
dashboardEndpoint string
)
func init() {
serverEndpoint = os.Getenv("GORSE_SERVER_ENDPOINT")
dashboardEndpoint = os.Getenv("GORSE_DASHBOARD_ENDPOINT")
}
type GorseClientTestSuite struct {
suite.Suite
client *client.GorseClient
}
func (suite *GorseClientTestSuite) SetupSuite() {
if serverEndpoint == "" || dashboardEndpoint == "" {
suite.T().Skip("GORSE_SERVER_ENDPOINT or GORSE_DASHBOARD_ENDPOINT is not set")
}
suite.client = client.NewGorseClient(serverEndpoint, "")
}
func (suite *GorseClientTestSuite) TestUsers() {
ctx := suite.T().Context()
cursor, err := suite.client.GetUsers(ctx, 3, "")
suite.NoError(err)
suite.NotEmpty(cursor.Cursor)
if suite.Len(cursor.Users, 3) {
suite.Equal(client.User{
UserId: "1",
Labels: map[string]any{
"age": float64(24),
"gender": "M",
"occupation": "technician",
"zip_code": "85711",
},
}, cursor.Users[0])
suite.Equal(client.User{
UserId: "10",
Labels: map[string]any{
"age": float64(53),
"gender": "M",
"occupation": "lawyer",
"zip_code": "90703",
},
}, cursor.Users[1])
suite.Equal(client.User{
UserId: "100",
Labels: map[string]any{
"age": float64(36),
"gender": "M",
"occupation": "executive",
"zip_code": "90254",
},
}, cursor.Users[2])
}
user := client.User{
UserId: "1000",
Labels: map[string]any{"gender": "M", "occupation": "engineer"},
Comment: "zhenghaoz",
}
rowAffected, err := suite.client.InsertUser(ctx, user)
suite.NoError(err)
suite.Equal(1, rowAffected.RowAffected)
resp, err := suite.client.GetUser(ctx, "1000")
suite.NoError(err)
suite.Equal(user, resp)
patch := client.UserPatch{
Comment: new("hongmi"),
}
rowAffected, err = suite.client.UpdateUser(ctx, user.UserId, patch)
suite.NoError(err)
suite.Equal(1, rowAffected.RowAffected)
resp, err = suite.client.GetUser(ctx, "1000")
suite.NoError(err)
suite.Equal("hongmi", resp.Comment)
deleteAffect, err := suite.client.DeleteUser(ctx, "1000")
suite.NoError(err)
suite.Equal(1, deleteAffect.RowAffected)
_, err = suite.client.GetUser(ctx, "1000")
suite.Equal("1000: user not found", err.Error())
}
func (suite *GorseClientTestSuite) TestItems() {
ctx := suite.T().Context()
items, err := suite.client.GetItems(ctx, 3, "")
suite.NoError(err)
suite.NotEmpty(items.Cursor)
if suite.Len(items.Items, 3) {
suite.Equal("1", items.Items[0].ItemId)
suite.Equal([]string{"Animation", "Children's", "Comedy"}, items.Items[0].Categories)
suite.Equal(time.Date(1995, 1, 1, 0, 0, 0, 0, time.UTC), items.Items[0].Timestamp)
suite.Equal("Toy Story (1995)", items.Items[0].Comment)
suite.Equal("10", items.Items[1].ItemId)
suite.Equal([]string{"Drama", "War"}, items.Items[1].Categories)
suite.Equal(time.Date(1996, 1, 22, 0, 0, 0, 0, time.UTC), items.Items[1].Timestamp)
suite.Equal("Richard III (1995)", items.Items[1].Comment)
suite.Equal("100", items.Items[2].ItemId)
suite.Equal([]string{"Crime", "Drama", "Thriller"}, items.Items[2].Categories)
suite.Equal(time.Date(1997, 2, 14, 0, 0, 0, 0, time.UTC), items.Items[2].Timestamp)
suite.Equal("Fargo (1996)", items.Items[2].Comment)
}
item := client.Item{
ItemId: "2000",
IsHidden: true,
Labels: map[string]any{
"embedding": []any{0.1, 0.2, 0.3},
},
Categories: []string{"Comedy", "Animation"},
Timestamp: time.Now().UTC().Truncate(time.Second),
Comment: "Minions (2015)",
}
rowAffected, err := suite.client.InsertItem(ctx, item)
suite.NoError(err)
suite.Equal(1, rowAffected.RowAffected)
resp, err := suite.client.GetItem(ctx, "2000")
suite.NoError(err)
suite.Equal(item, resp)
patch := client.ItemPatch{
Comment: new("小黄人 (2015)"),
}
rowAffected, err = suite.client.UpdateItem(ctx, item.ItemId, patch)
suite.NoError(err)
suite.Equal(1, rowAffected.RowAffected)
resp, err = suite.client.GetItem(ctx, "2000")
suite.NoError(err)
suite.Equal("小黄人 (2015)", resp.Comment)
deleteAffect, err := suite.client.DeleteItem(ctx, "2000")
suite.NoError(err)
suite.Equal(1, deleteAffect.RowAffected)
_, err = suite.client.GetItem(ctx, "2000")
suite.Equal("2000: item not found", err.Error())
}
func (suite *GorseClientTestSuite) TestFeedback() {
ctx := suite.T().Context()
_, err := suite.client.InsertUser(ctx, client.User{UserId: "2000"})
suite.NoError(err)
feedback := []client.Feedback{
{
FeedbackType: "watch",
UserId: "2000",
ItemId: "1",
Value: 1.0,
Timestamp: time.Now().UTC().Truncate(time.Second),
},
{
FeedbackType: "watch",
UserId: "2000",
ItemId: "1060",
Value: 2.0,
Timestamp: time.Now().UTC().Truncate(time.Second),
},
{
FeedbackType: "watch",
UserId: "2000",
ItemId: "11",
Value: 3.0,
Timestamp: time.Now().UTC().Truncate(time.Second),
},
}
for _, fb := range feedback {
_, err := suite.client.DeleteFeedbacks(ctx, fb.UserId, fb.ItemId)
suite.NoError(err)
}
_, err = suite.client.InsertFeedback(ctx, feedback)
suite.NoError(err)
userFeedback, err := suite.client.ListFeedbacks(ctx, "watch", "2000")
suite.NoError(err)
suite.Equal(feedback, userFeedback)
_, err = suite.client.DeleteFeedback(ctx, "watch", "2000", "1")
suite.NoError(err)
userFeedback, err = suite.client.ListFeedbacks(ctx, "watch", "2000")
suite.NoError(err)
suite.Equal([]client.Feedback{feedback[1], feedback[2]}, userFeedback)
}
func (suite *GorseClientTestSuite) TestLatest() {
ctx := suite.T().Context()
items, err := suite.client.GetLatestItems(ctx, "", "", 3, 0)
suite.NoError(err)
if suite.Len(items, 3) {
suite.Equal("315", items[0].Id)
suite.Equal("1432", items[1].Id)
suite.Equal("918", items[2].Id)
}
}
func (suite *GorseClientTestSuite) TestItemToItem() {
ctx := suite.T().Context()
neighbors, err := suite.client.GetNeighbors(ctx, "1", 3)
suite.NoError(err)
if suite.Len(neighbors, 3) {
suite.Equal("1060", neighbors[0].Id)
suite.Equal("404", neighbors[1].Id)
suite.Equal("1219", neighbors[2].Id)
}
}
func (suite *GorseClientTestSuite) TestRecommend() {
ctx := suite.T().Context()
_, err := suite.client.InsertUser(ctx, client.User{UserId: "3000"})
suite.NoError(err)
recommendations, err := suite.client.GetRecommend(ctx, "3000", "", 3, 0)
suite.NoError(err)
suite.Len(recommendations, 3)
if suite.Len(recommendations, 3) {
suite.Equal("315", recommendations[0])
suite.Equal("1432", recommendations[1])
suite.Equal("918", recommendations[2])
}
}
func TestGorseClientTestSuite(t *testing.T) {
suite.Run(t, new(GorseClientTestSuite))
}
================================================
FILE: client/config.go
================================================
// Copyright 2025 gorse Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package client
import _ "embed"
//go:embed config.toml
var ConfigTOML string
================================================
FILE: client/config.toml
================================================
[master]
# GRPC port of the master node. The default value is 8086.
port = 8086
# gRPC host of the master node. The default values is "0.0.0.0".
host = "0.0.0.0"
# Enable SSL for the gRPC communication. The default value is false.
ssl_mode = false
# SSL certification authority for the gRPC communication.
ssl_ca = ""
# SSL certification for the gRPC communication.
ssl_cert = ""
# SSL certification key for the gRPC communication.
ssl_key = ""
# HTTP port of the master node. The default values is 8088.
http_port = 8088
# HTTP host of the master node. The default values is "0.0.0.0".
http_host = "0.0.0.0"
# AllowedDomains is a list of allowed values for Http Origin.
# The list may contain the special wildcard string ".*" ; all is allowed
# If empty all are allowed.
http_cors_domains = []
# AllowedMethods is either empty or has a list of http methods names. Checking is case-insensitive.
http_cors_methods = []
# Number of working jobs in the master node. The default value is 1.
n_jobs = 1
# Meta information timeout. The default value is 10s.
meta_timeout = "10s"
# Username for the master node dashboard.
dashboard_user_name = ""
# Password for the master node dashboard.
dashboard_password = ""
# Secret key for admin APIs (SSL required).
admin_api_key = ""
[server]
# Default number of returned items. The default value is 10.
default_n = 10
# Secret key for RESTful APIs (SSL required).
api_key = ""
# Clock error in the cluster. The default value is 5s.
clock_error = "5s"
# Insert new users while inserting feedback. The default value is true.
auto_insert_user = true
# Insert new items while inserting feedback. The default value is true.
auto_insert_item = true
# Server-side cache expire time. The default value is 10s.
cache_expire = "10s"
[recommend]
# The cache size for recommended/popular/latest items. The default value is 10.
cache_size = 100
# Recommended cache expire time. The default value is 72h.
cache_expire = "72h"
# The context size for online recommendations. Online recommendations can't use all user feedbacks to generate
# recommendations for efficiency consideration. Instead, only the latest `context_size` feedbacks are used.
# The default value is 100.
context_size = 100
# The time-to-live (days) of active users, 0 means disabled. Recommendation won't be cached for inactive users. The default value is 0.
active_user_ttl = 0
[recommend.data_source]
# The feedback types for positive events.
positive_feedback_types = ["rating>=4"]
# The feedback types for read events.
read_feedback_types = ["rating"]
# The time-to-live (days) of positive feedback, 0 means disabled. The default value is 0.
positive_feedback_ttl = 0
# The time-to-live (days) of items, 0 means disabled. The default value is 0.
item_ttl = 0
[[recommend.non-personalized]]
# The name of the leaderboard.
name = "popular"
# The score function for items in the leaderboard.
score = "len(feedback)"
[[recommend.item-to-item]]
# The name of the item-to-item recommender.
name = "neighbors"
# The type of the item-to-item recommender. There are three types:
# embedding: recommend by Euclidean distance of embeddings.
# tags: recommend by number of common tags.
# users: recommend by number of common users.
# chat: recommend by chat completion model.
type = "embedding"
# The column of the item embeddings. Leave blank if type is "users".
column = "item.Labels.embedding"
[[recommend.user-to-user]]
# The name of the user-to-user recommender.
name = "neighbors"
# The type of the user-to-user recommender. There are three types:
# embedding: recommend by Euclidean distance of embeddings.
# tags: recommend by number of common tags.
# items: recommend by number of common items.
type = "items"
[recommend.collaborative]
# The type of collaborative filtering. Supported values:
# none: disable collaborative filtering.
# mf: matrix factorization.
type = "mf"
# The time period for model fitting. The default value is "60m".
fit_period = "60m"
# The number of epochs for model fitting. The default value is 100.
fit_epoch = 100
[recommend.collaborative.early_stopping]
# Number of epochs to wait if no improvement and then stop the training. The default value is 10.
patience = 10
[recommend.ranker]
# The type of the ranker. There are two types:
# none: no ranking.
# fm: factorization machines.
type = "none"
# The recommenders used to fetch candidate items before ranking. The default values is all recommenders.
recommenders = ["latest"]
================================================
FILE: client/docker-compose.yml.j2
================================================
version: "3"
services:
{% if database == 'mysql' %}
mysql:
image: mysql/mysql-server
restart: unless-stopped
ports:
- 3306:3306
environment:
MYSQL_ROOT_PASSWORD: root_pass
MYSQL_DATABASE: gorse
MYSQL_USER: gorse
MYSQL_PASSWORD: gorse_pass
healthcheck:
test: mysqladmin ping
interval: 10s
timeout: 5s
retries: 5
{% elif database == 'postgres' %}
postgres:
image: postgres:10.0
ports:
- 5432:5432
environment:
POSTGRES_DB: gorse
POSTGRES_USER: gorse
POSTGRES_PASSWORD: gorse_pass
healthcheck:
test: pg_isready
interval: 10s
timeout: 5s
retries: 5
{% elif database == 'mongo' %}
mongo:
image: mongo:4.0
ports:
- 27017:27017
environment:
MONGO_INITDB_DATABASE: gorse
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: password
healthcheck:
test: mongo
interval: 10s
timeout: 5s
retries: 5
{% elif database == 'clickhouse+redis' %}
clickhouse:
image: clickhouse/clickhouse-server:23
ports:
- 8123:8123
environment:
CLICKHOUSE_DB: gorse
CLICKHOUSE_USER: gorse
CLICKHOUSE_PASSWORD: gorse_pass
healthcheck:
test: clickhouse-client --user $$CLICKHOUSE_USER --password $$CLICKHOUSE_PASSWORD --query "SELECT 1"
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis/redis-stack:6.2.6-v9
restart: unless-stopped
ports:
- 6379:6379
healthcheck:
test: redis-cli ping
interval: 10s
timeout: 5s
retries: 5
{% endif %}
worker:
build:
context: .
dockerfile: cmd/gorse-worker/Dockerfile
cache_from:
- type=gha
cache_to:
- type=gha,mode=max
restart: unless-stopped
ports:
- 8089:8089
command: >
--master-host master --master-port 8086
--http-host 0.0.0.0 --http-port 8089
--log-path /var/log/gorse/worker.log
--cache-path /var/lib/gorse/worker_cache.data
depends_on:
- master
server:
build:
context: .
dockerfile: cmd/gorse-server/Dockerfile
cache_from:
- type=gha
cache_to:
- type=gha,mode=max
restart: unless-stopped
ports:
- 8087:8087
command: >
--master-host master --master-port 8086
--http-host 0.0.0.0 --http-port 8087
--log-path /var/log/gorse/server.log
--cache-path /var/lib/gorse/server_cache.data
depends_on:
- master
master:
build:
context: .
dockerfile: cmd/gorse-master/Dockerfile
cache_from:
- type=gha
cache_to:
- type=gha,mode=max
restart: unless-stopped
ports:
- 8086:8086
- 8088:8088
environment:
{% if database == 'mysql' %}
GORSE_DATA_STORE: mysql://gorse:gorse_pass@tcp(mysql:3306)/gorse
GORSE_CACHE_STORE: mysql://gorse:gorse_pass@tcp(mysql:3306)/gorse
{% elif database == 'postgres' %}
GORSE_DATA_STORE: postgres://gorse:gorse_pass@postgres/gorse?sslmode=disable
GORSE_CACHE_STORE: postgres://gorse:gorse_pass@postgres/gorse?sslmode=disable
{% elif database == 'mongo' %}
GORSE_DATA_STORE: mongodb://root:password@mongo:27017/gorse?authSource=admin&connect=direct
GORSE_CACHE_STORE: mongodb://root:password@mongo:27017/gorse?authSource=admin&connect=direct
{% elif database == 'clickhouse+redis' %}
GORSE_DATA_STORE: clickhouse://gorse:gorse_pass@clickhouse:8123/gorse?mutations_sync=2
GORSE_CACHE_STORE: redis://redis:6379
{% elif database == 'sqlite' %}
GORSE_DATA_STORE: sqlite:///var/lib/gorse/data.sqlite3
GORSE_CACHE_STORE: sqlite:///var/lib/gorse/cache.sqlite3
{% endif %}
command: >
-c /etc/gorse/config.toml
--log-path /var/log/gorse/master.log
--cache-path /var/lib/gorse
volumes:
- ./client/config.toml:/etc/gorse/config.toml
{% if database != 'sqlite' %}
depends_on:
{% if database == 'mysql' %}
mysql:
condition: service_healthy
{% elif database == 'postgres' %}
postgres:
condition: service_healthy
{% elif database == 'mongo' %}
mongo:
condition: service_healthy
{% elif database == 'clickhouse+redis' %}
clickhouse:
condition: service_healthy
redis:
condition: service_healthy
{% endif %}
{% endif %}
================================================
FILE: client/setup-test.sh
================================================
#!/bin/bash
set -e
# Download config
if [ ! -f ./config.toml ]; then
wget https://github.com/gorse-io/gorse/raw/refs/heads/master/client/config.toml
fi
# Create docker-compose.yml
if [ ! -f ./docker-compose.yml ]; then
cat > docker-compose.yml <<EOF
version: '3'
services:
master:
image: zhenghaoz/gorse-in-one:latest
ports:
- 8088:8088
volumes:
- ./config.toml:/etc/gorse/config.toml
environment:
- GORSE_DATA_STORE=sqlite:///var/lib/gorse/data.sqlite3
- GORSE_CACHE_STORE=sqlite:///var/lib/gorse/cache.sqlite3
command: ["-c", "/etc/gorse/config.toml", "--cache-path", "/var/lib/gorse"]
EOF
fi
# Start Gorse
docker compose up -d
# Download MovieLens 100k dataset
if [ ! -f ./ml-100k.bin ]; then
wget https://cdn.gorse.io/example/ml-100k.bin.gz
gzip -d ml-100k.bin.gz
fi
# Wait for Gorse to be ready
max_attempts=6
attempt=0
until curl -s -o /dev/null -w "%{http_code}" "http://127.0.0.1:8088/api/health/ready" | grep -q "200" || [ $attempt -ge $max_attempts ]; do
echo "Waiting for Gorse to be ready... (attempt $((attempt+1))/$max_attempts)"
sleep 5
attempt=$((attempt+1))
done
if [ $attempt -ge $max_attempts ]; then
echo "Warning: Maximum attempts reached. Gorse may not be ready."
fi
# Import MovieLens 100k dataset
curl -X POST "http://localhost:8088/api/restore" --data-binary "@./ml-100k.bin"
# Restart Gorse to apply changes
docker compose restart master
max_attempts=18
attempt=0
until curl -s "http://localhost:8088/api/dashboard/tasks" | grep -q "Train Collaborative Filtering Model" || [ $attempt -ge $max_attempts ]; do
echo "Waiting for recommendation... (attempt $((attempt+1))/$max_attempts)"
sleep 10
attempt=$((attempt+1))
done
if [ $attempt -ge $max_attempts ]; then
echo "Warning: Maximum attempts reached. Recommendation may not be ready."
fi
================================================
FILE: cmd/goat/README.md
================================================
GOAT has been moved to https://github.com/gorse-io/goat
================================================
FILE: cmd/gorse-cli/main.go
================================================
// Copyright 2026 gorse Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"context"
"encoding/csv"
"fmt"
"maps"
"math"
"os"
"runtime"
"slices"
"strconv"
"sync"
mapset "github.com/deckarep/golang-set/v2"
"github.com/expr-lang/expr"
"github.com/expr-lang/expr/vm"
"github.com/gorse-io/gorse/common/floats"
"github.com/gorse-io/gorse/common/heap"
"github.com/gorse-io/gorse/common/log"
"github.com/gorse-io/gorse/common/parallel"
"github.com/gorse-io/gorse/config"
"github.com/gorse-io/gorse/dataset"
"github.com/gorse-io/gorse/logics"
"github.com/gorse-io/gorse/master"
"github.com/gorse-io/gorse/model/cf"
"github.com/gorse-io/gorse/model/ctr"
"github.com/gorse-io/gorse/storage"
"github.com/gorse-io/gorse/storage/data"
"github.com/olekukonko/tablewriter"
"github.com/samber/lo"
"github.com/sashabaranov/go-openai"
"github.com/schollz/progressbar/v3"
"github.com/spf13/cobra"
"go.uber.org/atomic"
"go.uber.org/zap"
)
var rootCmd = &cobra.Command{
Use: "gorse-cli",
Short: "Gorse command line tool",
Run: func(cmd *cobra.Command, args []string) {
_ = cmd.Help()
},
}
var benchLLMCmd = &cobra.Command{
Use: "bench-llm",
Short: "Benchmark LLM models for ranking",
Run: func(cmd *cobra.Command, args []string) {
// Load configuration
configPath, _ := cmd.Flags().GetString("config")
cfg, err := config.LoadConfig(configPath)
if err != nil {
log.Logger().Fatal("failed to load config", zap.Error(err))
}
// Load dataset
m := master.NewMaster(cfg, os.TempDir(), false, configPath)
m.DataClient, err = data.Open(m.Config.Database.DataStore, m.Config.Database.DataTablePrefix,
storage.WithIsolationLevel(m.Config.Database.MySQL.IsolationLevel))
if err != nil {
log.Logger().Fatal("failed to open data client", zap.Error(err))
}
evaluator := master.NewOnlineEvaluator(
m.Config.Recommend.DataSource.PositiveFeedbackTypes,
m.Config.Recommend.DataSource.ReadFeedbackTypes)
dataset, cfDataset, err := m.LoadDataFromDatabase(context.Background(), m.DataClient,
m.Config.Recommend.DataSource.PositiveFeedbackTypes,
m.Config.Recommend.DataSource.ReadFeedbackTypes,
m.Config.Recommend.DataSource.ItemTTL,
m.Config.Recommend.DataSource.PositiveFeedbackTTL,
evaluator,
nil)
if err != nil {
log.Logger().Fatal("failed to load dataset", zap.Error(err))
}
// Split dataset
var scores sync.Map
train, test := dataset.Split(0.2, 0)
table := tablewriter.NewWriter(os.Stdout)
table.Header([]string{"", "#interactions", "#positive", "#negative"})
lo.Must0(table.Bulk([][]string{
{"total", strconv.Itoa(dataset.Count()), strconv.Itoa(dataset.PositiveCount), strconv.Itoa(dataset.NegativeCount)},
{"train", strconv.Itoa(train.Count()), strconv.Itoa(train.PositiveCount), strconv.Itoa(train.NegativeCount)},
{"test", strconv.Itoa(test.Count()), strconv.Itoa(test.PositiveCount), strconv.Itoa(test.NegativeCount)},
}))
lo.Must0(table.Render())
exportUserAUC, _ := cmd.Flags().GetBool("user-auc")
go EvaluateAFM(cfg, train, test, exportUserAUC, &scores)
EvaluateLLM(cfg, train, test, cfDataset.GetItems(), exportUserAUC, &scores)
data := [][]string{{"Ranker", "GAUC"}}
scores.Range(func(key, value any) bool {
data = append(data, []string{
key.(string),
strconv.FormatFloat(value.(float64), 'f', 4, 32),
})
return true
})
table = tablewriter.NewWriter(os.Stdout)
table.Header(data[0])
lo.Must0(table.Bulk(data[1:]))
lo.Must0(table.Render())
},
}
func EvaluateAFM(cfg *config.Config, train, test *ctr.Dataset, exportUserAUC bool, scores *sync.Map) {
ml := ctr.NewAFM(nil)
ml.Fit(context.Background(), train, test,
ctr.NewFitConfig().
SetVerbose(10).
SetJobs(runtime.NumCPU()).
SetPatience(10))
feedbackCount := make(map[int32]int)
for i := 0; i < train.Count(); i++ {
indices, _, _, target := train.Get(i)
if target > 0 {
userIndex := indices[0]
feedbackCount[userIndex]++
}
}
var features []lo.Tuple2[[]int32, []float32]
var embeddings [][][]float32
positives := make(map[int32][]int)
negatives := make(map[int32][]int)
for i := 0; i < test.Count(); i++ {
indices, values, embedding, target := test.Get(i)
features = append(features, lo.Tuple2[[]int32, []float32]{A: indices, B: values})
embeddings = append(embeddings, embedding)
userIndex := indices[0]
if target > 0 {
positives[userIndex] = append(positives[userIndex], i)
} else {
negatives[userIndex] = append(negatives[userIndex], i)
}
}
predictions := ml.BatchInternalPredict(features, embeddings, runtime.NumCPU())
var csvFile *os.File
var csvWriter *csv.Writer
if exportUserAUC {
var err error
csvFile, err = os.Create("AFM.csv")
if err != nil {
log.Logger().Error("failed to create AFM.csv", zap.Error(err))
exportUserAUC = false
} else {
defer csvFile.Close()
csvWriter = csv.NewWriter(csvFile)
defer csvWriter.Flush()
_ = csvWriter.Write([]string{"Feedback", "Candidates", "AUC"})
}
}
var sum float32
var count float32
for userIndex, posIndices := range positives {
negIndices := negatives[userIndex]
if len(negIndices) == 0 || feedbackCount[userIndex] == 0 || feedbackCount[userIndex] > cfg.Recommend.ContextSize {
continue
}
var posPredictions, negPredictions []float32
for _, posIndex := range posIndices {
posPredictions = append(posPredictions, predictions[posIndex])
}
for _, negIndex := range negIndices {
negPredictions = append(negPredictions, predictions[negIndex])
}
userAUC := ctr.AUC(posPredictions, negPredictions)
if exportUserAUC {
_ = csvWriter.Write([]string{
strconv.Itoa(feedbackCount[userIndex]),
strconv.Itoa(len(posIndices) + len(negIndices)),
fmt.Sprintf("%.4f", userAUC),
})
}
userCount := float32(len(posIndices) + len(negIndices))
sum += userAUC * userCount
count += userCount
}
var score float64
if count > 0 {
score = float64(sum / count)
}
scores.Store("AFM", score)
}
func EvaluateLLM(cfg *config.Config, train, test *ctr.Dataset, items []data.Item, exportUserAUC bool, scores *sync.Map) {
chat, err := logics.NewChatReranker(
cfg.Recommend.Ranker.RerankerAPI,
cfg.Recommend.Ranker.QueryTemplate,
cfg.Recommend.Ranker.DocumentTemplate,
)
if err != nil {
log.Logger().Fatal("failed to create chat ranker", zap.Error(err))
}
feedbacks := make(map[int32][]*logics.FeedbackItem)
for i := 0; i < train.Count(); i++ {
indices, _, _, target := train.Get(i)
if target <= 0 {
continue
}
userIndex := indices[0]
itemIndex := indices[1] - int32(train.CountUsers())
feedbacks[userIndex] = append(feedbacks[userIndex], &logics.FeedbackItem{
Item: items[itemIndex],
})
}
positives := make(map[int32][]int32)
negatives := make(map[int32][]int32)
for i := 0; i < test.Count(); i++ {
indices, _, _, target := test.Get(i)
userIndex := indices[0]
itemIndex := indices[1] - int32(test.CountUsers())
if target > 0 {
positives[userIndex] = append(positives[userIndex], itemIndex)
} else {
negatives[userIndex] = append(negatives[userIndex], itemIndex)
}
}
var csvFile *os.File
var csvWriter *csv.Writer
var csvMu sync.Mutex
if exportUserAUC {
var err error
csvFile, err = os.Create(fmt.Sprintf("%s.csv", cfg.Recommend.Ranker.RerankerAPI.Model))
if err != nil {
log.Logger().Error("failed to create LLM.csv", zap.Error(err))
exportUserAUC = false
} else {
defer csvFile.Close()
csvWriter = csv.NewWriter(csvFile)
defer csvWriter.Flush()
_ = csvWriter.Write([]string{"Feedback", "Candidates", "AUC"})
}
}
var sum atomic.Float32
var count atomic.Float32
lo.Must0(parallel.ForEach(context.Background(), slices.Collect(maps.Keys(positives)), runtime.NumCPU(), func(_ int, userIndex int32) {
posIndices := positives[userIndex]
negIndices := negatives[userIndex]
if len(negIndices) == 0 {
return
}
candidates := make([]*data.Item, 0, len(posIndices)+len(negIndices))
positiveItems := mapset.NewSet[string]()
negativeItems := mapset.NewSet[string]()
for _, negIndex := range negIndices {
item := items[negIndex]
candidates = append(candidates, &item)
negativeItems.Add(item.ItemId)
}
for _, posIndex := range posIndices {
item := items[posIndex]
candidates = append(candidates, &item)
positiveItems.Add(item.ItemId)
}
feedback := feedbacks[int32(userIndex)]
if len(feedback) == 0 || len(feedback) > cfg.Recommend.ContextSize {
return
}
result, err := chat.Rank(context.Background(), &data.User{}, feedback, candidates)
if err != nil {
log.Logger().Error("failed to rank items for user", zap.Int32("user_index", userIndex), zap.Error(err))
return
}
var posPredictions, negPredictions []float32
for _, item := range result {
if positiveItems.Contains(item.Id) {
posPredictions = append(posPredictions, float32(item.Score))
} else if negativeItems.Contains(item.Id) {
negPredictions = append(negPredictions, float32(item.Score))
}
}
userAUC := ctr.AUC(posPredictions, negPredictions)
if exportUserAUC {
csvMu.Lock()
_ = csvWriter.Write([]string{
strconv.Itoa(len(feedback)),
strconv.Itoa(len(posIndices) + len(negIndices)),
fmt.Sprintf("%.4f", userAUC),
})
csvMu.Unlock()
}
userCount := float32(len(posIndices) + len(negIndices))
sum.Add(userAUC * userCount)
count.Add(userCount)
}))
var score float64
if count.Load() > 0 {
score = float64(sum.Load() / count.Load())
}
scores.Store(cfg.Recommend.Ranker.RerankerAPI.Model, score)
}
func EvaluateEmbedding(cfg *config.Config, train, test dataset.CFSplit, embeddingExpr, textExpr string, topK, jobs int, scores *sync.Map) {
// Compile expression
var embeddingProgram, textProgram *vm.Program
var err error
if embeddingExpr != "" {
embeddingProgram, err = expr.Compile(embeddingExpr, expr.Env(map[string]any{
"item": data.Item{},
}))
if err != nil {
log.Logger().Fatal("failed to compile embedding expression", zap.Error(err))
}
} else if textExpr != "" {
textProgram, err = expr.Compile(textExpr, expr.Env(map[string]any{
"item": data.Item{},
}))
if err != nil {
log.Logger().Fatal("failed to compile text expression", zap.Error(err))
}
} else {
log.Logger().Fatal("one of embedding-column or text-column is required")
}
// Extract embeddings
var dimensions atomic.Int64
embeddings := make([][]float32, test.CountItems())
if textExpr != "" {
clientConfig := openai.DefaultConfig(cfg.OpenAI.AuthToken)
clientConfig.BaseURL = cfg.OpenAI.BaseURL
client := openai.NewClientWithConfig(clientConfig)
// Generate embeddings
bar := progressbar.Default(int64(test.CountItems()))
lo.Must0(parallel.For(context.Background(), test.CountItems(), jobs, func(i int) {
_ = bar.Add(1)
item := &test.GetItems()[i]
result, err := expr.Run(textProgram, map[string]any{
"item": *item,
})
if err != nil {
return
}
text, ok := result.(string)
if !ok {
return
}
// Generate embedding
resp, err := client.CreateEmbeddings(context.Background(), openai.EmbeddingRequest{
Input: text,
Model: openai.EmbeddingModel(cfg.OpenAI.EmbeddingModel),
Dimensions: cfg.OpenAI.EmbeddingDimensions,
})
if err != nil {
log.Logger().Error("failed to create embeddings", zap.String("item_id", item.ItemId), zap.Error(err))
return
}
embeddings[i] = resp.Data[0].Embedding
if dimensions.Load() == 0 {
dimensions.Store(int64(len(resp.Data[0].Embedding)))
}
}))
} else {
lo.Must0(parallel.For(context.Background(), test.CountItems(), jobs, func(i int) {
item := test.GetItems()[i]
result, err := expr.Run(embeddingProgram, map[string]any{
"item": item,
})
if err == nil {
if e, ok := result.([]float32); ok {
embeddings[i] = e
if dim := dimensions.Swap(int64(len(e))); dim == 0 {
dimensions.Store(int64(len(e)))
} else if dim != int64(len(e)) {
log.Logger().Fatal("inconsistent embedding dimensions",
zap.Int64("expected", dim),
zap.Int64("got", int64(len(e))))
}
}
}
}))
}
var (
ndcg atomic.Float32
precision atomic.Float32
recall atomic.Float32
count atomic.Float32
)
negatives := test.SampleUserNegatives(train, 99)
lo.Must0(parallel.For(context.Background(), test.CountUsers(), jobs, func(userIdx int) {
targetSet := mapset.NewSet(test.GetUserFeedback()[userIdx]...)
negativeSample := negatives[userIdx]
if len(test.GetUserFeedback()[userIdx]) == 0 {
return
}
candidates := make([]int32, 0, targetSet.Cardinality()+len(negativeSample))
candidates = append(candidates, test.GetUserFeedback()[userIdx]...)
candidates = append(candidates, negativeSample...)
feedback := train.GetUserFeedback()[userIdx]
if len(feedback) == 0 {
return
}
h := heap.NewTopKFilter[int32, float32](topK)
for _, candidateIdx := range candidates {
candidateEmbedding := embeddings[candidateIdx]
if candidateEmbedding == nil {
continue
}
var totalDistance float32
var validShots int
for _, shotIdx := range feedback {
shotEmbedding := embeddings[shotIdx]
if shotEmbedding == nil {
continue
}
totalDistance -= floats.Euclidean(candidateEmbedding, shotEmbedding)
validShots++
}
if validShots > 0 {
h.Push(candidateIdx, totalDistance)
}
}
if h.Len() == 0 {
return
}
rankList := h.PopAllValues()
ndcg.Add(cf.NDCG(targetSet, rankList))
precision.Add(cf.Precision(targetSet, rankList))
recall.Add(cf.Recall(targetSet, rankList))
count.Add(1)
}))
var score cf.Score
if count.Load() > 0 {
score = cf.Score{
NDCG: ndcg.Load() / count.Load(),
Precision: precision.Load() / count.Load(),
Recall: recall.Load() / count.Load(),
}
}
scores.Store(fmt.Sprintf("%s (%d)", cfg.OpenAI.EmbeddingModel, dimensions.Load()), score)
}
var benchEmbeddingCmd = &cobra.Command{
Use: "bench-embedding",
Short: "Benchmark embedding models for item-to-item",
Run: func(cmd *cobra.Command, args []string) {
// Load configuration
configPath, _ := cmd.Flags().GetString("config")
cfg, err := config.LoadConfig(configPath)
if err != nil {
log.Logger().Fatal("failed to load config", zap.Error(err))
}
shots, _ := cmd.Flags().GetInt("shots")
embeddingColumn, _ := cmd.Flags().GetString("embedding-column")
textColumn, _ := cmd.Flags().GetString("text-column")
if embeddingColumn == "" && textColumn == "" {
log.Logger().Fatal("one of embedding-column or text-column is required")
}
// Load dataset
m := master.NewMaster(cfg, os.TempDir(), false, configPath)
m.DataClient, err = data.Open(m.Config.Database.DataStore, m.Config.Database.DataTablePrefix,
storage.WithIsolationLevel(m.Config.Database.MySQL.IsolationLevel))
if err != nil {
log.Logger().Fatal("failed to open data client", zap.Error(err))
}
evaluator := master.NewOnlineEvaluator(
m.Config.Recommend.DataSource.PositiveFeedbackTypes,
m.Config.Recommend.DataSource.ReadFeedbackTypes)
_, dataset, err := m.LoadDataFromDatabase(context.Background(), m.DataClient,
m.Config.Recommend.DataSource.PositiveFeedbackTypes,
m.Config.Recommend.DataSource.ReadFeedbackTypes,
m.Config.Recommend.DataSource.ItemTTL,
m.Config.Recommend.DataSource.PositiveFeedbackTTL,
evaluator,
nil)
if err != nil {
log.Logger().Fatal("failed to load dataset", zap.Error(err))
}
// Override config
if cmd.Flags().Changed("embedding-model") {
cfg.OpenAI.EmbeddingModel = cmd.Flag("embedding-model").Value.String()
}
dimensions, _ := cmd.Flags().GetInt("embedding-dimensions")
cfg.OpenAI.EmbeddingDimensions = dimensions
// Split dataset
var scores sync.Map
train, test := dataset.SplitLatest(shots)
test.SampleUserNegatives(dataset, 99)
table := tablewriter.NewWriter(os.Stdout)
table.Header([]string{"", "#users", "#items", "#interactions"})
lo.Must0(table.Bulk([][]string{
{"total", strconv.Itoa(dataset.CountUsers()), strconv.Itoa(dataset.CountItems()), strconv.Itoa(dataset.CountFeedback())},
{"train", strconv.Itoa(train.CountUsers()), strconv.Itoa(train.CountItems()), strconv.Itoa(train.CountFeedback())},
{"test", strconv.Itoa(test.CountUsers()), strconv.Itoa(test.CountItems()), strconv.Itoa(test.CountFeedback())},
}))
lo.Must0(table.Render())
topK, _ := cmd.Flags().GetInt("top")
jobs, _ := cmd.Flags().GetInt("jobs")
EvaluateEmbedding(cfg, train, test, embeddingColumn, textColumn, topK, jobs, &scores)
data := [][]string{{
"Embedding Model",
fmt.Sprintf("NDCG@%d", topK),
fmt.Sprintf("Precision@%d", topK),
fmt.Sprintf("Recall@%d", topK),
}}
scores.Range(func(key, value any) bool {
score := value.(cf.Score)
data = append(data, []string{
key.(string),
fmt.Sprintf("%.4f", score.NDCG),
fmt.Sprintf("%.4f", score.Precision),
fmt.Sprintf("%.4f", score.Recall),
})
return true
})
table = tablewriter.NewWriter(os.Stdout)
table.Header(data[0])
lo.Must0(table.Bulk(data[1:]))
lo.Must0(table.Render())
},
}
func init() {
rootCmd.PersistentFlags().StringP("config", "c", "", "Path to configuration file")
rootCmd.PersistentFlags().IntP("jobs", "j", runtime.NumCPU(), "Number of jobs to run in parallel")
rootCmd.AddCommand(benchLLMCmd)
rootCmd.AddCommand(benchEmbeddingCmd)
benchLLMCmd.PersistentFlags().Bool("user-auc", false, "Export user-level AUC scores to CSV file")
benchEmbeddingCmd.PersistentFlags().IntP("top", "k", 10, "Number of top items to evaluate for each user")
benchEmbeddingCmd.PersistentFlags().IntP("shots", "s", math.MaxInt, "Number of shots for each user")
benchEmbeddingCmd.PersistentFlags().Int("embedding-dimensions", 0, "Embedding dimensions")
benchEmbeddingCmd.PersistentFlags().String("embedding-model", "", "Embedding model")
benchEmbeddingCmd.PersistentFlags().String("embedding-column", "", "Column name of embedding in item label")
benchEmbeddingCmd.PersistentFlags().String("text-column", "", "Column name of text in item label")
}
func main() {
if err := rootCmd.Execute(); err != nil {
log.Logger().Fatal("failed to execute command", zap.Error(err))
}
}
================================================
FILE: cmd/gorse-in-one/Dockerfile
================================================
# syntax = docker/dockerfile:1
############################
# STEP 1 build executable binary
############################
FROM --platform=$BUILDPLATFORM golang:1.26
WORKDIR /src
COPY go.* ./
RUN go mod download
COPY . ./
ARG TARGETOS
ARG TARGETARCH
RUN --mount=type=cache,target=/root/.cache/go-build \
cd cmd/gorse-in-one && \
GOOS=${TARGETOS} GOARCH=${TARGETARCH} CGO_ENABLED=0 go build -ldflags=" \
-X 'github.com/gorse-io/gorse/cmd/version.Version=$(git describe --tags $(git rev-parse HEAD))' \
-X 'github.com/gorse-io/gorse/cmd/version.GitCommit=$(git rev-parse HEAD)' \
-X 'github.com/gorse-io/gorse/cmd/version.BuildTime=$(date)' \
-X 'github.com/gorse-io/gorse/config.RootDir=/var/lib/gorse'" . && \
mv gorse-in-one /usr/bin
############################
# STEP 2 build a small image
############################
FROM scratch
COPY --from=0 /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=0 /usr/bin/gorse-in-one /usr/bin/gorse-in-one
ENV USER=root
ENTRYPOINT ["/usr/bin/gorse-in-one", "-c", "/etc/gorse/config.toml"]
================================================
FILE: cmd/gorse-in-one/Dockerfile.cuda
================================================
# syntax = docker/dockerfile:1
############################
# STEP 1 build executable binary
############################
FROM nvidia/cuda:12.8.1-devel-ubuntu24.04
COPY --from=golang:1.26 /usr/local/go/ /usr/local/go/
ENV PATH=/usr/local/go/bin:$PATH
RUN apt update && apt install -y git
WORKDIR /src
COPY go.* ./
RUN go mod download
COPY . ./
RUN cd common/blas/cublas && make
RUN --mount=type=cache,target=/root/.cache/go-build \
cd cmd/gorse-in-one && \
go build -tags xla -ldflags=" \
-X 'github.com/gorse-io/gorse/cmd/version.Version=$(git describe --tags $(git rev-parse HEAD))' \
-X 'github.com/gorse-io/gorse/cmd/version.GitCommit=$(git rev-parse HEAD)' \
-X 'github.com/gorse-io/gorse/cmd/version.BuildTime=$(date)' \
-X 'github.com/gorse-io/gorse/config.RootDir=/var/lib/gorse'" . && \
mv gorse-in-one /usr/bin
############################
# STEP 2 build runtime image
############################
FROM nvidia/cuda:12.8.1-runtime-ubuntu24.04
COPY --from=0 /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=0 /usr/bin/gorse-in-one /usr/bin/gorse-in-one
RUN /usr/bin/gorse-in-one --version
ENV USER=root
ENTRYPOINT ["/usr/bin/gorse-in-one", "-c", "/etc/gorse/config.toml"]
================================================
FILE: cmd/gorse-in-one/Dockerfile.mkl
================================================
# syntax = docker/dockerfile:1
############################
# STEP 1 build executable binary
############################
FROM golang:1.26-bookworm
# Install Intel® oneAPI Toolkits
RUN apt update && apt install -y wget gnupg2 git
RUN wget -O- https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB \
| gpg --dearmor | tee /usr/share/keyrings/oneapi-archive-keyring.gpg > /dev/null
RUN echo "deb [signed-by=/usr/share/keyrings/oneapi-archive-keyring.gpg] https://apt.repos.intel.com/oneapi all main" | tee /etc/apt/sources.list.d/oneAPI.list
RUN apt update && apt install -y intel-oneapi-base-toolkit
# Build Gorse
WORKDIR /src
COPY go.* ./
RUN go mod download
COPY . ./
RUN --mount=type=cache,target=/root/.cache/go-build \
. /opt/intel/oneapi/setvars.sh && \
cd cmd/gorse-in-one && \
go build -tags mkl -ldflags=" \
-X 'github.com/gorse-io/gorse/cmd/version.Version=$(git describe --tags $(git rev-parse HEAD))' \
-X 'github.com/gorse-io/gorse/cmd/version.GitCommit=$(git rev-parse HEAD)' \
-X 'github.com/gorse-io/gorse/cmd/version.BuildTime=$(date)' \
-X 'github.com/gorse-io/gorse/config.RootDir=/var/lib/gorse'" .
############################
# STEP 2 build runtime image
############################
FROM debian:bookworm-slim
RUN apt update && apt install -y ca-certificates && rm -rf /var/lib/apt/lists/*
COPY --from=0 /src/cmd/gorse-in-one/gorse-in-one /usr/bin/gorse-in-one
RUN /usr/bin/gorse-in-one --version
ENV USER=root
ENTRYPOINT ["/usr/bin/gorse-in-one", "-c", "/etc/gorse/config.toml"]
================================================
FILE: cmd/gorse-in-one/Dockerfile.openblas
================================================
# syntax = docker/dockerfile:1
############################
# STEP 1 build executable binary
############################
FROM --platform=$BUILDPLATFORM golang:1.26
# Install OpenBLAS
ARG BUILDARCH
ARG TARGETARCH
RUN if [ "${TARGETARCH}" = "amd64" ]; then \
dpkg --add-architecture ${TARGETARCH} && apt update && apt install -y gcc-x86-64-linux-gnu libopenblas-dev:${TARGETARCH} git; \
elif [ "${TARGETARCH}" = "arm64" ]; then \
dpkg --add-architecture ${TARGETARCH} && apt update && apt install -y gcc-aarch64-linux-gnu libopenblas-dev:${TARGETARCH} git; \
elif [ "${TARGETARCH}" = "riscv64" ]; then \
dpkg --add-architecture ${TARGETARCH} && apt update && apt install -y gcc-riscv64-linux-gnu libopenblas-dev:${TARGETARCH} git; \
elif [ "${TARGETARCH}" = "ppc64le" ]; then \
dpkg --add-architecture ppc64el && apt update && apt install -y gcc-powerpc64le-linux-gnu libopenblas-dev:ppc64el git; \
elif [ "${TARGETARCH}" = "s390x" ]; then \
dpkg --add-architecture ${TARGETARCH} && apt update && apt install -y gcc-s390x-linux-gnu libopenblas-dev:${TARGETARCH} git; \
elif [ "${TARGETARCH}" = "loong64" ]; then \
dpkg --add-architecture ${TARGETARCH} && apt update && apt install -y gcc-loongarch64-linux-gnu libopenblas-dev:${TARGETARCH} git; \
else \
echo "Unsupported TARGETARCH ${TARGETARCH}"; exit 1; \
fi
# Build Gorse
WORKDIR /src
COPY go.* ./
RUN go mod download
COPY . ./
ARG TARGETOS
RUN --mount=type=cache,target=/root/.cache/go-build \
if [ "${TARGETARCH}" = "amd64" ]; then \
export CC=x86_64-linux-gnu-gcc; \
elif [ "${TARGETARCH}" = "arm64" ]; then \
export CC=aarch64-linux-gnu-gcc; \
elif [ "${TARGETARCH}" = "riscv64" ]; then \
export CC=riscv64-linux-gnu-gcc; \
elif [ "${TARGETARCH}" = "ppc64le" ]; then \
export CC=powerpc64le-linux-gnu-gcc; \
elif [ "${TARGETARCH}" = "s390x" ]; then \
export CC=s390x-linux-gnu-gcc; \
elif [ "${TARGETARCH}" = "loong64" ]; then \
export CC=loongarch64-linux-gnu-gcc; \
else \
echo "Unsupported TARGETARCH ${TARGETARCH}"; exit 1; \
fi && \
cd cmd/gorse-in-one && \
GOOS=${TARGETOS} GOARCH=${TARGETARCH} CGO_ENABLED=1 go build -tags openblas -ldflags=" \
-X 'github.com/gorse-io/gorse/cmd/version.Version=$(git describe --tags $(git rev-parse HEAD))' \
-X 'github.com/gorse-io/gorse/cmd/version.GitCommit=$(git rev-parse HEAD)' \
-X 'github.com/gorse-io/gorse/cmd/version.BuildTime=$(date)' \
-X 'github.com/gorse-io/gorse/config.RootDir=/var/lib/gorse'" .
############################
# STEP 2 build runtime image
############################
FROM debian:trixie-slim
RUN apt update && apt install -y ca-certificates && rm -rf /var/lib/apt/lists/*
COPY --from=0 /src/cmd/gorse-in-one/gorse-in-one /usr/bin/gorse-in-one
RUN /usr/bin/gorse-in-one --version
ENV USER=root
ENTRYPOINT ["/usr/bin/gorse-in-one", "-c", "/etc/gorse/config.toml"]
================================================
FILE: cmd/gorse-in-one/Dockerfile.windows
================================================
############################
# STEP 1 build executable binary
############################
FROM golang:1.26
WORKDIR /src
COPY . ./
ENV CGO_ENABLED=0
RUN go build -o / -ldflags="\" \
-X 'github.com/gorse-io/gorse/cmd/version.Version=$(git describe --tags $(git rev-parse HEAD))' \
-X 'github.com/gorse-io/gorse/cmd/version.GitCommit=$(git rev-parse HEAD)' \
-X 'github.com/gorse-io/gorse/cmd/version.BuildTime=$(date)'\"" ./cmd/...
############################
# STEP 2 build a small image
############################
FROM mcr.microsoft.com/windows/servercore:ltsc2022
COPY --from=0 /gorse-in-one.exe /gorse-in-one.exe
RUN /gorse-in-one.exe --version
ENTRYPOINT [ "/gorse-in-one.exe" ]
================================================
FILE: cmd/gorse-in-one/main.go
================================================
// Copyright 2022 gorse Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"compress/gzip"
"fmt"
"net/http"
"os"
"os/signal"
"path/filepath"
"runtime"
"github.com/gorse-io/gorse/client"
"github.com/gorse-io/gorse/cmd/version"
"github.com/gorse-io/gorse/common/log"
"github.com/gorse-io/gorse/config"
"github.com/gorse-io/gorse/master"
"github.com/gorse-io/gorse/storage/data"
"github.com/klauspost/cpuid/v2"
"github.com/schollz/progressbar/v3"
"github.com/spf13/cobra"
"go.uber.org/zap"
)
var oneCommand = &cobra.Command{
Use: "gorse-in-one",
Short: "The all in one distribution of gorse recommender system.",
Run: func(cmd *cobra.Command, args []string) {
// Show version
if showVersion, _ := cmd.PersistentFlags().GetBool("version"); showVersion {
fmt.Println(version.BuildInfo())
return
}
// setup logger
debug, _ := cmd.PersistentFlags().GetBool("debug")
log.SetLogger(cmd.PersistentFlags(), debug)
// locate config file
var configPath string
cachePath, _ := cmd.PersistentFlags().GetString("cache-path")
playground, _ := cmd.PersistentFlags().GetString("playground")
if playground != "" {
userHomeDir, err := os.UserHomeDir()
if err != nil {
log.Logger().Fatal("failed to get user home directory", zap.Error(err))
}
etcDir := filepath.Join(userHomeDir, ".gorse", "etc")
if err = os.MkdirAll(etcDir, os.ModePerm); err != nil {
log.Logger().Fatal("failed to create config directory", zap.Error(err))
}
configPath = filepath.Join(etcDir, "config.toml")
if playground == "ml-100k" {
err = os.WriteFile(configPath, []byte(client.ConfigTOML), 0644)
} else {
err = os.WriteFile(configPath, []byte(config.ConfigTOML), 0644)
}
if err != nil {
log.Logger().Fatal("failed to write playground config", zap.Error(err))
}
fmt.Println("Generated config file:", configPath)
fmt.Println("Using cache directory:", cachePath)
} else {
configPath, _ = cmd.PersistentFlags().GetString("config")
log.Logger().Info("load config", zap.String("config", configPath))
}
// load config
conf, err := config.LoadConfig(configPath)
if err != nil {
log.Logger().Fatal("failed to load config", zap.Error(err))
}
// create master
m := master.NewMaster(conf, cachePath, true, configPath)
if playground != "" {
setup(m, playground)
}
// Stop master
done := make(chan struct{})
go func() {
sigint := make(chan os.Signal, 1)
signal.Notify(sigint, os.Interrupt)
<-sigint
m.Shutdown()
close(done)
}()
// Start master
m.Serve()
<-done
log.Logger().Info("stop gorse-in-one successfully")
},
}
func init() {
log.AddFlags(oneCommand.PersistentFlags())
oneCommand.PersistentFlags().Bool("debug", false, "use debug log mode")
oneCommand.PersistentFlags().BoolP("version", "v", false, "gorse version")
oneCommand.PersistentFlags().String("playground", "", "playground mode (setup a recommender system for GitHub repositories)")
oneCommand.PersistentFlags().Lookup("playground").NoOptDefVal = "default"
oneCommand.PersistentFlags().StringP("config", "c", "", "configuration file path")
oneCommand.PersistentFlags().String("cache-path", config.MkDir("master"), "path of cache folder")
}
func main() {
if err := oneCommand.Execute(); err != nil {
log.Logger().Fatal("failed to execute", zap.Error(err))
}
}
func setup(m *master.Master, playground string) {
// set database to user home directory
m.Config.Database.DataStore = config.GetDefaultConfig().Database.DataStore
fmt.Println("Using database:", m.Config.Database.DataStore)
m.Config.Database.CacheStore = config.GetDefaultConfig().Database.CacheStore
fmt.Println("Using cache:", m.Config.Database.CacheStore)
m.Config.Master.NumJobs = runtime.NumCPU()
fmt.Printf("Using %d CPU cores: %s\n", m.Config.Master.NumJobs, cpuid.CPU.BrandName)
// connect database
var err error
dataOpts := m.Config.Database.StorageOptions(m.Config.Database.DataStore)
m.DataClient, err = data.Open(m.Config.Database.DataStore, m.Config.Database.DataTablePrefix, dataOpts...)
if err != nil {
log.Logger().Fatal("failed to connect data database", zap.Error(err),
zap.String("database", log.RedactDBURL(m.Config.Database.DataStore)))
}
defer m.DataClient.Close()
if err = m.DataClient.Init(); err != nil {
log.Logger().Fatal("failed to init database", zap.Error(err))
}
// import playground data
var resp *http.Response
if playground == "ml-100k" {
resp, err = http.Get("https://cdn.gorse.io/example/ml-100k.bin.gz")
} else {
resp, err = http.Get("https://cdn.gorse.io/example/github.bin.gz")
}
if err != nil {
log.Logger().Fatal("failed to download playground data", zap.Error(err))
}
defer resp.Body.Close()
bar := progressbar.DefaultBytes(
resp.ContentLength,
"Importing data",
)
p := progressbar.NewReader(resp.Body, bar)
d, err := gzip.NewReader(&p)
if err != nil {
log.Logger().Fatal("failed to decompress playground data", zap.Error(err))
}
_, err = m.Restore(d)
if err != nil {
log.Logger().Fatal("failed to import playground data", zap.Error(err))
}
// show info
fmt.Printf("Welcome to Gorse Playground\n")
fmt.Println()
fmt.Printf(" Dashboard: http://127.0.0.1:%d/overview\n", m.Config.Master.HttpPort)
fmt.Printf(" RESTful APIs: http://127.0.0.1:%d/apidocs\n", m.Config.Master.HttpPort)
fmt.Printf(" Documentation: https://gorse.io\n")
fmt.Println()
}
================================================
FILE: cmd/gorse-master/Dockerfile
================================================
# syntax = docker/dockerfile:1
############################
# STEP 1 build executable binary
############################
FROM --platform=$BUILDPLATFORM golang:1.26
WORKDIR /src
COPY go.* ./
RUN go mod download
COPY . ./
ARG TARGETOS
ARG TARGETARCH
RUN --mount=type=cache,target=/root/.cache/go-build \
cd cmd/gorse-master && \
GOOS=${TARGETOS} GOARCH=${TARGETARCH} CGO_ENABLED=0 go build -ldflags=" \
-X 'github.com/gorse-io/gorse/cmd/version.Version=$(git describe --tags $(git rev-parse HEAD))' \
-X 'github.com/gorse-io/gorse/cmd/version.GitCommit=$(git rev-parse HEAD)' \
-X 'github.com/gorse-io/gorse/cmd/version.BuildTime=$(date)' \
-X 'github.com/gorse-io/gorse/config.RootDir=/var/lib/gorse'" .
############################
# STEP 2 build a small image
############################
FROM scratch
COPY --from=0 /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=0 /src/cmd/gorse-master/gorse-master /usr/bin/gorse-master
ENV USER=root
ENTRYPOINT ["/usr/bin/gorse-master", "-c", "/etc/gorse/config.toml"]
================================================
FILE: cmd/gorse-master/Dockerfile.cuda
================================================
# syntax = docker/dockerfile:1
############################
# STEP 1 build executable binary
############################
FROM nvidia/cuda:12.8.1-devel-ubuntu24.04
COPY --from=golang:1.26 /usr/local/go/ /usr/local/go/
ENV PATH=/usr/local/go/bin:$PATH
RUN apt update && apt install -y git
WORKDIR /src
COPY go.* ./
RUN go mod download
COPY . ./
RUN cd common/blas/cublas && make
RUN --mount=type=cache,target=/root/.cache/go-build \
cd cmd/gorse-master && \
go build -tags xla -ldflags=" \
-X 'github.com/gorse-io/gorse/cmd/version.Version=$(git describe --tags $(git rev-parse HEAD))' \
-X 'github.com/gorse-io/gorse/cmd/version.GitCommit=$(git rev-parse HEAD)' \
-X 'github.com/gorse-io/gorse/cmd/version.BuildTime=$(date)' \
-X 'github.com/gorse-io/gorse/config.RootDir=/var/lib/gorse'" .
############################
# STEP 2 build runtime image
############################
FROM nvidia/cuda:12.8.1-runtime-ubuntu24.04
COPY --from=0 /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=0 /src/cmd/gorse-master/gorse-master /usr/bin/gorse-master
RUN /usr/bin/gorse-master --version
ENV USER=root
ENTRYPOINT ["/usr/bin/gorse-master", "-c", "/etc/gorse/config.toml"]
================================================
FILE: cmd/gorse-master/Dockerfile.mkl
================================================
# syntax = docker/dockerfile:1
############################
# STEP 1 build executable binary
############################
FROM golang:1.26-bookworm
# Install Intel® oneAPI Toolkits
RUN apt update && apt install -y wget gnupg2 git
RUN wget -O- https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB \
| gpg --dearmor | tee /usr/share/keyrings/oneapi-archive-keyring.gpg > /dev/null
RUN echo "deb [signed-by=/usr/share/keyrings/oneapi-archive-keyring.gpg] https://apt.repos.intel.com/oneapi all main" | tee /etc/apt/sources.list.d/oneAPI.list
RUN apt update && apt install -y intel-oneapi-base-toolkit
# Build Gorse
WORKDIR /src
COPY go.* ./
RUN go mod download
COPY . ./
RUN --mount=type=cache,target=/root/.cache/go-build \
. /opt/intel/oneapi/setvars.sh && \
cd cmd/gorse-master && \
go build -tags mkl -ldflags=" \
-X 'github.com/gorse-io/gorse/cmd/version.Version=$(git describe --tags $(git rev-parse HEAD))' \
-X 'github.com/gorse-io/gorse/cmd/version.GitCommit=$(git rev-parse HEAD)' \
-X 'github.com/gorse-io/gorse/cmd/version.BuildTime=$(date)' \
-X 'github.com/gorse-io/gorse/config.RootDir=/var/lib/gorse'" .
############################
# STEP 2 build runtime image
############################
FROM debian:bookworm-slim
RUN apt update && apt install -y ca-certificates && rm -rf /var/lib/apt/lists/*
COPY --from=0 /src/cmd/gorse-master/gorse-master /usr/bin/gorse-master
RUN /usr/bin/gorse-master --version
ENV USER=root
ENTRYPOINT ["/usr/bin/gorse-master", "-c", "/etc/gorse/config.toml"]
================================================
FILE: cmd/gorse-master/Dockerfile.openblas
================================================
# syntax = docker/dockerfile:1
############################
# STEP 1 build executable binary
############################
FROM --platform=$BUILDPLATFORM golang:1.26
# Install OpenBLAS
ARG BUILDARCH
ARG TARGETARCH
RUN if [ "${TARGETARCH}" = "amd64" ]; then \
dpkg --add-architecture ${TARGETARCH} && apt update && apt install -y gcc-x86-64-linux-gnu libopenblas-dev:${TARGETARCH} git; \
elif [ "${TARGETARCH}" = "arm64" ]; then \
dpkg --add-architecture ${TARGETARCH} && apt update && apt install -y gcc-aarch64-linux-gnu libopenblas-dev:${TARGETARCH} git; \
elif [ "${TARGETARCH}" = "riscv64" ]; then \
dpkg --add-architecture ${TARGETARCH} && apt update && apt install -y gcc-riscv64-linux-gnu libopenblas-dev:${TARGETARCH} git; \
elif [ "${TARGETARCH}" = "ppc64le" ]; then \
dpkg --add-architecture ppc64el && apt update && apt install -y gcc-powerpc64le-linux-gnu libopenblas-dev:ppc64el git; \
elif [ "${TARGETARCH}" = "s390x" ]; then \
dpkg --add-architecture ${TARGETARCH} && apt update && apt install -y gcc-s390x-linux-gnu libopenblas-dev:${TARGETARCH} git; \
elif [ "${TARGETARCH}" = "loong64" ]; then \
dpkg --add-architecture ${TARGETARCH} && apt update && apt install -y gcc-loongarch64-linux-gnu libopenblas-dev:${TARGETARCH} git; \
else \
echo "Unsupported TARGETARCH ${TARGETARCH}"; exit 1; \
fi
# Build Gorse
WORKDIR /src
COPY go.* ./
RUN go mod download
COPY . ./
ARG TARGETOS
RUN --mount=type=cache,target=/root/.cache/go-build \
if [ "${TARGETARCH}" = "amd64" ]; then \
export CC=x86_64-linux-gnu-gcc; \
elif [ "${TARGETARCH}" = "arm64" ]; then \
export CC=aarch64-linux-gnu-gcc; \
elif [ "${TARGETARCH}" = "riscv64" ]; then \
export CC=riscv64-linux-gnu-gcc; \
elif [ "${TARGETARCH}" = "ppc64le" ]; then \
export CC=powerpc64le-linux-gnu-gcc; \
elif [ "${TARGETARCH}" = "s390x" ]; then \
export CC=s390x-linux-gnu-gcc; \
elif [ "${TARGETARCH}" = "loong64" ]; then \
export CC=loongarch64-linux-gnu-gcc; \
else \
echo "Unsupported TARGETARCH ${TARGETARCH}"; exit 1; \
fi && \
cd cmd/gorse-master && \
GOOS=${TARGETOS} GOARCH=${TARGETARCH} CGO_ENABLED=1 go build -tags openblas -ldflags=" \
-X 'github.com/gorse-io/gorse/cmd/version.Version=$(git describe --tags $(git rev-parse HEAD))' \
-X 'github.com/gorse-io/gorse/cmd/version.GitCommit=$(git rev-parse HEAD)' \
-X 'github.com/gorse-io/gorse/cmd/version.BuildTime=$(date)' \
-X 'github.com/gorse-io/gorse/config.RootDir=/var/lib/gorse'" .
############################
# STEP 2 build runtime image
############################
FROM debian:trixie-slim
RUN apt update && apt install -y ca-certificates && rm -rf /var/lib/apt/lists/*
COPY --from=0 /src/cmd/gorse-master/gorse-master /usr/bin/gorse-master
RUN /usr/bin/gorse-master --version
ENV USER=root
ENTRYPOINT ["/usr/bin/gorse-master", "-c", "/etc/gorse/config.toml"]
================================================
FILE: cmd/gorse-master/Dockerfile.windows
================================================
############################
# STEP 1 build executable binary
############################
FROM golang:1.26
WORKDIR /src
COPY . ./
ENV CGO_ENABLED=0
RUN go build -o / -ldflags="\" \
-X 'github.com/gorse-io/gorse/cmd/version.Version=$(git describe --tags $(git rev-parse HEAD))' \
-X 'github.com/gorse-io/gorse/cmd/version.GitCommit=$(git rev-parse HEAD)' \
-X 'github.com/gorse-io/gorse/cmd/version.BuildTime=$(date)'\"" ./cmd/...
############################
# STEP 2 build a small image
############################
FROM mcr.microsoft.com/windows/servercore:ltsc2022
COPY --from=0 /gorse-master.exe /gorse-master.exe
RUN /gorse-master.exe --version
ENTRYPOINT [ "/gorse-master.exe" ]
================================================
FILE: cmd/gorse-master/main.go
================================================
// Copyright 2020 gorse Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"fmt"
"os"
"os/signal"
"github.com/gorse-io/gorse/cmd/version"
"github.com/gorse-io/gorse/common/log"
"github.com/gorse-io/gorse/config"
"github.com/gorse-io/gorse/master"
"github.com/spf13/cobra"
"go.uber.org/zap"
)
var masterCommand = &cobra.Command{
Use: "gorse-master",
Short: "The master node of gorse recommender system.",
Run: func(cmd *cobra.Command, args []string) {
// Show version
if showVersion, _ := cmd.PersistentFlags().GetBool("version"); showVersion {
fmt.Println(version.BuildInfo())
return
}
// setup logger
debug, _ := cmd.PersistentFlags().GetBool("debug")
log.SetLogger(cmd.PersistentFlags(), debug)
// Create master
configPath, _ := cmd.PersistentFlags().GetString("config")
log.Logger().Info("load config", zap.String("config", configPath))
conf, err := config.LoadConfig(configPath)
if err != nil {
log.Logger().Fatal("failed to load config", zap.Error(err))
}
cachePath, _ := cmd.PersistentFlags().GetString("cache-path")
m := master.NewMaster(conf, cachePath, false, configPath)
// Stop master
done := make(chan struct{})
go func() {
sigint := make(chan os.Signal, 1)
signal.Notify(sigint, os.Interrupt)
<-sigint
m.Shutdown()
close(done)
}()
// Start master
m.Serve()
<-done
log.Logger().Info("stop gorse master successfully")
},
}
func init() {
log.AddFlags(masterCommand.PersistentFlags())
masterCommand.PersistentFlags().Bool("debug", false, "use debug log mode")
masterCommand.PersistentFlags().StringP("config", "c", "", "configuration file path")
masterCommand.PersistentFlags().BoolP("version", "v", false, "gorse version")
masterCommand.PersistentFlags().String("cache-path", config.MkDir("master"), "path of cache folder")
}
func main() {
if err := masterCommand.Execute(); err != nil {
log.Logger().Fatal("failed to execute", zap.Error(err))
}
}
================================================
FILE: cmd/gorse-server/Dockerfile
================================================
# syntax = docker/dockerfile:1
############################
# STEP 1 build executable binary
############################
FROM --platform=$BUILDPLATFORM golang:1.26
WORKDIR /src
COPY go.* ./
RUN go mod download
COPY . ./
ARG TARGETOS
ARG TARGETARCH
RUN --mount=type=cache,target=/root/.cache/go-build \
cd cmd/gorse-server && \
GOOS=${TARGETOS} GOARCH=${TARGETARCH} CGO_ENABLED=0 go build -ldflags=" \
-X 'github.com/gorse-io/gorse/cmd/version.Version=$(git describe --tags $(git rev-parse HEAD))' \
-X 'github.com/gorse-io/gorse/cmd/version.GitCommit=$(git rev-parse HEAD)' \
-X 'github.com/gorse-io/gorse/cmd/version.BuildTime=$(date)' \
-X 'github.com/gorse-io/gorse/config.RootDir=/var/lib/gorse'" .
############################
# STEP 2 build a small image
############################
FROM scratch
COPY --from=0 /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=0 /src/cmd/gorse-server/gorse-server /usr/bin/gorse-server
ENV USER=root
ENTRYPOINT ["/usr/bin/gorse-server"]
================================================
FILE: cmd/gorse-server/Dockerfile.cuda
================================================
# syntax = docker/dockerfile:1
############################
# STEP 1 build executable binary
############################
FROM nvidia/cuda:12.8.1-devel-ubuntu24.04
COPY --from=golang:1.26 /usr/local/go/ /usr/local/go/
ENV PATH=/usr/local/go/bin:$PATH
RUN apt update && apt install -y git
WORKDIR /src
COPY go.* ./
RUN go mod download
COPY . ./
RUN cd common/blas/cublas && make
RUN --mount=type=cache,target=/root/.cache/go-build \
cd cmd/gorse-server && \
go build -tags xla -ldflags=" \
-X 'github.com/gorse-io/gorse/cmd/version.Version=$(git describe --tags $(git rev-parse HEAD))' \
-X 'github.com/gorse-io/gorse/cmd/version.GitCommit=$(git rev-parse HEAD)' \
-X 'github.com/gorse-io/gorse/cmd/version.BuildTime=$(date)' \
-X 'github.com/gorse-io/gorse/config.RootDir=/var/lib/gorse'" .
############################
# STEP 2 build runtime image
############################
FROM nvidia/cuda:12.8.1-runtime-ubuntu24.04
COPY --from=0 /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=0 /src/cmd/gorse-server/gorse-server /usr/bin/gorse-server
RUN /usr/bin/gorse-server --version
ENV USER=root
ENTRYPOINT ["/usr/bin/gorse-server"]
================================================
FILE: cmd/gorse-server/Dockerfile.mkl
================================================
# syntax = docker/dockerfile:1
############################
# STEP 1 build executable binary
############################
FROM golang:1.26-bookworm
# Install Intel® oneAPI Toolkits
RUN apt update && apt install -y wget gnupg2 git
RUN wget -O- https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB \
| gpg --dearmor | tee /usr/share/keyrings/oneapi-archive-keyring.gpg > /dev/null
RUN echo "deb [signed-by=/usr/share/keyrings/oneapi-archive-keyring.gpg] https://apt.repos.intel.com/oneapi all main" | tee /etc/apt/sources.list.d/oneAPI.list
RUN apt update && apt install -y intel-oneapi-base-toolkit
# Build Gorse
WORKDIR /src
COPY go.* ./
RUN go mod download
COPY . ./
RUN --mount=type=cache,target=/root/.cache/go-build \
. /opt/intel/oneapi/setvars.sh && \
cd cmd/gorse-server && \
go build -tags mkl -ldflags=" \
-X 'github.com/gorse-io/gorse/cmd/version.Version=$(git describe --tags $(git rev-parse HEAD))' \
-X 'github.com/gorse-io/gorse/cmd/version.GitCommit=$(git rev-parse HEAD)' \
-X 'github.com/gorse-io/gorse/cmd/version.BuildTime=$(date)' \
-X 'github.com/gorse-io/gorse/config.RootDir=/var/lib/gorse'" .
############################
# STEP 2 build runtime image
############################
FROM debian:bookworm-slim
RUN apt update && apt install -y ca-certificates && rm -rf /var/lib/apt/lists/*
COPY --from=0 /src/cmd/gorse-server/gorse-server /usr/bin/gorse-server
RUN /usr/bin/gorse-server --version
ENV USER=root
ENTRYPOINT ["/usr/bin/gorse-server"]
================================================
FILE: cmd/gorse-server/Dockerfile.openblas
================================================
# syntax = docker/dockerfile:1
############################
# STEP 1 build executable binary
############################
FROM --platform=$BUILDPLATFORM golang:1.26
# Install OpenBLAS
ARG BUILDARCH
ARG TARGETARCH
RUN if [ "${TARGETARCH}" = "amd64" ]; then \
dpkg --add-architecture ${TARGETARCH} && apt update && apt install -y gcc-x86-64-linux-gnu libopenblas-dev:${TARGETARCH} git; \
elif [ "${TARGETARCH}" = "arm64" ]; then \
dpkg --add-architecture ${TARGETARCH} && apt update && apt install -y gcc-aarch64-linux-gnu libopenblas-dev:${TARGETARCH} git; \
elif [ "${TARGETARCH}" = "riscv64" ]; then \
dpkg --add-architecture ${TARGETARCH} && apt update && apt install -y gcc-riscv64-linux-gnu libopenblas-dev:${TARGETARCH} git; \
elif [ "${TARGETARCH}" = "ppc64le" ]; then \
dpkg --add-architecture ppc64el && apt update && apt install -y gcc-powerpc64le-linux-gnu libopenblas-dev:ppc64el git; \
elif [ "${TARGETARCH}" = "s390x" ]; then \
dpkg --add-architecture ${TARGETARCH} && apt update && apt install -y gcc-s390x-linux-gnu libopenblas-dev:${TARGETARCH} git; \
elif [ "${TARGETARCH}" = "loong64" ]; then \
dpkg --add-architecture ${TARGETARCH} && apt update && apt install -y gcc-loongarch64-linux-gnu libopenblas-dev:${TARGETARCH} git; \
else \
echo "Unsupported TARGETARCH ${TARGETARCH}"; exit 1; \
fi
# Build Gorse
WORKDIR /src
COPY go.* ./
RUN go mod download
COPY . ./
ARG TARGETOS
RUN --mount=type=cache,target=/root/.cache/go-build \
if [ "${TARGETARCH}" = "amd64" ]; then \
export CC=x86_64-linux-gnu-gcc; \
elif [ "${TARGETARCH}" = "arm64" ]; then \
export CC=aarch64-linux-gnu-gcc; \
elif [ "${TARGETARCH}" = "riscv64" ]; then \
export CC=riscv64-linux-gnu-gcc; \
elif [ "${TARGETARCH}" = "ppc64le" ]; then \
export CC=powerpc64le-linux-gnu-gcc; \
elif [ "${TARGETARCH}" = "s390x" ]; then \
export CC=s390x-linux-gnu-gcc; \
elif [ "${TARGETARCH}" = "loong64" ]; then \
export CC=loongarch64-linux-gnu-gcc; \
else \
echo "Unsupported TARGETARCH ${TARGETARCH}"; exit 1; \
fi && \
cd cmd/gorse-server && \
GOOS=${TARGETOS} GOARCH=${TARGETARCH} CGO_ENABLED=1 go build -tags openblas -ldflags=" \
-X 'github.com/gorse-io/gorse/cmd/version.Version=$(git describe --tags $(git rev-parse HEAD))' \
-X 'github.com/gorse-io/gorse/cmd/version.GitCommit=$(git rev-parse HEAD)' \
-X 'github.com/gorse-io/gorse/cmd/version.BuildTime=$(date)' \
-X 'github.com/gorse-io/gorse/config.RootDir=/var/lib/gorse'" .
############################
# STEP 2 build runtime image
############################
FROM debian:trixie-slim
RUN apt update && apt install -y ca-certificates && rm -rf /var/lib/apt/lists/*
COPY --from=0 /src/cmd/gorse-server/gorse-server /usr/bin/gorse-server
RUN /usr/bin/gorse-server --version
ENV USER=root
ENTRYPOINT ["/usr/bin/gorse-server"]
================================================
FILE: cmd/gorse-server/Dockerfile.windows
================================================
############################
# STEP 1 build executable binary
############################
FROM golang:1.26
WORKDIR /src
COPY . ./
ENV CGO_ENABLED=0
RUN go build -o / -ldflags="\" \
-X 'github.com/gorse-io/gorse/cmd/version.Version=$(git describe --tags $(git rev-parse HEAD))' \
-X 'github.com/gorse-io/gorse/cmd/version.GitCommit=$(git rev-parse HEAD)' \
-X 'github.com/gorse-io/gorse/cmd/version.BuildTime=$(date)'\"" ./cmd/...
############################
# STEP 2 build a small image
############################
FROM mcr.microsoft.com/windows/servercore:ltsc2022
COPY --from=0 /gorse-server.exe /gorse-server.exe
RUN /gorse-server.exe --version
ENTRYPOINT [ "/gorse-server.exe" ]
================================================
FILE: cmd/gorse-server/main.go
================================================
// Copyright 2020 gorse Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"fmt"
"os"
"os/signal"
"github.com/gorse-io/gorse/cmd/version"
"github.com/gorse-io/gorse/common/log"
"github.com/gorse-io/gorse/common/util"
"github.com/gorse-io/gorse/server"
"github.com/spf13/cobra"
"go.uber.org/zap"
)
var serverCommand = &cobra.Command{
Use: "gorse-server",
Short: "The server node of gorse recommender system.",
Run: func(cmd *cobra.Command, args []string) {
// show version
showVersion, _ := cmd.PersistentFlags().GetBool("version")
if showVersion {
fmt.Println(version.BuildInfo())
return
}
// setup logger
debug, _ := cmd.PersistentFlags().GetBool("debug")
log.SetLogger(cmd.PersistentFlags(), debug)
// create server
masterPort, _ := cmd.PersistentFlags().GetInt("master-port")
masterHost, _ := cmd.PersistentFlags().GetString("master-host")
httpPort, _ := cmd.PersistentFlags().GetInt("http-port")
httpHost, _ := cmd.PersistentFlags().GetString("http-host")
cachePath, _ := cmd.PersistentFlags().GetString("cache-path")
caFile, _ := cmd.PersistentFlags().GetString("ssl-ca")
certFile, _ := cmd.PersistentFlags().GetString("ssl-cert")
keyFile, _ := cmd.PersistentFlags().GetString("ssl-key")
var tlsConfig *util.TLSConfig
if caFile != "" && certFile != "" && keyFile != "" {
tlsConfig = &util.TLSConfig{
SSLCA: caFile,
SSLCert: certFile,
SSLKey: keyFile,
}
} else if caFile == "" && certFile == "" && keyFile == "" {
tlsConfig = nil
} else {
log.Logger().Fatal("incomplete SSL configuration",
zap.String("ssl_ca", caFile),
zap.String("ssl_cert", certFile),
zap.String("ssl_key", keyFile))
}
s := server.NewServer(masterHost, masterPort, httpHost, httpPort, cachePath, tlsConfig)
// stop server
done := make(chan struct{})
go func() {
sigint := make(chan os.Signal, 1)
signal.Notify(sigint, os.Interrupt)
<-sigint
s.Shutdown()
close(done)
}()
// start server
s.Serve()
<-done
log.Logger().Info("stop gorse server successfully")
},
}
func init() {
log.AddFlags(serverCommand.PersistentFlags())
serverCommand.PersistentFlags().BoolP("version", "v", false, "gorse version")
serverCommand.PersistentFlags().Int("master-port", 8086, "port of master node")
serverCommand.PersistentFlags().String("master-host", "127.0.0.1", "host of master node")
serverCommand.PersistentFlags().Int("http-port", 8087, "host for RESTful APIs and Prometheus metrics export")
serverCommand.PersistentFlags().String("http-host", "127.0.0.1", "port for RESTful APIs and Prometheus metrics export")
serverCommand.PersistentFlags().Bool("debug", false, "use debug log mode")
serverCommand.PersistentFlags().String("cache-path", "server_cache.data", "path of cache file")
serverCommand.PersistentFlags().String("ssl-ca", "", "path of SSL CA")
serverCommand.PersistentFlags().String("ssl-cert", "", "path of SSL certificate")
serverCommand.PersistentFlags().String("ssl-key", "", "path of SSL key")
}
func main() {
if err := serverCommand.Execute(); err != nil {
log.Logger().Fatal("failed to execute", zap.Error(err))
}
}
================================================
FILE: cmd/gorse-worker/Dockerfile
================================================
# syntax = docker/dockerfile:1
############################
# STEP 1 build executable binary
############################
FROM --platform=$BUILDPLATFORM golang:1.26
WORKDIR /src
COPY go.* ./
RUN go mod download
COPY . ./
ARG TARGETOS
ARG TARGETARCH
RUN --mount=type=cache,target=/root/.cache/go-build \
cd cmd/gorse-worker && \
GOOS=${TARGETOS} GOARCH=${TARGETARCH} CGO_ENABLED=0 go build -ldflags=" \
-X 'github.com/gorse-io/gorse/cmd/version.Version=$(git describe --tags $(git rev-parse HEAD))' \
-X 'github.com/gorse-io/gorse/cmd/version.GitCommit=$(git rev-parse HEAD)' \
-X 'github.com/gorse-io/gorse/cmd/version.BuildTime=$(date)' \
-X 'github.com/gorse-io/gorse/config.RootDir=/var/lib/gorse'" .
############################
# STEP 2 build a small image
############################
FROM scratch
COPY --from=0 /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=0 /src/cmd/gorse-worker/gorse-worker /usr/bin/gorse-worker
ENV USER=root
ENTRYPOINT ["/usr/bin/gorse-worker"]
================================================
FILE: cmd/gorse-worker/Dockerfile.cuda
================================================
# syntax = docker/dockerfile:1
############################
# STEP 1 build executable binary
############################
FROM nvidia/cuda:12.8.1-devel-ubuntu24.04
COPY --from=golang:1.26 /usr/local/go/ /usr/local/go/
ENV PATH=/usr/local/go/bin:$PATH
RUN apt update && apt install -y git
WORKDIR /src
COPY go.* ./
RUN go mod download
COPY . ./
RUN cd common/blas/cublas && make
RUN --mount=type=cache,target=/root/.cache/go-build \
cd cmd/gorse-worker && \
go build -tags xla -ldflags=" \
-X 'github.com/gorse-io/gorse/cmd/version.Version=$(git describe --tags $(git rev-parse HEAD))' \
-X 'github.com/gorse-io/gorse/cmd/version.GitCommit=$(git rev-parse HEAD)' \
-X 'github.com/gorse-io/gorse/cmd/version.BuildTime=$(date)' \
-X 'github.com/gorse-io/gorse/config.RootDir=/var/lib/gorse'" .
############################
# STEP 2 build runtime image
############################
FROM nvidia/cuda:12.8.1-runtime-ubuntu24.04
COPY --from=0 /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=0 /src/cmd/gorse-worker/gorse-worker /usr/bin/gorse-worker
RUN /usr/bin/gorse-worker --version
ENV USER=root
ENTRYPOINT ["/usr/bin/gorse-worker"]
================================================
FILE: cmd/gorse-worker/Dockerfile.mkl
================================================
# syntax = docker/dockerfile:1
############################
# STEP 1 build executable binary
############################
FROM golang:1.26-bookworm
# Install Intel® oneAPI Toolkits
RUN apt update && apt install -y wget gnupg2 git
RUN wget -O- https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB \
| gpg --dearmor | tee /usr/share/keyrings/oneapi-archive-keyring.gpg > /dev/null
RUN echo "deb [signed-by=/usr/share/keyrings/oneapi-archive-keyring.gpg] https://apt.repos.intel.com/oneapi all main" | tee /etc/apt/sources.list.d/oneAPI.list
RUN apt update && apt install -y intel-oneapi-base-toolkit
# Build Gorse
WORKDIR /src
COPY go.* ./
RUN go mod download
COPY . ./
RUN --mount=type=cache,target=/root/.cache/go-build \
. /opt/intel/oneapi/setvars.sh && \
cd cmd/gorse-worker && \
go build -tags mkl -ldflags=" \
-X 'github.com/gorse-io/gorse/cmd/version.Version=$(git describe --tags $(git rev-parse HEAD))' \
-X 'github.com/gorse-io/gorse/cmd/version.GitCommit=$(git rev-parse HEAD)' \
-X 'github.com/gorse-io/gorse/cmd/version.BuildTime=$(date)' \
-X 'github.com/gorse-io/gorse/config.RootDir=/var/lib/gorse'" .
############################
# STEP 2 build runtime image
############################
FROM debian:bookworm-slim
RUN apt update && apt install -y ca-certificates && rm -rf /var/lib/apt/lists/*
COPY --from=0 /src/cmd/gorse-worker/gorse-worker /usr/bin/gorse-worker
RUN /usr/bin/gorse-worker --version
ENV USER=root
ENTRYPOINT ["/usr/bin/gorse-worker"]
================================================
FILE: cmd/gorse-worker/Dockerfile.openblas
================================================
# syntax = docker/dockerfile:1
############################
# STEP 1 build executable binary
############################
FROM --platform=$BUILDPLATFORM golang:1.26
# Install OpenBLAS
ARG BUILDARCH
ARG TARGETARCH
RUN if [ "${TARGETARCH}" = "amd64" ]; then \
dpkg --add-architecture ${TARGETARCH} && apt update && apt install -y gcc-x86-64-linux-gnu libopenblas-dev:${TARGETARCH} git; \
elif [ "${TARGETARCH}" = "arm64" ]; then \
dpkg --add-architecture ${TARGETARCH} && apt update && apt install -y gcc-aarch64-linux-gnu libopenblas-dev:${TARGETARCH} git; \
elif [ "${TARGETARCH}" = "riscv64" ]; then \
dpkg --add-architecture ${TARGETARCH} && apt update && apt install -y gcc-riscv64-linux-gnu libopenblas-dev:${TARGETARCH} git; \
elif [ "${TARGETARCH}" = "ppc64le" ]; then \
dpkg --add-architecture ppc64el && apt update && apt install -y gcc-powerpc64le-linux-gnu libopenblas-dev:ppc64el git; \
elif [ "${TARGETARCH}" = "s390x" ]; then \
dpkg --add-architecture ${TARGETARCH} && apt update && apt install -y gcc-s390x-linux-gnu libopenblas-dev:${TARGETARCH} git; \
elif [ "${TARGETARCH}" = "loong64" ]; then \
dpkg --add-architecture ${TARGETARCH} && apt update && apt install -y gcc-loongarch64-linux-gnu libopenblas-dev:${TARGETARCH} git; \
else \
echo "Unsupported TARGETARCH ${TARGETARCH}"; exit 1; \
fi
# Build Gorse
WORKDIR /src
COPY go.* ./
RUN go mod download
COPY . ./
ARG TARGETOS
RUN --mount=type=cache,target=/root/.cache/go-build \
if [ "${TARGETARCH}" = "amd64" ]; then \
export CC=x86_64-linux-gnu-gcc; \
elif [ "${TARGETARCH}" = "arm64" ]; then \
export CC=aarch64-linux-gnu-gcc; \
elif [ "${TARGETARCH}" = "riscv64" ]; then \
export CC=riscv64-linux-gnu-gcc; \
elif [ "${TARGETARCH}" = "ppc64le" ]; then \
export CC=powerpc64le-linux-gnu-gcc; \
elif [ "${TARGETARCH}" = "s390x" ]; then \
export CC=s390x-linux-gnu-gcc; \
elif [ "${TARGETARCH}" = "loong64" ]; then \
export CC=loongarch64-linux-gnu-gcc; \
else \
echo "Unsupported TARGETARCH ${TARGETARCH}"; exit 1; \
fi && \
cd cmd/gorse-worker && \
GOOS=${TARGETOS} GOARCH=${TARGETARCH} CGO_ENABLED=1 go build -tags openblas -ldflags=" \
-X 'github.com/gorse-io/gorse/cmd/version.Version=$(git describe --tags $(git rev-parse HEAD))' \
-X 'github.com/gorse-io/gorse/cmd/version.GitCommit=$(git rev-parse HEAD)' \
-X 'github.com/gorse-io/gorse/cmd/version.BuildTime=$(date)' \
-X 'github.com/gorse-io/gorse/config.RootDir=/var/lib/gorse'" .
############################
# STEP 2 build runtime image
############################
FROM debian:trixie-slim
RUN apt update && apt install -y ca-certificates && rm -rf /var/lib/apt/lists/*
COPY --from=0 /src/cmd/gorse-worker/gorse-worker /usr/bin/gorse-worker
RUN /usr/bin/gorse-worker --version
ENV USER=root
ENTRYPOINT ["/usr/bin/gorse-worker"]
================================================
FILE: cmd/gorse-worker/Dockerfile.windows
================================================
############################
# STEP 1 build executable binary
############################
FROM golang:1.26
WORKDIR /src
COPY . ./
ENV CGO_ENABLED=0
RUN go build -o / -ldflags="\" \
-X 'github.com/gorse-io/gorse/cmd/version.Version=$(git describe --tags $(git rev-parse HEAD))' \
-X 'github.com/gorse-io/gorse/cmd/version.GitCommit=$(git rev-parse HEAD)' \
-X 'github.com/gorse-io/gorse/cmd/version.BuildTime=$(date)'\"" ./cmd/...
############################
# STEP 2 build a small image
############################
FROM mcr.microsoft.com/windows/servercore:ltsc2022
COPY --from=0 /gorse-worker.exe /gorse-worker.exe
RUN /gorse-worker.exe --version
ENTRYPOINT [ "/gorse-worker.exe" ]
================================================
FILE: cmd/gorse-worker/main.go
================================================
// Copyright 2020 gorse Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"fmt"
_ "net/http/pprof"
"time"
"github.com/gorse-io/gorse/cmd/version"
"github.com/gorse-io/gorse/common/log"
"github.com/gorse-io/gorse/common/util"
"github.com/gorse-io/gorse/worker"
"github.com/spf13/cobra"
"go.uber.org/zap"
)
var workerCommand = &cobra.Command{
Use: "gorse-worker",
Short: "The worker node of gorse recommender system.",
Run: func(cmd *cobra.Command, args []string) {
// show version
showVersion, _ := cmd.PersistentFlags().GetBool("version")
if showVersion {
fmt.Println(version.BuildInfo())
return
}
masterHost, _ := cmd.PersistentFlags().GetString("master-host")
masterPort, _ := cmd.PersistentFlags().GetInt("master-port")
httpHost, _ := cmd.PersistentFlags().GetString("http-host")
httpPort, _ := cmd.PersistentFlags().GetInt("http-port")
workingJobs, _ := cmd.PersistentFlags().GetInt("jobs")
// setup logger
debug, _ := cmd.PersistentFlags().GetBool("debug")
log.SetLogger(cmd.PersistentFlags(), debug)
// create worker
cachePath, _ := cmd.PersistentFlags().GetString("cache-path")
caFile, _ := cmd.PersistentFlags().GetString("ssl-ca")
certFile, _ := cmd.PersistentFlags().GetString("ssl-cert")
keyFile, _ := cmd.PersistentFlags().GetString("ssl-key")
var tlsConfig *util.TLSConfig
if caFile != "" && certFile != "" && keyFile != "" {
tlsConfig = &util.TLSConfig{
SSLCA: caFile,
SSLCert: certFile,
SSLKey: keyFile,
}
} else if caFile == "" && certFile == "" && keyFile == "" {
tlsConfig = nil
} else {
log.Logger().Fatal("incomplete SSL configuration",
zap.String("ssl_ca", caFile),
zap.String("ssl_cert", certFile),
zap.String("ssl_key", keyFile))
}
interval, _ := cmd.PersistentFlags().GetDuration("interval")
w := worker.NewWorker(masterHost, masterPort, httpHost, httpPort, workingJobs, cachePath, tlsConfig, interval)
w.Serve()
},
}
func init() {
log.AddFlags(workerCommand.PersistentFlags())
workerCommand.PersistentFlags().BoolP("version", "v", false, "gorse version")
workerCommand.PersistentFlags().String("master-host", "127.0.0.1", "host of master node")
workerCommand.PersistentFlags().Int("master-port", 8086, "port of master node")
workerCommand.PersistentFlags().String("http-host", "127.0.0.1", "host for Prometheus metrics export")
workerCommand.PersistentFlags().Int("http-port", 8089, "port for Prometheus metrics export")
workerCommand.PersistentFlags().Bool("debug", false, "use debug log mode")
workerCommand.PersistentFlags().IntP("jobs", "j", 1, "number of working jobs.")
workerCommand.PersistentFlags().String("cache-path", "worker_cache.data", "path of cache file")
workerCommand.PersistentFlags().String("ssl-ca", "", "path of SSL CA")
workerCommand.PersistentFlags().String("ssl-cert", "", "path to SSL certificate")
workerCommand.PersistentFlags().String("ssl-key", "", "path to SSL key")
workerCommand.PersistentFlags().Duration("interval", time.Minute, "interval between checking users")
}
func main() {
if err := workerCommand.Execute(); err != nil {
log.Logger().Fatal("failed to execute", zap.Error(err))
}
}
================================================
FILE: cmd/version/version.go
================================================
package version
import (
"fmt"
"runtime"
)
// Default build-time variable.
// These values are overridden via ldflags
var (
Version = "unknown-version"
GitCommit = "unknown-commit"
BuildTime = "unknown-buildtime"
APIVersion = "v0.2.7"
)
func BuildInfo() string {
var buildInfo string
buildInfo += fmt.Sprintln("Version:\t", Version)
buildInfo += fmt.Sprintln("API version:\t", APIVersion)
buildInfo += fmt.Sprintln("Go version:\t", runtime.Version())
buildInfo += fmt.Sprintln("Git commit:\t", GitCommit)
buildInfo += fmt.Sprintln("Built:\t\t", BuildTime)
buildInfo += fmt.Sprintf("OS/Arch:\t %s/%s\n", runtime.GOOS, runtime.GOARCH)
return buildInfo
}
================================================
FILE: codecov.yml
================================================
coverage:
status:
patch:
default:
enabled: no
ignore:
- "protocol/*.pb.go"
- "cmd/**"
================================================
FILE: common/ann/ann.go
================================================
// Copyright 2024 gorse Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package ann
import (
"github.com/samber/lo"
)
type Index interface {
Add(v []float32) int
SearchIndex(q, k int, prune0 bool) ([]lo.Tuple2[int, float32], error)
SearchVector(q []float32, k int, prune0 bool) []lo.Tuple2[int, float32]
}
================================================
FILE: common/ann/ann_test.go
================================================
// Copyright 2024 gorse Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package ann
import (
"bufio"
"os"
"path/filepath"
"strconv"
"strings"
"sync"
"testing"
mapset "github.com/deckarep/golang-set/v2"
"github.com/gorse-io/gorse/common/datautil"
"github.com/gorse-io/gorse/common/floats"
"github.com/gorse-io/gorse/common/util"
"github.com/samber/lo"
"github.com/stretchr/testify/assert"
"go.uber.org/atomic"
)
const (
trainSize = 6000
testSize = 1000
)
func recall(gt, pred []lo.Tuple2[int, float32]) float64 {
s := mapset.NewSet[int]()
for _, pair := range gt {
s.Add(pair.A)
}
hit := 0
for _, pair := range pred {
if s.Contains(pair.A) {
hit++
}
}
return float64(hit) / float64(len(gt))
}
type MNIST struct {
TrainImages [][]float32
TrainLabels []uint8
TestImages [][]float32
TestLabels []uint8
}
func mnist() (*MNIST, error) {
// Download and unzip dataset
path, err := datautil.DownloadAndUnzip("mnist")
if err != nil {
return nil, err
}
// Open dataset
m := new(MNIST)
m.TrainImages, m.TrainLabels, err = m.openFile(filepath.Join(path, "train.libfm"))
if err != nil {
return nil, err
}
m.TestImages, m.TestLabels, err = m.openFile(filepath.Join(path, "test.libfm"))
if err != nil {
return nil, err
}
return m, nil
}
func (m *MNIST) openFile(path string) ([][]float32, []uint8, error) {
// Open file
f, err := os.Open(path)
if err != nil {
return nil, nil, err
}
defer f.Close()
// Read data line by line
var (
images [][]float32
labels []uint8
)
scanner := bufio.NewScanner(f)
for scanner.Scan() {
line := scanner.Text()
splits := strings.Split(line, " ")
// Parse label
label, err := util.ParseUInt[uint8](splits[0])
if err != nil {
return nil, nil, err
}
labels = append(labels, label)
// Parse image
image := make([]float32, 784)
for _, split := range splits[1:] {
kv := strings.Split(split, ":")
index, err := strconv.Atoi(kv[0])
if err != nil {
return nil, nil, err
}
value, err := util.ParseFloat[float32](kv[1])
if err != nil {
return nil, nil, err
}
image[index] = value
}
images = append(images, image)
}
return images, labels, nil
}
func TestMNIST(t *testing.T) {
dat, err := mnist()
assert.NoError(t, err)
// Create brute-force index
bf := NewBruteforce(floats.Euclidean)
for _, image := range dat.TrainImages[:trainSize] {
_ = bf.Add(image)
}
// Create HNSW index
hnsw := NewHNSW(floats.Euclidean)
for _, image := range dat.TrainImages[:trainSize] {
_ = hnsw.Add(image)
}
// Test search
r := 0.0
for _, image := range dat.TestImages[:testSize] {
gt := bf.SearchVector(image, 100, false)
assert.Len(t, gt, 100)
scores := hnsw.SearchVector(image, 100, false)
assert.Len(t, scores, 100)
r += recall(gt, scores)
}
r /= float64(testSize)
assert.Greater(t, r, 0.99)
// Test save and load
path := filepath.Join(t.TempDir(), "mnist.bin")
f, err := os.Create(path)
assert.NoError(t, err)
defer f.Close()
assert.NoError(t, hnsw.Marshal(f))
f, err = os.Open(path)
assert.NoError(t, err)
defer f.Close()
assert.NoError(t, hnsw.Unmarshal(f))
r = 0
for _, image := range dat.TestImages[:testSize] {
gt := bf.SearchVector(image, 100, false)
assert.Len(t, gt, 100)
scores := hnsw.SearchVector(image, 100, false)
assert.Len(t, scores, 100)
r += recall(gt, scores)
}
r /= float64(testSize)
assert.Greater(t, r, 0.99)
}
func TestMultithread(t *testing.T) {
dat, err := mnist()
assert.NoError(t, err)
// Create HNSW index
indices := make([]int, trainSize)
hnsw := NewHNSW(floats.Euclidean)
var wg1 sync.WaitGroup
wg1.Add(trainSize)
for i := range dat.TrainImages[:trainSize] {
go func(i int) {
defer wg1.Done()
indices[i] = hnsw.Add(dat.TrainImages[i])
}(i)
}
wg1.Wait()
// Create brute-force index
reverse := make([]int, trainSize)
for i, index := range indices {
reverse[index] = i
}
bf := NewBruteforce(floats.Euclidean)
for i := range reverse {
_ = bf.Add(dat.TrainImages[reverse[i]])
}
// Test search
var r atomic.Float64
var wg2 sync.WaitGroup
wg2.Add(testSize)
for _, image := range dat.TestImages[:testSize] {
go func(image []float32) {
defer wg2.Done()
gt := bf.SearchVector(image, 100, false)
assert.Len(t, gt, 100)
scores := hnsw.SearchVector(image, 100, false)
assert.Len(t, scores, 100)
r.Add(recall(gt, scores))
}(image)
}
wg2.Wait()
assert.Greater(t, r.Load()/float64(testSize), 0.99)
}
func movieLens() ([][]int, error) {
// Download and unzip dataset
path, err := datautil.DownloadAndUnzip("ml-1m")
if err != nil {
return nil, err
}
// Open file
f, err := os.Open(filepath.Join(path, "train.txt"))
if err != nil {
return nil, err
}
defer f.Close()
// Read data line by line
movies := make([][]int, 0)
scanner := bufio.NewScanner(f)
for scanner.Scan() {
line := scanner.Text()
splits := strings.Split(line, "\t")
userId, err := strconv.Atoi(splits[0])
if err != nil {
return nil, err
}
movieId, err := strconv.Atoi(splits[1])
if err != nil {
return nil, err
}
for movieId >= len(movies) {
movies = append(movies, make([]int, 0))
}
movies[movieId] = append(movies[movieId], userId)
}
return movies, nil
}
func jaccard(a, b []int) float32 {
var i, j, intersection int
for i < len(a) && j < len(b) {
if a[i] == b[j] {
intersection++
i++
j++
} else if a[i] < b[j] {
i++
} else {
j++
}
}
if len(a)+len(b)-intersection == 0 {
return 1
}
return 1 - float32(intersection)/float32(len(a)+len(b)-intersection)
}
func TestMovieLens(t *testing.T) {
movies, err := movieLens()
assert.NoError(t, err)
// Create brute-force index
bf := NewBruteforce(jaccard)
for _, movie := range movies {
_ = bf.Add(movie)
}
// Create HNSW index
hnsw := NewHNSW(jaccard)
for _, movie := range movies {
_ = hnsw.Add(movie)
}
// Test search
r := 0.0
for i := range movies[:testSize] {
gt, err := bf.SearchIndex(i, 100, false)
assert.NoError(t, err)
scores, err := hnsw.SearchIndex(i, 100, false)
assert.NoError(t, err)
r += recall(gt, scores)
}
r /= float64(testSize)
assert.Greater(t, r, 0.98)
}
================================================
FILE: common/ann/bruteforce.go
================================================
// Copyright 2024 gorse Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package ann
import (
"github.com/gorse-io/gorse/common/heap"
"github.com/juju/errors"
"github.com/samber/lo"
)
// Bruteforce is a naive implementation of vector index.
type Bruteforce[T any] struct {
distanceFunc func(a, b T) float32
vectors []T
}
func NewBruteforce[T any](distanceFunc func(a, b T) float32) *Bruteforce[T] {
return &Bruteforce[T]{distanceFunc: distanceFunc}
}
func (b *Bruteforce[T]) Add(v T) int {
// Add vector
b.vectors = append(b.vectors, v)
return len(b.vectors)
}
func (b *Bruteforce[T]) SearchIndex(q, k int, prune0 bool) ([]lo.Tuple2[int, float32], error) {
// Check index
if q < 0 || q >= len(b.vectors) {
return nil, errors.Errorf("index out of range: %v", q)
}
// Search
pq := heap.NewPriorityQueue(true)
for i, vec := range b.vectors {
if i != q {
pq.Push(int32(i), b.distanceFunc(b.vectors[q], vec))
if pq.Len() > k {
pq.Pop()
}
}
}
pq = pq.Reverse()
scores := make([]lo.Tuple2[int, float32], 0)
for pq.Len() > 0 {
value, score := pq.Pop()
if !prune0 || score > 0 {
scores = append(scores, lo.Tuple2[int, float32]{A: int(value), B: score})
}
}
return scores, nil
}
func (b *Bruteforce[T]) SearchVector(q T, k int, prune0 bool) []lo.Tuple2[int, float32] {
// Search
pq := heap.NewPriorityQueue(true)
for i, vec := range b.vectors {
pq.Push(int32(i), b.distanceFunc(q, vec))
if pq.Len() > k {
pq.Pop()
}
}
pq = pq.Reverse()
scores := make([]lo.Tuple2[int, float32], 0)
for pq.Len() > 0 {
value, score := pq.Pop()
if !prune0 || score > 0 {
scores = append(scores, lo.Tuple2[int, float32]{A: int(value), B: score})
}
}
return scores
}
================================================
FILE: common/ann/hnsw.go
================================================
// Copyright 2024 gorse Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package ann
import (
"encoding/binary"
"io"
"math/rand"
"sync"
"github.com/chewxy/math32"
mapset "github.com/deckarep/golang-set/v2"
"github.com/gorse-io/gorse/common/encoding"
"github.com/gorse-io/gorse/common/heap"
"github.com/pkg/errors"
"github.com/samber/lo"
"modernc.org/mathutil"
)
// HNSW is a vector index based on Hierarchical Navigable Small Worlds.
type HNSW[T any] struct {
distanceFunc func(a, b T) float32
vectors []T
bottomNeighbors []*heap.PriorityQueue
upperNeighbors []sync.Map
enterPoint int32
initOnce sync.Once
indexMutex sync.Mutex
rootMutex sync.Mutex
bottomMutex []*sync.RWMutex
levelFactor float32
maxConnection int // maximum number of connections for each element per layer
maxConnection0 int
ef int
efConstruction int
}
func NewHNSW[T any](distanceFunc func(a, b T) float32) *HNSW[T] {
return &HNSW[T]{
distanceFunc: distanceFunc,
levelFactor: 1.0 / math32.Log(48),
maxConnection: 48,
maxConnection0: 96,
efConstruction: 100,
}
}
func (h *HNSW[T]) Add(v T) int {
// Add vector
h.indexMutex.Lock()
h.vectors = append(h.vectors, v)
h.bottomNeighbors = append(h.bottomNeighbors, heap.NewPriorityQueue(false))
h.bottomMutex = append(h.bottomMutex, new(sync.RWMutex))
q := len(h.vectors) - 1
h.indexMutex.Unlock()
h.insert(int32(q))
return q
}
func (h *HNSW[T]) SearchIndex(q, k int, prune0 bool) ([]lo.Tuple2[int, float32], error) {
// Check index
if q < 0 || q >= len(h.vectors) {
return nil, errors.Errorf("index out of range: %v", q)
}
w := h.knnSearch(h.vectors[q], k, h.efSearchValue(k))
scores := make([]lo.Tuple2[int, float32], 0)
for w.Len() > 0 {
value, score := w.Pop()
if !prune0 || score > 0 {
scores = append(scores, lo.Tuple2[int, float32]{A: int(value), B: score})
}
}
return scores, nil
}
func (h *HNSW[T]) SearchVector(q T, k int, prune0 bool) []lo.Tuple2[int, float32] {
w := h.knnSearch(q, k, h.efSearchValue(k))
scores := make([]lo.Tuple2[int, float32], 0)
for w.Len() > 0 {
value, score := w.Pop()
if !prune0 || score > 0 {
scores = append(scores, lo.Tuple2[int, float32]{A: int(value), B: score})
}
}
return scores
}
func (h *HNSW[T]) knnSearch(q T, k, ef int) *heap.PriorityQueue {
var (
w *heap.PriorityQueue // set for the current the nearest element
enterPoints = h.distance(q, []int32{h.enterPoint}) // get enter point for hnsw
topLayer = len(h.upperNeighbors) // top layer for hnsw
)
for currentLayer := topLayer; currentLayer > 0; currentLayer-- {
w = h.searchLayer(q, enterPoints, 1, currentLayer)
enterPoints = heap.NewPriorityQueue(false)
enterPoints.Push(w.Peek())
}
w = h.searchLayer(q, enterPoints, ef, 0)
return h.selectNeighbors(q, w, k)
}
// insert i-th vector into the vector index.
func (h *HNSW[T]) insert(q int32) {
// insert first point
var isFirstPoint bool
h.initOnce.Do(func() {
if h.upperNeighbors == nil {
h.bottomNeighbors[q] = heap.NewPriorityQueue(false)
h.upperNeighbors = make([]sync.Map, 0)
h.enterPoint = q
isFirstPoint = true
return
}
})
if isFirstPoint {
return
}
h.rootMutex.Lock()
var (
w *heap.PriorityQueue // list for the currently found nearest elements
enterPoints = h.distance(h.vectors[q], []int32{h.enterPoint}) // get enter point for hnsw
l = int(math32.Floor(-math32.Log(rand.Float32()) * h.levelFactor))
topLayer = len(h.upperNeighbors)
)
if l <= topLayer {
h.rootMutex.Unlock()
} else {
defer h.rootMutex.Unlock()
}
for currentLayer := topLayer; currentLayer >= l+1; currentLayer-- {
w = h.searchLayer(h.vectors[q], enterPoints, 1, currentLayer)
enterPoints = h.selectNeighbors(h.vectors[q], w, 1)
}
h.bottomMutex[q].Lock()
for currentLayer := mathutil.Min(topLayer, l); currentLayer >= 0; currentLayer-- {
w = h.searchLayer(h.vectors[q], enterPoints, h.efConstruction, currentLayer)
neighbors := h.selectNeighbors(h.vectors[q], w, h.maxConnection)
// add bidirectional connections from upperNeighbors to q at layer l_c
h.setNeighbourhood(q, currentLayer, neighbors)
for _, e := range neighbors.Elems() {
h.bottomMutex[e.Value].Lock()
h.getNeighbourhood(e.Value, currentLayer).Push(q, e.Weight)
connections := h.getNeighbourhood(e.Value, currentLayer)
var currentMaxConnection int
if currentLayer == 0 {
currentMaxConnection = h.maxConnection0
} else {
currentMaxConnection = h.maxConnection
}
if connections.Len() > currentMaxConnection {
// shrink connections of e if lc = 0 then M_max = M_max0
newConnections := h.selectNeighbors(h.vectors[q], connections, h.maxConnection)
h.setNeighbourhood(e.Value, currentLayer, newConnections)
}
h.bottomMutex[e.Value].Unlock()
}
enterPoints = w
}
h.bottomMutex[q].Unlock()
if l > topLayer {
// set enter point for hnsw to q
h.enterPoint = q
h.upperNeighbors = append(h.upperNeighbors, sync.Map{})
h.setNeighbourhood(q, topLayer+1, heap.NewPriorityQueue(false))
}
}
func (h *HNSW[T]) searchLayer(q T, enterPoints *heap.PriorityQueue, ef, currentLayer int) *heap.PriorityQueue {
var (
v = mapset.NewSet(enterPoints.Values()...) // set of visited elements
candidates = enterPoints.Clone() // set of candidates
w = enterPoints.Reverse() // dynamic list of found nearest upperNeighbors
)
for candidates.Len() > 0 {
// extract nearest element from candidates to q
c, cq := candidates.Pop()
// get the furthest element from w to q
_, fq := w.Peek()
if cq > fq {
break // all elements in w are evaluated
}
// update candidates and w
h.bottomMutex[c].RLock()
neighbors := h.getNeighbourhood(c, currentLayer).Values()
h.bottomMutex[c].RUnlock()
for _, e := range neighbors {
if !v.Contains(e) {
v.Add(e)
// get the furthest element from w to q
_, fq = w.Peek()
if eq := h.distanceFunc(h.vectors[e], q); eq < fq || w.Len() < ef {
candidates.Push(e, eq)
w.Push(e, eq)
if w.Len() > ef {
// remove the furthest element from w to q
w.Pop()
}
}
}
}
}
return w.Reverse()
}
func (h *HNSW[T]) setNeighbourhood(e int32, currentLayer int, connections *heap.PriorityQueue) {
if currentLayer == 0 {
h.bottomNeighbors[e] = connections
} else {
h.upperNeighbors[currentLayer-1].Store(e, connections)
}
}
func (h *HNSW[T]) getNeighbourhood(e int32, currentLayer int) *heap.PriorityQueue {
if currentLayer == 0 {
return h.bottomNeighbors[e]
} else {
if connections, ok := h.upperNeighbors[currentLayer-1].Load(e); ok {
return connections.(*heap.PriorityQueue)
}
return nil
}
}
func (h *HNSW[T]) selectNeighbors(_ T, candidates *heap.PriorityQueue, m int) *heap.PriorityQueue {
pq := candidates.Reverse()
for pq.Len() > m {
pq.Pop()
}
return pq.Reverse()
}
func (h *HNSW[T]) distance(q T, points []int32) *heap.PriorityQueue {
pq := heap.NewPriorityQueue(false)
for _, point := range points {
pq.Push(point, h.distanceFunc(h.vectors[point], q))
}
return pq
}
// efSearchValue returns the efSearch value to use, given the current number of elements desired.
func (h *HNSW[T]) efSearchValue(n int) int {
if h.ef > 0 {
return mathutil.Max(h.ef, n)
}
return mathutil.Max(h.efConstruction, n)
}
func (h *HNSW[T]) Marshal(w io.Writer) error {
if err := binary.Write(w, binary.LittleEndian, h.levelFactor); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, int64(h.maxConnection)); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, int64(h.maxConnection0)); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, int64(h.ef)); err != nil {
return err
}
if err := binary.Write(w, binary.LittleEndian, int64(h.efConstruction)); err != nil {
return err
}
// save vectors
numVectors := int64(len(h.vectors))
if err := binary.Write(w, binary.LittleEndian, numVectors); err != nil {
return err
}
for i := int64(0); i < numVectors; i++ {
if err := encoding.WriteGob(w, h.vectors[i]); err != nil {
return err
}
}
// save neighbors
for i := int64(0); i < numVectors; i++ {
if err := h.bottomNeighbors[i].Marshal(w); err != nil {
return err
}
}
numLayers := len(h.upperNeighbors)
if err := binary.Write(w, binary.LittleEndian, int64(numLayers)); err != nil {
return err
}
for i := 0; i < numLayers; i++ {
var elements []lo.Tuple2[int32, *heap.PriorityQueue]
h.upperNeighbors[i].Range(func(key, value any) bool {
elements = append(elements, lo.Tuple2[int32, *heap.PriorityQueue]{
A: key.(int32), B: value.(*heap.PriorityQueue)})
return true
})
numElements := int32(len(elements))
if err := binary.Write(w, binary.LittleEndian, numElements); err != nil {
return err
}
for j := int32(0); j < numElements; j++ {
if err := binary.Write(w, binary.LittleEndian, elements[j].A); err != nil {
return err
}
if err := elements[j].B.Marshal(w); err != nil {
return err
}
}
}
if err := binary.Write(w, binary.LittleEndian, h.enterPoint); err != nil {
return err
}
return nil
}
func (h *HNSW[T]) Unmarshal(r io.Reader) error {
if err := binary.Read(r, binary.LittleEndian, &h.levelFactor); err != nil {
return err
}
var maxConnection int64
if err := binary.Read(r, binary.LittleEndian, &maxConnection); err != nil {
return err
}
h.maxConnection = int(maxConnection)
var maxConnection0 int64
if err := binary.Read(r, binary.LittleEndian, &maxConnection0); err != nil {
return err
}
h.maxConnection0 = int(maxConnection0)
var ef int64
if err := binary.Read(r, binary.LittleEndian, &ef); err != nil {
return err
}
h.ef = int(ef)
var efConstruction int64
if err := binary.Read(r, binary.LittleEndian, &efConstruction); err != nil {
return err
}
h.efConstruction = int(efConstruction)
// read vectors
var numVectors int64
if err := binary.Read(r, binary.LittleEndian, &numVectors); err != nil {
return errors.WithStack(err)
}
h.vectors = make([]T, numVectors)
for i := int64(0); i < numVectors; i++ {
if err := encoding.ReadGob(r, &h.vectors[i]); err != nil {
return errors.WithStack(err)
}
}
// save neighbors
h.bottomNeighbors = make([]*heap.PriorityQueue, numVectors)
for i := int64(0); i < numVectors; i++ {
h.bottomNeighbors[i] = heap.NewPriorityQueue(false)
if err := h.bottomNeighbors[i].Unmarshal(r); err != nil {
return errors.WithStack(err)
}
}
var numLayers int64
if err := binary.Read(r, binary.LittleEndian, &numLayers); err != nil {
return errors.WithStack(err)
}
h.upperNeighbors = make([]sync.Map, numLayers)
for i := int64(0); i < numLayers; i++ {
var numElements int32
if err := binary.Read(r, binary.LittleEndian, &numElements); err != nil {
return errors.WithStack(err)
}
for j := int32(0); j < numElements; j++ {
var e int32
if err := binary.Read(r, binary.LittleEndian, &e); err != nil {
return errors.WithStack(err)
}
pq := heap.NewPriorityQueue(false)
if err := pq.Unmarshal(r); err != nil {
return errors.WithStack(err)
}
h.upperNeighbors[i].Store(e, pq)
}
}
if err := binary.Read(r, binary.LittleEndian, &h.enterPoint); err != nil {
return errors.WithStack(err)
}
h.bottomMutex = make([]*sync.RWMutex, numVectors)
for i := int64(0); i < numVectors; i++ {
h.bottomMutex[i] = new(sync.RWMutex)
}
return nil
}
================================================
FILE: common/blas/blas.go
================================================
// Copyright 2025 gorse Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package blas
type Order int
const RowMajor Order = 101
type Transpose int
const (
NoTrans Transpose = 111
Trans Transpose = 112
)
func NewTranspose(transpose bool) Transpose {
if transpose {
return Trans
} else {
return NoTrans
}
}
================================================
FILE: common/blas/blas_darwin_arm64.go
================================================
//go:build cgo
// Copyright 2025 gorse Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package blas
// #cgo CFLAGS: -DACCELERATE_NEW_LAPACK
// #cgo LDFLAGS: -framework Accelerate
// #include <Accelerate/Accelerate.h>
import "C"
func SGEMM(order Order, transA, transB Transpose, m, n, k int, alpha float32, a []float32, lda int, b []float32, ldb int, beta float32, c []float32, ldc int) {
C.cblas_sgemm(uint32(order), uint32(transA), uint32(transB), C.int(m), C.int(n), C.int(k), C.float(alpha),
(*C.float)(&a[0]), C.int(lda), (*C.float)(&b[0]), C.int(ldb), C.float(beta), (*C.float)(&c[0]), C.int(ldc))
}
================================================
FILE: common/blas/blas_mkl.go
================================================
//go:build cgo && mkl
// Copyright 2025 gorse Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package blas
// #cgo CFLAGS: -I/opt/intel/oneapi/mkl/latest/include
// #cgo LDFLAGS: -L/opt/intel/oneapi/mkl/latest/lib/intel64 -Wl,--start-group -lmkl_intel_lp64 -lmkl_sequential -lmkl_core -Wl,--end-group -lpthread -lm -ldl -static
// #include "mkl.h"
import "C"
func SGEMM(order Order, transA, transB Transpose, m, n, k int, alpha float32, a []float32, lda int, b []float32, ldb int, beta float32, c []float32, ldc int) {
C.cblas_sgemm(C.CBLAS_LAYOUT(order), C.CBLAS_TRANSPOSE(transA), C.CBLAS_TRANSPOSE(transB), C.int(m), C.int(n), C.int(k), C.float(alpha),
(*C.float)(&a[0]), C.int(lda), (*C.float)(&b[0]), C.int(ldb), C.float(beta), (*C.float)(&c[0]), C.int(ldc))
}
================================================
FILE: common/blas/blas_openblas.go
================================================
//go:build cgo && openblas
// Copyright 2025 gorse Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package blas
// #cgo LDFLAGS: -lopenblas -lm -pthread -static
// #include <cblas.h>
import "C"
func SGEMM(order Order, transA, transB Transpose, m, n, k int, alpha float32, a []float32, lda int, b []float32, ldb int, beta float32, c []float32, ldc int) {
C.cblas_sgemm(uint32(order), uint32(transA), uint32(transB), C.int(m), C.int(n), C.int(k), C.float(alpha),
(*C.float)(&a[0]), C.int(lda), (*C.float)(&b[0]), C.int(ldb), C.float(beta), (*C.float)(&c[0]), C.int(ldc))
}
================================================
FILE: common/copier/copier.go
================================================
// Copyright 2021 gorse Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package copier
import (
"encoding"
"reflect"
"github.com/juju/errors"
)
func Copy(dst, src interface{}) error {
dstPtr := reflect.ValueOf(dst)
if dstPtr.Kind() != reflect.Ptr {
return errors.NotValidf("expect dst to be a pointer, but receive %v", dstPtr.Kind())
}
dstValue := dstPtr.Elem()
srcValue := reflect.ValueOf(src)
return copyValue(dstValue, srcValue)
}
func copyValue(dst, src reflect.Value) error {
if dst.Kind() != src.Kind() {
if dst.Kind() == reflect.Interface {
newValuePointer := reflect.New(src.Type())
err := copyValue(newValuePointer.Elem(), src)
if err != nil {
return err
}
dst.Set(newValuePointer.Elem())
return nil
} else {
return errors.NotValidf("different type: %v != %v", dst.Kind(), src.Kind())
}
}
switch dst.Kind() {
case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint,
reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64,
reflect.Complex64, reflect.Complex128, reflect.String:
dst.Set(src)
case reflect.Slice:
if dst.IsNil() || (!dst.CanAddr() && dst.Len() != src.Len()) || dst.Cap() < src.Len() {
newSlice := reflect.MakeSlice(src.Type(), src.Len(), src.Len())
dst.Set(newSlice)
} else if dst.CanAddr() {
dst.SetLen(src.Len())
}
for i := 0; i < src.Len(); i++ {
err := copyValue(dst.Index(i), src.Index(i))
if err != nil {
return err
}
}
case reflect.Map:
if !reflect.DeepEqual(dst.Interface(), src.Interface()) {
dst.Set(reflect.MakeMap(dst.Type()))
keys := src.MapKeys()
for _, k := range keys {
value := src.MapIndex(k)
newValuePointer := reflect.New((value).Type())
err := copyValue(newValuePointer.Elem(), src.MapIndex(k))
if err != nil {
return err
}
dst.SetMapIndex(k, newValuePointer.Elem())
}
}
case reflect.Struct:
if dst.Type().Name() != src.Type().Name() {
return errors.NotValidf("different struct: %v != %v", dst.Type().Name(), src.Type().Name())
}
dstPointer := reflect.New(dst.Type())
srcPointer := reflect.New(src.Type())
srcPointer.Elem().Set(src)
srcMarshaller, hasSrcMarshaller := srcPointer.Interface().(encoding.BinaryMarshaler)
dstUnmarshaler, hasDstUnmarshaler := dstPointer.Interface().(encoding.BinaryUnmarshaler)
if hasDstUnmarshaler && hasSrcMarshaller {
dstByte, err := srcMarshaller.MarshalBinary()
if err != nil {
return err
}
err = dstUnmarshaler.UnmarshalBinary(dstByte)
if err != nil {
return err
}
dst.Set(dstPointer.Elem())
} else {
numFiled := src.NumField()
for i := 0; i < numFiled; i++ {
fieldDST := dst.Field(i)
fieldSRC := src.Field(i)
if !fieldDST.CanSet() {
continue
}
err := copyValue(fieldDST, fieldSRC)
if err != nil {
return err
}
}
}
case reflect.Ptr:
if src.IsNil() {
// If source is nil, set dst to nil.
dst.Set(reflect.Zero(dst.Type()))
return nil
}
if dst.IsNil() {
dst.Set(reflect.New(src.Elem().Type()))
}
srcElem := src.Elem()
dstElem := dst.Elem()
err := copyValue(dstElem, srcElem)
if err != nil {
return err
}
case reflect.Interface:
if src.IsNil() {
// If source is nil, set dst to nil.
dst.Set(reflect.Zero(dst.Type()))
return nil
}
if !dst.IsNil() {
switch dst.Elem().Kind() {
case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint,
reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64,
reflect.Complex64, reflect.Complex128, reflect.String:
newValuePointer := reflect.New(src.Elem().Type())
err := copyValue(newValuePointer.Elem(), src.Elem())
if err != nil {
return err
}
dst.Set(newValuePointer.Elem())
default:
err := copyValue(dst.Elem(), src.Elem())
if err != nil {
return err
}
}
} else {
newValuePointer := reflect.New(src.Elem().Type())
err := copyValue(newValuePointer.Elem(), src.Elem())
if err != nil {
return err
}
dst.Set(newValuePointer.Elem())
}
default:
return errors.NotValidf("unsupported type: %v", dst.Kind())
}
return nil
}
================================================
FILE: common/copier/copier_test.go
================================================
// Copyright 2021 gorse Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package copier
import (
"testing"
"github.com/juju/errors"
"github.com/stretchr/testify/assert"
)
func TestPrimitives(t *testing.T) {
var a = 1
var b int
err := Copy(&b, a)
assert.NoError(t, err)
assert.Equal(t, a, b)
// not a pointer
err = Copy(b, a)
assert.True(t, errors.Is(err, errors.NotValid))
// test type mismatch
var c bool
err = Copy(&c, a)
assert.True(t, errors.Is(err, errors.NotValid))
// copy to interface
var d interface{}
err = Copy(&d, a)
assert.NoError(t, err)
assert.Equal(t, a, d)
}
func TestSlice(t *testing.T) {
a := [][]int{{1}, {2}, {3}, {4}}
b := make([][]int, 0)
err := Copy(&b, a)
assert.NoError(t, err)
assert.Equal(t, a, b)
// test deep copy
a[0][0] = 100
assert.Equal(t, 1, b[0][0])
// test reuse memory
var integers = []int{10}
c := [][]int{integers, {20}, {30}, {40}}
err = Copy(&c, a)
assert.NoError(t, err)
integers[0] = 100
assert.Equal(t, 100, c[0][0])
// copy to interface
var d interface{}
err = Copy(&d, a)
assert.NoError(t, err)
assert.Equal(t, a, d)
// copy empty slice
var e interface{}
err = Copy(&e, make([]int, 0))
assert.NoError(t, err)
assert.NotNil(t, e)
// copy to larger slice
var f = [][]int{{10}, {20}, {30}, {40}, {50}}
err = Copy(&f, a)
assert.NoError(t, err)
assert.Equal(t, a, f)
assert.Equal(t, 5, cap(f))
}
func TestMap(t *testing.T) {
a := map[int64][]int64{1: {1}, 2: {1}, 3: {1}}
b := map[int64][]int64{4: {100}, 5: {200}, 6: {300}}
err := Copy(&b, a)
assert.NoError(t, err)
assert.Equal(t, a, b)
// test deep copy
a[1][0] = 100
assert.Equal(t, int64(1), b[1][0])
// copy to interface
var d interface{}
err = Copy(&d, a)
assert.NoError(t, err)
assert.Equal(t, a, d)
// test no copy
var integers = []int64{100}
c := map[int64][]int64{1: integers, 2: {1}, 3: {1}}
err = Copy(&c, a)
assert.NoError(t, err)
assert.Equal(t, a, c)
integers[0] = 10
assert.Equal(t, int64(10), c[1][0])
}
type Foo struct {
A int64
B []string
}
type Bar struct {
A int64
}
func TestStruct(t *testing.T) {
a := Foo{A: 3, B: []string{"3"}}
b := Foo{A: 4, B: []string{"4"}}
err := Copy(&b, a)
assert.NoError(t, err)
assert.Equal(t, a, b)
// test deep copy
a.B[0] = "100"
assert.Equal(t, "3", b.B[0])
// test type mismatch
var c Bar
err = Copy(&c, a)
assert.True(t, errors.Is(err, errors.NotValid))
}
func TestPtr(t *testing.T) {
a := &Foo{A: 3, B: []string{"3"}}
b := &Foo{A: 4, B: []string{"4"}}
err := Copy(&b, a)
assert.NoError(t, err)
assert.Equal(t, a, b)
}
func TestInterface(t *testing.T) {
var a = []interface{}{&Foo{A: 3, B: []string{"3"}}, []int{100}, 1}
var b []interface{}
err := Copy(&b, a)
assert.NoError(t, err)
assert.Equal(t, a, b)
// test reuse memory
var strings = []string{"30"}
var c = []interface{}{&Foo{A: 30, B: strings}, []int{1000}, 10}
err = Copy(&c, a)
assert.NoError(t, err)
assert.Equal(t, a, c)
strings[0] = "123"
assert.Equal(t, "123", c[0].(*Foo).B[0])
}
type PrivateStruct struct {
text *string
}
func (ps *PrivateStruct) MarshalBinary() (data []byte, err error) {
return []byte(*ps.text), nil
}
func (ps *PrivateStruct) UnmarshalBinary(data []byte) error {
ps.text = new(string(data))
return nil
}
func TestPrivate(t *testing.T) {
var a = PrivateStruct{new("hello")}
var b PrivateStruct
err := Copy(&b, a)
assert.NoError(t, err)
assert.Equal(t, a, b)
// test deep copy
*a.text = "world"
assert.Equal(t, "hello", *b.text)
}
type NilInterface interface{}
type NilStruct struct {
Interface NilInterface
Pointer *Foo
}
func TestNil(t *testing.T) {
var d = NilStruct{
Interface: 100,
Pointer: &Foo{A: 100},
}
var e NilStruct
err := Copy(&d, e)
assert.NoError(t, err)
assert.Nil(t, d.Interface)
assert.Nil(t, d.Pointer)
}
================================================
FILE: common/datautil/datautil.go
================================================
// Copyright 2024 gorse Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package datautil
import (
"archive/zip"
"encoding/csv"
"fmt"
"io"
"net/http"
"os"
"os/user"
"path/filepath"
"strings"
"github.com/gorse-io/gorse/common/log"
"github.com/gorse-io/gorse/common/util"
"go.uber.org/zap"
)
var (
tempDir string
datasetDir string
)
func init() {
usr, err := user.Current()
if err != nil {
log.Logger().Fatal("failed to get user directory", zap.Error(err))
}
datasetDir = filepath.Join(usr.HomeDir, ".gorse", "dataset")
tempDir = filepath.Join(usr.HomeDir, ".gorse", "temp")
}
func LoadIris() ([][]float32, []int, error) {
// Download dataset
path, err := DownloadAndUnzip("iris")
if err != nil {
return nil, nil, err
}
dataFile := filepath.Join(path, "iris.data")
// Load data
f, err := os.Open(dataFile)
if err != nil {
return nil, nil, err
}
reader := csv.NewReader(f)
rows, err := reader.ReadAll()
if err != nil {
return nil, nil, err
}
// Parse data
data := make([][]float32, len(rows))
target := make([]int, len(rows))
types := make(map[string]int)
for i, row := range rows {
data[i] = make([]float32, 4)
for j, cell := range row[:4] {
data[i][j], err = util.ParseFloat[float32](cell)
if err != nil {
return nil, nil, err
}
}
if _, exist := types[row[4]]; !exist {
types[row[4]] = len(types)
}
target[i] = types[row[4]]
}
return data, target, nil
}
func DownloadAndUnzip(name string) (string, error) {
url := fmt.Sprintf("https://cdn.gorse.io/datasets/%s.zip", name)
path := filepath.Join(datasetDir, name)
if _, err := os.Stat(path); os.IsNotExist(err) {
zipFileName, _ := downloadFromUrl(url, tempDir)
if _, err := unzip(zipFileName, datasetDir); err != nil {
return "", err
}
}
return path, nil
}
// downloadFromUrl downloads file from URL.
func downloadFromUrl(src, dst string) (string, error) {
log.Logger().Info("Download dataset", zap.String("source", src), zap.String("destination", dst))
// Extract file name
tokens := strings.Split(src, "/")
fileName := filepath.Join(dst, tokens[len(tokens)-1])
// Create file
if err := os.MkdirAll(filepath.Dir(fileName), os.ModePerm); err != nil {
return fileName, err
}
output, err := os.Create(fileName)
if err != nil {
log.Logger().Error("failed to create file", zap.Error(err), zap.String("filename", fileName))
return fileName, err
}
defer output.Close()
// Download file
response, err := http.Get(src)
if err != nil {
log.Logger().Error("failed to download", zap.Error(err), zap.String("source", src))
return fileName, err
}
defer response.Body.Close()
// Save file
_, err = io.Copy(output, response.Body)
if err != nil {
log.Logger().Error("failed to download", zap.Error(err), zap.String("source", src))
return fileName, err
}
return fileName, nil
}
// unzip zip file.
func unzip(src, dst string) ([]string, error) {
var fileNames []string
// Open zip file
r, err := zip.OpenReader(src)
if err != nil {
return fileNames, err
}
defer r.Close()
// Extract files
for _, f := range r.File {
// Open file
rc, err := f.Open()
if err != nil {
return fileNames, err
}
// Store filename/path for returning and using later on
filePath := filepath.Join(dst, f.Name)
// Check for ZipSlip. More Info: http://bit.ly/2MsjAWE
if !strings.HasPrefix(filePath, filepath.Clean(dst)+string(os.PathSeparator)) {
return fileNames, fmt.Errorf("%s: illegal file path", filePath)
}
// Add filename
fileNames = append(fileNames, filePath)
if f.FileInfo().IsDir() {
// Create folder
if err = os.MkdirAll(filePath, os.ModePerm); err != nil {
return fileNames, err
}
} else {
// Create all folders
if err = os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil {
return fileNames, err
}
// Create file
outFile, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
if err != nil {
return fileNames, err
}
// Save file
_, err = io.Copy(outFile, rc)
if err != nil {
return nil, err
}
// Close the file without defer to close before next iteration of loop
err = outFile.Close()
if err != nil {
return nil, err
}
}
// Close file
err = rc.Close()
if err != nil {
return nil, err
}
}
return fileNames, nil
}
================================================
FILE: common/datautil/datautil_test.go
================================================
// Copyright 2025 gorse Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package datautil
import (
"github.com/stretchr/testify/assert"
"testing"
)
func TestLoadIris(t *testing.T) {
data, target, err := LoadIris()
assert.NoError(t, err)
assert.Len(t, data, 150)
assert.Len(t, data[0], 4)
assert.Len(t, target, 150)
}
================================================
FILE: common/encoding/encoding.go
================================================
// Copyright 2022 gorse Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package encoding
import (
"bytes"
"encoding/binary"
"encoding/gob"
"github.com/pkg/errors"
"io"
)
// WriteSlice writes matrix to byte stream.
func WriteSlice[T any](w io.Writer, s []T) error {
if err := binary.Write(w, binary.LittleEndian, int32(len(s))); err != nil {
return errors.WithStack(err)
}
return binary.Write(w, binary.LittleEndian, s)
}
// ReadSlice reads matrix from byte stream.
func ReadSlice[T any](r io.Reader, s *[]T) error {
var length int32
if err := binary.Read(r, binary.LittleEndian, &length); err != nil {
return errors.WithStack(err)
}
*s = make([]T, length)
return binary.Read(r, binary.LittleEndian, *s)
}
// WriteString writes string to byte stream.
func WriteString(w io.Writer, s string) error {
return WriteBytes(w, []byte(s))
}
// ReadString reads string from byte stream.
func ReadString(r io.Reader) (string, error) {
data, err := ReadBytes(r)
return string(data), err
}
// WriteBytes writes bytes to byte stream.
func WriteBytes(w io.Writer, s []byte) error {
err := binary.Write(w, binary.LittleEndian, int32(len(s)))
if err != nil {
return err
}
n, err := w.Write(s)
if err != nil {
return err
} else if n != len(s) {
return errors.New("fail to write string")
}
return nil
}
// ReadBytes reads bytes from byte stream.
func ReadBytes(r io.Reader) ([]byte, error) {
var length int32
err := binary.Read(r, binary.LittleEndian, &length)
if err != nil {
return nil, err
}
data := make([]byte, length)
readCount := 0
for {
n, err := r.Read(data[readCount:])
if err != nil {
return nil, err
}
readCount += n
if readCount == len(data) {
return data, nil
} else if n == 0 {
return nil, errors.New("fail to read string")
}
}
}
// WriteGob writes object to byte stream.
func WriteGob(w io.Writer, v interface{}) error {
buffer := bytes.NewBuffer(nil)
encoder := gob.NewEncoder(buffer)
err := encoder.Encode(v)
if err != nil {
return err
}
return WriteBytes(w, buffer.Bytes())
}
// ReadGob read object from byte stream.
func ReadGob(r io.Reader, v interface{}) error {
data, err := ReadBytes(r)
if err != nil {
return err
}
buffer := bytes.NewBuffer(data)
decoder := gob.NewDecoder(buffer)
return decoder.Decode(v)
}
================================================
FILE: common/encoding/encoding_test.go
================================================
// Copyright 2022 gorse Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package encoding
import (
"bytes"
"testing"
"github.com/stretchr/testify/assert"
)
func TestReadWriteSlice(t *testing.T) {
a := []float32{1, 2, 3, 4}
buf := bytes.NewBuffer(nil)
err := WriteSlice(buf, a)
assert.NoError(t, err)
var b []float32
err = ReadSlice(buf, &b)
assert.NoError(t, err)
assert.Equal(t, a, b)
}
func TestWriteString(t *testing.T) {
a := "abc"
buf := bytes.NewBuffer(nil)
err := WriteString(buf, a)
assert.NoError(t, err)
var b string
b, err = ReadString(buf)
assert.NoError(t, err)
assert.Equal(t, a, b)
}
func TestWriteGob(t *testing.T) {
a := "abc"
buf := bytes.NewBuffer(nil)
err := WriteGob(buf, a)
assert.NoError(t, err)
var b string
err = ReadGob(buf, &b)
assert.NoError(t, err)
assert.Equal(t, a, b)
}
================================================
FILE: common/expression/expression.go
================================================
// Copyright 2025 gorse Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package expression
import (
"encoding/json"
"errors"
"fmt"
"regexp"
"strconv"
"github.com/gorse-io/gorse/protocol"
"github.com/samber/lo"
)
var expressionPattern = regexp.MustCompile(`^(?P<feedback_type>[a-zA-Z][a-zA-Z0-9_]*)(?P<expr_type><=|>=|<|>|=)?(?P<value>[0-9]*\.?[0-9]*)$`)
type ExprType int
const (
None ExprType = iota
Less
LessOrEqual
Greater
GreaterOrEqual
)
func (typ ExprType) String() string {
switch typ {
case Less:
return "<"
case LessOrEqual:
return "<="
case Greater:
return ">"
case GreaterOrEqual:
return ">="
default:
return ""
}
}
type FeedbackTypeExpression struct {
FeedbackType string
ExprType ExprType
Value float64
}
func (f *FeedbackTypeExpression) String() string {
if f.ExprType == None {
return f.FeedbackType
} else {
return fmt.Sprintf("%s%v%v", f.FeedbackType, f.ExprType, f.Value)
}
}
func (f *FeedbackTypeExpression) FromString(data string) error {
groupNames := expressionPattern.SubexpNames()
subMatches := expressionPattern.FindStringSubmatch(data)
if len(subMatches) == 0 {
return errors.New("invalid expression format, expected format: <feedback_type>[<operator><value>]")
}
for i, match := range subMatches {
switch groupNames[i] {
case "feedback_type":
f.FeedbackType = match
case "expr_type":
switch match {
case "<":
f.ExprType = Less
case "<=":
f.ExprType = LessOrEqual
case ">":
f.ExprType = Greater
case ">=":
f.ExprType = GreaterOrEqual
default:
f.ExprType = None
}
case "value":
if len(match) > 0 {
var err error
f.Value, err = strconv.ParseFloat(match, 64)
if err != nil {
return fmt.Errorf("invalid value: %w", err)
}
}
}
}
return nil
}
func (f *FeedbackTypeExpression) MarshalJSON() ([]byte, error) {
return json.Marshal(f.String())
}
func (f *FeedbackTypeExpression) UnmarshalJSON(data []byte) error {
var s string
if err := json.Unmarshal(data, &s); err != nil {
return fmt.Errorf("unmarshal FeedbackTypeExpression: %w", err)
}
if err := f.FromString(s); err != nil {
return fmt.Errorf("unmarshal FeedbackTypeExpression: %w", err)
}
return nil
}
func (f *FeedbackTypeExpression) ToPB() *protocol.FeedbackTypeExpression {
pb := &protocol.FeedbackTypeExpression{}
pb.FeedbackType = f.FeedbackType
switch f.ExprType {
case None:
pb.ExpressionType = protocol.ExpressionType_None
case Less:
pb.ExpressionType = protocol.ExpressionType_Less
case LessOrEqual:
pb.ExpressionType = protocol.ExpressionType_LessOrEqual
case Greater:
pb.ExpressionType = protocol.ExpressionType_Greater
case GreaterOrEqual:
pb.ExpressionType = protocol.ExpressionType_GreaterOrEqual
}
pb.Value = f.Value
return pb
}
func (f *FeedbackTypeExpression) FromPB(pb *protocol.FeedbackTypeExpression) {
f.FeedbackType = pb.FeedbackType
switch pb.ExpressionType {
case protocol.ExpressionType_None:
f.ExprType = None
case protocol.ExpressionType_Less:
f.ExprType = Less
case protocol.ExpressionType_LessOrEqual:
f.ExprType = LessOrEqual
case protocol.ExpressionType_Greater:
f.ExprType = Greater
case protocol.ExpressionType_GreaterOrEqual:
f.ExprType = GreaterOrEqual
}
f.Value = pb.Value
}
func (f *FeedbackTypeExpression) Match(feedbackType string, value float64) bool {
if f.FeedbackType != feedbackType {
return false
}
switch f.ExprType {
case None:
return true
case Less:
return value < f.Value
case LessOrEqual:
return value <= f.Value
case Greater:
return value > f.Value
case GreaterOrEqual:
return value >= f.Value
default:
return false
}
}
func MatchFeedbackTypeExpressions(exprs []FeedbackTypeExpression, feedbackType string, value float64) bool {
for _, expr := range exprs {
if expr.Match(feedbackType, value) {
return true
}
}
return false
}
func MustParseFeedbackTypeExpression(s string) FeedbackTypeExpression {
var expr FeedbackTypeExpression
lo.Must0(expr.FromString(s))
return expr
}
================================================
FILE: common/expression/expression_test.go
================================================
// Copyright 2025 gorse Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package expression
import (
"testing"
"github.com/gorse-io/gorse/protocol"
"github.com/stretchr/testify/assert"
)
func TestFeedbackTypeExpression_UnmarshalJSON(t *testing.T) {
var f FeedbackTypeExpression
err := f.UnmarshalJSON([]byte(`"test"`))
assert.NoError(t, err)
assert.Equal(t, "test", f.FeedbackType)
assert.Equal(t, None, f.ExprType)
err = f.UnmarshalJSON([]byte(`"1a"`))
assert.Error(t, err)
err = f.UnmarshalJSON([]byte(`"test<16"`))
assert.NoError(t, err)
assert.Equal(t, "test", f.FeedbackType)
assert.Equal(t, Less, f.ExprType)
assert.Equal(t, 16.0, f.Value)
err = f.UnmarshalJSON([]byte(`"test<=16"`))
assert.NoError(t, err)
assert.Equal(t, "test", f.FeedbackType)
assert.Equal(t, LessOrEqual, f.ExprType)
assert.Equal(t, 16.0, f.Value)
err = f.UnmarshalJSON([]byte(`"test>16"`))
assert.NoError(t, err)
assert.Equal(t, "test", f.FeedbackType)
assert.Equal(t, Greater, f.ExprType)
assert.Equal(t, 16.0, f.Value)
err = f.UnmarshalJSON([]byte(`"test>=16"`))
assert.NoError(t, err)
assert.Equal(t, "test", f.FeedbackType)
assert.Equal(t, GreaterOrEqual, f.ExprType)
assert.Equal(t, 16.0, f.Value)
}
func TestFeedbackTypeExpression_MarshalJSON(t *testing.T) {
f := FeedbackTypeExpression{FeedbackType: "test", Value: 16}
buf, err := f.MarshalJSON()
assert.NoError(t, err)
assert.Equal(t, `"test"`, string(buf))
f.ExprType = Less
buf, err = f.MarshalJSON()
assert.NoError(t, err)
assert.Equal(t, `"test\u003c16"`, string(buf))
f.ExprType = LessOrEqual
buf, err = f.MarshalJSON()
assert.NoError(t, err)
assert.Equal(t, `"test\u003c=16"`, string(buf))
f.ExprType = Greater
buf, err = f.MarshalJSON()
assert.NoError(t, err)
assert.Equal(t, `"test\u003e16"`, string(buf))
f.ExprType = GreaterOrEqual
buf, err = f.MarshalJSON()
assert.NoError(t, err)
assert.Equal(t, `"test\u003e=16"`, string(buf))
}
func TestFeedbackTypeExpression_ToPB(t *testing.T) {
f := FeedbackTypeExpression{FeedbackType: "test", Value: 6}
pb := f.ToPB()
assert.Equal(t, "test", pb.FeedbackType)
assert.Equal(t, protocol.ExpressionType_None, pb.ExpressionType)
assert.Equal(t, 6.0, pb.Value)
f.ExprType = Less
pb = f.ToPB()
assert.Equal(t, protocol.ExpressionType_Less, pb.ExpressionType)
f.ExprType = LessOrEqual
pb = f.ToPB()
assert.Equal(t, protocol.ExpressionType_LessOrEqual, pb.ExpressionType)
f.ExprType = Greater
pb = f.ToPB()
assert.Equal(t, protocol.ExpressionType_Greater, pb.ExpressionType)
f.ExprType = GreaterOrEqual
pb = f.ToPB()
assert.Equal(t, protocol.ExpressionType_GreaterOrEqual, pb.ExpressionType)
}
func TestFeedbackTypeExpression_FromPB(t *testing.T) {
pb := &protocol.FeedbackTypeExpression{
FeedbackType: "test",
ExpressionType: protocol.ExpressionType_Less,
Value: 6.0,
}
f := FeedbackTypeExpression{}
f.FromPB(pb)
assert.Equal(t, "test", f.FeedbackType)
assert.Equal(t, Less, f.ExprType)
assert.Equal(t, 6.0, f.Value)
pb.ExpressionType = protocol.ExpressionType_LessOrEqual
f.FromPB(pb)
assert.Equal(t, LessOrEqual, f.ExprType)
pb.ExpressionType = protocol.ExpressionType_Greater
f.FromPB(pb)
assert.Equal(t, Greater, f.ExprType)
pb.ExpressionType = protocol.ExpressionType_GreaterOrEqual
f.FromPB(pb)
assert.Equal(t, GreaterOrEqual, f.ExprType)
pb.ExpressionType = protocol.ExpressionType_None
f.FromPB(pb)
assert.Equal(t, None, f.ExprType)
}
func TestFeedbackTypeExpression_Match(t *testing.T) {
f := FeedbackTypeExpression{FeedbackType: "test", Value: 6}
assert.True(t, f.Match("test", 0))
assert.False(t, f.Match("a", 1))
f.ExprType = Less
assert.True(t, f.Match("test", 5))
assert.False(t, f.Match("test", 6))
f.ExprType = LessOrEqual
assert.True(t, f.Match("test", 6))
assert.False(t, f.Match("test", 7))
f.ExprType = Greater
assert.True(t, f.Match("test", 7))
assert.False(t, f.Match("test", 6))
f.ExprType = GreaterOrEqual
assert.True(t, f.Match("test", 6))
assert.False(t, f.Match("test", 5))
}
func TestMatchFeedbackTypeExpressions(t *testing.T) {
expressions := []FeedbackTypeExpression{
{FeedbackType: "a"},
{FeedbackType: "b"},
{FeedbackType: "c"},
}
assert.Tr
gitextract_2md3h71u/
├── .devcontainer/
│ ├── Dockerfile
│ └── devcontainer.json
├── .dockerignore
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ ├── custom.md
│ │ └── feature_request.md
│ └── workflows/
│ ├── assign_issue.yml
│ ├── backport.yml
│ ├── build_docker.yml
│ ├── build_release.yml
│ ├── build_test.yml
│ ├── dockerhub-description.yml
│ └── translate_issues.yml
├── .gitignore
├── .golangci.yml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── client/
│ ├── README.md
│ ├── client_test.go
│ ├── config.go
│ ├── config.toml
│ ├── docker-compose.yml.j2
│ └── setup-test.sh
├── cmd/
│ ├── goat/
│ │ └── README.md
│ ├── gorse-cli/
│ │ └── main.go
│ ├── gorse-in-one/
│ │ ├── Dockerfile
│ │ ├── Dockerfile.cuda
│ │ ├── Dockerfile.mkl
│ │ ├── Dockerfile.openblas
│ │ ├── Dockerfile.windows
│ │ └── main.go
│ ├── gorse-master/
│ │ ├── Dockerfile
│ │ ├── Dockerfile.cuda
│ │ ├── Dockerfile.mkl
│ │ ├── Dockerfile.openblas
│ │ ├── Dockerfile.windows
│ │ └── main.go
│ ├── gorse-server/
│ │ ├── Dockerfile
│ │ ├── Dockerfile.cuda
│ │ ├── Dockerfile.mkl
│ │ ├── Dockerfile.openblas
│ │ ├── Dockerfile.windows
│ │ └── main.go
│ ├── gorse-worker/
│ │ ├── Dockerfile
│ │ ├── Dockerfile.cuda
│ │ ├── Dockerfile.mkl
│ │ ├── Dockerfile.openblas
│ │ ├── Dockerfile.windows
│ │ └── main.go
│ └── version/
│ └── version.go
├── codecov.yml
├── common/
│ ├── ann/
│ │ ├── ann.go
│ │ ├── ann_test.go
│ │ ├── bruteforce.go
│ │ └── hnsw.go
│ ├── blas/
│ │ ├── blas.go
│ │ ├── blas_darwin_arm64.go
│ │ ├── blas_mkl.go
│ │ └── blas_openblas.go
│ ├── copier/
│ │ ├── copier.go
│ │ └── copier_test.go
│ ├── datautil/
│ │ ├── datautil.go
│ │ └── datautil_test.go
│ ├── encoding/
│ │ ├── encoding.go
│ │ └── encoding_test.go
│ ├── expression/
│ │ ├── expression.go
│ │ └── expression_test.go
│ ├── floats/
│ │ ├── floats.go
│ │ ├── floats_amd64.go
│ │ ├── floats_amd64_test.go
│ │ ├── floats_arm64.go
│ │ ├── floats_arm64_test.go
│ │ ├── floats_avx.go
│ │ ├── floats_avx.s
│ │ ├── floats_avx512.go
│ │ ├── floats_avx512.s
│ │ ├── floats_neon.go
│ │ ├── floats_neon.s
│ │ ├── floats_noasm.go
│ │ ├── floats_riscv64.go
│ │ ├── floats_riscv64_test.go
│ │ ├── floats_rvv.go
│ │ ├── floats_rvv.s
│ │ ├── floats_test.go
│ │ ├── mm.go
│ │ ├── mm_darwin_arm64.go
│ │ ├── mm_mkl.go
│ │ ├── mm_openblas.go
│ │ └── src/
│ │ ├── .gitignore
│ │ ├── Makefile
│ │ ├── floats_avx.c
│ │ ├── floats_avx512.c
│ │ ├── floats_neon.c
│ │ ├── floats_rvv.c
│ │ ├── floats_sve2.c
│ │ ├── floats_test.c
│ │ ├── munit.c
│ │ └── munit.h
│ ├── heap/
│ │ ├── filter.go
│ │ ├── filter_test.go
│ │ ├── pq.go
│ │ └── pq_test.go
│ ├── jsonutil/
│ │ ├── json.go
│ │ └── json_test.go
│ ├── log/
│ │ ├── log.go
│ │ └── log_test.go
│ ├── mock/
│ │ ├── openai.go
│ │ └── openai_test.go
│ ├── monitor/
│ │ ├── progress.go
│ │ └── progress_test.go
│ ├── nn/
│ │ ├── functions.go
│ │ ├── layers.go
│ │ ├── nn_test.go
│ │ ├── op.go
│ │ ├── op_test.go
│ │ ├── optimizers.go
│ │ ├── tensor.go
│ │ └── tensor_test.go
│ ├── parallel/
│ │ ├── parallel.go
│ │ ├── parallel_test.go
│ │ ├── ratelimit.go
│ │ └── ratelimit_test.go
│ ├── rc/
│ │ ├── rc.go
│ │ └── rc_test.go
│ ├── reranker/
│ │ ├── client.go
│ │ └── client_test.go
│ ├── sizeof/
│ │ ├── size.go
│ │ └── size_test.go
│ └── util/
│ ├── random.go
│ ├── random_test.go
│ ├── strconv.go
│ ├── tls.go
│ ├── util.go
│ └── util_test.go
├── config/
│ ├── config.go
│ ├── config.toml
│ └── config_test.go
├── dataset/
│ ├── dataset.go
│ ├── dataset_test.go
│ ├── dict.go
│ ├── dict_test.go
│ ├── index.go
│ ├── index_test.go
│ ├── unified_index.go
│ └── unified_index_test.go
├── docker-bake.hcl
├── docker-compose.yml
├── go.mod
├── go.sum
├── logics/
│ ├── cf.go
│ ├── cf_test.go
│ ├── chat.go
│ ├── chat_test.go
│ ├── external.go
│ ├── external_test.go
│ ├── item_to_item.go
│ ├── item_to_item_test.go
│ ├── non_personalized.go
│ ├── non_personalized_test.go
│ ├── recommend.go
│ ├── recommend_test.go
│ ├── user_to_user.go
│ └── user_to_user_test.go
├── master/
│ ├── master.go
│ ├── master_test.go
│ ├── metrics.go
│ ├── metrics_test.go
│ ├── rest.go
│ ├── rest_test.go
│ ├── rpc.go
│ ├── rpc_test.go
│ ├── tasks.go
│ └── tasks_test.go
├── model/
│ ├── built_in.go
│ ├── built_in_test.go
│ ├── cf/
│ │ ├── evaluator.go
│ │ ├── evaluator_test.go
│ │ ├── model.go
│ │ ├── model_test.go
│ │ ├── optimize.go
│ │ └── optimize_test.go
│ ├── ctr/
│ │ ├── data.go
│ │ ├── data_test.go
│ │ ├── evaluator.go
│ │ ├── evaluator_test.go
│ │ ├── fm.go
│ │ ├── fm_xla.go
│ │ ├── model.go
│ │ ├── model.py
│ │ ├── model_test.go
│ │ ├── optimize.go
│ │ └── optimize_test.go
│ ├── model.go
│ ├── params.go
│ └── params_test.go
├── protocol/
│ ├── cache_store.pb.go
│ ├── cache_store.proto
│ ├── cache_store_grpc.pb.go
│ ├── data_store.pb.go
│ ├── data_store.proto
│ ├── data_store_grpc.pb.go
│ ├── encoding.pb.go
│ ├── encoding.proto
│ ├── generate.go
│ ├── protocol.pb.go
│ ├── protocol.proto
│ ├── protocol_grpc.pb.go
│ ├── vector_store.pb.go
│ ├── vector_store.proto
│ └── vector_store_grpc.pb.go
├── server/
│ ├── metrics.go
│ ├── rest.go
│ ├── rest_test.go
│ ├── server.go
│ └── server_test.go
├── storage/
│ ├── blob/
│ │ ├── azure.go
│ │ ├── azure_test.go
│ │ ├── blob.go
│ │ ├── blob_test.go
│ │ ├── gcs.go
│ │ ├── gcs_test.go
│ │ ├── posix.go
│ │ ├── posix_test.go
│ │ ├── s3.go
│ │ └── s3_test.go
│ ├── cache/
│ │ ├── database.go
│ │ ├── database_test.go
│ │ ├── mongodb.go
│ │ ├── mongodb_test.go
│ │ ├── no_database.go
│ │ ├── no_database_test.go
│ │ ├── proxy.go
│ │ ├── proxy_test.go
│ │ ├── redis.go
│ │ ├── redis_test.go
│ │ ├── sql.go
│ │ └── sql_test.go
│ ├── data/
│ │ ├── database.go
│ │ ├── database_test.go
│ │ ├── mongodb.go
│ │ ├── mongodb_test.go
│ │ ├── no_database.go
│ │ ├── no_database_test.go
│ │ ├── proxy.go
│ │ ├── proxy_test.go
│ │ ├── sql.go
│ │ └── sql_test.go
│ ├── docker-compose.yml
│ ├── meta/
│ │ ├── database.go
│ │ ├── database_test.go
│ │ ├── sqlite.go
│ │ └── sqlite_test.go
│ ├── options.go
│ ├── schema_test.go
│ ├── scheme.go
│ └── vectors/
│ ├── database.go
│ ├── database_test.go
│ ├── milvus.go
│ ├── milvus_test.go
│ ├── proxy.go
│ ├── proxy_test.go
│ ├── qdrant.go
│ ├── qdrant_test.go
│ ├── sqlite.go
│ ├── sqlite_test.go
│ ├── weaviate.go
│ └── weaviate_test.go
└── worker/
├── metrics.go
├── pipeline.go
├── pipeline_test.go
├── worker.go
└── worker_test.go
Showing preview only (345K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (3974 symbols across 209 files)
FILE: client/client_test.go
function init (line 31) | func init() {
type GorseClientTestSuite (line 36) | type GorseClientTestSuite struct
method SetupSuite (line 41) | func (suite *GorseClientTestSuite) SetupSuite() {
method TestUsers (line 48) | func (suite *GorseClientTestSuite) TestUsers() {
method TestItems (line 113) | func (suite *GorseClientTestSuite) TestItems() {
method TestFeedback (line 167) | func (suite *GorseClientTestSuite) TestFeedback() {
method TestLatest (line 213) | func (suite *GorseClientTestSuite) TestLatest() {
method TestItemToItem (line 224) | func (suite *GorseClientTestSuite) TestItemToItem() {
method TestRecommend (line 235) | func (suite *GorseClientTestSuite) TestRecommend() {
function TestGorseClientTestSuite (line 249) | func TestGorseClientTestSuite(t *testing.T) {
FILE: cmd/gorse-cli/main.go
function EvaluateAFM (line 124) | func EvaluateAFM(cfg *config.Config, train, test *ctr.Dataset, exportUse...
function EvaluateLLM (line 208) | func EvaluateLLM(cfg *config.Config, train, test *ctr.Dataset, items []d...
function EvaluateEmbedding (line 321) | func EvaluateEmbedding(cfg *config.Config, train, test dataset.CFSplit, ...
function init (line 553) | func init() {
function main (line 567) | func main() {
FILE: cmd/gorse-in-one/main.go
function init (line 110) | func init() {
function main (line 120) | func main() {
function setup (line 126) | func setup(m *master.Master, playground string) {
FILE: cmd/gorse-master/main.go
function init (line 67) | func init() {
function main (line 75) | func main() {
FILE: cmd/gorse-server/main.go
function init (line 87) | func init() {
function main (line 101) | func main() {
FILE: cmd/gorse-worker/main.go
function init (line 73) | func init() {
function main (line 89) | func main() {
FILE: cmd/version/version.go
function BuildInfo (line 17) | func BuildInfo() string {
FILE: common/ann/ann.go
type Index (line 21) | type Index interface
FILE: common/ann/ann_test.go
constant trainSize (line 36) | trainSize = 6000
constant testSize (line 37) | testSize = 1000
function recall (line 40) | func recall(gt, pred []lo.Tuple2[int, float32]) float64 {
type MNIST (line 54) | type MNIST struct
method openFile (line 80) | func (m *MNIST) openFile(path string) ([][]float32, []uint8, error) {
function mnist (line 61) | func mnist() (*MNIST, error) {
function TestMNIST (line 121) | func TestMNIST(t *testing.T) {
function TestMultithread (line 172) | func TestMultithread(t *testing.T) {
function movieLens (line 217) | func movieLens() ([][]int, error) {
function jaccard (line 251) | func jaccard(a, b []int) float32 {
function TestMovieLens (line 270) | func TestMovieLens(t *testing.T) {
FILE: common/ann/bruteforce.go
type Bruteforce (line 24) | type Bruteforce struct
function NewBruteforce (line 29) | func NewBruteforce[T any](distanceFunc func(a, b T) float32) *Bruteforce...
method Add (line 33) | func (b *Bruteforce[T]) Add(v T) int {
method SearchIndex (line 39) | func (b *Bruteforce[T]) SearchIndex(q, k int, prune0 bool) ([]lo.Tuple2[...
method SearchVector (line 65) | func (b *Bruteforce[T]) SearchVector(q T, k int, prune0 bool) []lo.Tuple...
FILE: common/ann/hnsw.go
type HNSW (line 33) | type HNSW struct
function NewHNSW (line 51) | func NewHNSW[T any](distanceFunc func(a, b T) float32) *HNSW[T] {
method Add (line 61) | func (h *HNSW[T]) Add(v T) int {
method SearchIndex (line 73) | func (h *HNSW[T]) SearchIndex(q, k int, prune0 bool) ([]lo.Tuple2[int, f...
method SearchVector (line 89) | func (h *HNSW[T]) SearchVector(q T, k int, prune0 bool) []lo.Tuple2[int,...
method knnSearch (line 101) | func (h *HNSW[T]) knnSearch(q T, k, ef int) *heap.PriorityQueue {
method insert (line 117) | func (h *HNSW[T]) insert(q int32) {
method searchLayer (line 186) | func (h *HNSW[T]) searchLayer(q T, enterPoints *heap.PriorityQueue, ef, ...
method setNeighbourhood (line 225) | func (h *HNSW[T]) setNeighbourhood(e int32, currentLayer int, connection...
method getNeighbourhood (line 233) | func (h *HNSW[T]) getNeighbourhood(e int32, currentLayer int) *heap.Prio...
method selectNeighbors (line 244) | func (h *HNSW[T]) selectNeighbors(_ T, candidates *heap.PriorityQueue, m...
method distance (line 252) | func (h *HNSW[T]) distance(q T, points []int32) *heap.PriorityQueue {
method efSearchValue (line 261) | func (h *HNSW[T]) efSearchValue(n int) int {
method Marshal (line 268) | func (h *HNSW[T]) Marshal(w io.Writer) error {
method Unmarshal (line 332) | func (h *HNSW[T]) Unmarshal(r io.Reader) error {
FILE: common/blas/blas.go
type Order (line 17) | type Order
constant RowMajor (line 19) | RowMajor Order = 101
type Transpose (line 21) | type Transpose
constant NoTrans (line 24) | NoTrans Transpose = 111
constant Trans (line 25) | Trans Transpose = 112
function NewTranspose (line 28) | func NewTranspose(transpose bool) Transpose {
FILE: common/blas/blas_darwin_arm64.go
function SGEMM (line 24) | func SGEMM(order Order, transA, transB Transpose, m, n, k int, alpha flo...
FILE: common/blas/blas_mkl.go
function SGEMM (line 24) | func SGEMM(order Order, transA, transB Transpose, m, n, k int, alpha flo...
FILE: common/blas/blas_openblas.go
function SGEMM (line 23) | func SGEMM(order Order, transA, transB Transpose, m, n, k int, alpha flo...
FILE: common/copier/copier.go
function Copy (line 24) | func Copy(dst, src interface{}) error {
function copyValue (line 35) | func copyValue(dst, src reflect.Value) error {
FILE: common/copier/copier_test.go
function TestPrimitives (line 24) | func TestPrimitives(t *testing.T) {
function TestSlice (line 44) | func TestSlice(t *testing.T) {
function TestMap (line 78) | func TestMap(t *testing.T) {
type Foo (line 102) | type Foo struct
type Bar (line 107) | type Bar struct
function TestStruct (line 111) | func TestStruct(t *testing.T) {
function TestPtr (line 126) | func TestPtr(t *testing.T) {
function TestInterface (line 134) | func TestInterface(t *testing.T) {
type PrivateStruct (line 150) | type PrivateStruct struct
method MarshalBinary (line 154) | func (ps *PrivateStruct) MarshalBinary() (data []byte, err error) {
method UnmarshalBinary (line 158) | func (ps *PrivateStruct) UnmarshalBinary(data []byte) error {
function TestPrivate (line 163) | func TestPrivate(t *testing.T) {
type NilInterface (line 174) | type NilInterface interface
type NilStruct (line 176) | type NilStruct struct
function TestNil (line 181) | func TestNil(t *testing.T) {
FILE: common/datautil/datautil.go
function init (line 38) | func init() {
function LoadIris (line 47) | func LoadIris() ([][]float32, []int, error) {
function DownloadAndUnzip (line 84) | func DownloadAndUnzip(name string) (string, error) {
function downloadFromUrl (line 97) | func downloadFromUrl(src, dst string) (string, error) {
function unzip (line 129) | func unzip(src, dst string) ([]string, error) {
FILE: common/datautil/datautil_test.go
function TestLoadIris (line 22) | func TestLoadIris(t *testing.T) {
FILE: common/encoding/encoding.go
function WriteSlice (line 26) | func WriteSlice[T any](w io.Writer, s []T) error {
function ReadSlice (line 34) | func ReadSlice[T any](r io.Reader, s *[]T) error {
function WriteString (line 44) | func WriteString(w io.Writer, s string) error {
function ReadString (line 49) | func ReadString(r io.Reader) (string, error) {
function WriteBytes (line 55) | func WriteBytes(w io.Writer, s []byte) error {
function ReadBytes (line 70) | func ReadBytes(r io.Reader) ([]byte, error) {
function WriteGob (line 93) | func WriteGob(w io.Writer, v interface{}) error {
function ReadGob (line 104) | func ReadGob(r io.Reader, v interface{}) error {
FILE: common/encoding/encoding_test.go
function TestReadWriteSlice (line 24) | func TestReadWriteSlice(t *testing.T) {
function TestWriteString (line 35) | func TestWriteString(t *testing.T) {
function TestWriteGob (line 46) | func TestWriteGob(t *testing.T) {
FILE: common/expression/expression.go
type ExprType (line 30) | type ExprType
method String (line 40) | func (typ ExprType) String() string {
constant None (line 33) | None ExprType = iota
constant Less (line 34) | Less
constant LessOrEqual (line 35) | LessOrEqual
constant Greater (line 36) | Greater
constant GreaterOrEqual (line 37) | GreaterOrEqual
type FeedbackTypeExpression (line 55) | type FeedbackTypeExpression struct
method String (line 61) | func (f *FeedbackTypeExpression) String() string {
method FromString (line 69) | func (f *FeedbackTypeExpression) FromString(data string) error {
method MarshalJSON (line 105) | func (f *FeedbackTypeExpression) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 109) | func (f *FeedbackTypeExpression) UnmarshalJSON(data []byte) error {
method ToPB (line 120) | func (f *FeedbackTypeExpression) ToPB() *protocol.FeedbackTypeExpressi...
method FromPB (line 139) | func (f *FeedbackTypeExpression) FromPB(pb *protocol.FeedbackTypeExpre...
method Match (line 156) | func (f *FeedbackTypeExpression) Match(feedbackType string, value floa...
function MatchFeedbackTypeExpressions (line 176) | func MatchFeedbackTypeExpressions(exprs []FeedbackTypeExpression, feedba...
function MustParseFeedbackTypeExpression (line 185) | func MustParseFeedbackTypeExpression(s string) FeedbackTypeExpression {
FILE: common/expression/expression_test.go
function TestFeedbackTypeExpression_UnmarshalJSON (line 24) | func TestFeedbackTypeExpression_UnmarshalJSON(t *testing.T) {
function TestFeedbackTypeExpression_MarshalJSON (line 59) | func TestFeedbackTypeExpression_MarshalJSON(t *testing.T) {
function TestFeedbackTypeExpression_ToPB (line 86) | func TestFeedbackTypeExpression_ToPB(t *testing.T) {
function TestFeedbackTypeExpression_FromPB (line 110) | func TestFeedbackTypeExpression_FromPB(t *testing.T) {
function TestFeedbackTypeExpression_Match (line 139) | func TestFeedbackTypeExpression_Match(t *testing.T) {
function TestMatchFeedbackTypeExpressions (line 161) | func TestMatchFeedbackTypeExpressions(t *testing.T) {
function TestMustParseFeedbackTypeExpression (line 171) | func TestMustParseFeedbackTypeExpression(t *testing.T) {
FILE: common/floats/floats.go
function dot (line 23) | func dot(a, b []float32) (ret float32) {
function euclidean (line 30) | func euclidean(a, b []float32) (ret float32) {
function addConst (line 37) | func addConst(a []float32, c float32) {
function sub (line 43) | func sub(a, b []float32) {
function subTo (line 49) | func subTo(a, b, c []float32) {
function mulTo (line 55) | func mulTo(a, b, c []float32) {
function mulConstAddTo (line 61) | func mulConstAddTo(a []float32, b float32, c []float32, dst []float32) {
function mulConstAdd (line 67) | func mulConstAdd(a []float32, c float32, dst []float32) {
function mulConstTo (line 73) | func mulConstTo(a []float32, b float32, c []float32) {
function mulConst (line 79) | func mulConst(a []float32, b float32) {
function divTo (line 85) | func divTo(a, b, c []float32) {
function sqrtTo (line 91) | func sqrtTo(a, b []float32) {
function MatZero (line 98) | func MatZero(x [][]float32) {
function Zero (line 107) | func Zero(a []float32) {
function SubTo (line 114) | func SubTo(a, b, dst []float32) {
function Add (line 122) | func Add(dst, s []float32) {
function MulConst (line 132) | func MulConst(dst []float32, c float32) {
function Div (line 137) | func Div(dst, s []float32) {
function MulTo (line 146) | func MulTo(a, b, c []float32) {
function Sub (line 154) | func Sub(dst, s []float32) {
function MulConstTo (line 162) | func MulConstTo(a []float32, c float32, dst []float32) {
function MulConstAddTo (line 169) | func MulConstAddTo(a []float32, c float32, b, dst []float32) {
function MulConstAdd (line 177) | func MulConstAdd(a []float32, c float32, dst []float32) {
function MulAddTo (line 185) | func MulAddTo(a, b, c []float32) {
function AddTo (line 195) | func AddTo(a, b, dst []float32) {
function AddConst (line 204) | func AddConst(dst []float32, c float32) {
function DivTo (line 208) | func DivTo(a, b, c []float32) {
function SqrtTo (line 215) | func SqrtTo(a, b []float32) {
function Sqrt (line 222) | func Sqrt(a []float32) {
function Dot (line 229) | func Dot(a, b []float32) (ret float32) {
function Euclidean (line 236) | func Euclidean(a, b []float32) float32 {
function MM (line 243) | func MM(transA, transB bool, m, n, k int, a []float32, lda int, b []floa...
FILE: common/floats/floats_amd64.go
type Feature (line 29) | type Feature
method String (line 55) | func (feature Feature) String() string {
method mulConstAddTo (line 68) | func (feature Feature) mulConstAddTo(a []float32, b float32, c []float...
method mulConstAdd (line 78) | func (feature Feature) mulConstAdd(a []float32, b float32, c []float32) {
method mulConstTo (line 88) | func (feature Feature) mulConstTo(a []float32, b float32, c []float32) {
method addConst (line 98) | func (feature Feature) addConst(a []float32, b float32) {
method sub (line 108) | func (feature Feature) sub(a, b []float32) {
method subTo (line 118) | func (feature Feature) subTo(a, b, c []float32) {
method mulTo (line 128) | func (feature Feature) mulTo(a, b, c []float32) {
method mulConst (line 138) | func (feature Feature) mulConst(a []float32, b float32) {
method divTo (line 148) | func (feature Feature) divTo(a, b, c []float32) {
method sqrtTo (line 158) | func (feature Feature) sqrtTo(a, b []float32) {
method dot (line 168) | func (feature Feature) dot(a, b []float32) float32 {
method euclidean (line 178) | func (feature Feature) euclidean(a, b []float32) float32 {
method mm (line 188) | func (feature Feature) mm(transA, transB bool, m, n, k int, a []float3...
constant AVX (line 32) | AVX Feature = 1 << iota
constant FMA (line 33) | FMA
constant AVX512F (line 34) | AVX512F
constant MKL (line 35) | MKL
constant OPENBLAS (line 36) | OPENBLAS
constant AVX512 (line 39) | AVX512 = AVX | FMA | AVX512F
function init (line 43) | func init() {
FILE: common/floats/floats_amd64_test.go
function init (line 31) | func init() {
function TestAVX (line 41) | func TestAVX(t *testing.T) {
function TestAVX512 (line 45) | func TestAVX512(t *testing.T) {
function initializeFloat32Array (line 49) | func initializeFloat32Array(n int) []float32 {
function BenchmarkDot (line 57) | func BenchmarkDot(b *testing.B) {
function BenchmarkEuclidean (line 74) | func BenchmarkEuclidean(b *testing.B) {
function BenchmarkMulConstAddTo (line 91) | func BenchmarkMulConstAddTo(b *testing.B) {
function BenchmarkMulConstAdd (line 109) | func BenchmarkMulConstAdd(b *testing.B) {
function BenchmarkMulConst (line 126) | func BenchmarkMulConst(b *testing.B) {
function BenchmarkMulConstTo (line 142) | func BenchmarkMulConstTo(b *testing.B) {
function BenchmarkAddConst (line 159) | func BenchmarkAddConst(b *testing.B) {
function BenchmarkSub (line 175) | func BenchmarkSub(b *testing.B) {
function BenchmarkSubTo (line 192) | func BenchmarkSubTo(b *testing.B) {
function BenchmarkMulTo (line 210) | func BenchmarkMulTo(b *testing.B) {
function BenchmarkDivTo (line 228) | func BenchmarkDivTo(b *testing.B) {
function BenchmarkSqrtTo (line 246) | func BenchmarkSqrtTo(b *testing.B) {
function BenchmarkMM (line 263) | func BenchmarkMM(b *testing.B) {
FILE: common/floats/floats_arm64.go
type Feature (line 26) | type Feature
method String (line 35) | func (feature Feature) String() string {
method mulConstAddTo (line 43) | func (feature Feature) mulConstAddTo(a []float32, b float32, c, dst []...
method mulConstAdd (line 47) | func (feature Feature) mulConstAdd(a []float32, b float32, c []float32) {
method mulConstTo (line 51) | func (feature Feature) mulConstTo(a []float32, b float32, c []float32) {
method addConst (line 55) | func (feature Feature) addConst(a []float32, b float32) {
method sub (line 59) | func (feature Feature) sub(a, b []float32) {
method subTo (line 63) | func (feature Feature) subTo(a, b, c []float32) {
method mulTo (line 67) | func (feature Feature) mulTo(a, b, c []float32) {
method divTo (line 71) | func (feature Feature) divTo(a, b, c []float32) {
method sqrtTo (line 75) | func (feature Feature) sqrtTo(a, b []float32) {
method mulConst (line 79) | func (feature Feature) mulConst(a []float32, b float32) {
method dot (line 83) | func (feature Feature) dot(a, b []float32) float32 {
method euclidean (line 87) | func (feature Feature) euclidean(a, b []float32) float32 {
method mm (line 91) | func (feature Feature) mm(transA, transB bool, m, n, k int, a []float3...
constant AMX (line 29) | AMX Feature = 1 << iota
constant OPENBLAS (line 30) | OPENBLAS
FILE: common/floats/floats_arm64_test.go
function TestASIMD (line 29) | func TestASIMD(t *testing.T) {
function TestAMX (line 33) | func TestAMX(t *testing.T) {
function initializeFloat32Array (line 40) | func initializeFloat32Array(n int) []float32 {
function BenchmarkDot (line 48) | func BenchmarkDot(b *testing.B) {
function BenchmarkEuclidean (line 65) | func BenchmarkEuclidean(b *testing.B) {
function BenchmarkMulConstAddTo (line 82) | func BenchmarkMulConstAddTo(b *testing.B) {
function BenchmarkMulConstAdd (line 100) | func BenchmarkMulConstAdd(b *testing.B) {
function BenchmarkMulConstTo (line 117) | func BenchmarkMulConstTo(b *testing.B) {
function BenchmarkAddConst (line 134) | func BenchmarkAddConst(b *testing.B) {
function BenchmarkMulConst (line 150) | func BenchmarkMulConst(b *testing.B) {
function BenchmarkSubTo (line 166) | func BenchmarkSubTo(b *testing.B) {
function BenchmarkSub (line 184) | func BenchmarkSub(b *testing.B) {
function BenchmarkMulTo (line 201) | func BenchmarkMulTo(b *testing.B) {
function BenchmarkDivTo (line 219) | func BenchmarkDivTo(b *testing.B) {
function BenchmarkSqrtTo (line 237) | func BenchmarkSqrtTo(b *testing.B) {
function BenchmarkMM (line 254) | func BenchmarkMM(b *testing.B) {
FILE: common/floats/floats_avx.go
function _mm256_mul_const_add_to (line 14) | func _mm256_mul_const_add_to(a, b, c, dst unsafe.Pointer, n int64)
function _mm256_mul_const_add (line 17) | func _mm256_mul_const_add(a, b, c unsafe.Pointer, n int64)
function _mm256_mul_const_to (line 20) | func _mm256_mul_const_to(a, b, c unsafe.Pointer, n int64)
function _mm256_mul_const (line 23) | func _mm256_mul_const(a, b unsafe.Pointer, n int64)
function _mm256_add_const (line 26) | func _mm256_add_const(a, b unsafe.Pointer, n int64)
function _mm256_sub_to (line 29) | func _mm256_sub_to(a, b, c unsafe.Pointer, n int64)
function _mm256_sub (line 32) | func _mm256_sub(a, b unsafe.Pointer, n int64)
function _mm256_mul_to (line 35) | func _mm256_mul_to(a, b, c unsafe.Pointer, n int64)
function _mm256_div_to (line 38) | func _mm256_div_to(a, b, c unsafe.Pointer, n int64)
function _mm256_sqrt_to (line 41) | func _mm256_sqrt_to(a, b unsafe.Pointer, n int64)
function _mm256_dot (line 44) | func _mm256_dot(a, b unsafe.Pointer, n int64) (result float32)
function _mm256_euclidean (line 47) | func _mm256_euclidean(a, b unsafe.Pointer, n int64) (result float32)
function _mm256_mm (line 50) | func _mm256_mm(transA, transB bool, m, n, k int64, a unsafe.Pointer, lda...
FILE: common/floats/floats_avx512.go
function _mm512_mul_const_add_to (line 14) | func _mm512_mul_const_add_to(a, b, c, dst unsafe.Pointer, n int64)
function _mm512_mul_const_add (line 17) | func _mm512_mul_const_add(a, b, c unsafe.Pointer, n int64)
function _mm512_mul_const_to (line 20) | func _mm512_mul_const_to(a, b, c unsafe.Pointer, n int64)
function _mm512_mul_const (line 23) | func _mm512_mul_const(a, b unsafe.Pointer, n int64)
function _mm512_add_const (line 26) | func _mm512_add_const(a, b unsafe.Pointer, n int64)
function _mm512_sub_to (line 29) | func _mm512_sub_to(a, b, c unsafe.Pointer, n int64)
function _mm512_sub (line 32) | func _mm512_sub(a, b unsafe.Pointer, n int64)
function _mm512_mul_to (line 35) | func _mm512_mul_to(a, b, c unsafe.Pointer, n int64)
function _mm512_div_to (line 38) | func _mm512_div_to(a, b, c unsafe.Pointer, n int64)
function _mm512_sqrt_to (line 41) | func _mm512_sqrt_to(a, b unsafe.Pointer, n int64)
function _mm512_dot (line 44) | func _mm512_dot(a, b unsafe.Pointer, n int64) (result float32)
function _mm512_euclidean (line 47) | func _mm512_euclidean(a, b unsafe.Pointer, n int64) (result float32)
function _mm512_mm (line 50) | func _mm512_mm(transA, transB bool, m, n, k int64, a unsafe.Pointer, lda...
FILE: common/floats/floats_neon.go
function vmul_const_add_to (line 14) | func vmul_const_add_to(a, b, c, dst unsafe.Pointer, n int64)
function vmul_const_add (line 17) | func vmul_const_add(a, b, c unsafe.Pointer, n int64)
function vmul_const_to (line 20) | func vmul_const_to(a, b, c unsafe.Pointer, n int64)
function vmul_const (line 23) | func vmul_const(a, b unsafe.Pointer, n int64)
function vadd_const (line 26) | func vadd_const(a, b unsafe.Pointer, n int64)
function vsub_to (line 29) | func vsub_to(a, b, c unsafe.Pointer, n int64)
function vsub (line 32) | func vsub(a, b unsafe.Pointer, n int64)
function vmul_to (line 35) | func vmul_to(a, b, c unsafe.Pointer, n int64)
function vdiv_to (line 38) | func vdiv_to(a, b, c unsafe.Pointer, n int64)
function vsqrt_to (line 41) | func vsqrt_to(a, b unsafe.Pointer, n int64)
function vdot (line 44) | func vdot(a, b unsafe.Pointer, n int64) (result float32)
function veuclidean (line 47) | func veuclidean(a, b unsafe.Pointer, n int64) (result float32)
function vmm (line 50) | func vmm(transA, transB bool, m, n, k int64, a unsafe.Pointer, lda int64...
FILE: common/floats/floats_noasm.go
type Feature (line 19) | type Feature
method String (line 25) | func (Feature) String() string {
method mulConstAddTo (line 29) | func (Feature) mulConstAddTo(a []float32, b float32, c, dst []float32) {
method mulConstAdd (line 33) | func (Feature) mulConstAdd(a []float32, b float32, c []float32) {
method mulConstTo (line 37) | func (Feature) mulConstTo(a []float32, b float32, c []float32) {
method addConst (line 41) | func (Feature) addConst(a []float32, b float32) {
method sub (line 45) | func (Feature) sub(a, b []float32) {
method subTo (line 49) | func (Feature) subTo(a, b, c []float32) {
method mulTo (line 53) | func (Feature) mulTo(a, b, c []float32) {
method mulConst (line 57) | func (Feature) mulConst(a []float32, b float32) {
method divTo (line 61) | func (Feature) divTo(a, b, c []float32) {
method sqrtTo (line 65) | func (Feature) sqrtTo(a, b []float32) {
method dot (line 69) | func (Feature) dot(a, b []float32) float32 {
method euclidean (line 73) | func (Feature) euclidean(a, b []float32) float32 {
method mm (line 77) | func (Feature) mm(transA, transB bool, m, n, k int, a []float32, lda i...
constant OPENBLAS (line 21) | OPENBLAS Feature = 1 << iota
FILE: common/floats/floats_riscv64.go
type Feature (line 27) | type Feature
method String (line 42) | func (feature Feature) String() string {
method mulConstAddTo (line 50) | func (feature Feature) mulConstAddTo(a []float32, b float32, c []float...
method mulConstAdd (line 58) | func (feature Feature) mulConstAdd(a []float32, b float32, c []float32) {
method mulConstTo (line 66) | func (feature Feature) mulConstTo(a []float32, b float32, c []float32) {
method addConst (line 74) | func (feature Feature) addConst(a []float32, b float32) {
method sub (line 82) | func (feature Feature) sub(a, b []float32) {
method subTo (line 90) | func (feature Feature) subTo(a, b, c []float32) {
method mulTo (line 98) | func (feature Feature) mulTo(a, b, c []float32) {
method mulConst (line 106) | func (feature Feature) mulConst(a []float32, b float32) {
method divTo (line 114) | func (feature Feature) divTo(a, b, c []float32) {
method sqrtTo (line 122) | func (feature Feature) sqrtTo(a, b []float32) {
method dot (line 130) | func (feature Feature) dot(a, b []float32) float32 {
method euclidean (line 138) | func (feature Feature) euclidean(a, b []float32) float32 {
method mm (line 146) | func (feature Feature) mm(transA, transB bool, m, n, k int, a []float3...
constant V (line 30) | V Feature = 1 << iota
constant OPENBLAS (line 31) | OPENBLAS
function init (line 36) | func init() {
FILE: common/floats/floats_riscv64_test.go
function TestV (line 28) | func TestV(t *testing.T) {
function initializeFloat32Array (line 32) | func initializeFloat32Array(n int) []float32 {
function BenchmarkDot (line 40) | func BenchmarkDot(b *testing.B) {
function BenchmarkEuclidean (line 57) | func BenchmarkEuclidean(b *testing.B) {
function BenchmarkMulConstAddTo (line 74) | func BenchmarkMulConstAddTo(b *testing.B) {
function BenchmarkMulConstAdd (line 92) | func BenchmarkMulConstAdd(b *testing.B) {
function BenchmarkMulConst (line 109) | func BenchmarkMulConst(b *testing.B) {
function BenchmarkMulConstTo (line 125) | func BenchmarkMulConstTo(b *testing.B) {
function BenchmarkAddConst (line 142) | func BenchmarkAddConst(b *testing.B) {
function BenchmarkSub (line 158) | func BenchmarkSub(b *testing.B) {
function BenchmarkSubTo (line 175) | func BenchmarkSubTo(b *testing.B) {
function BenchmarkMulTo (line 193) | func BenchmarkMulTo(b *testing.B) {
function BenchmarkDivTo (line 211) | func BenchmarkDivTo(b *testing.B) {
function BenchmarkSqrtTo (line 229) | func BenchmarkSqrtTo(b *testing.B) {
function BenchmarkMM (line 246) | func BenchmarkMM(b *testing.B) {
FILE: common/floats/floats_rvv.go
function vmul_const_add_to (line 14) | func vmul_const_add_to(a, b, c, dst unsafe.Pointer, n int64)
function vmul_const_add (line 17) | func vmul_const_add(a, b, c unsafe.Pointer, n int64)
function vmul_const_to (line 20) | func vmul_const_to(a, b, c unsafe.Pointer, n int64)
function vmul_const (line 23) | func vmul_const(a, b unsafe.Pointer, n int64)
function vadd_const (line 26) | func vadd_const(a, b unsafe.Pointer, n int64)
function vsub_to (line 29) | func vsub_to(a, b, c unsafe.Pointer, n int64)
function vsub (line 32) | func vsub(a, b unsafe.Pointer, n int64)
function vmul_to (line 35) | func vmul_to(a, b, c unsafe.Pointer, n int64)
function vdiv_to (line 38) | func vdiv_to(a, b, c unsafe.Pointer, n int64)
function vsqrt_to (line 41) | func vsqrt_to(a, b unsafe.Pointer, n int64)
function vdot (line 44) | func vdot(a, b unsafe.Pointer, n int64) (result float32)
function veuclidean (line 47) | func veuclidean(a, b unsafe.Pointer, n int64) (result float32)
function vmm (line 50) | func vmm(transA, transB bool, m, n, k int64, a unsafe.Pointer, lda int64...
FILE: common/floats/floats_test.go
function TestMatZero (line 24) | func TestMatZero(t *testing.T) {
function TestZero (line 36) | func TestZero(t *testing.T) {
function TestAdd (line 42) | func TestAdd(t *testing.T) {
function TestSub (line 50) | func TestSub(t *testing.T) {
function TestSubTo (line 58) | func TestSubTo(t *testing.T) {
function TestMulTo (line 67) | func TestMulTo(t *testing.T) {
function TestMulConst (line 76) | func TestMulConst(t *testing.T) {
function TestDiv (line 82) | func TestDiv(t *testing.T) {
function TestMulConstTo (line 90) | func TestMulConstTo(t *testing.T) {
function TestMulConstAdd (line 99) | func TestMulConstAdd(t *testing.T) {
function TestMulConstAddTo (line 108) | func TestMulConstAddTo(t *testing.T) {
function TestMulAddTo (line 117) | func TestMulAddTo(t *testing.T) {
function TestAddTo (line 127) | func TestAddTo(t *testing.T) {
function TestAddConst (line 137) | func TestAddConst(t *testing.T) {
function TestDivTo (line 143) | func TestDivTo(t *testing.T) {
function TestSqrtTo (line 152) | func TestSqrtTo(t *testing.T) {
function TestSqrt (line 160) | func TestSqrt(t *testing.T) {
function TestDot (line 166) | func TestDot(t *testing.T) {
function TestEuclidean (line 173) | func TestEuclidean(t *testing.T) {
type NativeTestSuite (line 180) | type NativeTestSuite struct
method TestDot (line 184) | func (suite *NativeTestSuite) TestDot() {
method TestEuclidean (line 190) | func (suite *NativeTestSuite) TestEuclidean() {
method TestMulConstAddTo (line 196) | func (suite *NativeTestSuite) TestMulConstAddTo() {
method TestMulConstAdd (line 204) | func (suite *NativeTestSuite) TestMulConstAdd() {
method TestMulConstTo (line 212) | func (suite *NativeTestSuite) TestMulConstTo() {
method TestAddConst (line 220) | func (suite *NativeTestSuite) TestAddConst() {
method TestSub (line 226) | func (suite *NativeTestSuite) TestSub() {
method TestSubTo (line 233) | func (suite *NativeTestSuite) TestSubTo() {
method TestMulTo (line 241) | func (suite *NativeTestSuite) TestMulTo() {
method TestDivTo (line 249) | func (suite *NativeTestSuite) TestDivTo() {
method TestSqrtTo (line 257) | func (suite *NativeTestSuite) TestSqrtTo() {
method TestMulConst (line 264) | func (suite *NativeTestSuite) TestMulConst() {
method TestMM (line 270) | func (suite *NativeTestSuite) TestMM() {
function TestNativeTestSuite (line 294) | func TestNativeTestSuite(t *testing.T) {
type SIMDTestSuite (line 298) | type SIMDTestSuite struct
method SetupSuite (line 303) | func (suite *SIMDTestSuite) SetupSuite() {
method TestMulConstAddTo (line 309) | func (suite *SIMDTestSuite) TestMulConstAddTo() {
method TestMulConstAdd (line 319) | func (suite *SIMDTestSuite) TestMulConstAdd() {
method TestMulConstTo (line 328) | func (suite *SIMDTestSuite) TestMulConstTo() {
method TestAddConst (line 337) | func (suite *SIMDTestSuite) TestAddConst() {
method TestSub (line 345) | func (suite *SIMDTestSuite) TestSub() {
method TestSubTo (line 354) | func (suite *SIMDTestSuite) TestSubTo() {
method TestMulTo (line 364) | func (suite *SIMDTestSuite) TestMulTo() {
method TestMulConst (line 373) | func (suite *SIMDTestSuite) TestMulConst() {
method TestDivTo (line 381) | func (suite *SIMDTestSuite) TestDivTo() {
method TestSqrtTo (line 391) | func (suite *SIMDTestSuite) TestSqrtTo() {
method TestDot (line 400) | func (suite *SIMDTestSuite) TestDot() {
method TestEuclidean (line 408) | func (suite *SIMDTestSuite) TestEuclidean() {
method TestMM (line 416) | func (suite *SIMDTestSuite) TestMM() {
FILE: common/floats/mm.go
function mm (line 19) | func mm(transA, transB bool, m, n, k int, a []float32, lda int, b []floa...
FILE: common/floats/mm_darwin_arm64.go
function init (line 21) | func init() {
function mm (line 25) | func mm(transA, transB bool, m, n, k int, a []float32, lda int, b []floa...
FILE: common/floats/mm_mkl.go
function init (line 21) | func init() {
function mm (line 25) | func mm(transA, transB bool, m, n, k int, a []float32, lda int, b []floa...
FILE: common/floats/mm_openblas.go
function init (line 21) | func init() {
function mm (line 25) | func mm(transA, transB bool, m, n, k int, a []float32, lda int, b []floa...
FILE: common/floats/src/floats_avx.c
function _mm256_mul_const_add_to (line 18) | void _mm256_mul_const_add_to(float *a, float *b, float *c, float *dst, i...
function _mm256_mul_const_add (line 39) | void _mm256_mul_const_add(float *a, float *b, float *c, int64_t n)
function _mm256_mul_const_to (line 59) | void _mm256_mul_const_to(float *a, float *b, float *c, int64_t n)
function _mm256_mul_const (line 78) | void _mm256_mul_const(float *a, float *b, int64_t n)
function _mm256_add_const (line 96) | void _mm256_add_const(float *a, float *b, int64_t n)
function _mm256_sub_to (line 114) | void _mm256_sub_to(float *a, float *b, float *c, int64_t n)
function _mm256_sub (line 134) | void _mm256_sub(float *a, float *b, int64_t n)
function _mm256_mul_to (line 153) | void _mm256_mul_to(float *a, float *b, float *c, int64_t n)
function _mm256_div_to (line 173) | void _mm256_div_to(float *a, float *b, float *c, int64_t n)
function _mm256_sqrt_to (line 193) | void _mm256_sqrt_to(float *a, float *b, int64_t n)
function dot (line 213) | inline __attribute__((always_inline)) float dot(float *a, float *b, int6...
function _mm256_dot (line 251) | float _mm256_dot(float *a, float *b, int64_t n)
function _mm256_euclidean (line 256) | float _mm256_euclidean(float *a, float *b, int64_t n)
function _mm256_mm (line 299) | void _mm256_mm(_Bool transA, _Bool transB, int64_t m, int64_t n, int64_t...
FILE: common/floats/src/floats_avx512.c
function _mm512_mul_const_add_to (line 18) | void _mm512_mul_const_add_to(float *a, float *b, float *c, float *dst, i...
function _mm512_mul_const_add (line 51) | void _mm512_mul_const_add(float *a, float *b, float *c, int64_t n)
function _mm512_mul_const_to (line 82) | void _mm512_mul_const_to(float *a, float *b, float *c, int64_t n)
function _mm512_mul_const (line 111) | void _mm512_mul_const(float *a, float *b, int64_t n)
function _mm512_add_const (line 138) | void _mm512_add_const(float *a, float *b, int64_t n)
function _mm512_sub_to (line 165) | void _mm512_sub_to(float *a, float *b, float *c, int64_t n)
function _mm512_sub (line 196) | void _mm512_sub(float *a, float *b, int64_t n)
function _mm512_mul_to (line 215) | void _mm512_mul_to(float *a, float *b, float *c, int64_t n)
function _mm512_div_to (line 246) | void _mm512_div_to(float *a, float *b, float *c, int64_t n)
function _mm512_sqrt_to (line 277) | void _mm512_sqrt_to(float *a, float *b, int64_t n)
function dot (line 306) | inline __attribute__((always_inline)) float dot(float *a, float *b, int6...
function _mm512_dot (line 369) | float _mm512_dot(float *a, float *b, int64_t n)
function _mm512_euclidean (line 374) | float _mm512_euclidean(float *a, float *b, int64_t n)
function _mm512_mm (line 443) | void _mm512_mm(_Bool transA, _Bool transB, int64_t m, int64_t n, int64_t...
FILE: common/floats/src/floats_neon.c
function vmul_const_add_to (line 18) | void vmul_const_add_to(float *a, float *b, float *c, float *dst, long n) {
function vmul_const_add (line 24) | void vmul_const_add(float *a, float *b, float *c, long n) {
function vmul_const_to (line 30) | void vmul_const_to(float *a, float *b, float *c, long n) {
function vmul_const (line 36) | void vmul_const(float *a, float *b, long n) {
function vadd_const (line 42) | void vadd_const(float *a, float *b, long n) {
function vsub_to (line 48) | void vsub_to(float *a, float *b, float *c, long n) {
function vsub (line 54) | void vsub(float *a, float *b, long n) {
function vmul_to (line 60) | void vmul_to(float *a, float *b, float *c, long n) {
function vdiv_to (line 66) | void vdiv_to(float *a, float *b, float *c, long n) {
function vsqrt_to (line 72) | void vsqrt_to(float *a, float *b, long n) {
function dot (line 89) | inline float dot(float *a, float *b, long n) {
function vdot (line 119) | float vdot(float *a, float *b, long n) {
function veuclidean (line 123) | float veuclidean(float *a, float *b, long n) {
function vmm (line 157) | void vmm(_Bool transA, _Bool transB, long m, long n, long k, float *a, l...
FILE: common/floats/src/floats_rvv.c
function vmul_const_add_to (line 17) | void vmul_const_add_to(float *a, float *b, float *c, float *dst, long n) {
function vmul_const_add (line 23) | void vmul_const_add(float *a, float *b, float *c, long n) {
function vmul_const_to (line 29) | void vmul_const_to(float *a, float *b, float *c, long n) {
function vmul_const (line 35) | void vmul_const(float *a, float *b, long n) {
function vadd_const (line 41) | void vadd_const(float *a, float *b, long n) {
function vsub_to (line 47) | void vsub_to(float *a, float *b, float *c, long n) {
function vsub (line 53) | void vsub(float *a, float *b, long n) {
function vmul_to (line 59) | void vmul_to(float *a, float *b, float *c, long n) {
function vdiv_to (line 65) | void vdiv_to(float *a, float *b, float *c, long n) {
function vsqrt_to (line 71) | void vsqrt_to(float *a, float *b, long n) {
function dot (line 80) | inline float dot(float *a, float *b, long n) {
function vdot (line 102) | float vdot(float *a, float *b, long n) {
function veuclidean (line 106) | float veuclidean(float *a, float *b, long n) {
function vmm (line 131) | void vmm(_Bool transA, _Bool transB, long m, long n, long k, float *a, l...
FILE: common/floats/src/floats_sve2.c
function svmul_const_add_to (line 18) | void svmul_const_add_to(float *a, float *b, float *c, long n)
function svmul_const_to (line 29) | void svmul_const_to(float *a, float *b, float *c, long n)
function svmul_const (line 39) | void svmul_const(float *a, float *b, long n)
function svmul_to (line 49) | void svmul_to(float *a, float *b, float *c, long n)
FILE: common/floats/src/floats_test.c
function mul_const_add_to (line 9) | void mul_const_add_to(float *a, float *b, float *c, float *dst, int64_t n)
function mul_const_add (line 17) | void mul_const_add(float *a, float *b, float *c, int64_t n)
function mul_const_to (line 25) | void mul_const_to(float *a, float *b, float *c, int64_t n)
function mul_const (line 33) | void mul_const(float *a, float *b, int64_t n)
function sub_to (line 41) | void sub_to(float *a, float *b, float *c, int64_t n)
function sub (line 49) | void sub(float *a, float *b, int64_t n)
function mul_to (line 57) | void mul_to(float *a, float *b, float *c, int64_t n)
function div_to (line 65) | void div_to(float *a, float *b, float *c, int64_t n)
function sqrt_to (line 73) | void sqrt_to(float *a, float *b, int64_t n)
function dot (line 81) | float dot(float *a, float *b, int64_t n)
function euclidean (line 91) | float euclidean(float *a, float *b, int64_t n)
function rand_float (line 101) | int rand_float(float *a, int64_t n)
function MunitResult (line 135) | MunitResult mm256_mul_const_add_to_test(const MunitParameter params[], v...
function MunitResult (line 148) | MunitResult mm256_mul_const_add_test(const MunitParameter params[], void...
function MunitResult (line 162) | MunitResult mm256_mul_const_to_test(const MunitParameter params[], void ...
function MunitResult (line 174) | MunitResult mm256_mul_const_test(const MunitParameter params[], void *us...
function MunitResult (line 187) | MunitResult mm256_sub_to_test(const MunitParameter params[], void *user_...
function MunitResult (line 199) | MunitResult mm256_sub_test(const MunitParameter params[], void *user_dat...
function MunitResult (line 212) | MunitResult mm256_mul_to_test(const MunitParameter params[], void *user_...
function MunitResult (line 224) | MunitResult mm256_div_to_test(const MunitParameter params[], void *user_...
function MunitResult (line 236) | MunitResult mm256_sqrt_to_test(const MunitParameter params[], void *user...
function MunitResult (line 248) | MunitResult mm256_dot_test(const MunitParameter params[], void *user_dat...
function MunitResult (line 260) | MunitResult mm256_euclidean_test(const MunitParameter params[], void *us...
function MunitResult (line 289) | MunitResult mm512_mul_const_add_to_test(const MunitParameter params[], v...
function MunitResult (line 304) | MunitResult mm512_mul_const_add_test(const MunitParameter params[], void...
function MunitResult (line 318) | MunitResult mm512_mul_const_to_test(const MunitParameter params[], void ...
function MunitResult (line 330) | MunitResult mm512_mul_const_test(const MunitParameter params[], void *us...
function MunitResult (line 343) | MunitResult mm512_sub_test(const MunitParameter params[], void *user_dat...
function MunitResult (line 356) | MunitResult mm512_sub_to_test(const MunitParameter params[], void *user_...
function MunitResult (line 368) | MunitResult mm512_mul_to_test(const MunitParameter params[], void *user_...
function MunitResult (line 380) | MunitResult mm512_div_to_test(const MunitParameter params[], void *user_...
function MunitResult (line 392) | MunitResult mm512_sqrt_to_test(const MunitParameter params[], void *user...
function MunitResult (line 404) | MunitResult mm512_dot_test(const MunitParameter params[], void *user_dat...
function MunitResult (line 416) | MunitResult mm512_euclidean_test(const MunitParameter params[], void *us...
function main (line 445) | int main(int argc, char *const argv[MUNIT_ARRAY_PARAM(argc + 1)])
function MunitResult (line 466) | MunitResult vmul_const_add_to_test(const MunitParameter params[], void *...
function MunitResult (line 479) | MunitResult vmul_const_add_test(const MunitParameter params[], void *use...
function MunitResult (line 493) | MunitResult vmul_const_to_test(const MunitParameter params[], void *user...
function MunitResult (line 505) | MunitResult vmul_const_test(const MunitParameter params[], void *user_da...
function MunitResult (line 518) | MunitResult vmul_to_test(const MunitParameter params[], void *user_data_...
function MunitResult (line 530) | MunitResult vdot_test(const MunitParameter params[], void *user_data_or_...
function MunitResult (line 542) | MunitResult veuclidean_test(const MunitParameter params[], void *user_da...
function MunitResult (line 571) | MunitResult svmul_const_add_to_test(const MunitParameter params[], void ...
function MunitResult (line 584) | MunitResult svmul_const_to_test(const MunitParameter params[], void *use...
function MunitResult (line 596) | MunitResult svmul_const_test(const MunitParameter params[], void *user_d...
function MunitResult (line 609) | MunitResult svmul_to_test(const MunitParameter params[], void *user_data...
function main (line 631) | int main(int argc, char *const argv[MUNIT_ARRAY_PARAM(argc + 1)])
function MunitResult (line 652) | MunitResult vmul_const_add_to_test(const MunitParameter params[], void *...
function MunitResult (line 665) | MunitResult vmul_const_add_test(const MunitParameter params[], void *use...
function MunitResult (line 679) | MunitResult vmul_const_to_test(const MunitParameter params[], void *user...
function MunitResult (line 691) | MunitResult vmul_const_test(const MunitParameter params[], void *user_da...
function MunitResult (line 704) | MunitResult vmul_to_test(const MunitParameter params[], void *user_data_...
function MunitResult (line 716) | MunitResult vsqrt_to_test(const MunitParameter params[], void *user_data...
function MunitResult (line 728) | MunitResult vdot_test(const MunitParameter params[], void *user_data_or_...
function MunitResult (line 740) | MunitResult veuclidean_test(const MunitParameter params[], void *user_da...
function main (line 765) | int main(int argc, char *const argv[MUNIT_ARRAY_PARAM(argc + 1)])
FILE: common/floats/src/munit.c
function munit_logf_exv (line 168) | static void
function munit_logf_internal (line 199) | static void
function munit_log_internal (line 208) | static void
function munit_logf_ex (line 213) | void
function munit_errorf_ex (line 230) | void
function munit_log_errno (line 253) | static void
type PsnipClockType (line 327) | enum PsnipClockType {
type PsnipClockTimespec (line 343) | struct PsnipClockTimespec {
function PSNIP_CLOCK__FUNCTION (line 520) | PSNIP_CLOCK__FUNCTION psnip_uint32_t
function PSNIP_CLOCK__FUNCTION (line 532) | PSNIP_CLOCK__FUNCTION int
function psnip_clock_wall_get_precision (line 547) | psnip_clock_wall_get_precision (void) {
function PSNIP_CLOCK__FUNCTION (line 561) | PSNIP_CLOCK__FUNCTION int
function psnip_clock_cpu_get_precision (line 588) | psnip_clock_cpu_get_precision (void) {
function PSNIP_CLOCK__FUNCTION (line 602) | PSNIP_CLOCK__FUNCTION int
function psnip_clock_monotonic_get_precision (line 646) | psnip_clock_monotonic_get_precision (void) {
function PSNIP_CLOCK__FUNCTION (line 667) | PSNIP_CLOCK__FUNCTION int
function PSNIP_CLOCK__FUNCTION (line 717) | PSNIP_CLOCK__FUNCTION psnip_uint32_t
function PSNIP_CLOCK__FUNCTION (line 734) | PSNIP_CLOCK__FUNCTION int
function psnip_uint64_t (line 752) | static psnip_uint64_t
function munit_atomic_store (line 817) | static inline void
function munit_atomic_load (line 823) | static inline uint32_t
function munit_atomic_cas (line 831) | static inline uint32_t
function munit_bool (line 871) | static inline munit_bool
function munit_uint32_t (line 885) | static munit_uint32_t
function munit_uint32_t (line 890) | static munit_uint32_t
function munit_rand_seed (line 897) | void
function munit_uint32_t (line 903) | static munit_uint32_t
function munit_uint32_t (line 919) | static munit_uint32_t
function munit_uint32_t (line 926) | munit_uint32_t
function munit_rand_state_memory (line 938) | static void
function munit_rand_memory (line 955) | void
function munit_uint32_t (line 965) | static munit_uint32_t
function munit_uint32_t (line 986) | static munit_uint32_t
function munit_rand_int_range (line 999) | int
function munit_rand_double (line 1012) | double
type MunitReport (line 1031) | typedef struct {
type MunitTestRunner (line 1042) | typedef struct {
function munit_print_time (line 1069) | static void
function MunitResult (line 1076) | static MunitResult
function munit_maybe_free_concat (line 1123) | static void
function munit_uint32_t (line 1130) | static munit_uint32_t
function munit_splice (line 1141) | static void
function MunitResult (line 1170) | static MunitResult
function munit_test_runner_print_color (line 1246) | static void
function munit_replace_stderr (line 1255) | static int
function munit_restore_stderr (line 1273) | static void
function munit_test_runner_run_test_with_params (line 1283) | static void
function munit_test_runner_run_test_wild (line 1519) | static void
function munit_test_runner_run_test (line 1552) | static void
function munit_test_runner_run_suite (line 1655) | static void
function munit_test_runner_run (line 1694) | static void
function munit_print_help (line 1699) | static void
function MunitArgument (line 1752) | static const MunitArgument*
function munit_suite_list_tests (line 1763) | static void
function munit_bool (line 1812) | static munit_bool
function munit_suite_main_custom (line 1834) | int
function munit_suite_main (line 2051) | int
FILE: common/floats/src/munit.h
type MunitLogLevel (line 172) | typedef enum {
type MunitResult (line 439) | typedef enum {
type MunitParameterEnum (line 452) | typedef struct {
type MunitParameter (line 457) | typedef struct {
type MunitTestOptions (line 464) | typedef enum {
type MunitResult (line 470) | typedef MunitResult (* MunitTestFunc)(const MunitParameter params[], voi...
type MunitTest (line 474) | typedef struct {
type MunitSuiteOptions (line 483) | typedef enum {
type MunitSuite (line 487) | typedef struct MunitSuite_ MunitSuite;
type MunitSuite_ (line 489) | struct MunitSuite_ {
type MunitArgument (line 502) | typedef struct MunitArgument_ MunitArgument;
type MunitArgument_ (line 504) | struct MunitArgument_ {
FILE: common/heap/filter.go
type TopKFilter (line 24) | type TopKFilter struct
function NewTopKFilter (line 30) | func NewTopKFilter[T any, W constraints.Ordered](k int) *TopKFilter[T, W] {
method Push (line 36) | func (filter *TopKFilter[T, W]) Push(item T, weight W) {
method PopAllValues (line 44) | func (filter *TopKFilter[T, W]) PopAllValues() []T {
method PopAll (line 54) | func (filter *TopKFilter[T, W]) PopAll() []Elem[T, W] {
FILE: common/heap/filter_test.go
function TestTopKFilter (line 22) | func TestTopKFilter(t *testing.T) {
function TestTopKStringFilter (line 48) | func TestTopKStringFilter(t *testing.T) {
FILE: common/heap/pq.go
type Elem (line 28) | type Elem struct
type _heap (line 33) | type _heap struct
method Len (line 38) | func (e *_heap[T, W]) Len() int {
method Less (line 42) | func (e *_heap[T, W]) Less(i, j int) bool {
method Swap (line 50) | func (e *_heap[T, W]) Swap(i, j int) {
method Push (line 54) | func (e *_heap[T, W]) Push(x interface{}) {
method Pop (line 59) | func (e *_heap[T, W]) Pop() interface{} {
type PriorityQueue (line 67) | type PriorityQueue struct
method Push (line 81) | func (p *PriorityQueue) Push(v int32, weight float32) {
method Pop (line 96) | func (p *PriorityQueue) Pop() (int32, float32) {
method Peek (line 101) | func (p *PriorityQueue) Peek() (int32, float32) {
method Values (line 105) | func (p *PriorityQueue) Values() []int32 {
method Elems (line 113) | func (p *PriorityQueue) Elems() []Elem[int32, float32] {
method Clone (line 117) | func (p *PriorityQueue) Clone() *PriorityQueue {
method Reverse (line 124) | func (p *PriorityQueue) Reverse() *PriorityQueue {
method Marshal (line 133) | func (p *PriorityQueue) Marshal(w io.Writer) error {
method Unmarshal (line 140) | func (p *PriorityQueue) Unmarshal(r io.Reader) error {
function NewPriorityQueue (line 73) | func NewPriorityQueue(desc bool) *PriorityQueue {
FILE: common/heap/pq_test.go
function TestPriorityQueue (line 28) | func TestPriorityQueue(t *testing.T) {
function TestMarshalUnmarshal (line 63) | func TestMarshalUnmarshal(t *testing.T) {
FILE: common/jsonutil/json.go
function Marshal (line 20) | func Marshal(v interface{}) ([]byte, error) {
function Unmarshal (line 27) | func Unmarshal(data []byte, v interface{}) error {
function MustMarshal (line 35) | func MustMarshal(v interface{}) string {
FILE: common/jsonutil/json_test.go
function TestUnmarshal (line 23) | func TestUnmarshal(t *testing.T) {
function TestMarshal (line 34) | func TestMarshal(t *testing.T) {
function TestMustMarshal (line 40) | func TestMustMarshal(t *testing.T) {
FILE: common/log/log.go
function init (line 39) | func init() {
function Logger (line 67) | func Logger() *zap.Logger {
function ResponseLogger (line 71) | func ResponseLogger(resp *restful.Response) *zap.Logger {
function CloseLogger (line 75) | func CloseLogger() {
function AddFlags (line 85) | func AddFlags(flagSet *pflag.FlagSet) {
function SetLogger (line 92) | func SetLogger(flagSet *pflag.FlagSet, debug bool) {
constant mysqlPrefix (line 125) | mysqlPrefix = "mysql://"
function RedactDBURL (line 127) | func RedactDBURL(rawURL string) string {
function GetErrorHandler (line 150) | func GetErrorHandler() otel.ErrorHandler {
type errorHandler (line 154) | type errorHandler struct
method Handle (line 156) | func (h *errorHandler) Handle(err error) {
function OpenAILogger (line 160) | func OpenAILogger() *zap.Logger {
function InitOpenAILogger (line 164) | func InitOpenAILogger(filename string) {
type OptunaLogger (line 176) | type OptunaLogger struct
method Debug (line 184) | func (o OptunaLogger) Debug(msg string, fields ...interface{}) {
method Info (line 188) | func (o OptunaLogger) Info(msg string, fields ...interface{}) {
method Warn (line 192) | func (o OptunaLogger) Warn(msg string, fields ...interface{}) {
method Error (line 196) | func (o OptunaLogger) Error(msg string, fields ...interface{}) {
function NewOptunaLogger (line 180) | func NewOptunaLogger(logger *zap.Logger) goptuna.Logger {
FILE: common/log/log_test.go
function TestSetDevelopmentLogger (line 25) | func TestSetDevelopmentLogger(t *testing.T) {
function TestSetProductionLogger (line 44) | func TestSetProductionLogger(t *testing.T) {
function TestRedactDBURL (line 63) | func TestRedactDBURL(t *testing.T) {
FILE: common/mock/openai.go
type OpenAIServer (line 30) | type OpenAIServer struct
method Start (line 59) | func (s *OpenAIServer) Start() error {
method BaseURL (line 69) | func (s *OpenAIServer) BaseURL() string {
method AuthToken (line 73) | func (s *OpenAIServer) AuthToken() string {
method Ready (line 77) | func (s *OpenAIServer) Ready() {
method Close (line 81) | func (s *OpenAIServer) Close() error {
method chatCompletion (line 85) | func (s *OpenAIServer) chatCompletion(req *restful.Request, resp *rest...
method embeddings (line 122) | func (s *OpenAIServer) embeddings(req *restful.Request, resp *restful....
function NewOpenAIServer (line 37) | func NewOpenAIServer() *OpenAIServer {
function Hash (line 144) | func Hash(input string) []float32 {
FILE: common/mock/openai_test.go
type OpenAITestSuite (line 27) | type OpenAITestSuite struct
method SetupSuite (line 33) | func (suite *OpenAITestSuite) SetupSuite() {
method TearDownSuite (line 46) | func (suite *OpenAITestSuite) TearDownSuite() {
method TestChatCompletion (line 50) | func (suite *OpenAITestSuite) TestChatCompletion() {
method TestChatCompletionStream (line 67) | func (suite *OpenAITestSuite) TestChatCompletionStream() {
method TestEmbeddings (line 99) | func (suite *OpenAITestSuite) TestEmbeddings() {
function TestOpenAITestSuite (line 111) | func TestOpenAITestSuite(t *testing.T) {
FILE: common/monitor/progress.go
type spanKeyType (line 28) | type spanKeyType
type Status (line 32) | type Status
constant StatusPending (line 35) | StatusPending Status = "Pending"
constant StatusComplete (line 36) | StatusComplete Status = "Complete"
constant StatusRunning (line 37) | StatusRunning Status = "Running"
constant StatusSuspended (line 38) | StatusSuspended Status = "Suspended"
constant StatusFailed (line 39) | StatusFailed Status = "Failed"
type Monitor (line 42) | type Monitor struct
method Start (line 52) | func (t *Monitor) Start(ctx context.Context, name string, total int) (...
method List (line 63) | func (t *Monitor) List() []Progress {
function NewTracer (line 47) | func NewTracer(name string) *Monitor {
type Span (line 79) | type Span struct
method Add (line 90) | func (s *Span) Add(n int) {
method End (line 94) | func (s *Span) End() {
method Fail (line 102) | func (s *Span) Fail(err error) {
method Count (line 107) | func (s *Span) Count() int {
method Progress (line 111) | func (s *Span) Progress() Progress {
function Start (line 156) | func Start(ctx context.Context, name string, total int) (context.Context...
function Fail (line 175) | func Fail(ctx context.Context, err error) {
type Progress (line 183) | type Progress struct
function DecodeProgress (line 194) | func DecodeProgress(in *protocol.PushProgressRequest) []Progress {
function EncodeProgress (line 210) | func EncodeProgress(progressList []Progress) *protocol.PushProgressReque...
FILE: common/monitor/progress_test.go
type ProgressTestSuite (line 25) | type ProgressTestSuite struct
method SetupTest (line 30) | func (suite *ProgressTestSuite) SetupTest() {
function TestProgressTestSuite (line 34) | func TestProgressTestSuite(t *testing.T) {
function TestEncodeDecode (line 38) | func TestEncodeDecode(t *testing.T) {
FILE: common/nn/functions.go
function Neg (line 21) | func Neg(x *Tensor) *Tensor {
function Add (line 26) | func Add(x0 *Tensor, x ...*Tensor) *Tensor {
function Sub (line 43) | func Sub(x0, x1 *Tensor) *Tensor {
function Mul (line 56) | func Mul(x0, x1 *Tensor) *Tensor {
function Div (line 69) | func Div(x0, x1 *Tensor) *Tensor {
function Square (line 82) | func Square(x *Tensor) *Tensor {
function Pow (line 87) | func Pow(x *Tensor, n *Tensor) *Tensor {
function Exp (line 100) | func Exp(x *Tensor) *Tensor {
function Log (line 105) | func Log(x *Tensor) *Tensor {
function Sin (line 110) | func Sin(x *Tensor) *Tensor {
function Cos (line 114) | func Cos(x *Tensor) *Tensor {
function Abs (line 118) | func Abs(x *Tensor) *Tensor {
function Sum (line 123) | func Sum(x *Tensor, along ...int) *Tensor {
function Mean (line 133) | func Mean(x *Tensor) *Tensor {
function MatMul (line 137) | func MatMul(x, y *Tensor, transpose1, transpose2 bool, jobs int) *Tensor {
function BMM (line 146) | func BMM(x, y *Tensor, transpose1, transpose2 bool, jobs int) *Tensor {
function Broadcast (line 155) | func Broadcast(x *Tensor, shape ...int) *Tensor {
function Flatten (line 159) | func Flatten(x *Tensor) *Tensor {
function Reshape (line 163) | func Reshape(x *Tensor, shape ...int) *Tensor {
function Embedding (line 178) | func Embedding(w, x *Tensor) *Tensor {
function Sigmoid (line 182) | func Sigmoid(x *Tensor) *Tensor {
function ReLu (line 186) | func ReLu(x *Tensor) *Tensor {
function Softmax (line 190) | func Softmax(x *Tensor, axis int) *Tensor {
function MeanSquareError (line 194) | func MeanSquareError(x, y *Tensor) *Tensor {
function SoftmaxCrossEntropy (line 198) | func SoftmaxCrossEntropy(x, y *Tensor) *Tensor {
function BCEWithLogits (line 218) | func BCEWithLogits(target, prediction, weights *Tensor) *Tensor {
FILE: common/nn/layers.go
type Layer (line 28) | type Layer interface
type Model (line 34) | type Model
type LinearLayer (line 36) | type LinearLayer struct
method Forward (line 50) | func (l *LinearLayer) Forward(x *Tensor) *Tensor {
method Parameters (line 54) | func (l *LinearLayer) Parameters() []*Tensor {
method SetJobs (line 58) | func (l *LinearLayer) SetJobs(jobs int) {
function NewLinear (line 42) | func NewLinear(in, out int) Layer {
type flattenLayer (line 62) | type flattenLayer struct
method Parameters (line 68) | func (f *flattenLayer) Parameters() []*Tensor {
method Forward (line 72) | func (f *flattenLayer) Forward(x *Tensor) *Tensor {
method SetJobs (line 76) | func (f *flattenLayer) SetJobs(int) {}
function NewFlatten (line 64) | func NewFlatten() Layer {
type EmbeddingLayer (line 78) | type EmbeddingLayer struct
method Parameters (line 89) | func (e *EmbeddingLayer) Parameters() []*Tensor {
method Forward (line 93) | func (e *EmbeddingLayer) Forward(x *Tensor) *Tensor {
method SetJobs (line 97) | func (e *EmbeddingLayer) SetJobs(int) {}
function NewEmbedding (line 82) | func NewEmbedding(n int, shape ...int) Layer {
type sigmoidLayer (line 99) | type sigmoidLayer struct
method Parameters (line 105) | func (s *sigmoidLayer) Parameters() []*Tensor {
method Forward (line 109) | func (s *sigmoidLayer) Forward(x *Tensor) *Tensor {
method SetJobs (line 113) | func (s *sigmoidLayer) SetJobs(int) {}
function NewSigmoid (line 101) | func NewSigmoid() Layer {
type reluLayer (line 115) | type reluLayer struct
method Parameters (line 121) | func (r *reluLayer) Parameters() []*Tensor {
method Forward (line 125) | func (r *reluLayer) Forward(x *Tensor) *Tensor {
method SetJobs (line 129) | func (r *reluLayer) SetJobs(int) {}
function NewReLU (line 117) | func NewReLU() Layer {
type Sequential (line 131) | type Sequential struct
method Parameters (line 139) | func (s *Sequential) Parameters() []*Tensor {
method Forward (line 147) | func (s *Sequential) Forward(x *Tensor) *Tensor {
method SetJobs (line 154) | func (s *Sequential) SetJobs(jobs int) {
function NewSequential (line 135) | func NewSequential(layers ...Layer) Model {
type Attention (line 160) | type Attention struct
method Parameters (line 173) | func (a *Attention) Parameters() []*Tensor {
method Forward (line 180) | func (a *Attention) Forward(x *Tensor) *Tensor {
method SetJobs (line 187) | func (a *Attention) SetJobs(jobs int) {
function NewAttention (line 166) | func NewAttention(dimensions, k int) *Attention {
function Save (line 192) | func Save(o any, w io.Writer) error {
function Load (line 237) | func Load(o any, r io.Reader) error {
FILE: common/nn/nn_test.go
function TestLinearRegression (line 40) | func TestLinearRegression(t *testing.T) {
function TestNeuralNetwork (line 67) | func TestNeuralNetwork(t *testing.T) {
function iris (line 94) | func iris() (*Tensor, *Tensor, error) {
function TestIris (line 130) | func TestIris(t *testing.T) {
function mnist (line 155) | func mnist() (lo.Tuple2[*Tensor, *Tensor], lo.Tuple2[*Tensor, *Tensor], ...
function openMNISTFile (line 174) | func openMNISTFile(path string) (*Tensor, *Tensor, error) {
function accuracy (line 215) | func accuracy(prediction, target *Tensor) float32 {
function TestMNIST (line 226) | func TestMNIST(t *testing.T) {
function spiral (line 281) | func spiral() (*Tensor, *Tensor, error) {
function TestSaveAndLoad (line 305) | func TestSaveAndLoad(t *testing.T) {
FILE: common/nn/op.go
type op (line 24) | type op interface
type base (line 35) | type base struct
method inputsAndOutput (line 41) | func (b *base) inputsAndOutput() ([]*Tensor, *Tensor) {
method setInputs (line 45) | func (b *base) setInputs(inputs ...*Tensor) {
method setOutput (line 49) | func (b *base) setOutput(y *Tensor) {
method generation (line 53) | func (b *base) generation() int {
method setGeneration (line 57) | func (b *base) setGeneration(gen int) {
function apply (line 61) | func apply[T op](f T, inputs ...*Tensor) *Tensor {
type neg (line 78) | type neg struct
method String (line 82) | func (n *neg) String() string {
method forward (line 86) | func (n *neg) forward(inputs ...*Tensor) *Tensor {
method backward (line 92) | func (n *neg) backward(dy *Tensor) []*Tensor {
type add (line 98) | type add struct
method String (line 102) | func (a *add) String() string {
method forward (line 106) | func (a *add) forward(inputs ...*Tensor) *Tensor {
method backward (line 112) | func (a *add) backward(dy *Tensor) []*Tensor {
type sub (line 125) | type sub struct
method String (line 129) | func (s *sub) String() string {
method forward (line 133) | func (s *sub) forward(inputs ...*Tensor) *Tensor {
method backward (line 139) | func (s *sub) backward(dy *Tensor) []*Tensor {
type mul (line 152) | type mul struct
method String (line 156) | func (m *mul) String() string {
method forward (line 160) | func (m *mul) forward(inputs ...*Tensor) *Tensor {
method backward (line 166) | func (m *mul) backward(dy *Tensor) []*Tensor {
type div (line 180) | type div struct
method String (line 184) | func (d *div) String() string {
method forward (line 188) | func (d *div) forward(inputs ...*Tensor) *Tensor {
method backward (line 194) | func (d *div) backward(dy *Tensor) []*Tensor {
type sin (line 210) | type sin struct
method String (line 214) | func (s *sin) String() string {
method forward (line 218) | func (s *sin) forward(inputs ...*Tensor) *Tensor {
method backward (line 224) | func (s *sin) backward(dy *Tensor) []*Tensor {
type cos (line 231) | type cos struct
method String (line 235) | func (c *cos) String() string {
method forward (line 239) | func (c *cos) forward(inputs ...*Tensor) *Tensor {
method backward (line 245) | func (c *cos) backward(dy *Tensor) []*Tensor {
type square (line 253) | type square struct
method String (line 257) | func (s *square) String() string {
method forward (line 261) | func (s *square) forward(inputs ...*Tensor) *Tensor {
method backward (line 267) | func (s *square) backward(dy *Tensor) []*Tensor {
type pow (line 274) | type pow struct
method String (line 278) | func (p *pow) String() string {
method forward (line 282) | func (p *pow) forward(inputs ...*Tensor) *Tensor {
method backward (line 288) | func (p *pow) backward(dy *Tensor) []*Tensor {
type exp (line 305) | type exp struct
method String (line 309) | func (e *exp) String() string {
method forward (line 313) | func (e *exp) forward(inputs ...*Tensor) *Tensor {
method backward (line 319) | func (e *exp) backward(dy *Tensor) []*Tensor {
type log (line 326) | type log struct
method String (line 330) | func (l *log) String() string {
method forward (line 334) | func (l *log) forward(inputs ...*Tensor) *Tensor {
method backward (line 340) | func (l *log) backward(dy *Tensor) []*Tensor {
type abs (line 346) | type abs struct
method String (line 350) | func (a *abs) String() string {
method forward (line 354) | func (a *abs) forward(inputs ...*Tensor) *Tensor {
method backward (line 364) | func (a *abs) backward(dy *Tensor) []*Tensor {
type sum (line 374) | type sum struct
method String (line 378) | func (s *sum) String() string {
method forward (line 382) | func (s *sum) forward(inputs ...*Tensor) *Tensor {
method backward (line 391) | func (s *sum) backward(dy *Tensor) []*Tensor {
type partialSum (line 399) | type partialSum struct
method String (line 404) | func (p *partialSum) String() string {
method forward (line 408) | func (p *partialSum) forward(inputs ...*Tensor) *Tensor {
method backward (line 441) | func (p *partialSum) backward(dy *Tensor) []*Tensor {
type mean (line 466) | type mean struct
method String (line 470) | func (m *mean) String() string {
method forward (line 474) | func (m *mean) forward(inputs ...*Tensor) *Tensor {
method backward (line 484) | func (m *mean) backward(dy *Tensor) []*Tensor {
type matMul (line 492) | type matMul struct
method String (line 499) | func (m *matMul) String() string {
method forward (line 503) | func (m *matMul) forward(inputs ...*Tensor) *Tensor {
method backward (line 507) | func (m *matMul) backward(dy *Tensor) []*Tensor {
type batchMatMul (line 533) | type batchMatMul struct
method String (line 540) | func (b *batchMatMul) String() string {
method forward (line 544) | func (b *batchMatMul) forward(inputs ...*Tensor) *Tensor {
method backward (line 548) | func (b *batchMatMul) backward(dy *Tensor) []*Tensor {
type broadcast (line 574) | type broadcast struct
method String (line 579) | func (b *broadcast) String() string {
method forward (line 583) | func (b *broadcast) forward(inputs ...*Tensor) *Tensor {
method backward (line 607) | func (b *broadcast) backward(dy *Tensor) []*Tensor {
type flatten (line 621) | type flatten struct
method String (line 625) | func (f *flatten) String() string {
method forward (line 629) | func (f *flatten) forward(inputs ...*Tensor) *Tensor {
method backward (line 633) | func (f *flatten) backward(dy *Tensor) []*Tensor {
type reshape (line 637) | type reshape struct
method String (line 642) | func (r *reshape) String() string {
method forward (line 646) | func (r *reshape) forward(inputs ...*Tensor) *Tensor {
method backward (line 650) | func (r *reshape) backward(dy *Tensor) []*Tensor {
type embedding (line 654) | type embedding struct
method String (line 658) | func (e *embedding) String() string {
method forward (line 662) | func (e *embedding) forward(inputs ...*Tensor) *Tensor {
method backward (line 687) | func (e *embedding) backward(dy *Tensor) []*Tensor {
type sigmoid (line 703) | type sigmoid struct
method String (line 707) | func (s *sigmoid) String() string {
method forward (line 711) | func (s *sigmoid) forward(inputs ...*Tensor) *Tensor {
method backward (line 721) | func (s *sigmoid) backward(dy *Tensor) []*Tensor {
type relu (line 731) | type relu struct
method String (line 735) | func (r *relu) String() string {
method forward (line 739) | func (r *relu) forward(inputs ...*Tensor) *Tensor {
method backward (line 745) | func (r *relu) backward(dy *Tensor) []*Tensor {
type softmax (line 751) | type softmax struct
method String (line 756) | func (s *softmax) String() string {
method forward (line 760) | func (s *softmax) forward(inputs ...*Tensor) *Tensor {
method backward (line 769) | func (s *softmax) backward(dy *Tensor) []*Tensor {
type softmaxCrossEntropy (line 779) | type softmaxCrossEntropy struct
method String (line 783) | func (c *softmaxCrossEntropy) String() string {
method forward (line 787) | func (c *softmaxCrossEntropy) forward(inputs ...*Tensor) *Tensor {
method backward (line 804) | func (c *softmaxCrossEntropy) backward(dy *Tensor) []*Tensor {
type opHeap (line 823) | type opHeap
method Len (line 825) | func (h opHeap) Len() int {
method Less (line 829) | func (h opHeap) Less(i, j int) bool {
method Swap (line 833) | func (h opHeap) Swap(i, j int) {
method Push (line 837) | func (h *opHeap) Push(o any) {
method Pop (line 841) | func (h *opHeap) Pop() any {
FILE: common/nn/op_test.go
constant eps (line 25) | eps = 1e-4
constant rtol (line 26) | rtol = 1e-2
constant atol (line 27) | atol = 5e-3
function numericalDiff (line 30) | func numericalDiff(f func(*Tensor) *Tensor, x *Tensor) *Tensor {
function allClose (line 47) | func allClose(t *testing.T, a, b *Tensor) {
function TestAdd (line 59) | func TestAdd(t *testing.T) {
function TestSub (line 99) | func TestSub(t *testing.T) {
function TestMul (line 139) | func TestMul(t *testing.T) {
function TestDiv (line 179) | func TestDiv(t *testing.T) {
function TestSquare (line 216) | func TestSquare(t *testing.T) {
function TestPow (line 230) | func TestPow(t *testing.T) {
function TestExp (line 266) | func TestExp(t *testing.T) {
function TestLog (line 280) | func TestLog(t *testing.T) {
function TestAbs (line 294) | func TestAbs(t *testing.T) {
function TestSum (line 308) | func TestSum(t *testing.T) {
function TestMean (line 334) | func TestMean(t *testing.T) {
function TestCos (line 347) | func TestCos(t *testing.T) {
function TestSin (line 361) | func TestSin(t *testing.T) {
function TestMatMul (line 375) | func TestMatMul(t *testing.T) {
function TestBMM (line 417) | func TestBMM(t *testing.T) {
function TestBroadcast (line 469) | func TestBroadcast(t *testing.T) {
function TestEmbedding (line 480) | func TestEmbedding(t *testing.T) {
function TestSigmoid (line 506) | func TestSigmoid(t *testing.T) {
function TestReLu (line 520) | func TestReLu(t *testing.T) {
function TestSoftmax (line 534) | func TestSoftmax(t *testing.T) {
function TestFlatten (line 547) | func TestFlatten(t *testing.T) {
function TestReshape (line 558) | func TestReshape(t *testing.T) {
function TestSoftmaxCrossEntropy (line 569) | func TestSoftmaxCrossEntropy(t *testing.T) {
function TestReuseLeaf (line 583) | func TestReuseLeaf(t *testing.T) {
function TestReuseNode (line 595) | func TestReuseNode(t *testing.T) {
function TestDependency (line 611) | func TestDependency(t *testing.T) {
function TestSphere (line 627) | func TestSphere(t *testing.T) {
function TestMatyas (line 642) | func TestMatyas(t *testing.T) {
function TestGoldsteinPrice (line 661) | func TestGoldsteinPrice(t *testing.T) {
FILE: common/nn/optimizers.go
type Optimizer (line 25) | type Optimizer interface
type baseOptimizer (line 32) | type baseOptimizer struct
method ZeroGrad (line 38) | func (o *baseOptimizer) ZeroGrad() {
method SetWeightDecay (line 44) | func (o *baseOptimizer) SetWeightDecay(wd float32) {
method SetJobs (line 48) | func (o *baseOptimizer) SetJobs(jobs int) {
type SGD (line 52) | type SGD struct
method Step (line 70) | func (s *SGD) Step() {
function NewSGD (line 58) | func NewSGD(params []*Tensor, lr float32) Optimizer {
type Adam (line 86) | type Adam struct
method Step (line 118) | func (a *Adam) Step() {
function NewAdam (line 100) | func NewAdam(params []*Tensor, alpha float32) Optimizer {
function partitionAligned (line 160) | func partitionAligned(n, m, k int) []lo.Tuple2[int, int] {
FILE: common/nn/tensor.go
function SetInferenceMode (line 40) | func SetInferenceMode(enabled bool) {
type Tensor (line 44) | type Tensor struct
method generation (line 162) | func (t *Tensor) generation() int {
method IsScalar (line 169) | func (t *Tensor) IsScalar() bool {
method NoGrad (line 174) | func (t *Tensor) NoGrad() *Tensor {
method Shape (line 181) | func (t *Tensor) Shape() []int {
method Slice (line 186) | func (t *Tensor) Slice(start, end int) *Tensor {
method SliceIndices (line 203) | func (t *Tensor) SliceIndices(indices ...int) *Tensor {
method Get (line 221) | func (t *Tensor) Get(indices ...int) float32 {
method String (line 235) | func (t *Tensor) String() string {
method Backward (line 267) | func (t *Tensor) Backward() {
method Grad (line 293) | func (t *Tensor) Grad() *Tensor {
method Data (line 297) | func (t *Tensor) Data() []float32 {
method clone (line 301) | func (t *Tensor) clone() *Tensor {
method add (line 310) | func (t *Tensor) add(other *Tensor) *Tensor {
method sub (line 328) | func (t *Tensor) sub(other *Tensor) *Tensor {
method bSub (line 342) | func (t *Tensor) bSub(other *Tensor) *Tensor {
method mul (line 356) | func (t *Tensor) mul(other *Tensor) *Tensor {
method div (line 370) | func (t *Tensor) div(other *Tensor) *Tensor {
method bDiv (line 384) | func (t *Tensor) bDiv(other *Tensor) *Tensor {
method square (line 398) | func (t *Tensor) square() *Tensor {
method pow (line 403) | func (t *Tensor) pow(other *Tensor) *Tensor {
method exp (line 414) | func (t *Tensor) exp() *Tensor {
method log (line 421) | func (t *Tensor) log() *Tensor {
method sin (line 428) | func (t *Tensor) sin() *Tensor {
method cos (line 435) | func (t *Tensor) cos() *Tensor {
method tanh (line 442) | func (t *Tensor) tanh() *Tensor {
method neg (line 449) | func (t *Tensor) neg() *Tensor {
method matMul (line 494) | func (t *Tensor) matMul(other *Tensor, transpose1, transpose2 bool, jo...
method batchMatMul (line 553) | func (t *Tensor) batchMatMul(other *Tensor, transpose1, transpose2 boo...
method maximum (line 602) | func (t *Tensor) maximum(other *Tensor) {
method gt (line 614) | func (t *Tensor) gt(other *Tensor) *Tensor {
method transpose (line 635) | func (t *Tensor) transpose() *Tensor {
method max (line 661) | func (t *Tensor) max(axis int, keepDim bool) *Tensor {
method sum (line 700) | func (t *Tensor) sum(axis int, keepDim bool) *Tensor {
method argmax (line 739) | func (t *Tensor) argmax() []int {
method toPB (line 759) | func (t *Tensor) toPB() *protocol.Tensor {
method fromPB (line 766) | func (t *Tensor) fromPB(pb *protocol.Tensor) {
function NewTensor (line 51) | func NewTensor(data []float32, shape ...int) *Tensor {
function NewScalar (line 65) | func NewScalar(data float32) *Tensor {
function LinSpace (line 72) | func LinSpace(start, end float32, shape ...int) *Tensor {
function Rand (line 88) | func Rand(shape ...int) *Tensor {
function Uniform (line 103) | func Uniform(low, high float32, shape ...int) *Tensor {
function Normal (line 118) | func Normal(mean, std float32, shape ...int) *Tensor {
function Ones (line 134) | func Ones(shape ...int) *Tensor {
function Zeros (line 150) | func Zeros(shape ...int) *Tensor {
function partition (line 456) | func partition(n, p int) []lo.Tuple2[int, int] {
function NormalInit (line 774) | func NormalInit(t *Tensor, mean, std float32) {
FILE: common/nn/tensor_test.go
function TestTensor_Slice (line 23) | func TestTensor_Slice(t *testing.T) {
function TestTensor_SliceIndices (line 36) | func TestTensor_SliceIndices(t *testing.T) {
function TestTensor_Max (line 43) | func TestTensor_Max(t *testing.T) {
function TestTensor_Sum (line 61) | func TestTensor_Sum(t *testing.T) {
function TestTensor_Transpose (line 79) | func TestTensor_Transpose(t *testing.T) {
method matMulLegacy (line 86) | func (t *Tensor) matMulLegacy(other *Tensor, transpose1, transpose2 bool...
method batchMatMulLegacy (line 170) | func (t *Tensor) batchMatMulLegacy(other *Tensor, transpose1, transpose2...
function BenchmarkMatMulLegacy64 (line 262) | func BenchmarkMatMulLegacy64(b *testing.B) {
function BenchmarkMatMul64 (line 276) | func BenchmarkMatMul64(b *testing.B) {
function BenchmarkBatchMatMulLegacy64 (line 290) | func BenchmarkBatchMatMulLegacy64(b *testing.B) {
function BenchmarkBatchMatMul64 (line 304) | func BenchmarkBatchMatMul64(b *testing.B) {
FILE: common/parallel/parallel.go
constant chanSize (line 26) | chanSize = 1024
function Parallel (line 33) | func Parallel(ctx context.Context, nJobs, nWorkers int, worker func(work...
function For (line 96) | func For(ctx context.Context, nJobs, nWorkers int, worker func(int)) err...
function ForEach (line 143) | func ForEach[T any](ctx context.Context, a []T, nWorkers int, worker fun...
function Split (line 191) | func Split[T any](a []T, n int) [][]T {
type Context (line 212) | type Context struct
method Detach (line 218) | func (ctx *Context) Detach() {
method Attach (line 227) | func (ctx *Context) Attach() {
function Detachable (line 236) | func Detachable(ctx context.Context, nJobs, nWorkers, nMaxDetached int, ...
FILE: common/parallel/parallel_test.go
function TestParallel (line 29) | func TestParallel(t *testing.T) {
function TestFor (line 57) | func TestFor(t *testing.T) {
function TestForCancel (line 78) | func TestForCancel(t *testing.T) {
function TestForEach (line 96) | func TestForEach(t *testing.T) {
function TestForEachCancel (line 119) | func TestForEachCancel(t *testing.T) {
function TestParallelFail (line 137) | func TestParallelFail(t *testing.T) {
function TestParallelCancel (line 156) | func TestParallelCancel(t *testing.T) {
function TestSplit (line 175) | func TestSplit(t *testing.T) {
function TestDetachable (line 185) | func TestDetachable(t *testing.T) {
function TestDetachableCancel (line 209) | func TestDetachableCancel(t *testing.T) {
FILE: common/parallel/ratelimit.go
function InitChatCompletionLimiters (line 18) | func InitChatCompletionLimiters(rpm, tpm int) {
function InitEmbeddingLimiters (line 28) | func InitEmbeddingLimiters(rpm, tpm int) {
type RateLimiter (line 38) | type RateLimiter interface
type Unlimited (line 42) | type Unlimited struct
method Take (line 44) | func (n *Unlimited) Take(count int64) time.Duration {
FILE: common/parallel/ratelimit_test.go
function TestUnlimited (line 10) | func TestUnlimited(t *testing.T) {
function TestInitEmbeddingLimiters (line 15) | func TestInitEmbeddingLimiters(t *testing.T) {
function TestInitChatCompletionLimiters (line 23) | func TestInitChatCompletionLimiters(t *testing.T) {
FILE: common/rc/rc.go
type DropFunc (line 25) | type DropFunc
type rcPointer (line 27) | type rcPointer struct
type Rc (line 32) | type Rc struct
method Reset (line 38) | func (r *Rc[T]) Reset(pointer T) {
method Get (line 52) | func (r *Rc[T]) Get() (T, DropFunc) {
method get (line 58) | func (r *Rc[T]) get() (T, DropFunc) {
method Apply (line 76) | func (r *Rc[T]) Apply(f func(T)) {
FILE: common/rc/rc_test.go
type Foo (line 26) | type Foo struct
method Close (line 36) | func (f *Foo) Close() error {
function NewFoo (line 30) | func NewFoo() *Foo {
function TestRc_Get (line 41) | func TestRc_Get(t *testing.T) {
function TestRc_Apply (line 51) | func TestRc_Apply(t *testing.T) {
function TestRc_Concurrent (line 62) | func TestRc_Concurrent(t *testing.T) {
FILE: common/reranker/client.go
type Client (line 29) | type Client struct
method Rerank (line 65) | func (c *Client) Rerank(ctx context.Context, req RerankRequest) (*Rera...
function NewClient (line 35) | func NewClient(apiKey, endpoint string) *Client {
type RerankRequest (line 43) | type RerankRequest struct
type RerankResponse (line 50) | type RerankResponse struct
type RerankResult (line 56) | type RerankResult struct
type Usage (line 61) | type Usage struct
type MockServer (line 105) | type MockServer struct
method Start (line 130) | func (s *MockServer) Start() error {
method URL (line 140) | func (s *MockServer) URL() string {
method AuthToken (line 144) | func (s *MockServer) AuthToken() string {
method Ready (line 148) | func (s *MockServer) Ready() {
method Close (line 152) | func (s *MockServer) Close() error {
method rerank (line 156) | func (s *MockServer) rerank(req *restful.Request, resp *restful.Respon...
function NewMockServer (line 112) | func NewMockServer() *MockServer {
FILE: common/reranker/client_test.go
type ClientTestSuite (line 24) | type ClientTestSuite struct
method SetupSuite (line 29) | func (suite *ClientTestSuite) SetupSuite() {
method TearDownSuite (line 38) | func (suite *ClientTestSuite) TearDownSuite() {
method TestRerank (line 42) | func (suite *ClientTestSuite) TestRerank() {
function TestClient (line 63) | func TestClient(t *testing.T) {
FILE: common/sizeof/size.go
function DeepSize (line 43) | func DeepSize(v any) int {
function valueSize (line 47) | func valueSize(v reflect.Value, seen map[uintptr]bool) uintptr {
FILE: common/sizeof/size_test.go
function TestCyclic (line 23) | func TestCyclic(t *testing.T) {
function TestDeepSize (line 38) | func TestDeepSize(t *testing.T) {
FILE: common/util/random.go
type RandomGenerator (line 25) | type RandomGenerator struct
method UniformVector (line 35) | func (rng RandomGenerator) UniformVector(size int, low, high float32) ...
method NewNormalVector (line 45) | func (rng RandomGenerator) NewNormalVector(size int, mean, stdDev floa...
method NormalMatrix (line 54) | func (rng RandomGenerator) NormalMatrix(row, col int, mean, stdDev flo...
method NormalVector (line 62) | func (rng RandomGenerator) NormalVector(size int, mean, stdDev float32...
method UniformMatrix (line 71) | func (rng RandomGenerator) UniformMatrix(row, col int, low, high float...
method NormalVector64 (line 80) | func (rng RandomGenerator) NormalVector64(size int, mean, stdDev float...
method Sample (line 89) | func (rng RandomGenerator) Sample(low, high, n int, exclude ...mapset....
method SampleInt32 (line 116) | func (rng RandomGenerator) SampleInt32(low, high int32, n int, exclude...
function NewRandomGenerator (line 30) | func NewRandomGenerator(seed int64) RandomGenerator {
type lockedSource (line 144) | type lockedSource struct
method Int63 (line 154) | func (r *lockedSource) Int63() (n int64) {
method Seed (line 161) | func (r *lockedSource) Seed(seed int64) {
function NewRand (line 150) | func NewRand(seed int64) *rand.Rand {
FILE: common/util/random_test.go
constant randomEpsilon (line 25) | randomEpsilon = 0.1
function TestRandomGenerator_MakeNormalMatrix (line 27) | func TestRandomGenerator_MakeNormalMatrix(t *testing.T) {
function TestRandomGenerator_MakeUniformMatrix (line 34) | func TestRandomGenerator_MakeUniformMatrix(t *testing.T) {
function TestRandomGenerator_Sample (line 41) | func TestRandomGenerator_Sample(t *testing.T) {
function TestRandomGenerator_SampleInt32 (line 52) | func TestRandomGenerator_SampleInt32(t *testing.T) {
function mean (line 64) | func mean(x []float32) float32 {
function stdDev (line 69) | func stdDev(x []float32) float32 {
function meanVariance (line 83) | func meanVariance(x []float32) (m, variance float32) {
FILE: common/util/strconv.go
function ParseFloat (line 24) | func ParseFloat[T constraints.Float](s string) (T, error) {
function ParseUInt (line 29) | func ParseUInt[T constraints.Unsigned](s string) (T, error) {
function ParseInt (line 34) | func ParseInt[T constraints.Signed](s string) (T, error) {
function FormatInt (line 39) | func FormatInt[T constraints.Signed](i T) string {
FILE: common/util/tls.go
type TLSConfig (line 26) | type TLSConfig struct
function NewServerCreds (line 32) | func NewServerCreds(o *TLSConfig) (credentials.TransportCredentials, err...
function NewClientCreds (line 60) | func NewClientCreds(o *TLSConfig) (credentials.TransportCredentials, err...
FILE: common/util/util.go
function RangeInt (line 29) | func RangeInt(n int) []int {
function RepeatFloat32s (line 38) | func RepeatFloat32s(n int, value float32) []float32 {
function NewMatrix32 (line 47) | func NewMatrix32(row, col int) [][]float32 {
function NewTensor32 (line 56) | func NewTensor32(a, b, c int) [][][]float32 {
function NewMatrixInt (line 65) | func NewMatrixInt(row, col int) [][]int {
function CheckPanic (line 74) | func CheckPanic() {
function ValidateId (line 81) | func ValidateId(text string) error {
function MD5 (line 92) | func MD5(s ...string) string {
FILE: common/util/util_test.go
function TestNewMatrix32 (line 23) | func TestNewMatrix32(t *testing.T) {
function TestRangeInt (line 31) | func TestRangeInt(t *testing.T) {
function TestRepeatFloat32s (line 39) | func TestRepeatFloat32s(t *testing.T) {
function TestNewMatrixInt (line 44) | func TestNewMatrixInt(t *testing.T) {
function TestNewTensor32 (line 52) | func TestNewTensor32(t *testing.T) {
function TestValidateId (line 59) | func TestValidateId(t *testing.T) {
function TestMD5 (line 65) | func TestMD5(t *testing.T) {
FILE: config/config.go
function init (line 53) | func init() {
type Config (line 61) | type Config struct
method Now (line 516) | func (config *Config) Now() *time.Time {
method Validate (line 747) | func (config *Config) Validate() error {
type DatabaseConfig (line 73) | type DatabaseConfig struct
method StorageOptions (line 101) | func (db *DatabaseConfig) StorageOptions(path string) []storage.Option {
type MySQLConfig (line 84) | type MySQLConfig struct
type SQLConfig (line 91) | type SQLConfig struct
type RedisConfig (line 97) | type RedisConfig struct
type MasterConfig (line 127) | type MasterConfig struct
type ServerConfig (line 147) | type ServerConfig struct
type RecommendConfig (line 157) | type RecommendConfig struct
method ListRecommenders (line 173) | func (r *RecommendConfig) ListRecommenders() []string {
method Hash (line 192) | func (r *RecommendConfig) Hash() string {
function StringToFeedbackTypeHookFunc (line 227) | func StringToFeedbackTypeHookFunc() mapstructure.DecodeHookFunc {
type DataSourceConfig (line 244) | type DataSourceConfig struct
type NonPersonalizedConfig (line 251) | type NonPersonalizedConfig struct
method FullName (line 257) | func (config *NonPersonalizedConfig) FullName() string {
method Hash (line 261) | func (config *NonPersonalizedConfig) Hash() string {
type ItemToItemConfig (line 269) | type ItemToItemConfig struct
method FullName (line 276) | func (config *ItemToItemConfig) FullName() string {
method Hash (line 280) | func (config *ItemToItemConfig) Hash(cfg *RecommendConfig) string {
type UserToUserConfig (line 293) | type UserToUserConfig struct
method FullName (line 299) | func (config *UserToUserConfig) FullName() string {
method Hash (line 303) | func (config *UserToUserConfig) Hash(cfg *RecommendConfig) string {
type CollaborativeConfig (line 316) | type CollaborativeConfig struct
method FullName (line 325) | func (config *CollaborativeConfig) FullName() string {
method Hash (line 329) | func (config *CollaborativeConfig) Hash(cfg *RecommendConfig) string {
type EarlyStoppingConfig (line 337) | type EarlyStoppingConfig struct
type ExternalConfig (line 341) | type ExternalConfig struct
method FullName (line 346) | func (config *ExternalConfig) FullName() string {
method Hash (line 350) | func (config *ExternalConfig) Hash() string {
type ReplacementConfig (line 357) | type ReplacementConfig struct
type RankerConfig (line 363) | type RankerConfig struct
type FallbackConfig (line 377) | type FallbackConfig struct
type TracingConfig (line 381) | type TracingConfig struct
method NewTracerProvider (line 520) | func (config *TracingConfig) NewTracerProvider() (trace.TracerProvider...
method Equal (line 571) | func (config *TracingConfig) Equal(other TracingConfig) bool {
type OIDCConfig (line 389) | type OIDCConfig struct
type RerankerAPIConfig (line 397) | type RerankerAPIConfig struct
type OpenAIConfig (line 403) | type OpenAIConfig struct
type BlobConfig (line 416) | type BlobConfig struct
type S3Config (line 423) | type S3Config struct
type GCSConfig (line 429) | type GCSConfig struct
type AzureBlobConfig (line 433) | type AzureBlobConfig struct
function GetDefaultConfig (line 440) | func GetDefaultConfig() *Config {
function setDefault (line 582) | func setDefault() {
type configBinding (line 645) | type configBinding struct
function LoadConfig (line 694) | func LoadConfig(path string) (*Config, error) {
function MkDir (line 906) | func MkDir(elem ...string) string {
FILE: config/config_test.go
function TestUnmarshal (line 33) | func TestUnmarshal(t *testing.T) {
function TestSetDefault (line 173) | func TestSetDefault(t *testing.T) {
type environmentVariable (line 187) | type environmentVariable struct
function TestBindEnv (line 192) | func TestBindEnv(t *testing.T) {
function TestTablePrefixCompat (line 285) | func TestTablePrefixCompat(t *testing.T) {
function TestNonPersonalizedConfig (line 303) | func TestNonPersonalizedConfig(t *testing.T) {
function TestItemToItemConfig (line 323) | func TestItemToItemConfig(t *testing.T) {
function TestUserToUserConfig (line 352) | func TestUserToUserConfig(t *testing.T) {
function TestCollaborativeConfig (line 381) | func TestCollaborativeConfig(t *testing.T) {
function TestExternalConfig (line 392) | func TestExternalConfig(t *testing.T) {
function TestRecommendConfig (line 408) | func TestRecommendConfig(t *testing.T) {
type ValidateTestSuite (line 452) | type ValidateTestSuite struct
method SetupTest (line 457) | func (s *ValidateTestSuite) SetupTest() {
method TestDuplicateNonPersonalized (line 463) | func (s *ValidateTestSuite) TestDuplicateNonPersonalized() {
method TestDuplicateItemToItem (line 474) | func (s *ValidateTestSuite) TestDuplicateItemToItem() {
method TestRecommendersExistence (line 485) | func (s *ValidateTestSuite) TestRecommendersExistence() {
function TestValidate (line 494) | func TestValidate(t *testing.T) {
FILE: dataset/dataset.go
type ID (line 36) | type ID
type CFSplit (line 39) | type CFSplit interface
type CTRSplit (line 61) | type CTRSplit interface
type Dataset (line 77) | type Dataset struct
method GetTimestamp (line 109) | func (d *Dataset) GetTimestamp() time.Time {
method CountFeedback (line 113) | func (d *Dataset) CountFeedback() int {
method GetUsers (line 117) | func (d *Dataset) GetUsers() []data.User {
method GetUserDict (line 121) | func (d *Dataset) GetUserDict() *FreqDict {
method CountUsers (line 125) | func (d *Dataset) CountUsers() int {
method GetItems (line 129) | func (d *Dataset) GetItems() []data.Item {
method GetItemDict (line 133) | func (d *Dataset) GetItemDict() *FreqDict {
method CountItems (line 137) | func (d *Dataset) CountItems() int {
method GetUserFeedback (line 141) | func (d *Dataset) GetUserFeedback() [][]int32 {
method GetItemFeedback (line 145) | func (d *Dataset) GetItemFeedback() [][]int32 {
method GetCategories (line 149) | func (d *Dataset) GetCategories() map[string]int {
method GetUserIDF (line 159) | func (d *Dataset) GetUserIDF() []float32 {
method GetItemIDF (line 174) | func (d *Dataset) GetItemIDF() []float32 {
method GetUserColumnValuesIDF (line 183) | func (d *Dataset) GetUserColumnValuesIDF() []float32 {
method GetItemColumnValuesIDF (line 192) | func (d *Dataset) GetItemColumnValuesIDF() []float32 {
method AddUser (line 201) | func (d *Dataset) AddUser(user data.User) {
method AddItem (line 216) | func (d *Dataset) AddItem(item data.Item) {
method AddFeedback (line 234) | func (d *Dataset) AddFeedback(userId, itemId string, timestamp time.Ti...
method SampleUserNegatives (line 243) | func (d *Dataset) SampleUserNegatives(excludeSet CFSplit, numCandidate...
method SplitCF (line 259) | func (d *Dataset) SplitCF(numTestUsers int, seed int64) (CFSplit, CFSp...
method SplitLatest (line 322) | func (d *Dataset) SplitLatest(shots int) (CFSplit, CFSplit) {
function NewDataset (line 93) | func NewDataset(timestamp time.Time, userCount, itemCount int) *Dataset {
type Labels (line 354) | type Labels struct
method processLabels (line 366) | func (l *Labels) processLabels(labels any, parent string) any {
function NewLabels (line 359) | func NewLabels() *Labels {
function isSliceOf (line 392) | func isSliceOf[T any](v []any) bool {
function LoadDataFromBuiltIn (line 401) | func LoadDataFromBuiltIn(dataSetName string) (*Dataset, *Dataset, error) {
function loadTrain (line 426) | func loadTrain(path string) (*Dataset, error) {
function loadTest (line 461) | func loadTest(dataset *Dataset, path string) error {
FILE: dataset/dataset_test.go
function TestDataset_AddItem (line 29) | func TestDataset_AddItem(t *testing.T) {
function TestDataset_GetItemColumnValuesIDF (line 84) | func TestDataset_GetItemColumnValuesIDF(t *testing.T) {
function TestDataset_AddUser (line 112) | func TestDataset_AddUser(t *testing.T) {
function TestDataset_GetUserColumnValuesIDF (line 127) | func TestDataset_GetUserColumnValuesIDF(t *testing.T) {
function TestDataset_AddFeedback (line 149) | func TestDataset_AddFeedback(t *testing.T) {
function TestDataset_Split (line 177) | func TestDataset_Split(t *testing.T) {
function TestDataset_SplitLatest (line 211) | func TestDataset_SplitLatest(t *testing.T) {
function TestDataset_LoadMovieLens1M (line 242) | func TestDataset_LoadMovieLens1M(t *testing.T) {
FILE: dataset/dict.go
type FreqDict (line 17) | type FreqDict struct
method Count (line 28) | func (d *FreqDict) Count() int32 {
method Add (line 32) | func (d *FreqDict) Add(s string) (y int32) {
method AddNoCount (line 45) | func (d *FreqDict) AddNoCount(s string) (y int32) {
method Id (line 57) | func (d *FreqDict) Id(s string) int32 {
method String (line 64) | func (d *FreqDict) String(id int32) (s string, ok bool) {
method Freq (line 71) | func (d *FreqDict) Freq(id int32) int32 {
method ToIndex (line 78) | func (d *FreqDict) ToIndex() *Index {
function NewFreqDict (line 23) | func NewFreqDict() (d *FreqDict) {
FILE: dataset/dict_test.go
function TestFreqDict (line 23) | func TestFreqDict(t *testing.T) {
FILE: dataset/index.go
function MarshalIndex (line 26) | func MarshalIndex(w io.Writer, index *Index) error {
function UnmarshalIndex (line 31) | func UnmarshalIndex(r io.Reader) (*Index, error) {
type Index (line 43) | type Index struct
method Len (line 60) | func (idx *Index) Len() int32 {
method Add (line 68) | func (idx *Index) Add(name string) {
method ToNumber (line 76) | func (idx *Index) ToNumber(name string) int32 {
method ToName (line 84) | func (idx *Index) ToName(index int32) string {
method GetNames (line 89) | func (idx *Index) GetNames() []string {
method Marshal (line 94) | func (idx *Index) Marshal(w io.Writer) error {
method Unmarshal (line 111) | func (idx *Index) Unmarshal(r io.Reader) error {
constant NotId (line 49) | NotId = int32(-1)
function NewMapIndex (line 52) | func NewMapIndex() *Index {
FILE: dataset/index_test.go
function TestIndex (line 10) | func TestIndex(t *testing.T) {
FILE: dataset/unified_index.go
type UnifiedIndex (line 28) | type UnifiedIndex interface
constant mapIndex (line 50) | mapIndex uint8 = iota
constant directIndex (line 51) | directIndex
constant nilIndex (line 52) | nilIndex
function MarshalUnifiedIndex (line 56) | func MarshalUnifiedIndex(w io.Writer, index UnifiedIndex) error {
function UnmarshalUnifiedIndex (line 80) | func UnmarshalUnifiedIndex(r io.Reader) (UnifiedIndex, error) {
type UnifiedMapIndexBuilder (line 107) | type UnifiedMapIndexBuilder struct
method AddUser (line 127) | func (builder *UnifiedMapIndexBuilder) AddUser(userId string) {
method AddItem (line 132) | func (builder *UnifiedMapIndexBuilder) AddItem(itemId string) {
method AddUserLabel (line 137) | func (builder *UnifiedMapIndexBuilder) AddUserLabel(userLabel string) {
method AddItemLabel (line 142) | func (builder *UnifiedMapIndexBuilder) AddItemLabel(itemLabel string) {
method AddCtxLabel (line 147) | func (builder *UnifiedMapIndexBuilder) AddCtxLabel(ctxLabel string) {
method Build (line 152) | func (builder *UnifiedMapIndexBuilder) Build() UnifiedIndex {
function NewUnifiedMapIndexBuilder (line 116) | func NewUnifiedMapIndexBuilder() *UnifiedMapIndexBuilder {
type UnifiedMapIndex (line 164) | type UnifiedMapIndex struct
method GetUserLabels (line 173) | func (unified *UnifiedMapIndex) GetUserLabels() []string {
method GetItemLabels (line 178) | func (unified *UnifiedMapIndex) GetItemLabels() []string {
method GetContextLabels (line 183) | func (unified *UnifiedMapIndex) GetContextLabels() []string {
method CountUserLabels (line 188) | func (unified *UnifiedMapIndex) CountUserLabels() int32 {
method CountItemLabels (line 193) | func (unified *UnifiedMapIndex) CountItemLabels() int32 {
method CountContextLabels (line 198) | func (unified *UnifiedMapIndex) CountContextLabels() int32 {
method Len (line 203) | func (unified *UnifiedMapIndex) Len() int32 {
method EncodeUser (line 210) | func (unified *UnifiedMapIndex) EncodeUser(userId string) int32 {
method EncodeItem (line 215) | func (unified *UnifiedMapIndex) EncodeItem(itemId string) int32 {
method EncodeUserLabel (line 224) | func (unified *UnifiedMapIndex) EncodeUserLabel(userLabel string) int32 {
method EncodeItemLabel (line 233) | func (unified *UnifiedMapIndex) EncodeItemLabel(itemLabel string) int32 {
method EncodeContextLabel (line 242) | func (unified *UnifiedMapIndex) EncodeContextLabel(label string) int32 {
method GetUsers (line 252) | func (unified *UnifiedMapIndex) GetUsers() []string {
method GetItems (line 257) | func (unified *UnifiedMapIndex) GetItems() []string {
method CountUsers (line 262) | func (unified *UnifiedMapIndex) CountUsers() int32 {
method CountItems (line 267) | func (unified *UnifiedMapIndex) CountItems() int32 {
method Marshal (line 272) | func (unified *UnifiedMapIndex) Marshal(w io.Writer) error {
method Unmarshal (line 284) | func (unified *UnifiedMapIndex) Unmarshal(r io.Reader) error {
type UnifiedDirectIndex (line 297) | type UnifiedDirectIndex struct
method EncodeUserLabel (line 302) | func (unified *UnifiedDirectIndex) EncodeUserLabel(userLabel string) i...
method EncodeItemLabel (line 311) | func (unified *UnifiedDirectIndex) EncodeItemLabel(itemLabel string) i...
method GetUserLabels (line 320) | func (unified *UnifiedDirectIndex) GetUserLabels() []string {
method GetItemLabels (line 330) | func (unified *UnifiedDirectIndex) GetItemLabels() []string {
method GetContextLabels (line 340) | func (unified *UnifiedDirectIndex) GetContextLabels() []string {
method CountUserLabels (line 350) | func (unified *UnifiedDirectIndex) CountUserLabels() int32 {
method CountItemLabels (line 355) | func (unified *UnifiedDirectIndex) CountItemLabels() int32 {
method CountContextLabels (line 360) | func (unified *UnifiedDirectIndex) CountContextLabels() int32 {
method Len (line 370) | func (unified *UnifiedDirectIndex) Len() int32 {
method EncodeUser (line 375) | func (unified *UnifiedDirectIndex) EncodeUser(userId string) int32 {
method EncodeItem (line 384) | func (unified *UnifiedDirectIndex) EncodeItem(itemId string) int32 {
method EncodeContextLabel (line 393) | func (unified *UnifiedDirectIndex) EncodeContextLabel(label string) in...
method GetUsers (line 402) | func (unified *UnifiedDirectIndex) GetUsers() []string {
method GetItems (line 412) | func (unified *UnifiedDirectIndex) GetItems() []string {
method CountUsers (line 423) | func (unified *UnifiedDirectIndex) CountUsers() int32 {
method CountItems (line 428) | func (unified *UnifiedDirectIndex) CountItems() int32 {
method Marshal (line 433) | func (unified *UnifiedDirectIndex) Marshal(w io.Writer) error {
method Unmarshal (line 438) | func (unified *UnifiedDirectIndex) Unmarshal(r io.Reader) error {
function NewUnifiedDirectIndex (line 365) | func NewUnifiedDirectIndex(n int32) UnifiedIndex {
FILE: dataset/unified_index_test.go
function TestUnifiedMapIndex (line 24) | func TestUnifiedMapIndex(t *testing.T) {
function TestUnifiedDirectIndex (line 91) | func TestUnifiedDirectIndex(t *testing.T) {
FILE: logics/cf.go
function distance (line 32) | func distance(a, b []float32) float32 {
type MatrixFactorizationItems (line 36) | type MatrixFactorizationItems struct
method Add (line 52) | func (items *MatrixFactorizationItems) Add(itemId string, v []float32) {
method Search (line 70) | func (items *MatrixFactorizationItems) Search(v []float32, n int) []ca...
method Marshal (line 81) | func (items *MatrixFactorizationItems) Marshal(w io.Writer) error {
method Unmarshal (line 103) | func (items *MatrixFactorizationItems) Unmarshal(r io.Reader) error {
function NewMatrixFactorizationItems (line 44) | func NewMatrixFactorizationItems(timestamp time.Time) *MatrixFactorizati...
type MatrixFactorizationUsers (line 126) | type MatrixFactorizationUsers struct
method Add (line 136) | func (users *MatrixFactorizationUsers) Add(userId string, v []float32) {
method Get (line 140) | func (users *MatrixFactorizationUsers) Get(userId string) ([]float32, ...
method Marshal (line 145) | func (users *MatrixFactorizationUsers) Marshal(w io.Writer) error {
method Unmarshal (line 161) | func (users *MatrixFactorizationUsers) Unmarshal(r io.Reader) error {
function NewMatrixFactorizationUsers (line 130) | func NewMatrixFactorizationUsers() *MatrixFactorizationUsers {
FILE: logics/cf_test.go
function TestMatrixFactorizationItems (line 26) | func TestMatrixFactorizationItems(t *testing.T) {
function TestNewMatrixFactorizationUsers (line 60) | func TestNewMatrixFactorizationUsers(t *testing.T) {
FILE: logics/chat.go
type FeedbackItem (line 34) | type FeedbackItem struct
type ChatReranker (line 39) | type ChatReranker struct
method Rank (line 66) | func (r *ChatReranker) Rank(ctx context.Context, user *data.User, feed...
function NewChatReranker (line 46) | func NewChatReranker(cfg config.RerankerAPIConfig, queryTemplate, docTem...
function parseArrayFromCompletion (line 110) | func parseArrayFromCompletion(completion string) []string {
function isThrottled (line 168) | func isThrottled(err error) bool {
FILE: logics/chat_test.go
function TestChatReranker (line 28) | func TestChatReranker(t *testing.T) {
function TestParseArrayFromCompletion (line 72) | func TestParseArrayFromCompletion(t *testing.T) {
FILE: logics/external.go
type External (line 30) | type External struct
method Close (line 84) | func (e *External) Close() error {
method Pull (line 88) | func (e *External) Pull(userId string) (res []string, err error) {
method fetch (line 129) | func (e *External) fetch(args ...quickjs.Value) quickjs.Value {
method parseRequest (line 164) | func (e *External) parseRequest(url string, req quickjs.Value) *http.R...
method newResponse (line 207) | func (e *External) newResponse(resp *http.Response) quickjs.Value {
function NewExternal (line 37) | func NewExternal(cfg config.ExternalConfig) (*External, error) {
FILE: logics/external_test.go
function TestEnv (line 30) | func TestEnv(t *testing.T) {
function TestFetch (line 42) | func TestFetch(t *testing.T) {
function TestExternal (line 99) | func TestExternal(t *testing.T) {
function TestException (line 122) | func TestException(t *testing.T) {
function TestPanic (line 134) | func TestPanic(t *testing.T) {
FILE: logics/item_to_item.go
function init (line 49) | func init() {
type ItemToItemOptions (line 57) | type ItemToItemOptions struct
type ItemToItem (line 63) | type ItemToItem interface
function NewItemToItem (line 71) | func NewItemToItem(cfg config.ItemToItemConfig, n int, timestamp time.Ti...
type baseItemToItem (line 100) | type baseItemToItem struct
method Timestamp (line 114) | func (b *baseItemToItem[T]) Timestamp() time.Time {
method Count (line 118) | func (b *baseItemToItem[T]) Count() int {
method Get (line 122) | func (b *baseItemToItem[T]) Get(i int) *data.Item {
method pushItem (line 129) | func (b *baseItemToItem[T]) pushItem(item *data.Item, v T) {
method PopAll (line 146) | func (b *baseItemToItem[T]) PopAll(i int) []cache.Score {
type embeddingItemToItem (line 170) | type embeddingItemToItem struct
method Push (line 192) | func (e *embeddingItemToItem) Push(item *data.Item, _ []int32) {
function newEmbeddingItemToItem (line 175) | func newEmbeddingItemToItem(cfg config.ItemToItemConfig, n int, timestam...
type tagsItemToItem (line 221) | type tagsItemToItem struct
method Push (line 245) | func (t *tagsItemToItem) Push(item *data.Item, _ []int32) {
function newTagsItemToItem (line 226) | func newTagsItemToItem(cfg config.ItemToItemConfig, n int, timestamp tim...
type usersItemToItem (line 265) | type usersItemToItem struct
method Push (line 284) | func (u *usersItemToItem) Push(item *data.Item, feedback []int32) {
function newUsersItemToItem (line 270) | func newUsersItemToItem(cfg config.ItemToItemConfig, n int, timestamp ti...
type autoItemToItem (line 292) | type autoItemToItem struct
method Push (line 312) | func (a *autoItemToItem) Push(item *data.Item, feedback []int32) {
method distance (line 327) | func (a *autoItemToItem) distance(u, v lo.Tuple2[[]dataset.ID, []int32...
function newAutoItemToItem (line 298) | func newAutoItemToItem(cfg config.ItemToItemConfig, n int, timestamp tim...
type IDF (line 331) | type IDF
method distance (line 333) | func (idf IDF[T]) distance(a, b []T) float32 {
method weightedSumCommonElements (line 350) | func (idf IDF[T]) weightedSumCommonElements(a, b []T) (float32, float32) {
method weightedSum (line 367) | func (idf IDF[T]) weightedSum(a []T) float32 {
function flatten (line 375) | func flatten(o any, tSet mapset.Set[dataset.ID]) {
type chatItemToItem (line 390) | type chatItemToItem struct
method PopAll (line 425) | func (g *chatItemToItem) PopAll(i int) []cache.Score {
function newChatItemToItem (line 400) | func newChatItemToItem(cfg config.ItemToItemConfig, n int, timestamp tim...
function stripThinkInCompletion (line 538) | func stripThinkInCompletion(s string) string {
FILE: logics/item_to_item_test.go
type ItemToItemTestSuite (line 30) | type ItemToItemTestSuite struct
method TestColumnFunc (line 34) | func (suite *ItemToItemTestSuite) TestColumnFunc() {
method TestEmbedding (line 85) | func (suite *ItemToItemTestSuite) TestEmbedding() {
method TestHidden (line 108) | func (suite *ItemToItemTestSuite) TestHidden() {
method TestTags (line 152) | func (suite *ItemToItemTestSuite) TestTags() {
method TestUsers (line 181) | func (suite *ItemToItemTestSuite) TestUsers() {
method TestAuto (line 205) | func (suite *ItemToItemTestSuite) TestAuto() {
method TestChat (line 243) | func (suite *ItemToItemTestSuite) TestChat() {
function TestItemToItem (line 282) | func TestItemToItem(t *testing.T) {
FILE: logics/non_personalized.go
type NonPersonalized (line 35) | type NonPersonalized struct
method Push (line 86) | func (l *NonPersonalized) Push(item data.Item, feedback []data.Feedbac...
method PopAll (line 144) | func (l *NonPersonalized) PopAll() []cache.Score {
method Name (line 172) | func (l *NonPersonalized) Name() string {
method Timestamp (line 176) | func (l *NonPersonalized) Timestamp() time.Time {
function NewNonPersonalized (line 45) | func NewNonPersonalized(cfg config.NonPersonalizedConfig, n int, timesta...
FILE: logics/non_personalized_test.go
function TestLatest (line 28) | func TestLatest(t *testing.T) {
function TestPopular (line 48) | func TestPopular(t *testing.T) {
function TestPopularWindow (line 68) | func TestPopularWindow(t *testing.T) {
function TestFilter (line 100) | func TestFilter(t *testing.T) {
function TestHidden (line 122) | func TestHidden(t *testing.T) {
function TestMostStarredWeekly (line 143) | func TestMostStarredWeekly(t *testing.T) {
FILE: logics/recommend.go
constant LatestRecommender (line 34) | LatestRecommender = "latest"
constant NonPersonalizedRecommender (line 35) | NonPersonalizedRecommender = "non-personalized/"
constant ItemToItemRecommender (line 36) | ItemToItemRecommender = "item-to-item/"
constant UserToUserRecommender (line 37) | UserToUserRecommender = "user-to-user/"
constant ExternalRecommender (line 38) | ExternalRecommender = "external/"
constant CollaborativeRecommender (line 39) | CollaborativeRecommender = "collaborative"
type Recommender (line 42) | type Recommender struct
method ExcludeSet (line 86) | func (r *Recommender) ExcludeSet() mapset.Set[string] {
method UserFeedback (line 90) | func (r *Recommender) UserFeedback() []data.Feedback {
method IsColdStart (line 94) | func (r *Recommender) IsColdStart() bool {
method Recommend (line 98) | func (r *Recommender) Recommend(ctx context.Context, limit int) (resul...
method RecommendSequential (line 126) | func (r *Recommender) RecommendSequential(ctx context.Context, result ...
method parse (line 149) | func (r *Recommender) parse(fullname string) (RecommenderFunc, error) {
method recommendLatest (line 171) | func (r *Recommender) recommendLatest(ctx context.Context) ([]cache.Sc...
method recommendNonPersonalized (line 189) | func (r *Recommender) recommendNonPersonalized(name string) Recommende...
method recommendCollaborative (line 214) | func (r *Recommender) recommendCollaborative(ctx context.Context) ([]c...
method recommendItemToItem (line 231) | func (r *Recommender) recommendItemToItem(name string) RecommenderFunc {
method recommendUserToUser (line 281) | func (r *Recommender) recommendUserToUser(name string) RecommenderFunc {
method recommendExternal (line 340) | func (r *Recommender) recommendExternal(name string) RecommenderFunc {
type RecommenderFunc (line 55) | type RecommenderFunc
function NewRecommender (line 57) | func NewRecommender(config config.RecommendConfig, cacheClient cache.Dat...
FILE: logics/recommend_test.go
type RecommenderTestSuite (line 30) | type RecommenderTestSuite struct
method SetupSuite (line 36) | func (suite *RecommenderTestSuite) SetupSuite() {
method TearDownSuite (line 50) | func (suite *RecommenderTestSuite) TearDownSuite() {
method TestLatest (line 57) | func (suite *RecommenderTestSuite) TestLatest() {
method TestCollaborative (line 109) | func (suite *RecommenderTestSuite) TestCollaborative() {
method TestNonPersonalized (line 163) | func (suite *RecommenderTestSuite) TestNonPersonalized() {
method TestExternal (line 221) | func (suite *RecommenderTestSuite) TestExternal() {
function TestRecommenderTestSuite (line 264) | func TestRecommenderTestSuite(t *testing.T) {
FILE: logics/user_to_user.go
type UserToUserOptions (line 37) | type UserToUserOptions struct
type UserToUser (line 42) | type UserToUser interface
function NewUserToUser (line 49) | func NewUserToUser(cfg config.UserToUserConfig, n int, timestamp time.Ti...
type baseUserToUser (line 72) | type baseUserToUser struct
method Users (line 82) | func (b *baseUserToUser[T]) Users() []*data.User {
method Timestamp (line 86) | func (b *baseUserToUser[T]) Timestamp() time.Time {
method PopAll (line 90) | func (b *baseUserToUser[T]) PopAll(i int) []cache.Score {
type embeddingUserToUser (line 105) | type embeddingUserToUser struct
method Push (line 128) | func (e *embeddingUserToUser) Push(user *data.User, _ []int32) {
function newEmbeddingUserToUser (line 110) | func newEmbeddingUserToUser(cfg config.UserToUserConfig, n int, timestam...
type tagsUserToUser (line 160) | type tagsUserToUser struct
method Push (line 184) | func (t *tagsUserToUser) Push(user *data.User, _ []int32) {
function newTagsUserToUser (line 165) | func newTagsUserToUser(cfg config.UserToUserConfig, n int, timestamp tim...
type itemsUserToUser (line 210) | type itemsUserToUser struct
method Push (line 229) | func (i *itemsUserToUser) Push(user *data.User, feedback []int32) {
function newItemsUserToUser (line 215) | func newItemsUserToUser(cfg config.UserToUserConfig, n int, timestamp ti...
type autoUserToUser (line 244) | type autoUserToUser struct
method Push (line 264) | func (a *autoUserToUser) Push(user *data.User, feedback []int32) {
method distance (line 286) | func (a *autoUserToUser) distance(u, v lo.Tuple2[[]dataset.ID, []int32...
function newAutoUserToUser (line 250) | func newAutoUserToUser(cfg config.UserToUserConfig, n int, timestamp tim...
FILE: logics/user_to_user_test.go
type UserToUserTestSuite (line 28) | type UserToUserTestSuite struct
method TestEmbedding (line 32) | func (suite *UserToUserTestSuite) TestEmbedding() {
method TestTags (line 55) | func (suite *UserToUserTestSuite) TestTags() {
method TestItems (line 84) | func (suite *UserToUserTestSuite) TestItems() {
method TestAuto (line 108) | func (suite *UserToUserTestSuite) TestAuto() {
function TestUserToUser (line 140) | func TestUserToUser(t *testing.T) {
FILE: master/master.go
type Datasets (line 53) | type Datasets struct
type Master (line 63) | type Master struct
method Serve (line 149) | func (m *Master) Serve() {
method Shutdown (line 289) | func (m *Master) Shutdown() {
method RunTasksLoop (line 299) | func (m *Master) RunTasksLoop() {
function NewMaster (line 104) | func NewMaster(cfg *config.Config, cacheFolder string, standalone bool, ...
FILE: master/master_test.go
type MasterTestSuite (line 27) | type MasterTestSuite struct
method SetupTest (line 32) | func (s *MasterTestSuite) SetupTest() {
method TearDownTest (line 48) | func (s *MasterTestSuite) TearDownTest() {
function TestMaster (line 53) | func TestMaster(t *testing.T) {
FILE: master/metrics.go
constant LabelFeedbackType (line 28) | LabelFeedbackType = "feedback_type"
constant LabelStep (line 29) | LabelStep = "step"
constant LabelData (line 30) | LabelData = "data"
type OnlineEvaluator (line 218) | type OnlineEvaluator struct
method Add (line 242) | func (evaluator *OnlineEvaluator) Add(feedbackType string, value float...
method Evaluate (line 269) | func (evaluator *OnlineEvaluator) Evaluate() []cache.TimeSeriesPoint {
function NewOnlineEvaluator (line 227) | func NewOnlineEvaluator(positiveTypes, readTypes []expression.FeedbackTy...
FILE: master/metrics_test.go
function TestOnlineEvaluator (line 26) | func TestOnlineEvaluator(t *testing.T) {
FILE: master/rest.go
type UserInfo (line 63) | type UserInfo struct
type RerankerPrompt (line 76) | type RerankerPrompt struct
method CreateWebService (line 81) | func (m *Master) CreateWebService() {
type SinglePageAppFileSystem (line 254) | type SinglePageAppFileSystem struct
method Open (line 259) | func (fs *SinglePageAppFileSystem) Open(name string) (http.File, error) {
method StartHttpServer (line 267) | func (m *Master) StartHttpServer() {
function init (line 292) | func init() {
function noCache (line 333) | func noCache(h http.Handler) http.Handler {
method dashboard (line 350) | func (m *Master) dashboard(response http.ResponseWriter, request *http.R...
method login (line 369) | func (m *Master) login(response http.ResponseWriter, request *http.Reque...
method logout (line 410) | func (m *Master) logout(response http.ResponseWriter, request *http.Requ...
method LoginFilter (line 422) | func (m *Master) LoginFilter(req *restful.Request, resp *restful.Respons...
method checkLogin (line 435) | func (m *Master) checkLogin(request *http.Request) bool {
method handleUserInfo (line 465) | func (m *Master) handleUserInfo(request *restful.Request, response *rest...
method getCategories (line 490) | func (m *Master) getCategories(request *restful.Request, response *restf...
method getCluster (line 507) | func (m *Master) getCluster(_ *restful.Request, response *restful.Respon...
function formatConfig (line 519) | func formatConfig(configMap map[string]interface{}) map[string]interface...
method postConfig (line 539) | func (m *Master) postConfig(request *restful.Request, response *restful....
method getConfig (line 586) | func (m *Master) getConfig(_ *restful.Request, response *restful.Respons...
method deleteConfig (line 599) | func (m *Master) deleteConfig(_request *restful.Request, response *restf...
method getConfigSchema (line 619) | func (m *Master) getConfigSchema(_ *restful.Request, response *restful.R...
type Status (line 623) | type Status struct
method getStats (line 642) | func (m *Master) getStats(request *restful.Request, response *restful.Re...
method getTasks (line 710) | func (m *Master) getTasks(_ *restful.Request, response *restful.Response) {
method getTimeseries (line 735) | func (m *Master) getTimeseries(request *restful.Request, response *restf...
type UserIterator (line 781) | type UserIterator struct
type User (line 786) | type User struct
method getUser (line 792) | func (m *Master) getUser(request *restful.Request, response *restful.Res...
method getUsers (line 821) | func (m *Master) getUsers(request *restful.Request, response *restful.Re...
method getRecommend (line 854) | func (m *Master) getRecommend(request *restful.Request, response *restfu...
type DetailedFeedback (line 921) | type DetailedFeedback struct
method getUserFeedback (line 931) | func (m *Master) getUserFeedback(request *restful.Request, response *res...
type ScoredItem (line 1019) | type ScoredItem struct
type ScoreUser (line 1024) | type ScoreUser struct
method GetItem (line 1029) | func (m *Master) GetItem(score cache.Score) (any, error) {
method GetUser (line 1040) | func (m *Master) GetUser(score cache.Score) (any, error) {
method getLatest (line 1051) | func (m *Master) getLatest(request *restful.Request, response *restful.R...
method getNonPersonalized (line 1085) | func (m *Master) getNonPersonalized(request *restful.Request, response *...
method getItemToItem (line 1092) | func (m *Master) getItemToItem(request *restful.Request, response *restf...
method getUserToUser (line 1100) | func (m *Master) getUserToUser(request *restful.Request, response *restf...
method getExternal (line 1107) | func (m *Master) getExternal(request *restful.Request, response *restful...
method getRankerPrompt (line 1141) | func (m *Master) getRankerPrompt(request *restful.Request, response *res...
method importExportUsers (line 1260) | func (m *Master) importExportUsers(response http.ResponseWriter, request...
method importExportItems (line 1358) | func (m *Master) importExportItems(response http.ResponseWriter, request...
method importExportFeedback (line 1481) | func (m *Master) importExportFeedback(response http.ResponseWriter, requ...
method purge (line 1610) | func (m *Master) purge(response http.ResponseWriter, request *http.Reque...
function writeError (line 1652) | func writeError(response http.ResponseWriter, httpStatus int, message st...
method checkAdmin (line 1661) | func (m *Master) checkAdmin(request *http.Request) bool {
constant EOF (line 1672) | EOF = int64(0)
constant UserStream (line 1673) | UserStream = int64(-1)
constant ItemStream (line 1674) | ItemStream = int64(-2)
constant FeedbackStream (line 1675) | FeedbackStream = int64(-3)
type DumpStats (line 1678) | type DumpStats struct
function writeDump (line 1685) | func writeDump[T proto.Message](w io.Writer, data T) error {
function readDump (line 1699) | func readDump[T proto.Message](r io.Reader, data T) (int64, error) {
method dump (line 1714) | func (m *Master) dump(response http.ResponseWriter, request *http.Reques...
method Restore (line 1825) | func (m *Master) Restore(r io.ReadCloser) (stats DumpStats, err error) {
method restore (line 1940) | func (m *Master) restore(response http.ResponseWriter, request *http.Req...
method handleOAuth2Callback (line 1971) | func (m *Master) handleOAuth2Callback(w http.ResponseWriter, r *http.Req...
method chat (line 2015) | func (m *Master) chat(response http.ResponseWriter, request *http.Reques...
FILE: master/rest_test.go
constant mockMasterUsername (line 49) | mockMasterUsername = "admin"
constant mockMasterPassword (line 50) | mockMasterPassword = "pass"
function marshal (line 53) | func marshal(t *testing.T, v interface{}) string {
function marshalJSONLines (line 59) | func marshalJSONLines[T any](t *testing.T, v []T) string {
function convertToMapStructure (line 69) | func convertToMapStructure(t *testing.T, v interface{}) map[string]inter...
type MasterAPITestSuite (line 76) | type MasterAPITestSuite struct
method SetupTest (line 84) | func (suite *MasterAPITestSuite) SetupTest() {
method TearDownTest (line 135) | func (suite *MasterAPITestSuite) TearDownTest() {
method TestExportUsers (line 146) | func (suite *MasterAPITestSuite) TestExportUsers() {
method TestExportItems (line 167) | func (suite *MasterAPITestSuite) TestExportItems() {
method TestExportFeedback (line 209) | func (suite *MasterAPITestSuite) TestExportFeedback() {
method TestImportUsers (line 230) | func (suite *MasterAPITestSuite) TestImportUsers() {
method TestImportItems (line 261) | func (suite *MasterAPITestSuite) TestImportItems() {
method TestImportFeedback (line 312) | func (suite *MasterAPITestSuite) TestImportFeedback() {
method TestGetCluster (line 343) | func (suite *MasterAPITestSuite) TestGetCluster() {
method TestGetStats (line 374) | func (suite *MasterAPITestSuite) TestGetStats() {
method TestGetCategories (line 402) | func (suite *MasterAPITestSuite) TestGetCategories() {
method TestGetUsers (line 423) | func (suite *MasterAPITestSuite) TestGetUsers() {
method TestGetLatestItems (line 462) | func (suite *MasterAPITestSuite) TestGetLatestItems() {
method TestSearchDocumentsOfItems (line 486) | func (suite *MasterAPITestSuite) TestSearchDocumentsOfItems() {
method TestSearchDocumentsOfUsers (line 547) | func (suite *MasterAPITestSuite) TestSearchDocumentsOfUsers() {
method TestFeedback (line 590) | func (suite *MasterAPITestSuite) TestFeedback() {
method TestGetRecommends (line 617) | func (suite *MasterAPITestSuite) TestGetRecommends() {
method TestGetNonPersonalizedRecommends (line 661) | func (suite *MasterAPITestSuite) TestGetNonPersonalizedRecommends() {
method TestGetExternal (line 701) | func (suite *MasterAPITestSuite) TestGetExternal() {
method TestPurge (line 726) | func (suite *MasterAPITestSuite) TestPurge() {
method TestConfig (line 791) | func (suite *MasterAPITestSuite) TestConfig() {
method TestGetConfigSchema (line 862) | func (suite *MasterAPITestSuite) TestGetConfigSchema() {
method TestGetTimeseries (line 873) | func (suite *MasterAPITestSuite) TestGetTimeseries() {
method TestGetRankerPrompt (line 893) | func (suite *MasterAPITestSuite) TestGetRankerPrompt() {
method TestDumpAndRestore (line 968) | func (suite *MasterAPITestSuite) TestDumpAndRestore() {
method TestExportAndImport (line 1040) | func (suite *MasterAPITestSuite) TestExportAndImport() {
method TestChat (line 1165) | func (suite *MasterAPITestSuite) TestChat() {
function TestMasterAPI (line 1178) | func TestMasterAPI(t *testing.T) {
FILE: master/rpc.go
method GetMeta (line 29) | func (m *Master) GetMeta(ctx context.Context, nodeInfo *protocol.NodeInf...
method PushProgress (line 79) | func (m *Master) PushProgress(
FILE: master/rpc_test.go
function newRankingDataset (line 44) | func newRankingDataset() (*dataset.Dataset, *dataset.Dataset) {
function newClickDataset (line 48) | func newClickDataset() (*ctr.Dataset, *ctr.Dataset) {
type mockMasterRPC (line 55) | type mockMasterRPC struct
method Start (line 90) | func (m *mockMasterRPC) Start(t *testing.T) {
method StartTLS (line 101) | func (m *mockMasterRPC) StartTLS(t *testing.T, o *util.TLSConfig) {
method Stop (line 117) | func (m *mockMasterRPC) Stop() {
function newMockMasterRPC (line 61) | func newMockMasterRPC(t *testing.T) *mockMasterRPC {
function TestRPC (line 122) | func TestRPC(t *testing.T) {
function generateToTempFile (line 174) | func generateToTempFile(t *testing.T) (string, string, string) {
function TestSSL (line 192) | func TestSSL(t *testing.T) {
FILE: master/tasks.go
constant batchSize (line 48) | batchSize = 10000
method loadDataset (line 50) | func (m *Master) loadDataset(parent context.Context) (datasets Datasets,...
method runLoadDatasetTask (line 208) | func (m *Master) runLoadDatasetTask(ctx context.Context) error {
method LoadDataFromDatabase (line 253) | func (m *Master) LoadDataFromDatabase(
method updateItemToItem (line 622) | func (m *Master) updateItemToItem(parent context.Context, dataset *datas...
method needUpdateItemToItem (line 704) | func (m *Master) needUpdateItemToItem(ctx context.Context, itemId string...
method updateUserToUser (line 739) | func (m *Master) updateUserToUser(parent context.Context, dataset *datas...
method needUpdateUserToUser (line 811) | func (m *Master) needUpdateUserToUser(ctx context.Context, userId string...
method trainCollaborativeFiltering (line 843) | func (m *Master) trainCollaborativeFiltering(parent context.Context, tra...
method newCollaborativeFilteringModel (line 980) | func (m *Master) newCollaborativeFilteringModel(modelType string, params...
method trainClickThroughRatePrediction (line 991) | func (m *Master) trainClickThroughRatePrediction(parent context.Context,...
method removeOutOfDateModels (line 1101) | func (m *Master) removeOutOfDateModels() {
method collectGarbage (line 1129) | func (m *Master) collectGarbage(parent context.Context, dataSet *dataset...
method optimizeCollaborativeFiltering (line 1183) | func (m *Master) optimizeCollaborativeFiltering(parent context.Context, ...
method optimizeClickThroughRatePrediction (line 1233) | func (m *Master) optimizeClickThroughRatePrediction(parent context.Conte...
method updateRecommend (line 1281) | func (m *Master) updateRecommend(ctx context.Context) error {
method pullAllUsers (line 1337) | func (m *Master) pullAllUsers(ctx context.Context) ([]data.User, error) {
FILE: master/tasks_test.go
method TestFindItemToItem (line 29) | func (s *MasterTestSuite) TestFindItemToItem() {
method TestUserToUser (line 132) | func (s *MasterTestSuite) TestUserToUser() {
method TestLoadDataFromDatabase (line 210) | func (s *MasterTestSuite) TestLoadDataFromDatabase() {
method TestNonPersonalizedRecommend (line 332) | func (s *MasterTestSuite) TestNonPersonalizedRecommend() {
method TestNeedUpdateItemToItem (line 409) | func (s *MasterTestSuite) TestNeedUpdateItemToItem() {
method TestNeedUpdateUserToUser (line 442) | func (s *MasterTestSuite) TestNeedUpdateUserToUser() {
method TestGarbageCollection (line 475) | func (s *MasterTestSuite) TestGarbageCollection() {
FILE: model/built_in.go
type DatasetFormat (line 31) | type DatasetFormat
constant FormatNCF (line 34) | FormatNCF DatasetFormat = iota
constant FormatLibFM (line 35) | FormatLibFM
type _BuiltInDataSet (line 39) | type _BuiltInDataSet struct
function init (line 92) | func init() {
function LocateBuiltInDataset (line 111) | func LocateBuiltInDataset(name string, format DatasetFormat) (string, st...
function downloadFromUrl (line 133) | func downloadFromUrl(src, dst string) (string, error) {
function unzip (line 165) | func unzip(src, dst string) ([]string, error) {
FILE: model/built_in_test.go
function TestUnzip (line 23) | func TestUnzip(t *testing.T) {
function TestLocateBuiltInDataset (line 34) | func TestLocateBuiltInDataset(t *testing.T) {
FILE: model/cf/evaluator.go
type Metric (line 32) | type Metric
function Evaluate (line 35) | func Evaluate(estimator MatrixFactorization, testSet, trainSet dataset.C...
function NDCG (line 75) | func NDCG(targetSet mapset.Set[int32], rankList []int32) float32 {
function Precision (line 94) | func Precision(targetSet mapset.Set[int32], rankList []int32) float32 {
function Recall (line 108) | func Recall(targetSet mapset.Set[int32], rankList []int32) float32 {
function HR (line 119) | func HR(targetSet mapset.Set[int32], rankList []int32) float32 {
function MAP (line 130) | func MAP(targetSet mapset.Set[int32], rankList []int32) float32 {
function MRR (line 153) | func MRR(targetSet mapset.Set[int32], rankList []int32) float32 {
function Rank (line 162) | func Rank(model MatrixFactorization, userId int32, candidates []int32, t...
FILE: model/cf/evaluator_test.go
constant evalEpsilon (line 31) | evalEpsilon = 0.00001
function TestNDCG (line 33) | func TestNDCG(t *testing.T) {
function TestPrecision (line 39) | func TestPrecision(t *testing.T) {
function TestRecall (line 45) | func TestRecall(t *testing.T) {
function TestAP (line 51) | func TestAP(t *testing.T) {
function TestRR (line 57) | func TestRR(t *testing.T) {
function TestHR (line 63) | func TestHR(t *testing.T) {
type mockMatrixFactorizationForEval (line 69) | type mockMatrixFactorizationForEval struct
method GetUserFactor (line 75) | func (m *mockMatrixFactorizationForEval) GetUserFactor(_ int32) []floa...
method GetItemFactor (line 79) | func (m *mockMatrixFactorizationForEval) GetItemFactor(_ int32) []floa...
method IsUserPredictable (line 83) | func (m *mockMatrixFactorizationForEval) IsUserPredictable(_ int32) bo...
method IsItemPredictable (line 87) | func (m *mockMatrixFactorizationForEval) IsItemPredictable(_ int32) bo...
method Marshal (line 91) | func (m *mockMatrixFactorizationForEval) Marshal(_ io.Writer) error {
method Unmarshal (line 95) | func (m *mockMatrixFactorizationForEval) Unmarshal(_ io.Reader) error {
method Invalid (line 99) | func (m *mockMatrixFactorizationForEval) Invalid() bool {
method GetUserIndex (line 103) | func (m *mockMatrixFactorizationForEval) GetUserIndex() *dataset.FreqD...
method GetItemIndex (line 107) | func (m *mockMatrixFactorizationForEval) GetItemIndex() *dataset.FreqD...
method Fit (line 111) | func (m *mockMatrixFactorizationForEval) Fit(_ context.Context, _, _ d...
method Predict (line 115) | func (m *mockMatrixFactorizationForEval) Predict(_, _ string) float32 {
method internalPredict (line 119) | func (m *mockMatrixFactorizationForEval) internalPredict(userId, itemI...
method Clear (line 129) | func (m *mockMatrixFactorizationForEval) Clear() {
method SuggestParams (line 133) | func (m *mockMatrixFactorizationForEval) SuggestParams(trial goptuna.T...
function TestEvaluate (line 137) | func TestEvaluate(t *testing.T) {
FILE: model/cf/model.go
type Score (line 44) | type Score struct
type FitConfig (line 50) | type FitConfig struct
method SetVerbose (line 67) | func (config *FitConfig) SetVerbose(verbose int) *FitConfig {
method SetJobs (line 72) | func (config *FitConfig) SetJobs(jobs int) *FitConfig {
method SetPatience (line 77) | func (config *FitConfig) SetPatience(patience int) *FitConfig {
function NewFitConfig (line 58) | func NewFitConfig() *FitConfig {
type Model (line 82) | type Model interface
type MatrixFactorization (line 98) | type MatrixFactorization interface
type BaseMatrixFactorization (line 118) | type BaseMatrixFactorization struct
method Init (line 129) | func (baseModel *BaseMatrixFactorization) Init(trainSet dataset.CFSpli...
method GetUserIndex (line 148) | func (baseModel *BaseMatrixFactorization) GetUserIndex() *dataset.Freq...
method GetItemIndex (line 152) | func (baseModel *BaseMatrixFactorization) GetItemIndex() *dataset.Freq...
method IsUserPredictable (line 157) | func (baseModel *BaseMatrixFactorization) IsUserPredictable(userIndex ...
method IsItemPredictable (line 165) | func (baseModel *BaseMatrixFactorization) IsItemPredictable(itemIndex ...
method GetUserFactor (line 173) | func (baseModel *BaseMatrixFactorization) GetUserFactor(userIndex int3...
method GetItemFactor (line 178) | func (baseModel *BaseMatrixFactorization) GetItemFactor(itemIndex int3...
method Predict (line 182) | func (baseModel *BaseMatrixFactorization) Predict(userId, itemId strin...
method internalPredict (line 195) | func (baseModel *BaseMatrixFactorization) internalPredict(userIndex, i...
method Marshal (line 206) | func (baseModel *BaseMatrixFactorization) Marshal(w io.Writer) error {
method Unmarshal (line 250) | func (baseModel *BaseMatrixFactorization) Unmarshal(r io.Reader) error {
method Clear (line 294) | func (baseModel *BaseMatrixFactorization) Clear() {
method Invalid (line 301) | func (baseModel *BaseMatrixFactorization) Invalid() bool {
function GetModelName (line 309) | func GetModelName(m Model) string {
function MarshalModel (line 320) | func MarshalModel(w io.Writer, m Model) error {
function UnmarshalModel (line 330) | func UnmarshalModel(r io.Reader) (MatrixFactorization, error) {
type BPR (line 367) | type BPR struct
method SetParams (line 386) | func (bpr *BPR) SetParams(params model.Params) {
method SuggestParams (line 397) | func (bpr *BPR) SuggestParams(trial goptuna.Trial) model.Params {
method Fit (line 408) | func (bpr *BPR) Fit(ctx context.Context, trainSet, valSet dataset.CFSp...
method Init (line 532) | func (bpr *BPR) Init(trainSet dataset.CFSplit) {
method Marshal (line 543) | func (bpr *BPR) Marshal(w io.Writer) error {
method Unmarshal (line 551) | func (bpr *BPR) Unmarshal(r io.Reader) error {
function NewBPR (line 379) | func NewBPR(params model.Params) *BPR {
type ALS (line 559) | type ALS struct
method SetParams (line 578) | func (als *ALS) SetParams(params model.Params) {
method SuggestParams (line 588) | func (als *ALS) SuggestParams(trial goptuna.Trial) model.Params {
method Init (line 598) | func (als *ALS) Init(trainSet dataset.CFSplit) {
method Fit (line 609) | func (als *ALS) Fit(ctx context.Context, trainSet, valSet dataset.CFSp...
method Marshal (line 778) | func (als *ALS) Marshal(w io.Writer) error {
method Unmarshal (line 786) | func (als *ALS) Unmarshal(r io.Reader) error {
function NewALS (line 571) | func NewALS(params model.Params) *ALS {
FILE: model/cf/model_test.go
constant benchDelta (line 28) | benchDelta = 0.01
function newFitConfig (line 30) | func newFitConfig(_ int) *FitConfig {
function TestBPR_MovieLens (line 35) | func TestBPR_MovieLens(t *testing.T) {
function TestCCD_MovieLens (line 93) | func TestCCD_MovieLens(t *testing.T) {
FILE: model/cf/optimize.go
type ModelCreator (line 28) | type ModelCreator
type ModelSearch (line 30) | type ModelSearch struct
method WithContext (line 51) | func (ms *ModelSearch) WithContext(ctx context.Context) *ModelSearch {
method WithSpan (line 56) | func (ms *ModelSearch) WithSpan(span *monitor.Span) *ModelSearch {
method Objective (line 61) | func (ms *ModelSearch) Objective(trial goptuna.Trial) (float64, error) {
method Result (line 83) | func (ms *ModelSearch) Result() meta.Model[Score] {
function NewModelSearch (line 41) | func NewModelSearch(models map[string]ModelCreator, trainSet, valSet dat...
FILE: model/cf/optimize_test.go
type mockMatrixFactorizationForSearch (line 29) | type mockMatrixFactorizationForSearch struct
method GetUserFactor (line 37) | func (m *mockMatrixFactorizationForSearch) GetUserFactor(_ int32) []fl...
method GetItemFactor (line 41) | func (m *mockMatrixFactorizationForSearch) GetItemFactor(_ int32) []fl...
method IsUserPredictable (line 45) | func (m *mockMatrixFactorizationForSearch) IsUserPredictable(_ int32) ...
method IsItemPredictable (line 49) | func (m *mockMatrixFactorizationForSearch) IsItemPredictable(_ int32) ...
method Marshal (line 53) | func (m *mockMatrixFactorizationForSearch) Marshal(_ io.Writer) error {
method Unmarshal (line 57) | func (m *mockMatrixFactorizationForSearch) Unmarshal(_ io.Reader) error {
method Invalid (line 61) | func (m *mockMatrixFactorizationForSearch) Invalid() bool {
method GetUserIndex (line 65) | func (m *mockMatrixFactorizationForSearch) GetUserIndex() *dataset.Fre...
method GetItemIndex (line 69) | func (m *mockMatrixFactorizationForSearch) GetItemIndex() *dataset.Fre...
method Fit (line 73) | func (m *mockMatrixFactorizationForSearch) Fit(_ context.Context, _, _...
method Predict (line 81) | func (m *mockMatrixFactorizationForSearch) Predict(_, _ string) float32 {
method internalPredict (line 85) | func (m *mockMatrixFactorizationForSearch) internalPredict(_, _ int32)...
method Clear (line 89) | func (m *mockMatrixFactorizationForSearch) Clear() {
method SuggestParams (line 93) | func (m *mockMatrixFactorizationForSearch) SuggestParams(trial goptuna...
function newMockMatrixFactorizationForSearch (line 33) | func newMockMatrixFactorizationForSearch(numEpoch int) *mockMatrixFactor...
function TestTPE (line 101) | func TestTPE(t *testing.T) {
FILE: model/ctr/data.go
type Label (line 34) | type Label struct
function ConvertLabels (line 39) | func ConvertLabels(o any) []Label {
function convertLabels (line 44) | func convertLabels(result []Label, prefix string, o any) []Label {
type Embedding (line 85) | type Embedding struct
function ConvertEmbeddings (line 90) | func ConvertEmbeddings(o any) []Embedding {
function convertEmbeddings (line 95) | func convertEmbeddings(result []Embedding, prefix string, o any) []Embed...
type Dataset (line 142) | type Dataset struct
method CountUsers (line 158) | func (dataset *Dataset) CountUsers() int {
method CountItems (line 163) | func (dataset *Dataset) CountItems() int {
method CountUserLabels (line 167) | func (dataset *Dataset) CountUserLabels() int {
method CountItemLabels (line 171) | func (dataset *Dataset) CountItemLabels() int {
method CountContextLabels (line 175) | func (dataset *Dataset) CountContextLabels() int {
method CountPositive (line 179) | func (dataset *Dataset) CountPositive() int {
method CountNegative (line 183) | func (dataset *Dataset) CountNegative() int {
method GetIndex (line 187) | func (dataset *Dataset) GetIndex() dataset.UnifiedIndex {
method Count (line 192) | func (dataset *Dataset) Count() int {
method GetTarget (line 205) | func (dataset *Dataset) GetTarget(i int) float32 {
method Get (line 210) | func (dataset *Dataset) Get(i int) ([]int32, []float32, [][]float32, f...
method Split (line 329) | func (dataset *Dataset) Split(ratio float32, seed int64) (*Dataset, *D...
method GetItemEmbeddingDim (line 383) | func (dataset *Dataset) GetItemEmbeddingDim() []int {
method GetItemEmbeddingIndex (line 387) | func (dataset *Dataset) GetItemEmbeddingIndex() *dataset.Index {
function LoadLibFMFile (line 259) | func LoadLibFMFile(path string) (features [][]lo.Tuple2[int32, float32],...
function LoadDataFromBuiltIn (line 309) | func LoadDataFromBuiltIn(name string) (train, test *Dataset, err error) {
FILE: model/ctr/data_test.go
function TestConvertLabels (line 26) | func TestConvertLabels(t *testing.T) {
function TestConvertEmbeddings (line 68) | func TestConvertEmbeddings(t *testing.T) {
function TestLoadDataFromBuiltIn (line 105) | func TestLoadDataFromBuiltIn(t *testing.T) {
function TestDataset_Split (line 112) | func TestDataset_Split(t *testing.T) {
FILE: model/ctr/evaluator.go
function EvaluateRegression (line 27) | func EvaluateRegression(estimator FactorizationMachines, testSet *Datase...
function EvaluateClassification (line 46) | func EvaluateClassification(estimator FactorizationMachines, testSet dat...
function Precision (line 85) | func Precision(posPrediction, negPrediction []float32) float32 {
function Recall (line 103) | func Recall(posPrediction, _ []float32) float32 {
function Accuracy (line 118) | func Accuracy(posPrediction, negPrediction []float32) float32 {
function AUC (line 136) | func AUC(posPrediction, negPrediction []float32) float32 {
FILE: model/ctr/evaluator_test.go
function TestPrecision (line 22) | func TestPrecision(t *testing.T) {
function TestRecall (line 31) | func TestRecall(t *testing.T) {
function TestAccuracy (line 39) | func TestAccuracy(t *testing.T) {
FILE: model/ctr/fm.go
constant headerAFM (line 40) | headerAFM = "AFM"
type AFM (line 42) | type AFM struct
method SuggestParams (line 73) | func (fm *AFM) SuggestParams(trial goptuna.Trial) model.Params {
method SetParams (line 83) | func (fm *AFM) SetParams(params model.Params) {
method Clear (line 95) | func (fm *AFM) Clear() {
method Invalid (line 99) | func (fm *AFM) Invalid() bool {
method Forward (line 103) | func (fm *AFM) Forward(indices, values *nn.Tensor, embeddings []*nn.Te...
method Parameters (line 127) | func (fm *AFM) Parameters() []*nn.Tensor {
method Predict (line 139) | func (fm *AFM) Predict(_, _ string, _, _ []Label) float32 {
method InternalPredict (line 143) | func (fm *AFM) InternalPredict(_ []int32, _ []float32) float32 {
method BatchInternalPredict (line 147) | func (fm *AFM) BatchInternalPredict(x []lo.Tuple2[[]int32, []float32],...
method BatchPredict (line 164) | func (fm *AFM) BatchPredict(inputs []lo.Tuple4[string, string, []Label...
method Init (line 212) | func (fm *AFM) Init(trainSet dataset.CTRSplit) {
method Fit (line 233) | func (fm *AFM) Fit(ctx context.Context, trainSet, testSet dataset.CTRS...
method Marshal (line 337) | func (fm *AFM) Marshal(w io.Writer) error {
method Unmarshal (line 368) | func (fm *AFM) Unmarshal(r io.Reader) error {
method convertToTensors (line 412) | func (fm *AFM) convertToTensors(x []lo.Tuple2[[]int32, []float32], e [...
function NewAFM (line 67) | func NewAFM(params model.Params) *AFM {
FILE: model/ctr/fm_xla.go
constant headerAFM (line 51) | headerAFM = "AFM"
type AFM (line 53) | type AFM struct
method SuggestParams (line 83) | func (fm *AFM) SuggestParams(trial goptuna.Trial) model.Params {
method SetParams (line 93) | func (fm *AFM) SetParams(params model.Params) {
method Clear (line 105) | func (fm *AFM) Clear() {
method Invalid (line 109) | func (fm *AFM) Invalid() bool {
method Predict (line 113) | func (fm *AFM) Predict(_, _ string, _, _ []Label) float32 {
method InternalPredict (line 117) | func (fm *AFM) InternalPredict(_ []int32, _ []float32) float32 {
method attentionForward (line 121) | func (fm *AFM) attentionForward(ctx *mlx_context.Context, x *graph.Nod...
method forwardGraph (line 144) | func (fm *AFM) forwardGraph(ctx *mlx_context.Context, indices, values ...
method BatchInternalPredict (line 205) | func (fm *AFM) BatchInternalPredict(x []lo.Tuple2[[]int32, []float32],...
method BatchPredict (line 265) | func (fm *AFM) BatchPredict(inputs []lo.Tuple4[string, string, []Label...
method Init (line 313) | func (fm *AFM) Init(trainSet dataset.CTRSplit) {
method Fit (line 392) | func (fm *AFM) Fit(ctx std_context.Context, trainSet, testSet dataset....
method Marshal (line 473) | func (fm *AFM) Marshal(w io.Writer) error {
method Unmarshal (line 521) | func (fm *AFM) Unmarshal(r io.Reader) error {
function NewAFM (line 77) | func NewAFM(params model.Params) *AFM {
type ctrDataset (line 339) | type ctrDataset struct
method Name (line 348) | func (d *ctrDataset) Name() string { return "CTRDataset" }
method Reset (line 349) | func (d *ctrDataset) Reset() { d.currentOffset = 0 }
method Yield (line 350) | func (d *ctrDataset) Yield() (spec any, inputs []*tensors.Tensor, labe...
type savedVariable (line 466) | type savedVariable struct
FILE: model/ctr/model.go
type Score (line 31) | type Score struct
method ZapFields (line 39) | func (score Score) ZapFields() []zap.Field {
method GetValue (line 48) | func (score Score) GetValue() float32 {
method BetterThan (line 52) | func (score Score) BetterThan(s Score) bool {
type FitConfig (line 56) | type FitConfig struct
method SetVerbose (line 70) | func (config *FitConfig) SetVerbose(verbose int) *FitConfig {
method SetJobs (line 75) | func (config *FitConfig) SetJobs(jobs int) *FitConfig {
method SetPatience (line 80) | func (config *FitConfig) SetPatience(patience int) *FitConfig {
method LoadDefaultIfNil (line 85) | func (config *FitConfig) LoadDefaultIfNil() *FitConfig {
function NewFitConfig (line 62) | func NewFitConfig() *FitConfig {
type FactorizationMachines (line 92) | type FactorizationMachines interface
type BatchInference (line 100) | type BatchInference interface
type BaseFactorizationMachines (line 105) | type BaseFactorizationMachines struct
method Init (line 110) | func (b *BaseFactorizationMachines) Init(trainSet dataset.CTRSplit) {
function MarshalModel (line 114) | func MarshalModel(w io.Writer, m FactorizationMachines) error {
function UnmarshalModel (line 129) | func UnmarshalModel(r io.Reader) (FactorizationMachines, error) {
FILE: model/ctr/model.py
class Dataset (line 10) | class Dataset:
method __init__ (line 12) | def __init__(self):
method __len__ (line 19) | def __len__(self):
method aligned (line 23) | def aligned(self) -> Tuple[List[List[int]], List[List[float]]]:
function load_libfm (line 39) | def load_libfm(path: str) -> Dataset:
function load_dataset (line 55) | def load_dataset(name: str) -> Tuple[Dataset, Dataset]:
function accuracy (line 60) | def accuracy(positive_predictions: List[float], negative_predictions: Li...
function auc (line 73) | def auc(positive_predictions: List[float], negative_predictions: List[fl...
class Evaluator (line 88) | class Evaluator:
method __init__ (line 90) | def __init__(self, test: Dataset, device: str = "cpu") -> None:
method evaluate (line 102) | def evaluate(self, model) -> Dict[str, float]:
class FactorizationMachine (line 125) | class FactorizationMachine(torch.nn.Module):
method __init__ (line 127) | def __init__(
method forward (line 137) | def forward(self, indices, values):
method predict (line 148) | def predict(self, indices, values):
method fit (line 151) | def fit(
function main (line 200) | def main(dataset: str, dim: int, iter: int, learn_rate: float, regular: ...
FILE: model/ctr/model_test.go
constant classificationDelta (line 27) | classificationDelta = 0.01
function newFitConfigWithTestTracker (line 29) | func newFitConfigWithTestTracker() *FitConfig {
function TestFactorizationMachines_Classification_Frappe (line 34) | func TestFactorizationMachines_Classification_Frappe(t *testing.T) {
function TestFactorizationMachines_Classification_MovieLens (line 50) | func TestFactorizationMachines_Classification_MovieLens(t *testing.T) {
function TestFactorizationMachines_Classification_Criteo (line 68) | func TestFactorizationMachines_Classification_Criteo(t *testing.T) {
function newSynthesisDataset (line 115) | func newSynthesisDataset() *Dataset {
function TestFactorizationMachines_Classification_Synthesis (line 155) | func TestFactorizationMachines_Classification_Synthesis(t *testing.T) {
FILE: model/ctr/optimize.go
type ModelCreator (line 28) | type ModelCreator
type ModelSearch (line 30) | type ModelSearch struct
method WithContext (line 51) | func (ms *ModelSearch) WithContext(ctx context.Context) *ModelSearch {
method WithSpan (line 56) | func (ms *ModelSearch) WithSpan(span *monitor.Span) *ModelSearch {
method Objective (line 61) | func (ms *ModelSearch) Objective(trial goptuna.Trial) (float64, error) {
method Result (line 85) | func (ms *ModelSearch) Result() meta.Model[Score] {
function NewModelSearch (line 41) | func NewModelSearch(models map[string]ModelCreator, trainSet, testSet da...
FILE: model/ctr/optimize_test.go
function NewMapIndexDataset (line 30) | func NewMapIndexDataset() *Dataset {
type mockFactorizationMachineForSearch (line 36) | type mockFactorizationMachineForSearch struct
method Marshal (line 40) | func (m *mockFactorizationMachineForSearch) Marshal(_ io.Writer) error {
method Invalid (line 44) | func (m *mockFactorizationMachineForSearch) Invalid() bool {
method GetUserIndex (line 48) | func (m *mockFactorizationMachineForSearch) GetUserIndex() dataset.Ind...
method GetItemIndex (line 52) | func (m *mockFactorizationMachineForSearch) GetItemIndex() dataset.Ind...
method Fit (line 56) | func (m *mockFactorizationMachineForSearch) Fit(_ context.Context, _, ...
method Predict (line 64) | func (m *mockFactorizationMachineForSearch) Predict(_, _ string, _, _ ...
method InternalPredict (line 68) | func (m *mockFactorizationMachineForSearch) InternalPredict(_ []int32,...
method Clear (line 72) | func (m *mockFactorizationMachineForSearch) Clear() {
method GetParamsGrid (line 76) | func (m *mockFactorizationMachineForSearch) GetParamsGrid(_ bool) mode...
method SuggestParams (line 84) | func (m *mockFactorizationMachineForSearch) SuggestParams(trial goptun...
function TestTPE (line 92) | func TestTPE(t *testing.T) {
FILE: model/model.go
type Model (line 24) | type Model interface
type BaseModel (line 34) | type BaseModel struct
method SetParams (line 41) | func (model *BaseModel) SetParams(params Params) {
method GetParams (line 48) | func (model *BaseModel) GetParams() Params {
method GetRandomGenerator (line 52) | func (model *BaseModel) GetRandomGenerator() util.RandomGenerator {
FILE: model/params.go
type ParamName (line 27) | type ParamName
constant Lr (line 31) | Lr ParamName = "Lr"
constant Reg (line 32) | Reg ParamName = "Reg"
constant NEpochs (line 33) | NEpochs ParamName = "NEpochs"
constant NFactors (line 34) | NFactors ParamName = "NFactors"
constant RandomState (line 35) | RandomState ParamName = "RandomState"
constant InitMean (line 36) | InitMean ParamName = "InitMean"
constant InitStdDev (line 37) | InitStdDev ParamName = "InitStdDev"
constant Alpha (line 38) | Alpha ParamName = "Alpha"
constant Similarity (line 39) | Similarity ParamName = "Similarity"
constant UseFeature (line 40) | UseFeature ParamName = "UseFeature"
constant BatchSize (line 41) | BatchSize ParamName = "BatchSize"
constant HiddenLayers (line 42) | HiddenLayers ParamName = "HiddenLayers"
constant Optimizer (line 43) | Optimizer ParamName = "Optimizer"
constant SGD (line 45) | SGD = "sgd"
constant Adam (line 46) | Adam = "adam"
type Params (line 59) | type Params
method Copy (line 62) | func (parameters Params) Copy() Params {
method GetBool (line 71) | func (parameters Params) GetBool(name ParamName, _default bool) bool {
method GetInt (line 86) | func (parameters Params) GetInt(name ParamName, _default int) int {
method GetInt64 (line 102) | func (parameters Params) GetInt64(name ParamName, _default int64) int64 {
method GetFloat32 (line 118) | func (parameters Params) GetFloat32(name ParamName, _default float32) ...
method GetString (line 137) | func (parameters Params) GetString(name ParamName, _default string) st...
method GetIntSlice (line 144) | func (parameters Params) GetIntSlice(name ParamName, _default []int) [...
method Overwrite (line 158) | func (parameters Params) Overwrite(params Params) Params {
type ParamsGrid (line 170) | type ParamsGrid
method Len (line 172) | func (grid ParamsGrid) Len() int {
method NumCombinations (line 176) | func (grid ParamsGrid) NumCombinations() int {
method Fill (line 184) | func (grid ParamsGrid) Fill(_default ParamsGrid) {
FILE: model/params_test.go
function TestParams_Copy (line 22) | func TestParams_Copy(t *testing.T) {
function TestParams_GetFloat32 (line 44) | func TestParams_GetFloat32(t *testing.T) {
function TestParams_GetBool (line 63) | func TestParams_GetBool(t *testing.T) {
function TestParams_GetInt (line 75) | func TestParams_GetInt(t *testing.T) {
function TestParams_GetInt64 (line 87) | func TestParams_GetInt64(t *testing.T) {
function TestParams_GetString (line 101) | func TestParams_GetString(t *testing.T) {
function TestParams_GetIntSlice (line 110) | func TestParams_GetIntSlice(t *testing.T) {
function TestParams_Overwrite (line 122) | func TestParams_Overwrite(t *testing.T) {
function TestParamsGrid (line 137) | func TestParamsGrid(t *testing.T) {
FILE: protocol/cache_store.pb.go
constant _ (line 34) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 36) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type Value (line 39) | type Value struct
method Reset (line 47) | func (x *Value) Reset() {
method String (line 54) | func (x *Value) String() string {
method ProtoMessage (line 58) | func (*Value) ProtoMessage() {}
method ProtoReflect (line 60) | func (x *Value) ProtoReflect() protoreflect.Message {
method Descriptor (line 73) | func (*Value) Descriptor() ([]byte, []int) {
method GetName (line 77) | func (x *Value) GetName() string {
method GetValue (line 84) | func (x *Value) GetValue() string {
type Score (line 91) | type Score struct
method Reset (line 102) | func (x *Score) Reset() {
method String (line 109) | func (x *Score) String() string {
method ProtoMessage (line 113) | func (*Score) ProtoMessage() {}
method ProtoReflect (line 115) | func (x *Score) ProtoReflect() protoreflect.Message {
method Descriptor (line 128) | func (*Score) Descriptor() ([]byte, []int) {
method GetId (line 132) | func (x *Score) GetId() string {
method GetScore (line 139) | func (x *Score) GetScore() float64 {
method GetIsHidden (line 146) | func (x *Score) GetIsHidden() bool {
method GetCategories (line 153) | func (x *Score) GetCategories() []string {
method GetTimestamp (line 160) | func (x *Score) GetTimestamp() *timestamppb.Timestamp {
type ScoreCondition (line 167) | type ScoreCondition struct
method Reset (line 176) | func (x *ScoreCondition) Reset() {
method String (line 183) | func (x *ScoreCondition) String() string {
method ProtoMessage (line 187) | func (*ScoreCondition) ProtoMessage() {}
method ProtoReflect (line 189) | func (x *ScoreCondition) ProtoReflect() protoreflect.Message {
method Descriptor (line 202) | func (*ScoreCondition) Descriptor() ([]byte, []int) {
method GetSubset (line 206) | func (x *ScoreCondition) GetSubset() string {
method GetId (line 213) | func (x *ScoreCondition) GetId() string {
method GetBefore (line 220) | func (x *ScoreCondition) GetBefore() *timestamppb.Timestamp {
type ScorePatch (line 227) | type ScorePatch struct
method Reset (line 236) | func (x *ScorePatch) Reset() {
method String (line 243) | func (x *ScorePatch) String() string {
method ProtoMessage (line 247) | func (*ScorePatch) ProtoMessage() {}
method ProtoReflect (line 249) | func (x *ScorePatch) ProtoReflect() protoreflect.Message {
method Descriptor (line 262) | func (*ScorePatch) Descriptor() ([]byte, []int) {
method GetIsHidden (line 266) | func (x *ScorePatch) GetIsHidden() bool {
method GetCategories (line 273) | func (x *ScorePatch) GetCategories() []string {
method GetScore (line 280) | func (x *ScorePatch) GetScore() float64 {
type TimeSeriesPoint (line 287) | type TimeSeriesPoint struct
method Reset (line 296) | func (x *TimeSeriesPoint) Reset() {
method String (line 303) | func (x *TimeSeriesPoint) String() string {
method ProtoMessage (line 307) | func (*TimeSeriesPoint) ProtoMessage() {}
method ProtoReflect (line 309) | func (x *TimeSeriesPoint) ProtoReflect() protoreflect.Message {
method Descriptor (line 322) | func (*TimeSeriesPoint) Descriptor() ([]byte, []int) {
method GetName (line 326) | func (x *TimeSeriesPoint) GetName() string {
method GetTimestamp (line 333) | func (x *TimeSeriesPoint) GetTimestamp() *timestamppb.Timestamp {
method GetValue (line 340) | func (x *TimeSeriesPoint) GetValue() float64 {
type GetRequest (line 347) | type GetRequest struct
method Reset (line 354) | func (x *GetRequest) Reset() {
method String (line 361) | func (x *GetRequest) String() string {
method ProtoMessage (line 365) | func (*GetRequest) ProtoMessage() {}
method ProtoReflect (line 367) | func (x *GetRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 380) | func (*GetRequest) Descriptor() ([]byte, []int) {
method GetName (line 384) | func (x *GetRequest) GetName() string {
type GetResponse (line 391) | type GetResponse struct
method Reset (line 398) | func (x *GetResponse) Reset() {
method String (line 405) | func (x *GetResponse) String() string {
method ProtoMessage (line 409) | func (*GetResponse) ProtoMessage() {}
method ProtoReflect (line 411) | func (x *GetResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 424) | func (*GetResponse) Descriptor() ([]byte, []int) {
method GetValue (line 428) | func (x *GetResponse) GetValue() string {
type SetRequest (line 435) | type SetRequest struct
method Reset (line 442) | func (x *SetRequest) Reset() {
method String (line 449) | func (x *SetRequest) String() string {
method ProtoMessage (line 453) | func (*SetRequest) ProtoMessage() {}
method ProtoReflect (line 455) | func (x *SetRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 468) | func (*SetRequest) Descriptor() ([]byte, []int) {
method GetValues (line 472) | func (x *SetRequest) GetValues() []*Value {
type SetResponse (line 479) | type SetResponse struct
method Reset (line 485) | func (x *SetResponse) Reset() {
method String (line 492) | func (x *SetResponse) String() string {
method ProtoMessage (line 496) | func (*SetResponse) ProtoMessage() {}
method ProtoReflect (line 498) | func (x *SetResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 511) | func (*SetResponse) Descriptor() ([]byte, []int) {
type DeleteRequest (line 515) | type DeleteRequest struct
method Reset (line 522) | func (x *DeleteRequest) Reset() {
method String (line 529) | func (x *DeleteRequest) String() string {
method ProtoMessage (line 533) | func (*DeleteRequest) ProtoMessage() {}
method ProtoReflect (line 535) | func (x *DeleteRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 548) | func (*DeleteRequest) Descriptor() ([]byte, []int) {
method GetName (line 552) | func (x *DeleteRequest) GetName() string {
type DeleteResponse (line 559) | type DeleteResponse struct
method Reset (line 565) | func (x *DeleteResponse) Reset() {
method String (line 572) | func (x *DeleteResponse) String() string {
method ProtoMessage (line 576) | func (*DeleteResponse) ProtoMessage() {}
method ProtoReflect (line 578) | func (x *DeleteResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 591) | func (*DeleteResponse) Descriptor() ([]byte, []int) {
type PushRequest (line 595) | type PushRequest struct
method Reset (line 603) | func (x *PushRequest) Reset() {
method String (line 610) | func (x *PushRequest) String() string {
method ProtoMessage (line 614) | func (*PushRequest) ProtoMessage() {}
method ProtoReflect (line 616) | func (x *PushRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 629) | func (*PushRequest) Descriptor() ([]byte, []int) {
method GetName (line 633) | func (x *PushRequest) GetName() string {
method GetValue (line 640) | func (x *PushRequest) GetValue() string {
type PushResponse (line 647) | type PushResponse struct
method Reset (line 653) | func (x *PushResponse) Reset() {
method String (line 660) | func (x *PushResponse) String() string {
method ProtoMessage (line 664) | func (*PushResponse) ProtoMessage() {}
method ProtoReflect (line 666) | func (x *PushResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 679) | func (*PushResponse) Descriptor() ([]byte, []int) {
type PopRequest (line 683) | type PopRequest struct
method Reset (line 690) | func (x *PopRequest) Reset() {
method String (line 697) | func (x *PopRequest) String() string {
method ProtoMessage (line 701) | func (*PopRequest) ProtoMessage() {}
method ProtoReflect (line 703) | func (x *PopRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 716) | func (*PopRequest) Descriptor() ([]byte, []int) {
method GetName (line 720) | func (x *PopRequest) GetName() string {
type PopResponse (line 727) | type PopResponse struct
method Reset (line 734) | func (x *PopResponse) Reset() {
method String (line 741) | func (x *PopResponse) String() string {
method ProtoMessage (line 745) | func (*PopResponse) ProtoMessage() {}
method ProtoReflect (line 747) | func (x *PopResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 760) | func (*PopResponse) Descriptor() ([]byte, []int) {
method GetValue (line 764) | func (x *PopResponse) GetValue() string {
type RemainRequest (line 771) | type RemainRequest struct
method Reset (line 778) | func (x *RemainRequest) Reset() {
method String (line 785) | func (x *RemainRequest) String() string {
method ProtoMessage (line 789) | func (*RemainRequest) ProtoMessage() {}
method ProtoReflect (line 791) | func (x *RemainRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 804) | func (*RemainRequest) Descriptor() ([]byte, []int) {
method GetName (line 808) | func (x *RemainRequest) GetName() string {
type RemainResponse (line 815) | type RemainResponse struct
method Reset (line 822) | func (x *RemainResponse) Reset() {
method String (line 829) | func (x *RemainResponse) String() string {
method ProtoMessage (line 833) | func (*RemainResponse) ProtoMessage() {}
method ProtoReflect (line 835) | func (x *RemainResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 848) | func (*RemainResponse) Descriptor() ([]byte, []int) {
method GetCount (line 852) | func (x *RemainResponse) GetCount() int64 {
type AddScoresRequest (line 859) | type AddScoresRequest struct
method Reset (line 868) | func (x *AddScoresRequest) Reset() {
method String (line 875) | func (x *AddScoresRequest) String() string {
method ProtoMessage (line 879) | func (*AddScoresRequest) ProtoMessage() {}
method ProtoReflect (line 881) | func (x *AddScoresRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 894) | func (*AddScoresRequest) Descriptor() ([]byte, []int) {
method GetCollection (line 898) | func (x *AddScoresRequest) GetCollection() string {
method GetSubset (line 905) | func (x *AddScoresRequest) GetSubset() string {
method GetDocuments (line 912) | func (x *AddScoresRequest) GetDocuments() []*Score {
type AddScoresResponse (line 919) | type AddScoresResponse struct
method Reset (line 925) | func (x *AddScoresResponse) Reset() {
method String (line 932) | func (x *AddScoresResponse) String() string {
method ProtoMessage (line 936) | func (*AddScoresResponse) ProtoMessage() {}
method ProtoReflect (line 938) | func (x *AddScoresResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 951) | func (*AddScoresResponse) Descriptor() ([]byte, []int) {
type SearchScoresRequest (line 955) | type SearchScoresRequest struct
method Reset (line 966) | func (x *SearchScoresRequest) Reset() {
method String (line 973) | func (x *SearchScoresRequest) String() string {
method ProtoMessage (line 977) | func (*SearchScoresRequest) ProtoMessage() {}
method ProtoReflect (line 979) | func (x *SearchScoresRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 992) | func (*SearchScoresRequest) Descriptor() ([]byte, []int) {
method GetCollection (line 996) | func (x *SearchScoresRequest) GetCollection() string {
method GetSubset (line 1003) | func (x *SearchScoresRequest) GetSubset() string {
method GetQuery (line 1010) | func (x *SearchScoresRequest) GetQuery() []string {
method GetBegin (line 1017) | func (x *SearchScoresRequest) GetBegin() int32 {
method GetEnd (line 1024) | func (x *SearchScoresRequest) GetEnd() int32 {
type SearchScoresResponse (line 1031) | type SearchScoresResponse struct
method Reset (line 1038) | func (x *SearchScoresResponse) Reset() {
method String (line 1045) | func (x *SearchScoresResponse) String() string {
method ProtoMessage (line 1049) | func (*SearchScoresResponse) ProtoMessage() {}
method ProtoReflect (line 1051) | func (x *SearchScoresResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 1064) | func (*SearchScoresResponse) Descriptor() ([]byte, []int) {
method GetDocuments (line 1068) | func (x *SearchScoresResponse) GetDocuments() []*Score {
type DeleteScoresRequest (line 1075) | type DeleteScoresRequest struct
method Reset (line 1083) | func (x *DeleteScoresRequest) Reset() {
method String (line 1090) | func (x *DeleteScoresRequest) String() string {
method ProtoMessage (line 1094) | func (*DeleteScoresRequest) ProtoMessage() {}
method ProtoReflect (line 1096) | func (x *DeleteScoresRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 1109) | func (*DeleteScoresRequest) Descriptor() ([]byte, []int) {
method GetCollection (line 1113) | func (x *DeleteScoresRequest) GetCollection() []string {
method GetCondition (line 1120) | func (x *DeleteScoresRequest) GetCondition() *ScoreCondition {
type DeleteScoresResponse (line 1127) | type DeleteScoresResponse struct
method Reset (line 1133) | func (x *DeleteScoresResponse) Reset() {
method String (line 1140) | func (x *DeleteScoresResponse) String() string {
method ProtoMessage (line 1144) | func (*DeleteScoresResponse) ProtoMessage() {}
method ProtoReflect (line 1146) | func (x *DeleteScoresResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 1159) | func (*DeleteScoresResponse) Descriptor() ([]byte, []int) {
type UpdateScoresRequest (line 1163) | type UpdateScoresRequest struct
method Reset (line 1173) | func (x *UpdateScoresRequest) Reset() {
method String (line 1180) | func (x *UpdateScoresRequest) String() string {
method ProtoMessage (line 1184) | func (*UpdateScoresRequest) ProtoMessage() {}
method ProtoReflect (line 1186) | func (x *UpdateScoresRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 1199) | func (*UpdateScoresRequest) Descriptor() ([]byte, []int) {
method GetCollection (line 1203) | func (x *UpdateScoresRequest) GetCollection() []string {
method GetSubset (line 1210) | func (x *UpdateScoresRequest) GetSubset() string {
method GetId (line 1217) | func (x *UpdateScoresRequest) GetId() string {
method GetPatch (line 1224) | func (x *UpdateScoresRequest) GetPatch() *ScorePatch {
type UpdateScoresResponse (line 1231) | type UpdateScoresResponse struct
method Reset (line 1237) | func (x *UpdateScoresResponse) Reset() {
method String (line 1244) | func (x *UpdateScoresResponse) String() string {
method ProtoMessage (line 1248) | func (*UpdateScoresResponse) ProtoMessage() {}
method ProtoReflect (line 1250) | func (x *UpdateScoresResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 1263) | func (*UpdateScoresResponse) Descriptor() ([]byte, []int) {
type ScanScoresRequest (line 1267) | type ScanScoresRequest struct
method Reset (line 1273) | func (x *ScanScoresRequest) Reset() {
method String (line 1280) | func (x *ScanScoresRequest) String() string {
method ProtoMessage (line 1284) | func (*ScanScoresRequest) ProtoMessage() {}
method ProtoReflect (line 1286) | func (x *ScanScoresRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 1299) | func (*ScanScoresRequest) Descriptor() ([]byte, []int) {
type ScanScoresResponse (line 1303) | type ScanScoresResponse struct
method Reset (line 1313) | func (x *ScanScoresResponse) Reset() {
method String (line 1320) | func (x *ScanScoresResponse) String() string {
method ProtoMessage (line 1324) | func (*ScanScoresResponse) ProtoMessage() {}
method ProtoReflect (line 1326) | func (x *ScanScoresResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 1339) | func (*ScanScoresResponse) Descriptor() ([]byte, []int) {
method GetCollection (line 1343) | func (x *ScanScoresResponse) GetCollection() string {
method GetId (line 1350) | func (x *ScanScoresResponse) GetId() string {
method GetSubset (line 1357) | func (x *ScanScoresResponse) GetSubset() string {
method GetTimestamp (line 1364) | func (x *ScanScoresResponse) GetTimestamp() *timestamppb.Timestamp {
type AddTimeSeriesPointsRequest (line 1371) | type AddTimeSeriesPointsRequest struct
method Reset (line 1378) | func (x *AddTimeSeriesPointsRequest) Reset() {
method String (line 1385) | func (x *AddTimeSeriesPointsRequest) String() string {
method ProtoMessage (line 1389) | func (*AddTimeSeriesPointsRequest) ProtoMessage() {}
method ProtoReflect (line 1391) | func (x *AddTimeSeriesPointsRequest) ProtoReflect() protoreflect.Messa...
method Descriptor (line 1404) | func (*AddTimeSeriesPointsRequest) Descriptor() ([]byte, []int) {
method GetPoints (line 1408) | func (x *AddTimeSeriesPointsRequest) GetPoints() []*TimeSeriesPoint {
type AddTimeSeriesPointsResponse (line 1415) | type AddTimeSeriesPointsResponse struct
method Reset (line 1421) | func (x *AddTimeSeriesPointsResponse) Reset() {
method String (line 1428) | func (x *AddTimeSeriesPointsResponse) String() string {
method ProtoMessage (line 1432) | func (*AddTimeSeriesPointsResponse) ProtoMessage() {}
method ProtoReflect (line 1434) | func (x *AddTimeSeriesPointsResponse) ProtoReflect() protoreflect.Mess...
method Descriptor (line 1447) | func (*AddTimeSeriesPointsResponse) Descriptor() ([]byte, []int) {
type GetTimeSeriesPointsRequest (line 1451) | type GetTimeSeriesPointsRequest struct
method Reset (line 1461) | func (x *GetTimeSeriesPointsRequest) Reset() {
method String (line 1468) | func (x *GetTimeSeriesPointsRequest) String() string {
method ProtoMessage (line 1472) | func (*GetTimeSeriesPointsRequest) ProtoMessage() {}
method ProtoReflect (line 1474) | func (x *GetTimeSeriesPointsRequest) ProtoReflect() protoreflect.Messa...
method Descriptor (line 1487) | func (*GetTimeSeriesPointsRequest) Descriptor() ([]byte, []int) {
method GetName (line 1491) | func (x *GetTimeSeriesPointsRequest) GetName() string {
method GetBegin (line 1498) | func (x *GetTimeSeriesPointsRequest) GetBegin() *timestamppb.Timestamp {
method GetEnd (line 1505) | func (x *GetTimeSeriesPointsRequest) GetEnd() *timestamppb.Timestamp {
method GetDuration (line 1512) | func (x *GetTimeSeriesPointsRequest) GetDuration() int64 {
type GetTimeSeriesPointsResponse (line 1519) | type GetTimeSeriesPointsResponse struct
method Reset (line 1526) | func (x *GetTimeSeriesPointsResponse) Reset() {
method String (line 1533) | func (x *GetTimeSeriesPointsResponse) String() string {
method ProtoMessage (line 1537) | func (*GetTimeSeriesPointsResponse) ProtoMessage() {}
method ProtoReflect (line 1539) | func (x *GetTimeSeriesPointsResponse) ProtoReflect() protoreflect.Mess...
method Descriptor (line 1552) | func (*GetTimeSeriesPointsResponse) Descriptor() ([]byte, []int) {
method GetPoints (line 1556) | func (x *GetTimeSeriesPointsResponse) GetPoints() []*TimeSeriesPoint {
constant file_cache_store_proto_rawDesc (line 1565) | file_cache_store_proto_rawDesc = "" +
function file_cache_store_proto_rawDescGZIP (line 1700) | func file_cache_store_proto_rawDescGZIP() []byte {
function init (line 1793) | func init() { file_cache_store_proto_init() }
function file_cache_store_proto_init (line 1794) | func file_cache_store_proto_init() {
FILE: protocol/cache_store_grpc.pb.go
constant _ (line 33) | _ = grpc.SupportPackageIsVersion9
constant CacheStore_Ping_FullMethodName (line 36) | CacheStore_Ping_FullMethodName = "/protocol.CacheStore/Ping"
constant CacheStore_Get_FullMethodName (line 37) | CacheStore_Get_FullMethodName = "/protocol.CacheStore/Get"
constant CacheStore_Set_FullMethodName (line 38) | CacheStore_Set_FullMethodName = "/protocol.CacheStore/Set"
constant CacheStore_Delete_FullMethodName (line 39) | CacheStore_Delete_FullMethodName = "/protocol.CacheStore/De...
constant CacheStore_Push_FullMethodName (line 40) | CacheStore_Push_FullMethodName = "/protocol.CacheStore/Push"
constant CacheStore_Pop_FullMethodName (line 41) | CacheStore_Pop_FullMethodName = "/protocol.CacheStore/Pop"
constant CacheStore_Remain_FullMethodName (line 42) | CacheStore_Remain_FullMethodName = "/protocol.CacheStore/Re...
constant CacheStore_AddScores_FullMethodName (line 43) | CacheStore_AddScores_FullMethodName = "/protocol.CacheStore/Ad...
constant CacheStore_SearchScores_FullMethodName (line 44) | CacheStore_SearchScores_FullMethodName = "/protocol.CacheStore/Se...
constant CacheStore_DeleteScores_FullMethodName (line 45) | CacheStore_DeleteScores_FullMethodName = "/protocol.CacheStore/De...
constant CacheStore_UpdateScores_FullMethodName (line 46) | CacheStore_UpdateScores_FullMethodName = "/protocol.CacheStore/Up...
constant CacheStore_ScanScores_FullMethodName (line 47) | CacheStore_ScanScores_FullMethodName = "/protocol.CacheStore/Sc...
constant CacheStore_AddTimeSeriesPoints_FullMethodName (line 48) | CacheStore_AddTimeSeriesPoints_FullMethodName = "/protocol.CacheStore/Ad...
constant CacheStore_GetTimeSeriesPoints_FullMethodName (line 49) | CacheStore_GetTimeSeriesPoints_FullMethodName = "/protocol.CacheStore/Ge...
type CacheStoreClient (line 55) | type CacheStoreClient interface
type cacheStoreClient (line 72) | type cacheStoreClient struct
method Ping (line 80) | func (c *cacheStoreClient) Ping(ctx context.Context, in *PingRequest, ...
method Get (line 90) | func (c *cacheStoreClient) Get(ctx context.Context, in *GetRequest, op...
method Set (line 100) | func (c *cacheStoreClient) Set(ctx context.Context, in *SetRequest, op...
method Delete (line 110) | func (c *cacheStoreClient) Delete(ctx context.Context, in *DeleteReque...
method Push (line 120) | func (c *cacheStoreClient) Push(ctx context.Context, in *PushRequest, ...
method Pop (line 130) | func (c *cacheStoreClient) Pop(ctx context.Context, in *PopRequest, op...
method Remain (line 140) | func (c *cacheStoreClient) Remain(ctx context.Context, in *RemainReque...
method AddScores (line 150) | func (c *cacheStoreClient) AddScores(ctx context.Context, in *AddScore...
method SearchScores (line 160) | func (c *cacheStoreClient) SearchScores(ctx context.Context, in *Searc...
method DeleteScores (line 170) | func (c *cacheStoreClient) DeleteScores(ctx context.Context, in *Delet...
method UpdateScores (line 180) | func (c *cacheStoreClient) UpdateScores(ctx context.Context, in *Updat...
method ScanScores (line 190) | func (c *cacheStoreClient) ScanScores(ctx context.Context, in *ScanSco...
method AddTimeSeriesPoints (line 209) | func (c *cacheStoreClient) AddTimeSeriesPoints(ctx context.Context, in...
method GetTimeSeriesPoints (line 219) | func (c *cacheStoreClient) GetTimeSeriesPoints(ctx context.Context, in...
function NewCacheStoreClient (line 76) | func NewCacheStoreClient(cc grpc.ClientConnInterface) CacheStoreClient {
type CacheStoreServer (line 232) | type CacheStoreServer interface
type UnimplementedCacheStoreServer (line 255) | type UnimplementedCacheStoreServer struct
method Ping (line 257) | func (UnimplementedCacheStoreServer) Ping(context.Context, *PingReques...
method Get (line 260) | func (UnimplementedCacheStoreServer) Get(context.Context, *GetRequest)...
method Set (line 263) | func (UnimplementedCacheStoreServer) Set(context.Context, *SetRequest)...
method Delete (line 266) | func (UnimplementedCacheStoreServer) Delete(context.Context, *DeleteRe...
method Push (line 269) | func (UnimplementedCacheStoreServer) Push(context.Context, *PushReques...
method Pop (line 272) | func (UnimplementedCacheStoreServer) Pop(context.Context, *PopRequest)...
method Remain (line 275) | func (UnimplementedCacheStoreServer) Remain(context.Context, *RemainRe...
method AddScores (line 278) | func (UnimplementedCacheStoreServer) AddScores(context.Context, *AddSc...
method SearchScores (line 281) | func (UnimplementedCacheStoreServer) SearchScores(context.Context, *Se...
method DeleteScores (line 284) | func (UnimplementedCacheStoreServer) DeleteScores(context.Context, *De...
method UpdateScores (line 287) | func (UnimplementedCacheStoreServer) UpdateScores(context.Context, *Up...
method ScanScores (line 290) | func (UnimplementedCacheStoreServer) ScanScores(*ScanScoresRequest, gr...
method AddTimeSeriesPoints (line 293) | func (UnimplementedCacheStoreServer) AddTimeSeriesPoints(context.Conte...
method GetTimeSeriesPoints (line 296) | func (UnimplementedCacheStoreServer) GetTimeSeriesPoints(context.Conte...
method mustEmbedUnimplementedCacheStoreServer (line 299) | func (UnimplementedCacheStoreServer) mustEmbedUnimplementedCacheStoreS...
method testEmbeddedByValue (line 300) | func (UnimplementedCacheStoreServer) testEmbeddedByValue() ...
type UnsafeCacheStoreServer (line 305) | type UnsafeCacheStoreServer interface
function RegisterCacheStoreServer (line 309) | func RegisterCacheStoreServer(s grpc.ServiceRegistrar, srv CacheStoreSer...
function _CacheStore_Ping_Handler (line 320) | func _CacheStore_Ping_Handler(srv interface{}, ctx context.Context, dec ...
function _CacheStore_Get_Handler (line 338) | func _CacheStore_Get_Handler(srv interface{}, ctx context.Context, dec f...
function _CacheStore_Set_Handler (line 356) | func _CacheStore_Set_Handler(srv interface{}, ctx context.Context, dec f...
function _CacheStore_Delete_Handler (line 374) | func _CacheStore_Delete_Handler(srv interface{}, ctx context.Context, de...
function _CacheStore_Push_Handler (line 392) | func _CacheStore_Push_Handler(srv interface{}, ctx context.Context, dec ...
function _CacheStore_Pop_Handler (line 410) | func _CacheStore_Pop_Handler(srv interface{}, ctx context.Context, dec f...
function _CacheStore_Remain_Handler (line 428) | func _CacheStore_Remain_Handler(srv interface{}, ctx context.Context, de...
function _CacheStore_AddScores_Handler (line 446) | func _CacheStore_AddScores_Handler(srv interface{}, ctx context.Context,...
function _CacheStore_SearchScores_Handler (line 464) | func _CacheStore_SearchScores_Handler(srv interface{}, ctx context.Conte...
function _CacheStore_DeleteScores_Handler (line 482) | func _CacheStore_DeleteScores_Handler(srv interface{}, ctx context.Conte...
function _CacheStore_UpdateScores_Handler (line 500) | func _CacheStore_UpdateScores_Handler(srv interface{}, ctx context.Conte...
function _CacheStore_ScanScores_Handler (line 518) | func _CacheStore_ScanScores_Handler(srv interface{}, stream grpc.ServerS...
function _CacheStore_AddTimeSeriesPoints_Handler (line 529) | func _CacheStore_AddTimeSeriesPoints_Handler(srv interface{}, ctx contex...
function _CacheStore_GetTimeSeriesPoints_Handler (line 547) | func _CacheStore_GetTimeSeriesPoints_Handler(srv interface{}, ctx contex...
FILE: protocol/data_store.pb.go
constant _ (line 34) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 36) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type ExpressionType (line 39) | type ExpressionType
method Enum (line 67) | func (x ExpressionType) Enum() *ExpressionType {
method String (line 73) | func (x ExpressionType) String() string {
method Descriptor (line 77) | func (ExpressionType) Descriptor() protoreflect.EnumDescriptor {
method Type (line 81) | func (ExpressionType) Type() protoreflect.EnumType {
method Number (line 85) | func (x ExpressionType) Number() protoreflect.EnumNumber {
method EnumDescriptor (line 90) | func (ExpressionType) EnumDescriptor() ([]byte, []int) {
constant ExpressionType_None (line 42) | ExpressionType_None ExpressionType = 0
constant ExpressionType_Less (line 43) | ExpressionType_Less ExpressionType = 1
constant ExpressionType_LessOrEqual (line 44) | ExpressionType_LessOrEqual ExpressionType = 2
constant ExpressionType_Greater (line 45) | ExpressionType_Greater ExpressionType = 3
constant ExpressionType_GreaterOrEqual (line 46) | ExpressionType_GreaterOrEqual ExpressionType = 4
type FeedbackTypeExpression (line 94) | type FeedbackTypeExpression struct
method Reset (line 103) | func (x *FeedbackTypeExpression) Reset() {
method String (line 110) | func (x *FeedbackTypeExpression) String() string {
method ProtoMessage (line 114) | func (*FeedbackTypeExpression) ProtoMessage() {}
method ProtoReflect (line 116) | func (x *FeedbackTypeExpression) ProtoReflect() protoreflect.Message {
method Descriptor (line 129) | func (*FeedbackTypeExpression) Descriptor() ([]byte, []int) {
method GetFeedbackType (line 133) | func (x *FeedbackTypeExpression) GetFeedbackType() string {
method GetExpressionType (line 140) | func (x *FeedbackTypeExpression) GetExpressionType() ExpressionType {
method GetValue (line 147) | func (x *FeedbackTypeExpression) GetValue() float64 {
type UserPatch (line 154) | type UserPatch struct
method Reset (line 163) | func (x *UserPatch) Reset() {
method String (line 170) | func (x *UserPatch) String() string {
method ProtoMessage (line 174) | func (*UserPatch) ProtoMessage() {}
method ProtoReflect (line 176) | func (x *UserPatch) ProtoReflect() protoreflect.Message {
method Descriptor (line 189) | func (*UserPatch) Descriptor() ([]byte, []int) {
method GetLabels (line 193) | func (x *UserPatch) GetLabels() []byte {
method GetComment (line 200) | func (x *UserPatch) GetComment() string {
method GetSubscribe (line 207) | func (x *UserPatch) GetSubscribe() []string {
type ItemPatch (line 214) | type ItemPatch struct
method Reset (line 225) | func (x *ItemPatch) Reset() {
method String (line 232) | func (x *ItemPatch) String() string {
method ProtoMessage (line 236) | func (*ItemPatch) ProtoMessage() {}
method ProtoReflect (line 238) | func (x *ItemPatch) ProtoReflect() protoreflect.Message {
method Descriptor (line 251) | func (*ItemPatch) Descriptor() ([]byte, []int) {
method GetIsHidden (line 255) | func (x *ItemPatch) GetIsHidden() bool {
method GetCategories (line 262) | func (x *ItemPatch) GetCategories() []string {
method GetTimestamp (line 269) | func (x *ItemPatch) GetTimestamp() *timestamppb.Timestamp {
method GetLabels (line 276) | func (x *ItemPatch) GetLabels() []byte {
method GetComment (line 283) | func (x *ItemPatch) GetComment() string {
type ScanOptions (line 290) | type ScanOptions struct
method Reset (line 304) | func (x *ScanOptions) Reset() {
method String (line 311) | func (x *ScanOptions) String() string {
method ProtoMessage (line 315) | func (*ScanOptions) ProtoMessage() {}
method ProtoReflect (line 317) | func (x *ScanOptions) ProtoReflect() protoreflect.Message {
method Descriptor (line 330) | func (*ScanOptions) Descriptor() ([]byte, []int) {
method GetBeginUserId (line 334) | func (x *ScanOptions) GetBeginUserId() string {
method GetEndUserId (line 341) | func (x *ScanOptions) GetEndUserId() string {
method GetBeginItemId (line 348) | func (x *ScanOptions) GetBeginItemId() string {
method GetEndItemId (line 355) | func (x *ScanOptions) GetEndItemId() string {
method GetBeginTime (line 362) | func (x *ScanOptions) GetBeginTime() *timestamppb.Timestamp {
method GetEndTime (line 369) | func (x *ScanOptions) GetEndTime() *timestamppb.Timestamp {
method GetFeedbackTypes (line 376) | func (x *ScanOptions) GetFeedbackTypes() []*FeedbackTypeExpression {
method GetOrderByItemId (line 383) | func (x *ScanOptions) GetOrderByItemId() bool {
type BatchInsertItemsRequest (line 390) | type BatchInsertItemsRequest struct
method Reset (line 397) | func (x *BatchInsertItemsRequest) Reset() {
method String (line 404) | func (x *BatchInsertItemsRequest) String() string {
method ProtoMessage (line 408) | func (*BatchInsertItemsRequest) ProtoMessage() {}
method ProtoReflect (line 410) | func (x *BatchInsertItemsRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 423) | func (*BatchInsertItemsRequest) Descriptor() ([]byte, []int) {
method GetItems (line 427) | func (x *BatchInsertItemsRequest) GetItems() []*Item {
type BatchInsertItemsResponse (line 434) | type BatchInsertItemsResponse struct
method Reset (line 440) | func (x *BatchInsertItemsResponse) Reset() {
method String (line 447) | func (x *BatchInsertItemsResponse) String() string {
method ProtoMessage (line 451) | func (*BatchInsertItemsResponse) ProtoMessage() {}
method ProtoReflect (line 453) | func (x *BatchInsertItemsResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 466) | func (*BatchInsertItemsResponse) Descriptor() ([]byte, []int) {
type BatchGetItemsRequest (line 470) | type BatchGetItemsRequest struct
method Reset (line 477) | func (x *BatchGetItemsRequest) Reset() {
method String (line 484) | func (x *BatchGetItemsRequest) String() string {
method ProtoMessage (line 488) | func (*BatchGetItemsRequest) ProtoMessage() {}
method ProtoReflect (line 490) | func (x *BatchGetItemsRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 503) | func (*BatchGetItemsRequest) Descriptor() ([]byte, []int) {
method GetItemIds (line 507) | func (x *BatchGetItemsRequest) GetItemIds() []string {
type BatchGetItemsResponse (line 514) | type BatchGetItemsResponse struct
method Reset (line 521) | func (x *BatchGetItemsResponse) Reset() {
method String (line 528) | func (x *BatchGetItemsResponse) String() string {
method ProtoMessage (line 532) | func (*BatchGetItemsResponse) ProtoMessage() {}
method ProtoReflect (line 534) | func (x *BatchGetItemsResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 547) | func (*BatchGetItemsResponse) Descriptor() ([]byte, []int) {
method GetItems (line 551) | func (x *BatchGetItemsResponse) GetItems() []*Item {
type DeleteItemRequest (line 558) | type DeleteItemRequest struct
method Reset (line 565) | func (x *DeleteItemRequest) Reset() {
method String (line 572) | func (x *DeleteItemRequest) String() string {
method ProtoMessage (line 576) | func (*DeleteItemRequest) ProtoMessage() {}
method ProtoReflect (line 578) | func (x *DeleteItemRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 591) | func (*DeleteItemRequest) Descriptor() ([]byte, []int) {
method GetItemId (line 595) | func (x *DeleteItemRequest) GetItemId() string {
type DeleteItemResponse (line 602) | type DeleteItemResponse struct
method Reset (line 608) | func (x *DeleteItemResponse) Reset() {
method String (line 615) | func (x *DeleteItemResponse) String() string {
method ProtoMessage (line 619) | func (*DeleteItemResponse) ProtoMessage() {}
method ProtoReflect (line 621) | func (x *DeleteItemResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 634) | func (*DeleteItemResponse) Descriptor() ([]byte, []int) {
type GetItemRequest (line 638) | type GetItemRequest struct
method Reset (line 645) | func (x *GetItemRequest) Reset() {
method String (line 652) | func (x *GetItemRequest) String() string {
method ProtoMessage (line 656) | func (*GetItemRequest) ProtoMessage() {}
method ProtoReflect (line 658) | func (x *GetItemRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 671) | func (*GetItemRequest) Descriptor() ([]byte, []int) {
method GetItemId (line 675) | func (x *GetItemRequest) GetItemId() string {
type GetItemResponse (line 682) | type GetItemResponse struct
method Reset (line 689) | func (x *GetItemResponse) Reset() {
method String (line 696) | func (x *GetItemResponse) String() string {
method ProtoMessage (line 700) | func (*GetItemResponse) ProtoMessage() {}
method ProtoReflect (line 702) | func (x *GetItemResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 715) | func (*GetItemResponse) Descriptor() ([]byte, []int) {
method GetItem (line 719) | func (x *GetItemResponse) GetItem() *Item {
type ModifyItemRequest (line 726) | type ModifyItemRequest struct
method Reset (line 734) | func (x *ModifyItemRequest) Reset() {
method String (line 741) | func (x *ModifyItemRequest) String() string {
method ProtoMessage (line 745) | func (*ModifyItemRequest) ProtoMessage() {}
method ProtoReflect (line 747) | func (x *ModifyItemRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 760) | func (*ModifyItemRequest) Descriptor() ([]byte, []int) {
method GetItemId (line 764) | func (x *ModifyItemRequest) GetItemId() string {
method GetPatch (line 771) | func (x *ModifyItemRequest) GetPatch() *ItemPatch {
type ModifyItemResponse (line 778) | type ModifyItemResponse struct
method Reset (line 784) | func (x *ModifyItemResponse) Reset() {
method String (line 791) | func (x *ModifyItemResponse) String() string {
method ProtoMessage (line 795) | func (*ModifyItemResponse) ProtoMessage() {}
method ProtoReflect (line 797) | func (x *ModifyItemResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 810) | func (*ModifyItemResponse) Descriptor() ([]byte, []int) {
type GetItemsRequest (line 814) | type GetItemsRequest struct
method Reset (line 823) | func (x *GetItemsRequest) Reset() {
method String (line 830) | func (x *GetItemsRequest) String() string {
method ProtoMessage (line 834) | func (*GetItemsRequest) ProtoMessage() {}
method ProtoReflect (line 836) | func (x *GetItemsRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 849) | func (*GetItemsRequest) Descriptor() ([]byte, []int) {
method GetCursor (line 853) | func (x *GetItemsRequest) GetCursor() string {
method GetN (line 860) | func (x *GetItemsRequest) GetN() int32 {
method GetBeginTime (line 867) | func (x *GetItemsRequest) GetBeginTime() *timestamppb.Timestamp {
type GetItemsResponse (line 874) | type GetItemsResponse struct
method Reset (line 882) | func (x *GetItemsResponse) Reset() {
method String (line 889) | func (x *GetItemsResponse) String() string {
method ProtoMessage (line 893) | func (*GetItemsResponse) ProtoMessage() {}
method ProtoReflect (line 895) | func (x *GetItemsResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 908) | func (*GetItemsResponse) Descriptor() ([]byte, []int) {
method GetCursor (line 912) | func (x *GetItemsResponse) GetCursor() string {
method GetItems (line 919) | func (x *GetItemsResponse) GetItems() []*Item {
type GetItemFeedbackRequest (line 926) | type GetItemFeedbackRequest struct
method Reset (line 934) | func (x *GetItemFeedbackRequest) Reset() {
method String (line 941) | func (x *GetItemFeedbackRequest) String() string {
method ProtoMessage (line 945) | func (*GetItemFeedbackRequest) ProtoMessage() {}
method ProtoReflect (line 947) | func (x *GetItemFeedbackRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 960) | func (*GetItemFeedbackRequest) Descriptor() ([]byte, []int) {
method GetItemId (line 964) | func (x *GetItemFeedbackRequest) GetItemId() string {
method GetFeedbackTypes (line 971) | func (x *GetItemFeedbackRequest) GetFeedbackTypes() []*FeedbackTypeExp...
type BatchInsertUsersRequest (line 978) | type BatchInsertUsersRequest struct
method Reset (line 985) | func (x *BatchInsertUsersRequest) Reset() {
method String (line 992) | func (x *BatchInsertUsersRequest) String() string {
method ProtoMessage (line 996) | func (*BatchInsertUsersRequest) ProtoMessage() {}
method ProtoReflect (line 998) | func (x *BatchInsertUsersRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 1011) | func (*BatchInsertUsersRequest) Descriptor() ([]byte, []int) {
method GetUsers (line 1015) | func (x *BatchInsertUsersRequest) GetUsers() []*User {
type BatchInsertUsersResponse (line 1022) | type BatchInsertUsersResponse struct
method Reset (line 1028) | func (x *BatchInsertUsersResponse) Reset() {
method String (line 1035) | func (x *BatchInsertUsersResponse) String() string {
method ProtoMessage (line 1039) | func (*BatchInsertUsersResponse) ProtoMessage() {}
method ProtoReflect (line 1041) | func (x *BatchInsertUsersResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 1054) | func (*BatchInsertUsersResponse) Descriptor() ([]byte, []int) {
type DeleteUserRequest (line 1058) | type DeleteUserRequest struct
method Reset (line 1065) | func (x *DeleteUserRequest) Reset() {
method String (line 1072) | func (x *DeleteUserRequest) String() string {
method ProtoMessage (line 1076) | func (*DeleteUserRequest) ProtoMessage() {}
method ProtoReflect (line 1078) | func (x *DeleteUserRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 1091) | func (*DeleteUserRequest) Descriptor() ([]byte, []int) {
method GetUserId (line 1095) | func (x *DeleteUserRequest) GetUserId() string {
type DeleteUserResponse (line 1102) | type DeleteUserResponse struct
method Reset (line 1108) | func (x *DeleteUserResponse) Reset() {
method String (line 1115) | func (x *DeleteUserResponse) String() string {
method ProtoMessage (line 1119) | func (*DeleteUserResponse) ProtoMessage() {}
method ProtoReflect (line 1121) | func (x *DeleteUserResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 1134) | func (*DeleteUserResponse) Descriptor() ([]byte, []int) {
type GetUserRequest (line 1138) | type GetUserRequest struct
method Reset (line 1145) | func (x *GetUserRequest) Reset() {
method String (line 1152) | func (x *GetUserRequest) String() string {
method ProtoMessage (line 1156) | func (*GetUserRequest) ProtoMessage() {}
method ProtoReflect (line 1158) | func (x *GetUserRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 1171) | func (*GetUserRequest) Descriptor() ([]byte, []int) {
method GetUserId (line 1175) | func (x *GetUserRequest) GetUserId() string {
type GetUserResponse (line 1182) | type GetUserResponse struct
method Reset (line 1189) | func (x *GetUserResponse) Reset() {
method String (line 1196) | func (x *GetUserResponse) String() string {
method ProtoMessage (line 1200) | func (*GetUserResponse) ProtoMessage() {}
method ProtoReflect (line 1202) | func (x *GetUserResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 1215) | func (*GetUserResponse) Descriptor() ([]byte, []int) {
method GetUser (line 1219) | func (x *GetUserResponse) GetUser() *User {
type ModifyUserRequest (line 1226) | type ModifyUserRequest struct
method Reset (line 1234) | func (x *ModifyUserRequest) Reset() {
method String (line 1241) | func (x *ModifyUserRequest) String() string {
method ProtoMessage (line 1245) | func (*ModifyUserRequest) ProtoMessage() {}
method ProtoReflect (line 1247) | func (x *ModifyUserRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 1260) | func (*ModifyUserRequest) Descriptor() ([]byte, []int) {
method GetUserId (line 1264) | func (x *ModifyUserRequest) GetUserId() string {
method GetPatch (line 1271) | func (x *ModifyUserRequest) GetPatch() *UserPatch {
type ModifyUserResponse (line 1278) | type ModifyUserResponse struct
method Reset (line 1284) | func (x *ModifyUserResponse) Reset() {
method String (line 1291) | func (x *ModifyUserResponse) String() string {
method ProtoMessage (line 1295) | func (*ModifyUserResponse) ProtoMessage() {}
method ProtoReflect (line 1297) | func (x *ModifyUserResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 1310) | func (*ModifyUserResponse) Descriptor() ([]byte, []int) {
type GetUsersRequest (line 1314) | type GetUsersRequest struct
method Reset (line 1322) | func (x *GetUsersRequest) Reset() {
method String (line 1329) | func (x *GetUsersRequest) String() string {
method ProtoMessage (line 1333) | func (*GetUsersRequest) ProtoMessage() {}
method ProtoReflect (line 1335) | func (x *GetUsersRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 1348) | func (*GetUsersRequest) Descriptor() ([]byte, []int) {
method GetCursor (line 1352) | func (x *GetUsersRequest) GetCursor() string {
method GetN (line 1359) | func (x *GetUsersRequest) GetN() int32 {
type GetUsersResponse (line 1366) | type GetUsersResponse struct
method Reset (line 1374) | func (x *GetUsersResponse) Reset() {
method String (line 1381) | func (x *GetUsersResponse) String() string {
method ProtoMessage (line 1385) | func (*GetUsersResponse) ProtoMessage() {}
method ProtoReflect (line 1387) | func (x *GetUsersResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 1400) | func (*GetUsersResponse) Descriptor() ([]byte, []int) {
method GetCursor (line 1404) | func (x *GetUsersResponse) GetCursor() string {
method GetUsers (line 1411) | func (x *GetUsersResponse) GetUsers() []*User {
type GetUserFeedbackRequest (line 1418) | type GetUserFeedbackRequest struct
method Reset (line 1427) | func (x *GetUserFeedbackRequest) Reset() {
method String (line 1434) | func (x *GetUserFeedbackRequest) String() string {
method ProtoMessage (line 1438) | func (*GetUserFeedbackRequest) ProtoMessage() {}
method ProtoReflect (line 1440) | func (x *GetUserFeedbackRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 1453) | func (*GetUserFeedbackRequest) Descriptor() ([]byte, []int) {
method GetUserId (line 1457) | func (x *GetUserFeedbackRequest) GetUserId() string {
method GetEndTime (line 1464) | func (x *GetUserFeedbackRequest) GetEndTime() *timestamppb.Timestamp {
method GetFeedbackTypes (line 1471) | func (x *GetUserFeedbackRequest) GetFeedbackTypes() []*FeedbackTypeExp...
type GetUserItemFeedbackRequest (line 1478) | type GetUserItemFeedbackRequest struct
method Reset (line 1487) | func (x *GetUserItemFeedbackRequest) Reset() {
method String (line 1494) | func (x *GetUserItemFeedbackReques
Condensed preview — 274 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,767K chars).
[
{
"path": ".devcontainer/Dockerfile",
"chars": 268,
"preview": "FROM mcr.microsoft.com/devcontainers/base:ubuntu-24.04\n\n# use this Dockerfile to install additional tools you might need"
},
{
"path": ".devcontainer/devcontainer.json",
"chars": 1072,
"preview": "// The Dev Container format allows you to configure your environment. At the heart of it\n// is a Docker image or Dockerf"
},
{
"path": ".dockerignore",
"chars": 36,
"preview": ".github\nassets\n\nLICENSE\n\n*.yml\n*.md\n"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 518,
"preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: bug\nassignees: ''\n\n---\n\nPlease answer t"
},
{
"path": ".github/ISSUE_TEMPLATE/custom.md",
"chars": 126,
"preview": "---\nname: Custom issue template\nabout: Describe this issue template's purpose here.\ntitle: ''\nlabels: ''\nassignees: ''\n\n"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 595,
"preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your fea"
},
{
"path": ".github/workflows/assign_issue.yml",
"chars": 397,
"preview": "name: 'assign issues'\n\non:\n issue_comment:\n types: [created, edited]\n\njobs:\n assign_issues:\n name: assign issues"
},
{
"path": ".github/workflows/backport.yml",
"chars": 1075,
"preview": "name: backport merged pull request\n\non:\n pull_request_target:\n types: [closed]\n issue_comment:\n types: [created]"
},
{
"path": ".github/workflows/build_docker.yml",
"chars": 1706,
"preview": "name: build\n\non:\n push:\n branches: \n - master\n\njobs:\n windows_images:\n name: docker images (windows)\n "
},
{
"path": ".github/workflows/build_release.yml",
"chars": 4887,
"preview": "name: release\n\non:\n release:\n types: [published]\n\njobs:\n binaries:\n name: binaries\n runs-on: macos-latest\n "
},
{
"path": ".github/workflows/build_test.yml",
"chars": 11794,
"preview": "name: test\n\non:\n push:\n branches: \n - master\n - 'release-**'\n pull_request:\n branches: \n - "
},
{
"path": ".github/workflows/dockerhub-description.yml",
"chars": 779,
"preview": "name: update\n\non:\n push:\n branches: \n - master\n paths:\n - 'README.md'\n\njobs:\n dockerhub_description"
},
{
"path": ".github/workflows/translate_issues.yml",
"chars": 277,
"preview": "name: 'translate issues'\non: \n issue_comment: \n types: [created]\n issues: \n types: [opened]\n\njobs:\n translate-i"
},
{
"path": ".gitignore",
"chars": 2176,
"preview": "\n# Created by https://www.gitignore.io/api/go,windows,jetbrains\n\n### Go ###\n# Binaries for programs and plugins\n*.exe\n*."
},
{
"path": ".golangci.yml",
"chars": 315,
"preview": "version: \"2\"\nlinters:\n settings:\n govet:\n disable:\n - composites\n staticcheck:\n checks:\n "
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 5214,
"preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participa"
},
{
"path": "CONTRIBUTING.md",
"chars": 3884,
"preview": "# Contribution Guide\n\nWelcome and thank you for considering contributing to Gorse!\n\nReading and following these guidelin"
},
{
"path": "LICENSE",
"chars": 11356,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 5292,
"preview": "# Gorse Open-source Recommender System Engine\n\n<img width=160 src=\"assets/gorse.png\"/>\n\n;\n// you may"
},
{
"path": "client/config.go",
"chars": 674,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "client/config.toml",
"chars": 4521,
"preview": "[master]\n\n# GRPC port of the master node. The default value is 8086.\nport = 8086\n\n# gRPC host of the master node. The de"
},
{
"path": "client/docker-compose.yml.j2",
"chars": 4491,
"preview": "version: \"3\"\nservices:\n\n {% if database == 'mysql' %}\n\n mysql:\n image: mysql/mysql-server\n restart: unless-stopp"
},
{
"path": "client/setup-test.sh",
"chars": 1912,
"preview": "#!/bin/bash\nset -e\n\n# Download config\nif [ ! -f ./config.toml ]; then\n wget https://github.com/gorse-io/gorse/raw/ref"
},
{
"path": "cmd/goat/README.md",
"chars": 56,
"preview": "GOAT has been moved to https://github.com/gorse-io/goat\n"
},
{
"path": "cmd/gorse-cli/main.go",
"chars": 18712,
"preview": "// Copyright 2026 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "cmd/gorse-in-one/Dockerfile",
"chars": 1081,
"preview": "# syntax = docker/dockerfile:1\n\n############################\n# STEP 1 build executable binary\n##########################"
},
{
"path": "cmd/gorse-in-one/Dockerfile.cuda",
"chars": 1253,
"preview": "# syntax = docker/dockerfile:1\n\n############################\n# STEP 1 build executable binary\n##########################"
},
{
"path": "cmd/gorse-in-one/Dockerfile.mkl",
"chars": 1586,
"preview": "# syntax = docker/dockerfile:1\n\n############################\n# STEP 1 build executable binary\n##########################"
},
{
"path": "cmd/gorse-in-one/Dockerfile.openblas",
"chars": 2962,
"preview": "# syntax = docker/dockerfile:1\n\n############################\n# STEP 1 build executable binary\n##########################"
},
{
"path": "cmd/gorse-in-one/Dockerfile.windows",
"chars": 718,
"preview": "############################\n# STEP 1 build executable binary\n############################\nFROM golang:1.26\n\nWORKDIR /sr"
},
{
"path": "cmd/gorse-in-one/main.go",
"chars": 5968,
"preview": "// Copyright 2022 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "cmd/gorse-master/Dockerfile",
"chars": 1060,
"preview": "# syntax = docker/dockerfile:1\n\n############################\n# STEP 1 build executable binary\n##########################"
},
{
"path": "cmd/gorse-master/Dockerfile.cuda",
"chars": 1229,
"preview": "# syntax = docker/dockerfile:1\n\n############################\n# STEP 1 build executable binary\n##########################"
},
{
"path": "cmd/gorse-master/Dockerfile.mkl",
"chars": 1586,
"preview": "# syntax = docker/dockerfile:1\n\n############################\n# STEP 1 build executable binary\n##########################"
},
{
"path": "cmd/gorse-master/Dockerfile.openblas",
"chars": 2962,
"preview": "# syntax = docker/dockerfile:1\n\n############################\n# STEP 1 build executable binary\n##########################"
},
{
"path": "cmd/gorse-master/Dockerfile.windows",
"chars": 718,
"preview": "############################\n# STEP 1 build executable binary\n############################\nFROM golang:1.26\n\nWORKDIR /sr"
},
{
"path": "cmd/gorse-master/main.go",
"chars": 2497,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "cmd/gorse-server/Dockerfile",
"chars": 1028,
"preview": "# syntax = docker/dockerfile:1\n\n############################\n# STEP 1 build executable binary\n##########################"
},
{
"path": "cmd/gorse-server/Dockerfile.cuda",
"chars": 1197,
"preview": "# syntax = docker/dockerfile:1\n\n############################\n# STEP 1 build executable binary\n##########################"
},
{
"path": "cmd/gorse-server/Dockerfile.mkl",
"chars": 1554,
"preview": "# syntax = docker/dockerfile:1\n\n############################\n# STEP 1 build executable binary\n##########################"
},
{
"path": "cmd/gorse-server/Dockerfile.openblas",
"chars": 2930,
"preview": "# syntax = docker/dockerfile:1\n\n############################\n# STEP 1 build executable binary\n##########################"
},
{
"path": "cmd/gorse-server/Dockerfile.windows",
"chars": 718,
"preview": "############################\n# STEP 1 build executable binary\n############################\nFROM golang:1.26\n\nWORKDIR /sr"
},
{
"path": "cmd/gorse-server/main.go",
"chars": 3692,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "cmd/gorse-worker/Dockerfile",
"chars": 1028,
"preview": "# syntax = docker/dockerfile:1\n\n############################\n# STEP 1 build executable binary\n##########################"
},
{
"path": "cmd/gorse-worker/Dockerfile.cuda",
"chars": 1197,
"preview": "# syntax = docker/dockerfile:1\n\n############################\n# STEP 1 build executable binary\n##########################"
},
{
"path": "cmd/gorse-worker/Dockerfile.mkl",
"chars": 1554,
"preview": "# syntax = docker/dockerfile:1\n\n############################\n# STEP 1 build executable binary\n##########################"
},
{
"path": "cmd/gorse-worker/Dockerfile.openblas",
"chars": 2930,
"preview": "# syntax = docker/dockerfile:1\n\n############################\n# STEP 1 build executable binary\n##########################"
},
{
"path": "cmd/gorse-worker/Dockerfile.windows",
"chars": 718,
"preview": "############################\n# STEP 1 build executable binary\n############################\nFROM golang:1.26\n\nWORKDIR /sr"
},
{
"path": "cmd/gorse-worker/main.go",
"chars": 3722,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "cmd/version/version.go",
"chars": 674,
"preview": "package version\n\nimport (\n\t\"fmt\"\n\t\"runtime\"\n)\n\n// Default build-time variable.\n// These values are overridden via ldflag"
},
{
"path": "codecov.yml",
"chars": 111,
"preview": "coverage:\n status:\n patch:\n default:\n enabled: no\n\nignore:\n - \"protocol/*.pb.go\"\n - \"cmd/**\"\n"
},
{
"path": "common/ann/ann.go",
"chars": 835,
"preview": "// Copyright 2024 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/ann/ann_test.go",
"chars": 6687,
"preview": "// Copyright 2024 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/ann/bruteforce.go",
"chars": 2244,
"preview": "// Copyright 2024 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/ann/hnsw.go",
"chars": 12093,
"preview": "// Copyright 2024 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/blas/blas.go",
"chars": 843,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/blas/blas_darwin_arm64.go",
"chars": 1134,
"preview": "//go:build cgo\n\n// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licen"
},
{
"path": "common/blas/blas_mkl.go",
"chars": 1295,
"preview": "//go:build cgo && mkl\n\n// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the"
},
{
"path": "common/blas/blas_openblas.go",
"chars": 1100,
"preview": "//go:build cgo && openblas\n\n// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0"
},
{
"path": "common/copier/copier.go",
"chars": 4801,
"preview": "// Copyright 2021 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/copier/copier_test.go",
"chars": 4329,
"preview": "// Copyright 2021 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/datautil/datautil.go",
"chars": 4846,
"preview": "// Copyright 2024 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/datautil/datautil_test.go",
"chars": 848,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/encoding/encoding.go",
"chars": 2829,
"preview": "// Copyright 2022 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/encoding/encoding_test.go",
"chars": 1356,
"preview": "// Copyright 2022 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/expression/expression.go",
"chars": 4564,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/expression/expression_test.go",
"chars": 4991,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/floats/floats.go",
"chars": 5224,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/floats/floats_amd64.go",
"chars": 6264,
"preview": "//go:build !noasm\n\n// Copyright 2022 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Li"
},
{
"path": "common/floats/floats_amd64_test.go",
"chars": 6711,
"preview": "//go:build !noasm\n\n// Copyright 2022 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Li"
},
{
"path": "common/floats/floats_arm64.go",
"chars": 3170,
"preview": "//go:build !noasm\n\n// Copyright 2022 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Li"
},
{
"path": "common/floats/floats_arm64_test.go",
"chars": 6559,
"preview": "//go:build !noasm\n\n// Copyright 2022 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Li"
},
{
"path": "common/floats/floats_avx.go",
"chars": 1259,
"preview": "//go:build !noasm && amd64\n// Code generated by GoAT. DO NOT EDIT.\n// versions:\n// \tclang 19.1.7 (++20250114103320+cd7"
},
{
"path": "common/floats/floats_avx.s",
"chars": 113768,
"preview": "//go:build !noasm && amd64\n// Code generated by GoAT. DO NOT EDIT.\n// versions:\n// \tclang 19.1.7 (++20250114103320+cd7"
},
{
"path": "common/floats/floats_avx512.go",
"chars": 1278,
"preview": "//go:build !noasm && amd64\n// Code generated by GoAT. DO NOT EDIT.\n// versions:\n// \tclang 19.1.7 (++20250114103320+cd7"
},
{
"path": "common/floats/floats_avx512.s",
"chars": 135592,
"preview": "//go:build !noasm && amd64\n// Code generated by GoAT. DO NOT EDIT.\n// versions:\n// \tclang 19.1.7 (++20250114103320+cd7"
},
{
"path": "common/floats/floats_neon.go",
"chars": 1130,
"preview": "//go:build !noasm && arm64\n// Code generated by GoAT. DO NOT EDIT.\n// versions:\n// \tclang 18.1.3 (1ubuntu1)\n// \tobjdum"
},
{
"path": "common/floats/floats_neon.s",
"chars": 45461,
"preview": "//go:build !noasm && arm64\n// Code generated by GoAT. DO NOT EDIT.\n// versions:\n// \tclang 18.1.3 (1ubuntu1)\n// \tobjdum"
},
{
"path": "common/floats/floats_noasm.go",
"chars": 1826,
"preview": "//go:build noasm || (!amd64 && !arm64 && !riscv64)\n\n// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apa"
},
{
"path": "common/floats/floats_riscv64.go",
"chars": 3819,
"preview": "//go:build !noasm\n\n// Copyright 2022 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Li"
},
{
"path": "common/floats/floats_riscv64_test.go",
"chars": 6294,
"preview": "//go:build !noasm\n\n// Copyright 2022 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Li"
},
{
"path": "common/floats/floats_rvv.go",
"chars": 1146,
"preview": "//go:build !noasm && riscv64\n// Code generated by GoAT. DO NOT EDIT.\n// versions:\n// \tclang 18.1.8 (11bb4)\n// \tobjdump"
},
{
"path": "common/floats/floats_rvv.s",
"chars": 43969,
"preview": "//go:build !noasm && riscv64\n// Code generated by GoAT. DO NOT EDIT.\n// versions:\n// \tclang 18.1.8 (11bb4)\n// \tobjdump"
},
{
"path": "common/floats/floats_test.go",
"chars": 13479,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/floats/mm.go",
"chars": 1470,
"preview": "//go:build !cgo || (!(darwin && arm64) && !mkl && !openblas)\n\n// Copyright 2025 gorse Project Authors\n//\n// Licensed und"
},
{
"path": "common/floats/mm_darwin_arm64.go",
"chars": 953,
"preview": "//go:build cgo\n\n// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licen"
},
{
"path": "common/floats/mm_mkl.go",
"chars": 960,
"preview": "//go:build cgo && mkl\n\n// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the"
},
{
"path": "common/floats/mm_openblas.go",
"chars": 970,
"preview": "//go:build cgo && openblas\n\n// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0"
},
{
"path": "common/floats/src/.gitignore",
"chars": 34,
"preview": "*\n!.gitignore\n!*.c\n!*.h\n!Makefile\n"
},
{
"path": "common/floats/src/Makefile",
"chars": 763,
"preview": "SOURCES = munit.c floats_test.c\n\nifeq ($(shell uname -m),x86_64)\n\tSOURCES += floats_avx.c floats_avx512.c\n\tCFLAGS = -O3 "
},
{
"path": "common/floats/src/floats_avx.c",
"chars": 8942,
"preview": "// Copyright 2022 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/floats/src/floats_avx512.c",
"chars": 13773,
"preview": "// Copyright 2022 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/floats/src/floats_neon.c",
"chars": 5051,
"preview": "// Copyright 2022 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/floats/src/floats_rvv.c",
"chars": 5205,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/floats/src/floats_sve2.c",
"chars": 1751,
"preview": "// Copyright 2022 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/floats/src/floats_test.c",
"chars": 26585,
"preview": "#include \"munit.h\"\n#include \"math.h\"\n\nconst size_t kVectorLength = 63;\nconst size_t kIteration = 1;\n\n/* no simd */\n\nvoid"
},
{
"path": "common/floats/src/munit.c",
"chars": 67814,
"preview": "/* Copyright (c) 2013-2018 Evan Nemerson <evan@nemerson.com>\n *\n * Permission is hereby granted, free of charge, to any "
},
{
"path": "common/floats/src/munit.h",
"chars": 19064,
"preview": "/* µnit Testing Framework\n * Copyright (c) 2013-2017 Evan Nemerson <evan@nemerson.com>\n *\n * Permission is hereby grante"
},
{
"path": "common/heap/filter.go",
"chars": 1793,
"preview": "// Copyright 2022 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/heap/filter_test.go",
"chars": 1911,
"preview": "// Copyright 2022 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/heap/pq.go",
"chars": 3765,
"preview": "// Copyright 2022 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/heap/pq_test.go",
"chars": 2238,
"preview": "// Copyright 2022 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/jsonutil/json.go",
"chars": 1229,
"preview": "// Copyright 2022 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/jsonutil/json_test.go",
"chars": 1131,
"preview": "// Copyright 2022 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/log/log.go",
"chars": 5272,
"preview": "// Copyright 2022 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/log/log_test.go",
"chars": 2636,
"preview": "// Copyright 2022 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/mock/openai.go",
"chars": 3784,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/mock/openai_test.go",
"chars": 3062,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/monitor/progress.go",
"chars": 5101,
"preview": "// Copyright 2023 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/monitor/progress_test.go",
"chars": 1639,
"preview": "// Copyright 2023 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/nn/functions.go",
"chars": 7210,
"preview": "// Copyright 2024 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/nn/layers.go",
"chars": 6047,
"preview": "// Copyright 2024 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/nn/nn_test.go",
"chars": 8381,
"preview": "// Copyright 2024 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/nn/op.go",
"chars": 16582,
"preview": "// Copyright 2024 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/nn/op_test.go",
"chars": 21665,
"preview": "// Copyright 2024 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/nn/optimizers.go",
"chars": 4438,
"preview": "// Copyright 2024 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/nn/tensor.go",
"chars": 18354,
"preview": "// Copyright 2024 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/nn/tensor_test.go",
"chars": 8884,
"preview": "// Copyright 2024 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/parallel/parallel.go",
"chars": 5266,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/parallel/parallel_test.go",
"chars": 5552,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/parallel/ratelimit.go",
"chars": 1285,
"preview": "package parallel\n\nimport (\n\t\"time\"\n\n\t\"github.com/juju/ratelimit\"\n)\n\nvar (\n\tChatCompletionBackoff = t"
},
{
"path": "common/parallel/ratelimit_test.go",
"chars": 1031,
"preview": "package parallel\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestUnlimited(t *testing.T)"
},
{
"path": "common/rc/rc.go",
"chars": 1684,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/rc/rc_test.go",
"chars": 1725,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/reranker/client.go",
"chars": 3950,
"preview": "// Copyright 2026 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/reranker/client_test.go",
"chars": 1671,
"preview": "// Copyright 2026 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/sizeof/size.go",
"chars": 3874,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/sizeof/size_test.go",
"chars": 1677,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/util/random.go",
"chars": 4571,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/util/random_test.go",
"chars": 3041,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/util/strconv.go",
"chars": 1204,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/util/tls.go",
"chars": 2453,
"preview": "// Copyright 2024 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/util/util.go",
"chars": 2308,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "common/util/util_test.go",
"chars": 1678,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "config/config.go",
"chars": 35121,
"preview": "// Copyright 2021 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "config/config.toml",
"chars": 12925,
"preview": "[database]\n\n# The database for caching, support Redis, MySQL, Postgres and MongoDB:\n# redis://<user>:<password>@<host>"
},
{
"path": "config/config_test.go",
"chars": 21568,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "dataset/dataset.go",
"chars": 16442,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "dataset/dataset_test.go",
"chars": 7392,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "dataset/dict.go",
"chars": 1670,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "dataset/dict_test.go",
"chars": 1232,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "dataset/index.go",
"chars": 3248,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "dataset/index_test.go",
"chars": 1057,
"preview": "package dataset\n\nimport (\n\t\"bytes\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestIndex(t *testing.T) {\n\t"
},
{
"path": "dataset/unified_index.go",
"chars": 12528,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "dataset/unified_index_test.go",
"chars": 4768,
"preview": "// Copyright 2021 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "docker-bake.hcl",
"chars": 1748,
"preview": "variable \"VERSIONS\" {\n default = \"nightly\"\n}\n\nvariable versions {\n default = split(\",\", VERSIONS)\n}\n\nvariable componen"
},
{
"path": "docker-compose.yml",
"chars": 3539,
"preview": "version: \"3\"\nservices:\n mysql:\n image: mysql/mysql-server\n restart: unless-stopped\n ports:\n - 3306:3306\n "
},
{
"path": "go.mod",
"chars": 13032,
"preview": "module github.com/gorse-io/gorse\n\ngo 1.26\n\nrequire (\n\tcloud.google.com/go/storage v1.61.3\n\tgithub.com/Azure/azure-sdk-fo"
},
{
"path": "go.sum",
"chars": 139808,
"preview": "cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4=\ncel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ"
},
{
"path": "logics/cf.go",
"chars": 4903,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "logics/cf_test.go",
"chars": 2368,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "logics/chat.go",
"chars": 5042,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "logics/chat_test.go",
"chars": 3099,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "logics/external.go",
"chars": 6244,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "logics/external_test.go",
"chars": 3883,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "logics/item_to_item.go",
"chars": 15463,
"preview": "// Copyright 2024 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "logics/item_to_item_test.go",
"chars": 7021,
"preview": "// Copyright 2024 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "logics/non_personalized.go",
"chars": 4598,
"preview": "// Copyright 2024 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "logics/non_personalized_test.go",
"chars": 6126,
"preview": "// Copyright 2024 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "logics/recommend.go",
"chars": 12137,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "logics/recommend_test.go",
"chars": 8380,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "logics/user_to_user.go",
"chars": 7719,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "logics/user_to_user_test.go",
"chars": 3526,
"preview": "// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "master/master.go",
"chars": 10625,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "master/master_test.go",
"chars": 1548,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "master/metrics.go",
"chars": 9902,
"preview": "// Copyright 2021 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "master/metrics_test.go",
"chars": 2612,
"preview": "// Copyright 2022 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "master/rest.go",
"chars": 66575,
"preview": "// Copyright 2021 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "master/rest_test.go",
"chars": 40771,
"preview": "// Copyright 2021 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "master/rpc.go",
"chars": 2950,
"preview": "// Copyright 2021 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "master/rpc_test.go",
"chars": 7482,
"preview": "// Copyright 2021 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "master/tasks.go",
"chars": 53517,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "master/tasks_test.go",
"chars": 23567,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "model/built_in.go",
"chars": 6024,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "model/built_in_test.go",
"chars": 1368,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "model/cf/evaluator.go",
"chars": 5642,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "model/cf/evaluator_test.go",
"chars": 4938,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "model/cf/model.go",
"chars": 28042,
"preview": "// Copyright 2021 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "model/cf/model_test.go",
"chars": 4173,
"preview": "// Copyright 2021 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "model/cf/optimize.go",
"chars": 2291,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "model/cf/optimize_test.go",
"chars": 3774,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "model/ctr/data.go",
"chars": 10953,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "model/ctr/data_test.go",
"chars": 6893,
"preview": "// Copyright 2021 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "model/ctr/evaluator.go",
"chars": 4439,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "model/ctr/evaluator_test.go",
"chars": 1409,
"preview": "// Copyright 2021 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "model/ctr/fm.go",
"chars": 14535,
"preview": "//go:build !cgo || !xla\n\n// Copyright 2024 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (t"
},
{
"path": "model/ctr/fm_xla.go",
"chars": 18589,
"preview": "//go:build cgo && xla\n\n// Copyright 2025 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the"
},
{
"path": "model/ctr/model.go",
"chars": 3329,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "model/ctr/model.py",
"chars": 7500,
"preview": "import os\nfrom pathlib import Path\nfrom typing import Dict, List, Tuple\n\nimport click\nimport torch\nfrom tqdm import tqdm"
},
{
"path": "model/ctr/model_test.go",
"chars": 6992,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "model/ctr/optimize.go",
"chars": 2340,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "model/ctr/optimize_test.go",
"chars": 3502,
"preview": "// Copyright 2021 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "model/model.go",
"chars": 1717,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "model/params.go",
"chars": 5188,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "model/params_test.go",
"chars": 4074,
"preview": "// Copyright 2020 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "protocol/cache_store.pb.go",
"chars": 55424,
"preview": "// Copyright 2024 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "protocol/cache_store.proto",
"chars": 3957,
"preview": "// Copyright 2024 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
},
{
"path": "protocol/cache_store_grpc.pb.go",
"chars": 25509,
"preview": "// Copyright 2024 gorse Project Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may"
}
]
// ... and 74 more files (download for full content)
About this extraction
This page contains the full source code of the gorse-io/gorse GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 274 files (2.4 MB), approximately 653.2k tokens, and a symbol index with 3974 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.