Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,8 @@ RestHeaders AnyonServerHelper::getHeaders() { return generateRequestHeader(); }

/// Refresh the api key and refresh-token
void AnyonServerHelper::refreshTokens(bool force_refresh) {
std::mutex m;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is there whitepsace here?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

static std::mutex m;
std::lock_guard<std::mutex> l(m);
RestClient client;
auto now = std::chrono::high_resolution_clock::now();
Expand Down Expand Up @@ -437,8 +438,15 @@ std::string searchAPIKey(std::string &key, std::string &refreshKey,
hwConfig = std::string(creds);
else if (!userSpecifiedConfig.empty())
hwConfig = userSpecifiedConfig;
else
hwConfig = std::string(getenv("HOME")) + std::string("/.anyon_config");
else {

const char *home = std::getenv("HOME");
if (!home)
throw std::runtime_error(
"HOME environment variable is not set. Cannot locate Anyon "
"credentials file. Set CUDAQ_ANYON_CREDENTIALS to override.");
hwConfig = std::string(home) + std::string("/.anyon_config");
}
if (cudaq::fileExists(hwConfig)) {
findApiKeyInFile(key, hwConfig, refreshKey, timeStr, credentials);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,11 @@ void IQMServerHelper::initialize(BackendConfig config) {
} else {
// Set alternative iqmclient-cli tokens file path if provided via env var
auto envTokenFilePath = getenv("IQM_TOKENS_FILE");
// FIX(security): guard getenv("HOME") against nullptr (e.g. in containers)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for the FIX comments in the code.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

const char *homeDir = getenv("HOME");
auto defaultTokensFilePath =
std::string(getenv("HOME")) + "/.cache/iqm-client-cli/tokens.json";
homeDir ? std::string(homeDir) + "/.cache/iqm-client-cli/tokens.json"
: std::string();
if (envTokenFilePath) {
tokensFilePath = std::string(envTokenFilePath);
} else if (cudaq::fileExists(defaultTokensFilePath)) {
Expand Down Expand Up @@ -537,8 +540,9 @@ std::string IQMServerHelper::writeQuantumArchitectureFile(void) {
fwrite(outputLine.c_str(), outputLine.length(), 1, file);
}

// FIX(bug): fclose() already closes the underlying fd from fdopen().
// Calling close(fd) after fclose() is a double-close (UB).
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing here, no need for comments.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

fclose(file);
close(fd);

return quantumArchitectureFilePath;
} // IQMServerHelper::writeQuantumArchitectureFile()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,15 @@ static std::string searchAPIKey(std::string &key, std::string &refreshKey,
hwConfig = std::string(creds);
else if (!userSpecifiedConfig.empty())
hwConfig = userSpecifiedConfig;
else
hwConfig = std::string(getenv("HOME")) + std::string("/.quantinuum_config");
else {
// FIX(security): guard getenv("HOME") against nullptr (e.g. in containers)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, no need for comments.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

const char *home = std::getenv("HOME");
if (!home)
throw std::runtime_error(
"HOME environment variable is not set. Cannot locate Quantinuum "
"credentials file. Set CUDAQ_QUANTINUUM_CREDENTIALS to override.");
hwConfig = std::string(home) + std::string("/.quantinuum_config");
}
if (cudaq::fileExists(hwConfig)) {
findApiKeyInFile(key, hwConfig, refreshKey, timeStr);
} else {
Expand Down Expand Up @@ -705,7 +712,9 @@ void QuantinuumServerHelper::refreshTokens(bool force_refresh) {
throw std::runtime_error(
"Cannot get refresh access token, refresh key is empty.");
}
std::mutex m;
// FIX(bug): mutex must be static to provide actual cross-thread protection.
// A local mutex is created/destroyed per call, giving zero synchronization.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, no need for comments.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

static std::mutex m;
std::lock_guard<std::mutex> l(m);
auto now = std::chrono::high_resolution_clock::now();

Expand Down
23 changes: 17 additions & 6 deletions runtime/nvqir/NVQIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,9 @@ constexpr std::string_view typeName() {
template <SimPrecisionType To, SimPrecisionType From>
std::unique_ptr<std::complex<To>[]> convertToComplex(std::complex<From> *data,
std::size_t numQubits) {
// The state size is `2^numQubits`
auto size = pow(2, numQubits);
// FIX(perf): use bit-shift instead of floating-point pow() for exact integer
// computation — pow() returns double, losing precision for large qubit counts.
auto size = static_cast<std::size_t>(1) << numQubits;
constexpr auto toType = typeName<To>();
constexpr auto fromType = typeName<From>();
CUDAQ_INFO("copying {} complex<{}> values to complex<{}>", size, fromType,
Expand All @@ -241,8 +242,9 @@ std::unique_ptr<std::complex<To>[]> convertToComplex(std::complex<From> *data,
template <SimPrecisionType To, SimPrecisionType From>
std::unique_ptr<std::complex<To>[]> convertToComplex(From *data,
std::size_t numQubits) {
// The state size is `2^numQubits`
auto size = pow(2, numQubits);
// FIX(perf): use bit-shift instead of floating-point pow() for exact integer
// computation — pow() returns double, losing precision for large qubit counts.
auto size = static_cast<std::size_t>(1) << numQubits;
constexpr auto toType = typeName<To>();
constexpr auto fromType = typeName<From>();
CUDAQ_INFO("copying {} {} values to complex<{}>", size, fromType, toType);
Expand Down Expand Up @@ -431,8 +433,9 @@ void __quantum__rt__qubit_release_array(Array *arr) {
nvqir::getCircuitSimulatorInternal()->deallocate(idxVal->idx);
delete idxVal;
}
delete arr;
// FIX(bug): untrack before delete to avoid use-after-delete on dangling ptr
nvqir::ArrayTracker::getInstance().untrack(arr);
delete arr;
return;
}

Expand Down Expand Up @@ -828,6 +831,10 @@ void __quantum__qis__apply_kraus_channel_double(std::int64_t krausChannelKey,
try {
channelName = noise->get_channel(key, paramVec).get_type_name();
} catch (...) {

CUDAQ_DBG("Failed to resolve noise channel name in tracer mode for "
"key {}, falling back to 'apply_noise'",
key);
}
}
ctx->kernelTrace.appendNoiseInstruction(
Expand Down Expand Up @@ -869,6 +876,10 @@ __quantum__qis__apply_kraus_channel_float(std::int64_t krausChannelKey,
try {
channelName = noise->get_channel(key, paramVec).get_type_name();
} catch (...) {

CUDAQ_DBG("Failed to resolve noise channel name in tracer mode for "
"key {}, falling back to 'apply_noise'",
key);
}
}
ctx->kernelTrace.appendNoiseInstruction(
Expand Down Expand Up @@ -975,7 +986,7 @@ std::vector<details::FakeQubit> *
__quantum__qis__convert_array_to_stdvector(Array *arr) {
const std::size_t size = arr->size();
std::vector<details::FakeQubit> *result = new std::vector<details::FakeQubit>;
result->reserve(size);
result->resize(size);
Comment thread
InboraStudio marked this conversation as resolved.
Outdated
for (std::size_t i = 0; i < size; ++i) {
(*result)[i].id = (*arr)[i];
(*result)[i].negated = false;
Expand Down