Skip to content
Merged
10 changes: 9 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,15 @@ if (CMAKE_SYSTEM_NAME MATCHES "Windows")
set(CMAKE_OBJECT_PATH_MAX 260)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")

message(STATUS "Windows: setting CMAKE_OBJECT_PATH_MAX to ${CMAKE_OBJECT_PATH_MAX}")
if (VCPKG_APPLOCAL_DEPS)
# vcpkg's z-applocal deployment tool can crash the build if it loses a race
# against another process (e.g. an antivirus scanner) transiently holding a
# shared dependency DLL open (see https://github.com/microsoft/vcpkg-tool/issues/2076).
# This is more likely to happen with many targets linking in parallel, as here.
# Ask vcpkg to serialize its deployment step across targets to reduce how often
# this occurs.
set(X_VCPKG_APPLOCAL_DEPS_SERIALIZED ON)
endif ()
endif ()

# Export all symbols on Windows to match GCC/Clang behavior on Linux/macOS
Expand Down
10 changes: 10 additions & 0 deletions apps/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ project(Halide_apps)

enable_testing()

if (CMAKE_SYSTEM_NAME MATCHES "Windows" AND VCPKG_APPLOCAL_DEPS)
# vcpkg's z-applocal deployment tool can crash the build if it loses a race
# against another process (e.g. an antivirus scanner) transiently holding a
# shared dependency DLL open (see https://github.com/microsoft/vcpkg-tool/issues/2076).
# This is more likely to happen with many targets linking in parallel, as here.
# Ask vcpkg to serialize its deployment step across targets to reduce how often
# this occurs.
set(X_VCPKG_APPLOCAL_DEPS_SERIALIZED ON)
endif ()

if (WIN32)
option(ENABLE_APPS_HANNK "Build apps/hannk" OFF)
else ()
Expand Down
20 changes: 10 additions & 10 deletions apps/hannk/interpreter/ops.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -584,22 +584,22 @@ double dequantize_scalar(const Tensor *t) {
int zero = q.zero.empty() ? 0 : q.zero.front();

const auto &buf = t->buffer();
switch (buf.type().element_of().as_u32()) {
case halide_type_of<uint8_t>().as_u32():
switch (buf.type()) {
case halide_type_of<uint8_t>():
return (as_scalar<uint8_t>(buf) - zero) * scale;
case halide_type_of<int8_t>().as_u32():
case halide_type_of<int8_t>():
return (as_scalar<int8_t>(buf) - zero) * scale;
case halide_type_of<uint16_t>().as_u32():
case halide_type_of<uint16_t>():
return (as_scalar<uint16_t>(buf) - zero) * scale;
case halide_type_of<int16_t>().as_u32():
case halide_type_of<int16_t>():
return (as_scalar<int16_t>(buf) - zero) * scale;
case halide_type_of<uint32_t>().as_u32():
case halide_type_of<uint32_t>():
return (as_scalar<uint32_t>(buf) - zero) * scale;
case halide_type_of<int32_t>().as_u32():
case halide_type_of<int32_t>():
return (as_scalar<int32_t>(buf) - zero) * scale;
case halide_type_of<float>().as_u32():
case halide_type_of<float>():
return (as_scalar<float>(buf) - zero) * scale;
case halide_type_of<double>().as_u32():
case halide_type_of<double>():
return (as_scalar<double>(buf) - zero) * scale;
default:
HLOG(FATAL) << "Unsupported type " << buf.type();
Expand Down Expand Up @@ -765,7 +765,7 @@ halide_type_t ConvOp::filter_type() const {
return metadata->arguments[2].type;
} else {
HLOG(FATAL) << "Unsupported type " << output()->type() << "\n";
return halide_type_t(halide_type_int, 0, 0);
return halide_type_t(halide_type_int, 0);
}
}

Expand Down
6 changes: 3 additions & 3 deletions apps/hannk/util/buffer_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ template<template<typename> class Functor, typename... Args>
auto dynamic_type_dispatch(const halide_type_t &type, Args &&...args)
-> decltype(std::declval<Functor<uint8_t>>()(std::forward<Args>(args)...)) {

#define HANDLE_CASE(CODE, BITS, TYPE) \
case halide_type_t(CODE, BITS).as_u32(): \
#define HANDLE_CASE(CODE, BITS, TYPE) \
case halide_type_t(CODE, BITS): \
return Functor<TYPE>()(std::forward<Args>(args)...);

switch (type.element_of().as_u32()) {
switch (type) {
// HANDLE_CASE(halide_type_float, 16, float) // TODO
HANDLE_CASE(halide_type_float, 32, float)
HANDLE_CASE(halide_type_float, 64, double)
Expand Down
14 changes: 0 additions & 14 deletions apps/hannk/util/error_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,6 @@

namespace hannk {

std::ostream &operator<<(std::ostream &stream, const halide_type_t &type) {
if (type.code == halide_type_uint && type.bits == 1) {
stream << "bool";
} else {
static const char *const names[5] = {"int", "uint", "float", "handle", "bfloat"};
assert(type.code >= 0 && type.code < size(names));
stream << names[type.code] << (int)type.bits;
}
if (type.lanes > 1) {
stream << "x" << (int)type.lanes;
}
return stream;
}

std::ostream &operator<<(std::ostream &s, const halide_dimension_t &dim) {
return s << "{" << dim.min << ", " << dim.extent << ", " << dim.stride << "}";
}
Expand Down
1 change: 0 additions & 1 deletion apps/hannk/util/error_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ constexpr size_t size(T (&)[N]) {
return N;
}

std::ostream &operator<<(std::ostream &stream, const halide_type_t &type);
std::ostream &operator<<(std::ostream &s, const halide_dimension_t &dim);

template<typename T>
Expand Down
65 changes: 46 additions & 19 deletions cmake/MutexCopy.ps1
Original file line number Diff line number Diff line change
@@ -1,31 +1,58 @@
param([string]$src, [string]$dstDir)

try {
$bytes = [System.Text.Encoding]::UTF8.GetBytes($dstDir)
$hash = [System.Security.Cryptography.SHA512]::Create().ComputeHash($bytes)
$key = "Halide-" + ([Convert]::ToBase64String($hash) -replace ('/', '-'))
$ErrorActionPreference = 'Stop'

$m = New-Object System.Threading.Mutex($false, $key)
if (!$m) {
throw "Failed to create mutex $key"
function Test-UpToDate([string]$src, [string]$dst) {
if (!(Test-Path $dst)) {
return $false
}
return (Get-Item $dst).LastWriteTime -ge (Get-Item $src).LastWriteTime
}

$name = Split-Path $src -leaf
$dst = Join-Path $dstDir $name

if (Test-UpToDate $src $dst) {
return
}

$m.WaitOne() | Out-Null
$bytes = [System.Text.Encoding]::UTF8.GetBytes($dstDir)
$hash = [System.Security.Cryptography.SHA512]::Create().ComputeHash($bytes)
$key = "Halide-" + ([Convert]::ToBase64String($hash) -replace ('/', '-'))

$name = Split-Path $src -leaf
$dst = Join-Path $dstDir $name
if (Test-Path $dst) {
$srcTime = (Get-Item $src).LastWriteTime
$dstTime = (Get-Item $dst).LastWriteTime
if ($dstTime -ge $srcTime) {
Return
}
$m = New-Object System.Threading.Mutex($false, $key)
$acquired = $false
try {
try {
$acquired = $m.WaitOne(120000)
} catch [System.Threading.AbandonedMutexException] {
# A previous copy was killed/cancelled while holding the lock. We still
# got ownership; the destination may be left mid-copy from that run, but
# the recheck below re-copies if it's not known-good, so it's safe to
# just proceed rather than failing the build over it.
$acquired = $true
}
if (!$acquired) {
throw "Timed out waiting for lock on $dstDir"
}

Copy-Item $src $dstDir
if (Test-UpToDate $src $dst) {
return
}

# Copy-Item directly to $dst would hold an exclusive (read-blocking) lock
# on the file for the whole duration. Move-Item is nearly instantaneous and
# atomic.
$tmp = Join-Path $dstDir ($name + "." + [System.Guid]::NewGuid().ToString("N") + ".tmp")
try {
Copy-Item $src $tmp
Move-Item -Force $tmp $dst
} finally {
Remove-Item $tmp -ErrorAction SilentlyContinue
}
} finally {
if ($m) {
if ($acquired) {
$m.ReleaseMutex() | Out-Null
$m.Dispose() | Out-Null
}
$m.Dispose() | Out-Null
}
2 changes: 1 addition & 1 deletion python_bindings/src/halide/halide_/PyBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Halide::Runtime::Buffer<T, Dims, InClassDimStorage> pybufferinfo_to_halidebuffer
const int dst_axis = reverse_axes ? (info.ndim - i - 1) : i;
dims[dst_axis] = {0, (int32_t)info.shape[i], (int32_t)elem_stride};
}
return Halide::Runtime::Buffer<T, Dims, InClassDimStorage>(t, info.ptr, (int)info.ndim, dims);
return Halide::Runtime::Buffer<T, Dims, InClassDimStorage>(t.to_abi(), info.ptr, (int)info.ndim, dims);
}

} // namespace PythonBindings
Expand Down
6 changes: 3 additions & 3 deletions python_bindings/src/halide/halide_/PyCallable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,12 @@ class PyCallable {
argv[slot] = &scalar_storage[slot];

#define HALIDE_HANDLE_TYPE_DISPATCH(CODE, BITS, TYPE, FIELD) \
case halide_type_t(CODE, BITS).as_u32(): \
case halide_type_t(CODE, BITS): \
scalar_storage[slot].u.FIELD = cast_to<TYPE>(value); \
cci[slot] = Callable::make_scalar_qcci(halide_type_t(CODE, BITS)); \
break;

switch (((halide_type_t)c_arg.type).element_of().as_u32()) {
switch (c_arg.type.to_abi()) {
HALIDE_HANDLE_TYPE_DISPATCH(halide_type_float, 32, float, f32)
HALIDE_HANDLE_TYPE_DISPATCH(halide_type_float, 64, double, f64)
HALIDE_HANDLE_TYPE_DISPATCH(halide_type_int, 8, int8_t, i8)
Expand All @@ -137,7 +137,7 @@ class PyCallable {
HALIDE_HANDLE_TYPE_DISPATCH(halide_type_uint, 64, uint64_t, u64)
HALIDE_HANDLE_TYPE_DISPATCH(halide_type_handle, 64, uint64_t, u64) // Handle types are always uint64, regardless of pointer size
default:
_halide_user_assert(0) << "Unsupported type in Callable argument list: " << c_arg.type << "\n";
_halide_user_error << "Unsupported type in Callable argument list: " << c_arg.type << "\n";
}

#undef HALIDE_HANDLE_TYPE_DISPATCH
Expand Down
4 changes: 2 additions & 2 deletions python_bindings/src/halide/halide_/PyType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ std::string halide_type_to_string(const Type &type) {
stream << "bfloat";
break;
case halide_type_handle:
if (type.handle_type) {
stream << type.handle_type->inner_name.name;
if (type.handle_type()) {
stream << type.handle_type()->inner_name.name;
} else {
stream << "handle";
}
Expand Down
2 changes: 1 addition & 1 deletion src/AddImageChecks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ Stmt add_image_checks_inner(Stmt s,
{
string type_name = name + ".type";
Expr type_var = Variable::make(UInt(32), type_name, image, param, rdom);
uint32_t correct_type_bits = ((halide_type_t)type).as_u32();
uint32_t correct_type_bits = type.to_abi();
Expr correct_type_expr = make_const(UInt(32), correct_type_bits);
Expr error = Call::make(Int(32), "halide_error_bad_type",
{error_name, type_var, correct_type_expr},
Expand Down
20 changes: 10 additions & 10 deletions src/Buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ class Buffer {
typename = std::enable_if_t<Internal::all_ints_and_optional_name<Args...>::value>>
explicit Buffer(Type t,
int first, Args... rest)
: Buffer(Runtime::Buffer<T, Dims>(t, Internal::get_shape_from_start_of_parameter_pack(first, rest...)),
: Buffer(Runtime::Buffer<T, Dims>(t.to_abi(), Internal::get_shape_from_start_of_parameter_pack(first, rest...)),
Internal::get_name_from_end_of_parameter_pack(rest...)) {
}

Expand All @@ -229,14 +229,14 @@ class Buffer {
explicit Buffer(Type t,
const std::vector<int> &sizes,
const std::string &name = "")
: Buffer(Runtime::Buffer<T, Dims>(t, sizes), name) {
: Buffer(Runtime::Buffer<T, Dims>(t.to_abi(), sizes), name) {
}

explicit Buffer(Type t,
const std::vector<int> &sizes,
const std::vector<int> &storage_order,
const std::string &name = "")
: Buffer(Runtime::Buffer<T, Dims>(t, sizes, storage_order), name) {
: Buffer(Runtime::Buffer<T, Dims>(t.to_abi(), sizes, storage_order), name) {
}

explicit Buffer(const std::vector<int> &sizes,
Expand All @@ -261,7 +261,7 @@ class Buffer {
explicit Buffer(Type t,
Internal::add_const_if_T_is_const<T, void> *data,
int first, Args &&...rest)
: Buffer(Runtime::Buffer<T, Dims>(t, data, Internal::get_shape_from_start_of_parameter_pack(first, rest...)),
: Buffer(Runtime::Buffer<T, Dims>(t.to_abi(), data, Internal::get_shape_from_start_of_parameter_pack(first, rest...)),
Internal::get_name_from_end_of_parameter_pack(rest...)) {
}

Expand All @@ -271,7 +271,7 @@ class Buffer {
Internal::add_const_if_T_is_const<T, void> *data,
const std::vector<int> &sizes,
const std::string &name = "")
: Buffer(Runtime::Buffer<T, Dims>(t, data, sizes, name)) {
: Buffer(Runtime::Buffer<T, Dims>(t.to_abi(), data, sizes, name)) {
}

template<typename... Args,
Expand All @@ -292,15 +292,15 @@ class Buffer {
Internal::add_const_if_T_is_const<T, void> *data,
const std::vector<int> &sizes,
const std::string &name = "")
: Buffer(Runtime::Buffer<T, Dims>(t, data, sizes), name) {
: Buffer(Runtime::Buffer<T, Dims>(t.to_abi(), data, sizes), name) {
}

explicit Buffer(Type t,
Internal::add_const_if_T_is_const<T, void> *data,
int d,
const halide_dimension_t *shape,
const std::string &name = "")
: Buffer(Runtime::Buffer<T, Dims>(t, data, d, shape), name) {
: Buffer(Runtime::Buffer<T, Dims>(t.to_abi(), data, d, shape), name) {
}

explicit Buffer(T *data,
Expand All @@ -315,7 +315,7 @@ class Buffer {
}

static Buffer<> make_scalar(Type t, const std::string &name = "") {
return Buffer<>(Runtime::Buffer<>::make_scalar(t), name);
return Buffer<>(Runtime::Buffer<>::make_scalar(t.to_abi()), name);
}

static Buffer<T, Dims> make_scalar(T *data, const std::string &name = "") {
Expand All @@ -327,7 +327,7 @@ class Buffer {
}

static Buffer<> make_interleaved(Type t, int width, int height, int channels, const std::string &name = "") {
return Buffer<>(Runtime::Buffer<>::make_interleaved(t, width, height, channels), name);
return Buffer<>(Runtime::Buffer<>::make_interleaved(t.to_abi(), width, height, channels), name);
}

static Buffer<T, Dims> make_interleaved(T *data, int width, int height, int channels, const std::string &name = "") {
Expand All @@ -337,7 +337,7 @@ class Buffer {
static Buffer<Internal::add_const_if_T_is_const<T, void>>
make_interleaved(Type t, T *data, int width, int height, int channels, const std::string &name = "") {
using T2 = Internal::add_const_if_T_is_const<T, void>;
return Buffer<T2, Dims>(Runtime::Buffer<T2, Dims>::make_interleaved(t, data, width, height, channels), name);
return Buffer<T2, Dims>(Runtime::Buffer<T2, Dims>::make_interleaved(t.to_abi(), data, width, height, channels), name);
}

template<typename T2, int D2>
Expand Down
Loading
Loading