Program Listing for File TensorLayout.h
↰ Return to documentation for file (nvcv_types/include/nvcv/TensorLayout.h
)
/*
* SPDX-FileCopyrightText: Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*
* 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.
*/
#ifndef NVCV_TENSORLAYOUT_H
#define NVCV_TENSORLAYOUT_H
#include "Export.h"
#include "Status.h"
#include "detail/CompilerUtils.h"
#include <stdint.h>
#include <string.h>
#ifdef __cplusplus
extern "C"
{
#endif
#define NVCV_TENSOR_MAX_RANK (15)
typedef struct NVCVTensorLayoutRec
{
// Not to be used directly.
char data[NVCV_TENSOR_MAX_RANK + 1]; // +1 for '\0'
int32_t rank;
} NVCVTensorLayout;
typedef enum
{
NVCV_TLABEL_BATCH = 'N',
NVCV_TLABEL_CHANNEL = 'C',
NVCV_TLABEL_FRAME = 'F',
NVCV_TLABEL_DEPTH = 'D',
NVCV_TLABEL_HEIGHT = 'H',
NVCV_TLABEL_WIDTH = 'W'
} NVCVTensorLabel;
#ifdef __cplusplus
# define NVCV_TENSOR_LAYOUT_MAKE(layout) \
NVCVTensorLayout \
{ \
layout, sizeof(layout) - 1 \
}
#else
# define NVCV_TENSOR_LAYOUT_MAKE(layout) \
{ \
.data = layout, .rank = sizeof(layout) - 1 \
}
#endif
NVCV_CONSTEXPR static const NVCVTensorLayout NVCV_TENSOR_NONE = NVCV_TENSOR_LAYOUT_MAKE("");
#define NVCV_DETAIL_DEF_TLAYOUT(LAYOUT) \
NVCV_CONSTEXPR static const NVCVTensorLayout NVCV_TENSOR_##LAYOUT = NVCV_TENSOR_LAYOUT_MAKE(#LAYOUT);
#include "TensorLayoutDef.inc"
#undef NVCV_DETAIL_DEF_TLAYOUT
// clang-format off
NVCV_CONSTEXPR static const NVCVTensorLayout NVCV_TENSOR_IMPLICIT[7] =
{
// Can't use the NVCV_TENSOR_* identifiers directly,
// clang complains they are not compile-time constants.
// We must resort to the make macros instead.
NVCV_TENSOR_LAYOUT_MAKE(""), // none
NVCV_TENSOR_LAYOUT_MAKE("W"),
NVCV_TENSOR_LAYOUT_MAKE("HW"),
NVCV_TENSOR_LAYOUT_MAKE("NHW"),
NVCV_TENSOR_LAYOUT_MAKE("NCHW"),
NVCV_TENSOR_LAYOUT_MAKE("NCDHW"),
NVCV_TENSOR_LAYOUT_MAKE("NCFDHW"),
};
// clang-format on
NVCV_PUBLIC NVCVStatus nvcvTensorLayoutMake(const char *descr, NVCVTensorLayout *layout);
NVCV_PUBLIC NVCVStatus nvcvTensorLayoutMakeRange(const char *beg, const char *end, NVCVTensorLayout *layout);
NVCV_PUBLIC NVCVStatus nvcvTensorLayoutMakeFirst(NVCVTensorLayout in, int32_t n, NVCVTensorLayout *layout);
NVCV_PUBLIC NVCVStatus nvcvTensorLayoutMakeLast(NVCVTensorLayout in, int32_t n, NVCVTensorLayout *layout);
NVCV_PUBLIC NVCVStatus nvcvTensorLayoutMakeSubRange(NVCVTensorLayout in, int32_t beg, int32_t end,
NVCVTensorLayout *layout);
inline static int32_t nvcvTensorLayoutFindDimIndex(NVCVTensorLayout layout, char dimLabel, int idxStart)
{
if (idxStart < 0)
{
idxStart = layout.rank + idxStart;
}
int n = layout.rank - idxStart;
if (n > 0)
{
void *p = memchr(layout.data + idxStart, dimLabel, n);
if (p != NULL)
{
return (int32_t)((char *)p - (char *)layout.data);
}
}
return -1;
}
NVCV_CONSTEXPR inline static char nvcvTensorLayoutGetLabel(NVCVTensorLayout layout, int idx)
{
// Must be all a single statement for C++11 compatibility
return idx < 0 ? (0 <= layout.rank + idx && layout.rank + idx < layout.rank ? layout.data[layout.rank + idx] : '\0')
: (0 <= idx && idx < layout.rank ? layout.data[idx] : '\0');
}
NVCV_CONSTEXPR inline static int32_t nvcvTensorLayoutGetNumDim(NVCVTensorLayout layout)
{
return layout.rank;
}
inline static int32_t nvcvTensorLayoutCompare(NVCVTensorLayout a, NVCVTensorLayout b)
{
if (a.rank == b.rank)
{
return memcmp(a.data, b.data, a.rank);
}
else
{
return a.rank - b.rank;
}
}
inline static int32_t nvcvTensorLayoutStartsWith(NVCVTensorLayout layout, NVCVTensorLayout test)
{
if (test.rank <= layout.rank)
{
return memcmp(test.data, layout.data, test.rank) == 0;
}
else
{
return 0;
}
}
inline static int32_t nvcvTensorLayoutEndsWith(NVCVTensorLayout layout, NVCVTensorLayout test)
{
if (test.rank <= layout.rank)
{
return memcmp(test.data, layout.data + layout.rank - test.rank, test.rank) == 0;
}
else
{
return 0;
}
}
NVCV_CONSTEXPR inline static const char *nvcvTensorLayoutGetName(const NVCVTensorLayout *layout)
{
return layout == NULL ? "" : layout->data;
}
#ifdef __cplusplus
}
#endif
#endif // NVCV_TENSORLAYOUT_H