diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 00000000..7c6b218b
--- /dev/null
+++ b/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1,3 @@
+wrapperVersion=3.3.4
+distributionType=only-script
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip
diff --git a/Makefile b/Makefile
index 752659b8..787b40fc 100644
--- a/Makefile
+++ b/Makefile
@@ -1,31 +1,91 @@
# Simple Makefile for Maven build without tests
-.PHONY: build clean package help
+.PHONY: build clean package validate test release release-prepare release-perform deploy help
+
+# Maven wrapper
+MVN = ./mvnw
# Default target
all: package
+# Validate environment setup
+validate:
+ @echo "Running environment validation..."
+ @./scripts/validate-setup.sh
+
# Build the project (clean and package without tests)
build: clean package
# Clean the project
clean:
- mvn clean
+ $(MVN) clean
# Package the project without running tests
package:
- mvn package -DskipTests
+ $(MVN) package -DskipTests
+# Run tests
+test:
+ $(MVN) test
# Combined clean and package
package-with-clean:
- mvn clean package -DskipTests
+ $(MVN) clean package -DskipTests
+
+# Validate then build
+safe-build: validate build
+
+# Deploy to repository
+deploy:
+ $(MVN) clean deploy
+
+# Deploy without running tests
+deploy-skip-tests:
+ $(MVN) clean deploy -DskipTests
+
+# Prepare release (version bump and tag)
+release-prepare:
+ @echo "Preparing release..."
+ $(MVN) release:prepare
+
+# Perform release (build and deploy)
+release-perform:
+ @echo "Performing release..."
+ $(MVN) release:perform
+
+# Full release (prepare + perform)
+release: release-prepare release-perform
+
+# Rollback failed release
+release-rollback:
+ @echo "Rolling back release..."
+ $(MVN) release:rollback
+
+# Clean release artifacts
+release-clean:
+ @echo "Cleaning release artifacts..."
+ $(MVN) release:clean
# Display help
help:
@echo "Available targets:"
- @echo " all - Same as 'package' (default)"
- @echo " build - Clean and package (without tests)"
- @echo " clean - Clean the project"
- @echo " package - Package without running tests"
+ @echo " all - Same as 'package' (default)"
+ @echo " validate - Validate environment setup"
+ @echo " build - Clean and package (without tests)"
+ @echo " clean - Clean the project"
+ @echo " package - Package without running tests"
+ @echo " test - Run tests"
@echo " package-with-clean - Clean and package in one command"
- @echo " help - Show this help message"
+ @echo " safe-build - Validate environment then build"
+ @echo ""
+ @echo "Deployment targets:"
+ @echo " deploy - Deploy artifacts to repository"
+ @echo " deploy-skip-tests - Deploy without running tests"
+ @echo ""
+ @echo "Release targets:"
+ @echo " release-prepare - Prepare release (version bump, tag)"
+ @echo " release-perform - Perform release (build and deploy)"
+ @echo " release - Full release (prepare + perform)"
+ @echo " release-rollback - Rollback a failed release"
+ @echo " release-clean - Clean release artifacts"
+ @echo ""
+ @echo " help - Show this help message"
diff --git a/docs/RELEASE_PROCESS.md b/docs/RELEASE_PROCESS.md
new file mode 100644
index 00000000..3c227395
--- /dev/null
+++ b/docs/RELEASE_PROCESS.md
@@ -0,0 +1,250 @@
+# Release Process
+
+This document describes how to create and publish releases for GPULlama3.java.
+
+## Prerequisites
+
+Before creating a release, ensure you have:
+
+1. **Git access** - Push access to the repository
+2. **GPG key** - For signing artifacts (releases only)
+3. **Maven credentials** - Configured in `~/.m2/settings.xml` for publishing
+4. **Clean working directory** - All changes committed
+
+## Quick Start
+
+### Option 1: Using Makefile (Recommended)
+
+```bash
+# Full automated release
+make release
+
+# Or step by step:
+make release-prepare # Version bump + git tag
+make release-perform # Build + deploy
+```
+
+### Option 2: Using Maven directly
+
+```bash
+# Full automated release
+./mvnw release:prepare release:perform
+
+# Or step by step:
+./mvnw release:prepare
+./mvnw release:perform
+```
+
+## What Happens During Release
+
+### Step 1: release:prepare
+
+The `release:prepare` command:
+1. Runs tests to verify the build
+2. Removes `-SNAPSHOT` from version (e.g., `0.2.2-SNAPSHOT` → `0.2.2`)
+3. Commits the release version to git with `[release] prepare release v0.2.2`
+4. Creates a git tag (e.g., `v0.2.2`)
+5. Bumps version to next development version (e.g., `0.2.3-SNAPSHOT`)
+6. Commits the new snapshot version with `[release] prepare for next development iteration`
+
+**Example:**
+```bash
+$ ./mvnw release:prepare
+What is the release version for "GPU Llama3"? (io.github.beehive-lab:gpu-llama3) 0.2.2: :
+What is SCM release tag or label for "GPU Llama3"? (io.github.beehive-lab:gpu-llama3) v0.2.2: :
+What is the new development version for "GPU Llama3"? (io.github.beehive-lab:gpu-llama3) 0.2.3-SNAPSHOT: :
+```
+
+### Step 2: release:perform
+
+The `release:perform` command:
+1. Checks out the release tag
+2. Builds the project with the `release` profile
+ - Enables GPG signing
+ - Generates Javadocs
+ - Creates sources JAR
+3. Deploys artifacts to Maven Central
+4. Cleans up temporary files
+
+## Release Profiles
+
+The project has a `release` profile that is automatically activated during `release:perform`:
+
+```xml
+
+ release
+
+ false
+ false
+
+
+```
+
+## Configuration
+
+### Maven Settings (~/.m2/settings.xml)
+
+You need credentials configured for publishing:
+
+```xml
+
+
+
+ central
+ YOUR_USERNAME
+ YOUR_PASSWORD
+
+
+
+```
+
+### GPG Configuration
+
+For signing artifacts, you need:
+
+```bash
+# Generate a GPG key (if you don't have one)
+gpg --gen-key
+
+# List your keys
+gpg --list-keys
+
+# Export public key to keyserver
+gpg --keyserver keyserver.ubuntu.com --send-keys YOUR_KEY_ID
+```
+
+Configure Maven to use your key in `~/.m2/settings.xml`:
+
+```xml
+
+
+ gpg
+
+ gpg
+ YOUR_PASSPHRASE
+
+
+
+
+
+ gpg
+
+```
+
+## Troubleshooting
+
+### Release Fails - How to Rollback
+
+If `release:prepare` fails:
+
+```bash
+make release-rollback
+# or
+./mvnw release:rollback
+```
+
+This will:
+- Remove the release tag from git
+- Revert version changes in pom.xml
+
+### Clean Up After Failed Release
+
+```bash
+make release-clean
+# or
+./mvnw release:clean
+```
+
+This removes temporary files created during the release process:
+- `release.properties`
+- `pom.xml.releaseBackup`
+
+### Common Issues
+
+#### Issue: "Working directory is not clean"
+**Solution:** Commit all changes before releasing
+```bash
+git status
+git add .
+git commit -m "Prepare for release"
+```
+
+#### Issue: "GPG signing failed"
+**Solution:** Ensure GPG key is configured and passphrase is correct
+```bash
+gpg --list-secret-keys
+```
+
+#### Issue: "Authentication failed for Maven Central"
+**Solution:** Check credentials in `~/.m2/settings.xml`
+
+#### Issue: "Tests failed"
+**Solution:** Run tests manually first
+```bash
+make test
+# or
+./mvnw test
+```
+
+## Release Checklist
+
+Before releasing:
+
+- [ ] All tests passing (`make test`)
+- [ ] CHANGELOG.md updated with release notes
+- [ ] README.md version references updated (if any)
+- [ ] All changes committed and pushed
+- [ ] Working directory clean (`git status`)
+- [ ] Maven Central credentials configured
+- [ ] GPG key configured for signing
+
+During release:
+
+- [ ] Run `make release-prepare` (or `./mvnw release:prepare`)
+- [ ] Verify git tags created (`git tag -l`)
+- [ ] Run `make release-perform` (or `./mvnw release:perform`)
+- [ ] Verify artifacts published to Maven Central
+
+After release:
+
+- [ ] Push tags to remote: `git push origin --tags`
+- [ ] Create GitHub release from tag
+- [ ] Announce release (if applicable)
+
+## Manual Deployment (Without Release Plugin)
+
+If you just want to deploy without version management:
+
+```bash
+# Deploy with tests
+make deploy
+
+# Deploy without tests
+make deploy-skip-tests
+```
+
+## Version Numbering
+
+We follow [Semantic Versioning](https://semver.org/):
+
+- **MAJOR.MINOR.PATCH** (e.g., `0.2.2`)
+- Increment MAJOR for incompatible API changes
+- Increment MINOR for backwards-compatible new features
+- Increment PATCH for backwards-compatible bug fixes
+
+Development versions have `-SNAPSHOT` suffix (e.g., `0.2.3-SNAPSHOT`)
+
+## Release Schedule
+
+Releases are created as needed. Typical triggers:
+
+- Major new features
+- Critical bug fixes
+- Security updates
+- Quarterly maintenance releases
+
+## See Also
+
+- [Maven Release Plugin Documentation](https://maven.apache.org/maven-release/maven-release-plugin/)
+- [Semantic Versioning](https://semver.org/)
+- [Maven Central Publishing](https://central.sonatype.org/publish/)
diff --git a/mvnw b/mvnw
new file mode 100755
index 00000000..bd8896bf
--- /dev/null
+++ b/mvnw
@@ -0,0 +1,295 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Apache Maven Wrapper startup batch script, version 3.3.4
+#
+# Optional ENV vars
+# -----------------
+# JAVA_HOME - location of a JDK home dir, required when download maven via java source
+# MVNW_REPOURL - repo url base for downloading maven distribution
+# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
+# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
+# ----------------------------------------------------------------------------
+
+set -euf
+[ "${MVNW_VERBOSE-}" != debug ] || set -x
+
+# OS specific support.
+native_path() { printf %s\\n "$1"; }
+case "$(uname)" in
+CYGWIN* | MINGW*)
+ [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
+ native_path() { cygpath --path --windows "$1"; }
+ ;;
+esac
+
+# set JAVACMD and JAVACCMD
+set_java_home() {
+ # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
+ if [ -n "${JAVA_HOME-}" ]; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ]; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ JAVACCMD="$JAVA_HOME/jre/sh/javac"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ JAVACCMD="$JAVA_HOME/bin/javac"
+
+ if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
+ echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
+ echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
+ return 1
+ fi
+ fi
+ else
+ JAVACMD="$(
+ 'set' +e
+ 'unset' -f command 2>/dev/null
+ 'command' -v java
+ )" || :
+ JAVACCMD="$(
+ 'set' +e
+ 'unset' -f command 2>/dev/null
+ 'command' -v javac
+ )" || :
+
+ if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
+ echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
+ return 1
+ fi
+ fi
+}
+
+# hash string like Java String::hashCode
+hash_string() {
+ str="${1:-}" h=0
+ while [ -n "$str" ]; do
+ char="${str%"${str#?}"}"
+ h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
+ str="${str#?}"
+ done
+ printf %x\\n $h
+}
+
+verbose() { :; }
+[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
+
+die() {
+ printf %s\\n "$1" >&2
+ exit 1
+}
+
+trim() {
+ # MWRAPPER-139:
+ # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
+ # Needed for removing poorly interpreted newline sequences when running in more
+ # exotic environments such as mingw bash on Windows.
+ printf "%s" "${1}" | tr -d '[:space:]'
+}
+
+scriptDir="$(dirname "$0")"
+scriptName="$(basename "$0")"
+
+# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
+while IFS="=" read -r key value; do
+ case "${key-}" in
+ distributionUrl) distributionUrl=$(trim "${value-}") ;;
+ distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
+ esac
+done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties"
+[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
+
+case "${distributionUrl##*/}" in
+maven-mvnd-*bin.*)
+ MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
+ case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
+ *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
+ :Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
+ :Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
+ :Linux*x86_64*) distributionPlatform=linux-amd64 ;;
+ *)
+ echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
+ distributionPlatform=linux-amd64
+ ;;
+ esac
+ distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
+ ;;
+maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
+*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
+esac
+
+# apply MVNW_REPOURL and calculate MAVEN_HOME
+# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/
+[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
+distributionUrlName="${distributionUrl##*/}"
+distributionUrlNameMain="${distributionUrlName%.*}"
+distributionUrlNameMain="${distributionUrlNameMain%-bin}"
+MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
+MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
+
+exec_maven() {
+ unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
+ exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
+}
+
+if [ -d "$MAVEN_HOME" ]; then
+ verbose "found existing MAVEN_HOME at $MAVEN_HOME"
+ exec_maven "$@"
+fi
+
+case "${distributionUrl-}" in
+*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
+*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
+esac
+
+# prepare tmp dir
+if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
+ clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
+ trap clean HUP INT TERM EXIT
+else
+ die "cannot create temp dir"
+fi
+
+mkdir -p -- "${MAVEN_HOME%/*}"
+
+# Download and Install Apache Maven
+verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
+verbose "Downloading from: $distributionUrl"
+verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
+
+# select .zip or .tar.gz
+if ! command -v unzip >/dev/null; then
+ distributionUrl="${distributionUrl%.zip}.tar.gz"
+ distributionUrlName="${distributionUrl##*/}"
+fi
+
+# verbose opt
+__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
+[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
+
+# normalize http auth
+case "${MVNW_PASSWORD:+has-password}" in
+'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
+has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
+esac
+
+if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
+ verbose "Found wget ... using wget"
+ wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
+elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
+ verbose "Found curl ... using curl"
+ curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
+elif set_java_home; then
+ verbose "Falling back to use Java to download"
+ javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
+ targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
+ cat >"$javaSource" <<-END
+ public class Downloader extends java.net.Authenticator
+ {
+ protected java.net.PasswordAuthentication getPasswordAuthentication()
+ {
+ return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
+ }
+ public static void main( String[] args ) throws Exception
+ {
+ setDefault( new Downloader() );
+ java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
+ }
+ }
+ END
+ # For Cygwin/MinGW, switch paths to Windows format before running javac and java
+ verbose " - Compiling Downloader.java ..."
+ "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
+ verbose " - Running Downloader.java ..."
+ "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
+fi
+
+# If specified, validate the SHA-256 sum of the Maven distribution zip file
+if [ -n "${distributionSha256Sum-}" ]; then
+ distributionSha256Result=false
+ if [ "$MVN_CMD" = mvnd.sh ]; then
+ echo "Checksum validation is not supported for maven-mvnd." >&2
+ echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
+ exit 1
+ elif command -v sha256sum >/dev/null; then
+ if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then
+ distributionSha256Result=true
+ fi
+ elif command -v shasum >/dev/null; then
+ if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
+ distributionSha256Result=true
+ fi
+ else
+ echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
+ echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
+ exit 1
+ fi
+ if [ $distributionSha256Result = false ]; then
+ echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
+ echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
+ exit 1
+ fi
+fi
+
+# unzip and move
+if command -v unzip >/dev/null; then
+ unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
+else
+ tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
+fi
+
+# Find the actual extracted directory name (handles snapshots where filename != directory name)
+actualDistributionDir=""
+
+# First try the expected directory name (for regular distributions)
+if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then
+ if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then
+ actualDistributionDir="$distributionUrlNameMain"
+ fi
+fi
+
+# If not found, search for any directory with the Maven executable (for snapshots)
+if [ -z "$actualDistributionDir" ]; then
+ # enable globbing to iterate over items
+ set +f
+ for dir in "$TMP_DOWNLOAD_DIR"/*; do
+ if [ -d "$dir" ]; then
+ if [ -f "$dir/bin/$MVN_CMD" ]; then
+ actualDistributionDir="$(basename "$dir")"
+ break
+ fi
+ fi
+ done
+ set -f
+fi
+
+if [ -z "$actualDistributionDir" ]; then
+ verbose "Contents of $TMP_DOWNLOAD_DIR:"
+ verbose "$(ls -la "$TMP_DOWNLOAD_DIR")"
+ die "Could not find Maven distribution directory in extracted archive"
+fi
+
+verbose "Found extracted Maven distribution directory: $actualDistributionDir"
+printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url"
+mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
+
+clean || :
+exec_maven "$@"
diff --git a/mvnw.cmd b/mvnw.cmd
new file mode 100644
index 00000000..5761d948
--- /dev/null
+++ b/mvnw.cmd
@@ -0,0 +1,189 @@
+<# : batch portion
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Apache Maven Wrapper startup batch script, version 3.3.4
+@REM
+@REM Optional ENV vars
+@REM MVNW_REPOURL - repo url base for downloading maven distribution
+@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
+@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output
+@REM ----------------------------------------------------------------------------
+
+@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
+@SET __MVNW_CMD__=
+@SET __MVNW_ERROR__=
+@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
+@SET PSModulePath=
+@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
+ IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
+)
+@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
+@SET __MVNW_PSMODULEP_SAVE=
+@SET __MVNW_ARG0_NAME__=
+@SET MVNW_USERNAME=
+@SET MVNW_PASSWORD=
+@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*)
+@echo Cannot start maven from wrapper >&2 && exit /b 1
+@GOTO :EOF
+: end batch / begin powershell #>
+
+$ErrorActionPreference = "Stop"
+if ($env:MVNW_VERBOSE -eq "true") {
+ $VerbosePreference = "Continue"
+}
+
+# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
+$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
+if (!$distributionUrl) {
+ Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
+}
+
+switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
+ "maven-mvnd-*" {
+ $USE_MVND = $true
+ $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
+ $MVN_CMD = "mvnd.cmd"
+ break
+ }
+ default {
+ $USE_MVND = $false
+ $MVN_CMD = $script -replace '^mvnw','mvn'
+ break
+ }
+}
+
+# apply MVNW_REPOURL and calculate MAVEN_HOME
+# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/
+if ($env:MVNW_REPOURL) {
+ $MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" }
+ $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')"
+}
+$distributionUrlName = $distributionUrl -replace '^.*/',''
+$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
+
+$MAVEN_M2_PATH = "$HOME/.m2"
+if ($env:MAVEN_USER_HOME) {
+ $MAVEN_M2_PATH = "$env:MAVEN_USER_HOME"
+}
+
+if (-not (Test-Path -Path $MAVEN_M2_PATH)) {
+ New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null
+}
+
+$MAVEN_WRAPPER_DISTS = $null
+if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) {
+ $MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists"
+} else {
+ $MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists"
+}
+
+$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain"
+$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
+$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
+
+if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
+ Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
+ Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
+ exit $?
+}
+
+if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
+ Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
+}
+
+# prepare tmp dir
+$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
+$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
+$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
+trap {
+ if ($TMP_DOWNLOAD_DIR.Exists) {
+ try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
+ catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
+ }
+}
+
+New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
+
+# Download and Install Apache Maven
+Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
+Write-Verbose "Downloading from: $distributionUrl"
+Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
+
+$webclient = New-Object System.Net.WebClient
+if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
+ $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
+}
+[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
+$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
+
+# If specified, validate the SHA-256 sum of the Maven distribution zip file
+$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
+if ($distributionSha256Sum) {
+ if ($USE_MVND) {
+ Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
+ }
+ Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
+ if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
+ Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
+ }
+}
+
+# unzip and move
+Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
+
+# Find the actual extracted directory name (handles snapshots where filename != directory name)
+$actualDistributionDir = ""
+
+# First try the expected directory name (for regular distributions)
+$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain"
+$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD"
+if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) {
+ $actualDistributionDir = $distributionUrlNameMain
+}
+
+# If not found, search for any directory with the Maven executable (for snapshots)
+if (!$actualDistributionDir) {
+ Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object {
+ $testPath = Join-Path $_.FullName "bin/$MVN_CMD"
+ if (Test-Path -Path $testPath -PathType Leaf) {
+ $actualDistributionDir = $_.Name
+ }
+ }
+}
+
+if (!$actualDistributionDir) {
+ Write-Error "Could not find Maven distribution directory in extracted archive"
+}
+
+Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir"
+Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null
+try {
+ Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
+} catch {
+ if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
+ Write-Error "fail to move MAVEN_HOME"
+ }
+} finally {
+ try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
+ catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
+}
+
+Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
diff --git a/pom.xml b/pom.xml
index 8c641c68..915c62a7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -37,39 +37,174 @@
+
21
21
UTF-8
+
+
+ 5.10.2
+ 1.1.2-dev
+
+
+ 3.11.0
+ 3.5.0
+ 3.3.0
+ 3.6.3
+ 3.2.4
+ 3.2.5
+ 3.4.1
+ 3.0.1
+ 0.8.0
+
+
true
true
+
+
+
+
+ org.junit
+ junit-bom
+ ${junit.version}
+ pom
+ import
+
+
+
+
+ tornado
+ tornado-api
+ ${tornadovm.version}
+
+
+ tornado
+ tornado-runtime
+ ${tornadovm.version}
+
+
+
+
+
- junit
- junit
- 4.13.2
+ org.junit.jupiter
+ junit-jupiter
test
+
+
tornado
tornado-api
- 1.1.2-dev
tornado
tornado-runtime
- 1.1.2-dev
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ ${maven-shade-plugin.version}
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ ${maven-source-plugin.version}
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ ${maven-javadoc-plugin.version}
+
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ ${maven-gpg-plugin.version}
+
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+ ${maven-enforcer-plugin.version}
+
+
+
+
+ org.apache.maven.plugins
+ maven-release-plugin
+ ${maven-release-plugin.version}
+
+
+
+
+ org.sonatype.central
+ central-publishing-maven-plugin
+ ${central-publishing-maven-plugin.version}
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+
+
+ enforce-versions
+
+ enforce
+
+
+
+
+ [21,)
+ Java 21 or higher is required for this project
+
+
+ [3.6.0,)
+ Maven 3.6.0 or higher is required
+
+
+
+
+
+
+
org.apache.maven.plugins
maven-compiler-plugin
- 3.11.0
--enable-preview
@@ -79,11 +214,16 @@
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
org.apache.maven.plugins
maven-shade-plugin
- 3.5.0
package
@@ -103,7 +243,6 @@
org.apache.maven.plugins
maven-source-plugin
- 3.3.0
attach-sources
@@ -116,7 +255,6 @@
org.apache.maven.plugins
maven-javadoc-plugin
- 3.6.3
attach-javadocs
@@ -135,7 +273,6 @@
org.apache.maven.plugins
maven-gpg-plugin
- 3.2.4
sign-artifacts
@@ -145,11 +282,25 @@
+
+
+ org.apache.maven.plugins
+ maven-release-plugin
+
+ v@{project.version}
+ true
+ release
+ deploy
+ [release]
+ clean verify
+ clean
+
+
+
org.sonatype.central
central-publishing-maven-plugin
- 0.8.0
true
central
@@ -159,4 +310,35 @@
+
+
+
+
+ release
+
+
+ false
+
+ false
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+
+
+ sign-artifacts
+ verify
+
+ sign
+
+
+
+
+
+
+
+
diff --git a/scripts/validate-setup.sh b/scripts/validate-setup.sh
new file mode 100755
index 00000000..7059a5e3
--- /dev/null
+++ b/scripts/validate-setup.sh
@@ -0,0 +1,169 @@
+#!/bin/bash
+# Setup validation script for GPULlama3.java
+# Validates all prerequisites before building
+
+set -e
+
+# Color codes for output
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+NC='\033[0m' # No Color
+
+# Counters
+ERRORS=0
+WARNINGS=0
+
+echo -e "${BLUE}=== GPULlama3.java Setup Validation ===${NC}\n"
+
+# Function to print status
+print_status() {
+ local status=$1
+ local message=$2
+ if [ "$status" == "OK" ]; then
+ echo -e "${GREEN}[✓]${NC} $message"
+ elif [ "$status" == "WARN" ]; then
+ echo -e "${YELLOW}[!]${NC} $message"
+ ((WARNINGS++))
+ elif [ "$status" == "ERROR" ]; then
+ echo -e "${RED}[✗]${NC} $message"
+ ((ERRORS++))
+ else
+ echo -e "${BLUE}[i]${NC} $message"
+ fi
+}
+
+# Check Java version
+echo -e "${BLUE}Checking Java installation...${NC}"
+if command -v java &> /dev/null; then
+ JAVA_VERSION=$(java -version 2>&1 | awk -F '"' '/version/ {print $2}' | cut -d'.' -f1)
+ if [ "$JAVA_VERSION" -ge 21 ]; then
+ print_status "OK" "Java version: $(java -version 2>&1 | head -n 1)"
+ else
+ print_status "ERROR" "Java version $JAVA_VERSION found, but Java 21+ is required"
+ fi
+else
+ print_status "ERROR" "Java not found in PATH"
+fi
+
+# Check JAVA_HOME
+if [ -n "$JAVA_HOME" ]; then
+ if [ -d "$JAVA_HOME" ]; then
+ print_status "OK" "JAVA_HOME: $JAVA_HOME"
+ else
+ print_status "ERROR" "JAVA_HOME set but directory does not exist: $JAVA_HOME"
+ fi
+else
+ print_status "WARN" "JAVA_HOME not set (optional but recommended)"
+fi
+
+echo ""
+
+# Check Maven
+echo -e "${BLUE}Checking Maven installation...${NC}"
+if [ -f "./mvnw" ]; then
+ print_status "OK" "Maven wrapper found (./mvnw)"
+ MVN_VERSION=$(./mvnw --version 2>&1 | head -n 1)
+ print_status "INFO" "$MVN_VERSION"
+else
+ print_status "ERROR" "Maven wrapper (./mvnw) not found"
+fi
+
+echo ""
+
+# Check TornadoVM
+echo -e "${BLUE}Checking TornadoVM setup...${NC}"
+if [ -n "$TORNADO_SDK" ]; then
+ if [ -d "$TORNADO_SDK" ]; then
+ print_status "OK" "TORNADO_SDK: $TORNADO_SDK"
+
+ # Check for key TornadoVM files
+ if [ -f "$TORNADO_SDK/bin/tornado" ]; then
+ print_status "OK" "TornadoVM binary found"
+ else
+ print_status "WARN" "TornadoVM binary not found at $TORNADO_SDK/bin/tornado"
+ fi
+ else
+ print_status "ERROR" "TORNADO_SDK set but directory does not exist: $TORNADO_SDK"
+ fi
+else
+ print_status "WARN" "TORNADO_SDK not set (required for running, not for building)"
+fi
+
+# Check for TornadoVM submodule
+if [ -d "external/tornadovm" ]; then
+ print_status "OK" "TornadoVM submodule exists at external/tornadovm"
+
+ # Check if submodule is initialized
+ if [ -f "external/tornadovm/.git" ] || [ -d "external/tornadovm/.git" ]; then
+ print_status "OK" "TornadoVM submodule initialized"
+ else
+ print_status "WARN" "TornadoVM submodule not initialized (run: git submodule update --init)"
+ fi
+else
+ print_status "WARN" "TornadoVM submodule not found at external/tornadovm"
+fi
+
+echo ""
+
+# Check LLAMA_ROOT
+echo -e "${BLUE}Checking project configuration...${NC}"
+if [ -n "$LLAMA_ROOT" ]; then
+ print_status "OK" "LLAMA_ROOT: $LLAMA_ROOT"
+else
+ print_status "WARN" "LLAMA_ROOT not set (optional, auto-detected by scripts)"
+fi
+
+# Check for pom.xml
+if [ -f "pom.xml" ]; then
+ print_status "OK" "pom.xml found"
+else
+ print_status "ERROR" "pom.xml not found in current directory"
+fi
+
+# Check for setup scripts
+if [ -f "set_paths" ]; then
+ print_status "OK" "Environment setup script found (set_paths)"
+else
+ print_status "WARN" "set_paths script not found"
+fi
+
+echo ""
+
+# Check for common issues
+echo -e "${BLUE}Checking for common issues...${NC}"
+
+# Check if running from project root
+if [ -f "llama-tornado" ]; then
+ print_status "OK" "Running from project root (llama-tornado found)"
+else
+ print_status "WARN" "llama-tornado runner not found - are you in the project root?"
+fi
+
+# Check git
+if command -v git &> /dev/null; then
+ print_status "OK" "Git is installed"
+else
+ print_status "WARN" "Git not found (needed for submodule management)"
+fi
+
+# Check for build artifacts
+if [ -d "target" ]; then
+ print_status "INFO" "Previous build artifacts found in target/"
+fi
+
+echo ""
+echo -e "${BLUE}=== Validation Summary ===${NC}"
+
+if [ $ERRORS -eq 0 ] && [ $WARNINGS -eq 0 ]; then
+ echo -e "${GREEN}✓ All checks passed! Your environment is properly configured.${NC}"
+ exit 0
+elif [ $ERRORS -eq 0 ]; then
+ echo -e "${YELLOW}! $WARNINGS warning(s) found. You can proceed but some features may not work.${NC}"
+ exit 0
+else
+ echo -e "${RED}✗ $ERRORS error(s) and $WARNINGS warning(s) found.${NC}"
+ echo -e "${YELLOW}Please fix the errors before building.${NC}"
+ exit 1
+fi