Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Duplicate trial numbers are assigned on parallel execution. #130

Closed
c-bata opened this issue Jul 7, 2020 · 2 comments · Fixed by #168
Closed

Duplicate trial numbers are assigned on parallel execution. #130

c-bata opened this issue Jul 7, 2020 · 2 comments · Fixed by #168
Labels
bug Something isn't working effort high

Comments

@c-bata
Copy link
Owner

c-bata commented Jul 7, 2020

Refs: optuna/optuna#1488

The same problem is exist on Goptuna.

@c-bata c-bata added bug Something isn't working effort high labels Jul 7, 2020
@c-bata c-bata changed the title Trial numbers are not unique on parallel execution. Duplicate trial numbers are assigned on parallel execution. Jul 7, 2020
@c-bata
Copy link
Owner Author

c-bata commented Jul 8, 2020

Optuna resolved this issue by using SELECT ... FOR UPDATE.

optuna/optuna#1490

@c-bata c-bata mentioned this issue Oct 28, 2020
10 tasks
@c-bata
Copy link
Owner Author

c-bata commented Oct 28, 2020

Before

package main

import (
	"context"
	"flag"
	"log"
	"math"

	"github.com/c-bata/goptuna"
	"github.com/c-bata/goptuna/rdb"
	"github.com/c-bata/goptuna/tpe"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
	_ "github.com/jinzhu/gorm/dialects/sqlite"
	"golang.org/x/sync/errgroup"
)

func objective(trial goptuna.Trial) (float64, error) {
	x1, _ := trial.SuggestFloat("x1", -10, 10)
	x2, _ := trial.SuggestFloat("x2", -10, 10)
	return math.Pow(x1-2, 2) + math.Pow(x2+5, 2), nil
}

