Compare commits

...

8 Commits

Author SHA1 Message Date
coissac
f92f285417 Merge pull request #101 from metabarcoding/push-klzowrsmmnyv
Dynamic Batch Flushing and Build Improvements
2026-03-16 22:29:29 +01:00
Eric Coissac
a786b58ed3 Dynamic Batch Flushing and Build Improvements
This release introduces dynamic batch flushing in the Distribute component, replacing the previous fixed-size batching with a memory- and count-aware strategy. Batches now flush automatically when either the maximum sequence count (BatchSizeMax()) or memory threshold (BatchMem()) per key is reached, ensuring more efficient resource usage and consistent behavior with the RebatchBySize strategy. The optional sizes parameter has been removed, and related code—including the Lua wrapper and worker buffer handling—has been updated for correctness and simplicity. Unused BatchSize() references have been eliminated from obidistribute.

Additionally, this release includes improvements to static Linux builds and overall build stability, enhancing reliability across deployment environments.
2026-03-16 22:06:51 +01:00
Eric Coissac
a2b26712b2 refactor: replace fixed batch size with dynamic flushing based on count and memory
Replace the old fixed batch-size mechanism in Distribute with a dynamic strategy that flushes batches when either BatchSizeMax() sequences or BatchMem() bytes are reached per key. This aligns with the RebatchBySize strategy and removes the optional sizes parameter. Also update related code: simplify Lua wrapper to accept optional capacity, and fix buffer growth logic in worker.go using slices.Grow correctly. Remove unused BatchSize() usage from obidistribute.
2026-03-16 22:06:44 +01:00
coissac
1599abc9ad Merge pull request #99 from metabarcoding/push-urlyqwkrqypt
4.4.28: Static Linux Builds, Memory-Aware Batching, and Build Stability
2026-03-14 12:21:34 +01:00
Eric Coissac
af213ab446 4.4.28: Static Linux Builds, Memory-Aware Batching, and Build Stability
This release focuses on improving build reliability, memory efficiency for large datasets, and portability of Linux binaries.

### Static Linux Binaries
- Linux binaries are now built with static linking using musl, eliminating external runtime dependencies and ensuring portability across distributions.

### Memory-Aware Batching
- Users can now control memory usage during processing with the new `--batch-mem` option, specifying limits such as 128K, 64M, or 1G.
- Batching logic now respects both size and memory constraints: batches are flushed when either threshold is exceeded.
- Conservative memory estimation for sequences helps avoid over-allocation, and explicit garbage collection after large batch discards reduces memory spikes.

### Build System Improvements
- Upgraded to Go 1.26 for improved performance and toolchain stability.
- Fixed cross-compilation issues by replacing generic include paths with architecture-specific ones (x86_64-linux-gnu and aarch64-linux-gnu).
- Streamlined macOS builds by removing special flags, using standard `make` targets.
- Enhanced error reporting during build failures: logs are now shown before cleanup and exit.
- Updated install script to correctly configure GOROOT, GOPATH, and GOTOOLCHAIN, with visual progress feedback for downloads.

All batching behavior is non-breaking and maintains backward compatibility while offering more predictable resource usage on large datasets.
2026-03-14 11:59:15 +01:00
Eric Coissac
a60184c115 chore: bump version to 4.4.27 and add zlib-static dependency
Update version to 4.4.27 in version.txt and pkg/obioptions/version.go.

Add zlib-static package to release workflow to ensure static linking of zlib, resolving potential runtime dependency issues with the external link mode.
2026-03-14 11:59:04 +01:00
Eric Coissac
585b024bf0 chore: update to Go 1.26 and refactor release workflow
- Upgrade Go version from 1.23 to 1.26 in release.yml
- Remove CGO_CFLAGS from cross-compilation matrix entries
- Replace Linux build tools installation with Docker-based static build using golang:1.26-alpine
- Simplify macOS build to use standard make without special flags
- Increment version to 4.4.26
2026-03-14 11:43:31 +01:00
Eric Coissac
afc9ffda85 chore: bump version to 4.4.25 and fix CGO_CFLAGS for cross-compilation
Update version to 4.4.25 in version.txt and pkg/obioptions/version.go.

Fix CGO_CFLAGS in release.yml by replacing generic '-I/usr/include' with architecture-specific paths (x86_64-linux-gnu and aarch64-linux-gnu) to ensure correct header inclusion during cross-compilation on Linux.
2026-03-13 19:30:29 +01:00
8 changed files with 47 additions and 50 deletions

View File

