1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-09 00:00:00 +01:00

card: add API to create a single card

this is a preparation for allowing defining the card in the node config
rather than separately.

Signed-off-by: Niklas Eiling <niklas.eiling@eonerc.rwth-aachen.de>
This commit is contained in:
Niklas Eiling 2024-02-26 11:04:59 +01:00 committed by Niklas Eiling
parent ee068621e6
commit 4b7ed781c0
3 changed files with 114 additions and 92 deletions

View file

@ -17,8 +17,13 @@ namespace fpga {
std::shared_ptr<fpga::Card>
setupFpgaCard(const std::string &configFile, const std::string &fpgaName);
std::shared_ptr<fpga::Card>
createCard(json_t *config, std::list<std::shared_ptr<fpga::Card>> &cards,
std::filesystem::path &searchPath,
std::shared_ptr<kernel::vfio::Container> vfioContainer,
std::string card_name = "anonymous Card");
int createCards(json_t *config, std::list<std::shared_ptr<fpga::Card>> &cards,
std::filesystem::path &searchPath);
std::filesystem::path &searchPath, std::shared_ptr<kernel::vfio::Container> vfioContainer = nullptr);
std::shared_ptr<std::vector<std::shared_ptr<fpga::ip::Node>>>
getAuroraChannels(std::shared_ptr<fpga::Card> card);
@ -55,81 +60,82 @@ protected:
int dstAsInt;
};
class BufferedSampleFormatter {
public:
virtual void format(float value) = 0;
virtual void output(std::ostream& out)
{
out << buf.data() << std::flush;
clearBuf();
}
virtual void clearBuf()
{
for (size_t i = 0; i < bufSamples && buf[i*bufSampleSize] != '\0'; i++) {
buf[i*bufSampleSize] = '\0';
}
currentBufLoc = 0;
}
protected:
std::vector<char> buf;
const size_t bufSamples;
const size_t bufSampleSize;
size_t currentBufLoc;
class BufferedSampleFormatter {
public:
virtual void format(float value) = 0;
virtual void output(std::ostream &out) {
out << buf.data() << std::flush;
clearBuf();
}
virtual void clearBuf() {
for (size_t i = 0; i < bufSamples && buf[i * bufSampleSize] != '\0';
i++) {
buf[i * bufSampleSize] = '\0';
}
currentBufLoc = 0;
}
BufferedSampleFormatter(const size_t bufSamples, const size_t bufSampleSize) :
buf(bufSamples*bufSampleSize+1), // Leave room for a final `\0'
bufSamples(bufSamples),
bufSampleSize(bufSampleSize),
currentBufLoc(0) {};
BufferedSampleFormatter() = delete;
BufferedSampleFormatter(const BufferedSampleFormatter&) = delete;
virtual char* nextBufPos()
{
return &buf[(currentBufLoc++)*bufSampleSize];
}
};
protected:
std::vector<char> buf;
const size_t bufSamples;
const size_t bufSampleSize;
size_t currentBufLoc;
class BufferedSampleFormatterShort : public BufferedSampleFormatter {
public:
BufferedSampleFormatterShort(size_t bufSizeInSamples) :
BufferedSampleFormatter(bufSizeInSamples, formatStringSize) {};
BufferedSampleFormatter(const size_t bufSamples, const size_t bufSampleSize)
: buf(bufSamples * bufSampleSize + 1), // Leave room for a final `\0'
bufSamples(bufSamples), bufSampleSize(bufSampleSize),
currentBufLoc(0){};
BufferedSampleFormatter() = delete;
BufferedSampleFormatter(const BufferedSampleFormatter &) = delete;
virtual char *nextBufPos() {
return &buf[(currentBufLoc++) * bufSampleSize];
}
};
virtual void format(float value) override
{
size_t chars;
if ((chars = std::snprintf(nextBufPos(), formatStringSize+1, formatString, value)) > (int)formatStringSize) {
throw RuntimeError("Output buffer too small. Expected " + std::to_string(formatStringSize) +
" characters, got " + std::to_string(chars));
}
}
class BufferedSampleFormatterShort : public BufferedSampleFormatter {
public:
BufferedSampleFormatterShort(size_t bufSizeInSamples)
: BufferedSampleFormatter(bufSizeInSamples, formatStringSize){};
protected:
static constexpr char formatString[] = "%013.6f\n";
static constexpr size_t formatStringSize = 14;
};
virtual void format(float value) override {
size_t chars;
if ((chars = std::snprintf(nextBufPos(), formatStringSize + 1,
formatString, value)) >
(int)formatStringSize) {
throw RuntimeError("Output buffer too small. Expected " +
std::to_string(formatStringSize) +
" characters, got " + std::to_string(chars));
}
}
class BufferedSampleFormatterLong : public BufferedSampleFormatter {
public:
BufferedSampleFormatterLong(size_t bufSizeInSamples) :
BufferedSampleFormatter(bufSizeInSamples, formatStringSize),
sampleCnt(0) {};
protected:
static constexpr char formatString[] = "%013.6f\n";
static constexpr size_t formatStringSize = 14;
};
virtual void format(float value) override
{
if (std::snprintf(nextBufPos(), formatStringSize+1, formatString, sampleCnt, value) > (int)formatStringSize) {
throw RuntimeError("Output buffer too small");
}
sampleCnt = (sampleCnt+1) % 100000;
}
class BufferedSampleFormatterLong : public BufferedSampleFormatter {
public:
BufferedSampleFormatterLong(size_t bufSizeInSamples)
: BufferedSampleFormatter(bufSizeInSamples, formatStringSize),
sampleCnt(0){};
protected:
static constexpr char formatString[] = "%05zd: %013.6f\n";
static constexpr size_t formatStringSize = 22;
size_t sampleCnt;
};
virtual void format(float value) override {
if (std::snprintf(nextBufPos(), formatStringSize + 1, formatString,
sampleCnt, value) > (int)formatStringSize) {
throw RuntimeError("Output buffer too small");
}
sampleCnt = (sampleCnt + 1) % 100000;
}
protected:
static constexpr char formatString[] = "%05zd: %013.6f\n";
static constexpr size_t formatStringSize = 22;
size_t sampleCnt;
};
std::unique_ptr<BufferedSampleFormatter> getBufferedSampleFormatter(const std::string &format, size_t bufSizeInSamples);
std::unique_ptr<BufferedSampleFormatter>
getBufferedSampleFormatter(const std::string &format,
size_t bufSizeInSamples);
} // namespace fpga
} // namespace villas