func main() {
	flag.Parse()
	if len(flag.Args()) == 0 {
		log.Fatal("please pass dialect and dsn")
	}
	dialect := flag.Arg(0)
	dsn := flag.Arg(1)

	db, err := gorm.Open(dialect, dsn)
	if err != nil {
		log.Fatal("failed to open db:", err)
	}

	rdb.RunAutoMigrate(db)
	storage := rdb.NewStorage(db)
	defer db.Close()

	study, err := goptuna.CreateStudy(
		"rdb",
		goptuna.StudyOptionStorage(storage),
		goptuna.StudyOptionSampler(tpe.NewSampler()),
		goptuna.StudyOptionDirection(goptuna.StudyDirectionMinimize),
		goptuna.StudyOptionLoadIfExists(true),
	)
	if err != nil {
		log.Fatal("failed to create study", err)
	}

	eg, ctx := errgroup.WithContext(context.Background())
	study.WithContext(ctx)
	for i := 0; i < 10; i++ {
		eg.Go(func() error {
			return study.Optimize(objective, 20)
		})
	}
	if err := eg.Wait(); err != nil {
		log.Fatal("Optimize error", err)
	}

	trials, err := study.GetTrials()
	if err != nil {
		log.Fatal("failed to get trials", err)
	}
	for i := range trials {
		log.Printf("trial id=%d: number=%d\n", trials[i].ID, trials[i].Number)
	}

	v, err := study.GetBestValue()
	if err != nil {
		log.Fatal("failed to get best value", err)
	}
	params, err := study.GetBestParams()
	if err != nil {
		log.Fatal("failed to get best params:", err)
	}
	log.Printf("Best evaluation=%f (x1=%f, x2=%f)",
		v, params["x1"].(float64), params["x2"].(float64))
}
2020/10/29 01:39:30 trial id=1: number=0
2020/10/29 01:39:30 trial id=2: number=1
2020/10/29 01:39:30 trial id=3: number=1
2020/10/29 01:39:30 trial id=4: number=1
2020/10/29 01:39:30 trial id=5: number=1
2020/10/29 01:39:30 trial id=6: number=1
2020/10/29 01:39:30 trial id=7: number=1
2020/10/29 01:39:30 trial id=8: number=1
2020/10/29 01:39:30 trial id=9: number=4
2020/10/29 01:39:30 trial id=10: number=5
2020/10/29 01:39:30 trial id=11: number=10
2020/10/29 01:39:30 trial id=12: number=11
2020/10/29 01:39:30 trial id=13: number=12
2020/10/29 01:39:30 trial id=14: number=13
2020/10/29 01:39:30 trial id=15: number=14
2020/10/29 01:39:30 trial id=16: number=15
2020/10/29 01:39:30 trial id=17: number=16
2020/10/29 01:39:30 trial id=18: number=17
2020/10/29 01:39:30 trial id=19: number=17
2020/10/29 01:39:30 trial id=20: number=19
2020/10/29 01:39:30 trial id=21: number=20
2020/10/29 01:39:30 trial id=22: number=21
2020/10/29 01:39:30 trial id=23: number=22
2020/10/29 01:39:30 trial id=24: number=23
2020/10/29 01:39:30 trial id=25: number=24
2020/10/29 01:39:30 trial id=26: number=25
2020/10/29 01:39:30 trial id=27: number=26
2020/10/29 01:39:30 trial id=28: number=26
2020/10/29 01:39:30 trial id=29: number=28
2020/10/29 01:39:30 trial id=30: number=29
2020/10/29 01:39:30 trial id=31: number=30
2020/10/29 01:39:30 trial id=32: number=31
2020/10/29 01:39:30 trial id=33: number=32
2020/10/29 01:39:30 trial id=34: number=33
2020/10/29 01:39:30 trial id=35: number=34
2020/10/29 01:39:30 trial id=36: number=35
2020/10/29 01:39:30 trial id=37: number=35
2020/10/29 01:39:30 trial id=38: number=37
2020/10/29 01:39:30 trial id=39: number=38
2020/10/29 01:39:30 trial id=40: number=39
2020/10/29 01:39:30 trial id=41: number=40
2020/10/29 01:39:30 trial id=42: number=41
2020/10/29 01:39:30 trial id=43: number=42
2020/10/29 01:39:30 trial id=44: number=43
2020/10/29 01:39:30 trial id=45: number=44
2020/10/29 01:39:30 trial id=46: number=45
2020/10/29 01:39:30 trial id=47: number=46
2020/10/29 01:39:30 trial id=48: number=47
2020/10/29 01:39:30 trial id=49: number=48
2020/10/29 01:39:30 trial id=50: number=49
2020/10/29 01:39:30 trial id=51: number=50
2020/10/29 01:39:30 trial id=52: number=51
2020/10/29 01:39:30 trial id=53: number=52
2020/10/29 01:39:30 trial id=54: number=53
2020/10/29 01:39:30 trial id=55: number=54
2020/10/29 01:39:30 trial id=56: number=55
2020/10/29 01:39:30 trial id=57: number=56
2020/10/29 01:39:30 trial id=58: number=57
2020/10/29 01:39:30 trial id=59: number=58
2020/10/29 01:39:30 trial id=60: number=59
2020/10/29 01:39:30 trial id=61: number=60
2020/10/29 01:39:30 trial id=62: number=61
2020/10/29 01:39:30 trial id=63: number=62
2020/10/29 01:39:30 trial id=64: number=63
2020/10/29 01:39:30 trial id=65: number=64
2020/10/29 01:39:30 trial id=66: number=65
2020/10/29 01:39:30 trial id=67: number=66
2020/10/29 01:39:30 trial id=68: number=67
2020/10/29 01:39:30 trial id=69: number=68
2020/10/29 01:39:30 trial id=70: number=69
2020/10/29 01:39:30 trial id=71: number=70
2020/10/29 01:39:30 trial id=72: number=71
2020/10/29 01:39:30 trial id=73: number=72
2020/10/29 01:39:30 trial id=74: number=73
2020/10/29 01:39:30 trial id=75: number=74
2020/10/29 01:39:30 trial id=76: number=75
2020/10/29 01:39:30 trial id=77: number=75
2020/10/29 01:39:30 trial id=78: number=77
2020/10/29 01:39:30 trial id=79: number=78
2020/10/29 01:39:30 trial id=80: number=79
2020/10/29 01:39:30 trial id=81: number=80
2020/10/29 01:39:30 trial id=82: number=81
2020/10/29 01:39:30 trial id=83: number=82
2020/10/29 01:39:30 trial id=84: number=83
2020/10/29 01:39:30 trial id=85: number=84
2020/10/29 01:39:30 trial id=86: number=85
2020/10/29 01:39:30 trial id=87: number=86
2020/10/29 01:39:30 trial id=88: number=87
2020/10/29 01:39:30 trial id=89: number=88
2020/10/29 01:39:30 trial id=90: number=89
2020/10/29 01:39:30 trial id=91: number=90
2020/10/29 01:39:30 trial id=92: number=91
2020/10/29 01:39:30 trial id=93: number=92
2020/10/29 01:39:30 trial id=94: number=93
2020/10/29 01:39:30 trial id=95: number=94
2020/10/29 01:39:30 trial id=96: number=95
2020/10/29 01:39:30 trial id=97: number=96
2020/10/29 01:39:30 trial id=98: number=97
2020/10/29 01:39:30 trial id=99: number=98
2020/10/29 01:39:30 trial id=100: number=99
2020/10/29 01:39:30 trial id=101: number=100
2020/10/29 01:39:30 trial id=102: number=101
2020/10/29 01:39:30 trial id=103: number=102
2020/10/29 01:39:30 trial id=104: number=103
2020/10/29 01:39:30 trial id=105: number=104
2020/10/29 01:39:30 trial id=106: number=105
2020/10/29 01:39:30 trial id=107: number=106
2020/10/29 01:39:30 trial id=108: number=107
2020/10/29 01:39:30 trial id=109: number=108
2020/10/29 01:39:30 trial id=110: number=109
2020/10/29 01:39:30 trial id=111: number=110
2020/10/29 01:39:30 trial id=112: number=111
2020/10/29 01:39:30 trial id=113: number=112
2020/10/29 01:39:30 trial id=114: number=113
2020/10/29 01:39:30 trial id=115: number=114
2020/10/29 01:39:30 trial id=116: number=115
2020/10/29 01:39:30 trial id=117: number=116
2020/10/29 01:39:30 trial id=118: number=117
2020/10/29 01:39:30 trial id=119: number=118
2020/10/29 01:39:30 trial id=120: number=119
2020/10/29 01:39:30 trial id=121: number=120
2020/10/29 01:39:30 trial id=122: number=121
2020/10/29 01:39:30 trial id=123: number=122
2020/10/29 01:39:30 trial id=124: number=123
2020/10/29 01:39:30 trial id=125: number=124
2020/10/29 01:39:30 trial id=126: number=125
2020/10/29 01:39:30 trial id=127: number=126
2020/10/29 01:39:30 trial id=128: number=127
2020/10/29 01:39:30 trial id=129: number=128
2020/10/29 01:39:30 trial id=130: number=129
2020/10/29 01:39:30 trial id=131: number=130
2020/10/29 01:39:30 trial id=132: number=131
2020/10/29 01:39:30 trial id=133: number=132
2020/10/29 01:39:30 trial id=134: number=133
2020/10/29 01:39:30 trial id=135: number=134
2020/10/29 01:39:30 trial id=136: number=135
2020/10/29 01:39:30 trial id=137: number=136
2020/10/29 01:39:30 trial id=138: number=137
2020/10/29 01:39:30 trial id=139: number=138
2020/10/29 01:39:30 trial id=140: number=139
2020/10/29 01:39:30 trial id=141: number=140
2020/10/29 01:39:30 trial id=142: number=141
2020/10/29 01:39:30 trial id=143: number=142
2020/10/29 01:39:30 trial id=144: number=143
2020/10/29 01:39:30 trial id=145: number=144
2020/10/29 01:39:30 trial id=146: number=145
2020/10/29 01:39:30 trial id=147: number=146
2020/10/29 01:39:30 trial id=148: number=147
2020/10/29 01:39:30 trial id=149: number=148
2020/10/29 01:39:30 trial id=150: number=149
2020/10/29 01:39:30 trial id=151: number=150
2020/10/29 01:39:30 trial id=152: number=151
2020/10/29 01:39:30 trial id=153: number=152
2020/10/29 01:39:30 trial id=154: number=153
2020/10/29 01:39:30 trial id=155: number=153
2020/10/29 01:39:30 trial id=156: number=155
2020/10/29 01:39:30 trial id=157: number=156
2020/10/29 01:39:30 trial id=158: number=157
2020/10/29 01:39:30 trial id=159: number=158
2020/10/29 01:39:30 trial id=160: number=159
2020/10/29 01:39:30 trial id=161: number=160
2020/10/29 01:39:30 trial id=162: number=161
2020/10/29 01:39:30 trial id=163: number=162
2020/10/29 01:39:30 trial id=164: number=163
2020/10/29 01:39:30 trial id=165: number=164
2020/10/29 01:39:30 trial id=166: number=165
2020/10/29 01:39:30 trial id=167: number=166
2020/10/29 01:39:30 trial id=168: number=167
2020/10/29 01:39:30 trial id=169: number=168
2020/10/29 01:39:30 trial id=170: number=169
2020/10/29 01:39:30 trial id=171: number=170
2020/10/29 01:39:30 trial id=172: number=171
2020/10/29 01:39:30 trial id=173: number=172
2020/10/29 01:39:30 trial id=174: number=173
2020/10/29 01:39:30 trial id=175: number=174
2020/10/29 01:39:30 trial id=176: number=175
2020/10/29 01:39:30 trial id=177: number=176
2020/10/29 01:39:30 trial id=178: number=177
2020/10/29 01:39:30 trial id=179: number=178
2020/10/29 01:39:30 trial id=180: number=179
2020/10/29 01:39:30 trial id=181: number=180
2020/10/29 01:39:30 trial id=182: number=181
2020/10/29 01:39:30 trial id=183: number=182
2020/10/29 01:39:30 trial id=184: number=183
2020/10/29 01:39:30 trial id=185: number=184
2020/10/29 01:39:30 trial id=186: number=185
2020/10/29 01:39:30 trial id=187: number=186
2020/10/29 01:39:30 trial id=188: number=187
2020/10/29 01:39:30 trial id=189: number=188
2020/10/29 01:39:30 trial id=190: number=189
2020/10/29 01:39:30 trial id=191: number=190
2020/10/29 01:39:30 trial id=192: number=191
2020/10/29 01:39:30 trial id=193: number=192
2020/10/29 01:39:30 trial id=194: number=193
2020/10/29 01:39:30 trial id=195: number=194
2020/10/29 01:39:30 trial id=196: number=195
2020/10/29 01:39:30 trial id=197: number=196
2020/10/29 01:39:30 trial id=198: number=197
2020/10/29 01:39:30 trial id=199: number=198
2020/10/29 01:39:30 trial id=200: number=199

