Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[dev-alloc] pimAlloc updates #165

Open
wants to merge 40 commits into
base: dev-alloc
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
37db4eb
Support padded allocation.
deyuan Aug 22, 2024
7958e61
Merge with main branch.
deyuan Aug 22, 2024
86fa8e1
Merge branch 'main' into deyuan_dev2
deyuan Sep 19, 2024
e457017
Merge branch 'main' into deyuan_dev2
deyuan Oct 2, 2024
59d7520
Define PIM_BOOL data type.
deyuan Oct 2, 2024
a237c8a
Remove bitsPerElement parameter from default pimAlloc and pimAllocAss…
deyuan Oct 2, 2024
f768538
Fix a few warnings in misc-bench.
deyuan Oct 2, 2024
9dedf90
Merge with main branch.
deyuan Oct 4, 2024
b1b5ef0
Fixed FP divscalar result bias issue. Due to compiler optimization no…
Oct 17, 2024
d798755
Adding FP32 support for pimRedSum, all other operations are supported!
Oct 17, 2024
c619a79
Merge branch 'main' into dev_float_support
Oct 19, 2024
03de35a
FP32 functional support for all operations completed!
Oct 19, 2024
c72f925
Merge with the latest main branch.
deyuan Oct 20, 2024
41c56f5
Organize customized APIs in libpimeval.h
deyuan Oct 20, 2024
90f9138
FP support, only redSumRanged left.
Oct 20, 2024
ab5ca02
Code clean up.
Oct 20, 2024
95fa27a
Update libpimeval/src/pimCmd.cpp
fzx333 Oct 21, 2024
5c22506
Update libpimeval/src/pimCmd.cpp
fzx333 Oct 21, 2024
9f8ec8a
Update libpimeval/src/pimCmd.cpp
fzx333 Oct 21, 2024
22495a9
Update tests/test-functional/test-functional-fp.h
fzx333 Oct 21, 2024
1378d5e
All operation suppoerted.
Oct 21, 2024
39cbf1b
Updated golden results.
Oct 21, 2024
9908918
Resolve an assertion in FP32 reduction sum perf energy model on bit-s…
deyuan Oct 22, 2024
75bc6f4
Support fuzzy equal check with a percentage tolerance for FP reductio…
deyuan Oct 22, 2024
5d7b865
Update result-golden.txt for functional testing
deyuan Oct 22, 2024
0977455
GOL code cleanup
fasiddique Oct 22, 2024
af887c5
GOL code cleanup (#191)
Arleee1 Oct 22, 2024
72f9e9f
test device API bugfix. code cleanup for test large copies.
fasiddique Oct 22, 2024
bec79fe
FP32 functional support for all operation completed! (#189)
deyuan Oct 23, 2024
5fb02fd
PIMeval: test cleanup (#192)
deyuan Oct 23, 2024
4def6dd
bitmap, xor codecleanup
fasiddique Oct 27, 2024
2938617
code cleanup gemv & pool
fasiddique Oct 27, 2024
b6186ce
relu & batched-relu code cleanup
fasiddique Oct 27, 2024
3e3a7e8
relu code cleanup
fasiddique Oct 27, 2024
24ee191
code cleanup convolution
fasiddique Oct 27, 2024
83f95e3
batched convolution code cleanup
fasiddique Oct 27, 2024
84c9485
Bitmap, xor code cleanup (#196)
fasiddique Oct 28, 2024
d0781a9
Merge branch 'main' into pimbench-code-cleanup
fasiddique Oct 28, 2024
e039afd
Pimbench code cleanup (#197)
fasiddique Oct 29, 2024
45d597f
Merge branch 'main' into deyuan_dev2
deyuan Oct 29, 2024
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
14 changes: 14 additions & 0 deletions libpimeval/src/libpimeval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,20 @@ pimAllocAssociated(PimObjId assocId, PimDataType dataType)
return pimSim::get()->pimAllocAssociated(bitsPerElement, assocId, dataType);
}

//! @brief Allocate a PIM resource
PimObjId
pimAllocCustomized(PimAllocEnum allocType, uint64_t numElements, PimDataType dataType, unsigned bitsPerElement)
{
return pimSim::get()->pimAlloc(allocType, numElements, bitsPerElement, dataType);
}

//! @brief Allocate a PIM resource, with an associated object as reference
PimObjId
pimAllocAssociatedCustomized(PimObjId assocId, PimDataType dataType, unsigned bitsPerElement)
{
return pimSim::get()->pimAllocAssociated(bitsPerElement, assocId, dataType);
}

//! @brief Free a PIM resource
PimStatus
pimFree(PimObjId obj)
Expand Down
10 changes: 9 additions & 1 deletion libpimeval/src/libpimeval.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ enum PimCopyEnum {

//! @brief PIM datatypes
enum PimDataType {
PIM_INT8 = 0,
PIM_BOOL = 0,
PIM_INT8,
PIM_INT16,
PIM_INT32,
PIM_INT64,
Expand Down Expand Up @@ -142,6 +143,10 @@ PimStatus pimShiftElementsLeft(PimObjId src);
PimStatus pimShiftBitsRight(PimObjId src, PimObjId dest, unsigned shiftAmount);
PimStatus pimShiftBitsLeft(PimObjId src, PimObjId dest, unsigned shiftAmount);

////////////////////////////////////////////////////////////////////////////////
// Warning: Do not use below micro-ops level APIs for functional simulation //
////////////////////////////////////////////////////////////////////////////////

// BitSIMD micro ops
// Note: Below APIs are for low-level micro-ops programming but not for functional simulation
// BitSIMD-V: Row-wide bit registers per subarray
Expand All @@ -155,6 +160,9 @@ enum PimRowReg {
PIM_RREG_R5,
};

// Customized allocation with bitsPerElement less than the number of bits of dataType
PimObjId pimAllocCustomized(PimAllocEnum allocType, uint64_t numElements, PimDataType dataType, unsigned bitsPerElement);
PimObjId pimAllocAssociatedCustomized(PimObjId assocId, PimDataType dataType, unsigned bitsPerElement);
// BitSIMD-V micro ops
PimStatus pimOpReadRowToSa(PimObjId src, unsigned ofst);
PimStatus pimOpWriteSaToRow(PimObjId src, unsigned ofst);
Expand Down
40 changes: 31 additions & 9 deletions libpimeval/src/pimResMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ pimResMgr::~pimResMgr()
}

//! @brief Alloc a PIM object
//! Expect bitsPerElement to be smaller than or equal to the width of dataType
//! For V layout, allocate bitsPerElement rows
//! For H layout, pad element to the width of dataType
PimObjId
pimResMgr::pimAlloc(PimAllocEnum allocType, uint64_t numElements, unsigned bitsPerElement, PimDataType dataType)
{
Expand All @@ -114,6 +117,12 @@ pimResMgr::pimAlloc(PimAllocEnum allocType, uint64_t numElements, unsigned bitsP
std::printf("PIM-Error: Invalid parameters to allocate %llu elements of %u bits\n", numElements, bitsPerElement);
return -1;
}
unsigned bitsOfDataType = pimUtils::getNumBitsOfDataType(dataType);
if (bitsPerElement > bitsOfDataType) {
std::printf("PIM-Error: Cannot allocate %u bits which is greater than the width of %s data type\n",
bitsPerElement, pimUtils::pimDataTypeEnumToStr(dataType).c_str());
return -1;
}

std::vector<PimCoreId> sortedCoreId = getCoreIdsSortedByLeastUsage();
pimObjInfo newObj(m_availObjId, dataType, allocType, numElements, bitsPerElement);
Expand Down Expand Up @@ -141,8 +150,8 @@ pimResMgr::pimAlloc(PimAllocEnum allocType, uint64_t numElements, unsigned bitsP
} else if (allocType == PIM_ALLOC_H || allocType == PIM_ALLOC_H1) {
// allocate one region per core, with horizontal layout
numRowsToAlloc = 1;
numRegions = (numElements * bitsPerElement - 1) / numCols + 1;
numColsToAllocLast = (numElements * bitsPerElement) % numCols;
numRegions = (numElements * bitsOfDataType - 1) / numCols + 1;
numColsToAllocLast = (numElements * bitsOfDataType) % numCols;
if (numColsToAllocLast == 0) {
numColsToAllocLast = numCols;
}
Expand All @@ -156,7 +165,8 @@ pimResMgr::pimAlloc(PimAllocEnum allocType, uint64_t numElements, unsigned bitsP

if (numRegions > numCores) {
if (allocType == PIM_ALLOC_V1 || allocType == PIM_ALLOC_H1) {
std::printf("PIM-Error: Obj requires %llu regions among %u cores. Abort.\n", numRegions, numCores);
std::printf("PIM-Error: Obj requires %llu regions among %u cores. Abort since wrapping up is disabled.\n",
numRegions, numCores);
return -1;
} else {
#if defined(DEBUG)
Expand All @@ -165,7 +175,7 @@ pimResMgr::pimAlloc(PimAllocEnum allocType, uint64_t numElements, unsigned bitsP
}
}

// create new regions
// create regions
bool success = true;
for (unsigned i = 0; i < numCores; ++i) {
m_coreUsage.at(i)->newAllocStart();
Expand Down Expand Up @@ -218,8 +228,11 @@ pimResMgr::pimAlloc(PimAllocEnum allocType, uint64_t numElements, unsigned bitsP
}

//! @brief Alloc a PIM object assiciated to an existing object
//! For V layout, expect same number of elements, while bits per element may be different
//! For H layout, expect exact same number of elements and bits per elements
//! Expect bitsPerElement to be smaller than or equal to the width of dataType
//! Expect dataType to be narrower or equal to the width of associated dataType
//! For V layout, allocate bitsPerElement rows
//! For H layout, pad element to the width of assiciated dataType
//! Number of elements will be the same as the assiciated object
PimObjId
pimResMgr::pimAllocAssociated(unsigned bitsPerElement, PimObjId assocId, PimDataType dataType)
{
Expand All @@ -233,6 +246,12 @@ pimResMgr::pimAllocAssociated(unsigned bitsPerElement, PimObjId assocId, PimData
std::printf("PIM-Error: Invalid associated object ID %d for PIM allocation\n", assocId);
return -1;
}
unsigned bitsOfDataType = pimUtils::getNumBitsOfDataType(dataType);
if (bitsPerElement > bitsOfDataType) {
std::printf("PIM-Error: Cannot allocate %u bits which is greater than the width of %s data type\n",
bitsPerElement, pimUtils::pimDataTypeEnumToStr(dataType).c_str());
return -1;
}

// get regions of the assoc obj
unsigned numCores = m_device->getNumCores();
Expand All @@ -241,10 +260,13 @@ pimResMgr::pimAllocAssociated(unsigned bitsPerElement, PimObjId assocId, PimData
// check if the request can be associated with ref
PimAllocEnum allocType = assocObj.getAllocType();
uint64_t numElements = assocObj.getNumElements();
PimDataType assocDataType = assocObj.getDataType();
unsigned bitsOfAssocDataType = pimUtils::getNumBitsOfDataType(assocDataType);
if (allocType == PIM_ALLOC_H || allocType == PIM_ALLOC_H1) {
if (bitsPerElement != assocObj.getBitsPerElement()) {
std::printf("PIM-Error: Cannot allocate elements of %u bits associated with object ID %d with %u bits in H1 style\n",
bitsPerElement, assocId, assocObj.getBitsPerElement());
if (bitsOfDataType > bitsOfAssocDataType) {
std::printf("PIM-Error: Cannot associate or pad a wider %s data type to %s data type\n",
pimUtils::pimDataTypeEnumToStr(dataType).c_str(),
pimUtils::pimDataTypeEnumToStr(assocDataType).c_str());
return -1;
}
}
Expand Down
2 changes: 2 additions & 0 deletions libpimeval/src/pimResMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class pimObjInfo
PimDataType getDataType() const { return m_dataType; }
uint64_t getNumElements() const { return m_numElements; }
unsigned getBitsPerElement() const { return m_bitsPerElement; }
unsigned getBitsPerElementPadded() const { return m_bitsPerElementPadded; }
bool isValid() const { return m_numElements > 0 && m_bitsPerElement > 0 && !m_regions.empty(); }
bool isVLayout() const { return m_allocType == PIM_ALLOC_V || m_allocType == PIM_ALLOC_V1; }
bool isHLayout() const { return m_allocType == PIM_ALLOC_H || m_allocType == PIM_ALLOC_H1; }
Expand All @@ -128,6 +129,7 @@ class pimObjInfo
PimAllocEnum m_allocType;
uint64_t m_numElements = 0;
unsigned m_bitsPerElement = 0;
unsigned m_bitsPerElementPadded = 0;
std::vector<pimRegion> m_regions; // a list of core ID and regions
unsigned m_maxNumRegionsPerCore = 0;
unsigned m_numCoresUsed = 0;
Expand Down
2 changes: 2 additions & 0 deletions libpimeval/src/pimUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ std::string
pimUtils::pimDataTypeEnumToStr(PimDataType dataType)
{
switch (dataType) {
case PIM_BOOL: return "bool";
case PIM_INT8: return "int8";
case PIM_INT16: return "int16";
case PIM_INT32: return "int32";
Expand All @@ -94,6 +95,7 @@ unsigned
pimUtils::getNumBitsOfDataType(PimDataType dataType)
{
switch (dataType) {
case PIM_BOOL: return 1;
case PIM_INT8: return 8;
case PIM_INT16: return 16;
case PIM_INT32: return 32;
Expand Down
19 changes: 19 additions & 0 deletions tests/test-padding/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Makefile: Test PIM alloc and padding
# Copyright (c) 2024 University of Virginia
# This file is licensed under the MIT License.
# See the LICENSE file in the root of this repository for more details.

PROJ_ROOT = ../..
include ${PROJ_ROOT}/Makefile.common

EXEC := test-padding.out
SRC := test-padding.cpp

debug perf dramsim3_integ: $(EXEC)

$(EXEC): $(SRC) $(DEPS)
$(CXX) $< $(CXXFLAGS) -o $@

clean:
rm -rf $(EXEC) *.dSYM

109 changes: 109 additions & 0 deletions tests/test-padding/test-padding.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// Test: Test PIM alloc
// Copyright (c) 2024 University of Virginia
// This file is licensed under the MIT License.
// See the LICENSE file in the root of this repository for more details.

#include "libpimeval.h"
#include <iostream>
#include <vector>
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cstdlib>
#include <cstdio>


void testAlloc(PimDeviceEnum deviceType)
{
// 1GB capacity
unsigned numRanks = 1;
unsigned numBankPerRank = 1;
unsigned numSubarrayPerBank = 4;
unsigned numRows = 1024;
unsigned numCols = 8192;

uint64_t numElements = 32 * 1024;

std::vector<int> srcInt(numElements);
std::vector<int> srcIntNarrow(numElements);
std::vector<char> srcChar(numElements);
std::vector<char> srcCharNarrow(numElements);

for (uint64_t i = 0; i < numElements; ++i) {
srcInt[i] = static_cast<int>(i);
srcIntNarrow[i] = (srcInt[i] & 0xffffff);
srcChar[i] = i % 256;
srcCharNarrow[i] = (srcChar[i] & 0xf);
}

PimStatus status = pimCreateDevice(deviceType, numRanks, numBankPerRank, numSubarrayPerBank, numRows, numCols);
assert(status == PIM_OK);

// test PIM allocation
PimObjId objInt = pimAlloc(PIM_ALLOC_AUTO, numElements, PIM_INT32);
PimObjId objIntNarrow = pimAllocCustomized(PIM_ALLOC_AUTO, numElements, PIM_INT32, 24/*bitsPerElement*/);
PimObjId objChar = pimAlloc(PIM_ALLOC_AUTO, numElements, PIM_INT8);
PimObjId objCharNarrow = pimAllocCustomized(PIM_ALLOC_AUTO, numElements, PIM_INT8, 4/*bitsPerElement*/);
assert(objInt != -1);
assert(objIntNarrow != -1);
assert(objChar != -1);
assert(objCharNarrow != -1);

// copy host to device
status = pimCopyHostToDevice((void*)srcInt.data(), objInt);
assert(status == PIM_OK);
status = pimCopyHostToDevice((void*)srcInt.data(), objIntNarrow); // auto truncate
assert(status == PIM_OK);
status = pimCopyHostToDevice((void*)srcChar.data(), objChar);
assert(status == PIM_OK);
status = pimCopyHostToDevice((void*)srcChar.data(), objCharNarrow); // auto truncate
assert(status == PIM_OK);

std::vector<int> destInt(numElements);
std::vector<int> destIntNarrow(numElements);
std::vector<char> destChar(numElements);
std::vector<char> destCharNarrow(numElements);

status = pimCopyDeviceToHost(objInt, (void*)destInt.data());
assert(status == PIM_OK);
status = pimCopyDeviceToHost(objIntNarrow, (void*)destIntNarrow.data());
assert(status == PIM_OK);
status = pimCopyDeviceToHost(objChar, (void*)destChar.data());
assert(status == PIM_OK);
status = pimCopyDeviceToHost(objCharNarrow, (void*)destCharNarrow.data());
assert(status == PIM_OK);

if (srcInt != destInt) {
std::printf("ERROR: Incorrect int32 values\n");
}
if (srcIntNarrow != destIntNarrow) {
std::printf("ERROR: Incorrect int32 truncated values\n");
}
if (srcChar != destChar) {
std::printf("ERROR: Incorrect int8 values\n");
}
if (srcCharNarrow != destCharNarrow) {
std::printf("ERROR: Incorrect int8 truncated values\n");
}

pimFree(objInt);
pimFree(objIntNarrow);
pimFree(objChar);
pimFree(objCharNarrow);

pimShowStats();
pimResetStats();
pimDeleteDevice();
}

int main()
{
std::cout << "PIM Regression Test: PIM alloc and padding" << std::endl;

testAlloc(PIM_DEVICE_BITSIMD_V);

testAlloc(PIM_DEVICE_FULCRUM);

return 0;
}