@@ -16,7 +16,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: "1.23"
go-version: "1.26"
- name: Checkout obitools4 project
uses: actions/checkout@v4
- name: Run tests
@@ -54,7 +54,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: "1.23"
go-version: "1.26"
- name: Extract version from tag
id: get_version
@@ -62,12 +62,6 @@ jobs:
TAG=${GITHUB_REF#refs/tags/Release_}
echo "version=$TAG" >> $GITHUB_OUTPUT
- name: Install build tools (Linux)
if: runner.os == 'Linux'
run: |
sudo apt-get update -q
sudo apt-get install -y musl-tools zlib1g-dev
- name: Install build tools (macOS)
if: runner.os == 'macOS'
run: |
@@ -75,21 +69,30 @@ jobs:
xcode-select --install 2>/dev/null || true
xcode-select -p
- name: Build binaries
- name: Build binaries (Linux)
if: runner.os == 'Linux'
env:
VERSION: ${{ steps.get_version.outputs.version }}
run: |
docker run --rm \
-v "$(pwd):/src" \
-w /src \
-e VERSION="${VERSION}" \
golang:1.26-alpine \
sh -c "apk add --no-cache gcc musl-dev zlib-dev zlib-static make && \
make LDFLAGS='-linkmode=external -extldflags=-static' obitools"
mkdir -p artifacts
tar -czf artifacts/obitools4_${VERSION}_${{ matrix.output_name }}.tar.gz -C build .
- name: Build binaries (macOS)
if: runner.os == 'macOS'
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
VERSION: ${{ steps.get_version.outputs.version }}
CC: ${{ matrix.goos == 'linux' && 'musl-gcc' || '' }}
CGO_CFLAGS: ${{ matrix.goos == 'linux' && '-I/usr/include' || '' }}
run: |
if [ "$GOOS" = "linux" ]; then
make LDFLAGS='-linkmode=external -extldflags=-static' obitools
else
make obitools
fi
mkdir -p artifacts
# Create a single tar.gz with all binaries for this platform
tar -czf artifacts/obitools4_${VERSION}_${{ matrix.output_name }}.tar.gz -C build .
- name: Upload artifacts

BIN
logs_60535302930.zip Normal file

Binary file not shown.

View File

@@ -57,34 +57,21 @@ func (dist *IDistribute) Classifier() *obiseq.BioSequenceClassifier {
}
// Distribute organizes the biosequences from the iterator into batches
// based on the provided classifier and batch sizes. It returns an
// IDistribute instance that manages the distribution of the sequences.
// based on the provided classifier. It returns an IDistribute instance
// that manages the distribution of the sequences.
//
// Parameters:
// - class: A pointer to a BioSequenceClassifier used to classify
// the biosequences during distribution.
// - sizes: Optional integer values specifying the batch size. If
// no sizes are provided, a default batch size of 5000 is used.
//
// Returns:
// An IDistribute instance that contains the outputs of the
// classified biosequences, a channel for new data notifications,
// and the classifier used for distribution. The method operates
// asynchronously, processing the sequences in separate goroutines.
// It ensures that the outputs are closed and cleaned up once
// processing is complete.
func (iterator IBioSequence) Distribute(class *obiseq.BioSequenceClassifier, sizes ...int) IDistribute {
batchsize := obidefault.BatchSize()
// Batches are flushed when either BatchSizeMax() sequences or BatchMem()
// bytes are accumulated per key, mirroring the RebatchBySize strategy.
func (iterator IBioSequence) Distribute(class *obiseq.BioSequenceClassifier) IDistribute {
maxCount := obidefault.BatchSizeMax()
maxBytes := obidefault.BatchMem()
outputs := make(map[int]IBioSequence, 100)
slices := make(map[int]*obiseq.BioSequenceSlice, 100)
bufBytes := make(map[int]int, 100)
orders := make(map[int]int, 100)
news := make(chan int)
if len(sizes) > 0 {
batchsize = sizes[0]
}
jobDone := sync.WaitGroup{}
lock := sync.Mutex{}
@@ -115,6 +102,7 @@ func (iterator IBioSequence) Distribute(class *obiseq.BioSequenceClassifier, siz
slice = &s
slices[key] = slice
orders[key] = 0
bufBytes[key] = 0
lock.Lock()
outputs[key] = MakeIBioSequence()
@@ -123,14 +111,20 @@ func (iterator IBioSequence) Distribute(class *obiseq.BioSequenceClassifier, siz
news <- key
}
*slice = append(*slice, s)
if len(*slice) == batchsize {
sz := s.MemorySize()
countFull := maxCount > 0 && len(*slice) >= maxCount
memFull := maxBytes > 0 && bufBytes[key]+sz > maxBytes && len(*slice) > 0
if countFull || memFull {
outputs[key].Push(MakeBioSequenceBatch(source, orders[key], *slice))
orders[key]++
s := obiseq.MakeBioSequenceSlice()
slices[key] = &s
slice = &s
bufBytes[key] = 0
}
*slice = append(*slice, s)
bufBytes[key] += sz
}
}

View File

@@ -31,7 +31,8 @@ func obiseqslice2Lua(interpreter *lua.LState,
}
func newObiSeqSlice(luaState *lua.LState) int {
seqslice := obiseq.NewBioSequenceSlice()
capacity := luaState.OptInt(1, 0)
seqslice := obiseq.NewBioSequenceSlice(capacity)
luaState.Push(obiseqslice2Lua(luaState, seqslice))
return 1
}

View File

@@ -3,7 +3,7 @@ package obioptions
// Version is automatically updated by the Makefile from version.txt
// The patch number (third digit) is incremented on each push to the repository
var _Version = "Release 4.4.24"
var _Version = "Release 4.4.29"
// Version returns the version of the obitools package.
//

View File

@@ -104,11 +104,11 @@ func SeqToSliceWorker(worker SeqWorker,
for _, s := range input {
r, err := worker(s)
if err == nil {
for _, rs := range r {
if i == len(output) {
output = slices.Grow(output, cap(output))
if i+len(r) > cap(output) {
output = slices.Grow(output[:i], len(r))
output = output[:cap(output)]
}
for _, rs := range r {
output[i] = rs
i++
}

View File

@@ -46,8 +46,7 @@ func CLIDistributeSequence(sequences obiiter.IBioSequence) {
formater = obiformats.WriteSequencesToFile
}
dispatcher := sequences.Distribute(CLISequenceClassifier(),
obidefault.BatchSize())
dispatcher := sequences.Distribute(CLISequenceClassifier())
obiformats.WriterDispatcher(CLIFileNamePattern(),
dispatcher, formater, opts...,

View File

@@ -1 +1 @@
4.4.24
4.4.29