View file

@ -48,7 +48,7 @@ PCIeCardFactory::make(json_t *json_card, std::string card_name,
if (ret != 0)
throw ConfigError(json_card, err, "", "Failed to parse card");
auto card = std::unique_ptr<PCIeCard>(make());
auto card = std::shared_ptr<PCIeCard>(make());
// Populate generic properties
card->name = std::string(card_name);

View file

@ -225,11 +225,46 @@ void fpga::setupColorHandling()
});
}
std::shared_ptr<fpga::Card>
fpga::createCard(json_t *config, std::list<std::shared_ptr<fpga::Card>> &cards,
std::filesystem::path &searchPath,
std::shared_ptr<kernel::vfio::Container> vfioContainer,
std::string card_name) {
auto configDir = std::filesystem::path().parent_path();
const char *interfaceName;
json_error_t err;
logger->info("Found config for FPGA card {}", card_name);
int ret =
json_unpack_ex(config, &err, 0, "{s: s}", "interface", &interfaceName);
if (ret) {
throw ConfigError(config, err, "interface",
"Failed to parse interface name for card {}", card_name);
}
std::string interfaceNameStr(interfaceName);
if (interfaceNameStr == "pcie") {
auto card = fpga::PCIeCardFactory::make(config, std::string(card_name),
vfioContainer, searchPath);
if (card) {
cards.push_back(card);
return card;
}
return nullptr;
} else if (interfaceNameStr == "platform") {
throw RuntimeError("Platform interface not implemented yet");
} else {
throw RuntimeError("Unknown interface type {}", interfaceNameStr);
}
}
int fpga::createCards(json_t *config,
std::list<std::shared_ptr<fpga::Card>> &cards,
std::filesystem::path &searchPath) {
std::filesystem::path &searchPath,
std::shared_ptr<kernel::vfio::Container> vfioContainer) {
int numFpgas = 0;
auto vfioContainer = std::make_shared<kernel::vfio::Container>();
if (vfioContainer == nullptr) {
vfioContainer = std::make_shared<kernel::vfio::Container>();
}
auto configDir = std::filesystem::path().parent_path();
json_t *fpgas = json_object_get(config, "fpgas");
@ -241,28 +276,9 @@ int fpga::createCards(json_t *config,
const char *card_name;
json_t *json_card;
json_object_foreach(fpgas, card_name, json_card) {
const char *interfaceName;
json_error_t err;
logger->info("Found config for FPGA card {}", card_name);
int ret = json_unpack_ex(json_card, &err, 0, "{s: s}", "interface",
&interfaceName);
if (ret) {
throw ConfigError(json_card, err, "interface",
"Failed to parse interface name for card {}",
card_name);
}
std::string interfaceNameStr(interfaceName);
if (interfaceNameStr == "pcie") {
auto card = fpga::PCIeCardFactory::make(json_card, std::string(card_name),
vfioContainer, searchPath);
if (card) {
cards.push_back(std::move(card));
numFpgas++;
}
} else if (interfaceNameStr == "platform") {
throw RuntimeError("Platform interface not implemented yet");
} else {
throw RuntimeError("Unknown interface type {}", interfaceNameStr);
if (createCard(json_card, cards, searchPath, vfioContainer, card_name) !=
nullptr) {
numFpgas++;
}
}
return numFpgas;