Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions .github/workflows/macos-arm.yml → .github/workflows/arm.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: ITK.macOS.Arm64
name: ITK.Arm64

on:
push:
Expand Down Expand Up @@ -36,12 +36,24 @@ env:
jobs:
build:
runs-on: ${{ matrix.os }}
timeout-minutes: 0
timeout-minutes: 600

strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-24.04-arm
name: "Ubuntu-24.04-arm"
cmake-build-type: "Release"
cmake-generator: "Ninja"
python-version: ""
ctest-cache: |
BUILD_SHARED_LIBS:BOOL=OFF
BUILD_EXAMPLES:BOOL=OFF
ITK_WRAP_PYTHON:BOOL=OFF
ITK_USE_CLANG_FORMAT:BOOL=OFF
ctest-options: ""

- os: macos-15
name: "x86_64-rosetta"
cmake-build-type: "Release"
Expand All @@ -67,7 +79,7 @@ jobs:
ITK_USE_CLANG_FORMAT:BOOL=OFF
ctest-options: "-E itkPyBufferMemoryLeakTest"

name: macOS-${{ matrix.name }}
name: ARMBUILD-${{ matrix.name }}

steps:
- name: Checkout
Expand Down Expand Up @@ -122,6 +134,6 @@ jobs:
c++ --version
cmake --version

ctest -S ${{ github.workspace }}/ITK-dashboard/dashboard.cmake -VV -j 4 ${{ matrix.ctest-options }}
ctest -S ${{ github.workspace }}/ITK-dashboard/dashboard.cmake --output-on-failure -j 4 ${{ matrix.ctest-options }}
env:
CTEST_OUTPUT_ON_FAILURE: 1
1 change: 1 addition & 0 deletions Modules/Core/Common/src/itkMetaDataDictionary.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ MetaDataDictionary::Print(std::ostream & os) const
{
os << it.first << " ";
it.second->Print(os);
os << std::endl;
}
}

Expand Down
154 changes: 154 additions & 0 deletions Modules/Core/Common/test/itkMetaDataDictionaryGTest.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,157 @@ createMetaDataDictionary()
return metaDataDictionary;
}

// DUPLICATE CODE IN HDF5ImageIOTest
namespace
{
template <typename T>
void
AddMetaData(itk::MetaDataDictionary & metaDict, const std::string & key, const T & knownValue)
{
itk::EncapsulateMetaData<T>(metaDict, key, knownValue);
}

template <typename T>
int
VerifyMetaData(const itk::MetaDataDictionary & metaDict, const std::string & key, const T & knownValue)
{
int status = EXIT_SUCCESS;
T exposedValue{};
if (!itk::ExposeMetaData<T>(metaDict, key, exposedValue))
{
std::cerr << "Failure ExposeMetaData '" << key << "'" << std::endl;
status = EXIT_FAILURE;
}
if constexpr (std::is_floating_point_v<T>)
{
if (itk::Math::NotAlmostEquals(exposedValue, knownValue))
{
std::cerr << "Incorrect meta value read in for " << key << " '" << exposedValue << "' != '" << knownValue << "'"
<< std::endl;
status = EXIT_FAILURE;
}
}
else
{
if (exposedValue != knownValue)
{
std::cerr << "Incorrect meta value read in for " << key << " '" << exposedValue << "' != '" << knownValue << "'"
<< std::endl;
status = EXIT_FAILURE;
}
}
if (status == EXIT_FAILURE)
{
std::cerr << "========================================" << std::endl;
metaDict.Print(std::cerr);
std::cerr << "========================================" << std::endl;
}
return status;
}
} // namespace


template <typename T>
static int
CheckMetaData(itk::MetaDataDictionary & metaDict, const std::string & key, const T & knownValue)
{
AddMetaData<T>(metaDict, key, knownValue);
return VerifyMetaData<T>(metaDict, key, knownValue);
}