After #168

package main

import (
	"context"
	"flag"
	"log"
	"math"

	"github.com/c-bata/goptuna"
	"github.com/c-bata/goptuna/rdb.v2"
	"github.com/c-bata/goptuna/tpe"
	"golang.org/x/sync/errgroup"
	"gorm.io/driver/mysql"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
)

func objective(trial goptuna.Trial) (float64, error) {
	x1, _ := trial.SuggestFloat("x1", -10, 10)
	x2, _ := trial.SuggestFloat("x2", -10, 10)
	return math.Pow(x1-2, 2) + math.Pow(x2+5, 2), nil
}

func main() {
	flag.Parse()
	if len(flag.Args()) == 0 {
		log.Fatal("please pass dialect and dsn")
	}
	dialect := flag.Arg(0)
	dsn := flag.Arg(1)

	var db *gorm.DB
	var err error
	if dialect == "sqlite3" {
		db, err = gorm.Open(sqlite.Open(dsn), &gorm.Config{})
	} else if dialect == "mysql" {
		db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
	} else {
		log.Fatal("unsupported dialect")
	}
	if err != nil {
		log.Fatal("failed to open db:", err)
	}
	err = rdb.RunAutoMigrate(db)
	if err != nil {
		log.Fatal("failed to run auto migrate:", err)
	}

	study, err := goptuna.CreateStudy(
		"rdb",
		goptuna.StudyOptionStorage(rdb.NewStorage(db)),
		goptuna.StudyOptionSampler(tpe.NewSampler()),
		goptuna.StudyOptionDirection(goptuna.StudyDirectionMinimize),
		goptuna.StudyOptionLoadIfExists(true),
	)
	if err != nil {
		log.Fatal("failed to create study", err)
	}

	eg, ctx := errgroup.WithContext(context.Background())
	study.WithContext(ctx)
	for i := 0; i < 10; i++ {
		eg.Go(func() error {
			return study.Optimize(objective, 20)
		})
	}
	if err := eg.Wait(); err != nil {
		log.Fatal("Optimize error", err)
	}

	trials, err := study.GetTrials()
	if err != nil {
		log.Fatal("failed to get trials", err)
	}
	for i := range trials {
		log.Printf("trial id=%d: number=%d\n", trials[i].ID, trials[i].Number)
	}

	v, err := study.GetBestValue()
	if err != nil {
		log.Fatal("failed to get best value", err)
	}
	params, err := study.GetBestParams()
	if err != nil {
		log.Fatal("failed to get best params:", err)
	}
	log.Printf("Best evaluation=%f (x1=%f, x2=%f)",
		v, params["x1"].(float64), params["x2"].(float64))
}
2020/10/29 02:16:13 trial id=1: number=0
2020/10/29 02:16:13 trial id=2: number=1
2020/10/29 02:16:13 trial id=3: number=2
2020/10/29 02:16:13 trial id=4: number=3
2020/10/29 02:16:13 trial id=5: number=4
2020/10/29 02:16:13 trial id=6: number=5
2020/10/29 02:16:13 trial id=7: number=6
2020/10/29 02:16:13 trial id=8: number=7
2020/10/29 02:16:13 trial id=9: number=8
2020/10/29 02:16:13 trial id=10: number=9
2020/10/29 02:16:13 trial id=11: number=10
2020/10/29 02:16:13 trial id=12: number=11
2020/10/29 02:16:13 trial id=13: number=12
2020/10/29 02:16:13 trial id=14: number=13
2020/10/29 02:16:13 trial id=15: number=14
2020/10/29 02:16:13 trial id=16: number=15
2020/10/29 02:16:13 trial id=17: number=16
2020/10/29 02:16:13 trial id=18: number=17
2020/10/29 02:16:13 trial id=19: number=18
2020/10/29 02:16:13 trial id=20: number=19
2020/10/29 02:16:13 trial id=21: number=20
2020/10/29 02:16:13 trial id=22: number=21
2020/10/29 02:16:13 trial id=23: number=22
2020/10/29 02:16:13 trial id=24: number=23
2020/10/29 02:16:13 trial id=25: number=24
2020/10/29 02:16:13 trial id=26: number=25
2020/10/29 02:16:13 trial id=27: number=26
2020/10/29 02:16:13 trial id=28: number=27
2020/10/29 02:16:13 trial id=29: number=28
2020/10/29 02:16:13 trial id=30: number=29
2020/10/29 02:16:13 trial id=31: number=30
2020/10/29 02:16:13 trial id=32: number=31
2020/10/29 02:16:13 trial id=33: number=32
2020/10/29 02:16:13 trial id=34: number=33
2020/10/29 02:16:13 trial id=35: number=34
2020/10/29 02:16:13 trial id=36: number=35
2020/10/29 02:16:13 trial id=37: number=36
2020/10/29 02:16:13 trial id=38: number=37
2020/10/29 02:16:13 trial id=39: number=38
2020/10/29 02:16:13 trial id=40: number=39
2020/10/29 02:16:13 trial id=41: number=40
2020/10/29 02:16:13 trial id=42: number=41
2020/10/29 02:16:13 trial id=43: number=42
2020/10/29 02:16:13 trial id=44: number=43
2020/10/29 02:16:13 trial id=45: number=44
2020/10/29 02:16:13 trial id=46: number=45
2020/10/29 02:16:13 trial id=47: number=46
2020/10/29 02:16:13 trial id=48: number=47
2020/10/29 02:16:13 trial id=49: number=48
2020/10/29 02:16:13 trial id=50: number=49
2020/10/29 02:16:13 trial id=51: number=50
2020/10/29 02:16:13 trial id=52: number=51
2020/10/29 02:16:13 trial id=53: number=52
2020/10/29 02:16:13 trial id=54: number=53
2020/10/29 02:16:13 trial id=55: number=54
2020/10/29 02:16:13 trial id=56: number=55
2020/10/29 02:16:13 trial id=57: number=56
2020/10/29 02:16:13 trial id=58: number=57
2020/10/29 02:16:13 trial id=59: number=58
2020/10/29 02:16:13 trial id=60: number=59
2020/10/29 02:16:13 trial id=61: number=60
2020/10/29 02:16:13 trial id=62: number=61
2020/10/29 02:16:13 trial id=63: number=62
2020/10/29 02:16:13 trial id=64: number=63
2020/10/29 02:16:13 trial id=65: number=64
2020/10/29 02:16:13 trial id=66: number=65
2020/10/29 02:16:13 trial id=67: number=66
2020/10/29 02:16:13 trial id=68: number=67
2020/10/29 02:16:13 trial id=69: number=68
2020/10/29 02:16:13 trial id=70: number=69
2020/10/29 02:16:13 trial id=71: number=70
2020/10/29 02:16:13 trial id=72: number=71
2020/10/29 02:16:13 trial id=73: number=72
2020/10/29 02:16:13 trial id=74: number=73
2020/10/29 02:16:13 trial id=75: number=74
2020/10/29 02:16:13 trial id=76: number=75
2020/10/29 02:16:13 trial id=77: number=76
2020/10/29 02:16:13 trial id=78: number=77
2020/10/29 02:16:13 trial id=79: number=78
2020/10/29 02:16:13 trial id=80: number=79
2020/10/29 02:16:13 trial id=81: number=80
2020/10/29 02:16:13 trial id=82: number=81
2020/10/29 02:16:13 trial id=83: number=82
2020/10/29 02:16:13 trial id=84: number=83
2020/10/29 02:16:13 trial id=85: number=84
2020/10/29 02:16:13 trial id=86: number=85
2020/10/29 02:16:13 trial id=87: number=86
2020/10/29 02:16:13 trial id=88: number=87
2020/10/29 02:16:13 trial id=89: number=88
2020/10/29 02:16:13 trial id=90: number=89
2020/10/29 02:16:13 trial id=91: number=90
2020/10/29 02:16:13 trial id=92: number=91
2020/10/29 02:16:13 trial id=93: number=92
2020/10/29 02:16:13 trial id=94: number=93
2020/10/29 02:16:13 trial id=95: number=94
2020/10/29 02:16:13 trial id=96: number=95
2020/10/29 02:16:13 trial id=97: number=96
2020/10/29 02:16:13 trial id=98: number=97
2020/10/29 02:16:13 trial id=99: number=98
2020/10/29 02:16:13 trial id=100: number=99
2020/10/29 02:16:13 Best evaluation=0.130782 (x1=1.718881, x2=-5.227495)


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working effort high
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant