Skip to content

Commit 669d1be

Browse files
Improved error message for uninitialized variables
1 parent 9e1c8c5 commit 669d1be

File tree

2 files changed

+49
-16
lines changed

2 files changed

+49
-16
lines changed

src/record_ts.cpp

+48-16
Original file line numberDiff line numberDiff line change
@@ -1853,8 +1853,6 @@ void RecordThreadState::poke(void *dst, const void *src, uint32_t size) {
18531853
// and we cannot track it.
18541854
jitc_raise("RecordThreadState::poke(): this function cannot be recorded!");
18551855
(void) dst; (void) src; (void) size;
1856-
// pause_scope pause(this);
1857-
// return m_internal->poke(dst, src, size);
18581856
}
18591857

18601858
// Enqueue a function to be run on the host once backend computation is done
@@ -1863,22 +1861,54 @@ void RecordThreadState::enqueue_host_func(void (*callback)(void *),
18631861
jitc_raise("RecordThreadState::enqueue_host_func(): this function cannot "
18641862
"be recorded!");
18651863
(void) callback; (void) payload;
1866-
// pause_scope pause(this);
1867-
// return m_internal->enqueue_host_func(callback, payload);
18681864
}
18691865

18701866
void Recording::validate() {
18711867
for (uint32_t i = 0; i < recorded_variables.size(); i++) {
18721868
RecordedVariable &rv = recorded_variables[i];
18731869
if (rv.state == RecordedVarState::Uninitialized) {
1870+
Operation &last_op = operations[rv.last_op];
18741871
#ifndef NDEBUG
1875-
jitc_raise("record(): Variable at slot s%u %p was left in an "
1876-
"uninitialized state!",
1877-
i, rv.ptr);
1872+
if (last_op.type == OpType::Aggregate) {
1873+
jitc_raise(
1874+
"validate(): The frozen function included a virtual "
1875+
"function call involving variable s%u <%p>, last used by "
1876+
"operation o%u. Dr.Jit would normally traverse a registry "
1877+
"of all relevant object instances in order to collect "
1878+
"their member variables. However, when recording this "
1879+
"frozen function, this traversal was skipped because no "
1880+
"such object instance was found in the function's inputs. "
1881+
"You can trigger traversal by including the relevant "
1882+
"objects in the function input, or by specifying them "
1883+
"using the state_fn argument.",
1884+
i, rv.ptr, rv.last_op);
1885+
} else
1886+
jitc_raise(
1887+
"validate(): Variable at slot s%u <%p> was used by %s operation "
1888+
"o%u but left in an uninitialized state! This indicates "
1889+
"that the associated variable was used, but not traversed "
1890+
"as part of the frozen function input.",
1891+
i, rv.ptr, op_type_name[(uint32_t) last_op.type], rv.last_op);
18781892
#else
1879-
jitc_raise("record(): Variable at slot s%u was left in an "
1880-
"uninitialized state!",
1881-
i);
1893+
if (last_op.type == OpType::Aggregate) {
1894+
jitc_raise(
1895+
"validate(): The frozen function included a virtual "
1896+
"function call involving variable s%u. Dr.Jit would "
1897+
"normally traverse a registry of all relevant object "
1898+
"instances in order to collect their member variables. "
1899+
"However, when recording this frozen function, this "
1900+
"traversal was skipped because no such object instance was "
1901+
"found in the function's inputs. You can trigger traversal "
1902+
"by including the relevant objects in the function input, "
1903+
"or by specifying them using the state_fn argument.",
1904+
i);
1905+
} else
1906+
jitc_raise(
1907+
"validate(): Variable at slot s%u was used by %s operation "
1908+
"o%u but left in an uninitialized state! This indicates "
1909+
"that the associated variable was used, but not traversed "
1910+
"as part of the frozen function input.",
1911+
i, op_type_name[(uint32_t) last_op.type], rv.last_op);
18821912
#endif
18831913
}
18841914
}
@@ -1990,8 +2020,9 @@ uint32_t RecordThreadState::capture_variable(uint32_t index,
19902020
uint32_t RecordThreadState::add_variable(const void *ptr) {
19912021
auto it = ptr_to_slot.find(ptr);
19922022

2023+
uint32_t slot;
19932024
if (it == ptr_to_slot.end()) {
1994-
uint32_t slot = (uint32_t) m_recording.recorded_variables.size();
2025+
slot = (uint32_t) m_recording.recorded_variables.size();
19952026

19962027
RecordedVariable rv;
19972028
#ifndef NDEBUG
@@ -2001,12 +2032,13 @@ uint32_t RecordThreadState::add_variable(const void *ptr) {
20012032

20022033
ptr_to_slot.insert({ ptr, slot });
20032034

2004-
return slot;
2005-
} else {
2006-
uint32_t slot = it.value();
2035+
} else
2036+
slot = it.value();
20072037

2008-
return slot;
2009-
}
2038+
m_recording.recorded_variables[slot].last_op =
2039+
(uint32_t) m_recording.operations.size();
2040+
2041+
return slot;
20102042
}
20112043

20122044
/// Return the slot index given the data pointer of a variable.

src/record_ts.h

+1
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ struct RecordedVariable {
163163
/// \c operations vector, necessary for recording the expand operation.
164164
uint32_t last_memset = 0;
165165
uint32_t last_memcpy = 0;
166+
uint32_t last_op = 0;
166167

167168
/// Tracks the current state of a variable
168169
RecordedVarState state = RecordedVarState::Uninitialized;

0 commit comments

Comments
 (0)