Skip to content

Commit 5e723a5

Browse files
committed
PERF: Call tensorstoreToITKComponentType at compile-time, by constexpr
Ensures that `tensorstoreToITKComponentType` is evaluated at compile-time, by introducing a constexpr variable template, `toITKComponentType<T>`.
1 parent 63c4d91 commit 5e723a5

File tree

1 file changed

+53
-50
lines changed

1 file changed

+53
-50
lines changed

src/itkOMEZarrNGFFImageIO.cxx

Lines changed: 53 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,10 @@ itkToTensorstoreComponentType(const IOComponentEnum itkComponentType)
246246
}
247247
}
248248

249+
// Variable template, ensuring that tensorstoreToITKComponentType is evaluated at compile-time.
250+
template <typename T>
251+
constexpr static IOComponentEnum toITKComponentType = tensorstoreToITKComponentType(tensorstore::dtype_v<T>);
252+
249253
// Returns TensorStore KvStore driver name appropriate for this path.
250254
// Options are file, zip. TODO: http, gcs (GoogleCouldStorage), etc.
251255
std::string
@@ -602,11 +606,10 @@ OMEZarrNGFFImageIO::ReadImageInformation()
602606
}
603607

604608
// We call tensorstoreToITKComponentType for each type.
605-
// Hopefully compiler will optimize it away via constant propagation and inlining.
606-
#define READ_ELEMENT_IF(typeName) \
607-
else if (tensorstoreToITKComponentType(tensorstore::dtype_v<typeName>) == this->GetComponentType()) \
608-
{ \
609-
ReadFromStore<typeName>(store, storeIORegion, reinterpret_cast<typeName *>(buffer)); \
609+
#define READ_ELEMENT_IF(typeName) \
610+
else if (toITKComponentType<typeName> == this->GetComponentType()) \
611+
{ \
612+
ReadFromStore<typeName>(store, storeIORegion, reinterpret_cast<typeName *>(buffer)); \
610613
}
611614

612615
void
@@ -708,51 +711,51 @@ OMEZarrNGFFImageIO::WriteImageInformation()
708711

709712

710713
// We need to specify dtype for opening. As dtype is dependent on component type, this macro is long.
711-
#define ELEMENT_WRITE(typeName) \
712-
else if (tensorstoreToITKComponentType(tensorstore::dtype_v<typeName>) == this->GetComponentType()) \
713-
{ \
714-
if (sizeof(typeName) == 1) \
715-
{ \
716-
dtype = "|"; \
717-
} \
718-
if (std::numeric_limits<typeName>::is_integer) \
719-
{ \
720-
if (std::numeric_limits<typeName>::is_signed) \
721-
{ \
722-
dtype += 'i'; \
723-
} \
724-
else \
725-
{ \
726-
dtype += 'u'; \
727-
} \
728-
} \
729-
else \
730-
{ \
731-
dtype += 'f'; \
732-
} \
733-
dtype += std::to_string(sizeof(typeName)); \
734-
\
735-
auto openFuture = tensorstore::Open( \
736-
{ \
737-
{ "driver", "zarr" }, \
738-
{ "kvstore", { { "driver", driver }, { "path", this->m_FileName + "/" + path } } }, \
739-
{ "metadata", \
740-
{ \
741-
{ "compressor", { { "id", "blosc" } } }, \
742-
{ "dtype", dtype }, \
743-
{ "shape", shape }, \
744-
} }, \
745-
}, \
746-
tsContext, \
747-
tensorstore::OpenMode::create | tensorstore::OpenMode::delete_existing, \
748-
tensorstore::ReadWriteMode::read_write); \
749-
TS_EVAL_CHECK(openFuture); \
750-
\
751-
auto writeStore = openFuture.value(); \
752-
auto * p = reinterpret_cast<typeName const *>(buffer); \
753-
auto arr = tensorstore::Array(p, shape, tensorstore::c_order); \
754-
auto writeFuture = tensorstore::Write(tensorstore::UnownedToShared(arr), writeStore); \
755-
TS_EVAL_CHECK(writeFuture); \
714+
#define ELEMENT_WRITE(typeName) \
715+
else if (toITKComponentType<typeName> == this->GetComponentType()) \
716+
{ \
717+
if (sizeof(typeName) == 1) \
718+
{ \
719+
dtype = "|"; \
720+
} \
721+
if (std::numeric_limits<typeName>::is_integer) \
722+
{ \
723+
if (std::numeric_limits<typeName>::is_signed) \
724+
{ \
725+
dtype += 'i'; \
726+
} \
727+
else \
728+
{ \
729+
dtype += 'u'; \
730+
} \
731+
} \
732+
else \
733+
{ \
734+
dtype += 'f'; \
735+
} \
736+
dtype += std::to_string(sizeof(typeName)); \
737+
\
738+
auto openFuture = tensorstore::Open( \
739+
{ \
740+
{ "driver", "zarr" }, \
741+
{ "kvstore", { { "driver", driver }, { "path", this->m_FileName + "/" + path } } }, \
742+
{ "metadata", \
743+
{ \
744+
{ "compressor", { { "id", "blosc" } } }, \
745+
{ "dtype", dtype }, \
746+
{ "shape", shape }, \
747+
} }, \
748+
}, \
749+
tsContext, \
750+
tensorstore::OpenMode::create | tensorstore::OpenMode::delete_existing, \
751+
tensorstore::ReadWriteMode::read_write); \
752+
TS_EVAL_CHECK(openFuture); \
753+
\
754+
auto writeStore = openFuture.value(); \
755+
auto * p = reinterpret_cast<typeName const *>(buffer); \
756+
auto arr = tensorstore::Array(p, shape, tensorstore::c_order); \
757+
auto writeFuture = tensorstore::Write(tensorstore::UnownedToShared(arr), writeStore); \
758+
TS_EVAL_CHECK(writeFuture); \
756759
}
757760

758761
void

0 commit comments

Comments
 (0)