sugarme / gotch

Go binding for Pytorch C++ API (libtorch)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Releasing tensor causes segmentation fault error

luxiant opened this issue · comments

This is an extension of following discussion : #96

Here is my full code : https://github.com/luxiant/marketsentiment/blob/main/main.go

I found a spot where memory leaks, so I tried to manually free the received tensors with following code.

func (m *customModel) bertSentimentProcess(dataframe dataframe.DataFrame) sentimentRow {
	var logit []float64
	ts.NoGrad(func() {
                // input is a newly created tensor
                input := processSentenceIntoInput(m.tokenizer, dataframe.Col("text").Records()[0])

                // receive all values, and then delete unusued tensor slices if existing.
		torchResult, unused1, unused2:= m.bertModel.ForwardT(
			input,
			ts.None,
			ts.None,
			ts.None,
			ts.None,
			false,
		)
                // drop input tensor. this works.
                input.MustDrop()

                // trying to drop unused tensor slices
                for _, tensor := range unused1 {
                        (&tensor).MustDrop() // <- this causes segfault error
                }
                for _, tensor := range unused2 {
                        (&tensor).MustDrop() // <- this causes segfault error
                }
		logit = torchResult.MustSoftmax(-1, gotch.Double, true).Float64Values(true)
	})
	var sentiment string
	switch {
	case logit[0] > logit[1] && logit[0] > logit[2]:
		sentiment = "long"
	case logit[1] > logit[0] && logit[1] > logit[2]:
		sentiment = "neutral"
	default:
		sentiment = "short"
	}
	return sentimentRow{
		post_num:  dataframe.Col("post_num").Records()[0],
		time:      dataframe.Col("time").Records()[0],
		text:      dataframe.Col("text").Records()[0],
		long:      logit[0],
		neutral:   logit[1],
		short:     logit[2],
		sentiment: sentiment,
	}
}

But I met segfault error when I receive the unused values from Forward method and then try to manually free them. That is why I chose not to receive the unnecessary values at the first place. But yes...I can tell that this was meaningless. The process allocates memory to these unnecessary tensor slices even though I'm not receiving the values.

Is there any idea for this? I can't even remember how many times I run into segfault error to deal with this and can't think of the way to go forward.