From 2122425105ed098d641aead5964896b35a75410e Mon Sep 17 00:00:00 2001 From: Samuel Cui Date: Sat, 22 Aug 2026 12:27:13 +0800 Subject: [PATCH] keep source preparation parallel for linear targets --- opt.go | 4 ---- opt_test.go | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/opt.go b/opt.go index c3a63d0..5e783a7 100644 --- a/opt.go +++ b/opt.go @@ -64,10 +64,6 @@ func (o *option) check() error { o.fromDevice.check() o.toDevice.check() - if o.fromDevice.linear || o.toDevice.linear { - o.fromDevice.threads = 1 - o.toDevice.threads = 1 - } if o.logger == nil { o.logger = logrus.StandardLogger() } diff --git a/opt_test.go b/opt_test.go index 61de271..193a4f9 100644 --- a/opt_test.go +++ b/opt_test.go @@ -51,3 +51,50 @@ func TestComparePath(t *testing.T) { } } } + +func TestLinearDeviceOnlySerializesItsOwnStage(t *testing.T) { + // Cover each directional linear constraint independently. + tests := []struct { + name string + options []Option + wantFromThreads int + wantToThreads int + }{ + { + name: "linear target", + options: []Option{ + SetToDevice(LinearDevice(true)), + }, + wantFromThreads: 8, + wantToThreads: 1, + }, + { + name: "linear source", + options: []Option{ + SetFromDevice(LinearDevice(true)), + }, + wantFromThreads: 1, + wantToThreads: 8, + }, + } + + // Keep the unconstrained side parallel while serializing only the linear stage. + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + option := newOption() + for _, apply := range test.options { + option = apply(option) + } + + if err := option.check(); err != nil { + t.Fatal(err) + } + if option.fromDevice.threads != test.wantFromThreads { + t.Fatalf("source threads = %d, want %d", option.fromDevice.threads, test.wantFromThreads) + } + if option.toDevice.threads != test.wantToThreads { + t.Fatalf("target threads = %d, want %d", option.toDevice.threads, test.wantToThreads) + } + }) + } +}