Do you mean to say that for evaluation and test set the code should be:
with torch.no_grad():
    model.eval()
    y_pred = model(valX)
    val_loss = criterion(y_pred, valY)

and
with torch.no_grad():
    model.eval()
    y_pred = model(test)
    test_loss = criterion(y_pred, testY)

Also, how about the answer to the second part of the question where I ask about the best way to save the model?