static int
doExposeMetaDatas()
{
// Simplified version of tests found in HDF5 reading/writing
// that are broken out here to improve localization of bugs
// found during linux-arm building
itk::MetaDataDictionary metaDict;
int success = EXIT_SUCCESS;

if (CheckMetaData<bool>(metaDict, "TestBool", false) != EXIT_SUCCESS)
{
success = EXIT_FAILURE;
}
if (CheckMetaData<char>(metaDict, "TestChar", 'c') != EXIT_SUCCESS)
{
success = EXIT_FAILURE;
}
if (CheckMetaData<unsigned char>(metaDict, "TestUChar", 'u') != EXIT_SUCCESS)
{
success = EXIT_FAILURE;
}
if (CheckMetaData<short>(metaDict, "TestShort", 1) != EXIT_SUCCESS)
{
success = EXIT_FAILURE;
}
if (CheckMetaData<unsigned short>(metaDict, "TestUShort", 3) != EXIT_SUCCESS)
{
success = EXIT_FAILURE;
}
if (CheckMetaData<int>(metaDict, "TestInt", 5) != EXIT_SUCCESS)
{
success = EXIT_FAILURE;
}
if (CheckMetaData<unsigned int>(metaDict, "TestUInt", 7) != EXIT_SUCCESS)
{
success = EXIT_FAILURE;
}
if (CheckMetaData<long>(metaDict, "TestLong", 5) != EXIT_SUCCESS)
{
success = EXIT_FAILURE;
}
if (CheckMetaData<unsigned long>(metaDict, "TestULong", 7) != EXIT_SUCCESS)
{
success = EXIT_FAILURE;
}
if (CheckMetaData<long long>(metaDict, "TestLLong", -5) != EXIT_SUCCESS)
{
success = EXIT_FAILURE;
}
if (CheckMetaData<unsigned long long>(metaDict, "TestULLong", 7ull) != EXIT_SUCCESS)
{
success = EXIT_FAILURE;
}
if (CheckMetaData<float>(metaDict, "TestFloat", 1.23456f) != EXIT_SUCCESS)
{
success = EXIT_FAILURE;
}
if (CheckMetaData<double>(metaDict, "TestDouble", 1.23456) != EXIT_SUCCESS)
{
success = EXIT_FAILURE;
}

itk::Array<char> metaDataCharArray(5);
metaDataCharArray[0] = 'h';
metaDataCharArray[1] = 'e';
metaDataCharArray[2] = 'l';
metaDataCharArray[3] = 'l';
metaDataCharArray[4] = 'o';
if (CheckMetaData<itk::Array<char>>(metaDict, "TestCharArray", metaDataCharArray) != EXIT_SUCCESS)
{
success = EXIT_FAILURE;
}

itk::Array<double> metaDataDoubleArray(5);
metaDataDoubleArray[0] = 3.0;
metaDataDoubleArray[1] = 1.0;
metaDataDoubleArray[2] = 4.0;
metaDataDoubleArray[3] = 5.0;
metaDataDoubleArray[4] = 2.0;
if (CheckMetaData<itk::Array<double>>(metaDict, "TestDoubleArray", metaDataDoubleArray) != EXIT_SUCCESS)
{
success = EXIT_FAILURE;
}

if (CheckMetaData<std::string>(metaDict, "StdString", "Test std::string") != EXIT_SUCCESS)
{
success = EXIT_FAILURE;
}
return success;
}


template <typename T>
itk::MetaDataObjectBase::Pointer
createMetaDataObject(const T & invalue)
Expand All @@ -56,6 +207,9 @@ createMetaDataObject(const T & invalue)

TEST(MetaDataDictionary, Basic)
{
// Isolate
EXPECT_EQ(doExposeMetaDatas(), EXIT_SUCCESS);

// This test exercises and checks the non-constant interface
itk::MetaDataDictionary dic = createMetaDataDictionary();

Expand Down
46 changes: 23 additions & 23 deletions Modules/IO/HDF5/src/itkHDF5ImageIO.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -80,32 +80,32 @@ GetType()
H5::PredType GetType<CXXType>() \
{ \
return H5Type; \
}

GetH5TypeSpecialize(float, H5::PredType::NATIVE_FLOAT) GetH5TypeSpecialize(double, H5::PredType::NATIVE_DOUBLE)

GetH5TypeSpecialize(char, H5::PredType::NATIVE_CHAR) GetH5TypeSpecialize(unsigned char, H5::PredType::NATIVE_UCHAR)

GetH5TypeSpecialize(short, H5::PredType::NATIVE_SHORT)
GetH5TypeSpecialize(short unsigned int, H5::PredType::NATIVE_USHORT)

GetH5TypeSpecialize(int, H5::PredType::NATIVE_INT) GetH5TypeSpecialize(unsigned int, H5::PredType::NATIVE_UINT)

GetH5TypeSpecialize(long, H5::PredType::NATIVE_LONG)
GetH5TypeSpecialize(long unsigned int, H5::PredType::NATIVE_ULONG)

GetH5TypeSpecialize(long long, H5::PredType::NATIVE_LLONG)
GetH5TypeSpecialize(unsigned long long, H5::PredType::NATIVE_ULLONG)
}; \
ITK_MACROEND_NOOP_STATEMENT

GetH5TypeSpecialize(float, H5::PredType::NATIVE_FLOAT);
GetH5TypeSpecialize(double, H5::PredType::NATIVE_DOUBLE);
GetH5TypeSpecialize(char, H5::PredType::NATIVE_CHAR);
GetH5TypeSpecialize(unsigned char, H5::PredType::NATIVE_UCHAR);
GetH5TypeSpecialize(short, H5::PredType::NATIVE_SHORT);
GetH5TypeSpecialize(short unsigned int, H5::PredType::NATIVE_USHORT);
GetH5TypeSpecialize(int, H5::PredType::NATIVE_INT);
GetH5TypeSpecialize(unsigned int, H5::PredType::NATIVE_UINT);
GetH5TypeSpecialize(long, H5::PredType::NATIVE_LONG);
GetH5TypeSpecialize(long unsigned int, H5::PredType::NATIVE_ULONG);
GetH5TypeSpecialize(long long, H5::PredType::NATIVE_LLONG);
GetH5TypeSpecialize(unsigned long long, H5::PredType::NATIVE_ULLONG);

/* The following types are not implemented. This comment serves
* to indicate that the full complement of possible H5::PredType
* types are not implemented int the ITK IO reader/writer
* types is not implemented int the ITK IO reader/writer
* GetH5TypeSpecialize(bool, H5::PredType::NATIVE_HBOOL)
*/

#undef GetH5TypeSpecialize

inline IOComponentEnum PredTypeToComponentType(H5::DataType & type)
inline IOComponentEnum
PredTypeToComponentType(H5::DataType & type)
{
if (type == H5::PredType::NATIVE_UCHAR)
{
Expand Down Expand Up @@ -964,12 +964,12 @@ template <typename TType>
bool
HDF5ImageIO::WriteMeta(const std::string & name, MetaDataObjectBase * metaObjBase)
{
auto * metaObj = dynamic_cast<MetaDataObject<TType> *>(metaObjBase);
if (metaObj == nullptr)
if (metaObjBase == nullptr || metaObjBase->GetMetaDataObjectTypeInfo() != typeid(TType))
{
return false;
}
TType val = metaObj->GetMetaDataObjectValue();
auto * metaObj = static_cast<MetaDataObject<TType> *>(metaObjBase);
TType val = metaObj->GetMetaDataObjectValue();
this->WriteScalar(name, val);
return true;
}
Expand All @@ -979,11 +979,11 @@ bool
HDF5ImageIO::WriteMetaArray(const std::string & name, MetaDataObjectBase * metaObjBase)
{
using MetaDataArrayObject = MetaDataObject<Array<TType>>;
auto * metaObj = dynamic_cast<MetaDataArrayObject *>(metaObjBase);
if (metaObj == nullptr)
if (metaObjBase == nullptr || metaObjBase->GetMetaDataObjectTypeInfo() != typeid(Array<TType>))
{
return false;
}
auto * metaObj = static_cast<MetaDataArrayObject *>(metaObjBase);
Array<TType> val = metaObj->GetMetaDataObjectValue();
std::vector<TType> vecVal(val.GetSize());
for (unsigned int i = 0; i < val.size(); ++i)
Expand Down
Loading
Loading