Skip to content

Commit

Permalink
Merge signed and unsigned integer types
Browse files Browse the repository at this point in the history
  • Loading branch information
axelboc committed Sep 4, 2024
1 parent ac0b148 commit c40aa55
Show file tree
Hide file tree
Showing 14 changed files with 76 additions and 86 deletions.
5 changes: 4 additions & 1 deletion packages/app/src/metadata-viewer/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
isH5WebComplex,
isIntegerType,
isNumericType,
isScalarShape,
} from '@h5web/shared/guards';
Expand Down Expand Up @@ -29,7 +30,9 @@ export function renderShape(shape: Shape): string {
export function renderType(type: DType): string {
if (isNumericType(type)) {
const { endianness, size } = type;
return `${type.class}, ${size}-bit${endianness ? `, ${endianness}` : ''}`;
const signStr = isIntegerType(type) && !type.signed ? ' (unsigned)' : '';
const endiannessStr = endianness ? `, ${endianness}` : '';
return `${type.class}${signStr}, ${size}-bit${endiannessStr}`;
}

if (type.class === DTypeClass.String) {
Expand Down
7 changes: 3 additions & 4 deletions packages/app/src/providers/h5grove/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
referenceType,
strType,
timeType,
uintType,
unknownType,
} from '@h5web/shared/hdf5-utils';
import { describe, expect, it } from 'vitest';
Expand All @@ -23,10 +22,10 @@ import { parseDType } from './utils';
describe('parseDType', () => {
it('should convert integer types', () => {
expect(parseDType({ class: 0, size: 1, order: 0, sign: 1 })).toStrictEqual(
intType(8, H5T_ORDER.LE),
intType(true, 8, H5T_ORDER.LE),
);
expect(parseDType({ class: 0, size: 8, order: 1, sign: 0 })).toStrictEqual(
uintType(64, H5T_ORDER.BE),
intType(false, 64, H5T_ORDER.BE),
);
});

Expand Down Expand Up @@ -83,7 +82,7 @@ describe('parseDType', () => {
base: { class: 0, size: 4, order: 0, sign: 0 },
members: { FOO: 41, BAR: 42 },
}),
).toStrictEqual(enumType(uintType(), { FOO: 41, BAR: 42 }));
).toStrictEqual(enumType(intType(false), { FOO: 41, BAR: 42 }));

expect(
parseDType({
Expand Down
6 changes: 3 additions & 3 deletions packages/app/src/providers/h5grove/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { isNumericType } from '@h5web/shared/guards';
import { H5T_CLASS } from '@h5web/shared/h5t';
import { H5T_CLASS, H5T_SIGN } from '@h5web/shared/h5t';
import type {
Attribute,
ChildEntity,
Expand All @@ -15,7 +15,7 @@ import {
compoundOrCplxType,
enumOrBoolType,
floatType,
intOrUintType,
intType,
opaqueType,
referenceType,
strType,
Expand Down Expand Up @@ -149,7 +149,7 @@ export function parseDType(type: H5GroveType): DType {
const { class: h5tClass, size } = type;

if (h5tClass === H5T_CLASS.INTEGER) {
return intOrUintType(type.sign, size * 8, type.order);
return intType(type.sign === H5T_SIGN.SIGN_2, size * 8, type.order);
}

if (h5tClass === H5T_CLASS.FLOAT) {
Expand Down
5 changes: 2 additions & 3 deletions packages/app/src/providers/hsds/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
floatType,
intType,
strType,
uintType,
unknownType,
} from '@h5web/shared/hdf5-utils';
import { describe, expect, it } from 'vitest';
Expand All @@ -29,12 +28,12 @@ interface TestType {

const leInt = {
hsds: { class: 'H5T_INTEGER', base: 'H5T_STD_I8LE' },
hdf5: intType(8, H5T_ORDER.LE),
hdf5: intType(true, 8, H5T_ORDER.LE),
} satisfies TestType;

const beUint = {
hsds: { class: 'H5T_INTEGER', base: 'H5T_STD_U64BE' },
hdf5: uintType(64, H5T_ORDER.BE),
hdf5: intType(false, 64, H5T_ORDER.BE),
} satisfies TestType;

const leFloat = {
Expand Down
7 changes: 1 addition & 6 deletions packages/app/src/providers/hsds/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import {
floatType,
intType,
strType,
uintType,
unknownType,
} from '@h5web/shared/hdf5-utils';

Expand Down Expand Up @@ -88,11 +87,7 @@ function convertHsdsNumericType(hsdsType: HsdsNumericType): NumericType {
return floatType(size, h5tOrder);
}

if (sign === 'U') {
return uintType(size, h5tOrder);
}

return intType(size, h5tOrder);
return intType(sign === 'I', size, h5tOrder);
}

function convertHsdsCompoundType(
Expand Down
29 changes: 16 additions & 13 deletions packages/app/src/providers/mock/mock-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
opaqueType,
printableCompoundType,
strType,
uintType,
unknownType,
} from '@h5web/shared/hdf5-utils';
import {
Expand Down Expand Up @@ -65,13 +64,13 @@ export function makeMockFile(): GroupWithChildren {
scalar('scalar_compound', ['foo', 2], {
type: compoundType({
str: strType(H5T_CSET.ASCII, H5T_STR.NULLPAD, 3),
int: intType(8),
int: intType(true, 8),
}),
attributes: [
scalarAttr('attr', ['foo', 2], {
type: compoundType({
str: strType(H5T_CSET.UTF8),
int: intType(8),
int: intType(true, 8),
}),
}),
],
Expand All @@ -89,10 +88,10 @@ export function makeMockFile(): GroupWithChildren {
],
}),
scalar('scalar_enum', 2, {
type: enumType(uintType(8), ENUM_MAPPING),
type: enumType(intType(false, 8), ENUM_MAPPING),
attributes: [
scalarAttr('attr', 2, {
type: enumType(uintType(8), ENUM_MAPPING),
type: enumType(intType(false, 8), ENUM_MAPPING),
}),
],
}),
Expand All @@ -119,7 +118,9 @@ export function makeMockFile(): GroupWithChildren {
}),
}),
array('oneD_bool'),
array('oneD_enum', { type: enumType(uintType(8), ENUM_MAPPING) }),
array('oneD_enum', {
type: enumType(intType(false, 8), ENUM_MAPPING),
}),
array('twoD'),
array('twoD_cplx'),
array('twoD_compound', {
Expand All @@ -132,21 +133,23 @@ export function makeMockFile(): GroupWithChildren {
}),
}),
array('twoD_bool'),
array('twoD_enum', { type: enumType(uintType(8), ENUM_MAPPING) }),
array('twoD_enum', {
type: enumType(intType(false, 8), ENUM_MAPPING),
}),
array('threeD'),
array('threeD_bool'),
array('threeD_cplx'),
withImageAttr(array('threeD_rgb')),
array('fourD'),
]),
group('typed_arrays', [
array('uint8', { type: uintType(8) }),
array('int16', { type: intType(16) }),
array('uint8', { type: intType(false, 8) }),
array('int16', { type: intType(true, 16) }),
array('float32', { type: floatType(32) }),
array('float64', { type: floatType(64) }),
withImageAttr(array('uint8_rgb', { type: uintType(8) })),
withImageAttr(array('int8_rgb', { type: intType(8) })),
withImageAttr(array('int32_rgb', { type: intType(32) })),
withImageAttr(array('uint8_rgb', { type: intType(false, 8) })),
withImageAttr(array('int8_rgb', { type: intType(true, 8) })),
withImageAttr(array('int32_rgb', { type: intType(true, 32) })),
withImageAttr(array('float32_rgb', { type: floatType(32) })),
]),
nxGroup('nexus_entry', 'NXentry', {
Expand Down Expand Up @@ -277,7 +280,7 @@ export function makeMockFile(): GroupWithChildren {
nxData('bool', { signal: array('twoD_bool') }),
nxData('enum', {
signal: array('twoD_enum', {
type: enumType(uintType(8), ENUM_MAPPING),
type: enumType(intType(false, 8), ENUM_MAPPING),
}),
}),
],
Expand Down
22 changes: 7 additions & 15 deletions packages/app/src/providers/utils.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { isEnumType, isNumericType } from '@h5web/shared/guards';
import { isEnumType, isFloatType, isIntegerType } from '@h5web/shared/guards';
import type {
ArrayShape,
Dataset,
DType,
ScalarShape,
} from '@h5web/shared/hdf5-models';
import { DTypeClass } from '@h5web/shared/hdf5-models';
import type { OnProgress } from '@h5web/shared/react-suspense-fetch';
import type { AxiosProgressEvent } from 'axios';

Expand All @@ -18,15 +17,8 @@ export function typedArrayFromDType(dtype: DType) {
return typedArrayFromDType(dtype.base);
}

if (!isNumericType(dtype)) {
return undefined;
}

/* Adapted from https://github.com/ludwigschubert/js-numpy-parser/blob/v1.2.3/src/main.js#L116 */
const { class: dtypeClass, size } = dtype;

if (dtypeClass === DTypeClass.Integer) {
switch (size) {
if (isIntegerType(dtype) && dtype.signed) {
switch (dtype.size) {
case 8:
return Int8Array;
case 16:
Expand All @@ -38,8 +30,8 @@ export function typedArrayFromDType(dtype: DType) {
}
}

if (dtypeClass === DTypeClass.Unsigned) {
switch (size) {
if (isIntegerType(dtype) && !dtype.signed) {
switch (dtype.size) {
case 8:
return Uint8Array;
case 16:
Expand All @@ -51,8 +43,8 @@ export function typedArrayFromDType(dtype: DType) {
}
}

if (dtypeClass === DTypeClass.Float) {
switch (size) {
if (isFloatType(dtype)) {
switch (dtype.size) {
case 16: // No support for 16-bit floating values in JS
return undefined;
case 32:
Expand Down
7 changes: 4 additions & 3 deletions packages/app/src/vis-packs/core/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isNumericType } from '@h5web/shared/guards';
import { isIntegerType, isNumericType } from '@h5web/shared/guards';
import type { ArrayValue, NumericLikeType } from '@h5web/shared/hdf5-models';
import { DTypeClass } from '@h5web/shared/hdf5-models';
import type { Axis, Domain, NumArray } from '@h5web/shared/vis-models';
Expand Down Expand Up @@ -100,10 +100,11 @@ const TYPE_STRINGS: Record<NumericLikeType['class'], string> = {
[DTypeClass.Bool]: 'bool',
[DTypeClass.Enum]: 'enum',
[DTypeClass.Integer]: 'int',
[DTypeClass.Unsigned]: 'uint',
[DTypeClass.Float]: 'float',
};

export function formatNumLikeType(type: NumericLikeType): string {
return `${TYPE_STRINGS[type.class]}${isNumericType(type) ? type.size : ''}`;
const unsignedPrefix = isIntegerType(type) && !type.signed ? 'u' : '';
const sizeSuffix = isNumericType(type) ? type.size : '';
return `${unsignedPrefix}${TYPE_STRINGS[type.class]}${sizeSuffix}`;
}
7 changes: 3 additions & 4 deletions packages/app/src/vis-packs/core/visualizations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
floatType,
intType,
strType,
uintType,
} from '@h5web/shared/hdf5-utils';
import {
assertMockAttribute,
Expand All @@ -31,19 +30,19 @@ const mockStore = {
} as AttrValuesStore;

const scalarInt = dataset('int', intType(), []);
const scalarUint = dataset('uint', uintType(), []);
const scalarUint = dataset('uint', intType(false, 32), []);
const scalarFloat = dataset('float', floatType(), []);
const scalarStr = dataset('float', strType(), []);
const scalarBool = dataset('bool', boolType(), []);
const scalarCplx = dataset('cplx', cplxType(floatType()), []);
const scalarCompound = dataset('comp', compoundType({ int: intType() }), []);
const oneDInt = dataset('int_1d', intType(), [5]);
const oneDUint = dataset('uint_1d', uintType(), [5]);
const oneDUint = dataset('uint_1d', intType(false, 32), [5]);
const oneDBool = dataset('bool_1d', boolType(), [3]);
const oneDCplx = dataset('cplx_1d', cplxType(floatType()), [10]);
const oneDCompound = dataset('comp_1d', compoundType({ int: intType() }), [5]);
const twoDInt = dataset('int_2d', intType(), [5, 3]);
const twoDUint = dataset('uint_2d', uintType(), [5, 3]);
const twoDUint = dataset('uint_2d', intType(false, 32), [5, 3]);
const twoDBool = dataset('bool_2d', boolType(), [3, 2]);
const twoDCplx = dataset('cplx_2d', cplxType(floatType()), [2, 2]);
const twoDStr = dataset('str_2d', strType(), [5, 3]);
Expand Down
5 changes: 1 addition & 4 deletions packages/h5wasm/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,7 @@ export function hasBigInts(type: DType): boolean {
return Object.values(type.fields).some(hasBigInts);
}

return (
(type.class === DTypeClass.Integer || type.class === DTypeClass.Unsigned) &&
type.size === 64
);
return type.class === DTypeClass.Integer && type.size === 64;
}

export function sanitizeBigInts(value: unknown): unknown {
Expand Down
8 changes: 4 additions & 4 deletions packages/h5wasm/src/worker-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
isNumericType,
} from '@h5web/shared/guards';
import type { H5T_STR } from '@h5web/shared/h5t';
import { H5T_CLASS, H5T_ORDER, H5T_SIGN } from '@h5web/shared/h5t';
import { H5T_CLASS, H5T_ORDER } from '@h5web/shared/h5t';
import type {
Attribute,
ChildEntity,
Expand All @@ -22,7 +22,7 @@ import {
enumOrBoolType,
floatType,
getNameFromPath,
intOrUintType,
intType,
opaqueType,
referenceType,
strType,
Expand Down Expand Up @@ -213,8 +213,8 @@ function parseDType(metadata: Metadata): DType {

if (h5tClass === H5T_CLASS.INTEGER) {
const { signed, littleEndian } = metadata;
return intOrUintType(
signed ? H5T_SIGN.SIGN_2 : H5T_SIGN.NONE,
return intType(
signed,
size * 8,
littleEndian ? H5T_ORDER.LE : H5T_ORDER.BE,
);
Expand Down
15 changes: 11 additions & 4 deletions packages/shared/src/guards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ import type {
DType,
Entity,
EnumType,
FloatType,
Group,
GroupWithChildren,
H5WebComplex,
IntegerType,
NumericLikeType,
NumericType,
Primitive,
Expand All @@ -34,7 +36,6 @@ import type {
import { AXIS_SCALE_TYPES, COLOR_SCALE_TYPES, getValues } from './vis-utils';

const PRINTABLE_DTYPES = new Set([
DTypeClass.Unsigned,
DTypeClass.Integer,
DTypeClass.Float,
DTypeClass.String,
Expand Down Expand Up @@ -294,10 +295,16 @@ export function assertStringType<S extends Shape>(
}
}

export function isIntegerType(type: DType): type is IntegerType {
return type.class === DTypeClass.Integer;
}

export function isFloatType(type: DType): type is FloatType {
return type.class === DTypeClass.Float;
}

export function isNumericType(type: DType): type is NumericType {
return [DTypeClass.Integer, DTypeClass.Unsigned, DTypeClass.Float].includes(
type.class,
);
return isIntegerType(type) || isFloatType(type);
}

export function hasNumericType<S extends Shape>(
Expand Down
Loading

0 comments on commit c40aa55

Please sign in to comment.