Skip to content
Merged
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
15 changes: 15 additions & 0 deletions docs/ubenchx-ascend-core-profiles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Core memory-access profiles: B200 and Huawei 950PR

The `/ubenchx/core-memory-profiles` page combines B200 and Huawei 950PR, showing both by default. Its hardware selector can focus on either device. The B200 SM matrix keeps its `clock64` cycle units, GPC/die grouping, statistics and independent color domain; the 950PR retains SYS_CNT ticks and a shared scale across its four panels. Colors and values across devices are not comparable absolute latency. Both matrices measure differences between matched-address latency profiles, not direct core-to-core communication time.

The legacy `/ubenchx/sm-l2-distance` page and its Chinese sibling redirect to the combined page; the existing `test=sm-l2-distance` API remains compatible.

The Ascend portion of the `core-memory-profiles` view preserves the four 128 MiB matrices from the 6–7 October 2026 (Singapore time) Cube/Vector locality rerun: 28 Cube scalar controllers and 56 Vector scalar controllers, each tested with one active core and with concurrent launches. Both core types use identical scalar pointer-chase instructions on the same allocation. Each address is averaged over six passes before computing the mean absolute difference between two cores' address profiles.

The data file contains every displayed matrix entry without rounding, the actual physical core-ID lists, the original pair statistics and source hashes. The arrays preserve ID gaps. Runtime-ID die groups divide IDs below 54 from those at or above 54; they do not assign physical coordinates. The frontend and API recompute within/between-group means from unique off-diagonal pairs using the same pure function. A shared 0–113.63708496093749 SYS_CNT-tick color domain applies to all four panels.

The unit is raw `SYS_CNT ticks`, not `clock64` cycles or nanoseconds. These are profile differences, not direct core-to-core latency, cache-controller distance or a recovered floorplan. The 128 MiB pattern is separate from the smaller-footprint profile classes and independent contention experiments; those extra inferences are not added here. Concurrent launches lack a grid-wide start barrier, and their fine structure is less repeatable than the broad grouping. No cache-sharing claim follows solely from these positive distances.

The complete displayed data is in `ascend-core-profiles.json`. Its `sourceSha256` identifies the original plotted-data JSON; each panel also retains the hashes of its archived analysis inputs. This publication contains the displayed matrices and aggregate statistics, not every original per-load observation.

Coverage: `/ubenchx/core-memory-profiles` and its `/zh` sibling show B200 and all four Ascend panels. Hover, keyboard arrows and pinning only inspect already-returned cells; they do not change data. A repeated click or Enter unpins the current cell. Clicking outside the panel, Escape, or Clear selection clears it. A click on a different cell changes the pin; pointer exit clears an unpinned hover preview. The hub's new test is available through `/api/v1/views/ubenchx?test=core-memory-profiles`, with `gpu=all` (default), `gpu=B200 SXM` or `gpu=Ascend 950PR_9579`, and as `coreMemoryProfiles` in `test=all`. Explicit device selections leave other unavailable test sections empty. B200 keeps its original transformed SM fields plus `unit`, `metric`, `limitations` and `colorLimits`; Ascend keeps its panel schema. API `unit`, `metric`, `limitations`, `coreIds`, `dieGroups` and `colorLimits` preserve the measurement interpretation.
109 changes: 104 additions & 5 deletions packages/app/cypress/e2e/ubenchx.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe('ubenchX hub and test routes', () => {
cy.get('[data-testid="ubenchx-metric-select"]').should('contain', 'TB/s');
});

