@@ -3078,33 +3078,41 @@ ExecResult assign_index_chain(Interpreter *interp, Env *env, Expr *idx_expr, Val
30783078 goto cleanup ;
30793079 }
30803080
3081+ int * out_to_orig = malloc (sizeof (int ) * new_ndim );
3082+ if (!out_to_orig ) {
3083+ free (starts );
3084+ free (ends );
3085+ free (orig_to_out );
3086+ free (out_shape );
3087+ out = make_error ("Out of memory" , stmt_line , stmt_col );
3088+ goto cleanup ;
3089+ }
3090+ for (size_t i = 0 ; i < t -> ndim ; i ++ ) {
3091+ if (orig_to_out [i ] >= 0 ) {
3092+ out_to_orig [orig_to_out [i ]] = (int )i ;
3093+ }
3094+ }
3095+
3096+ size_t fixed_dim_offset = 0 ;
3097+ for (size_t k = 0 ; k < t -> ndim ; k ++ ) {
3098+ if (orig_to_out [k ] == -1 ) {
3099+ size_t pos = (ends [k ] >= starts [k ]) ? (size_t )(starts [k ] - 1 ) : 0 ;
3100+ fixed_dim_offset += pos * t -> strides [k ];
3101+ }
3102+ }
3103+
30813104 // Write RHS elements into target tensor region
30823105 // Iterate over output positions and compute corresponding source offset
30833106 for (size_t out_idx = 0 ; out_idx < rt -> length ; out_idx ++ ) {
3084- // compute multi-index for out
30853107 size_t rem = out_idx ;
3086- size_t src_offset = 0 ;
3108+ size_t src_offset = fixed_dim_offset ;
30873109 for (size_t d = 0 ; d < new_ndim ; d ++ ) {
30883110 size_t pos = rem / rt -> strides [d ];
30893111 rem = rem % rt -> strides [d ];
3090- // find orig dim for this d
3091- size_t orig = 0 ;
3092- for (size_t k = 0 ; k < t -> ndim ; k ++ ) {
3093- if (orig_to_out [k ] == (int )d ) {
3094- orig = k ;
3095- break ;
3096- }
3097- }
3112+ size_t orig = (size_t )out_to_orig [d ];
30983113 size_t src_pos = pos + (size_t )(starts [orig ] - 1 );
30993114 src_offset += src_pos * t -> strides [orig ];
31003115 }
3101- // add fixed-dimension offsets
3102- for (size_t k = 0 ; k < t -> ndim ; k ++ ) {
3103- if (orig_to_out [k ] == -1 ) {
3104- size_t pos = (ends [k ] >= starts [k ]) ? (size_t )(starts [k ] - 1 ) : 0 ;
3105- src_offset += pos * t -> strides [k ];
3106- }
3107- }
31083116
31093117 // assign element
31103118 mtx_lock (& t -> lock );
@@ -3117,6 +3125,7 @@ ExecResult assign_index_chain(Interpreter *interp, Env *env, Expr *idx_expr, Val
31173125 free (starts );
31183126 free (ends );
31193127 free (orig_to_out );
3128+ free (out_to_orig );
31203129 // After slice assignment, set cur to base (no further chaining into this node)
31213130 cur = & base_val ;
31223131 rhs_applied_directly = true;
0 commit comments