blob: c623a47be62055c61e9488f48c5d71bc12047cb8 [file] [edit]
/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.
Copyright 2023 The StableHLO 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.
==============================================================================*/
#include "stablehlo/dialect/Version.h"
#include <array>
#include <cstdint>
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/raw_ostream.h"
#include "mlir/IR/Diagnostics.h"
#include "mlir/Support/LLVM.h"
namespace mlir {
namespace vhlo {
namespace {
// Helper function for number to string.
// Precondition that numRef is a valid decimal digit.
static int64_t parseNumber(llvm::StringRef numRef) {
int64_t num;
if (numRef.getAsInteger(/*radix=*/10, num)) {
llvm::report_fatal_error("failed to parse version number");
}
return num;
}
/// Validate version argument is `#.#.#` (ex: 0.9.0, 0.99.0, 1.2.3)
/// Returns the vector of 3 matches (major, minor, patch) if successful,
/// else returns failure.
static FailureOr<std::array<int64_t, 3>> extractVersionNumbers(
llvm::StringRef versionRef) {
llvm::Regex versionRegex("^([0-9]+)\\.([0-9]+)\\.([0-9]+)$");
llvm::SmallVector<llvm::StringRef> matches;
if (!versionRegex.match(versionRef, &matches)) return failure();
return std::array<int64_t, 3>{parseNumber(matches[1]),
parseNumber(matches[2]),
parseNumber(matches[3])};
}
} // namespace
FailureOr<Version> Version::fromString(llvm::StringRef versionRef) {
auto failOrVersionArray = extractVersionNumbers(versionRef);
if (failed(failOrVersionArray)) return failure();
auto versionArr = *failOrVersionArray;
return Version(versionArr[0], versionArr[1], versionArr[2]);
}
FailureOr<int64_t> Version::getBytecodeVersion() const {
if (*this < Version(0, 9, 0)) return failure();
if (*this < Version(0, 10, 0)) return 0;
if (*this < Version(0, 12, 0)) return 1;
if (*this < Version(0, 14, 0)) return 3;
if (*this < Version(0, 15, 0)) return 4; // (revised from 5 to 4 in #1827)
if (*this <= getCurrentVersion()) return 6;
return failure();
}
Version Version::fromCompatibilityRequirement(
CompatibilityRequirement requirement) {
// Compatibility requirement versions can be updated as needed, as long as the
// version satisifies the requirement.
// The time frames used are from the date that the release was tagged on, not
// merged. The tag date is when the version has been verified and exported to
// XLA. See: https://github.com/openxla/stablehlo/tags
switch (requirement) {
case CompatibilityRequirement::NONE:
return Version::getCurrentVersion();
case CompatibilityRequirement::WEEK_4:
return Version(1, 8, 8); // WEEK_4 ANCHOR: DO NOT MODIFY
case CompatibilityRequirement::WEEK_12:
return Version(1, 7, 9); // WEEK_12 ANCHOR: DO NOT MODIFY
case CompatibilityRequirement::MAX:
return Version::getMinimumVersion();
}
llvm::report_fatal_error("Unhandled compatibility requirement");
}
mlir::Diagnostic& operator<<(mlir::Diagnostic& diag, const Version& version) {
return diag << version.toString();
}
llvm::raw_ostream& operator<<(llvm::raw_ostream& os, const Version& version) {
return os << version.toString();
}
} // namespace vhlo
} // namespace mlir