it('switches to sm-l2-distance with the test selector', () => {
it('switches to the combined core profiles with the test selector', () => {
cy.visit('/ubenchx/mem-bw', dismissModal);
cy.contains('ubenchX').should('be.visible');
cy.get('[data-testid="ubenchx-metric-select"]').should('be.visible');
Expand All @@ -36,10 +36,10 @@ describe('ubenchX hub and test routes', () => {
.should('include', '/zh/ubenchx/mem-bw');

cy.get('[data-testid="ubenchx-test-select"]').click();
cy.contains('[role="option"]', 'SM-SM L2 Latency Difference').click();
cy.url().should('include', '/ubenchx/sm-l2-distance');
cy.contains('[role="option"]', 'Core memory-access profiles').click();
cy.url().should('include', '/ubenchx/core-memory-profiles');
cy.get('[data-testid="sm-l2-heatmap"]').should('be.visible');
cy.get('[data-testid="ubenchx-test-select"]').should('contain', 'SM-SM L2 Latency Difference');
cy.get('[data-testid="ubenchx-test-select"]').should('contain', 'Core memory-access profiles');
});

it('switches to the TPC Skyline table with the test selector', () => {
Expand Down Expand Up @@ -90,7 +90,7 @@ describe('ubenchX hub and test routes', () => {
cy.get('meta[name="robots"]').should('have.attr', 'content').and('contain', 'noindex');
cy.get('link[rel="alternate"][hreflang="zh-CN"]')
.invoke('attr', 'href')
.should('include', '/zh/ubenchx/sm-l2-distance');
.should('include', '/zh/ubenchx/core-memory-profiles');

cy.get('[data-testid="sm-l2-heatmap"] svg rect').last().as('overlay');
cy.get('@overlay').click(520, 120, { force: true });
Expand Down Expand Up @@ -132,6 +132,105 @@ const dismiss = {
},
};

describe('Ascend core memory-access profiles', () => {
it('navigates to all four profiles and inspects actual core IDs by keyboard', () => {
cy.visit('/ubenchx/mem-bw', dismiss);
cy.get('[data-testid="ubenchx-test-select"]').click();
cy.contains('[role="option"]', 'Core memory-access profiles').click();
cy.url().should('include', '/ubenchx/core-memory-profiles');
cy.contains('SYS_CNT ticks are not clock64 cycles').should('be.visible');
cy.get('[data-testid="profile-scalar_128MiB_cube_isolated"] svg')
.focus()
.trigger('keydown', { key: 'ArrowRight' });
cy.get('[data-testid="profile-scalar_128MiB_cube_isolated-value"]').should(
'contain',
'0 ↔ 2: 15.30 SYS_CNT ticks',
);
cy.get('[data-testid="profile-scalar_128MiB_vector_concurrent"] svg').should('exist');
cy.screenshot('ascend-core-profiles-en', { capture: 'fullPage' });
cy.visit('/zh/ubenchx/core-memory-profiles', dismiss);
cy.contains('h2', '核心访存特征').should('be.visible');
cy.get('[data-testid="ubenchx-test-select"]').should('contain', '核心访存特征');
cy.contains('不是核心间通信延迟').should('be.visible');
cy.contains('没有网格级起始同步屏障').should('be.visible');
cy.screenshot('ascend-core-profiles-zh', { capture: 'fullPage' });
});
it('returns the displayed matrix values and preserves absent GPU measurements', () => {
cy.request('/api/v1/views/ubenchx?test=all&gpu=Ascend%20950PR_9579').then(({ body }) => {
const panel = body.coreMemoryProfiles.gpus[0].panels[0];
expect(panel.coreIds.slice(12, 16)).to.deep.equal([14, 15, 54, 55]);
expect(panel.matrix[0][14]).to.be.closeTo(96.70648193359, 1e-8);
expect(panel.unit).to.equal('SYS_CNT ticks');
expect(body.smL2Distance.gpus).to.deep.equal([]);
});
});
});

it('unpins core-profile cells by repeated click or Enter and clears them outside or by button', () => {
cy.visit('/ubenchx/core-memory-profiles', dismiss);
const panel = '[data-testid="profile-scalar_128MiB_cube_isolated"]';
const value = '[data-testid="profile-scalar_128MiB_cube_isolated-value"]';
const clear = '[data-testid="profile-scalar_128MiB_cube_isolated-clear"]';
cy.get(`${panel} svg rect`).eq(1).click();
cy.get(value).should('contain', 'Pinned core pair: 0 ↔ 1: 19.03');
cy.get(`${panel} svg rect`).eq(2).click();
cy.get(value).should('contain', 'Pinned core pair: 0 ↔ 2: 15.30');
cy.get(`${panel} svg rect`).eq(2).click();
cy.get(value).should('not.contain', 'core pair:');
cy.get(clear).should('be.disabled');
cy.get(`${panel} svg`)
.trigger('keydown', { key: 'ArrowRight' })
.trigger('keydown', { key: 'Enter' });
cy.get(value).should('contain', 'Pinned core pair:');
cy.get(`${panel} svg`).trigger('keydown', { key: 'Enter' });
cy.get(clear).should('be.disabled');
cy.get(`${panel} svg rect`).eq(1).click();
cy.contains('h2', 'Core memory-access profiles').click();
cy.get(clear).should('be.disabled');
cy.get(`${panel} svg rect`).eq(1).click();
cy.get(clear).click();
cy.get(clear).should('be.disabled');
cy.get(`${panel} svg rect`).eq(1).click();
cy.get(`${panel} svg`).trigger('keydown', { key: 'Escape' });
cy.get(clear).should('be.disabled');
});

it('filters both devices on one page and preserves their API values and units', () => {
cy.visit('/ubenchx/core-memory-profiles', dismiss);
cy.get('[data-testid="sm-l2-heatmap"]').should('exist');
cy.get('[data-testid="ascend-core-profiles"]').should('exist');
cy.get('[data-testid="core-profile-hardware"]').should('contain', 'All hardware').click();
cy.contains('[role="option"]', 'B200 SXM').click();
cy.get('[data-testid="sm-l2-heatmap"]').should('be.visible');
cy.get('[data-testid="ascend-core-profiles"]').should('not.exist');
cy.request('/api/v1/views/ubenchx?test=core-memory-profiles&gpu=B200%20SXM').then(({ body }) => {
expect(body.gpus).to.have.length(1);
expect(body.gpus[0].unit).to.equal('clock64 cycles');
cy.contains(`${body.gpus[0].stats.crossDieMean.toFixed(1)} cycles`).should('be.visible');
});
cy.get('[data-testid="core-profile-hardware"]').click();
cy.contains('[role="option"]', 'Huawei 950PR').click();
cy.get('[data-testid="sm-l2-heatmap"]').should('not.exist');
cy.get('[data-testid="profile-scalar_128MiB_cube_isolated"] svg').focus();
cy.get('[data-testid="profile-scalar_128MiB_cube_isolated-value"]').should(
'contain',
'0 ↔ 1: 19.03 SYS_CNT ticks',
);
cy.get('[data-testid="core-profile-hardware"]').click();
cy.contains('[role="option"]', 'All hardware').click();
cy.get('[data-testid="sm-l2-heatmap"]').should('exist');
cy.get('[data-testid="ascend-core-profiles"]').should('exist');
cy.screenshot('combined-core-profiles-desktop', { capture: 'fullPage' });
cy.visit('/zh/ubenchx/sm-l2-distance', dismiss);
cy.location('pathname').should('equal', '/zh/ubenchx/core-memory-profiles');
cy.viewport(390, 844);
cy.get('[data-testid="core-profile-hardware"]').should('contain', '全部硬件');
cy.contains('不同设备上颜色或数值相同,并不代表延迟相同').should('be.visible');
cy.get('[data-testid="sm-l2-heatmap"]').should('exist');
cy.get('[data-testid="ascend-core-profiles"]').should('exist');
cy.screenshot('combined-core-profiles-mobile-zh', { capture: 'fullPage' });
});

describe('Huawei copy-bandwidth evidence', () => {
it('renders Huawei 950PR and qualifies the graph timing in English and Chinese', () => {
cy.visit('/ubenchx/mem-bw', dismiss);
Expand Down
53 changes: 52 additions & 1 deletion packages/app/src/app/api/v1/views/ubenchx/route.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('ubenchx view', () => {
expect(body.view).toBe('ubenchx');
expect(body.apiVersion).toBe('v1');
expect(body.test).toBe('all');
expect(body.tests).toEqual(['mem-bw', 'sm-l2-distance', 'tpc-skyline']);
expect(body.tests).toEqual(['mem-bw', 'sm-l2-distance', 'tpc-skyline', 'core-memory-profiles']);
expect(body.memBw.gpus).toHaveLength(1);
expect(body.smL2Distance.gpus.length).toBeGreaterThanOrEqual(1);
expect(body.tpcSkyline.gpus).toHaveLength(Object.keys(TPC_SKYLINE_RUNS).length);
Expand Down Expand Up @@ -159,6 +159,57 @@ describe('ubenchx view', () => {
});
});

it('returns the Ascend core profiles with raw timer units and leaves unavailable tests empty', async () => {
const response = await GET(request({ test: 'all', gpu: 'ascend 950pr_9579' }));
expect(response.status).toBe(200);
const body = await response.json();
expect(body.memBw.gpus).toEqual([]);
expect(body.smL2Distance.gpus).toEqual([]);
expect(body.tpcSkyline.gpus).toEqual([]);
const run = body.coreMemoryProfiles.gpus[0];
expect(run.gpu).toBe('Ascend 950PR_9579');
expect(run.panels.map((panel: { coreIds: number[] }) => panel.coreIds.length)).toEqual([
28, 28, 56, 56,
]);
expect(run.panels[0].unit).toBe('SYS_CNT ticks');
expect(run.panels[0].coreIds.slice(12, 16)).toEqual([14, 15, 54, 55]);
expect(run.panels[0].stats.withinDieGroupMean).toBeCloseTo(18.55499211685, 8);
expect(run.panels[0].stats.betweenDieGroupMean).toBeCloseTo(93.12987720723, 8);
expect(run.panels[0].matrix[0][14]).toBeCloseTo(96.70648193359, 8);
const onlyResponse = await GET(
request({ test: 'core-memory-profiles', gpu: 'Ascend 950PR_9579' }),
);
const only = await onlyResponse.json();
expect(only.gpus).toEqual(body.coreMemoryProfiles.gpus);
const missing = await GET(request({ test: 'core-memory-profiles', gpu: 'H100 SXM' }));
expect(missing.status).toBe(400);
});

it('combines both hardware profiles without converting or pooling their units', async () => {
const response = await GET(request({ test: 'core-memory-profiles' }));
const body = await response.json();
expect(body.params).toEqual({ test: 'core-memory-profiles', gpu: 'all' });
expect(body.gpus.map((run: { gpu: string }) => run.gpu)).toEqual([
'B200 SXM',
'Ascend 950PR_9579',
]);
const b200 = body.gpus[0];
expect(b200).toMatchObject(transformSmL2Run('B200 SXM', SM_L2_RUNS['B200 SXM']));
expect(b200.unit).toBe('clock64 cycles');
expect(b200.colorLimits).toEqual([0, b200.stats.max]);
expect(body.gpus[1].panels[0].unit).toBe('SYS_CNT ticks');
const filteredResponse = await GET(request({ test: 'core-memory-profiles', gpu: 'b200 sxm' }));
const filtered = await filteredResponse.json();
expect(filtered.params.gpu).toBe('B200 SXM');
expect(filtered.gpus).toEqual([b200]);
const allResponse = await GET(request({ test: 'all', gpu: 'B200 SXM' }));
const all = await allResponse.json();
expect(all.coreMemoryProfiles.gpus).toEqual([b200]);
const legacyResponse = await GET(request({ test: 'sm-l2-distance', gpu: 'B200 SXM' }));
const legacy = await legacyResponse.json();
expect(legacy.gpus[0]).toEqual(transformSmL2Run('B200 SXM', SM_L2_RUNS['B200 SXM']));
});

it('exposes Huawei rotating-copy evidence without inventing missing tests or sizes', async () => {
const response = await GET(request({ test: 'all', gpu: 'huawei 950pr' }));
expect(response.status).toBe(200);
Expand Down
37 changes: 34 additions & 3 deletions packages/app/src/app/api/v1/views/ubenchx/route.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import {
CORE_PROFILE_GPU,
CORE_PROFILE_GPU_KEYS,
coreMemoryProfileResults,
} from '@/components/ubenchx/core-memory-profiles';
import { SM_L2_RUNS } from '@/components/ubenchx/sm-l2-data';
import { transformSmL2Run } from '@/components/ubenchx/sm-l2-transform';
import { TPC_SKYLINE_RUNS } from '@/components/ubenchx/tpc-skyline-data';
Expand All @@ -12,7 +17,12 @@ import type { NextRequest } from 'next/server';

export const dynamic = 'force-dynamic';

const AVAILABLE_TESTS = ['mem-bw', 'sm-l2-distance', 'tpc-skyline'] as const;
const AVAILABLE_TESTS = [
'mem-bw',
'sm-l2-distance',
'tpc-skyline',
'core-memory-profiles',
] as const;

/** TPC per GPC groupings for every GPU (`gpu=all`, the default) or one GPU. */
function tpcSkylineResults(gpu: string) {
Expand All @@ -28,6 +38,19 @@ export function GET(request: NextRequest) {
const test = parseEnumParam(s.get('test'), 'test', ['all', ...AVAILABLE_TESTS], 'all');
const rawGpu = s.get('gpu');

if (test === 'core-memory-profiles') {
const gpu = parseEnumParam(rawGpu, 'gpu', ['all', ...CORE_PROFILE_GPU_KEYS], 'all');
return Promise.resolve(
cachedJson({
apiVersion: 'v1',
view: 'ubenchx',
test,
params: { test, gpu },
gpus: coreMemoryProfileResults(gpu),
}),
);
}

if (test === 'tpc-skyline') {
const gpuKeys = Object.keys(TPC_SKYLINE_RUNS);
const gpu = parseEnumParam(s.get('gpu'), 'gpu', ['all', ...gpuKeys], 'all');
Expand All @@ -43,13 +66,18 @@ export function GET(request: NextRequest) {
}

if (test === 'mem-bw' || test === 'all') {
const gpuKeys = Object.keys(UBENCHX_RUNS);
const gpuKeys =
test === 'all'
? [...Object.keys(UBENCHX_RUNS), CORE_PROFILE_GPU]
: Object.keys(UBENCHX_RUNS);
const gpu = parseEnumParam(s.get('gpu'), 'gpu', ['all', ...gpuKeys], gpuKeys[0]);

const memBwResults =
gpu === 'all'
? Object.entries(UBENCHX_RUNS).map(([key, run]) => transformUbenchxRun(key, run))
: [transformUbenchxRun(gpu, UBENCHX_RUNS[gpu])];
: UBENCHX_RUNS[gpu]
? [transformUbenchxRun(gpu, UBENCHX_RUNS[gpu])]
: [];

if (test === 'mem-bw') {
return Promise.resolve(
Expand Down Expand Up @@ -80,6 +108,9 @@ export function GET(request: NextRequest) {
tests: AVAILABLE_TESTS,
memBw: { gpus: memBwResults },
smL2Distance: { gpus: smL2Results },
coreMemoryProfiles: {
gpus: coreMemoryProfileResults(rawGpu === null ? 'all' : gpu),
},
// Like smL2Distance, default to every GPU rather than mem-bw's first one, and
// match the GPU key case-insensitively as parseEnumParam does for the others.
tpcSkyline: {
Expand Down
36 changes: 36 additions & 0 deletions packages/app/src/app/ubenchx/core-memory-profiles/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { Metadata } from 'next';

import { CoreMemoryProfilesContent } from '@/components/ubenchx/CoreMemoryProfilesContent';
import { UbenchxHub } from '@/components/ubenchx/UbenchxHub';
import { enAlternates } from '@/lib/i18n/i18n';
import { SITE_URL } from '@semianalysisai/inferencex-constants';

const TITLE = 'ubenchX: Core memory-access profiles';
const DESCRIPTION =
'Compare B200 SM and Huawei 950PR Cube/Vector memory-access profiles, preserving each device’s native timer units and measurement conditions.';

export const metadata: Metadata = {
title: TITLE,
description: DESCRIPTION,
alternates: enAlternates('/ubenchx/core-memory-profiles'),
robots: { index: false, follow: false },
openGraph: {
title: `${TITLE} | InferenceX`,
description: DESCRIPTION,
url: `${SITE_URL}/ubenchx/core-memory-profiles`,
},
twitter: { title: `${TITLE} | InferenceX`, description: DESCRIPTION },
};

export default function UbenchxCoreMemoryProfilesPage() {
return (
<main className="relative">
<div className="container mx-auto px-4 pb-8 lg:px-8">
<div className="space-y-8">
<UbenchxHub current="core-memory-profiles" />
<CoreMemoryProfilesContent />
</div>
</div>
</main>
);
}
37 changes: 3 additions & 34 deletions packages/app/src/app/ubenchx/sm-l2-distance/page.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,5 @@
import type { Metadata } from 'next';
import { permanentRedirect } from 'next/navigation';

import { SmL2Content } from '@/components/ubenchx/SmL2Heatmap';
import { UbenchxHub } from '@/components/ubenchx/UbenchxHub';
import { enAlternates } from '@/lib/i18n/i18n';
import { SITE_URL } from '@semianalysisai/inferencex-constants';

const TITLE = 'ubenchX: SM-SM L2 Latency Difference';
const DESCRIPTION =
'L2 pointer-chase microbenchmark showing SM-to-SM latency differences, revealing GPC and die topology structure on NVIDIA Blackwell GPUs.';

export const metadata: Metadata = {
title: TITLE,
description: DESCRIPTION,
alternates: enAlternates('/ubenchx/sm-l2-distance'),
robots: { index: false, follow: false },
openGraph: {
title: `${TITLE} | InferenceX`,
description: DESCRIPTION,
url: `${SITE_URL}/ubenchx/sm-l2-distance`,
},
twitter: { title: `${TITLE} | InferenceX`, description: DESCRIPTION },
};

export default function UbenchxSmL2DistancePage() {
return (
<main className="relative">
<div className="container mx-auto px-4 pb-8 lg:px-8">
<div className="space-y-8">
<UbenchxHub current="sm-l2-distance" />
<SmL2Content />
</div>
</div>
</main>
);
export default function LegacySmL2Page() {
permanentRedirect('/ubenchx/core-memory-profiles');
}
Loading
Loading