@@ -1853,8 +1853,6 @@ void RecordThreadState::poke(void *dst, const void *src, uint32_t size) {
1853
1853
// and we cannot track it.
1854
1854
jitc_raise (" RecordThreadState::poke(): this function cannot be recorded!" );
1855
1855
(void ) dst; (void ) src; (void ) size;
1856
- // pause_scope pause(this);
1857
- // return m_internal->poke(dst, src, size);
1858
1856
}
1859
1857
1860
1858
// 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 *),
1863
1861
jitc_raise (" RecordThreadState::enqueue_host_func(): this function cannot "
1864
1862
" be recorded!" );
1865
1863
(void ) callback; (void ) payload;
1866
- // pause_scope pause(this);
1867
- // return m_internal->enqueue_host_func(callback, payload);
1868
1864
}
1869
1865
1870
1866
void Recording::validate () {
1871
1867
for (uint32_t i = 0 ; i < recorded_variables.size (); i++) {
1872
1868
RecordedVariable &rv = recorded_variables[i];
1873
1869
if (rv.state == RecordedVarState::Uninitialized) {
1870
+ Operation &last_op = operations[rv.last_op ];
1874
1871
#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 );
1878
1892
#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 );
1882
1912
#endif
1883
1913
}
1884
1914
}
@@ -1990,8 +2020,9 @@ uint32_t RecordThreadState::capture_variable(uint32_t index,
1990
2020
uint32_t RecordThreadState::add_variable (const void *ptr) {
1991
2021
auto it = ptr_to_slot.find (ptr);
1992
2022
2023
+ uint32_t slot;
1993
2024
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 ();
1995
2026
1996
2027
RecordedVariable rv;
1997
2028
#ifndef NDEBUG
@@ -2001,12 +2032,13 @@ uint32_t RecordThreadState::add_variable(const void *ptr) {
2001
2032
2002
2033
ptr_to_slot.insert ({ ptr, slot });
2003
2034
2004
- return slot;
2005
- } else {
2006
- uint32_t slot = it.value ();
2035
+ } else
2036
+ slot = it.value ();
2007
2037
2008
- return slot;
2009
- }
2038
+ m_recording.recorded_variables [slot].last_op =
2039
+ (uint32_t ) m_recording.operations .size ();
2040
+
2041
+ return slot;
2010
2042
}
2011
2043
2012
2044
// / Return the slot index given the data pointer of a variable.
0 commit comments